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
|
// 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: @"$s4test1ACfD.ptrauth" = private constant { ptr, i32, i64, i64 } { ptr @"$s4test1ACfD", i32 0, i64 ptrtoint ({{.*}} @"$s4test1ACMf", i32 0, i32 1) to i64), i64 48063 }, section "llvm.ptrauth", align 8
// CHECK: @A_foo.ptrauth = private constant { ptr, i32, i64, i64 } { ptr @A_foo, i32 0, i64 ptrtoint ({{.*}} getelementptr inbounds ({{.*}} @"$s4test1ACMf", i32 0, i32 {{.*}}) to i64), i64 23008 }, section "llvm.ptrauth", align 8
// CHECK: @"$s4test1BCfD.ptrauth" = private constant { ptr, i32, i64, i64 } { ptr @"$s4test1BCfD", i32 0, i64 ptrtoint ({{.*}} @"$s4test1BCMf", i32 0, i32 1) to i64), i64 48063 }, section "llvm.ptrauth", align 8
// CHECK: @B_foo.ptrauth = private constant { ptr, i32, i64, i64 } { ptr @B_foo, i32 0, i64 ptrtoint ({{.*}} getelementptr inbounds ({{.*}} @"$s4test1BCMf", i32 0, i32 {{.*}}) to i64), i64 23008 }, section "llvm.ptrauth", align 8
// CHECK: @"$s4test1GCMn" =
// -1212481520 == 0xb7bb0010. 0xb7bb == 47035.
// CHECK-SAME: i32 -1212481520, {{.*}} @G_bar
open class A {
deinit {}
open func foo()
}
open class B : A {
deinit {}
override open func foo()
}
open class G<T> {
open func bar()
}
sil @A_foo : $@convention(method) (@guaranteed A) -> ()
sil @B_foo : $@convention(method) (@guaranteed B) -> ()
sil @G_bar : $@convention(method) <T> (@guaranteed G<T>) -> ()
sil @$s4test1ACfD : $@convention(method) (@owned A) -> ()
sil @$s4test1BCfD : $@convention(method) (@owned B) -> ()
sil_vtable A {
#A.deinit!deallocator: (A) -> () -> () : @$s4test1ACfD
#A.foo: (A) -> () -> () : @A_foo
}
sil_vtable B {
#B.deinit!deallocator: (B) -> () -> () : @$s4test1BCfD
#A.foo: (A) -> () -> () : @B_foo [override]
}
sil_vtable G {
#G.bar: @G_bar
}
sil @test_call_a : $@convention(thin) (@guaranteed A) -> () {
bb0(%0 : $A):
%1 = class_method %0 : $A, #A.foo : (A) -> () -> (), $@convention(method) (@guaranteed A) -> ()
%2 = apply %1(%0) : $@convention(method) (@guaranteed A) -> ()
return %2 : $()
}
// CHECK-LABEL: define swiftcc void @test_call_a(ptr %0)
// CHECK: [[META:%.*]] = load ptr, ptr %0, align
// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds ptr, ptr [[META]], i64 {{.*}}
// CHECK-NEXT: [[FN:%.*]] = load ptr, ptr [[SLOT]]
// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[SLOT]] to i64
// Discriminator value is arbitrary, but must be the same as the next test.
// CHECK-NEXT: [[DISCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 23008)
// CHECK-NEXT: call swiftcc void [[FN]](ptr swiftself %0) [ "ptrauth"(i32 0, i64 [[DISCRIMINATOR]]) ]
// CHECK-NEXT: ret void
sil @test_call_b : $@convention(thin) (@guaranteed B) -> () {
bb0(%0 : $B):
%1 = class_method %0 : $B, #B.foo : (B) -> () -> (), $@convention(method) (@guaranteed B) -> ()
%2 = apply %1(%0) : $@convention(method) (@guaranteed B) -> ()
return %2 : $()
}
// CHECK-LABEL: define swiftcc void @test_call_b(ptr %0)
// CHECK: [[META:%.*]] = load ptr, ptr %0, align
// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds ptr, ptr [[META]], i64 {{.*}}
// CHECK-NEXT: [[FN:%.*]] = load ptr, ptr [[SLOT]]
// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[SLOT]] to i64
// Discriminator value is arbitrary, but must be the same as the previous test.
// CHECK-NEXT: [[DISCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 23008)
// CHECK-NEXT: call swiftcc void [[FN]](ptr swiftself %0) [ "ptrauth"(i32 0, i64 [[DISCRIMINATOR]]) ]
// CHECK-NEXT: ret void
sil @test_call_g : $@convention(thin) <T> (@guaranteed G<T>) -> () {
bb0(%0 : $G<T>):
%1 = class_method %0 : $G<T>, #G.bar : <t> (G<t>) -> () -> (), $@convention(method) <t> (@guaranteed G<t>) -> ()
%2 = apply %1<T>(%0) : $@convention(method) <t> (@guaranteed G<t>) -> ()
return %2 : $()
}
// CHECK-LABEL: define swiftcc void @test_call_g(ptr %0)
// CHECK: load
// CHECK: [[META:%.*]] = load ptr, ptr %0, align
// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds ptr, ptr [[META]], i64 {{.*}}
// CHECK-NEXT: [[FN:%.*]] = load ptr, ptr [[SLOT]]
// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[SLOT]] to i64
// Discriminator value is arbitrary, but must be the same as the previous test.
// CHECK-NEXT: [[DISCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 47035)
// CHECK-NEXT: call swiftcc void [[FN]](ptr swiftself %0) [ "ptrauth"(i32 0, i64 [[DISCRIMINATOR]]) ]
// CHECK-NEXT: ret void
|