Files
swift-mirror/test/SIL/memory_lifetime_failures.sil

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
}