@@ -497,6 +497,8 @@ namespace {
497
497
unsigned BaseEltNo);
498
498
void collectStructElementUses (StructElementAddrInst *SEAI,
499
499
unsigned BaseEltNo);
500
+ void collectDelegatingClassInitSelfLoadUses (MarkUninitializedInst *MUI,
501
+ LoadInst *LI);
500
502
};
501
503
} // end anonymous namespace
502
504
@@ -1287,6 +1289,89 @@ collectClassSelfUses(SILValue ClassPointer, SILType MemorySILType,
1287
1289
}
1288
1290
}
1289
1291
1292
+ void ElementUseCollector::collectDelegatingClassInitSelfLoadUses (
1293
+ MarkUninitializedInst *MUI, LoadInst *LI) {
1294
+
1295
+ // If we have a load, then this is a use of the box. Look at the uses of
1296
+ // the load to find out more information.
1297
+ for (auto UI : LI->getUses ()) {
1298
+ auto *User = UI->getUser ();
1299
+
1300
+ // super_method always looks at the metatype for the class, not at any of
1301
+ // its stored properties, so it doesn't have any DI requirements.
1302
+ if (isa<SuperMethodInst>(User))
1303
+ continue ;
1304
+
1305
+ // We ignore retains of self.
1306
+ if (isa<StrongRetainInst>(User))
1307
+ continue ;
1308
+
1309
+ // A release of a load from the self box in a class delegating
1310
+ // initializer might be releasing an uninitialized self, which requires
1311
+ // special processing.
1312
+ if (isa<StrongReleaseInst>(User)) {
1313
+ Releases.push_back (User);
1314
+ continue ;
1315
+ }
1316
+
1317
+ if (auto *Method = dyn_cast<ClassMethodInst>(User)) {
1318
+ // class_method that refers to an initializing constructor is a method
1319
+ // lookup for delegation, which is ignored.
1320
+ if (Method->getMember ().kind == SILDeclRef::Kind::Initializer)
1321
+ continue ;
1322
+
1323
+ // / Returns true if \p Method used by an apply in a way that we know
1324
+ // / will cause us to emit a better error.
1325
+ if (shouldIgnoreClassMethodUseError (Method, LI))
1326
+ continue ;
1327
+ }
1328
+
1329
+ // If this is an upcast instruction, it is a conversion of self to the
1330
+ // base. This is either part of a super.init sequence, or a general
1331
+ // superclass access. We special case super.init calls since they are
1332
+ // part of the object lifecycle.
1333
+ if (auto *UCI = dyn_cast<UpcastInst>(User)) {
1334
+ if (auto *subAI = isSuperInitUse (UCI)) {
1335
+ Uses.push_back (DIMemoryUse (subAI, DIUseKind::SuperInit, 0 , 1 ));
1336
+ recordFailableInitCall (subAI);
1337
+ continue ;
1338
+ }
1339
+ }
1340
+
1341
+ // We only track two kinds of uses for delegating initializers:
1342
+ // calls to self.init, and "other", which we choose to model as escapes.
1343
+ // This intentionally ignores all stores, which (if they got emitted as
1344
+ // copyaddr or assigns) will eventually get rewritten as assignments
1345
+ // (not initializations), which is the right thing to do.
1346
+ DIUseKind Kind = DIUseKind::Escape;
1347
+
1348
+ // If this is an ApplyInst, check to see if this is part of a self.init
1349
+ // call in a delegating initializer.
1350
+ if (isa<FullApplySite>(User) && isSelfInitUse (User)) {
1351
+ Kind = DIUseKind::SelfInit;
1352
+ recordFailableInitCall (User);
1353
+ }
1354
+
1355
+ // If this load's value is being stored back into the delegating
1356
+ // mark_uninitialized buffer and it is a self init use, skip the
1357
+ // use. This is to handle situations where due to usage of a metatype to
1358
+ // allocate, we do not actually consume self.
1359
+ if (auto *SI = dyn_cast<StoreInst>(User)) {
1360
+ if (SI->getDest () == MUI && isSelfInitUse (User)) {
1361
+ continue ;
1362
+ }
1363
+ }
1364
+
1365
+ // A simple reference to "type(of:)" is always fine,
1366
+ // even if self is uninitialized.
1367
+ if (isa<ValueMetatypeInst>(User)) {
1368
+ continue ;
1369
+ }
1370
+
1371
+ Uses.push_back (DIMemoryUse (User, Kind, 0 , 1 ));
1372
+ }
1373
+ }
1374
+
1290
1375
// / collectDelegatingClassInitSelfUses - Collect uses of the self argument in a
1291
1376
// / delegating-constructor-for-a-class case.
1292
1377
void ElementUseCollector::collectDelegatingClassInitSelfUses () {
@@ -1314,21 +1399,20 @@ void ElementUseCollector::collectDelegatingClassInitSelfUses() {
1314
1399
1315
1400
// For class initializers, the assign into the self box may be
1316
1401
// captured as SelfInit or SuperInit elsewhere.
1317
- if (TheMemory.isClassInitSelf () &&
1318
- isa<AssignInst>(User) && UI->getOperandNumber () == 1 ) {
1402
+ if (TheMemory.isClassInitSelf () && isa<AssignInst>(User) &&
1403
+ UI->getOperandNumber () == 1 ) {
1319
1404
// If the source of the assignment is an application of a C
1320
1405
// function, there is no metatype argument, so treat the
1321
1406
// assignment to the self box as the initialization.
1322
1407
if (auto apply = dyn_cast<ApplyInst>(cast<AssignInst>(User)->getSrc ())) {
1323
1408
if (auto fn = apply->getCalleeFunction ()) {
1324
- if (fn->getRepresentation ()
1325
- == SILFunctionTypeRepresentation::CFunctionPointer) {
1409
+ if (fn->getRepresentation () ==
1410
+ SILFunctionTypeRepresentation::CFunctionPointer) {
1326
1411
Uses.push_back (DIMemoryUse (User, DIUseKind::SelfInit, 0 , 1 ));
1327
1412
continue ;
1328
1413
}
1329
1414
}
1330
1415
}
1331
-
1332
1416
}
1333
1417
1334
1418
// Stores *to* the allocation are writes. If the value being stored is a
@@ -1346,7 +1430,7 @@ void ElementUseCollector::collectDelegatingClassInitSelfUses() {
1346
1430
continue ;
1347
1431
}
1348
1432
}
1349
-
1433
+
1350
1434
if (auto *CAI = dyn_cast<CopyAddrInst>(User)) {
1351
1435
if (isSelfInitUse (CAI)) {
1352
1436
Uses.push_back (DIMemoryUse (User, DIUseKind::SelfInit, 0 , 1 ));
@@ -1356,85 +1440,7 @@ void ElementUseCollector::collectDelegatingClassInitSelfUses() {
1356
1440
1357
1441
// Loads of the box produce self, so collect uses from them.
1358
1442
if (auto *LI = dyn_cast<LoadInst>(User)) {
1359
-
1360
- // If we have a load, then this is a use of the box. Look at the uses of
1361
- // the load to find out more information.
1362
- for (auto UI : LI->getUses ()) {
1363
- auto *User = UI->getUser ();
1364
-
1365
- // super_method always looks at the metatype for the class, not at any of
1366
- // its stored properties, so it doesn't have any DI requirements.
1367
- if (isa<SuperMethodInst>(User))
1368
- continue ;
1369
-
1370
- // We ignore retains of self.
1371
- if (isa<StrongRetainInst>(User))
1372
- continue ;
1373
-
1374
- // A release of a load from the self box in a class delegating
1375
- // initializer might be releasing an uninitialized self, which requires
1376
- // special processing.
1377
- if (isa<StrongReleaseInst>(User)) {
1378
- Releases.push_back (User);
1379
- continue ;
1380
- }
1381
-
1382
- if (auto *Method = dyn_cast<ClassMethodInst>(User)) {
1383
- // class_method that refers to an initializing constructor is a method
1384
- // lookup for delegation, which is ignored.
1385
- if (Method->getMember ().kind == SILDeclRef::Kind::Initializer)
1386
- continue ;
1387
-
1388
- // / Returns true if \p Method used by an apply in a way that we know
1389
- // / will cause us to emit a better error.
1390
- if (shouldIgnoreClassMethodUseError (Method, LI))
1391
- continue ;
1392
- }
1393
-
1394
- // If this is an upcast instruction, it is a conversion of self to the
1395
- // base. This is either part of a super.init sequence, or a general
1396
- // superclass access. We special case super.init calls since they are
1397
- // part of the object lifecycle.
1398
- if (auto *UCI = dyn_cast<UpcastInst>(User)) {
1399
- if (auto *subAI = isSuperInitUse (UCI)) {
1400
- Uses.push_back (DIMemoryUse (subAI, DIUseKind::SuperInit, 0 , 1 ));
1401
- recordFailableInitCall (subAI);
1402
- continue ;
1403
- }
1404
- }
1405
-
1406
- // We only track two kinds of uses for delegating initializers:
1407
- // calls to self.init, and "other", which we choose to model as escapes.
1408
- // This intentionally ignores all stores, which (if they got emitted as
1409
- // copyaddr or assigns) will eventually get rewritten as assignments
1410
- // (not initializations), which is the right thing to do.
1411
- DIUseKind Kind = DIUseKind::Escape;
1412
-
1413
- // If this is an ApplyInst, check to see if this is part of a self.init
1414
- // call in a delegating initializer.
1415
- if (isa<FullApplySite>(User) && isSelfInitUse (User)) {
1416
- Kind = DIUseKind::SelfInit;
1417
- recordFailableInitCall (User);
1418
- }
1419
-
1420
- // If this load's value is being stored back into the delegating
1421
- // mark_uninitialized buffer and it is a self init use, skip the
1422
- // use. This is to handle situations where due to usage of a metatype to
1423
- // allocate, we do not actually consume self.
1424
- if (auto *SI = dyn_cast<StoreInst>(User)) {
1425
- if (SI->getDest () == MUI && isSelfInitUse (User)) {
1426
- continue ;
1427
- }
1428
- }
1429
-
1430
- // A simple reference to "type(of:)" is always fine,
1431
- // even if self is uninitialized.
1432
- if (isa<ValueMetatypeInst>(User)) {
1433
- continue ;
1434
- }
1435
-
1436
- Uses.push_back (DIMemoryUse (User, Kind, 0 , 1 ));
1437
- }
1443
+ collectDelegatingClassInitSelfLoadUses (MUI, LI);
1438
1444
continue ;
1439
1445
}
1440
1446
0 commit comments