@@ -365,6 +365,10 @@ static void diagnoseExclusivityViolation(const AccessedStorage &Storage,
365
365
const BeginAccessInst *NewAccess,
366
366
ASTContext &Ctx) {
367
367
368
+ DEBUG (llvm::dbgs () << " Conflict on " << *PriorAccess
369
+ << " \n vs " << *NewAccess
370
+ << " \n in function " << *PriorAccess->getFunction ());
371
+
368
372
// Can't have a conflict if both accesses are reads.
369
373
assert (!(PriorAccess->getAccessKind () == SILAccessKind::Read &&
370
374
NewAccess->getAccessKind () == SILAccessKind::Read));
@@ -431,30 +435,15 @@ static SILValue findUnderlyingObject(SILValue Value) {
431
435
static AccessedStorage findAccessedStorage (SILValue Source) {
432
436
SILValue Iter = Source;
433
437
while (true ) {
434
- // Inductive cases: look through operand to find ultimate source.
435
- if (auto *PBI = dyn_cast<ProjectBoxInst>(Iter)) {
436
- Iter = PBI->getOperand ();
437
- continue ;
438
- }
439
-
440
- if (auto *CVI = dyn_cast<CopyValueInst>(Iter)) {
441
- Iter = CVI->getOperand ();
442
- continue ;
443
- }
444
-
445
- if (auto *MII = dyn_cast<MarkUninitializedInst>(Iter)) {
446
- Iter = MII->getOperand ();
447
- continue ;
448
- }
449
-
450
- // Base cases: make sure ultimate source is recognized.
438
+ // Base case for globals: make sure ultimate source is recognized.
451
439
if (auto *GAI = dyn_cast<GlobalAddrInst>(Iter)) {
452
440
return AccessedStorage (GAI->getReferencedGlobal ());
453
441
}
454
442
443
+ // Base case for class objects.
455
444
if (auto *REA = dyn_cast<RefElementAddrInst>(Iter)) {
456
445
// Do a best-effort to find the identity of the object being projected
457
- // 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
458
447
// actually refer the same address) because these will be dynamically
459
448
// checked.
460
449
SILValue Object = findUnderlyingObject (REA->getOperand ());
@@ -463,18 +452,50 @@ static AccessedStorage findAccessedStorage(SILValue Source) {
463
452
return AccessedStorage (AccessedStorageKind::ClassProperty, OP);
464
453
}
465
454
466
- if (isa<AllocBoxInst>(Iter) || isa<BeginAccessInst>(Iter) ||
467
- isa<SILFunctionArgument>(Iter)) {
468
- // Treat the instruction itself as the identity of the storage being
469
- // 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.
470
487
return AccessedStorage (Iter);
471
- }
472
488
473
- // For now we're still allowing arbitrary addresses here. Once
474
- // we start doing a best-effort static check for dynamically-enforced
475
- // accesses we should lock this down to only recognized sources.
476
- assert (Iter->getType ().isAddress () || Iter->getType ().is <SILBoxType>());
477
- 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
+ }
478
499
}
479
500
}
480
501
0 commit comments