Skip to content

Commit 7bc5c5e

Browse files
committed
SIL: Fix ownership verifier to handle some missing interior pointer projections
My upcoming SILGen change introduces more stores directly into the result of a ref_element_addr or struct_element_addr in some cases. Make sure we handle the failing combinations flagged by the ownership verifier.
1 parent 1de9668 commit 7bc5c5e

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-4
lines changed

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -543,16 +543,18 @@ bool InteriorPointerOperand::getImplicitUses(
543543
isa<BeginUnpairedAccessInst>(user) ||
544544
isa<EndUnpairedAccessInst>(user) || isa<WitnessMethodInst>(user) ||
545545
isa<SwitchEnumAddrInst>(user) || isa<CheckedCastAddrBranchInst>(user) ||
546-
isa<SelectEnumAddrInst>(user)) {
546+
isa<SelectEnumAddrInst>(user) || isa<InjectEnumAddrInst>(user)) {
547547
continue;
548548
}
549549

550550
// Then handle users that we need to look at transitive uses of.
551551
if (Projection::isAddressProjection(user) ||
552552
isa<ProjectBlockStorageInst>(user) ||
553553
isa<OpenExistentialAddrInst>(user) ||
554-
isa<InitExistentialAddrInst>(user) || isa<BeginAccessInst>(user) ||
555-
isa<TailAddrInst>(user) || isa<IndexAddrInst>(user)) {
554+
isa<InitExistentialAddrInst>(user) ||
555+
isa<InitEnumDataAddrInst>(user) || isa<BeginAccessInst>(user) ||
556+
isa<TailAddrInst>(user) || isa<IndexAddrInst>(user) ||
557+
isa<UnconditionalCheckedCastAddrInst>(user)) {
556558
for (SILValue r : user->getResults()) {
557559
llvm::copy(r->getUses(), std::back_inserter(worklist));
558560
}

lib/SIL/Verifier/SILOwnershipVerifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ bool SILValueOwnershipChecker::gatherUsers(
391391
llvm::errs() << "Could not recognize address user of interior "
392392
"pointer operand!\n"
393393
<< "Interior Pointer Operand: "
394-
<< interiorPointerOperand->operand->getUser()
394+
<< *interiorPointerOperand->operand->getUser()
395395
<< "Address User: " << *op->getUser();
396396
});
397397
};

test/SIL/ownership-verifier/interior_pointer.sil

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// RUN: %target-sil-opt -sil-ownership-verifier-enable-testing -ownership-verifier-textual-error-dumper -enable-sil-verify-all=0 %s -o /dev/null 2>&1 | %FileCheck %s
22
// REQUIRES: asserts
33

4+
import Swift
5+
46
sil_stage canonical
57

68
class Klass {}
@@ -40,3 +42,48 @@ bb0(%0 : @owned $KlassUser):
4042
%3 = load [copy] %2 : $*Klass
4143
return %3 : $Klass
4244
}
45+
46+
class OptionalBox<T> {
47+
var t: T?
48+
}
49+
50+
// CHECK-NOT: Function: 'inject_enum_addr_test'
51+
sil [ossa] @inject_enum_addr_test : $@convention(thin) <T> (@owned OptionalBox<T>) -> () {
52+
bb0(%0 : @owned $OptionalBox<T>):
53+
%1 = begin_borrow %0 : $OptionalBox<T>
54+
%2 = ref_element_addr %1 : $OptionalBox<T>, #OptionalBox.t
55+
inject_enum_addr %2 : $*Optional<T>, #Optional.none!enumelt
56+
end_borrow %1 : $OptionalBox<T>
57+
destroy_value %0 : $OptionalBox<T>
58+
%3 = tuple ()
59+
return %3 : $()
60+
}
61+
62+
// CHECK-NOT: Function: 'init_enum_data_addr_test'
63+
sil [ossa] @init_enum_data_addr_test : $@convention(thin) <T> (@owned OptionalBox<T>, @in_guaranteed T) -> () {
64+
bb0(%0 : @owned $OptionalBox<T>, %1 : $*T):
65+
%2 = begin_borrow %0 : $OptionalBox<T>
66+
%3 = ref_element_addr %2 : $OptionalBox<T>, #OptionalBox.t
67+
%4 = init_enum_data_addr %3 : $*Optional<T>, #Optional.some!enumelt
68+
copy_addr %1 to [initialization] %4 : $*T
69+
end_borrow %2 : $OptionalBox<T>
70+
destroy_value %0 : $OptionalBox<T>
71+
%5 = tuple ()
72+
return %5 : $()
73+
}
74+
75+
class Box<T> {
76+
var t: T
77+
}
78+
79+
// CHECK-NOT: Function: 'unconditional_cast_test'
80+
sil [ossa] @unconditional_cast_test : $@convention(thin) <T> (@owned Box<T>, @in Int) -> () {
81+
bb0(%0 : @owned $Box<T>, %1 : $*Int):
82+
%2 = begin_borrow %0 : $Box<T>
83+
%3 = ref_element_addr %2 : $Box<T>, #Box.t
84+
unconditional_checked_cast_addr Int in %1 : $*Int to T in %3 : $*T
85+
end_borrow %2 : $Box<T>
86+
destroy_value %0 : $Box<T>
87+
%4 = tuple ()
88+
return %4 : $()
89+
}

0 commit comments

Comments
 (0)