Skip to content

Commit ce218b3

Browse files
authored
Fix LoadBorrowImmutabilityChecker for partial applies (#34658)
1 parent 7d05f37 commit ce218b3

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

lib/SIL/Verifier/LoadBorrowImmutabilityChecker.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,17 @@ bool GatherWritesVisitor::visitUse(Operand *op, AccessUseType useTy) {
243243
return false;
244244
}
245245

246+
if (auto *pa = dyn_cast<PartialApplyInst>(user)) {
247+
auto argConv = ApplySite(user).getArgumentConvention(*op);
248+
if (argConv == SILArgumentConvention::Indirect_In_Guaranteed) {
249+
return true;
250+
}
251+
252+
// For all other conventions, the underlying address could be mutated
253+
writeAccumulator.push_back(op);
254+
return true;
255+
}
256+
246257
// Handle a capture-by-address like a write.
247258
if (auto as = ApplySite::isa(user)) {
248259
writeAccumulator.push_back(op);
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// RUN: %target-sil-opt -enable-sil-verify-all -inline %s -o /dev/null
2+
3+
// Tests here are patterns we should not consider as broken
4+
5+
import Builtin
6+
7+
class SuperKlass {}
8+
class Klass : SuperKlass {}
9+
10+
struct WrapperStruct {
11+
var cls : Klass
12+
}
13+
14+
sil [ossa] @foo1 : $@convention(thin) (@guaranteed WrapperStruct, @in_guaranteed WrapperStruct) -> ()
15+
sil [ossa] @foo2 : $@convention(thin) (@owned WrapperStruct, @in_guaranteed WrapperStruct) -> ()
16+
17+
sil [ossa] @test1 : $@convention(thin) (@in_guaranteed WrapperStruct) -> () {
18+
bb0(%0 : $*WrapperStruct):
19+
%1 = load_borrow %0 : $*WrapperStruct
20+
%func = function_ref @foo1 : $@convention(thin) (@guaranteed WrapperStruct, @in_guaranteed WrapperStruct) -> ()
21+
%pa = partial_apply [callee_guaranteed] [on_stack] %func(%1, %0) : $@convention(thin) (@guaranteed WrapperStruct, @in_guaranteed WrapperStruct) -> ()
22+
end_borrow %1 : $WrapperStruct
23+
dealloc_stack %pa : $@noescape @callee_guaranteed () -> ()
24+
%res = tuple ()
25+
return %res : $()
26+
}
27+
28+
sil [ossa] @test2 : $@convention(thin) (@in_guaranteed WrapperStruct) -> () {
29+
bb0(%0 : $*WrapperStruct):
30+
%1 = load_borrow %0 : $*WrapperStruct
31+
%copy = copy_value %1 : $WrapperStruct
32+
%func = function_ref @foo2 : $@convention(thin) (@owned WrapperStruct, @in_guaranteed WrapperStruct) -> ()
33+
%pa = partial_apply %func(%copy, %0) : $@convention(thin) (@owned WrapperStruct, @in_guaranteed WrapperStruct) -> ()
34+
end_borrow %1 : $WrapperStruct
35+
destroy_value %pa : $@callee_owned () -> ()
36+
%res = tuple ()
37+
return %res : $()
38+
}
39+
40+
sil [ossa] @caller1 : $@convention(thin) (@owned WrapperStruct) -> () {
41+
bb0(%0 : @owned $WrapperStruct):
42+
%stk = alloc_stack $WrapperStruct
43+
store %0 to [init] %stk : $*WrapperStruct
44+
%func = function_ref @test1 : $@convention(thin) (@in_guaranteed WrapperStruct) -> ()
45+
%a = apply %func(%stk) : $@convention(thin) (@in_guaranteed WrapperStruct) -> ()
46+
destroy_addr %stk : $*WrapperStruct
47+
dealloc_stack %stk : $*WrapperStruct
48+
%res = tuple ()
49+
return %res : $()
50+
}
51+
52+
sil [ossa] @caller2 : $@convention(thin) (@owned WrapperStruct) -> () {
53+
bb0(%0 : @owned $WrapperStruct):
54+
%stk = alloc_stack $WrapperStruct
55+
store %0 to [init] %stk : $*WrapperStruct
56+
%func = function_ref @test2 : $@convention(thin) (@in_guaranteed WrapperStruct) -> ()
57+
%a = apply %func(%stk) : $@convention(thin) (@in_guaranteed WrapperStruct) -> ()
58+
destroy_addr %stk : $*WrapperStruct
59+
dealloc_stack %stk : $*WrapperStruct
60+
%res = tuple ()
61+
return %res : $()
62+
}
63+

0 commit comments

Comments
 (0)