@@ -7085,8 +7085,8 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
70857085 struct BBState {
70867086 std::vector<SILValue> Stack;
70877087
7088- // / Contents: BeginAccessInst*, BeginApplyInst*.
7089- std::set<SILInstruction* > ActiveOps;
7088+ // / Contents: Results of BeginAccessInst*, BeginApplyInst*.
7089+ std::set<SILValue > ActiveOps;
70907090
70917091 CFGState CFG = Normal;
70927092
@@ -7239,19 +7239,16 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
72397239 }
72407240 }
72417241
7242- void handleScopeInst (SILInstruction & i) {
7243- if (!ActiveOps.insert (& i).second ) {
7242+ void handleScopeInst (SILValue i) {
7243+ if (!ActiveOps.insert (i).second ) {
72447244 verificationFailure (" operation was not ended before re-beginning it" ,
7245- & i, nullptr );
7245+ i, nullptr );
72467246 }
72477247 }
72487248
7249- void handleScopeEndingInst (SILInstruction &i) {
7250- if (auto beginOp = i.getOperand (0 )->getDefiningInstruction ()) {
7251- if (!ActiveOps.erase (beginOp)) {
7252- verificationFailure (" operation has already been ended" , &i,
7253- nullptr );
7254- }
7249+ void handleScopeEndingInst (const SILInstruction &i) {
7250+ if (!ActiveOps.erase (i.getOperand (0 ))) {
7251+ verificationFailure (" operation has already been ended" , &i, nullptr );
72557252 }
72567253 }
72577254 };
@@ -7265,31 +7262,40 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
72657262 };
72667263 };
72677264
7268- static bool isScopeInst (SILInstruction *i) {
7269- if (isa<BeginAccessInst>(i) ||
7270- isa<BeginApplyInst>(i) ||
7271- isa<StoreBorrowInst>(i)) {
7272- return true ;
7273- } else if (auto bi = dyn_cast<BuiltinInst>(i)) {
7265+ // / If this is a scope ending inst, return the result from the instruction
7266+ // / that provides the scoped value whose lifetime must be ended by some other
7267+ // / scope ending instruction.
7268+ static SILValue isScopeInst (SILInstruction *i) {
7269+ if (auto *bai = dyn_cast<BeginAccessInst>(i))
7270+ return bai;
7271+ if (auto *bai = dyn_cast<BeginApplyInst>(i))
7272+ return bai->getTokenResult ();
7273+ if (auto *sbi = dyn_cast<StoreBorrowInst>(i))
7274+ return sbi;
7275+
7276+ if (auto bi = dyn_cast<BuiltinInst>(i)) {
72747277 if (auto bk = bi->getBuiltinKind ()) {
72757278 switch (*bk) {
72767279 case BuiltinValueKind::StartAsyncLetWithLocalBuffer:
7277- return true ;
7280+ return bi-> getResult ( 0 ) ;
72787281
72797282 default :
7280- return false ;
7283+ return SILValue () ;
72817284 }
72827285 }
72837286 }
7284- return false ;
7287+
7288+ return SILValue ();
72857289 }
72867290
72877291 static bool isScopeEndingInst (SILInstruction *i) {
72887292 if (isa<EndAccessInst>(i) ||
72897293 isa<AbortApplyInst>(i) ||
72907294 isa<EndApplyInst>(i)) {
72917295 return true ;
7292- } else if (auto bi = dyn_cast<BuiltinInst>(i)) {
7296+ }
7297+
7298+ if (auto bi = dyn_cast<BuiltinInst>(i)) {
72937299 if (auto bk = bi->getBuiltinKind ()) {
72947300 switch (*bk) {
72957301 case BuiltinValueKind::FinishAsyncLet:
@@ -7361,10 +7367,12 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
73617367 state.Stack .push_back (i.getStackAllocation ());
73627368
73637369 // Also track begin_apply as a scope instruction.
7364- if (isa<BeginApplyInst>(i))
7365- state.handleScopeInst (i);
7370+ if (auto *bai = dyn_cast<BeginApplyInst>(&i)) {
7371+ state.handleScopeInst (bai->getStackAllocation ());
7372+ state.handleScopeInst (bai->getTokenResult ());
7373+ }
73667374 } else {
7367- state.handleScopeInst (i);
7375+ state.handleScopeInst (i. getStackAllocation () );
73687376 }
73697377 } else if (i.isDeallocatingStack ()) {
73707378 SILValue op = i.getOperand (0 );
@@ -7390,8 +7398,8 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
73907398 // failure.
73917399 });
73927400 }
7393- } else if (isScopeInst (&i)) {
7394- state.handleScopeInst (i );
7401+ } else if (auto scopeEndingValue = isScopeInst (&i)) {
7402+ state.handleScopeInst (scopeEndingValue );
73957403 } else if (isScopeEndingInst (&i)) {
73967404 state.handleScopeEndingInst (i);
73977405 } else if (auto *endBorrow = dyn_cast<EndBorrowInst>(&i)) {
0 commit comments