@@ -290,13 +290,13 @@ class DestroyLocalVariable : public Cleanup {
290290namespace {
291291// / Cleanup to destroy an uninitialized local variable.
292292class DeallocateUninitializedLocalVariable : public Cleanup {
293- VarDecl *Var ;
293+ SILValue Box ;
294294public:
295- DeallocateUninitializedLocalVariable (VarDecl *var ) : Var(var ) {}
295+ DeallocateUninitializedLocalVariable (SILValue box ) : Box(box ) {}
296296
297297 void emit (SILGenFunction &SGF, CleanupLocation l,
298298 ForUnwind_t forUnwind) override {
299- SGF.deallocateUninitializedLocalVariable (l, Var );
299+ SGF.B . createDeallocBox (l, Box );
300300 }
301301
302302 void dump (SILGenFunction &) const override {
@@ -315,7 +315,12 @@ namespace {
315315class LocalVariableInitialization : public SingleBufferInitialization {
316316 // / The local variable decl being initialized.
317317 VarDecl *decl;
318- SILGenFunction &SGF;
318+
319+ // / The alloc_box instruction.
320+ SILValue Box;
321+
322+ // / The projected address.
323+ SILValue Addr;
319324
320325 // / The cleanup we pushed to deallocate the local variable before it
321326 // / gets initialized.
@@ -332,7 +337,7 @@ class LocalVariableInitialization : public SingleBufferInitialization {
332337 LocalVariableInitialization (VarDecl *decl,
333338 Optional<MarkUninitializedInst::Kind> kind,
334339 uint16_t ArgNo, SILGenFunction &SGF)
335- : decl(decl), SGF(SGF) {
340+ : decl(decl) {
336341 assert (decl->getDeclContext ()->isLocalContext () &&
337342 " can't emit a local var for a non-local var decl" );
338343 assert (decl->hasStorage () && " can't emit storage for a computed variable" );
@@ -348,26 +353,24 @@ class LocalVariableInitialization : public SingleBufferInitialization {
348353 // The variable may have its lifetime extended by a closure, heap-allocate
349354 // it using a box.
350355 SILDebugVariable DbgVar (decl->isLet (), ArgNo);
351- SILValue allocBox = SGF.B .createAllocBox (decl, boxType, DbgVar);
356+ Box = SGF.B .createAllocBox (decl, boxType, DbgVar);
352357
353358 // Mark the memory as uninitialized, so DI will track it for us.
354359 if (kind)
355- allocBox = SGF.B .createMarkUninitialized (decl, allocBox , kind.getValue ());
360+ Box = SGF.B .createMarkUninitialized (decl, Box , kind.getValue ());
356361
357- SILValue addr = SGF.B .createProjectBox (decl, allocBox, 0 );
358-
359- // / Remember that this is the memory location that we're emitting the
360- // / decl to.
361- SGF.VarLocs [decl] = SILGenFunction::VarLoc::get (addr, allocBox);
362+ Addr = SGF.B .createProjectBox (decl, Box, 0 );
362363
363364 // Push a cleanup to destroy the local variable. This has to be
364365 // inactive until the variable is initialized.
365366 SGF.Cleanups .pushCleanupInState <DestroyLocalVariable>(CleanupState::Dormant,
366367 decl);
367368 ReleaseCleanup = SGF.Cleanups .getTopCleanup ();
368369
369- // Push a cleanup to deallocate the local variable.
370- SGF.Cleanups .pushCleanup <DeallocateUninitializedLocalVariable>(decl);
370+ // Push a cleanup to deallocate the local variable. This references the
371+ // box directly since it might be activated before we update
372+ // SGF.VarLocs.
373+ SGF.Cleanups .pushCleanup <DeallocateUninitializedLocalVariable>(Box);
371374 DeallocCleanup = SGF.Cleanups .getTopCleanup ();
372375 }
373376
@@ -376,8 +379,7 @@ class LocalVariableInitialization : public SingleBufferInitialization {
376379 }
377380
378381 SILValue getAddress () const {
379- assert (SGF.VarLocs .count (decl) && " did not emit var?!" );
380- return SGF.VarLocs [decl].value ;
382+ return Addr;
381383 }
382384
383385 SILValue getAddressForInPlaceInitialization (SILGenFunction &SGF,
@@ -394,6 +396,11 @@ class LocalVariableInitialization : public SingleBufferInitialization {
394396 }
395397
396398 void finishInitialization (SILGenFunction &SGF) override {
399+ // / Remember that this is the memory location that we've emitted the
400+ // / decl to.
401+ assert (SGF.VarLocs .count (decl) == 0 && " Already emitted the local?" );
402+ SGF.VarLocs [decl] = SILGenFunction::VarLoc::get (Addr, Box);
403+
397404 SingleBufferInitialization::finishInitialization (SGF);
398405 assert (!DidFinish &&
399406 " called LocalVariableInitialization::finishInitialization twice!" );
@@ -1688,21 +1695,4 @@ void SILGenFunction::destroyLocalVariable(SILLocation silLoc, VarDecl *vd) {
16881695 B.emitDestroyValueOperation (silLoc, Val);
16891696 else
16901697 B.createDestroyAddr (silLoc, Val);
1691- }
1692-
1693- void SILGenFunction::deallocateUninitializedLocalVariable (SILLocation silLoc,
1694- VarDecl *vd) {
1695- assert (vd->getDeclContext ()->isLocalContext () &&
1696- " can't emit a local var for a non-local var decl" );
1697- assert (vd->hasStorage () && " can't emit storage for a computed variable" );
1698-
1699- assert (VarLocs.count (vd) && " var decl wasn't emitted?!" );
1700-
1701- auto loc = VarLocs[vd];
1702-
1703- // Ignore let values captured without a memory location.
1704- if (!loc.value ->getType ().isAddress ()) return ;
1705-
1706- assert (loc.box && " captured var should have been given a box" );
1707- B.createDeallocBox (silLoc, loc.box );
1708- }
1698+ }
0 commit comments