@@ -592,19 +592,26 @@ class PartitionOpTranslator {
592
592
593
593
// translate each SIL instruction to a PartitionOp, if necessary
594
594
std::vector<PartitionOp> partitionOps;
595
+ int lastTranslationIndex = -1 ;
595
596
for (SILInstruction &instruction : *basicBlock) {
596
597
auto ops = translateSILInstruction (&instruction);
597
598
for (PartitionOp &op : ops) {
598
599
partitionOps.push_back (op);
599
600
600
601
LLVM_DEBUG (
601
- llvm::dbgs () << " ┌─┬─╼" ;
602
- instruction.dump ();
603
- llvm::dbgs () << " │ └─╼ " ;
604
- instruction.getLoc ().getSourceLoc ().printLineAndColumn (llvm::dbgs (), function->getASTContext ().SourceMgr );
605
- llvm::dbgs () << " │ translation #" << translationIndex;
606
- llvm::dbgs () << " \n └─────╼ " ;
602
+ if (translationIndex != lastTranslationIndex) {
603
+ llvm::dbgs () << " ┌─┬─╼" ;
604
+ instruction.dump ();
605
+ llvm::dbgs () << " │ └─╼ " ;
606
+ instruction.getLoc ().getSourceLoc ().printLineAndColumn (
607
+ llvm::dbgs (), function->getASTContext ().SourceMgr );
608
+ llvm::dbgs () << " │ translation #" << translationIndex;
609
+ llvm::dbgs () << " \n └─────╼ " ;
610
+ } else {
611
+ llvm::dbgs () << " └╼ " ;
612
+ }
607
613
op.dump ();
614
+ lastTranslationIndex = translationIndex;
608
615
);
609
616
}
610
617
}
@@ -617,7 +624,7 @@ class PartitionOpTranslator {
617
624
// SILBasicBlock for the region-based Sendable checking fixpoint analysis.
618
625
// In particular, it records flags such as whether the block has been
619
626
// reached by the analysis, whether the prior round indicated that this block
620
- // needs to be updated; it recorsd aux data such as the underlying basic block
627
+ // needs to be updated; it records aux data such as the underlying basic block
621
628
// and associated PartitionOpTranslator; and most importantly of all it includes
622
629
// region partitions at entry and exit to this block - these are the stateful
623
630
// component of the fixpoint analysis.
@@ -1218,8 +1225,13 @@ class PartitionAnalysis {
1218
1225
/* handleFailure=*/
1219
1226
[&](const PartitionOp& partitionOp, TrackableValueID consumedVal) {
1220
1227
auto expr = getExprForPartitionOp (partitionOp);
1228
+
1229
+ // ensure that multiple consumptions at the same AST node are only
1230
+ // entered once into the race tracer
1221
1231
if (hasBeenEmitted (expr)) return ;
1232
+
1222
1233
raceTracer.traceUseOfConsumedValue (partitionOp, consumedVal);
1234
+
1223
1235
/*
1224
1236
* This handles diagnosing accesses to consumed values at the site
1225
1237
* of access instead of the site of consumption, as this is less
@@ -1229,6 +1241,7 @@ class PartitionAnalysis {
1229
1241
expr->getLoc(), diag::consumed_value_used);
1230
1242
*/
1231
1243
},
1244
+
1232
1245
/* handleConsumeNonConsumable=*/
1233
1246
[&](const PartitionOp& partitionOp, TrackableValueID consumedVal) {
1234
1247
auto expr = getExprForPartitionOp (partitionOp);
@@ -1247,11 +1260,13 @@ class PartitionAnalysis {
1247
1260
expr->getLoc (), diag::consumption_yields_race,
1248
1261
numDisplayed, numDisplayed != 1 , numHidden > 0 , numHidden);
1249
1262
},
1263
+
1250
1264
/* diagnoseRequire=*/
1251
1265
[&](const PartitionOp& requireOp) {
1252
1266
auto expr = getExprForPartitionOp (requireOp);
1253
1267
function->getASTContext ().Diags .diagnose (
1254
- expr->getLoc (), diag::possible_racy_access_site);
1268
+ expr->getLoc (), diag::possible_racy_access_site)
1269
+ .highlight (expr->getSourceRange ());
1255
1270
});
1256
1271
}
1257
1272
0 commit comments