mirror of
https://github.com/apple/swift.git
synced 2026-02-27 18:26:24 +01:00
Even if an indirect argument is unused, pretend that the function reads from it. If the unused argument is passed to another generic function and that function is specialized, the argument may be re-abstracted and the specializer inserts a load from the indirect argument. Therefore we must be prepared that unused indirect argument might get loaded from at some time. Fixes a compiler crash rdar://168623362
964 lines
34 KiB
Plaintext
964 lines
34 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_non_escaping_closure_with_mark_dependence: memory is not initialized, but should be
|
|
sil [ossa] @test_non_escaping_closure_with_mark_dependence : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = alloc_stack $T
|
|
%func = function_ref @closure : $@convention(thin) (@in_guaranteed T) -> ()
|
|
%pa = partial_apply [callee_guaranteed] [on_stack] %func(%0) : $@convention(thin) (@in_guaranteed T) -> ()
|
|
%pa1 = mark_dependence %pa on %0
|
|
destroy_value %pa1 : $@noescape @callee_guaranteed () -> ()
|
|
dealloc_stack %0
|
|
%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
|
|
}
|
|
|