mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
It is necessary for opaque values where for casts that will newly start out as checked_cast_brs and be lowered to checked_cast_addr_brs, since the latter has the source formal type, IRGen relies on being able to access it, and there's no way in general to obtain the source formal type from the source lowered type.
171 lines
3.8 KiB
Plaintext
171 lines
3.8 KiB
Plaintext
// RUN: %target-sil-opt -enable-objc-interop -enable-sil-verify-all %s -split-critical-edges | %FileCheck %s
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
sil_stage raw
|
|
|
|
enum OnePayload {
|
|
case x(Builtin.Int64)
|
|
case y
|
|
}
|
|
|
|
// CHECK-LABEL: sil @check_switch_value
|
|
// CHECK: bb0
|
|
// CHECK: cond_br %1, bb1, bb2
|
|
// CHECK: bb1:
|
|
// CHECK: integer_literal $Builtin.Int64, 1
|
|
// CHECK: br bb4
|
|
// CHECK: bb2:
|
|
// CHECK: [[VAL:%[0-9]+]] = integer_literal $Builtin.Int32, 1
|
|
// CHECK: switch_value %0 : $Builtin.Int32, case [[VAL]]: bb3, default bb5
|
|
// CHECK: bb3:
|
|
// CHECK: br bb4
|
|
// CHECK: bb4:
|
|
// CHECK: br bb6
|
|
// CHECK: bb5:
|
|
// CHECK: br bb6
|
|
// CHECK: bb6:
|
|
// CHECK: return
|
|
|
|
sil @check_switch_value : $(Builtin.Int32, Builtin.Int1) -> () {
|
|
entry(%0 : $Builtin.Int32, %1: $Builtin.Int1):
|
|
cond_br %1, bb1, bb2
|
|
|
|
bb1:
|
|
%2 = integer_literal $Builtin.Int64, 1
|
|
br x_cont
|
|
|
|
bb2:
|
|
%3 = integer_literal $Builtin.Int32, 1
|
|
switch_value %0 : $Builtin.Int32, case %3: x_dest, default y_dest
|
|
|
|
x_dest:
|
|
br x_cont
|
|
|
|
x_cont:
|
|
br end
|
|
|
|
y_dest:
|
|
br end
|
|
|
|
end:
|
|
%v = tuple ()
|
|
return %v : $()
|
|
}
|
|
|
|
class X {
|
|
@objc func f() { }
|
|
@objc class func g() { }
|
|
@objc var value : Int { get }
|
|
@objc subscript (i : Int) -> Int { get }
|
|
}
|
|
|
|
// CHECK: sil @dynamic_lookup_br : $@convention(thin) (AnyObject, Builtin.Int1) -> () {
|
|
// CHECK: bb0(
|
|
// CHECK: cond_br %1, bb1, bb2
|
|
// CHECK: bb1:
|
|
// CHECK: dynamic_method_br {{.*}} : $AnyObject, #X.f!foreign, bb3, bb4
|
|
// CHECK: bb2:
|
|
// CHECK: dynamic_method_br {{.*}} : $AnyObject, #X.f!foreign, bb5, bb6
|
|
// CHECK: bb3({{.*}} : $@convention(objc_method) (AnyObject) -> ())
|
|
// CHECK: br bb7
|
|
// CHECK: bb4:
|
|
// CHECK: br bb7
|
|
// CHECK: bb5({{.*}} : $@convention(objc_method) (AnyObject) -> ()):
|
|
// CHECK: br bb7
|
|
// CHECK: bb6:
|
|
// CHECK: br bb7
|
|
// CHECK: bb7:
|
|
// CHECK: return
|
|
// CHECK-LABEL: } // end sil function 'dynamic_lookup_br'
|
|
sil @dynamic_lookup_br : $@convention(thin) (AnyObject, Builtin.Int1) -> () {
|
|
bb0(%0 : $AnyObject, %10: $Builtin.Int1):
|
|
cond_br %10, lookup1, lookup2
|
|
|
|
lookup1:
|
|
%1 = alloc_box $<τ_0_0> { var τ_0_0 } <AnyObject>
|
|
%1a = project_box %1 : $<τ_0_0> { var τ_0_0 } <AnyObject>, 0
|
|
store %0 to %1a : $*AnyObject
|
|
%3 = alloc_box $<τ_0_0> { var τ_0_0 } <Optional<() -> ()>>
|
|
%4 = load %1a : $*AnyObject
|
|
strong_retain %4 : $AnyObject
|
|
dynamic_method_br %4 : $AnyObject, #X.f!foreign, bb1, bb2
|
|
|
|
lookup2:
|
|
%21 = alloc_box $<τ_0_0> { var τ_0_0 } <AnyObject>
|
|
%21a = project_box %21 : $<τ_0_0> { var τ_0_0 } <AnyObject>, 0
|
|
store %0 to %21a : $*AnyObject
|
|
%23 = alloc_box $<τ_0_0> { var τ_0_0 } <Optional<() -> ()>>
|
|
%24 = load %21a : $*AnyObject
|
|
strong_retain %24 : $AnyObject
|
|
dynamic_method_br %24 : $AnyObject, #X.f!foreign, bb3, bb4
|
|
|
|
bb1(%8 : $@convention(objc_method) (AnyObject) -> ()):
|
|
br bb5
|
|
|
|
bb2:
|
|
br bb5
|
|
|
|
bb3(%9 : $@convention(objc_method) (AnyObject) -> ()):
|
|
br bb5
|
|
|
|
bb4:
|
|
br bb5
|
|
|
|
bb5:
|
|
%43 = tuple ()
|
|
return %43 : $()
|
|
}
|
|
|
|
class Node {
|
|
}
|
|
|
|
class ParentNode : Node {
|
|
}
|
|
|
|
// CHECK-LABEL: sil @test_checked_cast_br
|
|
// CHECK: bb0(
|
|
// CHECK: cond_br %1, bb1, bb2
|
|
// CHECK: bb1:
|
|
// CHECK: checked_cast_br [exact] Node in {{.*}} : $Node to ParentNode, bb3, bb4
|
|
// CHECK: bb2:
|
|
// CHECK: checked_cast_br [exact] Node in {{.*}} : $Node to ParentNode, bb5, bb6
|
|
// CHECK: bb3({{.*}} : $ParentNode):
|
|
// CHECK: br bb7
|
|
// CHECK: bb4:
|
|
// CHECK: br bb7
|
|
// CHECK: bb5({{.*}} : $ParentNode):
|
|
// CHECK: br bb7
|
|
// CHECK: bb6:
|
|
// CHECK: br bb7
|
|
// CHECK: bb7:
|
|
// CHECK: return
|
|
|
|
sil @test_checked_cast_br : $@convention(method) (@owned Node, Builtin.Int1) -> () {
|
|
bb0(%0 : $Node, %2 : $Builtin.Int1):
|
|
cond_br %2, ccb1, ccb2
|
|
|
|
ccb1:
|
|
checked_cast_br [exact] Node in %0 : $Node to ParentNode, bb2, bb3
|
|
|
|
ccb2:
|
|
checked_cast_br [exact] Node in %0 : $Node to ParentNode, bb4, bb5
|
|
|
|
bb2(%5 : $ParentNode):
|
|
br bb1
|
|
|
|
bb3:
|
|
br bb1
|
|
|
|
bb4(%6 : $ParentNode):
|
|
br bb1
|
|
|
|
bb5:
|
|
br bb1
|
|
|
|
bb1:
|
|
%1 = tuple ()
|
|
return %1 : $()
|
|
}
|