@@ -2405,7 +2405,7 @@ emitAddressOnlyInitialization(VarDecl *dest, SILValue value) {
24052405
24062406// / Emit all the shared case statements.
24072407void PatternMatchEmission::emitSharedCaseBlocks () {
2408- for (auto &entry: SharedCases) {
2408+ for (auto &entry : SharedCases) {
24092409 CaseStmt *caseBlock = entry.first ;
24102410 SILBasicBlock *caseBB = entry.second .first ;
24112411 bool hasFallthroughTo = entry.second .second ;
@@ -2439,64 +2439,73 @@ void PatternMatchEmission::emitSharedCaseBlocks() {
24392439 // Then emit the case body into the caseBB.
24402440 SGF.B .setInsertionPoint (caseBB);
24412441 }
2442-
2442+
2443+ // Make sure that before/after we emit the case body we have emitted all
2444+ // cleanups we created within.
24432445 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+ }
24442454
24452455 // If we have a shared case with bound decls, then the 0th pattern has the
24462456 // 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 ;
24812465
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);
25002509 }
25012510}
25022511
0 commit comments