Skip to content

Commit 224aabf

Browse files
committed
DI: Add an assertion tracking stores to the 'self' box
1 parent 062646e commit 224aabf

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,10 @@ void ElementUseCollector::collectClassSelfUses() {
10591059
return;
10601060
}
10611061

1062+
// The number of stores of the initial 'self' argument into the self box
1063+
// that we saw.
1064+
unsigned StoresOfArgumentToSelf = 0;
1065+
10621066
// Okay, given that we have a proper setup, we walk the use chains of the self
10631067
// box to find any accesses to it. The possible uses are one of:
10641068
//
@@ -1076,9 +1080,12 @@ void ElementUseCollector::collectClassSelfUses() {
10761080
if (Op->getOperandNumber() == 1) {
10771081
// The initial store of 'self' into the box at the start of the
10781082
// function. Ignore it.
1079-
if (auto *Arg = dyn_cast<SILArgument>(SI->getSrc()))
1080-
if (Arg->getParent() == MUI->getParent())
1083+
if (auto *Arg = dyn_cast<SILArgument>(SI->getSrc())) {
1084+
if (Arg->getParent() == MUI->getParent()) {
1085+
StoresOfArgumentToSelf++;
10811086
continue;
1087+
}
1088+
}
10821089

10831090
// A store of a load from the box is ignored.
10841091
// FIXME: SILGen should not emit these.
@@ -1121,6 +1128,9 @@ void ElementUseCollector::collectClassSelfUses() {
11211128
// and super.init must be called.
11221129
trackUse(DIMemoryUse(User, DIUseKind::Load, 0, TheMemory.NumElements));
11231130
}
1131+
1132+
assert(StoresOfArgumentToSelf == 1 &&
1133+
"The 'self' argument should have been stored into the box exactly once");
11241134
}
11251135

11261136
static bool isSuperInitUse(SILInstruction *User) {
@@ -1430,6 +1440,10 @@ void DelegatingInitElementUseCollector::collectClassInitSelfUses() {
14301440
assert(TheMemory.NumElements == 1 && "delegating inits only have 1 bit");
14311441
auto *MUI = cast<MarkUninitializedInst>(TheMemory.MemoryInst);
14321442

1443+
// The number of stores of the initial 'self' argument into the self box
1444+
// that we saw.
1445+
unsigned StoresOfArgumentToSelf = 0;
1446+
14331447
// We walk the use chains of the self MUI to find any accesses to it. The
14341448
// possible uses are:
14351449
// 1) The initialization store.
@@ -1451,9 +1465,12 @@ void DelegatingInitElementUseCollector::collectClassInitSelfUses() {
14511465
if (Op->getOperandNumber() == 1) {
14521466
// The initial store of 'self' into the box at the start of the
14531467
// function. Ignore it.
1454-
if (auto *Arg = dyn_cast<SILArgument>(SI->getSrc()))
1455-
if (Arg->getParent() == MUI->getParent())
1468+
if (auto *Arg = dyn_cast<SILArgument>(SI->getSrc())) {
1469+
if (Arg->getParent() == MUI->getParent()) {
1470+
StoresOfArgumentToSelf++;
14561471
continue;
1472+
}
1473+
}
14571474

14581475
// A store of a load from the box is ignored.
14591476
// FIXME: SILGen should not emit these.
@@ -1524,6 +1541,14 @@ void DelegatingInitElementUseCollector::collectClassInitSelfUses() {
15241541
UseInfo.trackUse(DIMemoryUse(User, DIUseKind::Escape, 0, 1));
15251542
}
15261543

1544+
if (TheMemory.isClassInitSelf()) {
1545+
assert(StoresOfArgumentToSelf == 1 &&
1546+
"The 'self' argument should have been stored into the box exactly once");
1547+
} else {
1548+
assert(StoresOfArgumentToSelf == 0 &&
1549+
"Initializing constructor for class-constrained protocol extension?");
1550+
}
1551+
15271552
// The MUI must be used on an alloc_box or alloc_stack instruction. If we have
15281553
// an alloc_stack, there is nothing further to do.
15291554
if (isa<AllocStackInst>(MUI->getOperand()))

test/SILOptimizer/definite_init_markuninitialized_delegatingself.sil

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,13 +203,14 @@ class MyClass3 {
203203
sil @selfinit_myclass3 : $@convention(thin) (@owned MyClass3) -> @owned MyClass3
204204

205205
// CHECK-LABEL: sil hidden @test_conditional_destroy_class_delegating_init
206-
sil hidden @test_conditional_destroy_class_delegating_init : $@convention(thin) (Builtin.Int1) -> () {
207-
bb0(%0 : @trivial $Builtin.Int1):
206+
sil hidden @test_conditional_destroy_class_delegating_init : $@convention(thin) (Builtin.Int1, @owned MyClass3) -> () {
207+
bb0(%0 : @trivial $Builtin.Int1, %1 : @owned $MyClass3):
208208
// CHECK: [[CONTROL:%[0-9]+]] = alloc_stack $Builtin.Int2
209209
// CHECK-NEXT: [[SELF_BOX:%[0-9]+]] = alloc_stack $MyClass3
210210

211211
%2 = alloc_stack $MyClass3
212212
%3 = mark_uninitialized [delegatingself] %2 : $*MyClass3
213+
store %1 to [init] %3 : $*MyClass3
213214

214215
// CHECK: cond_br %0, [[SUCCESS:bb[0-9]+]], [[EXIT:bb[0-9]+]]
215216
cond_br %0, bb1, bb2

0 commit comments

Comments
 (0)