DI: Track of initialization state of trivial fields in root class initializers

While we don't need to destroy these fields, we still need to know
when the class is _semantically_ fully initialized, since this will
determine if we're going to release the class, running the deinitializer,
or if we're going to deallocate the memory for the instance directly.
This commit is contained in:
Slava Pestov
2020-08-31 22:06:35 -04:00
parent e6249576ea
commit df0a8b3746
2 changed files with 19 additions and 2 deletions

View File

@@ -1072,7 +1072,13 @@ void LifetimeChecker::handleStoreUse(unsigned UseID) {
// it for later. Once we've collected all of the conditional init/assigns,
// we can insert a single control variable for the memory object for the
// whole function.
if (!Use.onlyTouchesTrivialElements(TheMemory))
//
// For root class initializers, we must keep track of initializations of
// trivial stored properties also, since we need to know when the object
// has been fully initialized when deciding if a strong_release should
// lower to a partial_dealloc_ref.
if (TheMemory.isRootClassSelf() ||
!Use.onlyTouchesTrivialElements(TheMemory))
HasConditionalInitAssign = true;
return;
}
@@ -2285,7 +2291,13 @@ SILValue LifetimeChecker::handleConditionalInitAssign() {
// If this ambiguous store is only of trivial types, then we don't need to
// do anything special. We don't even need keep the init bit for the
// element precise.
if (Use.onlyTouchesTrivialElements(TheMemory))
//
// For root class initializers, we must keep track of initializations of
// trivial stored properties also, since we need to know when the object
// has been fully initialized when deciding if a strong_release should
// lower to a partial_dealloc_ref.
if (!TheMemory.isRootClassSelf() &&
Use.onlyTouchesTrivialElements(TheMemory))
continue;
B.setInsertionPoint(Use.Inst);