Skip to content

Commit ca7d186

Browse files
authored
Merge pull request #14394 from jckarter/class-init-writeback-di
DefiniteInitialization: Storing back to the 'self' box in a class init is OK.
2 parents a49f175 + 6e9a428 commit ca7d186

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,8 +1128,14 @@ void ElementUseCollector::collectClassSelfUses() {
11281128
}
11291129

11301130
// A store of a load from the box is ignored.
1131-
// FIXME: SILGen should not emit these.
1132-
if (auto *LI = dyn_cast<LoadInst>(SI->getSrc()))
1131+
// SILGen emits these if delegation to another initializer was
1132+
// interrupted before the initializer was called.
1133+
SILValue src = SI->getSrc();
1134+
// Look through conversions.
1135+
while (auto conversion = dyn_cast<ConversionInst>(src))
1136+
src = conversion->getConverted();
1137+
1138+
if (auto *LI = dyn_cast<LoadInst>(src))
11331139
if (LI->getOperand() == MUI)
11341140
continue;
11351141

@@ -1503,7 +1509,7 @@ void DelegatingInitElementUseCollector::collectClassInitSelfUses() {
15031509
// Stores to self.
15041510
if (auto *SI = dyn_cast<StoreInst>(User)) {
15051511
if (Op->getOperandNumber() == 1) {
1506-
// The initial store of 'self' into the box at the start of the
1512+
// A store of 'self' into the box at the start of the
15071513
// function. Ignore it.
15081514
if (auto *Arg = dyn_cast<SILArgument>(SI->getSrc())) {
15091515
if (Arg->getParent() == MUI->getParent()) {
@@ -1513,8 +1519,14 @@ void DelegatingInitElementUseCollector::collectClassInitSelfUses() {
15131519
}
15141520

15151521
// A store of a load from the box is ignored.
1516-
// FIXME: SILGen should not emit these.
1517-
if (auto *LI = dyn_cast<LoadInst>(SI->getSrc()))
1522+
// SILGen emits these if delegation to another initializer was
1523+
// interrupted before the initializer was called.
1524+
SILValue src = SI->getSrc();
1525+
// Look through conversions.
1526+
while (auto conversion = dyn_cast<ConversionInst>(src))
1527+
src = conversion->getConverted();
1528+
1529+
if (auto *LI = dyn_cast<LoadInst>(src))
15181530
if (LI->getOperand() == MUI)
15191531
continue;
15201532

lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1636,7 +1636,14 @@ void LifetimeChecker::handleLoadUseFailure(const DIMemoryUse &Use,
16361636
bool SuperInitDone,
16371637
bool FailedSelfUse) {
16381638
SILInstruction *Inst = Use.Inst;
1639-
1639+
1640+
// Stores back to the 'self' box are OK.
1641+
if (auto store = dyn_cast<StoreInst>(Inst)) {
1642+
if (store->getDest() == TheMemory.MemoryInst
1643+
&& TheMemory.isClassInitSelf())
1644+
return;
1645+
}
1646+
16401647
if (FailedSelfUse) {
16411648
emitSelfConsumedDiagnostic(Inst);
16421649
return;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %target-swift-frontend -emit-sil -verify %s
2+
3+
class Y: X {
4+
required init(_: Z) throws {
5+
try super.init(Z())
6+
}
7+
}
8+
class Z { init() throws {} }
9+
10+
class X {
11+
required init(_: Z) throws {}
12+
}

0 commit comments

Comments
 (0)