mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
951 lines
33 KiB
Plaintext
951 lines
33 KiB
Plaintext
// RUN: %target-sil-opt -disable-swift-verification -dont-abort-on-memory-lifetime-errors -o /dev/null %s 2>&1 | %FileCheck %s
|
|
// REQUIRES: asserts
|
|
// REQUIRES: swift_in_compiler
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
import SwiftShims
|
|
|
|
// A non-trivial type
|
|
class T {
|
|
init()
|
|
}
|
|
|
|
struct Inner {
|
|
var a: T
|
|
var b: T
|
|
}
|
|
|
|
struct Outer {
|
|
var x: T
|
|
var y: Inner
|
|
var z: T
|
|
}
|
|
|
|
struct Mixed {
|
|
var t: T
|
|
var i: Int
|
|
}
|
|
|
|
public struct InnerWrapper<T> {
|
|
@_hasStorage var _prop: T { get set }
|
|
public var prop: T
|
|
}
|
|
|
|
public struct GenWrapper<T> {
|
|
@_hasStorage var _prop: T { get set }
|
|
public var prop: T
|
|
|
|
@_hasStorage var _nestedProp: InnerWrapper<T> { get set }
|
|
public var nestedProp: InnerWrapper<T>
|
|
}
|
|
|
|
sil @use_owned : $@convention(thin) (@owned T) -> ()
|
|
sil @use_guaranteed : $@convention(thin) (@guaranteed T) -> ()
|
|
sil @get_owned : $@convention(thin) () -> @owned T
|
|
sil @use_T : $@convention(thin) <T> (@in_guaranteed T) -> ()
|
|
sil @mutate_T : $@convention(thin) <T> (@inout T) -> ()
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_simple: indirect argument is not alive at function return
|
|
sil [ossa] @test_simple : $@convention(thin) (@inout T) -> @owned T {
|
|
bb0(%0 : $*T):
|
|
%2 = begin_access [read] [static] %0 : $*T
|
|
%3 = load [copy] %2 : $*T
|
|
end_access %2 : $*T
|
|
br bb1
|
|
bb1:
|
|
destroy_addr %0 : $*T
|
|
return %3 : $T
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_loop: memory is initialized at function return but shouldn't
|
|
sil [ossa] @test_loop : $@convention(thin) (@in T) -> @owned T {
|
|
bb0(%0 : $*T):
|
|
%2 = begin_access [read] [static] %0 : $*T
|
|
%3 = load [copy] %2 : $*T
|
|
end_access %2 : $*T
|
|
br bb1
|
|
bb1:
|
|
cond_br undef, bb2, bb3
|
|
bb2:
|
|
br bb1
|
|
bb3:
|
|
return %3 : $T
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_merge: lifetime mismatch in predecessors
|
|
sil [ossa] @test_merge : $@convention(thin) (@in_guaranteed T) -> () {
|
|
bb0(%0 : $*T):
|
|
%2 = alloc_stack $T
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
copy_addr %0 to [init] %2 : $*T
|
|
br bb3
|
|
bb2:
|
|
copy_addr %0 to [init] %2 : $*T
|
|
destroy_addr %2 : $*T
|
|
br bb3
|
|
|
|
bb3:
|
|
dealloc_stack %2 : $*T
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_nesting: memory is initialized at function return but shouldn't
|
|
sil [ossa] @test_nesting : $@convention(thin) (@in Outer) -> () {
|
|
bb0(%0 : $*Outer):
|
|
%1 = struct_element_addr %0 : $*Outer, #Outer.x
|
|
%2 = struct_element_addr %0 : $*Outer, #Outer.y
|
|
destroy_addr %1 : $*T
|
|
destroy_addr %2 : $*Inner
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
sil @throwing_func : $@convention(thin) () -> (@out T, @error Error)
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_try_apply_return: memory is initialized, but shouldn't be
|
|
sil [ossa] @test_try_apply_return : $@convention(thin) () -> ((), @error Error) {
|
|
bb0:
|
|
%0 = alloc_stack $T
|
|
%1 = function_ref @throwing_func : $@convention(thin) () -> (@out T, @error Error)
|
|
try_apply %1(%0) : $@convention(thin) () -> (@out T, @error Error), normal bb1, error bb2
|
|
|
|
bb1(%2 : $()):
|
|
dealloc_stack %0 : $*T
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
|
|
bb2(%4 : @owned $Error):
|
|
dealloc_stack %0 : $*T
|
|
throw %4 : $Error
|
|
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_try_apply_throw: memory is not initialized, but should be
|
|
sil [ossa] @test_try_apply_throw : $@convention(thin) () -> ((), @error Error) {
|
|
bb0:
|
|
%0 = alloc_stack $T
|
|
%1 = function_ref @throwing_func : $@convention(thin) () -> (@out T, @error Error)
|
|
try_apply %1(%0) : $@convention(thin) () -> (@out T, @error Error), normal bb1, error bb2
|
|
|
|
bb1(%2 : $()):
|
|
destroy_addr %0 : $*T
|
|
dealloc_stack %0 : $*T
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
|
|
bb2(%4 : @owned $Error):
|
|
destroy_addr %0 : $*T
|
|
dealloc_stack %0 : $*T
|
|
throw %4 : $Error
|
|
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_single_block: memory is initialized, but shouldn't be
|
|
sil [ossa] @test_single_block : $@convention(thin) (@owned T) -> () {
|
|
bb0(%0 : @owned $T):
|
|
%2 = alloc_stack $T
|
|
store %0 to [init] %2 : $*T
|
|
dealloc_stack %2 : $*T
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_mixed: memory is not initialized, but should be
|
|
sil [ossa] @test_mixed : $@convention(thin) (@in Mixed, Int) -> Int {
|
|
bb0(%0 : $*Mixed, %1 : $Int):
|
|
%2 = struct_element_addr %0 : $*Mixed, #Mixed.i
|
|
store %1 to [trivial] %2 : $*Int
|
|
destroy_addr %0 : $*Mixed
|
|
%3 = load [trivial] %2 : $*Int
|
|
return %3 : $Int
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_missing_store_to_trivial: memory is not initialized, but should be
|
|
sil [ossa] @test_missing_store_to_trivial : $@convention(thin) () -> Int {
|
|
bb0:
|
|
%1 = alloc_stack $Mixed
|
|
%2 = struct_element_addr %1 : $*Mixed, #Mixed.i
|
|
%3 = load [trivial] %2 : $*Int
|
|
dealloc_stack %1 : $*Mixed
|
|
return %3 : $Int
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_load_after_dealloc: memory is not initialized, but should be
|
|
sil [ossa] @test_load_after_dealloc : $@convention(thin) (Int) -> Int {
|
|
bb0(%0 : $Int):
|
|
%1 = alloc_stack $Mixed
|
|
%2 = struct_element_addr %1 : $*Mixed, #Mixed.i
|
|
store %0 to [trivial] %2 : $*Int
|
|
dealloc_stack %1 : $*Mixed
|
|
%3 = load [trivial] %2 : $*Int
|
|
return %3 : $Int
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_switch_enum_addr: memory is initialized at function return but shouldn't
|
|
sil [ossa] @test_switch_enum_addr : $@convention(thin) (@in Optional<T>) -> () {
|
|
bb0(%0 : $*Optional<T>):
|
|
switch_enum_addr %0 : $*Optional<T>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
|
|
|
|
bb1:
|
|
%2 = unchecked_take_enum_data_addr %0 : $*Optional<T>, #Optional.some!enumelt
|
|
br bb3
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_switch_enum: memory is initialized at function return but shouldn't
|
|
sil [ossa] @test_switch_enum : $@convention(thin) (@in Optional<T>) -> () {
|
|
bb0(%0 : $*Optional<T>):
|
|
%1 = load_borrow %0 : $*Optional<T>
|
|
switch_enum %1 : $Optional<T>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
|
|
|
|
bb1(%3 : @guaranteed $T):
|
|
end_borrow %1 : $Optional<T>
|
|
%2 = unchecked_take_enum_data_addr %0 : $*Optional<T>, #Optional.some!enumelt
|
|
br bb3
|
|
|
|
bb2:
|
|
end_borrow %1 : $Optional<T>
|
|
br bb3
|
|
|
|
bb3:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_init_enum: indirect argument is not alive at function return
|
|
sil [ossa] @test_init_enum : $@convention(thin) (@in_guaranteed T) -> @out Optional<T> {
|
|
bb0(%0 : $*Optional<T>, %1 : $*T):
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
inject_enum_addr %0 : $*Optional<T>, #Optional.none!enumelt
|
|
br bb3
|
|
|
|
bb2:
|
|
%5 = init_enum_data_addr %0 : $*Optional<T>, #Optional.some!enumelt
|
|
inject_enum_addr %0 : $*Optional<T>, #Optional.some!enumelt
|
|
br bb3
|
|
|
|
bb3:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_store_to_enum: memory is initialized, but shouldn't be
|
|
sil [ossa] @test_store_to_enum : $@convention(thin) (@owned T) -> () {
|
|
bb0(%0 : @owned $T):
|
|
%1 = alloc_stack $Optional<T>
|
|
%2 = enum $Optional<T>, #Optional.none!enumelt
|
|
store %2 to [trivial] %1 : $*Optional<T>
|
|
destroy_addr %1 : $*Optional<T>
|
|
%3 = enum $Optional<T>, #Optional.some!enumelt, %0 : $T
|
|
store %3 to [init] %1 : $*Optional<T>
|
|
dealloc_stack %1 : $*Optional<T>
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_select_enum_addr: memory is not initialized, but should be
|
|
sil [ossa] @test_select_enum_addr : $@convention(thin) () -> Builtin.Int1 {
|
|
bb0:
|
|
%0 = alloc_stack $Optional<T>
|
|
%1 = integer_literal $Builtin.Int1, -1
|
|
%2 = integer_literal $Builtin.Int1, 0
|
|
%3 = select_enum_addr %0 : $*Optional<T>, case #Optional.some!enumelt: %1, case #Optional.none!enumelt: %2 : $Builtin.Int1
|
|
dealloc_stack %0 : $*Optional<T>
|
|
return %3 : $Builtin.Int1
|
|
}
|
|
|
|
sil [ossa] @closure : $@convention(thin) (@in_guaranteed T) -> ()
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_non_escaping_closure: memory is initialized at function return but shouldn't
|
|
sil [ossa] @test_non_escaping_closure : $@convention(thin) (@in T) -> () {
|
|
bb0(%0 : $*T):
|
|
%func = function_ref @closure : $@convention(thin) (@in_guaranteed T) -> ()
|
|
%pa = partial_apply [callee_guaranteed] [on_stack] %func(%0) : $@convention(thin) (@in_guaranteed T) -> ()
|
|
destroy_value %pa : $@noescape @callee_guaranteed () -> ()
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_escaping_closure: indirect argument is not alive at function return
|
|
sil [ossa] @test_escaping_closure : $@convention(thin) (@in_guaranteed T) -> () {
|
|
bb0(%0 : $*T):
|
|
%func = function_ref @closure : $@convention(thin) (@in_guaranteed T) -> ()
|
|
%pa = partial_apply %func(%0) : $@convention(thin) (@in_guaranteed T) -> ()
|
|
destroy_value %pa : $@callee_owned () -> ()
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_store_borrow_destroy1: store-borrow location cannot be written
|
|
sil [ossa] @test_store_borrow_destroy1 : $@convention(thin) (@guaranteed T) -> () {
|
|
bb0(%0 : @guaranteed $T):
|
|
%s = alloc_stack $T
|
|
%sb = store_borrow %0 to %s : $*T
|
|
destroy_addr %sb : $*T
|
|
end_borrow %sb : $*T
|
|
dealloc_stack %s : $*T
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_store_borrow_destroy2: store-borrow location cannot be written
|
|
sil [ossa] @test_store_borrow_destroy2 : $@convention(thin) (@guaranteed Inner) -> () {
|
|
bb0(%0 : @guaranteed $Inner):
|
|
%s = alloc_stack $Inner
|
|
%sb = store_borrow %0 to %s
|
|
%elem = struct_element_addr %sb, #Inner.a
|
|
destroy_addr %elem
|
|
end_borrow %sb
|
|
dealloc_stack %s
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
sil [ossa] @func_with_inout_param : $@convention(thin) (@inout T) -> ()
|
|
|
|
// T-CHECK: SIL memory lifetime failure in @test_store_borrow_inout: store-borrow location cannot be written
|
|
sil [ossa] @test_store_borrow_inout : $@convention(thin) (@guaranteed T) -> () {
|
|
bb0(%0 : @guaranteed $T):
|
|
%s = alloc_stack $T
|
|
%sb = store_borrow %0 to %s : $*T
|
|
%f = function_ref @func_with_inout_param : $@convention(thin) (@inout T) -> ()
|
|
%a = apply %f(%sb) : $@convention(thin) (@inout T) -> ()
|
|
end_borrow %sb : $*T
|
|
dealloc_stack %s : $*T
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_store_borrow_store: store-borrow location cannot be written
|
|
sil [ossa] @test_store_borrow_store : $@convention(thin) (@guaranteed T, @owned T) -> () {
|
|
bb0(%0 : @guaranteed $T, %1 : @owned $T):
|
|
%s = alloc_stack $T
|
|
%sb = store_borrow %0 to %s : $*T
|
|
store %1 to [assign] %sb : $*T
|
|
end_borrow %sb : $*T
|
|
dealloc_stack %s : $*T
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_store_borrow_load: store-borrow location cannot be written
|
|
sil [ossa] @test_store_borrow_load : $@convention(thin) (@guaranteed T) -> @owned T {
|
|
bb0(%0 : @guaranteed $T):
|
|
%s = alloc_stack $T
|
|
%sb = store_borrow %0 to %s : $*T
|
|
%res = load [take] %sb : $*T
|
|
end_borrow %sb : $*T
|
|
dealloc_stack %s : $*T
|
|
return %res : $T
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_store_borrow_copy_src: store-borrow location cannot be written
|
|
sil [ossa] @test_store_borrow_copy_src : $@convention(thin) (@guaranteed T) -> @out T {
|
|
bb0(%0 : $*T, %1 : @guaranteed $T):
|
|
%s = alloc_stack $T
|
|
%sb = store_borrow %1 to %s : $*T
|
|
copy_addr [take] %sb to [init] %0 : $*T
|
|
end_borrow %sb : $*T
|
|
dealloc_stack %s : $*T
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_store_borrow_copy_dst: store-borrow location cannot be written
|
|
sil [ossa] @test_store_borrow_copy_dst : $@convention(thin) (@in_guaranteed T, @guaranteed T) -> () {
|
|
bb0(%0 : $*T, %1 : @guaranteed $T):
|
|
%s = alloc_stack $T
|
|
%sb = store_borrow %1 to %s : $*T
|
|
copy_addr %0 to %sb : $*T
|
|
end_borrow %sb : $*T
|
|
dealloc_stack %s : $*T
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_store_borrow_init_enum: store-borrow location cannot be written
|
|
sil [ossa] @test_store_borrow_init_enum : $@convention(thin) (@guaranteed Optional<T>) -> () {
|
|
bb0(%0 : @guaranteed $Optional<T>):
|
|
%s = alloc_stack $Optional<T>
|
|
%sb = store_borrow %0 to %s : $*Optional<T>
|
|
%ie = init_enum_data_addr %sb : $*Optional<T>, #Optional.some!enumelt
|
|
end_borrow %sb : $*Optional<T>
|
|
dealloc_stack %s : $*Optional<T>
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
sil [ossa] @test_store_borrow_take_enum : $@convention(thin) (@guaranteed Optional<T>) -> () {
|
|
bb0(%0 : @guaranteed $Optional<T>):
|
|
%s = alloc_stack $Optional<T>
|
|
%sb = store_borrow %0 to %s : $*Optional<T>
|
|
%ue = unchecked_take_enum_data_addr %sb : $*Optional<T>, #Optional.some!enumelt
|
|
end_borrow %sb : $*Optional<T>
|
|
dealloc_stack %s : $*Optional<T>
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_store_borrow_addr_after_dealloc: memory is initialized, but shouldn't be
|
|
sil [ossa] @test_store_borrow_addr_after_dealloc : $@convention(thin) (@guaranteed Optional<T>) -> () {
|
|
bb0(%0 : @guaranteed $Optional<T>):
|
|
%s = alloc_stack $Optional<T>
|
|
%sb = store_borrow %0 to %s : $*Optional<T>
|
|
dealloc_stack %s : $*Optional<T>
|
|
end_borrow %sb : $*Optional<T>
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_cast_br_take_always: memory is not initialized, but should be
|
|
sil [ossa] @test_cast_br_take_always : $@convention(thin) <U, V> (@in U) -> () {
|
|
bb0(%0 : $*U):
|
|
%s = alloc_stack $V
|
|
checked_cast_addr_br take_always U in %0 : $*U to V in %s : $*V, bb1, bb2
|
|
bb1:
|
|
destroy_addr %s : $*V
|
|
br bb3
|
|
bb2:
|
|
destroy_addr %0 : $*U
|
|
br bb3
|
|
bb3:
|
|
dealloc_stack %s : $*V
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_cast_br_take_on_success: lifetime mismatch in predecessors
|
|
sil [ossa] @test_cast_br_take_on_success : $@convention(thin) <U, V> (@in U) -> () {
|
|
bb0(%0 : $*U):
|
|
%s = alloc_stack $V
|
|
checked_cast_addr_br take_on_success U in %0 : $*U to V in %s : $*V, bb1, bb2
|
|
bb1:
|
|
destroy_addr %s : $*V
|
|
br bb3
|
|
bb2:
|
|
br bb3
|
|
bb3:
|
|
dealloc_stack %s : $*V
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_cast_br_copy_on_success: lifetime mismatch in predecessors
|
|
sil [ossa] @test_cast_br_copy_on_success : $@convention(thin) <U, V> (@in U) -> () {
|
|
bb0(%0 : $*U):
|
|
%s = alloc_stack $V
|
|
checked_cast_addr_br copy_on_success U in %0 : $*U to V in %s : $*V, bb1, bb2
|
|
bb1:
|
|
destroy_addr %s : $*V
|
|
br bb3
|
|
bb2:
|
|
destroy_addr %0 : $*U
|
|
br bb3
|
|
bb3:
|
|
dealloc_stack %s : $*V
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_unconditional_checked_cast_1: memory is initialized, but shouldn't be
|
|
sil [ossa] @test_unconditional_checked_cast_1 : $@convention(thin) <U, V> (@in U) -> () {
|
|
bb0(%0 : $*U):
|
|
%s = alloc_stack $V
|
|
unconditional_checked_cast_addr U in %0 : $*U to V in %s : $*V
|
|
dealloc_stack %s : $*V
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_unconditional_checked_cast_2: memory is not initialized, but should be
|
|
sil [ossa] @test_unconditional_checked_cast_2 : $@convention(thin) <U, V> (@in_guaranteed U) -> () {
|
|
bb0(%0 : $*U):
|
|
%u = alloc_stack $U
|
|
%s = alloc_stack $V
|
|
unconditional_checked_cast_addr U in %u : $*U to V in %s : $*V
|
|
destroy_addr %s : $*V
|
|
dealloc_stack %s : $*V
|
|
dealloc_stack %u : $*U
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_unchecked_ref_cast_1: memory is initialized, but shouldn't be
|
|
sil [ossa] @test_unchecked_ref_cast_1 : $@convention(thin) <U : AnyObject, V : AnyObject> (@in U) -> () {
|
|
bb0(%0 : $*U):
|
|
%s = alloc_stack $V
|
|
unchecked_ref_cast_addr U in %0 : $*U to V in %s : $*V
|
|
dealloc_stack %s : $*V
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_unchecked_ref_cast_2: memory is not initialized, but should be
|
|
sil [ossa] @test_unchecked_ref_cast_2 : $@convention(thin) <U : AnyObject, V : AnyObject> (@in_guaranteed U) -> () {
|
|
bb0(%0 : $*U):
|
|
%u = alloc_stack $U
|
|
%s = alloc_stack $V
|
|
unchecked_ref_cast_addr U in %u : $*U to V in %s : $*V
|
|
destroy_addr %s : $*V
|
|
dealloc_stack %s : $*V
|
|
dealloc_stack %u : $*U
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
protocol P {}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_init_existential: memory is not initialized, but should be
|
|
sil [ossa] @test_init_existential : $@convention(thin) <U: P> (@in_guaranteed U) -> () {
|
|
bb0(%0 : $*U):
|
|
%s = alloc_stack $P
|
|
%i = init_existential_addr %s : $*P, $U
|
|
destroy_addr %s : $*P
|
|
dealloc_stack %s : $*P
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_open_existential: memory is not initialized, but should be
|
|
sil [ossa] @test_open_existential : $@convention(thin) <U: P> (@in_guaranteed U) -> () {
|
|
bb0(%0 : $*U):
|
|
%s = alloc_stack $P
|
|
%o = open_existential_addr immutable_access %s : $*P to $*@opened("5B62392E-7C62-11EB-BF90-D0817AD9985D", P) Self
|
|
%s2 = alloc_stack $@opened("5B62392E-7C62-11EB-BF90-D0817AD9985D", P) Self
|
|
copy_addr %o to [init] %s2 : $*@opened("5B62392E-7C62-11EB-BF90-D0817AD9985D", P) Self
|
|
destroy_addr %s2 : $*@opened("5B62392E-7C62-11EB-BF90-D0817AD9985D", P) Self
|
|
dealloc_stack %s2 : $*@opened("5B62392E-7C62-11EB-BF90-D0817AD9985D", P) Self
|
|
destroy_addr %s : $*P
|
|
dealloc_stack %s : $*P
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_existential_metatype: memory is not initialized, but should be
|
|
sil [ossa] @test_existential_metatype : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = alloc_stack $P
|
|
%714 = existential_metatype $@thick P.Type, %0 : $*P
|
|
dealloc_stack %0 : $*P
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_value_metatype: memory is not initialized, but should be
|
|
sil [ossa] @test_value_metatype : $@convention(thin) <U> (@in_guaranteed U) -> () {
|
|
bb0(%0 : $*U):
|
|
%1 = alloc_stack $U
|
|
%2 = value_metatype $@thick U.Type, %1 : $*U
|
|
dealloc_stack %1 : $*U
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_is_unique: memory is not initialized, but should be
|
|
sil [ossa] @test_is_unique : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = alloc_stack $T
|
|
%1 = is_unique %0 : $*T
|
|
dealloc_stack %0 : $*T
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_fix_lifetime: memory is not initialized, but should be
|
|
sil [ossa] @test_fix_lifetime : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = alloc_stack $T
|
|
fix_lifetime %0 : $*T
|
|
dealloc_stack %0 : $*T
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
sil @modify_bool : $@convention(thin) (@inout_aliasable Bool) -> ()
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_trivial_alloc_stack: memory is not initialized, but should be
|
|
sil [ossa] @test_trivial_alloc_stack : $@convention(thin) (Bool) -> () {
|
|
bb0(%0 : $Bool):
|
|
%1 = alloc_stack $Bool
|
|
store %0 to [trivial] %1 : $*Bool
|
|
dealloc_stack %1 : $*Bool
|
|
%8 = function_ref @modify_bool : $@convention(thin) (@inout_aliasable Bool) -> ()
|
|
%9 = apply %8(%1) : $@convention(thin) (@inout_aliasable Bool) -> ()
|
|
%10 = tuple ()
|
|
return %10 : $()
|
|
}
|
|
|
|
// MemoryLifetimeVerifier does not detect an error here due to reborrows
|
|
sil [ossa] @test_load_borrow1 : $@convention(thin) (@in Optional<T>) -> () {
|
|
bb0(%0 : $*Optional<T>):
|
|
destroy_addr %0 : $*Optional<T>
|
|
%1 = load_borrow %0 : $*Optional<T>
|
|
br bb1(%1 : $Optional<T>)
|
|
|
|
bb1(%3 : @guaranteed $Optional<T>):
|
|
end_borrow %3 : $Optional<T>
|
|
br bb2
|
|
|
|
bb2:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_load_borrow2: memory is not initialized, but should be
|
|
sil [ossa] @test_load_borrow2 : $@convention(thin) (@in Optional<T>) -> () {
|
|
bb0(%0 : $*Optional<T>):
|
|
destroy_addr %0 : $*Optional<T>
|
|
%1 = load_borrow %0 : $*Optional<T>
|
|
end_borrow %1 : $Optional<T>
|
|
br bb1
|
|
|
|
bb1:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
enum Result<T1, T2>{
|
|
case success(T1)
|
|
case failure(T2)
|
|
}
|
|
|
|
sil @try_get_error : $@convention(thin) () -> @error Error
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_init_enum_trivial_case: memory is not initialized, but should be
|
|
sil [ossa] @test_init_enum_trivial_case : $@convention(thin) () -> @error Error {
|
|
bb0:
|
|
%0 = alloc_stack $Result<Int, Error>
|
|
%1 = function_ref @try_get_error : $@convention(thin) () -> @error Error
|
|
try_apply %1() : $@convention(thin) () -> @error Error, normal bb1, error bb2
|
|
|
|
bb1(%3 : $()):
|
|
inject_enum_addr %0 : $*Result<Int, Error>, #Result.success!enumelt
|
|
br bb3
|
|
|
|
|
|
bb2(%7 : @owned $Error):
|
|
%8 = init_enum_data_addr %0 : $*Result<Int, Error>, #Result.failure!enumelt
|
|
store %7 to [init] %8 : $*Error
|
|
inject_enum_addr %0 : $*Result<Int, Error>, #Result.failure!enumelt
|
|
br bb3
|
|
|
|
bb3:
|
|
%12 = load [take] %0 : $*Result<Int, Error>
|
|
destroy_value %12 : $Result<Int, Error>
|
|
dealloc_stack %0 : $*Result<Int, Error>
|
|
%15 = tuple ()
|
|
return %15 : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_double_enum_destroy: memory is not initialized, but should be
|
|
sil [ossa] @test_double_enum_destroy : $@convention(thin) (@in Optional<String>) -> () {
|
|
bb0(%0 : $*Optional<String>):
|
|
%l = load_borrow %0 : $*Optional<String>
|
|
switch_enum %l : $Optional<String>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
|
|
|
|
bb1(%a : @guaranteed $String):
|
|
end_borrow %l : $Optional<String>
|
|
%2 = load [take] %0 : $*Optional<String>
|
|
destroy_value %2 : $Optional<String>
|
|
br bb3
|
|
|
|
bb2:
|
|
end_borrow %l : $Optional<String>
|
|
%3 = load [take] %0 : $*Optional<String>
|
|
destroy_value %3 : $Optional<String>
|
|
%4 = load [take] %0 : $*Optional<String>
|
|
destroy_value %4 : $Optional<String>
|
|
br bb3
|
|
|
|
bb3:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_destroy_enum_before_return: indirect argument is not alive at function return
|
|
sil [ossa] @test_destroy_enum_before_return : $@convention(thin) () -> @out Optional<String> {
|
|
bb0(%0 : $*Optional<String>):
|
|
%1 = enum $Optional<String>, #Optional.none!enumelt
|
|
store %1 to [trivial] %0 : $*Optional<String>
|
|
destroy_addr %0 : $*Optional<String>
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @begin_apply_in_no_destroy: memory is initialized, but shouldn't be
|
|
sil [ossa] @begin_apply_in_no_destroy : $@convention(thin) () -> () {
|
|
entry:
|
|
(%instance, %token) = begin_apply undef<Inner>() : $@yield_once @convention(thin) <U> () -> @yields @in U
|
|
end_apply %token as $()
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @begin_apply_in_use_after_end_apply: memory is initialized, but shouldn't be
|
|
sil [ossa] @begin_apply_in_use_after_end_apply : $@convention(thin) () -> () {
|
|
entry:
|
|
(%instance, %token) = begin_apply undef<Inner>() : $@yield_once @convention(thin) <U> () -> @yields @in U
|
|
end_apply %token as $()
|
|
apply undef<Inner>(%instance) : $@convention(thin) <U> (@in U) -> ()
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @begin_apply_in_constant_no_destroy: memory is initialized, but shouldn't be
|
|
sil [ossa] @begin_apply_in_constant_no_destroy : $@convention(thin) () -> () {
|
|
entry:
|
|
(%instance, %token) = begin_apply undef<Inner>() : $@yield_once @convention(thin) <U> () -> @yields @in_constant U
|
|
end_apply %token as $()
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @begin_apply_in_constant_use_after_end_apply: memory is initialized, but shouldn't be
|
|
sil [ossa] @begin_apply_in_constant_use_after_end_apply : $@convention(thin) () -> () {
|
|
entry:
|
|
(%instance, %token) = begin_apply undef<Inner>() : $@yield_once @convention(thin) <U> () -> @yields @in_constant U
|
|
end_apply %token as $()
|
|
apply undef<Inner>(%instance) : $@convention(thin) <U> (@in_constant U) -> ()
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @begin_apply_in_guaranteed_destroy: memory is not initialized, but should be
|
|
sil [ossa] @begin_apply_in_guaranteed_destroy : $@convention(thin) () -> () {
|
|
entry:
|
|
(%instance, %token) = begin_apply undef<Inner>() : $@yield_once @convention(thin) <U> () -> @yields @in_guaranteed U
|
|
destroy_addr %instance : $*Inner
|
|
end_apply %token as $()
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @begin_apply_in_guaranteed_use_after_end_apply: memory is not initialized, but should be
|
|
sil [ossa] @begin_apply_in_guaranteed_use_after_end_apply : $@convention(thin) () -> () {
|
|
entry:
|
|
(%instance, %token) = begin_apply undef<Inner>() : $@yield_once @convention(thin) <U> () -> @yields @in_guaranteed U
|
|
end_apply %token as $()
|
|
apply undef<Inner>(%instance) : $@convention(thin) <U> (@in_guaranteed U) -> ()
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @begin_apply_inout_destroy: memory is not initialized, but should be
|
|
sil [ossa] @begin_apply_inout_destroy : $@convention(thin) () -> () {
|
|
entry:
|
|
(%instance, %token) = begin_apply undef<Inner>() : $@yield_once @convention(thin) <U> () -> @yields @inout U
|
|
destroy_addr %instance : $*Inner
|
|
end_apply %token as $()
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @begin_apply_inout_use_after_end_apply: memory is not initialized, but should be
|
|
sil [ossa] @begin_apply_inout_use_after_end_apply : $@convention(thin) () -> () {
|
|
entry:
|
|
(%instance, %token) = begin_apply undef<Inner>() : $@yield_once @convention(thin) <U> () -> @yields @inout U
|
|
end_apply %token as $()
|
|
apply undef<Inner>(%instance) : $@convention(thin) <U> (@inout U) -> ()
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @begin_apply_inout_aliasable_destroy: memory is not initialized, but should be
|
|
sil [ossa] @begin_apply_inout_aliasable_destroy : $@convention(thin) () -> () {
|
|
entry:
|
|
(%instance, %token) = begin_apply undef<Inner>() : $@yield_once @convention(thin) <U> () -> @yields @inout_aliasable U
|
|
destroy_addr %instance : $*Inner
|
|
end_apply %token as $()
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @begin_apply_inout_aliasable_use_after_end_apply: memory is not initialized, but should be
|
|
sil [ossa] @begin_apply_inout_aliasable_use_after_end_apply : $@convention(thin) () -> () {
|
|
entry:
|
|
(%instance, %token) = begin_apply undef<Inner>() : $@yield_once @convention(thin) <U> () -> @yields @inout_aliasable U
|
|
end_apply %token as $()
|
|
apply undef<Inner>(%instance) : $@convention(thin) <U> (@inout_aliasable U) -> ()
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @begin_apply_inout_destroy: memory is not initialized, but should be
|
|
sil [ossa] @begin_apply_inout_no_destroy : $@convention(thin) () -> () {
|
|
entry:
|
|
(%instance, %token) = begin_apply undef<Inner>() : $@yield_once @convention(thin) <U> () -> @yields @inout U
|
|
end_apply %token as $()
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @begin_apply_inout_aliasable_destroy: memory is not initialized, but should be
|
|
sil [ossa] @begin_apply_inout_aliasable_no_destroy : $@convention(thin) () -> () {
|
|
entry:
|
|
(%instance, %token) = begin_apply undef<Inner>() : $@yield_once @convention(thin) <U> () -> @yields @inout_aliasable U
|
|
end_apply %token as $()
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|
|
sil @read_inner_b : $@convention(thin) (@in_guaranteed Inner) -> () {
|
|
[%0: read s0]
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_partial_read_in_argument: memory is not initialized, but should be
|
|
sil [ossa] @test_partial_read_in_argument : $@convention(thin) (@in Inner) -> () {
|
|
bb0(%0: $*Inner):
|
|
%1 = struct_element_addr %0 : $*Inner, #Inner.a
|
|
destroy_addr %1 : $*T
|
|
%3 = function_ref @read_inner_b : $@convention(thin) (@in_guaranteed Inner) -> ()
|
|
%4 = apply %3(%0) : $@convention(thin) (@in_guaranteed Inner) -> ()
|
|
%5 = struct_element_addr %0 : $*Inner, #Inner.b
|
|
destroy_addr %5 : $*T
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @mark_dependence_uninit_base: memory is not initialized, but should be
|
|
sil [ossa] @mark_dependence_uninit_base : $@convention(thin) (@owned T, @owned Inner) -> @owned Inner {
|
|
bb0(%0 : @owned $T, %1 : @owned $Inner):
|
|
%2 = alloc_stack $T
|
|
store %0 to [init] %2
|
|
%4 = alloc_stack $Inner
|
|
store %1 to [init] %4
|
|
destroy_addr %2
|
|
%6 = mark_dependence %4 on %2
|
|
%7 = begin_access [read] [dynamic] %6
|
|
%8 = load [take] %7
|
|
end_access %7
|
|
dealloc_stack %4
|
|
dealloc_stack %2
|
|
return %8
|
|
}
|
|
|
|
sil @initfn : $@convention(thin) () -> @out T
|
|
|
|
// CHECK: SIL memory lifetime failure in @inject_enum_case: memory is not initialized, but should be
|
|
sil [ossa] @inject_enum_case : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = alloc_stack $Optional<T>
|
|
%1 = function_ref @initfn : $@convention(thin) () -> @out T
|
|
%2 = init_enum_data_addr %0, #Optional.some!enumelt
|
|
%3 = apply %1(%2) : $@convention(thin) () -> @out T
|
|
destroy_addr %0
|
|
inject_enum_addr %0, #Optional.some!enumelt
|
|
dealloc_stack %0
|
|
%10 = tuple ()
|
|
return %10
|
|
}
|
|
|
|
|
|
// CHECK: SIL memory lifetime failure in @mark_dependence_addr_uninit_base: memory is not initialized, but should be
|
|
sil [ossa] @mark_dependence_addr_uninit_base : $@convention(thin) (@owned T, @owned Inner) -> @owned Inner {
|
|
bb0(%0 : @owned $T, %1 : @owned $Inner):
|
|
%2 = alloc_stack $T
|
|
store %0 to [init] %2
|
|
%4 = alloc_stack $Inner
|
|
store %1 to [init] %4
|
|
destroy_addr %2
|
|
mark_dependence %4 on %2
|
|
%7 = begin_access [read] [dynamic] %4
|
|
%8 = load [take] %7
|
|
end_access %7
|
|
dealloc_stack %4
|
|
dealloc_stack %2
|
|
return %8
|
|
}
|
|
|
|
sil [ossa] @borrow_addressonly_prop : $@convention(method) <T> (@in_guaranteed GenWrapper<T>) -> @guaranteed_address T {
|
|
bb0(%0 : $*GenWrapper<T>):
|
|
%2 = struct_element_addr %0, #GenWrapper._prop
|
|
return %2
|
|
}
|
|
|
|
sil [ossa] @mutate_addressonly_prop : $@convention(method) <T> (@inout GenWrapper<T>) -> @inout T {
|
|
bb0(%0 : $*GenWrapper<T>):
|
|
%2 = struct_element_addr %0, #GenWrapper._prop
|
|
return %2
|
|
}
|
|
|
|
sil [ossa] @borrow_addressonly_nested_prop : $@convention(method) <T> (@in_guaranteed GenWrapper<T>) -> @guaranteed_address InnerWrapper<T> {
|
|
bb0(%0 : $*GenWrapper<T>):
|
|
%2 = struct_element_addr %0, #GenWrapper._nestedProp
|
|
return %2
|
|
}
|
|
|
|
sil [ossa] @mutate_addressonly_nested_prop : $@convention(method) <T> (@inout GenWrapper<T>) -> @inout InnerWrapper<T> {
|
|
bb0(%0 : $*GenWrapper<T>):
|
|
%2 = struct_element_addr %0, #GenWrapper._nestedProp
|
|
return %2
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_use_after_free_address_only1: memory is not initialized, but should be
|
|
// CHECK: memory location: %2 = apply %1<T>(%0) : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address τ_0_0
|
|
// CHECK: at instruction: %5 = apply %3<T>(%2) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
|
|
sil [ossa] @test_use_after_free_address_only1 : $@convention(thin) <T> (@in GenWrapper<T>) -> () {
|
|
bb0(%0 : $*GenWrapper<T>):
|
|
%1 = function_ref @borrow_addressonly_prop : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address τ_0_0
|
|
%2 = apply %1<T>(%0) : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address τ_0_0
|
|
%3 = function_ref @use_T : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
|
|
destroy_addr %0
|
|
%5 = apply %3<T>(%2) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
|
|
%6 = tuple ()
|
|
return %6
|
|
}
|
|
|
|
// CHECK: SIL memory lifetime failure in @test_use_after_free_address_only2: memory is not initialized, but should be
|
|
// CHECK: memory location: %2 = apply %1<T>(%0) : $@convention(method) <τ_0_0> (@inout GenWrapper<τ_0_0>) -> @inout τ_0_0
|
|
// CHECK: at instruction: %5 = apply %3<T>(%2) : $@convention(thin) <τ_0_0> (@inout τ_0_0) -> ()
|
|
sil [ossa] @test_use_after_free_address_only2 : $@convention(thin) <T> (@in GenWrapper<T>) -> () {
|
|
bb0(%0 : $*GenWrapper<T>):
|
|
%1 = function_ref @mutate_addressonly_prop : $@convention(method) <τ_0_0> (@inout GenWrapper<τ_0_0>) -> @inout τ_0_0
|
|
%2 = apply %1<T>(%0) : $@convention(method) <τ_0_0> (@inout GenWrapper<τ_0_0>) -> @inout τ_0_0
|
|
%3 = function_ref @mutate_T : $@convention(thin) <τ_0_0> (@inout τ_0_0) -> ()
|
|
destroy_addr %0
|
|
%5 = apply %3<T>(%2) : $@convention(thin) <τ_0_0> (@inout τ_0_0) -> ()
|
|
%6 = tuple ()
|
|
return %6
|
|
}
|
|
|
|
// TODO-CHECK: SIL memory lifetime failure in @test_guaranteed_address_consume: store-borrow location cannot be written
|
|
// TODO-CHECK: memory location: %2 = apply %1<T>(%0) : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address τ_0_0
|
|
// TODO-CHECK: at instruction: destroy_addr %2 : $*T
|
|
sil [ossa] @test_guaranteed_address_consume : $@convention(thin) <T> (@in GenWrapper<T>) -> () {
|
|
bb0(%0 : $*GenWrapper<T>):
|
|
%1 = function_ref @borrow_addressonly_prop : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address τ_0_0
|
|
%2 = apply %1<T>(%0) : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address τ_0_0
|
|
destroy_addr %2
|
|
%4 = tuple ()
|
|
return %4
|
|
}
|
|
|
|
// TODO-CHECK: SIL memory lifetime failure in @test_guaranteed_nested_address_consume: store-borrow location cannot be written
|
|
// TODO-CHECK: memory location: %3 = struct_element_addr %2 : $*InnerWrapper<T>, #InnerWrapper._prop
|
|
// TODO-CHECK: at instruction: destroy_addr %3 : $*T
|
|
sil [ossa] @test_guaranteed_nested_address_consume : $@convention(thin) <T> (@in GenWrapper<T>) -> () {
|
|
bb0(%0 : $*GenWrapper<T>):
|
|
%1 = function_ref @borrow_addressonly_nested_prop : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address InnerWrapper<τ_0_0>
|
|
%2 = apply %1<T>(%0) : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address InnerWrapper<τ_0_0>
|
|
%3 = struct_element_addr %2, #InnerWrapper._prop
|
|
destroy_addr %3
|
|
%4 = tuple ()
|
|
return %4
|
|
}
|
|
|