|
| 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 |
| 6 | + |
| 7 | +// RUN: %clang_cc1 -DENABLE_TID=1 -I%S -std=c++11 -triple=arm64e-apple-darwin \ |
| 8 | +// RUN: -fptrauth-calls -fptrauth-intrinsics \ |
| 9 | +// RUN: -fptrauth-vtable-pointer-type-discrimination \ |
| 10 | +// RUN: -fptrauth-vtable-pointer-address-discrimination \ |
| 11 | +// RUN: -fptrauth-type-info-vtable-pointer-discrimination \ |
| 12 | +// RUN: %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,DISC |
| 13 | + |
| 14 | +// copied from typeinfo |
| 15 | +namespace std { |
| 16 | + |
| 17 | +#if __has_cpp_attribute(clang::ptrauth_vtable_pointer) |
| 18 | +# if __has_feature(ptrauth_type_info_vtable_pointer_discrimination) |
| 19 | +# define _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH \ |
| 20 | + [[clang::ptrauth_vtable_pointer(process_independent, address_discrimination, type_discrimination)]] |
| 21 | +# else |
| 22 | +# define _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH \ |
| 23 | + [[clang::ptrauth_vtable_pointer(process_independent, no_address_discrimination, no_extra_discrimination)]] |
| 24 | +# endif |
| 25 | +#else |
| 26 | +# define _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH |
| 27 | +#endif |
| 28 | + |
| 29 | + class _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH type_info |
| 30 | + { |
| 31 | + type_info& operator=(const type_info&); |
| 32 | + type_info(const type_info&); |
| 33 | + |
| 34 | + protected: |
| 35 | + explicit type_info(const char* __n); |
| 36 | + |
| 37 | + public: |
| 38 | + virtual ~type_info(); |
| 39 | + |
| 40 | + virtual void test_method(); |
| 41 | + }; |
| 42 | +} // namespace std |
| 43 | + |
| 44 | +static_assert(__has_feature(ptrauth_type_info_vtable_pointer_discrimination) == ENABLE_TID, "incorrect feature state"); |
| 45 | + |
| 46 | +// CHECK: @disc_std_type_info = global i32 [[STDTYPEINFO_DISC:45546]] |
| 47 | +extern "C" int disc_std_type_info = __builtin_ptrauth_string_discriminator("_ZTVSt9type_info"); |
| 48 | + |
| 49 | +// 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 |
| 50 | +// CHECK: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr] |
| 51 | +// CHECK: @_ZTS10TestStruct = constant [13 x i8] c"10TestStruct\00", align 1 |
| 52 | + |
| 53 | +// 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 |
| 54 | + |
| 55 | +// 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 @_ZTS10TestStruct }, align 8 |
| 56 | + |
| 57 | +struct TestStruct { |
| 58 | + virtual ~TestStruct(); |
| 59 | + int a; |
| 60 | +}; |
| 61 | + |
| 62 | +TestStruct::~TestStruct(){} |
| 63 | + |
| 64 | +extern "C" void test_vtable(std::type_info* t) { |
| 65 | + t->test_method(); |
| 66 | +} |
| 67 | +// NODISC: define void @test_vtable(ptr noundef %t) |
| 68 | +// NODISC: [[T_ADDR:%.*]] = alloca ptr, align 8 |
| 69 | +// NODISC: store ptr %t, ptr [[T_ADDR]], align 8 |
| 70 | +// NODISC: [[T:%.*]] = load ptr, ptr [[T_ADDR]], align 8 |
| 71 | +// NODISC: [[VPTR:%.*]] = load ptr, ptr [[T]], align 8 |
| 72 | +// NODISC: [[CAST_VPTR:%.*]] = ptrtoint ptr [[VPTR]] to i64 |
| 73 | +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[CAST_VPTR]], i32 2, i64 0) |
| 74 | + |
| 75 | +// DISC: define void @test_vtable(ptr noundef %t) |
| 76 | +// DISC: [[T_ADDR:%.*]] = alloca ptr, align 8 |
| 77 | +// DISC: store ptr %t, ptr [[T_ADDR]], align 8 |
| 78 | +// DISC: [[T:%.*]] = load ptr, ptr [[T_ADDR]], align 8 |
| 79 | +// DISC: [[VPTR:%.*]] = load ptr, ptr [[T]], align 8 |
| 80 | +// DISC: [[ADDR:%.*]] = ptrtoint ptr [[T]] to i64 |
| 81 | +// DISC: [[DISCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[ADDR]], i64 [[STDTYPEINFO_DISC]]) |
| 82 | +// DISC: [[VPTRI:%.*]] = ptrtoint ptr [[VPTR]] to i64 |
| 83 | +// DISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VPTRI]], i32 2, i64 [[DISCRIMINATOR]]) |
| 84 | + |
| 85 | +extern "C" const void *ensure_typeinfo() { |
| 86 | + return new TestStruct; |
| 87 | +} |
0 commit comments