[silgen] When pushing an RValue through a scope, use dealloc_box on any boxes we create instead of destroy_value.

It is only safe to perform a destroy_value on an alloc_box that contains an
initialized value. We preserve the original cleanups for the value we are
pushing through the scope implying that the box will not contain an initialized
value when its lifetime ends (just like an alloc_stack). Thus we must use
dealloc_box here.

The surprising thing about tracking down this error is that I was not hitting
any memory issues at -Onone. Instead what was happening was that at -O, we were
miscompiling (creating non-dominating uses of SSA values) in the face of an
address being taken twice.

This does not seem to hit any SILGen tests today (I hit this when testing a
patch I am trying to land today).

rdar://31521023
This commit is contained in:
Michael Gottesman
2017-09-03 17:49:33 -07:00
parent c1e77bf893
commit dc8b1c2c3a
3 changed files with 12 additions and 6 deletions

View File

@@ -3617,9 +3617,9 @@ public:
};
} // end anonymous namespace
static CleanupHandle enterDeallocBoxCleanup(SILGenFunction &SGF, SILValue box) {
SGF.Cleanups.pushCleanup<DeallocateUninitializedBox>(box);
return SGF.Cleanups.getTopCleanup();
CleanupHandle SILGenFunction::enterDeallocBoxCleanup(SILValue box) {
Cleanups.pushCleanup<DeallocateUninitializedBox>(box);
return Cleanups.getTopCleanup();
}
/// This is an initialization for a box.
@@ -3706,7 +3706,7 @@ ManagedValue SILGenFunction::emitInjectEnum(SILLocation loc,
CleanupHandle initCleanup = enterDestroyCleanup(box);
Cleanups.setCleanupState(initCleanup, CleanupState::Dormant);
CleanupHandle uninitCleanup = enterDeallocBoxCleanup(*this, box);
CleanupHandle uninitCleanup = enterDeallocBoxCleanup(box);
BoxInitialization dest(box, addr, uninitCleanup, initCleanup);