@@ -2405,7 +2405,7 @@ emitAddressOnlyInitialization(VarDecl *dest, SILValue value) {
2405
2405
2406
2406
// / Emit all the shared case statements.
2407
2407
void PatternMatchEmission::emitSharedCaseBlocks () {
2408
- for (auto &entry: SharedCases) {
2408
+ for (auto &entry : SharedCases) {
2409
2409
CaseStmt *caseBlock = entry.first ;
2410
2410
SILBasicBlock *caseBB = entry.second .first ;
2411
2411
bool hasFallthroughTo = entry.second .second ;
@@ -2439,64 +2439,73 @@ void PatternMatchEmission::emitSharedCaseBlocks() {
2439
2439
// Then emit the case body into the caseBB.
2440
2440
SGF.B .setInsertionPoint (caseBB);
2441
2441
}
2442
-
2442
+
2443
+ // Make sure that before/after we emit the case body we have emitted all
2444
+ // cleanups we created within.
2443
2445
assert (SGF.getCleanupsDepth () == PatternMatchStmtDepth);
2446
+ SWIFT_DEFER { assert (SGF.getCleanupsDepth () == PatternMatchStmtDepth); };
2447
+
2448
+ // If we do not have any bound decls, just emit the case body since we do
2449
+ // not need to setup any var locs.
2450
+ if (!caseBlock->hasBoundDecls ()) {
2451
+ emitCaseBody (caseBlock);
2452
+ continue ;
2453
+ }
2444
2454
2445
2455
// If we have a shared case with bound decls, then the 0th pattern has the
2446
2456
// order of variables that are the incoming BB arguments. Setup the VarLocs
2447
- // to point to the incoming args and setup initialization so any args needing
2448
- // cleanup will get that as well.
2449
- if (caseBlock->hasBoundDecls ()) {
2450
- Scope scope (SGF.Cleanups , CleanupLocation (caseBlock));
2451
- auto pattern = caseBlock->getCaseLabelItems ()[0 ].getPattern ();
2452
- unsigned argIndex = 0 ;
2453
- pattern->forEachVariable ([&](VarDecl *V) {
2454
- if (!V->hasName ())
2455
- return ;
2456
-
2457
- SILType ty = SGF.getLoweredType (V->getType ());
2458
-
2459
- // Initialize mv at +1. We always pass values in at +1 for today into
2460
- // shared blocks.
2461
- ManagedValue mv;
2462
- if (ty.isAddressOnly (SGF.F .getModule ())) {
2463
- // There's no basic block argument, since we don't allow basic blocks
2464
- // to have address arguments.
2465
- //
2466
- // Instead, we map the variable to a temporary alloc_stack in
2467
- // emitAddressOnlyAllocations(), and store into it at each
2468
- // predecessor block.
2469
- //
2470
- // There's nothing to do here, since the value should already have
2471
- // been initialized on entry.
2472
- auto found = Temporaries.find (V);
2473
- assert (found != Temporaries.end ());
2474
- mv = SGF.emitManagedRValueWithCleanup (found->second );
2475
- } else {
2476
- SILValue arg = caseBB->getArgument (argIndex++);
2477
- assert (arg.getOwnershipKind () == ValueOwnershipKind::Owned ||
2478
- arg.getOwnershipKind () == ValueOwnershipKind::Any);
2479
- mv = SGF.emitManagedRValueWithCleanup (arg);
2480
- }
2457
+ // to point to the incoming args and setup initialization so any args
2458
+ // needing cleanup will get that as well.
2459
+ Scope scope (SGF.Cleanups , CleanupLocation (caseBlock));
2460
+ auto pattern = caseBlock->getCaseLabelItems ()[0 ].getPattern ();
2461
+ unsigned argIndex = 0 ;
2462
+ pattern->forEachVariable ([&](VarDecl *V) {
2463
+ if (!V->hasName ())
2464
+ return ;
2481
2465
2482
- if (V->isLet ()) {
2483
- // Just emit a let and leave the cleanup alone.
2484
- SGF.VarLocs [V].value = mv.getValue ();
2485
- } else {
2486
- // The pattern variables were all emitted as lets and one got passed in,
2487
- // now we finally alloc a box for the var and forward in the chosen value.
2488
- SGF.VarLocs .erase (V);
2489
- auto newVar = SGF.emitInitializationForVarDecl (V, V->isLet ());
2490
- newVar->copyOrInitValueInto (SGF, V, mv, /* isInit*/ true );
2491
- newVar->finishInitialization (SGF);
2492
- }
2493
- });
2494
- emitCaseBody (caseBlock);
2495
- } else {
2496
- emitCaseBody (caseBlock);
2497
- }
2498
-
2499
- assert (SGF.getCleanupsDepth () == PatternMatchStmtDepth);
2466
+ SILType ty = SGF.getLoweredType (V->getType ());
2467
+
2468
+ // Initialize mv at +1. We always pass values in at +1 for today into
2469
+ // shared blocks.
2470
+ ManagedValue mv;
2471
+ if (ty.isAddressOnly (SGF.F .getModule ())) {
2472
+ // There's no basic block argument, since we don't allow basic blocks
2473
+ // to have address arguments.
2474
+ //
2475
+ // Instead, we map the variable to a temporary alloc_stack in
2476
+ // emitAddressOnlyAllocations(), and store into it at each
2477
+ // predecessor block.
2478
+ //
2479
+ // There's nothing to do here, since the value should already have
2480
+ // been initialized on entry.
2481
+ auto found = Temporaries.find (V);
2482
+ assert (found != Temporaries.end ());
2483
+ mv = SGF.emitManagedRValueWithCleanup (found->second );
2484
+ } else {
2485
+ SILValue arg = caseBB->getArgument (argIndex++);
2486
+ assert (arg.getOwnershipKind () == ValueOwnershipKind::Owned ||
2487
+ arg.getOwnershipKind () == ValueOwnershipKind::Any);
2488
+ mv = SGF.emitManagedRValueWithCleanup (arg);
2489
+ }
2490
+
2491
+ if (V->isLet ()) {
2492
+ // Just emit a let and leave the cleanup alone.
2493
+ SGF.VarLocs [V].value = mv.getValue ();
2494
+ return ;
2495
+ }
2496
+
2497
+ // Otherwise, the pattern variables were all emitted as lets and one got
2498
+ // passed in. Since we have a var, alloc a box for the var and forward in
2499
+ // the chosen value.
2500
+ SGF.VarLocs .erase (V);
2501
+ auto newVar = SGF.emitInitializationForVarDecl (V, V->isLet ());
2502
+ newVar->copyOrInitValueInto (SGF, V, mv, /* isInit*/ true );
2503
+ newVar->finishInitialization (SGF);
2504
+ });
2505
+
2506
+ // Now that we have setup all of the VarLocs correctly, emit the shared case
2507
+ // body.
2508
+ emitCaseBody (caseBlock);
2500
2509
}
2501
2510
}
2502
2511
0 commit comments