Merge pull request #14395 from jckarter/class-init-writeback-di-4.1
[4.1] DefiniteInitialization: Storing back to the 'self' box in a class init is OK.
diff --git a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp b/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
index 19d4537..3e43c05 100644
--- a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
+++ b/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
@@ -1128,8 +1128,14 @@
}
// A store of a load from the box is ignored.
- // FIXME: SILGen should not emit these.
- if (auto *LI = dyn_cast<LoadInst>(SI->getSrc()))
+ // SILGen emits these if delegation to another initializer was
+ // interrupted before the initializer was called.
+ SILValue src = SI->getSrc();
+ // Look through conversions.
+ while (auto conversion = dyn_cast<ConversionInst>(src))
+ src = conversion->getConverted();
+
+ if (auto *LI = dyn_cast<LoadInst>(src))
if (LI->getOperand() == MUI)
continue;
@@ -1503,7 +1509,7 @@
// Stores to self.
if (auto *SI = dyn_cast<StoreInst>(User)) {
if (Op->getOperandNumber() == 1) {
- // The initial store of 'self' into the box at the start of the
+ // A store of 'self' into the box at the start of the
// function. Ignore it.
if (auto *Arg = dyn_cast<SILArgument>(SI->getSrc())) {
if (Arg->getParent() == MUI->getParent()) {
@@ -1513,8 +1519,14 @@
}
// A store of a load from the box is ignored.
- // FIXME: SILGen should not emit these.
- if (auto *LI = dyn_cast<LoadInst>(SI->getSrc()))
+ // SILGen emits these if delegation to another initializer was
+ // interrupted before the initializer was called.
+ SILValue src = SI->getSrc();
+ // Look through conversions.
+ while (auto conversion = dyn_cast<ConversionInst>(src))
+ src = conversion->getConverted();
+
+ if (auto *LI = dyn_cast<LoadInst>(src))
if (LI->getOperand() == MUI)
continue;
diff --git a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
index 48cdeac..2ed62e5 100644
--- a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
+++ b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
@@ -1636,7 +1636,14 @@
bool SuperInitDone,
bool FailedSelfUse) {
SILInstruction *Inst = Use.Inst;
-
+
+ // Stores back to the 'self' box are OK.
+ if (auto store = dyn_cast<StoreInst>(Inst)) {
+ if (store->getDest() == TheMemory.MemoryInst
+ && TheMemory.isClassInitSelf())
+ return;
+ }
+
if (FailedSelfUse) {
emitSelfConsumedDiagnostic(Inst);
return;
diff --git a/test/SILOptimizer/definite-init-try-in-self-init-argument.swift b/test/SILOptimizer/definite-init-try-in-self-init-argument.swift
new file mode 100644
index 0000000..ebbaf4a
--- /dev/null
+++ b/test/SILOptimizer/definite-init-try-in-self-init-argument.swift
@@ -0,0 +1,12 @@
+// RUN: %target-swift-frontend -emit-sil -verify %s
+
+class Y: X {
+ required init(_: Z) throws {
+ try super.init(Z())
+ }
+}
+class Z { init() throws {} }
+
+class X {
+ required init(_: Z) throws {}
+}