@@ -7083,8 +7083,8 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
70837083 struct BBState {
70847084 std::vector<SILValue> Stack;
70857085
7086- // / Contents: BeginAccessInst*, BeginApplyInst*.
7087- std::set<SILInstruction* > ActiveOps;
7086+ // / Contents: Results of BeginAccessInst*, BeginApplyInst*.
7087+ std::set<SILValue > ActiveOps;
70887088
70897089 CFGState CFG = Normal;
70907090
@@ -7237,19 +7237,16 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
72377237 }
72387238 }
72397239
7240- void handleScopeInst (SILInstruction & i) {
7241- if (!ActiveOps.insert (& i).second ) {
7240+ void handleScopeInst (SILValue i) {
7241+ if (!ActiveOps.insert (i).second ) {
72427242 verificationFailure (" operation was not ended before re-beginning it" ,
7243- & i, nullptr );
7243+ i, nullptr );
72447244 }
72457245 }
72467246
7247- void handleScopeEndingInst (SILInstruction &i) {
7248- if (auto beginOp = i.getOperand (0 )->getDefiningInstruction ()) {
7249- if (!ActiveOps.erase (beginOp)) {
7250- verificationFailure (" operation has already been ended" , &i,
7251- nullptr );
7252- }
7247+ void handleScopeEndingInst (const SILInstruction &i) {
7248+ if (!ActiveOps.erase (i.getOperand (0 ))) {
7249+ verificationFailure (" operation has already been ended" , &i, nullptr );
72537250 }
72547251 }
72557252 };
@@ -7263,31 +7260,40 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
72637260 };
72647261 };
72657262
7266- static bool isScopeInst (SILInstruction *i) {
7267- if (isa<BeginAccessInst>(i) ||
7268- isa<BeginApplyInst>(i) ||
7269- isa<StoreBorrowInst>(i)) {
7270- return true ;
7271- } else if (auto bi = dyn_cast<BuiltinInst>(i)) {
7263+ // / If this is a scope ending inst, return the result from the instruction
7264+ // / that provides the scoped value whose lifetime must be ended by some other
7265+ // / scope ending instruction.
7266+ static SILValue isScopeInst (SILInstruction *i) {
7267+ if (auto *bai = dyn_cast<BeginAccessInst>(i))
7268+ return bai;
7269+ if (auto *bai = dyn_cast<BeginApplyInst>(i))
7270+ return bai->getTokenResult ();
7271+ if (auto *sbi = dyn_cast<StoreBorrowInst>(i))
7272+ return sbi;
7273+
7274+ if (auto bi = dyn_cast<BuiltinInst>(i)) {
72727275 if (auto bk = bi->getBuiltinKind ()) {
72737276 switch (*bk) {
72747277 case BuiltinValueKind::StartAsyncLetWithLocalBuffer:
7275- return true ;
7278+ return bi-> getResult ( 0 ) ;
72767279
72777280 default :
7278- return false ;
7281+ return SILValue () ;
72797282 }
72807283 }
72817284 }
7282- return false ;
7285+
7286+ return SILValue ();
72837287 }
72847288
72857289 static bool isScopeEndingInst (SILInstruction *i) {
72867290 if (isa<EndAccessInst>(i) ||
72877291 isa<AbortApplyInst>(i) ||
72887292 isa<EndApplyInst>(i)) {
72897293 return true ;
7290- } else if (auto bi = dyn_cast<BuiltinInst>(i)) {
7294+ }
7295+
7296+ if (auto bi = dyn_cast<BuiltinInst>(i)) {
72917297 if (auto bk = bi->getBuiltinKind ()) {
72927298 switch (*bk) {
72937299 case BuiltinValueKind::FinishAsyncLet:
@@ -7359,10 +7365,12 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
73597365 state.Stack .push_back (i.getStackAllocation ());
73607366
73617367 // Also track begin_apply as a scope instruction.
7362- if (isa<BeginApplyInst>(i))
7363- state.handleScopeInst (i);
7368+ if (auto *bai = dyn_cast<BeginApplyInst>(&i)) {
7369+ state.handleScopeInst (bai->getStackAllocation ());
7370+ state.handleScopeInst (bai->getTokenResult ());
7371+ }
73647372 } else {
7365- state.handleScopeInst (i);
7373+ state.handleScopeInst (i. getStackAllocation () );
73667374 }
73677375 } else if (i.isDeallocatingStack ()) {
73687376 SILValue op = i.getOperand (0 );
@@ -7388,8 +7396,8 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
73887396 // failure.
73897397 });
73907398 }
7391- } else if (isScopeInst (&i)) {
7392- state.handleScopeInst (i );
7399+ } else if (auto scopeEndingValue = isScopeInst (&i)) {
7400+ state.handleScopeInst (scopeEndingValue );
73937401 } else if (isScopeEndingInst (&i)) {
73947402 state.handleScopeEndingInst (i);
73957403 } else if (auto *endBorrow = dyn_cast<EndBorrowInst>(&i)) {
0 commit comments