blob: bb3ee97ee64b051ee7d8b1f66091237733ef4352 [file] [log] [blame]
// RUN: %target-sil-opt -enable-objc-interop -enable-sil-verify-all=0 -module-name Swift -o /dev/null 2>&1 %s
// REQUIRES: asserts
// This file is meant to contain tests that previously the verifier treated
// incorrectly. This is important to ensure that the verifier does not
// regress. It should only deal with use matching.
sil_stage canonical
import Builtin
//////////////////
// Declarations //
//////////////////
typealias AnyObject = Builtin.AnyObject
public protocol Error {}
struct SomeError: Error {
var ptr: Builtin.NativeObject
}
enum Never {}
enum Optional<T> {
case some(T)
case none
}
enum ThreeDifferingPayloadEnum {
case nopayload
case trivial_payload(Builtin.Int32)
case nontrivial_payload(Builtin.NativeObject)
}
struct TrivialStruct {
var f1: Builtin.Int32
var f2: Builtin.Int32
}
struct NonTrivialStructWithTrivialField {
var owner: Builtin.NativeObject
var payload: Builtin.Int32
}
struct TupleContainingNonTrivialStruct {
var t: (Builtin.NativeObject, Builtin.NativeObject)
var opt: Optional<Builtin.NativeObject>
}
class SuperKlass {
func d() {}
class func f() {}
}
class SubKlass : SuperKlass {}
class X {
@objc func f() { }
@objc class func g() {}
}
protocol SwiftKlassP : class {
func foo()
}
struct Val {
}
class Ref {
}
struct Aleph {
var a:Ref
var b:Val
}
struct Int {
var value: Builtin.Int64
}
class RefWithInt {
var value: Builtin.Int32
init()
}
struct EmptyStruct {}
class RefWithRef {
var value: RefWithRef
init()
}
sil @no_arg_or_output_function : $@convention(thin) () -> ()
sil @allocate_object : $@convention(thin) () -> @owned Builtin.NativeObject
sil @three_differing_payload_enum_user : $@convention(thin) (@owned ThreeDifferingPayloadEnum, @guaranteed ThreeDifferingPayloadEnum, ThreeDifferingPayloadEnum) -> ()
sil @nontrivial_unowned_user : $@convention(thin) (Builtin.NativeObject) -> ()
sil @borrow_tuple_user : $@convention(thin) (@guaranteed (Builtin.Int32, Builtin.NativeObject, Builtin.Int32, Builtin.NativeObject)) -> ()
sil @unowned_tuple_user : $@convention(thin) ((Builtin.Int32, Builtin.NativeObject, Builtin.Int32, Builtin.NativeObject)) -> ()
sil @produce_owned_optional : $@convention(thin) () -> @owned Optional<Builtin.NativeObject>
sil @guaranteed_nativeobject_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
////////////////
// Test Cases //
////////////////
// Make sure that guaranteed args do not have a consuming use.
sil [ossa] @direct_guaranteed_arg_doesnt_have_consuming_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
bb0(%0 : @guaranteed $Builtin.NativeObject):
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @store_borrow_result : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
bb0(%0 : @guaranteed $Builtin.NativeObject):
%1 = alloc_stack $Builtin.NativeObject
store_borrow %0 to %1 : $*Builtin.NativeObject
dealloc_stack %1 : $*Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @load_borrow_from_class : $@convention(thin) (@guaranteed RefWithRef) -> () {
bb0(%0 : @guaranteed $RefWithRef):
%1 = ref_element_addr %0 : $RefWithRef, #RefWithRef.value
%2 = load_borrow %1 : $*RefWithRef
end_borrow %2 : $RefWithRef
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @trivial_struct_extract_from_non_trivial : $@convention(thin) (@guaranteed NonTrivialStructWithTrivialField) -> () {
bb0(%0 : @guaranteed $NonTrivialStructWithTrivialField):
%1 = struct_extract %0 : $NonTrivialStructWithTrivialField, #NonTrivialStructWithTrivialField.payload
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @trivial_struct_extract_from_trivial : $@convention(thin) (TrivialStruct) -> () {
bb0(%0 : $TrivialStruct):
%1 = struct_extract %0 : $TrivialStruct, #TrivialStruct.f1
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @in_address_arg : $@convention(thin) (@in Builtin.NativeObject) -> () {
bb0(%0 : $*Builtin.NativeObject):
destroy_addr %0 : $*Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}
// We shouldn't assert given an unowned argument that is never used.
sil [ossa] @non_trivial_unowned_arg : $@convention(thin) (Builtin.NativeObject) -> () {
bb0(%0 : @unowned $Builtin.NativeObject):
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @builtin_unreachable_has_a_return_value : $@convention(thin) () -> () {
bb0:
%0 = builtin "unreachable"() : $Never
unreachable
}
// Make sure that we can pass an owned, guaranteed, and unowned argument as
// unowned parameters such that the use is viewed as a non-lifetime ending use.
sil [ossa] @call_func_with_nontrivial_unowned_user_arg : $@convention(thin) (@owned Builtin.NativeObject, Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject, %1 : @unowned $Builtin.NativeObject):
%2 = function_ref @nontrivial_unowned_user : $@convention(thin) (Builtin.NativeObject) -> ()
apply %2(%0) : $@convention(thin) (Builtin.NativeObject) -> ()
%3 = begin_borrow %0 : $Builtin.NativeObject
apply %2(%3) : $@convention(thin) (Builtin.NativeObject) -> ()
end_borrow %3 : $Builtin.NativeObject
destroy_value %0 : $Builtin.NativeObject
apply %2(%1) : $@convention(thin) (Builtin.NativeObject) -> ()
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @forwarding_guaranteed_nonfunction_values_doesnt_end_lifetime : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject):
%1 = begin_borrow %0 : $Builtin.NativeObject
%2 = unchecked_ref_cast %1 : $Builtin.NativeObject to $SuperKlass
end_borrow %1 : $Builtin.NativeObject
destroy_value %0 : $Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @alloc_value_buffer_dealloc_value_buffer : $@convention(thin) (@inout Builtin.UnsafeValueBuffer, Builtin.Int32) -> () {
bb0(%0 : $*Builtin.UnsafeValueBuffer, %1 : $Builtin.Int32):
%2 = alloc_value_buffer $Builtin.Int32 in %0 : $*Builtin.UnsafeValueBuffer
store %1 to [trivial] %2 : $*Builtin.Int32
dealloc_value_buffer $Builtin.Int32 in %0 : $*Builtin.UnsafeValueBuffer
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @builtins_test : $@convention(thin) (@owned Error, Builtin.Int1, Builtin.RawPointer, Builtin.Word) -> ((), @error Error) {
bb0(%0 : @owned $Error, %1 : $Builtin.Int1, %2 : $Builtin.RawPointer, %3 : $Builtin.Word):
%4 = metatype $@thick Builtin.Int32.Type
builtin "willThrow"(%0 : $Error) : $()
builtin "onFastPath"() : $()
builtin "staticReport"(%1 : $Builtin.Int1, %1 : $Builtin.Int1, %2 : $Builtin.RawPointer) : $()
builtin "destroyArray"<Builtin.Int32>(%4 : $@thick Builtin.Int32.Type, %2 : $Builtin.RawPointer, %3 : $Builtin.Word) : $()
builtin "copyArray"<Builtin.Int32>(%4 : $@thick Builtin.Int32.Type, %2 : $Builtin.RawPointer, %2 : $Builtin.RawPointer, %3 : $Builtin.Word) : $()
builtin "takeArrayFrontToBack"<Builtin.Int32>(%4 : $@thick Builtin.Int32.Type, %2 : $Builtin.RawPointer, %2 : $Builtin.RawPointer, %3 : $Builtin.Word) : $()
builtin "takeArrayBackToFront"<Builtin.Int32>(%4 : $@thick Builtin.Int32.Type, %2 : $Builtin.RawPointer, %2 : $Builtin.RawPointer, %3 : $Builtin.Word) : $()
builtin "unexpectedError"(%0 : $Error) : $()
builtin "errorInMain"(%0 : $Error) : $()
%5 = integer_literal $Builtin.Int64, 0
%6 = struct $Int(%5 : $Builtin.Int64)
builtin "deallocRaw"(%2 : $Builtin.RawPointer, %6 : $Int, %6 : $Int) : $()
builtin "fence_acquire"() : $()
%7 = integer_literal $Builtin.Int32, 0
builtin "atomicstore_release_Int32"(%2 : $Builtin.RawPointer, %7 : $Builtin.Int32) : $()
%8 = function_ref @no_arg_or_output_function : $@convention(thin) () -> ()
builtin "once"(%2 : $Builtin.RawPointer, %8 : $@convention(thin) () -> ()) : $()
throw %0 : $Error
}
sil [ossa] @existential_box_test : $@convention(thin) (@owned SomeError) -> () {
bb0(%0 : @owned $SomeError):
%1 = alloc_existential_box $Error, $SomeError
%2 = project_existential_box $SomeError in %1 : $Error
store %0 to [init] %2 : $*SomeError
%4 = open_existential_box %1 : $Error to $*@opened("01234567-89AB-CDEF-0123-333333333333") Error
destroy_addr %4 : $*@opened("01234567-89AB-CDEF-0123-333333333333") Error
dealloc_existential_box %1 : $Error, $SomeError
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @tail_allocated_alloc_ref : $@convention(thin) (Builtin.Word, Builtin.Word, @thick SuperKlass.Type) -> () {
bb0(%0 : $Builtin.Word, %1 : $Builtin.Word, %2 : $@thick SuperKlass.Type):
%3 = alloc_ref [tail_elems $Val * %0 : $Builtin.Word] [tail_elems $Aleph * %1 : $Builtin.Word] $SuperKlass
dealloc_ref %3 : $SuperKlass
%4 = alloc_ref_dynamic [tail_elems $Val * %0 : $Builtin.Word] [tail_elems $Aleph * %1 : $Builtin.Word] %2 : $@thick SuperKlass.Type, $SuperKlass
// CHECK: dealloc_ref %3 : $Class1
dealloc_ref %4 : $SuperKlass
%9999 = tuple()
return %9999 : $()
}
// All of these uses should not be consuming except for the destroy.
sil [ossa] @select_enum_test : $@convention(thin) (@owned ThreeDifferingPayloadEnum, @owned Builtin.NativeObject, Optional<Builtin.Int32>, @owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $ThreeDifferingPayloadEnum, %1 : @owned $Builtin.NativeObject, %2 : $Optional<Builtin.Int32>, %3 : @owned $Builtin.NativeObject):
%4 = integer_literal $Builtin.Int32, 2
select_enum %0 : $ThreeDifferingPayloadEnum, case #ThreeDifferingPayloadEnum.nopayload!enumelt: %4, case #ThreeDifferingPayloadEnum.trivial_payload!enumelt.1: %4, case #ThreeDifferingPayloadEnum.nontrivial_payload!enumelt.1: %4 : $Builtin.Int32
%5 = select_enum %2 : $Optional<Builtin.Int32>, case #Optional.none!enumelt: %1, case #Optional.some!enumelt.1: %3 : $Builtin.NativeObject
destroy_value %5 : $Builtin.NativeObject
destroy_value %0 : $ThreeDifferingPayloadEnum
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @cast_tests : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject):
%2 = unchecked_trivial_bit_cast %0 : $Builtin.NativeObject to $Builtin.RawPointer
%3 = unchecked_trivial_bit_cast %2 : $Builtin.RawPointer to $Builtin.RawPointer
destroy_value %0 : $Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @existential_metatype_test : $@convention(thin) (@owned SwiftKlassP, @in SwiftKlassP) -> () {
bb0(%0 : @owned $SwiftKlassP, %1 : $*SwiftKlassP):
%2 = existential_metatype $@thick SwiftKlassP.Type, %0 : $SwiftKlassP
%3 = existential_metatype $@thick SwiftKlassP.Type, %1 : $*SwiftKlassP
destroy_value %0 : $SwiftKlassP
destroy_addr %1 : $*SwiftKlassP
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @value_metatype_test : $@convention(thin) (@owned Ref, @in Ref) -> () {
bb0(%0 : @owned $Ref, %1 : $*Ref):
%2 = value_metatype $@thick Ref.Type, %0 : $Ref
%3 = value_metatype $@thick Ref.Type, %1 : $*Ref
destroy_value %0 : $Ref
destroy_addr %1 : $*Ref
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @ref_element_addr_test : $@convention(thin) (@owned RefWithInt) -> () {
bb0(%0 : @owned $RefWithInt):
%1 = begin_borrow %0 : $RefWithInt
%2 = ref_element_addr %1 : $RefWithInt, #RefWithInt.value
end_borrow %1 : $RefWithInt
destroy_value %0 : $RefWithInt
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @trivial_payload_enum_pass_to_apply : $@convention(thin) () -> () {
bb0:
%0 = enum $ThreeDifferingPayloadEnum, #ThreeDifferingPayloadEnum.nopayload!enumelt
%1 = function_ref @three_differing_payload_enum_user : $@convention(thin) (@owned ThreeDifferingPayloadEnum, @guaranteed ThreeDifferingPayloadEnum, ThreeDifferingPayloadEnum) -> ()
apply %1(%0, %0, %0) : $@convention(thin) (@owned ThreeDifferingPayloadEnum, @guaranteed ThreeDifferingPayloadEnum, ThreeDifferingPayloadEnum) -> ()
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @unsafeGuaranteedTest : $@convention(thin) (@owned Ref) -> () {
bb0(%0 : @owned $Ref):
%1 = builtin "unsafeGuaranteed"(%0 : $Ref) : $(Ref, Builtin.Int8)
%2 = begin_borrow %1 : $(Ref, Builtin.Int8)
%3 = tuple_extract %2 : $(Ref, Builtin.Int8), 1
end_borrow %2 : $(Ref, Builtin.Int8)
builtin "unsafeGuaranteedEnd"(%3 : $Builtin.Int8) : $()
destroy_value %1 : $(Ref, Builtin.Int8)
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @unchecked_enum_data_propagates_ownership : $@convention(thin) (@owned Optional<Builtin.NativeObject>) -> @owned Builtin.NativeObject {
bb0(%0 : @owned $Optional<Builtin.NativeObject>):
%1 = begin_borrow %0 : $Optional<Builtin.NativeObject>
unchecked_enum_data %1 : $Optional<Builtin.NativeObject>, #Optional.some!enumelt.1
unchecked_enum_data %1 : $Optional<Builtin.NativeObject>, #Optional.some!enumelt.1
unchecked_enum_data %1 : $Optional<Builtin.NativeObject>, #Optional.some!enumelt.1
end_borrow %1 : $Optional<Builtin.NativeObject>
%2 = unchecked_enum_data %0 : $Optional<Builtin.NativeObject>, #Optional.some!enumelt.1
return %2 : $Builtin.NativeObject
}
sil [ossa] @access_tests : $@convention(thin) () -> () {
bb0:
%0 = alloc_box ${ var Builtin.Int64 }, var, name "x"
%1 = project_box %0 : ${ var Builtin.Int64 }, 0
%2 = begin_access [read] [static] %1 : $*Builtin.Int64
%3 = load [trivial] %2 : $*Builtin.Int64
end_access %2 : $*Builtin.Int64
destroy_value %0 : ${ var Builtin.Int64 }
%01 = alloc_ref $RefWithInt
%011 = begin_borrow %01 : $RefWithInt
%11 = alloc_stack $Builtin.UnsafeValueBuffer
%21 = ref_element_addr %011 : $RefWithInt, #RefWithInt.value
begin_unpaired_access [modify] [dynamic] %21 : $*Builtin.Int32, %11 : $*Builtin.UnsafeValueBuffer
end_unpaired_access [dynamic] %11 : $*Builtin.UnsafeValueBuffer
begin_unpaired_access [read] [dynamic] %21 : $*Builtin.Int32, %11 : $*Builtin.UnsafeValueBuffer
end_unpaired_access [dynamic] %11 : $*Builtin.UnsafeValueBuffer
end_borrow %011 : $RefWithInt
dealloc_stack %11 : $*Builtin.UnsafeValueBuffer
destroy_value %01 : $RefWithInt
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @block_invoke_test : $@convention(thin) (@owned @convention(block) () -> ()) -> () {
bb0(%0 : @owned $@convention(block) () -> ()):
apply %0() : $@convention(block) () -> ()
destroy_value %0 : $@convention(block) () -> ()
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @class_method_metatype_test : $@convention(thin) (@thick SuperKlass.Type) -> () {
bb0(%0 : $@thick SuperKlass.Type):
%1 = class_method %0 : $@thick SuperKlass.Type, #SuperKlass.d!1 : (SuperKlass) -> () -> (), $@convention(method) (@guaranteed SuperKlass) -> ()
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @trivial_enum_return_value : $@convention(thin) () -> @owned Optional<Builtin.NativeObject> {
bb0:
%0 = enum $Optional<Builtin.NativeObject>, #Optional.none!enumelt
return %0 : $Optional<Builtin.NativeObject>
}
sil [ossa] @c_function : $@convention(c) (@inout_aliasable @block_storage @callee_owned () -> ()) -> ()
sil [ossa] @test_block_storage : $@convention(thin) () -> () {
bb0:
%0 = function_ref @c_function : $@convention(c) (@inout_aliasable @block_storage @callee_owned () -> ()) -> ()
%1 = alloc_stack $@block_storage @callee_owned () -> ()
%2 = project_block_storage %1 : $*@block_storage @callee_owned () -> ()
%3 = init_block_storage_header %1 : $*@block_storage @callee_owned () -> (), invoke %0 : $@convention(c) (@inout_aliasable @block_storage @callee_owned () -> ()) -> (), type $@convention(block) () -> ()
dealloc_stack %1 : $*@block_storage @callee_owned () -> ()
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @test_store_weak : $@convention(thin) (@owned Optional<SuperKlass>, @in @sil_weak Optional<SuperKlass>, @guaranteed Optional<SuperKlass>) -> () {
bb0(%0 : @owned $Optional<SuperKlass>, %1 : $*@sil_weak Optional<SuperKlass>, %2 : @guaranteed $Optional<SuperKlass>):
store_weak %0 to %1 : $*@sil_weak Optional<SuperKlass>
store_weak %2 to %1 : $*@sil_weak Optional<SuperKlass>
destroy_value %0 : $Optional<SuperKlass>
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @test_dealloc_partial_ref : $@convention(thin) (@owned SuperKlass) -> () {
bb0(%0 : @owned $SuperKlass):
%1 = metatype $@thick SuperKlass.Type
dealloc_partial_ref %0 : $SuperKlass, %1 : $@thick SuperKlass.Type
%9999 = tuple()
return %9999 : $()
}
//////////////////////
// Terminator Tests //
//////////////////////
sil [ossa] @simple_branch : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject):
// Simple branch without an argument.
br bb1
bb1:
// Branch with multiple trivial arguments
%1 = integer_literal $Builtin.Int32, 0
br bb2(%1 : $Builtin.Int32, %1 : $Builtin.Int32)
bb2(%2 : $Builtin.Int32, %3 : $Builtin.Int32):
// Branch with mixed trivial and owned argument
br bb3(%1 : $Builtin.Int32, %0 : $Builtin.NativeObject, %2 : $Builtin.Int32)
bb3(%4 : $Builtin.Int32, %5 : @owned $Builtin.NativeObject, %6 : $Builtin.Int32):
destroy_value %5 : $Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}
// Make sure that we can propagate through an argument through an enum that is
// switched upon and whose payload is then destroyed.
sil [ossa] @switch_enum_owned_payload_test : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject):
%1 = enum $Optional<Builtin.NativeObject>, #Optional.some!enumelt.1, %0 : $Builtin.NativeObject
switch_enum %1 : $Optional<Builtin.NativeObject>, case #Optional.some!enumelt.1: bb1, case #Optional.none!enumelt: bb2
bb1(%2 : @owned $Builtin.NativeObject):
destroy_value %2 : $Builtin.NativeObject
br bb3
bb2:
br bb3
bb3:
%9999 = tuple()
return %9999 : $()
}
// Make sure that we can propagate through an argument through an enum that is
// switched upon and whose payload is then destroyed.
sil [ossa] @switch_enum_owned_payload_test2 : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject):
%1 = enum $Optional<Builtin.NativeObject>, #Optional.some!enumelt.1, %0 : $Builtin.NativeObject
switch_enum %1 : $Optional<Builtin.NativeObject>, case #Optional.none!enumelt: bb1, case #Optional.some!enumelt.1: bb2
bb1:
br bb3
bb2(%2 : @owned $Builtin.NativeObject):
destroy_value %2 : $Builtin.NativeObject
br bb3
bb3:
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @switch_enum_owned_payload_test3 : $@convention(thin) () -> () {
bb0:
%1 = enum $Optional<Builtin.NativeObject>, #Optional.none!enumelt
switch_enum %1 : $Optional<Builtin.NativeObject>, case #Optional.none!enumelt: bb1, case #Optional.some!enumelt.1: bb2
bb1:
br bb3
bb2(%2 : @owned $Builtin.NativeObject):
destroy_value %2 : $Builtin.NativeObject
br bb3
bb3:
%9999 = tuple()
return %9999 : $()
}
// Make sure that we can propagate through an argument through an enum that is
// switched upon and whose payload is then destroyed.
sil [ossa] @switch_enum_owned_payload_test4 : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject):
%1 = enum $Optional<Builtin.NativeObject>, #Optional.some!enumelt.1, %0 : $Builtin.NativeObject
switch_enum %1 : $Optional<Builtin.NativeObject>, case #Optional.some!enumelt.1: bb2, case #Optional.none!enumelt: bb1
bb1:
br bb3
bb2(%2 : @owned $Builtin.NativeObject):
destroy_value %2 : $Builtin.NativeObject
br bb3
bb3:
%9999 = tuple()
return %9999 : $()
}
// Make sure that we can properly handle a guaranteed switch_enum.
sil [ossa] @switch_enum_guaranteed_arg_test : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
bb0(%0 : @guaranteed $Builtin.NativeObject):
%1 = enum $Optional<Builtin.NativeObject>, #Optional.some!enumelt.1, %0 : $Builtin.NativeObject
switch_enum %1 : $Optional<Builtin.NativeObject>, case #Optional.some!enumelt.1: bb1, case #Optional.none!enumelt: bb2
bb1(%2 : @guaranteed $Builtin.NativeObject):
end_borrow %2 : $Builtin.NativeObject
br bb3
bb2:
br bb3
bb3:
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @switch_enum_guaranteed_beginborrow_test_1a : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject):
%1 = begin_borrow %0 : $Builtin.NativeObject
%2 = enum $Optional<Builtin.NativeObject>, #Optional.some!enumelt.1, %1 : $Builtin.NativeObject
switch_enum %2 : $Optional<Builtin.NativeObject>, case #Optional.some!enumelt.1: bb1, case #Optional.none!enumelt: bb2
bb1(%3 : @guaranteed $Builtin.NativeObject):
end_borrow %3 : $Builtin.NativeObject
end_borrow %1 : $Builtin.NativeObject
br bb3
bb2:
end_borrow %1 : $Builtin.NativeObject
br bb3
bb3:
destroy_value %0 : $Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @switch_enum_guaranteed_beginborrow_test_1b : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject):
%1 = begin_borrow %0 : $Builtin.NativeObject
%2 = enum $Optional<Builtin.NativeObject>, #Optional.some!enumelt.1, %1 : $Builtin.NativeObject
switch_enum %2 : $Optional<Builtin.NativeObject>, case #Optional.some!enumelt.1: bb1, case #Optional.none!enumelt: bb2
bb1(%3 : @guaranteed $Builtin.NativeObject):
end_borrow %3 : $Builtin.NativeObject
br bb3
bb2:
br bb3
bb3:
end_borrow %1 : $Builtin.NativeObject
destroy_value %0 : $Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @switch_enum_guaranteed_beginborrow_test_2 : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject):
%1 = enum $Optional<Builtin.NativeObject>, #Optional.some!enumelt.1, %0 : $Builtin.NativeObject
%2 = begin_borrow %1 : $Optional<Builtin.NativeObject>
switch_enum %2 : $Optional<Builtin.NativeObject>, case #Optional.some!enumelt.1: bb1, case #Optional.none!enumelt: bb2
bb1(%3 : @guaranteed $Builtin.NativeObject):
end_borrow %3 : $Builtin.NativeObject
br bb3
bb2:
br bb3
bb3:
end_borrow %2 : $Optional<Builtin.NativeObject>
destroy_value %1 : $Optional<Builtin.NativeObject>
%9999 = tuple()
return %9999 : $()
}
// Make sure that we can properly handle a switch enum case where the input
// argument is an enum, but the final argument is trivial.
sil [ossa] @switch_enum_no_payload_test : $@convention(thin) () -> () {
bb0:
%0 = enum $Optional<Builtin.NativeObject>, #Optional.none!enumelt
switch_enum %0 : $Optional<Builtin.NativeObject>, case #Optional.some!enumelt.1: bb1, case #Optional.none!enumelt: bb2
bb1(%1 : @owned $Builtin.NativeObject):
destroy_value %1 : $Builtin.NativeObject
br bb3
bb2:
br bb3
bb3:
%9999 = tuple()
return %9999 : $()
}
// Test various combinations of enum payload arguments to make sure that we
// handle the ordering in an invariant way. The specific interesting cases here are:
//
// 1. initial value, second value, and remaining values.
// 2. input enum is no payload, trivial payload, non-trivial payload
//
// The reason why this is interesting is that we do a loop over enum cases to
// determine if we have all trivial cases. If we do, then we only accept a
// ownership kind to the switch enum. Otherwise, we only accept an
// @owned trivial ownership kind. When we do the loop, we first skip over all
// trivial enums and then process only the non-trivial enums. That is why we
// need to make sure we handle all 3 cases.
sil [ossa] @three_different_payload_enum_ordering : $@convention(thin) () -> () {
bb0:
%0 = integer_literal $Builtin.Int32, 0
%1 = function_ref @allocate_object : $@convention(thin) () -> @owned Builtin.NativeObject
br bb1
bb1:
%2 = apply %1() : $@convention(thin) () -> @owned Builtin.NativeObject
%e1a = enum $ThreeDifferingPayloadEnum, #ThreeDifferingPayloadEnum.nontrivial_payload!enumelt.1, %2 : $Builtin.NativeObject
switch_enum %e1a : $ThreeDifferingPayloadEnum, case #ThreeDifferingPayloadEnum.nontrivial_payload!enumelt.1: bb2, case #ThreeDifferingPayloadEnum.trivial_payload!enumelt.1: bb3, case #ThreeDifferingPayloadEnum.nopayload!enumelt: bb4
bb2(%10 : @owned $Builtin.NativeObject):
destroy_value %10 : $Builtin.NativeObject
br bb5
bb3(%11 : $Builtin.Int32):
br bb5
bb4:
br bb5
bb5:
%3 = apply %1() : $@convention(thin) () -> @owned Builtin.NativeObject
%e1b = enum $ThreeDifferingPayloadEnum, #ThreeDifferingPayloadEnum.nontrivial_payload!enumelt.1, %3 : $Builtin.NativeObject
switch_enum %e1b : $ThreeDifferingPayloadEnum, case #ThreeDifferingPayloadEnum.trivial_payload!enumelt.1: bb7, case #ThreeDifferingPayloadEnum.nopayload!enumelt: bb8, case #ThreeDifferingPayloadEnum.nontrivial_payload!enumelt.1: bb6
bb6(%12 : @owned $Builtin.NativeObject):
destroy_value %12 : $Builtin.NativeObject
br bb9
bb7(%13 : $Builtin.Int32):
br bb9
bb8:
br bb9
bb9:
%4 = apply %1() : $@convention(thin) () -> @owned Builtin.NativeObject
%e1c = enum $ThreeDifferingPayloadEnum, #ThreeDifferingPayloadEnum.nontrivial_payload!enumelt.1, %4 : $Builtin.NativeObject
switch_enum %e1c : $ThreeDifferingPayloadEnum, case #ThreeDifferingPayloadEnum.nopayload!enumelt: bb12, case #ThreeDifferingPayloadEnum.nontrivial_payload!enumelt.1: bb10, case #ThreeDifferingPayloadEnum.trivial_payload!enumelt.1: bb11
bb10(%14 : @owned $Builtin.NativeObject):
destroy_value %14 : $Builtin.NativeObject
br bb13
bb11(%15 : $Builtin.Int32):
br bb13
bb12:
br bb13
bb13:
%e2 = enum $ThreeDifferingPayloadEnum, #ThreeDifferingPayloadEnum.trivial_payload!enumelt.1, %0 : $Builtin.Int32
switch_enum %e2 : $ThreeDifferingPayloadEnum, case #ThreeDifferingPayloadEnum.nontrivial_payload!enumelt.1: bb16, case #ThreeDifferingPayloadEnum.trivial_payload!enumelt.1: bb18, case #ThreeDifferingPayloadEnum.nopayload!enumelt: bb20
bb16(%17 : @owned $Builtin.NativeObject):
destroy_value %17 : $Builtin.NativeObject
br bb21
bb18(%19 : $Builtin.Int32):
br bb21
bb20:
br bb21
bb21:
switch_enum %e2 : $ThreeDifferingPayloadEnum, case #ThreeDifferingPayloadEnum.trivial_payload!enumelt.1: bb24, case #ThreeDifferingPayloadEnum.nopayload!enumelt: bb26, case #ThreeDifferingPayloadEnum.nontrivial_payload!enumelt.1: bb22
bb22(%23 : @owned $Builtin.NativeObject):
destroy_value %23 : $Builtin.NativeObject
br bb27
bb24(%25 : $Builtin.Int32):
br bb27
bb26:
br bb27
bb27:
switch_enum %e2 : $ThreeDifferingPayloadEnum, case #ThreeDifferingPayloadEnum.nopayload!enumelt: bb32, case #ThreeDifferingPayloadEnum.nontrivial_payload!enumelt.1: bb28, case #ThreeDifferingPayloadEnum.trivial_payload!enumelt.1: bb30
bb28(%29 : @owned $Builtin.NativeObject):
destroy_value %29 : $Builtin.NativeObject
br bb33
bb30(%31 : $Builtin.Int32):
br bb33
bb32:
br bb33
bb33:
%e3 = enum $ThreeDifferingPayloadEnum, #ThreeDifferingPayloadEnum.nopayload!enumelt
switch_enum %e3 : $ThreeDifferingPayloadEnum, case #ThreeDifferingPayloadEnum.nontrivial_payload!enumelt.1: bb34, case #ThreeDifferingPayloadEnum.trivial_payload!enumelt.1: bb36, case #ThreeDifferingPayloadEnum.nopayload!enumelt: bb38
bb34(%35 : @owned $Builtin.NativeObject):
destroy_value %35 : $Builtin.NativeObject
br bb39
bb36(%37 : $Builtin.Int32):
br bb39
bb38:
br bb39
bb39:
switch_enum %e3 : $ThreeDifferingPayloadEnum, case #ThreeDifferingPayloadEnum.trivial_payload!enumelt.1: bb42, case #ThreeDifferingPayloadEnum.nopayload!enumelt: bb44, case #ThreeDifferingPayloadEnum.nontrivial_payload!enumelt.1: bb40
bb40(%41 : @owned $Builtin.NativeObject):
destroy_value %41 : $Builtin.NativeObject
br bb45
bb42(%43 : $Builtin.Int32):
br bb45
bb44:
br bb45
bb45:
switch_enum %e3 : $ThreeDifferingPayloadEnum, case #ThreeDifferingPayloadEnum.nopayload!enumelt: bb50, case #ThreeDifferingPayloadEnum.nontrivial_payload!enumelt.1: bb46, case #ThreeDifferingPayloadEnum.trivial_payload!enumelt.1: bb48
bb46(%47 : @owned $Builtin.NativeObject):
destroy_value %47 : $Builtin.NativeObject
br bb51
bb48(%49 : $Builtin.Int32):
br bb51
bb50:
br bb51
bb51:
%9999 = tuple()
return %9999 : $()
}
// We check first for objects, then for metatypes, then for guaranteed values
sil [ossa] @checked_cast_br_test : $@convention(thin) (@owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject, %6 : @guaranteed $Builtin.NativeObject):
checked_cast_br %0 : $Builtin.NativeObject to $SuperKlass, bb1, bb2
bb1(%1 : @owned $SuperKlass):
destroy_value %1 : $SuperKlass
br bb3
bb2(%2 : @owned $Builtin.NativeObject):
destroy_value %2 : $Builtin.NativeObject
br bb3
bb3:
%3 = metatype $@thick SuperKlass.Type
checked_cast_br %3 : $@thick SuperKlass.Type to $@thick SubKlass.Type, bb4, bb5
bb4(%4 : $@thick SubKlass.Type):
br bb6
bb5(%5 : $@thick SuperKlass.Type):
br bb6
bb6:
checked_cast_br %6 : $Builtin.NativeObject to $SuperKlass, bb7, bb8
bb7(%7 : @guaranteed $SuperKlass):
end_borrow %7 : $SuperKlass
br bb9
bb8(%8 : @guaranteed $Builtin.NativeObject):
end_borrow %8 : $Builtin.NativeObject
br bb9
bb9:
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @dynamic_method_br_test : $@convention(thin) (@owned AnyObject, @thick AnyObject.Type) -> () {
bb0(%0 : @owned $AnyObject, %1 : $@thick AnyObject.Type):
%2 = open_existential_ref %0 : $AnyObject to $@opened("01234567-89ab-cdef-0123-000000000000") AnyObject
%3 = unchecked_ref_cast %2 : $@opened("01234567-89ab-cdef-0123-000000000000") AnyObject to $Builtin.UnknownObject
dynamic_method_br %3 : $Builtin.UnknownObject, #X.f!1.foreign, bb1, bb2
bb1(%4 : $@convention(objc_method) (Builtin.UnknownObject) -> ()):
br bb3
bb2:
br bb3
bb3:
destroy_value %3 : $Builtin.UnknownObject
%5 = open_existential_metatype %1 : $@thick AnyObject.Type to $@thick (@opened("01234567-89ab-cdef-0123-000000000001") AnyObject).Type
dynamic_method_br %5 : $@thick (@opened("01234567-89ab-cdef-0123-000000000001") AnyObject).Type, #X.g!1.foreign, bb4, bb5
bb4(%6 : $@convention(objc_method) (@thick (@opened("01234567-89ab-cdef-0123-000000000001") AnyObject).Type) -> ()):
br bb6
bb5:
br bb6
bb6:
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @enum_cases_with_trivial_owned_cases_arg_into_phi : $@convention(thin) (@owned Builtin.NativeObject) -> @owned ThreeDifferingPayloadEnum {
bb0(%0 : @owned $Builtin.NativeObject):
cond_br undef, bb1, bb2
bb1:
cond_br undef, bb3, bb4
bb2:
%1 = enum $ThreeDifferingPayloadEnum, #ThreeDifferingPayloadEnum.nopayload!enumelt
destroy_value %0 : $Builtin.NativeObject
br bb5(%1 : $ThreeDifferingPayloadEnum)
bb3:
%2 = enum $ThreeDifferingPayloadEnum, #ThreeDifferingPayloadEnum.nontrivial_payload!enumelt.1, %0 : $Builtin.NativeObject
br bb5(%2 : $ThreeDifferingPayloadEnum)
bb4:
%3 = integer_literal $Builtin.Int32, 0
%4 = enum $ThreeDifferingPayloadEnum, #ThreeDifferingPayloadEnum.trivial_payload!enumelt.1, %3 : $Builtin.Int32
destroy_value %0 : $Builtin.NativeObject
br bb5(%4 : $ThreeDifferingPayloadEnum)
bb5(%5 : @owned $ThreeDifferingPayloadEnum):
return %5 : $ThreeDifferingPayloadEnum
}
sil [ossa] @enum_cases_with_trivial_unowned_cases_arg_into_phi : $@convention(thin) (Builtin.NativeObject) -> ThreeDifferingPayloadEnum {
bb0(%0 : @unowned $Builtin.NativeObject):
cond_br undef, bb1, bb2
bb1:
cond_br undef, bb3, bb4
bb2:
%1 = enum $ThreeDifferingPayloadEnum, #ThreeDifferingPayloadEnum.nopayload!enumelt
br bb5(%1 : $ThreeDifferingPayloadEnum)
bb3:
%2 = enum $ThreeDifferingPayloadEnum, #ThreeDifferingPayloadEnum.nontrivial_payload!enumelt.1, %0 : $Builtin.NativeObject
br bb5(%2 : $ThreeDifferingPayloadEnum)
bb4:
%3 = integer_literal $Builtin.Int32, 0
%4 = enum $ThreeDifferingPayloadEnum, #ThreeDifferingPayloadEnum.trivial_payload!enumelt.1, %3 : $Builtin.Int32
br bb5(%4 : $ThreeDifferingPayloadEnum)
bb5(%5 : @unowned $ThreeDifferingPayloadEnum):
return %5 : $ThreeDifferingPayloadEnum
}
sil [ossa] @enum_cases_with_trivial_guaranteed_cases_arg_into_phi : $@convention(thin) (@guaranteed Builtin.NativeObject) -> @owned ThreeDifferingPayloadEnum {
bb0(%0 : @guaranteed $Builtin.NativeObject):
cond_br undef, bb1, bb2
bb1:
cond_br undef, bb3, bb4
bb2:
%1 = enum $ThreeDifferingPayloadEnum, #ThreeDifferingPayloadEnum.nopayload!enumelt
br bb5(%1 : $ThreeDifferingPayloadEnum)
bb3:
%2 = enum $ThreeDifferingPayloadEnum, #ThreeDifferingPayloadEnum.nontrivial_payload!enumelt.1, %0 : $Builtin.NativeObject
br bb5(%2 : $ThreeDifferingPayloadEnum)
bb4:
%3 = integer_literal $Builtin.Int32, 0
%4 = enum $ThreeDifferingPayloadEnum, #ThreeDifferingPayloadEnum.trivial_payload!enumelt.1, %3 : $Builtin.Int32
br bb5(%4 : $ThreeDifferingPayloadEnum)
bb5(%5 : @guaranteed $ThreeDifferingPayloadEnum):
%6 = copy_value %5 : $ThreeDifferingPayloadEnum
end_borrow %5 : $ThreeDifferingPayloadEnum
return %6 : $ThreeDifferingPayloadEnum
}
sil [ossa] @enum_cases_with_trivial_guaranteed_cases_value_into_phi : $@convention(thin) (@owned Builtin.NativeObject) -> @owned ThreeDifferingPayloadEnum {
bb0(%0 : @owned $Builtin.NativeObject):
cond_br undef, bb1, bb2
bb1:
%1 = begin_borrow %0 : $Builtin.NativeObject
cond_br undef, bb3, bb4
bb2:
%2 = enum $ThreeDifferingPayloadEnum, #ThreeDifferingPayloadEnum.nopayload!enumelt
br bb6(%2 : $ThreeDifferingPayloadEnum)
bb3:
%3 = enum $ThreeDifferingPayloadEnum, #ThreeDifferingPayloadEnum.nontrivial_payload!enumelt.1, %1 : $Builtin.NativeObject
br bb5(%3 : $ThreeDifferingPayloadEnum)
bb4:
%4 = integer_literal $Builtin.Int32, 0
%5 = enum $ThreeDifferingPayloadEnum, #ThreeDifferingPayloadEnum.trivial_payload!enumelt.1, %4 : $Builtin.Int32
br bb5(%5 : $ThreeDifferingPayloadEnum)
bb5(%6 : @guaranteed $ThreeDifferingPayloadEnum):
%7 = copy_value %6 : $ThreeDifferingPayloadEnum
end_borrow %6 : $ThreeDifferingPayloadEnum
end_borrow %1 : $Builtin.NativeObject
br bb6(%7 : $ThreeDifferingPayloadEnum)
bb6(%8 : @owned $ThreeDifferingPayloadEnum):
destroy_value %0 : $Builtin.NativeObject
return %8 : $ThreeDifferingPayloadEnum
}
/////////////////////
// Aggregate Tests //
/////////////////////
// These tests make sure that we properly handle @owned forwarding of multiple
// levels of aggregate.
sil [ossa] @owned_aggregates_simple : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> (@owned (Builtin.NativeObject, Builtin.NativeObject)) {
bb0(%0 : @owned $Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
%2 = tuple(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject)
return %2 : $(Builtin.NativeObject, Builtin.NativeObject)
}
sil [ossa] @multiple_level_owned_aggregates : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> (@owned TupleContainingNonTrivialStruct) {
bb0(%0 : @owned $Builtin.NativeObject, %1 : @owned $Builtin.NativeObject, %2 : @owned $Builtin.NativeObject):
%3 = tuple(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject)
%4 = enum $Optional<Builtin.NativeObject>, #Optional.some!enumelt.1, %2 : $Builtin.NativeObject
%5 = struct $TupleContainingNonTrivialStruct(%3 : $(Builtin.NativeObject, Builtin.NativeObject), %4 : $Optional<Builtin.NativeObject>)
return %5 : $TupleContainingNonTrivialStruct
}
sil [ossa] @aggregates_with_mixed_trivial_nontrivial_types : $@convention(thin) (@owned Builtin.NativeObject, @guaranteed Builtin.NativeObject, Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject, %1 : @guaranteed $Builtin.NativeObject, %2 : @unowned $Builtin.NativeObject):
%3 = integer_literal $Builtin.Int32, 1
%4 = copy_value %0 : $Builtin.NativeObject
%5 = copy_value %2 : $Builtin.NativeObject
%6 = tuple(%3 : $Builtin.Int32, %4 : $Builtin.NativeObject, %3 : $Builtin.Int32, %5 : $Builtin.NativeObject)
destroy_value %6 : $(Builtin.Int32, Builtin.NativeObject, Builtin.Int32, Builtin.NativeObject)
%7 = tuple(%3 : $Builtin.Int32, %1 : $Builtin.NativeObject, %3 : $Builtin.Int32, %1 : $Builtin.NativeObject)
%8 = function_ref @borrow_tuple_user : $@convention(thin) (@guaranteed (Builtin.Int32, Builtin.NativeObject, Builtin.Int32, Builtin.NativeObject)) -> ()
apply %8(%7) : $@convention(thin) (@guaranteed (Builtin.Int32, Builtin.NativeObject, Builtin.Int32, Builtin.NativeObject)) -> ()
%9 = tuple(%3 : $Builtin.Int32, %2 : $Builtin.NativeObject, %3 : $Builtin.Int32, %2 : $Builtin.NativeObject)
%10 = function_ref @unowned_tuple_user : $@convention(thin) ((Builtin.Int32, Builtin.NativeObject, Builtin.Int32, Builtin.NativeObject)) -> ()
apply %10(%9) : $@convention(thin) ((Builtin.Int32, Builtin.NativeObject, Builtin.Int32, Builtin.NativeObject)) -> ()
destroy_value %0 : $Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}
// Make sure that we have a minimal verification as a non-lifetime ending use
// for mark_dependence. Eventually once we have a model of valid uses from the
// result of mark_dependence to move into the non-lifetime ending use set of the
// base object, this test should be extended with a negative use-after-free test
// in over-consume.
sil [ossa] @mark_dependence_test : $@convention(thin) (@owned Builtin.NativeObject, @guaranteed RefWithInt) -> () {
bb0(%0 : @owned $Builtin.NativeObject, %1 : @guaranteed $RefWithInt):
%2 = alloc_stack $Builtin.Int32
%3 = integer_literal $Builtin.Int32, 0
%4 = integer_literal $Builtin.Int32, 1
store %3 to [trivial] %2 : $*Builtin.Int32
%5 = mark_dependence %2 : $*Builtin.Int32 on %0 : $Builtin.NativeObject
store %4 to [trivial] %5 : $*Builtin.Int32
dealloc_stack %2 : $*Builtin.Int32
%6 = alloc_stack $Builtin.Int32
store %3 to [trivial] %6 : $*Builtin.Int32
%7 = mark_dependence %6 : $*Builtin.Int32 on %1 : $RefWithInt
store %3 to [trivial] %7 : $*Builtin.Int32
dealloc_stack %6 : $*Builtin.Int32
destroy_value %0 : $Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @test_destructure_struct_tuple : $@convention(thin) (@owned (Builtin.NativeObject, Builtin.Int32), @owned NonTrivialStructWithTrivialField) -> @owned (Builtin.NativeObject, Builtin.Int32, Builtin.NativeObject, Builtin.Int32) {
bb0(%0 : @owned $(Builtin.NativeObject, Builtin.Int32), %1 : @owned $NonTrivialStructWithTrivialField):
// First test guaranteed
%2 = begin_borrow %0 : $(Builtin.NativeObject, Builtin.Int32)
(%3, %4) = destructure_tuple %2 : $(Builtin.NativeObject, Builtin.Int32)
end_borrow %2 : $(Builtin.NativeObject, Builtin.Int32)
%5 = begin_borrow %1 : $NonTrivialStructWithTrivialField
(%6, %7) = destructure_struct %5 : $NonTrivialStructWithTrivialField
end_borrow %5 : $NonTrivialStructWithTrivialField
// Then test destructive.
(%8, %9) = destructure_tuple %0 : $(Builtin.NativeObject, Builtin.Int32)
(%10, %11) = destructure_struct %1 : $NonTrivialStructWithTrivialField
%12 = tuple(%8 : $Builtin.NativeObject, %9 : $Builtin.Int32, %10 : $Builtin.NativeObject, %11 : $Builtin.Int32)
return %12 : $(Builtin.NativeObject, Builtin.Int32, Builtin.NativeObject, Builtin.Int32)
}
sil [ossa] @test_empty_destructure : $@convention(thin) () -> () {
bb0:
%0 = struct $EmptyStruct()
() = destructure_struct %0 : $EmptyStruct
%1 = tuple()
() = destructure_tuple %1 : $()
return %1 : $()
}
//////////////////////////
// Dependent Type Tests //
//////////////////////////
// Make sure that we are properly ignoring type dependent operands. These do not
// have parameter conventions.
sil [ossa] @dependent_type : $@convention(thin) (@owned SwiftKlassP) -> () {
bb0(%0 : @owned $SwiftKlassP):
%1 = begin_borrow %0 : $SwiftKlassP
%2 = open_existential_ref %1 : $SwiftKlassP to $@opened("3B64717A-E2B3-11E6-9646-985AEB89C610") SwiftKlassP
%cast = unchecked_ref_cast %2 : $@opened("3B64717A-E2B3-11E6-9646-985AEB89C610") SwiftKlassP to $Builtin.NativeObject
%3 = witness_method $@opened("3B64717A-E2B3-11E6-9646-985AEB89C610") SwiftKlassP, #SwiftKlassP.foo!1, %2 : $@opened("3B64717A-E2B3-11E6-9646-985AEB89C610") SwiftKlassP : $@convention(witness_method: SwiftKlassP) <τ_0_0 where τ_0_0 : SwiftKlassP> (@guaranteed τ_0_0) -> ()
apply %3<@opened("3B64717A-E2B3-11E6-9646-985AEB89C610") SwiftKlassP>(%2) : $@convention(witness_method: SwiftKlassP) _0_0 where τ_0_0 : SwiftKlassP> (@guaranteed τ_0_0) -> ()
end_borrow %1 : $SwiftKlassP
destroy_value %0 : $SwiftKlassP
%9999 = tuple()
return %9999 : $()
}
/////////////////
// Undef Tests //
/////////////////
sil [ossa] @class_method_undef_test : $@convention(thin) () -> () {
bb0:
%0 = unchecked_ref_cast undef : $Builtin.NativeObject to $SuperKlass
%1 = class_method %0 : $SuperKlass, #SuperKlass.d!1 : (SuperKlass) -> () -> (), $@convention(method) (@guaranteed SuperKlass) -> ()
destroy_value %0 : $SuperKlass
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @forwarding_instruction_undef_test : $@convention(thin) () -> () {
bb0:
%0 = unchecked_ref_cast undef : $Builtin.NativeObject to $SuperKlass
%1 = unchecked_ref_cast %0 : $SuperKlass to $Builtin.NativeObject
destroy_value %1 : $Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @transforming_terminator_undef_test : $@convention(thin) () -> () {
bb0:
%0 = unchecked_ref_cast undef : $Builtin.NativeObject to $Builtin.NativeObject
checked_cast_br %0 : $Builtin.NativeObject to $SuperKlass, bb1, bb2
bb1(%1 : @owned $SuperKlass):
destroy_value %1 : $SuperKlass
br bb3
bb2(%2 : @owned $Builtin.NativeObject):
destroy_value %2 : $Builtin.NativeObject
br bb3
bb3:
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @super_method_metatype_test : $@convention(thin) (@thick SubKlass.Type) -> () {
bb0(%0 : $@thick SubKlass.Type):
%1 = upcast %0 : $@thick SubKlass.Type to $@thick SuperKlass.Type
%2 = class_method %1 : $@thick SuperKlass.Type, #SuperKlass.f!1 : (SuperKlass.Type) -> () -> (), $@convention(method) (@thick SuperKlass.Type) -> ()
apply %2(%1) : $@convention(method) (@thick SuperKlass.Type) -> ()
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @switch_enum_apply_test : $@convention(thin) () -> @owned Builtin.NativeObject {
bb0:
%0 = function_ref @produce_owned_optional : $@convention(thin) () -> @owned Optional<Builtin.NativeObject>
%1 = apply %0() : $@convention(thin) () -> @owned Optional<Builtin.NativeObject>
switch_enum %1 : $Optional<Builtin.NativeObject>, case #Optional.some!enumelt.1: bb2, case #Optional.none!enumelt: bb1
bb1:
unreachable
bb2(%2 : @owned $Builtin.NativeObject):
return %2 : $Builtin.NativeObject
}
// Make sure that we allow for @owned parameters to be passed as @guaranteed
// parameters since we are performing an "instantaneous" borrow.
sil [ossa] @owned_passed_to_guaranteed_apply_parameter : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0k(%0 : @owned $Builtin.NativeObject):
%1 = function_ref @guaranteed_nativeobject_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
apply %1(%0) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
destroy_value %0 : $Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @owned_partial_apply_used_as_callee_guaranteed : $@convention(thin) () -> () {
bb0:
%0 = function_ref @allocate_object : $@convention(thin) () -> @owned Builtin.NativeObject
%1 = partial_apply %0() : $@convention(thin) () -> @owned Builtin.NativeObject
%2 = convert_function %1 : $@callee_owned () -> @owned Builtin.NativeObject to $@callee_guaranteed () -> @owned Builtin.NativeObject
%3 = apply %2() : $@callee_guaranteed () -> @owned Builtin.NativeObject
destroy_value %3 : $Builtin.NativeObject
destroy_value %2 : $@callee_guaranteed () -> @owned Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @mark_dependence_test_2 : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
%2 = mark_dependence %0 : $Builtin.NativeObject on %1 : $Builtin.NativeObject
destroy_value %1 : $Builtin.NativeObject
destroy_value %2 : $Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @owned_partial_apply_is_escaping_closure : $@convention(thin) () -> () {
bb0:
%0 = function_ref @no_arg_or_output_function : $@convention(thin) () -> ()
%1 = partial_apply %0() : $@convention(thin) () -> ()
%2 = is_escaping_closure %1 : $@callee_owned () -> ()
%3 = begin_borrow %1 : $@callee_owned () -> ()
%4 = is_escaping_closure %3 : $@callee_owned () -> ()
end_borrow %3 : $@callee_owned () -> ()
destroy_value %1 : $@callee_owned () -> ()
%5 = partial_apply [callee_guaranteed] %0() : $@convention(thin) () -> ()
%6 = is_escaping_closure %5 : $@callee_guaranteed () -> ()
%7 = begin_borrow %5 : $@callee_guaranteed () -> ()
%8 = is_escaping_closure %7 : $@callee_guaranteed () -> ()
end_borrow %7 : $@callee_guaranteed () -> ()
destroy_value %5 : $@callee_guaranteed () -> ()
%9999 = tuple()
return %9999 : $()
}