| // REQUIRES: aarch64-registered-target | |
| // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-pauthtest -fptrauth-calls -disable-llvm-passes \ | |
| // RUN: -emit-llvm -O0 -o - | FileCheck --check-prefixes=CHECK,DEFAULT %s | |
| // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-pauthtest -fptrauth-calls -fptrauth-vtt-vtable-pointer-discrimination \ | |
| // RUN: -disable-llvm-passes -emit-llvm -O0 -o - | FileCheck --check-prefixes=CHECK,DEFAULT %s | |
| // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-pauthtest -fptrauth-calls -fptrauth-vtt-vtable-pointer-discrimination \ | |
| // RUN: -fptrauth-vtable-pointer-address-discrimination -disable-llvm-passes -emit-llvm -O0 -o - | FileCheck --check-prefixes=CHECK,ADDRESS %s | |
| // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-pauthtest -fptrauth-calls -fptrauth-vtt-vtable-pointer-discrimination \ | |
| // RUN: -fptrauth-vtable-pointer-type-discrimination -disable-llvm-passes -emit-llvm -O0 -o - | FileCheck --check-prefixes=CHECK,TYPE %s | |
| // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-pauthtest -fptrauth-calls -fptrauth-vtt-vtable-pointer-discrimination \ | |
| // RUN: -fptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-type-discrimination \ | |
| // RUN: -disable-llvm-passes -emit-llvm -O0 -o - | FileCheck --check-prefixes=CHECK,ADDRESSTYPE %s | |
| // CHECK: @_ZTT1D = linkonce_odr unnamed_addr constant [4 x ptr] [ | |
| // DEFAULT-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 4), i32 2), | |
| // DEFAULT-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTC1D0_1A, i32 0, i32 0, i32 4), i32 2), | |
| // DEFAULT-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTC1D0_1A, i32 0, i32 0, i32 4), i32 2), | |
| // DEFAULT-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 4), i32 2)] | |
| // ADDRESS-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 4), i32 2, i64 0, ptr @_ZTT1D), | |
| // ADDRESS-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTC1D0_1A, i32 0, i32 0, i32 4), i32 2, i64 0, ptr getelementptr (ptr, ptr @_ZTT1D, i32 1)), | |
| // ADDRESS-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTC1D0_1A, i32 0, i32 0, i32 4), i32 2, i64 0, ptr getelementptr (ptr, ptr @_ZTT1D, i32 2)), | |
| // ADDRESS-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 4), i32 2, i64 0, ptr getelementptr (ptr, ptr @_ZTT1D, i32 3))] | |
| // TYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 4), i32 2, i64 820), | |
| // TYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTC1D0_1A, i32 0, i32 0, i32 4), i32 2, i64 49118), | |
| // TYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTC1D0_1A, i32 0, i32 0, i32 4), i32 2, i64 49118), | |
| // TYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 4), i32 2, i64 820)] | |
| // ADDRESSTYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 4), i32 2, i64 820, ptr @_ZTT1D), | |
| // ADDRESSTYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTC1D0_1A, i32 0, i32 0, i32 4), i32 2, i64 49118, ptr getelementptr (ptr, ptr @_ZTT1D, i32 1)), | |
| // ADDRESSTYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTC1D0_1A, i32 0, i32 0, i32 4), i32 2, i64 49118, ptr getelementptr (ptr, ptr @_ZTT1D, i32 2)), | |
| // ADDRESSTYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 4), i32 2, i64 820, ptr getelementptr (ptr, ptr @_ZTT1D, i32 3))] | |
| // CHECK: @_ZTT1A = linkonce_odr unnamed_addr constant [2 x ptr] [ | |
| // DEFAULT-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 4), i32 2), | |
| // DEFAULT-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 4), i32 2)] | |
| // ADDRESS-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 4), i32 2, i64 0, ptr @_ZTT1A), | |
| // ADDRESS-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 4), i32 2, i64 0, ptr getelementptr (ptr, ptr @_ZTT1A, i32 1))] | |
| // TYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 4), i32 2, i64 49118), | |
| // TYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 4), i32 2, i64 49118)] | |
| // ADDRESSTYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 4), i32 2, i64 49118, ptr @_ZTT1A), | |
| // ADDRESSTYPE-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 4), i32 2, i64 49118, ptr getelementptr (ptr, ptr @_ZTT1A, i32 1))] | |
| // CHECK-LABEL: @_ZN1AC2Ev | |
| // CHECK: %vtt.addr = alloca ptr, align 8 | |
| // CHECK: store ptr %vtt, ptr %vtt.addr, align 8 | |
| // CHECK: [[VTT:%.*]] = load ptr, ptr %vtt.addr, align 8 | |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTT]], align 8 | |
| // ADDRESS: [[VTABLE_ADDR:%.*]] = ptrtoint ptr [[VTT]] to i64 | |
| // ADDRESSTYPE: [[VTABLE_ADDR:%.*]] = ptrtoint ptr [[VTT]] to i64 | |
| // ADDRESSTYPE: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTABLE_ADDR]], i64 49118) | |
| // CHECK: [[VTABLEi64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 | |
| // DEFAULT: call i64 @llvm.ptrauth.auth(i64 [[VTABLEi64]], i32 2, i64 0) | |
| // ADDRESS: call i64 @llvm.ptrauth.auth(i64 [[VTABLEi64]], i32 2, i64 [[VTABLE_ADDR]]) | |
| // TYPE: call i64 @llvm.ptrauth.auth(i64 [[VTABLEi64]], i32 2, i64 49118) | |
| // ADDRESSTYPE: call i64 @llvm.ptrauth.auth(i64 [[VTABLEi64]], i32 2, i64 [[DISC]]) | |
| // CHECK: [[VTTOFFSET:%.*]] = getelementptr inbounds ptr, ptr [[VTT]], i64 1 | |
| // CHECK: [[VTABLE2:%.*]] = load ptr, ptr [[VTTOFFSET]], align 8 | |
| // ADDRESS: [[VTABLE2_ADDR:%.*]] = ptrtoint ptr [[VTTOFFSET]] to i64 | |
| // ADDRESSTYPE: [[VTABLE2_ADDR:%.*]] = ptrtoint ptr [[VTTOFFSET]] to i64 | |
| // ADDRESSTYPE: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTABLE2_ADDR]], i64 49118) | |
| // CHECK: [[VTABLE2i64:%.*]] = ptrtoint ptr [[VTABLE2]] to i64 | |
| // DEFAULT: call i64 @llvm.ptrauth.auth(i64 [[VTABLE2i64]], i32 2, i64 0) | |
| // ADDRESS: call i64 @llvm.ptrauth.auth(i64 [[VTABLE2i64]], i32 2, i64 [[VTABLE2_ADDR]]) | |
| // TYPE: call i64 @llvm.ptrauth.auth(i64 [[VTABLE2i64]], i32 2, i64 49118) | |
| // ADDRESSTYPE: call i64 @llvm.ptrauth.auth(i64 [[VTABLE2i64]], i32 2, i64 [[DISC]]) | |
| // CHECK-LABEL: @_ZN1DC2Ev | |
| // CHECK: %vtt.addr = alloca ptr, align 8 | |
| // CHECK: store ptr %vtt, ptr %vtt.addr, align 8 | |
| // CHECK: [[VTT:%.*]] = load ptr, ptr %vtt.addr, align 8 | |
| // CHECK: [[VTTOFFSET:%.*]] = getelementptr inbounds ptr, ptr [[VTT]], i64 1 | |
| // CHECK: call void @_ZN1AC2Ev(ptr noundef nonnull align 8 dereferenceable(8) %this1, ptr noundef [[VTTOFFSET]]) | |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTT]], align 8 | |
| // ADDRESS: [[VTABLE_ADDR:%.*]] = ptrtoint ptr [[VTT]] to i64 | |
| // ADDRESSTYPE: [[VTABLE_ADDR:%.*]] = ptrtoint ptr [[VTT]] to i64 | |
| // ADDRESSTYPE: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTABLE_ADDR]], i64 820) | |
| // CHECK: [[VTABLEi64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 | |
| // DEFAULT: call i64 @llvm.ptrauth.auth(i64 [[VTABLEi64]], i32 2, i64 0) | |
| // ADDRESS: call i64 @llvm.ptrauth.auth(i64 [[VTABLEi64]], i32 2, i64 [[VTABLE_ADDR]]) | |
| // TYPE: call i64 @llvm.ptrauth.auth(i64 [[VTABLEi64]], i32 2, i64 820) | |
| // ADDRESSTYPE: call i64 @llvm.ptrauth.auth(i64 [[VTABLEi64]], i32 2, i64 [[DISC]]) | |
| struct V { | |
| virtual void f(); | |
| }; | |
| struct A : virtual V { | |
| A(); | |
| }; | |
| struct D : A { | |
| D(); | |
| }; | |
| A::A() {} | |
| D::D() {} |