1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
// RUN: %target-sil-opt -enable-sil-verify-all=0 -module-name Swift -o /dev/null %s 2>&1
// REQUIRES: asserts
// Make sure that we properly handle unreachable code the likes of which come
// from SILGen. This file should never crash.
sil_stage raw
import Builtin
//////////////////
// Declarations //
//////////////////
enum Never {}
sil @no_return_function : $@convention(thin) () -> Never
sil @create_object : $@convention(thin) () -> @owned Builtin.NativeObject
sil @use_object : $@convention(thin) (@owned Builtin.NativeObject) -> ()
///////////
// Tests //
///////////
// Make sure that we properly handle owned parameters in one function block that
// are leaked and those that are not leaked.
sil [ossa] @test1 : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
destroy_value %1 : $Builtin.NativeObject
unreachable
}
// Make sure that we properly handle owned parameters that are leaked along one
// block and are consumed along a different one.
sil [ossa] @test2 : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject):
cond_br undef, bb1, bb2
bb1:
unreachable
bb2:
destroy_value %0 : $Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}
// Make sure that we properly handle loop parameters that are leaked along the
// exit edge of a loop.
sil [ossa] @test3 : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject):
br bb1(%0 : $Builtin.NativeObject)
bb1(%1 : @owned $Builtin.NativeObject):
cond_br undef, bb2, bb3
bb2:
unreachable
bb3:
br bb1(%1 : $Builtin.NativeObject)
}
// Make sure that we properly handle loop parameters that are leaked in the body
// of a loop.
sil [ossa] @test4 : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject):
br bb1(%0 : $Builtin.NativeObject)
bb1(%1 : @owned $Builtin.NativeObject):
%2 = copy_value %1 : $Builtin.NativeObject
cond_br undef, bb2, bb3
bb2:
unreachable
bb3:
destroy_value %1 : $Builtin.NativeObject
cond_br undef, bb4, bb5
bb4:
br bb1(%2 : $Builtin.NativeObject)
bb5:
destroy_value %2 : $Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}
// Check that we handle diamonds correctly.
sil [ossa] @test5 : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject):
cond_br undef, bb1, bb2
bb1:
cond_br undef, bb3, bb4
bb2:
br bb5
bb3:
unreachable
bb4:
br bb5
bb5:
destroy_value %0 : $Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}
// Make sure that even if we have a destroy value in our unreachable path, we do
// not really care.
sil [ossa] @test6 : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject):
cond_br undef, bb1, bb2
bb1:
cond_br undef, bb3, bb4
bb2:
br bb5
bb3:
destroy_value %0 : $Builtin.NativeObject
unreachable
bb4:
br bb5
bb5:
destroy_value %0 : $Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}
sil [ossa] @test7 : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject):
%1 = begin_borrow %0 : $Builtin.NativeObject
cond_br undef, bb1, bb2
bb1:
end_borrow %1 : $Builtin.NativeObject
destroy_value %0 : $Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
bb2:
end_borrow %1 : $Builtin.NativeObject
br bb3
bb3:
unreachable
}
|