Skip to content

Commit 27cd40b

Browse files
committed
[ownership] When looking at an interior pointer's uses, look through store_borrow.
The store_borrow's result is a sub-interior pointer that ensures that any uses of the interior pointer are within the lifetime of the borrowed value that is being stored. But fundamentally this is just embedding lifetime ownership on def-use edges and once ossa is lowered the result is just the destination address. So it makes sense to include the uses of the result of the store_borrow as the dest's uses.
1 parent 9fe23a3 commit 27cd40b

File tree

2 files changed

+25
-8
lines changed

2 files changed

+25
-8
lines changed

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -707,13 +707,12 @@ bool InteriorPointerOperand::findTransitiveUsesForAddress(
707707
// and do not need to check transitive uses of.
708708
if (isa<LoadInst>(user) || isa<CopyAddrInst>(user) ||
709709
isIncidentalUse(user) || isa<StoreInst>(user) ||
710-
isa<StoreBorrowInst>(user) || isa<PartialApplyInst>(user) ||
711-
isa<DestroyAddrInst>(user) || isa<AssignInst>(user) ||
712-
isa<AddressToPointerInst>(user) || isa<YieldInst>(user) ||
713-
isa<LoadUnownedInst>(user) || isa<StoreUnownedInst>(user) ||
714-
isa<EndApplyInst>(user) || isa<LoadWeakInst>(user) ||
715-
isa<StoreWeakInst>(user) || isa<AssignByWrapperInst>(user) ||
716-
isa<BeginUnpairedAccessInst>(user) ||
710+
isa<PartialApplyInst>(user) || isa<DestroyAddrInst>(user) ||
711+
isa<AssignInst>(user) || isa<AddressToPointerInst>(user) ||
712+
isa<YieldInst>(user) || isa<LoadUnownedInst>(user) ||
713+
isa<StoreUnownedInst>(user) || isa<EndApplyInst>(user) ||
714+
isa<LoadWeakInst>(user) || isa<StoreWeakInst>(user) ||
715+
isa<AssignByWrapperInst>(user) || isa<BeginUnpairedAccessInst>(user) ||
717716
isa<EndUnpairedAccessInst>(user) || isa<WitnessMethodInst>(user) ||
718717
isa<SwitchEnumAddrInst>(user) || isa<CheckedCastAddrBranchInst>(user) ||
719718
isa<SelectEnumAddrInst>(user) || isa<InjectEnumAddrInst>(user)) {
@@ -726,7 +725,7 @@ bool InteriorPointerOperand::findTransitiveUsesForAddress(
726725
isa<OpenExistentialAddrInst>(user) ||
727726
isa<InitExistentialAddrInst>(user) || isa<InitEnumDataAddrInst>(user) ||
728727
isa<BeginAccessInst>(user) || isa<TailAddrInst>(user) ||
729-
isa<IndexAddrInst>(user) ||
728+
isa<IndexAddrInst>(user) || isa<StoreBorrowInst>(user) ||
730729
isa<UnconditionalCheckedCastAddrInst>(user) ||
731730
isa<UncheckedAddrCastInst>(user)) {
732731
for (SILValue r : user->getResults()) {

test/SIL/ownership-verifier/interior_pointer.sil

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,21 @@ bb0(%0 : @owned $Builtin.NativeObject):
118118
%9999 = tuple()
119119
return %9999 : $()
120120
}
121+
122+
// CHECK-LABEL: Error#: 0. Begin Error in Function: 'recursive_interior_pointer_error'
123+
// CHECK-NEXT: Found outside of lifetime use?!
124+
// CHECK-NEXT: Value: %2 = begin_borrow %0 : $KlassUser // users: %5, %3
125+
// CHECK-NEXT: Consuming User: end_borrow %2 : $KlassUser // id: %5
126+
// CHECK-NEXT: Non Consuming User: %7 = load [copy] %4 : $*Klass // user: %8
127+
// CHECK-NEXT: Block: bb0
128+
// CHECK: Error#: 0. End Error in Function: 'recursive_interior_pointer_error'
129+
sil [ossa] @recursive_interior_pointer_error : $@convention(thin) (@owned KlassUser, @guaranteed Klass) -> @owned Klass {
130+
bb0(%0 : @owned $KlassUser, %0a : @guaranteed $Klass):
131+
%1 = begin_borrow %0 : $KlassUser
132+
%2 = ref_tail_addr %1 : $KlassUser, $Klass
133+
%result = store_borrow %0a to %2 : $*Klass
134+
end_borrow %1 : $KlassUser
135+
destroy_value %0 : $KlassUser
136+
%3 = load [copy] %result : $*Klass
137+
return %3 : $Klass
138+
}

0 commit comments

Comments
 (0)