@@ -421,9 +421,34 @@ struct TransferredNonTransferrableInfo {
421
421
isolationRegionInfo(isolationRegionInfo) {}
422
422
};
423
423
424
+ // / A pointer to a TransferringOperand pointer that sorts according to the
425
+ // / Operand pointer in the TransferringOperand rather than the pointer of the
426
+ // / TransferringOperand itself.
427
+ class TransferringOperandRef {
428
+ TransferringOperand *operand;
429
+
430
+ public:
431
+ TransferringOperandRef (TransferringOperand *operand) : operand(operand) {}
432
+
433
+ TransferringOperand *operator *() const { return operand; }
434
+ TransferringOperand *operator ->() const { return operand; }
435
+
436
+ bool operator ==(const TransferringOperandRef &other) const {
437
+ return operand->getOperand () == other->getOperand ();
438
+ }
439
+
440
+ bool operator !=(const TransferringOperandRef &other) const {
441
+ return !(*this == other);
442
+ }
443
+
444
+ bool operator <(const TransferringOperandRef &other) const {
445
+ return operand->getOperand () < other->getOperand ();
446
+ }
447
+ };
448
+
424
449
class TransferNonSendableImpl {
425
450
RegionAnalysisFunctionInfo *regionInfo;
426
- SmallFrozenMultiMap<Operand * , SILInstruction *, 8 >
451
+ SmallFrozenMultiMap<TransferringOperandRef , SILInstruction *, 8 >
427
452
transferOpToRequireInstMultiMap;
428
453
SmallVector<TransferredNonTransferrableInfo, 8 >
429
454
transferredNonTransferrableInfoList;
@@ -467,6 +492,7 @@ class UseAfterTransferDiagnosticEmitter {
467
492
}
468
493
469
494
void emitNamedIsolationCrossingError (SILLocation loc, Identifier name,
495
+ SILIsolationInfo namesIsolationInfo,
470
496
ApplyIsolationCrossing isolationCrossing,
471
497
SILLocation variableDefinedLoc) {
472
498
// Emit the short error.
@@ -475,10 +501,15 @@ class UseAfterTransferDiagnosticEmitter {
475
501
.highlight (loc.getSourceRange ());
476
502
477
503
// Then emit the note with greater context.
478
- diagnoseNote (loc,
479
- diag::regionbasedisolation_named_info_transfer_yields_race,
480
- name, isolationCrossing.getCallerIsolation (),
481
- isolationCrossing.getCalleeIsolation ());
504
+ SmallString<64 > descriptiveKindStr;
505
+ {
506
+ llvm::raw_svector_ostream os (descriptiveKindStr);
507
+ namesIsolationInfo.printForDiagnostics (os);
508
+ }
509
+ diagnoseNote (
510
+ loc, diag::regionbasedisolation_named_info_transfer_yields_race, name,
511
+ descriptiveKindStr, isolationCrossing.getCalleeIsolation (),
512
+ isolationCrossing.getCallerIsolation ());
482
513
emitRequireInstDiagnostics ();
483
514
}
484
515
@@ -492,7 +523,7 @@ class UseAfterTransferDiagnosticEmitter {
492
523
emitRequireInstDiagnostics ();
493
524
}
494
525
495
- void emitUseOfStringlyTransferredValue (SILLocation loc, Type inferredType) {
526
+ void emitUseOfStronglyTransferredValue (SILLocation loc, Type inferredType) {
496
527
diagnoseError (
497
528
loc,
498
529
diag::
@@ -580,7 +611,7 @@ class UseAfterTransferDiagnosticEmitter {
580
611
};
581
612
582
613
class UseAfterTransferDiagnosticInferrer {
583
- Operand *transferOp;
614
+ TransferringOperand *transferOp;
584
615
UseAfterTransferDiagnosticEmitter diagnosticEmitter;
585
616
RegionAnalysisValueMap &valueMap;
586
617
SILLocation baseLoc = SILLocation::invalid();
@@ -590,13 +621,18 @@ class UseAfterTransferDiagnosticInferrer {
590
621
591
622
public:
592
623
UseAfterTransferDiagnosticInferrer (
593
- Operand *transferOp, SmallVectorImpl<SILInstruction *> &requireInsts,
624
+ TransferringOperand *transferOp,
625
+ SmallVectorImpl<SILInstruction *> &requireInsts,
594
626
RegionAnalysisValueMap &valueMap)
595
- : transferOp(transferOp), diagnosticEmitter(transferOp, requireInsts),
627
+ : transferOp(transferOp),
628
+ diagnosticEmitter(transferOp->getOperand (), requireInsts),
596
629
valueMap(valueMap), baseLoc(transferOp->getUser ()->getLoc()),
597
- baseInferredType(transferOp->get ()->getType().getASTType()) {}
630
+ baseInferredType(
631
+ transferOp->getOperand ()->get()->getType().getASTType()) {}
598
632
void infer ();
599
633
634
+ Operand *getTransferringOperand () const { return transferOp->getOperand (); }
635
+
600
636
private:
601
637
bool initForIsolatedPartialApply (Operand *op, AbstractClosureExpr *ace);
602
638
@@ -742,11 +778,12 @@ struct UseAfterTransferDiagnosticInferrer::Walker : ASTWalker {
742
778
void UseAfterTransferDiagnosticInferrer::infer () {
743
779
// Otherwise, see if our operand's instruction is a transferring parameter.
744
780
if (auto fas = FullApplySite::isa (transferOp->getUser ())) {
745
- assert (!fas.getArgumentConvention (*transferOp).isIndirectOutParameter () &&
781
+ assert (!fas.getArgumentConvention (*transferOp->getOperand ())
782
+ .isIndirectOutParameter () &&
746
783
" We should never transfer an indirect out parameter" );
747
- if (fas.getArgumentParameterInfo (*transferOp)
784
+ if (fas.getArgumentParameterInfo (*transferOp-> getOperand () )
748
785
.hasOption (SILParameterInfo::Transferring)) {
749
- return diagnosticEmitter.emitUseOfStringlyTransferredValue (
786
+ return diagnosticEmitter.emitUseOfStronglyTransferredValue (
750
787
baseLoc, baseInferredType);
751
788
}
752
789
}
@@ -757,7 +794,7 @@ void UseAfterTransferDiagnosticInferrer::infer() {
757
794
// transfer error due to us transferring a value into it.
758
795
if (auto *ace = loc.getAsASTNode <AbstractClosureExpr>()) {
759
796
if (ace->getActorIsolation ().isActorIsolated ()) {
760
- if (initForIsolatedPartialApply (transferOp, ace)) {
797
+ if (initForIsolatedPartialApply (transferOp-> getOperand () , ace)) {
761
798
return ;
762
799
}
763
800
}
@@ -770,21 +807,21 @@ void UseAfterTransferDiagnosticInferrer::infer() {
770
807
if (auto *svi =
771
808
dyn_cast<SingleValueInstruction>(rootValueAndName->second )) {
772
809
return diagnosticEmitter.emitNamedIsolationCrossingError (
773
- baseLoc, rootValueAndName->first ,
810
+ baseLoc, rootValueAndName->first , transferOp-> getIsolationInfo (),
774
811
*sourceApply->getIsolationCrossing (), svi->getLoc ());
775
812
}
776
813
777
814
if (auto *fArg =
778
815
dyn_cast<SILFunctionArgument>(rootValueAndName->second )) {
779
816
return diagnosticEmitter.emitNamedIsolationCrossingError (
780
- baseLoc, rootValueAndName->first ,
817
+ baseLoc, rootValueAndName->first , transferOp-> getIsolationInfo (),
781
818
*sourceApply->getIsolationCrossing (),
782
819
RegularLocation (fArg ->getDecl ()->getLoc ()));
783
820
}
784
821
}
785
822
786
823
// Otherwise, try to infer from the ApplyExpr.
787
- return initForApply (transferOp, sourceApply);
824
+ return initForApply (transferOp-> getOperand () , sourceApply);
788
825
}
789
826
790
827
if (auto fas = FullApplySite::isa (transferOp->getUser ())) {
@@ -801,7 +838,7 @@ void UseAfterTransferDiagnosticInferrer::infer() {
801
838
802
839
auto *i = transferOp->getUser ();
803
840
auto pai = ApplySite::isa (i);
804
- unsigned captureIndex = pai.getAppliedArgIndex (*transferOp);
841
+ unsigned captureIndex = pai.getAppliedArgIndex (*transferOp-> getOperand () );
805
842
806
843
auto captureInfo =
807
844
autoClosureExpr->getCaptureInfo ().getCaptures ()[captureIndex];
@@ -823,8 +860,9 @@ void TransferNonSendableImpl::emitUseAfterTransferDiagnostics() {
823
860
824
861
LLVM_DEBUG (llvm::dbgs () << " Emitting use after transfer diagnostics.\n " );
825
862
826
- for (auto [transferOp , requireInsts] :
863
+ for (auto [transferOpRef , requireInsts] :
827
864
transferOpToRequireInstMultiMap.getRange ()) {
865
+ auto *transferOp = *transferOpRef;
828
866
829
867
LLVM_DEBUG (llvm::dbgs ()
830
868
<< " Transfer Op. Number: " << transferOp->getOperandNumber ()
@@ -834,8 +872,8 @@ void TransferNonSendableImpl::emitUseAfterTransferDiagnostics() {
834
872
// single we don't understand error if we do not find the require.
835
873
bool didEmitRequireNote = false ;
836
874
InstructionSet requireInstsUnique (function);
837
- RequireLiveness liveness (blockLivenessInfoGeneration, transferOp,
838
- blockLivenessInfo);
875
+ RequireLiveness liveness (blockLivenessInfoGeneration,
876
+ transferOp-> getOperand (), blockLivenessInfo);
839
877
++blockLivenessInfoGeneration;
840
878
liveness.process (requireInsts);
841
879
@@ -860,7 +898,8 @@ void TransferNonSendableImpl::emitUseAfterTransferDiagnostics() {
860
898
// tells the user to file a bug. This importantly ensures that we can
861
899
// guarantee that we always find the require if we successfully compile.
862
900
if (!didEmitRequireNote) {
863
- diagnoseError (transferOp, diag::regionbasedisolation_unknown_pattern);
901
+ diagnoseError (transferOp->getOperand (),
902
+ diag::regionbasedisolation_unknown_pattern);
864
903
continue ;
865
904
}
866
905
@@ -1213,20 +1252,20 @@ namespace {
1213
1252
struct DiagnosticEvaluator final
1214
1253
: PartitionOpEvaluatorBaseImpl<DiagnosticEvaluator> {
1215
1254
RegionAnalysisFunctionInfo *info;
1216
- SmallFrozenMultiMap<Operand * , SILInstruction *, 8 >
1255
+ SmallFrozenMultiMap<TransferringOperandRef , SILInstruction *, 8 >
1217
1256
&transferOpToRequireInstMultiMap;
1218
1257
1219
1258
// / First value is the operand that was transferred... second value is the
1220
1259
// / non-transferrable value in the same region as that value. The second value
1221
1260
// / is what is non-transferrable.
1222
1261
SmallVectorImpl<TransferredNonTransferrableInfo> &transferredNonTransferrable;
1223
1262
1224
- DiagnosticEvaluator (Partition &workingPartition,
1225
- RegionAnalysisFunctionInfo *info,
1226
- SmallFrozenMultiMap<Operand * , SILInstruction *, 8 >
1227
- &transferOpToRequireInstMultiMap,
1228
- SmallVectorImpl<TransferredNonTransferrableInfo>
1229
- &transferredNonTransferrable)
1263
+ DiagnosticEvaluator (
1264
+ Partition &workingPartition, RegionAnalysisFunctionInfo *info,
1265
+ SmallFrozenMultiMap<TransferringOperandRef , SILInstruction *, 8 >
1266
+ &transferOpToRequireInstMultiMap,
1267
+ SmallVectorImpl<TransferredNonTransferrableInfo>
1268
+ &transferredNonTransferrable)
1230
1269
: PartitionOpEvaluatorBaseImpl(workingPartition,
1231
1270
info->getOperandSetFactory ()),
1232
1271
info(info),
@@ -1261,7 +1300,7 @@ struct DiagnosticEvaluator final
1261
1300
<< " ID: %%" << transferredVal << " \n "
1262
1301
<< " Rep: " << *rep << " Transferring Op Num: "
1263
1302
<< transferringOp->getOperand ()->getOperandNumber () << ' \n ' );
1264
- transferOpToRequireInstMultiMap.insert (transferringOp-> getOperand () ,
1303
+ transferOpToRequireInstMultiMap.insert ({ transferringOp} ,
1265
1304
partitionOp.getSourceInst ());
1266
1305
}
1267
1306
0 commit comments