blob: 80f9e4322758496736fd8f938e1a02289305e55b [file] [log] [blame]
// RUN: %swift -swift-version 4 -target arm64e-apple-ios12.0 -parse-stdlib -parse-as-library %s -emit-ir -module-name test -Xcc -Xclang -Xcc -fptrauth-calls | %FileCheck %s --check-prefix=CHECK
// REQUIRES: CPU=arm64e
// REQUIRES: OS=ios
import Builtin
// CHECK: @global_function.ptrauth = private constant { i8*, i32, i64, i64 } { i8* bitcast (void ()* @global_function to i8*), i32 0, i64 0, i64 {{.*}} }, section "llvm.ptrauth", align 8
sil @global_function : $@convention(thin) () -> ()
sil @test_sign : $@convention(thin) () -> @convention(thin) () -> () {
bb0:
%0 = function_ref @global_function : $@convention(thin) () -> ()
return %0 : $@convention(thin) () -> ()
}
// CHECK-LABEL: define swiftcc i8* @test_sign()
// CHECK: ret i8* bitcast ({ i8*, i32, i64, i64 }* @global_function.ptrauth to i8*)
sil @test_direct_call : $@convention(thin) () -> () {
bb0:
%0 = function_ref @global_function : $@convention(thin) () -> ()
%1 = apply %0() : $@convention(thin) () -> ()
return %1 : $()
}
// CHECK-LABEL: define swiftcc void @test_direct_call()
// CHECK: call swiftcc void @global_function(){{$}}
sil @test_indirect_call_thin : $@convention(thin) (@convention(thin) () -> ()) -> () {
bb0(%0 : $@convention(thin) () -> ()):
%1 = apply %0() : $@convention(thin) () -> ()
return %1 : $()
}
// CHECK-LABEL: define swiftcc void @test_indirect_call_thin(i8* %0)
// CHECK: [[CAST:%.*]] = bitcast i8* %0 to void ()*
// CHECK-NEXT: call swiftcc void [[CAST]]() [ "ptrauth"(i32 0, i64 {{.*}}) ]
sil @test_indirect_call_thick : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () {
bb0(%0 : $@callee_guaranteed () -> ()):
%1 = apply %0() : $@callee_guaranteed () -> ()
return %1 : $()
}
// CHECK-LABEL: define swiftcc void @test_indirect_call_thick(i8* %0, %swift.refcounted* %1)
// CHECK: [[CAST:%.*]] = bitcast i8* %0 to void (%swift.refcounted*)*
// CHECK-NEXT: call swiftcc void [[CAST]](%swift.refcounted* swiftself %1) [ "ptrauth"(i32 0, i64 {{.*}}) ]
sil @test_indirect_call_c : $@convention(thin) (@convention(c) () -> ()) -> () {
bb0(%0 : $@convention(c) () -> ()):
%1 = apply %0() : $@convention(c) () -> ()
return %1 : $()
}
// CHECK-LABEL: define swiftcc void @test_indirect_call_c(i8* %0)
// CHECK: [[CAST:%.*]] = bitcast i8* %0 to void ()*
// CHECK-NEXT: call void [[CAST]]() [ "ptrauth"(i32 0, i64 {{.*}}) ]
sil @test_thin_to_thick : $@convention(thin) (@convention(thin) () -> ()) -> (@callee_guaranteed () -> ()) {
bb0(%0 : $@convention(thin) () -> ()):
%1 = thin_to_thick_function %0 : $@convention(thin) () -> () to $@callee_guaranteed () -> ()
return %1 : $@callee_guaranteed () -> ()
}
// CHECK-LABEL: define swiftcc { i8*, %swift.refcounted* } @test_thin_to_thick(i8* %0)
// CHECK: [[T0:%.*]] = insertvalue { i8*, %swift.refcounted* } undef, i8* %0, 0
// CHECK-NEXT: [[T1:%.*]] = insertvalue { i8*, %swift.refcounted* } [[T0]], %swift.refcounted* null, 1
// CHECK-NEXT: ret { i8*, %swift.refcounted* } [[T1]]
sil @test_sign_thin_to_thick : $@convention(thin) () -> (@callee_guaranteed () -> ()) {
bb0:
%0 = function_ref @global_function : $@convention(thin) () -> ()
%1 = thin_to_thick_function %0 : $@convention(thin) () -> () to $@callee_guaranteed () -> ()
return %1 : $@callee_guaranteed () -> ()
}
// CHECK: define swiftcc { i8*, %swift.refcounted* } @test_sign_thin_to_thick() #[[ATTRS:[0-9]+]] {
// CHECK: ret { i8*, %swift.refcounted* } { i8* bitcast ({ i8*, i32, i64, i64 }* @global_function.ptrauth to i8*), %swift.refcounted* null }
class F {}
sil @generic_return : $@convention(thin) @yield_once <T : F> (@guaranteed T) -> @yields @guaranteed T
sil @test_generic_return : $@convention(thin) <T : F> (@guaranteed T) -> () {
bb0(%0 : $T):
%1 = function_ref @generic_return : $@convention(thin) @yield_once <T : F> (@guaranteed T) -> (@yields @guaranteed T)
(%value, %token) = begin_apply %1<T>(%0) : $@convention(thin) @yield_once <T : F> (@guaranteed T) -> (@yields @guaranteed T)
end_apply %token
%ret = tuple ()
return %ret : $()
}
sil_vtable F {
}
// CHECK: #[[ATTRS]] = {{{.*}} "ptrauth-auth-traps" "ptrauth-calls" "ptrauth-indirect-gotos" "ptrauth-returns"