1 // RUN: %clang_cc1 -DENABLE_TID=0 -I%S -std=c++11 -triple=arm64e-apple-darwin \
2 // RUN: -fptrauth-calls -fptrauth-intrinsics \
3 // RUN: -fptrauth-vtable-pointer-type-discrimination \
4 // RUN: -fptrauth-vtable-pointer-address-discrimination \
5 // RUN: %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NODISC
7 // RUN: %clang_cc1 -DENABLE_TID=0 -I%S -std=c++11 -triple=aarch64-linux-gnu \
8 // RUN: -fptrauth-calls -fptrauth-intrinsics \
9 // RUN: -fptrauth-vtable-pointer-type-discrimination \
10 // RUN: -fptrauth-vtable-pointer-address-discrimination \
11 // RUN: %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NODISC
13 // RUN: %clang_cc1 -DENABLE_TID=1 -I%S -std=c++11 -triple=arm64e-apple-darwin \
14 // RUN: -fptrauth-calls -fptrauth-intrinsics \
15 // RUN: -fptrauth-vtable-pointer-type-discrimination \
16 // RUN: -fptrauth-vtable-pointer-address-discrimination \
17 // RUN: -fptrauth-type-info-vtable-pointer-discrimination \
18 // RUN: %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,DISC
20 // RUN: %clang_cc1 -DENABLE_TID=1 -I%S -std=c++11 -triple=aarch64-linux-gnu \
21 // RUN: -fptrauth-calls -fptrauth-intrinsics \
22 // RUN: -fptrauth-vtable-pointer-type-discrimination \
23 // RUN: -fptrauth-vtable-pointer-address-discrimination \
24 // RUN: -fptrauth-type-info-vtable-pointer-discrimination \
25 // RUN: %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,DISC
27 // copied from typeinfo
30 #if __has_cpp_attribute(clang::ptrauth_vtable_pointer)
31 # if __has_feature(ptrauth_type_info_vtable_pointer_discrimination)
32 # define _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH \
33 [[clang::ptrauth_vtable_pointer(process_independent, address_discrimination, type_discrimination)]]
35 # define _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH \
36 [[clang::ptrauth_vtable_pointer(process_independent, no_address_discrimination, no_extra_discrimination)]]
39 # define _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH
42 class _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH type_info
44 type_info
& operator=(const type_info
&);
45 type_info(const type_info
&);
48 explicit type_info(const char* __n
);
53 virtual void test_method();
57 static_assert(__has_feature(ptrauth_type_info_vtable_pointer_discrimination
) == ENABLE_TID
, "incorrect feature state");
59 // CHECK: @disc_std_type_info = global i32 [[STDTYPEINFO_DISC:45546]]
60 extern "C" int disc_std_type_info
= __builtin_ptrauth_string_discriminator("_ZTVSt9type_info");
62 // CHECK: @_ZTV10TestStruct = unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTI10TestStruct, ptr ptrauth (ptr @_ZN10TestStructD1Ev, i32 0, i64 52216, ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV10TestStruct, i32 0, i32 0, i32 2)), ptr ptrauth (ptr @_ZN10TestStructD0Ev, i32 0, i64 39671, ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV10TestStruct, i32 0, i32 0, i32 3))] }, align 8
64 // NODISC: @_ZTI10TestStruct = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr @_ZTS10TestStruct }, align 8
66 // DISC: @_ZTI10TestStruct = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2, i64 [[STDTYPEINFO_DISC]], ptr @_ZTI10TestStruct), ptr @_ZTS10TestStruct }, align 8
68 // CHECK: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
69 // CHECK: @_ZTS10TestStruct = constant [13 x i8] c"10TestStruct\00", align 1
72 virtual ~TestStruct();
76 TestStruct::~TestStruct(){}
78 extern "C" void test_vtable(std::type_info
* t
) {
81 // NODISC: define{{.*}} void @test_vtable(ptr noundef %t)
82 // NODISC: [[T_ADDR:%.*]] = alloca ptr, align 8
83 // NODISC: store ptr %t, ptr [[T_ADDR]], align 8
84 // NODISC: [[T:%.*]] = load ptr, ptr [[T_ADDR]], align 8
85 // NODISC: [[VPTR:%.*]] = load ptr, ptr [[T]], align 8
86 // NODISC: [[CAST_VPTR:%.*]] = ptrtoint ptr [[VPTR]] to i64
87 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[CAST_VPTR]], i32 2, i64 0)
89 // DISC: define{{.*}} void @test_vtable(ptr noundef %t)
90 // DISC: [[T_ADDR:%.*]] = alloca ptr, align 8
91 // DISC: store ptr %t, ptr [[T_ADDR]], align 8
92 // DISC: [[T:%.*]] = load ptr, ptr [[T_ADDR]], align 8
93 // DISC: [[VPTR:%.*]] = load ptr, ptr [[T]], align 8
94 // DISC: [[ADDR:%.*]] = ptrtoint ptr [[T]] to i64
95 // DISC: [[DISCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[ADDR]], i64 [[STDTYPEINFO_DISC]])
96 // DISC: [[VPTRI:%.*]] = ptrtoint ptr [[VPTR]] to i64
97 // DISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VPTRI]], i32 2, i64 [[DISCRIMINATOR]])
99 extern "C" const void *ensure_typeinfo() {
100 return new TestStruct
;