@@ -29,9 +29,24 @@ struct Mixed {
2929 var i: Int
3030}
3131
32+ public struct InnerWrapper<T> {
33+ @_hasStorage var _prop: T { get set }
34+ public var prop: T
35+ }
36+
37+ public struct GenWrapper<T> {
38+ @_hasStorage var _prop: T { get set }
39+ public var prop: T
40+
41+ @_hasStorage var _nestedProp: InnerWrapper<T> { get set }
42+ public var nestedProp: InnerWrapper<T>
43+ }
44+
3245sil @use_owned : $@convention(thin) (@owned T) -> ()
3346sil @use_guaranteed : $@convention(thin) (@guaranteed T) -> ()
3447sil @get_owned : $@convention(thin) () -> @owned T
48+ sil @use_T : $@convention(thin) <T> (@in_guaranteed T) -> ()
49+ sil @mutate_T : $@convention(thin) <T> (@inout T) -> ()
3550
3651// CHECK: SIL memory lifetime failure in @test_simple: indirect argument is not alive at function return
3752sil [ossa] @test_simple : $@convention(thin) (@inout T) -> @owned T {
@@ -276,8 +291,8 @@ bb0(%0 : $*T):
276291 return %res : $()
277292}
278293
279- // CHECK: SIL memory lifetime failure in @test_store_borrow_destroy : store-borrow location cannot be written
280- sil [ossa] @test_store_borrow_destroy : $@convention(thin) (@guaranteed T) -> () {
294+ // CHECK: SIL memory lifetime failure in @test_store_borrow_destroy1 : store-borrow location cannot be written
295+ sil [ossa] @test_store_borrow_destroy1 : $@convention(thin) (@guaranteed T) -> () {
281296bb0(%0 : @guaranteed $T):
282297 %s = alloc_stack $T
283298 %sb = store_borrow %0 to %s : $*T
@@ -288,6 +303,19 @@ bb0(%0 : @guaranteed $T):
288303 return %res : $()
289304}
290305
306+ // CHECK: SIL memory lifetime failure in @test_store_borrow_destroy2: store-borrow location cannot be written
307+ sil [ossa] @test_store_borrow_destroy2 : $@convention(thin) (@guaranteed Inner) -> () {
308+ bb0(%0 : @guaranteed $Inner):
309+ %s = alloc_stack $Inner
310+ %sb = store_borrow %0 to %s
311+ %elem = struct_element_addr %sb, #Inner.a
312+ destroy_addr %elem
313+ end_borrow %sb
314+ dealloc_stack %s
315+ %res = tuple ()
316+ return %res : $()
317+ }
318+
291319sil [ossa] @func_with_inout_param : $@convention(thin) (@inout T) -> ()
292320
293321// T-CHECK: SIL memory lifetime failure in @test_store_borrow_inout: store-borrow location cannot be written
@@ -842,3 +870,81 @@ bb0(%0 : @owned $T, %1 : @owned $Inner):
842870 dealloc_stack %2
843871 return %8
844872}
873+
874+ sil [ossa] @borrow_addressonly_prop : $@convention(method) <T> (@in_guaranteed GenWrapper<T>) -> @guaranteed_address T {
875+ bb0(%0 : $*GenWrapper<T>):
876+ %2 = struct_element_addr %0, #GenWrapper._prop
877+ return %2
878+ }
879+
880+ sil [ossa] @mutate_addressonly_prop : $@convention(method) <T> (@inout GenWrapper<T>) -> @inout T {
881+ bb0(%0 : $*GenWrapper<T>):
882+ %2 = struct_element_addr %0, #GenWrapper._prop
883+ return %2
884+ }
885+
886+ sil [ossa] @borrow_addressonly_nested_prop : $@convention(method) <T> (@in_guaranteed GenWrapper<T>) -> @guaranteed_address InnerWrapper<T> {
887+ bb0(%0 : $*GenWrapper<T>):
888+ %2 = struct_element_addr %0, #GenWrapper._nestedProp
889+ return %2
890+ }
891+
892+ sil [ossa] @mutate_addressonly_nested_prop : $@convention(method) <T> (@inout GenWrapper<T>) -> @inout InnerWrapper<T> {
893+ bb0(%0 : $*GenWrapper<T>):
894+ %2 = struct_element_addr %0, #GenWrapper._nestedProp
895+ return %2
896+ }
897+
898+ // CHECK: SIL memory lifetime failure in @test_use_after_free_address_only1: memory is not initialized, but should be
899+ // CHECK: memory location: %2 = apply %1<T>(%0) : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address τ_0_0
900+ // CHECK: at instruction: %5 = apply %3<T>(%2) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
901+ sil [ossa] @test_use_after_free_address_only1 : $@convention(thin) <T> (@in GenWrapper<T>) -> () {
902+ bb0(%0 : $*GenWrapper<T>):
903+ %1 = function_ref @borrow_addressonly_prop : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address τ_0_0
904+ %2 = apply %1<T>(%0) : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address τ_0_0
905+ %3 = function_ref @use_T : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
906+ destroy_addr %0
907+ %5 = apply %3<T>(%2) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
908+ %6 = tuple ()
909+ return %6
910+ }
911+
912+ // CHECK: SIL memory lifetime failure in @test_use_after_free_address_only2: memory is not initialized, but should be
913+ // CHECK: memory location: %2 = apply %1<T>(%0) : $@convention(method) <τ_0_0> (@inout GenWrapper<τ_0_0>) -> @inout τ_0_0
914+ // CHECK: at instruction: %5 = apply %3<T>(%2) : $@convention(thin) <τ_0_0> (@inout τ_0_0) -> ()
915+ sil [ossa] @test_use_after_free_address_only2 : $@convention(thin) <T> (@in GenWrapper<T>) -> () {
916+ bb0(%0 : $*GenWrapper<T>):
917+ %1 = function_ref @mutate_addressonly_prop : $@convention(method) <τ_0_0> (@inout GenWrapper<τ_0_0>) -> @inout τ_0_0
918+ %2 = apply %1<T>(%0) : $@convention(method) <τ_0_0> (@inout GenWrapper<τ_0_0>) -> @inout τ_0_0
919+ %3 = function_ref @mutate_T : $@convention(thin) <τ_0_0> (@inout τ_0_0) -> ()
920+ destroy_addr %0
921+ %5 = apply %3<T>(%2) : $@convention(thin) <τ_0_0> (@inout τ_0_0) -> ()
922+ %6 = tuple ()
923+ return %6
924+ }
925+
926+ // TODO-CHECK: SIL memory lifetime failure in @test_guaranteed_address_consume: store-borrow location cannot be written
927+ // TODO-CHECK: memory location: %2 = apply %1<T>(%0) : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address τ_0_0
928+ // TODO-CHECK: at instruction: destroy_addr %2 : $*T
929+ sil [ossa] @test_guaranteed_address_consume : $@convention(thin) <T> (@in GenWrapper<T>) -> () {
930+ bb0(%0 : $*GenWrapper<T>):
931+ %1 = function_ref @borrow_addressonly_prop : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address τ_0_0
932+ %2 = apply %1<T>(%0) : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address τ_0_0
933+ destroy_addr %2
934+ %4 = tuple ()
935+ return %4
936+ }
937+
938+ // TODO-CHECK: SIL memory lifetime failure in @test_guaranteed_nested_address_consume: store-borrow location cannot be written
939+ // TODO-CHECK: memory location: %3 = struct_element_addr %2 : $*InnerWrapper<T>, #InnerWrapper._prop
940+ // TODO-CHECK: at instruction: destroy_addr %3 : $*T
941+ sil [ossa] @test_guaranteed_nested_address_consume : $@convention(thin) <T> (@in GenWrapper<T>) -> () {
942+ bb0(%0 : $*GenWrapper<T>):
943+ %1 = function_ref @borrow_addressonly_nested_prop : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address InnerWrapper<τ_0_0>
944+ %2 = apply %1<T>(%0) : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address InnerWrapper<τ_0_0>
945+ %3 = struct_element_addr %2, #InnerWrapper._prop
946+ destroy_addr %3
947+ %4 = tuple ()
948+ return %4
949+ }
950+
0 commit comments