@@ -1059,6 +1059,10 @@ void ElementUseCollector::collectClassSelfUses() {
1059
1059
return ;
1060
1060
}
1061
1061
1062
+ // The number of stores of the initial 'self' argument into the self box
1063
+ // that we saw.
1064
+ unsigned StoresOfArgumentToSelf = 0 ;
1065
+
1062
1066
// Okay, given that we have a proper setup, we walk the use chains of the self
1063
1067
// box to find any accesses to it. The possible uses are one of:
1064
1068
//
@@ -1076,9 +1080,12 @@ void ElementUseCollector::collectClassSelfUses() {
1076
1080
if (Op->getOperandNumber () == 1 ) {
1077
1081
// The initial store of 'self' into the box at the start of the
1078
1082
// 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++;
1081
1086
continue ;
1087
+ }
1088
+ }
1082
1089
1083
1090
// A store of a load from the box is ignored.
1084
1091
// FIXME: SILGen should not emit these.
@@ -1121,6 +1128,9 @@ void ElementUseCollector::collectClassSelfUses() {
1121
1128
// and super.init must be called.
1122
1129
trackUse (DIMemoryUse (User, DIUseKind::Load, 0 , TheMemory.NumElements ));
1123
1130
}
1131
+
1132
+ assert (StoresOfArgumentToSelf == 1 &&
1133
+ " The 'self' argument should have been stored into the box exactly once" );
1124
1134
}
1125
1135
1126
1136
static bool isSuperInitUse (SILInstruction *User) {
@@ -1430,6 +1440,10 @@ void DelegatingInitElementUseCollector::collectClassInitSelfUses() {
1430
1440
assert (TheMemory.NumElements == 1 && " delegating inits only have 1 bit" );
1431
1441
auto *MUI = cast<MarkUninitializedInst>(TheMemory.MemoryInst );
1432
1442
1443
+ // The number of stores of the initial 'self' argument into the self box
1444
+ // that we saw.
1445
+ unsigned StoresOfArgumentToSelf = 0 ;
1446
+
1433
1447
// We walk the use chains of the self MUI to find any accesses to it. The
1434
1448
// possible uses are:
1435
1449
// 1) The initialization store.
@@ -1451,9 +1465,12 @@ void DelegatingInitElementUseCollector::collectClassInitSelfUses() {
1451
1465
if (Op->getOperandNumber () == 1 ) {
1452
1466
// The initial store of 'self' into the box at the start of the
1453
1467
// 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++;
1456
1471
continue ;
1472
+ }
1473
+ }
1457
1474
1458
1475
// A store of a load from the box is ignored.
1459
1476
// FIXME: SILGen should not emit these.
@@ -1524,6 +1541,14 @@ void DelegatingInitElementUseCollector::collectClassInitSelfUses() {
1524
1541
UseInfo.trackUse (DIMemoryUse (User, DIUseKind::Escape, 0 , 1 ));
1525
1542
}
1526
1543
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
+
1527
1552
// The MUI must be used on an alloc_box or alloc_stack instruction. If we have
1528
1553
// an alloc_stack, there is nothing further to do.
1529
1554
if (isa<AllocStackInst>(MUI->getOperand ()))
0 commit comments