@@ -435,30 +435,15 @@ static SILValue findUnderlyingObject(SILValue Value) {
435
435
static AccessedStorage findAccessedStorage (SILValue Source) {
436
436
SILValue Iter = Source;
437
437
while (true ) {
438
- // Inductive cases: look through operand to find ultimate source.
439
- if (auto *PBI = dyn_cast<ProjectBoxInst>(Iter)) {
440
- Iter = PBI->getOperand ();
441
- continue ;
442
- }
443
-
444
- if (auto *CVI = dyn_cast<CopyValueInst>(Iter)) {
445
- Iter = CVI->getOperand ();
446
- continue ;
447
- }
448
-
449
- if (auto *MII = dyn_cast<MarkUninitializedInst>(Iter)) {
450
- Iter = MII->getOperand ();
451
- continue ;
452
- }
453
-
454
- // Base cases: make sure ultimate source is recognized.
438
+ // Base case for globals: make sure ultimate source is recognized.
455
439
if (auto *GAI = dyn_cast<GlobalAddrInst>(Iter)) {
456
440
return AccessedStorage (GAI->getReferencedGlobal ());
457
441
}
458
442
443
+ // Base case for class objects.
459
444
if (auto *REA = dyn_cast<RefElementAddrInst>(Iter)) {
460
445
// Do a best-effort to find the identity of the object being projected
461
- // from. It is OK to unsound here (i.e., miss when two ref_element_addrs
446
+ // from. It is OK to be unsound here (i.e. miss when two ref_element_addrs
462
447
// actually refer the same address) because these will be dynamically
463
448
// checked.
464
449
SILValue Object = findUnderlyingObject (REA->getOperand ());
@@ -467,18 +452,50 @@ static AccessedStorage findAccessedStorage(SILValue Source) {
467
452
return AccessedStorage (AccessedStorageKind::ClassProperty, OP);
468
453
}
469
454
470
- if (isa<AllocBoxInst>(Iter) || isa<BeginAccessInst>(Iter) ||
471
- isa<SILFunctionArgument>(Iter)) {
472
- // Treat the instruction itself as the identity of the storage being
473
- // being accessed.
455
+ switch (Iter->getKind ()) {
456
+ // Inductive cases: look through operand to find ultimate source.
457
+ case ValueKind::ProjectBoxInst:
458
+ case ValueKind::CopyValueInst:
459
+ case ValueKind::MarkUninitializedInst:
460
+ case ValueKind::UncheckedAddrCastInst:
461
+ // Inlined access to subobjects.
462
+ case ValueKind::StructElementAddrInst:
463
+ case ValueKind::TupleElementAddrInst:
464
+ case ValueKind::UncheckedTakeEnumDataAddrInst:
465
+ case ValueKind::RefTailAddrInst:
466
+ case ValueKind::TailAddrInst:
467
+ case ValueKind::IndexAddrInst:
468
+ Iter = cast<SILInstruction>(Iter)->getOperand (0 );
469
+ continue ;
470
+
471
+ // Base address producers.
472
+ case ValueKind::AllocBoxInst:
473
+ // An AllocBox is a fully identified memory location.
474
+ case ValueKind::AllocStackInst:
475
+ // An AllocStack is a fully identified memory location, which may occur
476
+ // after inlining code already subjected to stack promotion.
477
+ case ValueKind::BeginAccessInst:
478
+ // The current access is nested within another access.
479
+ // View the outer access as a separate location because nested accesses do
480
+ // not conflict with each other.
481
+ case ValueKind::SILFunctionArgument:
482
+ // A function argument is effectively a nested access, enforced
483
+ // independently in the caller and callee.
484
+ case ValueKind::PointerToAddressInst:
485
+ // An addressor provides access to a global or class property via a
486
+ // RawPointer. Calling the addressor casts that raw pointer to an address.
474
487
return AccessedStorage (Iter);
475
- }
476
488
477
- // For now we're still allowing arbitrary addresses here. Once
478
- // we start doing a best-effort static check for dynamically-enforced
479
- // accesses we should lock this down to only recognized sources.
480
- assert (Iter->getType ().isAddress () || Iter->getType ().is <SILBoxType>());
481
- return AccessedStorage (Iter);
489
+ // Unsupported address producers.
490
+ // Initialization is always local.
491
+ case ValueKind::InitEnumDataAddrInst:
492
+ case ValueKind::InitExistentialAddrInst:
493
+ // Accessing an existential value requires a cast.
494
+ case ValueKind::OpenExistentialAddrInst:
495
+ default :
496
+ DEBUG (llvm::dbgs () << " Bad memory access source: " << Iter);
497
+ llvm_unreachable (" Unexpected access source." );
498
+ }
482
499
}
483
500
}
484
501
0 commit comments