mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
109 lines
5.0 KiB
Plaintext
109 lines
5.0 KiB
Plaintext
// RUN: %target-swift-frontend -primary-file %s -emit-ir | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-runtime
|
|
// REQUIRES: executable_test
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
class A {}
|
|
sil_vtable A {}
|
|
|
|
sil @create_error : $@convention(thin) () -> @owned ErrorProtocol {
|
|
entry:
|
|
unreachable
|
|
}
|
|
|
|
// CHECK: define{{( protected)?}} void @throws(%swift.refcounted*, %swift.error**) {{.*}} {
|
|
sil @throws : $@convention(thin) () -> @error ErrorProtocol {
|
|
// CHECK: [[T0:%.*]] = call %swift.error* @create_error()
|
|
%0 = function_ref @create_error : $@convention(thin) () -> @owned ErrorProtocol
|
|
%1 = apply %0() : $@convention(thin) () -> @owned ErrorProtocol
|
|
|
|
// CHECK-NEXT: call void @swift_willThrow
|
|
// CHECK-NEXT: store %swift.error* [[T0]], %swift.error** %1,
|
|
// CHECK-NEXT: ret void
|
|
builtin "willThrow"(%1 : $ErrorProtocol) : $()
|
|
throw %1 : $ErrorProtocol
|
|
}
|
|
|
|
// CHECK: define{{( protected)?}} void @doesnt_throw(%swift.refcounted*, %swift.error**) {{.*}} {
|
|
sil @doesnt_throw : $@convention(thin) () -> @error ErrorProtocol {
|
|
// We don't have to do anything here because the caller always
|
|
// zeroes the error slot before a call.
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: ret void
|
|
%0 = tuple ()
|
|
return %0 : $()
|
|
}
|
|
|
|
sil @try_apply_helper : $@convention(thin) (@owned AnyObject) -> (@owned AnyObject, @error ErrorProtocol)
|
|
|
|
// CHECK-objc: define{{( protected)?}} void @try_apply(%objc_object*)
|
|
// CHECK-native: define{{( protected)?}} void @try_apply(%swift.refcounted*)
|
|
sil @try_apply : $@convention(thin) (@owned AnyObject) -> () {
|
|
entry(%0 : $AnyObject):
|
|
// CHECK: [[ERRORSLOT:%.*]] = alloca %swift.error*, align
|
|
// CHECK-NEXT: store %swift.error* null, %swift.error** [[ERRORSLOT]], align
|
|
|
|
// CHECK-objc-NEXT: [[RESULT:%.*]] = call %objc_object* @try_apply_helper(%objc_object* %0, %swift.refcounted* undef, %swift.error** nocapture [[ERRORSLOT]])
|
|
// CHECK-native-NEXT: [[RESULT:%.*]] = call %swift.refcounted* @try_apply_helper(%swift.refcounted* %0, %swift.refcounted* undef, %swift.error** nocapture [[ERRORSLOT]])
|
|
// CHECK-NEXT: [[ERR:%.*]] = load %swift.error*, %swift.error** [[ERRORSLOT]], align
|
|
// CHECK-NEXT: [[T0:%.*]] = icmp ne %swift.error* [[ERR]], null
|
|
// CHECK-NEXT: br i1 [[T0]],
|
|
%1 = function_ref @try_apply_helper : $@convention(thin) (@owned AnyObject) -> (@owned AnyObject, @error ErrorProtocol)
|
|
try_apply %1(%0) : $@convention(thin) (@owned AnyObject) -> (@owned AnyObject, @error ErrorProtocol),
|
|
normal bb1, error bb2
|
|
|
|
// CHECK-objc: [[T0:%.*]] = phi %objc_object* [ [[RESULT]],
|
|
// CHECK-objc-NEXT: call void @swift_unknownRelease(%objc_object* [[T0]])
|
|
// CHECK-native: [[T0:%.*]] = phi %swift.refcounted* [ [[RESULT]],
|
|
// CHECK-native-NEXT: call void @rt_swift_release(%swift.refcounted* [[T0]])
|
|
// CHECK-NEXT: br label [[CONT:%[0-9]+]]
|
|
bb1(%2 : $AnyObject):
|
|
strong_release %2 : $AnyObject
|
|
br bb3
|
|
|
|
// CHECK: [[T0:%.*]] = phi %swift.error* [ [[ERR]],
|
|
// CHECK-NEXT: store %swift.error* null, %swift.error** [[ERRORSLOT]], align
|
|
// CHECK-objc-NEXT: call void @swift_errorRelease(%swift.error* [[T0]])
|
|
// CHECK-native-NEXT: call void bitcast (void (%swift.refcounted*)* @rt_swift_release to void (%swift.error*)*)(%swift.error* [[T0]])
|
|
// CHECK-NEXT: br label [[CONT]]
|
|
bb2(%3 : $ErrorProtocol):
|
|
release_value %3 : $ErrorProtocol
|
|
br bb3
|
|
bb3:
|
|
%4 = tuple ()
|
|
return %4 : $()
|
|
}
|
|
|
|
enum ColorError : ErrorProtocol {
|
|
case Red, Green, Blue
|
|
}
|
|
|
|
// CHECK-LABEL: TestCallToWillThrowCallBack
|
|
// CHECK: call void @swift_willThrow(%swift.error* %0)
|
|
// CHECK: store %swift.error* %0
|
|
// CHECK: ret i64 undef
|
|
sil hidden @TestCallToWillThrowCallBack : $@convention(thin) (@owned ErrorProtocol) -> (Int64, @error ErrorProtocol) {
|
|
bb0(%0 : $ErrorProtocol):
|
|
builtin "willThrow"(%0 : $ErrorProtocol) : $()
|
|
throw %0 : $ErrorProtocol // id: %3
|
|
}
|
|
|
|
// rdar://21084084 - Partial application of throwing functions.
|
|
|
|
// CHECK-LABEL: define{{( protected)?}} { i8*, %swift.refcounted* } @partial_apply_single(%C6errors1A*)
|
|
// CHECK: insertvalue { i8*, %swift.refcounted* } { i8* bitcast (void (%swift.refcounted*, %swift.error**)* @_TPA_partial_apply_single_helper to i8*), %swift.refcounted* undef },
|
|
// CHECK-LABEL: define internal void @_TPA_partial_apply_single_helper(%swift.refcounted*, %swift.error**)
|
|
// CHECK: [[T0:%.*]] = bitcast %swift.refcounted* {{%.*}} to %C6errors1A*
|
|
// CHECK-NEXT: tail call void @partial_apply_single_helper(%C6errors1A* [[T0]], %swift.refcounted* undef, %swift.error** {{%.*}})
|
|
// CHECK-NEXT: ret void
|
|
sil @partial_apply_single : $@convention(thin) (@owned A) -> @callee_owned () -> @error ErrorProtocol {
|
|
entry(%0 : $A):
|
|
%1 = function_ref @partial_apply_single_helper : $@convention(thin) (@owned A) -> @error ErrorProtocol
|
|
%2 = partial_apply %1(%0) : $@convention(thin) (@owned A) -> @error ErrorProtocol
|
|
return %2 : $@callee_owned () -> @error ErrorProtocol
|
|
}
|
|
sil @partial_apply_single_helper : $@convention(thin) (@owned A) -> (@error ErrorProtocol)
|