1 // RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -emit-llvm -std=c++11 %s -o - | FileCheck --check-prefixes=CHECK,DARWIN %s 2 // RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -emit-llvm -std=c++11 %s -o - | FileCheck --check-prefixes=CHECK,ELF %s 3 4 // Check virtual function pointers in vtables are signed. 5 6 // CHECK: %[[CLASS_B1:.*]] = type { ptr } 7 8 // CHECK: @_ZTV2B1 = unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr @_ZTI2B1, ptr ptrauth (ptr @_ZN2B12m0Ev, i32 0, i64 58196, ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV2B1, i32 0, i32 0, i32 2))] }, align 8 9 10 // CHECK: @g_B1 = global %class.B1 { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV2B1, i32 0, i32 0, i32 2), i32 2) }, align 8 11 12 // CHECK: @_ZTV2B0 = unnamed_addr constant { [7 x ptr] } { [7 x ptr] [ptr null, ptr @_ZTI2B0, 13 // CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m0Ev, i32 0, i64 53119, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 2)), 14 // CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m1Ev, i32 0, i64 15165, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 3)), 15 // CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, i32 0, i64 43073, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 4)), 16 // CHECK-SAME: ptr ptrauth (ptr @_ZN2B0D1Ev, i32 0, i64 25525, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 5)), 17 // CHECK-SAME: ptr ptrauth (ptr @_ZN2B0D0Ev, i32 0, i64 21295, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 6))] }, align 8 18 19 // CHECK: @_ZTV2D0 = unnamed_addr constant { [9 x ptr] } { [9 x ptr] [ptr null, ptr @_ZTI2D0, 20 // CHECK-SAME: ptr ptrauth (ptr @_ZN2D02m0Ev, i32 0, i64 53119, ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 2)), 21 // CHECK-SAME: ptr ptrauth (ptr @_ZTch0_h4_N2D02m1Ev, i32 0, i64 15165, ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 3)), 22 // CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, i32 0, i64 43073, ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 4)), 23 // CHECK-SAME: ptr ptrauth (ptr @_ZN2D0D1Ev, i32 0, i64 25525, ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 5)), 24 // CHECK-SAME: ptr ptrauth (ptr @_ZN2D0D0Ev, i32 0, i64 21295, ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 6)), 25 // CHECK-SAME: ptr ptrauth (ptr @_ZN2D02m1Ev, i32 0, i64 35045, ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 7)), 26 // CHECK-SAME: ptr ptrauth (ptr @_ZN2D02m3Ev, i32 0, i64 10565, ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 8))] }, align 8 27 28 // CHECK: @_ZTV2D1 = unnamed_addr constant { [8 x ptr] } { [8 x ptr] [ptr null, ptr @_ZTI2D1, 29 // CHECK-SAME: ptr ptrauth (ptr @_ZN2D12m0Ev, i32 0, i64 53119, ptr getelementptr inbounds ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 2)), 30 // CHECK-SAME: ptr ptrauth (ptr @_ZTch0_h4_N2D12m1Ev, i32 0, i64 15165, ptr getelementptr inbounds ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 3)), 31 // CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, i32 0, i64 43073, ptr getelementptr inbounds ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 4)), 32 // CHECK-SAME: ptr ptrauth (ptr @_ZN2D1D1Ev, i32 0, i64 25525, ptr getelementptr inbounds ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 5)), 33 // CHECK-SAME: ptr ptrauth (ptr @_ZN2D1D0Ev, i32 0, i64 21295, ptr getelementptr inbounds ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 6)), 34 // CHECK-SAME: ptr ptrauth (ptr @_ZN2D12m1Ev, i32 0, i64 52864, ptr getelementptr inbounds ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 7))] }, align 8 35 36 // CHECK: @_ZTV2D2 = unnamed_addr constant { [9 x ptr], [8 x ptr] } { [9 x ptr] [ptr null, ptr @_ZTI2D2, 37 // CHECK-SAME: ptr ptrauth (ptr @_ZN2D22m0Ev, i32 0, i64 53119, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 2)), 38 // CHECK-SAME: ptr ptrauth (ptr @_ZTch0_h4_N2D22m1Ev, i32 0, i64 15165, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 3)), 39 // CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, i32 0, i64 43073, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 4)), 40 // CHECK-SAME: ptr ptrauth (ptr @_ZN2D2D1Ev, i32 0, i64 25525, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 5)), 41 // CHECK-SAME: ptr ptrauth (ptr @_ZN2D2D0Ev, i32 0, i64 21295, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 6)), 42 // CHECK-SAME: ptr ptrauth (ptr @_ZN2D22m1Ev, i32 0, i64 35045, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 7)), 43 // CHECK-SAME: ptr ptrauth (ptr @_ZN2D22m3Ev, i32 0, i64 10565, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 8))], 44 // CHECK-SAME: [8 x ptr] [ptr inttoptr (i64 -16 to ptr), ptr @_ZTI2D2, 45 // CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D22m0Ev, i32 0, i64 53119, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 2)), 46 // CHECK-SAME: ptr ptrauth (ptr @_ZTchn16_h4_N2D22m1Ev, i32 0, i64 15165, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 3)), 47 // CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, i32 0, i64 43073, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 4)), 48 // CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D2D1Ev, i32 0, i64 25525, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 5)), 49 // CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D2D0Ev, i32 0, i64 21295, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 6)), 50 // CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D22m1Ev, i32 0, i64 52864, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 7))] }, align 8 51 52 // CHECK: @_ZTV2D3 = unnamed_addr constant { [7 x ptr], [7 x ptr], [11 x ptr] } { [7 x ptr] [ptr inttoptr (i64 32 to ptr), ptr null, ptr @_ZTI2D3, 53 // CHECK-SAME: ptr ptrauth (ptr @_ZN2D32m0Ev, i32 0, i64 44578, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 0, i32 3)), 54 // CHECK-SAME: ptr ptrauth (ptr @_ZN2D32m1Ev, i32 0, i64 30766, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 0, i32 4)), 55 // CHECK-SAME: ptr ptrauth (ptr @_ZN2D3D1Ev, i32 0, i64 57279, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 0, i32 5)), 56 // CHECK-SAME: ptr ptrauth (ptr @_ZN2D3D0Ev, i32 0, i64 62452, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 0, i32 6))], 57 // CHECK-SAME: [7 x ptr] [ptr inttoptr (i64 16 to ptr), ptr inttoptr (i64 -16 to ptr), ptr @_ZTI2D3, 58 // CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D32m0Ev, i32 0, i64 49430, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 1, i32 3)), 59 // CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D32m1Ev, i32 0, i64 57119, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 1, i32 4)), 60 // CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D3D1Ev, i32 0, i64 60799, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 1, i32 5)), 61 // CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D3D0Ev, i32 0, i64 52565, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 1, i32 6))], 62 // CHECK-SAME: [11 x ptr] [ptr inttoptr (i64 -32 to ptr), ptr null, ptr inttoptr (i64 -32 to ptr), ptr inttoptr (i64 -32 to ptr), ptr inttoptr (i64 -32 to ptr), ptr @_ZTI2D3, 63 // CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n24_N2D32m0Ev, i32 0, i64 53119, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 2, i32 6)), 64 // CHECK-SAME: ptr ptrauth (ptr @_ZTcv0_n32_h4_N2D32m1Ev, i32 0, i64 15165, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 2, i32 7)), 65 // CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, i32 0, i64 43073, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 2, i32 8)), 66 // CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N2D3D1Ev, i32 0, i64 25525, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 2, i32 9)), 67 // CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N2D3D0Ev, i32 0, i64 21295, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 2, i32 10))] }, align 8 68 69 // CHECK: @_ZTC2D30_2V0 = unnamed_addr constant { [7 x ptr], [11 x ptr] } { [7 x ptr] [ptr inttoptr (i64 32 to ptr), ptr null, ptr @_ZTI2V0, 70 // CHECK-SAME: ptr ptrauth (ptr @_ZN2V02m0Ev, i32 0, i64 44578, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 0, i32 3)), 71 // CHECK-SAME: ptr ptrauth (ptr @_ZN2V02m1Ev, i32 0, i64 30766, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 0, i32 4)), 72 // CHECK-SAME: ptr ptrauth (ptr @_ZN2V0D1Ev, i32 0, i64 57279, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 0, i32 5)), 73 // CHECK-SAME: ptr ptrauth (ptr @_ZN2V0D0Ev, i32 0, i64 62452, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 0, i32 6))], 74 // CHECK-SAME: [11 x ptr] [ptr inttoptr (i64 -32 to ptr), ptr null, ptr inttoptr (i64 -32 to ptr), ptr inttoptr (i64 -32 to ptr), ptr inttoptr (i64 -32 to ptr), ptr @_ZTI2V0, 75 // CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n24_N2V02m0Ev, i32 0, i64 53119, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 1, i32 6)), 76 // CHECK-SAME: ptr ptrauth (ptr @_ZTcv0_n32_h4_N2V02m1Ev, i32 0, i64 15165, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 1, i32 7)), 77 // CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, i32 0, i64 43073, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 1, i32 8)), 78 // CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N2V0D1Ev, i32 0, i64 25525, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 1, i32 9)), 79 // CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N2V0D0Ev, i32 0, i64 21295, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 1, i32 10))] }, align 8 80 81 // CHECK: @_ZTC2D316_2V1 = unnamed_addr constant { [7 x ptr], [11 x ptr] } { [7 x ptr] [ptr inttoptr (i64 16 to ptr), ptr null, ptr @_ZTI2V1, 82 // CHECK-SAME: ptr ptrauth (ptr @_ZN2V12m0Ev, i32 0, i64 49430, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 0, i32 3)), 83 // CHECK-SAME: ptr ptrauth (ptr @_ZN2V12m1Ev, i32 0, i64 57119, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 0, i32 4)), 84 // CHECK-SAME: ptr ptrauth (ptr @_ZN2V1D1Ev, i32 0, i64 60799, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 0, i32 5)), 85 // CHECK-SAME: ptr ptrauth (ptr @_ZN2V1D0Ev, i32 0, i64 52565, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 0, i32 6))], 86 // CHECK-SAME: [11 x ptr] [ptr inttoptr (i64 -16 to ptr), ptr null, ptr inttoptr (i64 -16 to ptr), ptr inttoptr (i64 -16 to ptr), ptr inttoptr (i64 -16 to ptr), ptr @_ZTI2V1, 87 // CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n24_N2V12m0Ev, i32 0, i64 53119, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 1, i32 6)), 88 // CHECK-SAME: ptr ptrauth (ptr @_ZTcv0_n32_h4_N2V12m1Ev, i32 0, i64 15165, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 1, i32 7)), 89 // CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, i32 0, i64 43073, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 1, i32 8)), 90 // CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N2V1D1Ev, i32 0, i64 25525, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 1, i32 9)), 91 // CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N2V1D0Ev, i32 0, i64 21295, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 1, i32 10))] }, align 8 92 93 94 struct S0 { 95 int f; 96 }; 97 98 struct S1 { 99 int f; 100 }; 101 102 struct S2 : S0, S1 { 103 int f; 104 }; 105 106 class B0 { 107 public: 108 virtual void m0(); 109 virtual S1 *m1(); 110 virtual void m2(); 111 virtual ~B0(); 112 int f; 113 }; 114 115 class B1 { 116 public: 117 virtual void m0(); 118 }; 119 120 class D0 : public B0 { 121 public: 122 void m0() override; 123 S2 *m1() override; 124 virtual void m3(); 125 int f; 126 }; 127 128 class D1 : public B0 { 129 public: 130 void m0() override; 131 S2 *m1() override; 132 int f; 133 }; 134 135 class D2 : public D0, public D1 { 136 public: 137 void m0() override; 138 S2 *m1() override; 139 void m3() override; 140 int f; 141 }; 142 143 class V0 : public virtual B0 { 144 public: 145 void m0() override; 146 S2 *m1() override; 147 int f; 148 }; 149 150 class V1 : public virtual B0 { 151 public: 152 void m0() override; 153 S2 *m1() override; 154 ~V1(); 155 int f; 156 }; 157 158 class D3 : public V0, public V1 { 159 public: 160 void m0() override; 161 S2 *m1() override; 162 int f; 163 }; 164 165 B1 g_B1; 166 167 void B0::m0() {} 168 169 void B1::m0() {} 170 171 void D0::m0() {} 172 173 void D1::m0() {} 174 175 void D2::m0() {} 176 177 void D3::m0() {} 178 179 V1::~V1() { 180 m1(); 181 } 182 183 // Check sign/authentication of vtable pointers and authentication of virtual 184 // functions. 185 186 // DARWIN-LABEL: define noundef ptr @_ZN2V1D2Ev( 187 // ELF-LABEL: define dso_local void @_ZN2V1D2Ev( 188 // CHECK: %[[THIS1:.*]] = load ptr, ptr %{{.*}} 189 // CHECK: %[[T0:[0-9]+]] = load ptr, ptr %{{.*}} 190 // CHECK: %[[T1:[0-9]+]] = ptrtoint ptr %[[T0]] to i64 191 // CHECK: %[[T2:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T1]], i32 2, i64 0) 192 // CHECK: %[[T3:[0-9]+]] = inttoptr i64 %[[T2]] to ptr 193 // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[T3]] to i64 194 // CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 %[[T6]], i32 2, i64 0) 195 // CHECK: %[[SIGNED_VTADDR:[0-9]+]] = inttoptr i64 %[[T7]] to ptr 196 // CHECK: store ptr %[[SIGNED_VTADDR]], ptr %[[THIS1]] 197 198 // CHECK-LABEL: define{{.*}} void @_Z8testB0m0P2B0( 199 // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} 200 // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 201 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) 202 // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr 203 // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 0 204 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] 205 // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 206 // CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 53119) 207 // CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] 208 209 void testB0m0(B0 *a) { 210 a->m0(); 211 } 212 213 // CHECK-LABEL: define{{.*}} void @_Z8testB0m1P2B0( 214 // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} 215 // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 216 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) 217 // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr 218 // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 1 219 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] 220 // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 221 // CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 15165) 222 // CHECK: call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] 223 224 void testB0m1(B0 *a) { 225 a->m1(); 226 } 227 228 // CHECK-LABEL: define{{.*}} void @_Z8testB0m2P2B0( 229 // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} 230 // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 231 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) 232 // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr 233 // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 2 234 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] 235 // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 236 // CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 43073) 237 // CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] 238 239 void testB0m2(B0 *a) { 240 a->m2(); 241 } 242 243 // CHECK-LABEL: define{{.*}} void @_Z8testD0m0P2D0( 244 // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} 245 // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 246 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) 247 // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr 248 // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 0 249 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] 250 // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 251 // CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 53119) 252 // CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(16) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] 253 254 void testD0m0(D0 *a) { 255 a->m0(); 256 } 257 258 // CHECK-LABEL: define{{.*}} void @_Z8testD0m1P2D0( 259 // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} 260 // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 261 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) 262 // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr 263 // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 5 264 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] 265 // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 266 // CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 35045) 267 // CHECK: call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(16) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] 268 269 void testD0m1(D0 *a) { 270 a->m1(); 271 } 272 273 // CHECK-LABEL: define{{.*}} void @_Z8testD0m2P2D0( 274 // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} 275 // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 276 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) 277 // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr 278 // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 2 279 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] 280 // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 281 // CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 43073) 282 // CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] 283 284 void testD0m2(D0 *a) { 285 a->m2(); 286 } 287 288 // CHECK-LABEL: define{{.*}} void @_Z8testD0m3P2D0( 289 // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} 290 // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 291 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) 292 // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr 293 // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 6 294 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] 295 // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 296 // CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 10565) 297 // CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(16) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] 298 299 void testD0m3(D0 *a) { 300 a->m3(); 301 } 302 303 304 // CHECK-LABEL: define{{.*}} void @_Z8testD1m0P2D1( 305 // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} 306 // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 307 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) 308 // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr 309 // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 0 310 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] 311 // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 312 // CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 53119) 313 // CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(16) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] 314 315 void testD1m0(D1 *a) { 316 a->m0(); 317 } 318 319 // CHECK-LABEL: define{{.*}} void @_Z8testD1m1P2D1( 320 // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} 321 // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 322 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) 323 // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr 324 // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 5 325 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] 326 // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 327 // CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 52864) 328 // CHECK: call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(16) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] 329 330 void testD1m1(D1 *a) { 331 a->m1(); 332 } 333 334 // CHECK-LABEL: define{{.*}} void @_Z8testD1m2P2D1( 335 // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} 336 // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 337 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) 338 // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr 339 // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 2 340 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] 341 // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 342 // CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 43073) 343 // CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] 344 345 void testD1m2(D1 *a) { 346 a->m2(); 347 } 348 349 350 // CHECK-LABEL: define{{.*}} void @_Z8testD2m0P2D2( 351 // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} 352 // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 353 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) 354 // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr 355 // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 0 356 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] 357 // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 358 // CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 53119) 359 // CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(36) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] 360 361 void testD2m0(D2 *a) { 362 a->m0(); 363 } 364 365 // CHECK-LABEL: define{{.*}} void @_Z8testD2m1P2D2( 366 // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} 367 // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 368 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) 369 // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr 370 // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 5 371 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] 372 // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 373 // CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 35045) 374 // CHECK: call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(36) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] 375 376 void testD2m1(D2 *a) { 377 a->m1(); 378 } 379 380 // CHECK-LABEL: define{{.*}} void @_Z10testD2m2D0P2D2( 381 // CHECK: call void @_ZN2B02m2Ev(ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}){{$}} 382 383 void testD2m2D0(D2 *a) { 384 a->D0::m2(); 385 } 386 387 // CHECK-LABEL: define{{.*}} void @_Z10testD2m2D1P2D2( 388 // CHECK: call void @_ZN2B02m2Ev(ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}){{$}} 389 390 void testD2m2D1(D2 *a) { 391 a->D1::m2(); 392 } 393 394 // CHECK-LABEL: define{{.*}} void @_Z8testD2m3P2D2( 395 // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} 396 // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 397 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) 398 // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr 399 // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 6 400 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] 401 // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 402 // CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 10565) 403 // CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(36) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] 404 405 void testD2m3(D2 *a) { 406 a->m3(); 407 } 408 409 // CHECK-LABEL: define{{.*}} void @_Z8testD3m0P2D3( 410 // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} 411 // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 412 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) 413 // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr 414 // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 0 415 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] 416 // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 417 // CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 44578) 418 // CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] 419 420 void testD3m0(D3 *a) { 421 a->m0(); 422 } 423 424 // CHECK-LABEL: define{{.*}} void @_Z8testD3m1P2D3( 425 // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} 426 // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 427 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) 428 // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr 429 // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 1 430 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] 431 // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 432 // CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 30766) 433 // CHECK: call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] 434 435 void testD3m1(D3 *a) { 436 a->m1(); 437 } 438 439 // CHECK: define{{.*}} void @_Z8testD3m2P2D3(ptr noundef %[[A:.*]]) 440 // CHECK: %[[A_ADDR:.*]] = alloca ptr, align 8 441 // CHECK: store ptr %[[A]], ptr %[[A_ADDR]], align 8 442 // CHECK: %[[V0:.*]] = load ptr, ptr %[[A_ADDR]], align 8 443 // CHECK: %[[VTABLE:.*]] = load ptr, ptr %[[V0]], align 8 444 // CHECK: %[[V1:.*]] = ptrtoint ptr %[[VTABLE]] to i64 445 // CHECK: %[[V2:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V1]], i32 2, i64 0) 446 // CHECK: %[[V3:.*]] = inttoptr i64 %[[V2]] to ptr 447 // CHECK: %[[VBASE_OFFSET_PTR:.*]] = getelementptr i8, ptr %[[V3]], i64 -24 448 // CHECK: %[[VBASE_OFFSET:.*]] = load i64, ptr %[[VBASE_OFFSET_PTR]], align 8 449 // CHECK: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr %[[V0]], i64 %[[VBASE_OFFSET]] 450 // CHECK: %[[VTABLE1:.*]] = load ptr, ptr %[[ADD_PTR]], align 8 451 // CHECK: %[[V4:.*]] = ptrtoint ptr %[[VTABLE1]] to i64 452 // CHECK: %[[V5:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V4]], i32 2, i64 0) 453 // CHECK: %[[V6:.*]] = inttoptr i64 %[[V5]] to ptr 454 // CHECK: %[[VFN:.*]] = getelementptr inbounds ptr, ptr %[[V6]], i64 2 455 // CHECK: %[[V7:.*]] = load ptr, ptr %[[VFN]], align 8 456 // CHECK: %[[V8:.*]] = ptrtoint ptr %[[VFN]] to i64 457 // CHECK: %[[V9:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V8]], i64 43073) 458 // CHECK: call void %[[V7]](ptr noundef nonnull align 8 dereferenceable(12) %[[ADD_PTR]]) [ "ptrauth"(i32 0, i64 %[[V9]]) ] 459 460 void testD3m2(D3 *a) { 461 a->m2(); 462 } 463 464 // CHECK-LABEL: define{{.*}} void @_Z17testD3Destructor0P2D3( 465 // CHECK: load ptr, ptr 466 // CHECK: %[[VTABLE:.*]] = load ptr, ptr %{{.*}} 467 // CHECK: %[[T2:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 468 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T2]], i32 2, i64 0) 469 // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr 470 // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 3 471 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] 472 // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 473 // CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 62452) 474 // CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i32 0, i64 %[[T7]]) ] 475 476 void testD3Destructor0(D3 *a) { 477 delete a; 478 } 479 480 // CHECK-LABEL: define{{.*}} void @_Z17testD3Destructor1P2D3( 481 // CHECK: %[[T6:.*]] = load ptr, ptr % 482 // CHECK: %[[VTABLE0:[a-z0-9]+]] = load ptr, ptr % 483 // CHECK: %[[T2:[0-9]+]] = ptrtoint ptr %[[VTABLE0]] to i64 484 // CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T2]], i32 2, i64 0) 485 // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr 486 // CHECK: %[[COMPLETE_OFFSET_PTR:.*]] = getelementptr inbounds i64, ptr %[[T4]], i64 -2 487 // CHECK: %[[T5:[0-9]+]] = load i64, ptr %[[COMPLETE_OFFSET_PTR]] 488 // CHECK: %[[T7:[0-9]+]] = getelementptr inbounds i8, ptr %[[T6]], i64 %[[T5]] 489 // CHECK: %[[VTABLE1:[a-z0-9]+]] = load ptr, ptr %[[T6]] 490 // CHECK: %[[T9:[0-9]+]] = ptrtoint ptr %[[VTABLE1]] to i64 491 // CHECK: %[[T10:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T9]], i32 2, i64 0) 492 // CHECK: %[[T11:[0-9]+]] = inttoptr i64 %[[T10]] to ptr 493 // CHECK: %[[VFN:[a-z0-9]+]] = getelementptr inbounds ptr, ptr %[[T11]], i64 2 494 // CHECK: %[[T12:[0-9]+]] = load ptr, ptr %[[VFN]] 495 // CHECK: %[[T13:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 496 // CHECK: %[[T14:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T13]], i64 57279) 497 // DARWIN: %call = call noundef ptr %[[T12]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i32 0, i64 %[[T14]]) ] 498 // ELF: call void %[[T12]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i32 0, i64 %[[T14]]) ] 499 // CHECK: call void @_ZdlPv(ptr noundef %[[T7]]) 500 501 void testD3Destructor1(D3 *a) { 502 ::delete a; 503 } 504 505 // CHECK-LABEL: define{{.*}} void @_Z17testD3Destructor2P2D3( 506 // CHECK: load ptr, ptr 507 // CHECK: %[[VTABLE:.*]] = load ptr, ptr % 508 // CHECK: %[[T2:.*]] = ptrtoint ptr %[[VTABLE]] to i64 509 // CHECK: %[[T3:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[T2]], i32 2, i64 0) 510 // CHECK: %[[T4:.*]] = inttoptr i64 %[[T3]] to ptr 511 // CHECK: %[[VFN:.*]] = getelementptr inbounds ptr, ptr %[[T4]], i64 2 512 // CHECK: %[[T5:.*]] = load ptr, ptr %[[VFN]] 513 // CHECK: %[[T6:.*]] = ptrtoint ptr %[[VFN]] to i64 514 // CHECK: %[[T7:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 57279) 515 // DARWIN: %call = call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i32 0, i64 %[[T7]]) ] 516 // ELF: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i32 0, i64 %[[T7]]) ] 517 518 void testD3Destructor2(D3 *a) { 519 a->~D3(); 520 } 521 522 void materializeConstructors() { 523 B0 B0; 524 B1 B1; 525 D0 D0; 526 D1 D1; 527 D2 D2; 528 D3 D3; 529 V0 V0; 530 V1 V1; 531 } 532 533 // DARWIN-LABEL: define linkonce_odr noundef ptr @_ZN2B0C2Ev( 534 // ELF-LABEL: define linkonce_odr void @_ZN2B0C2Ev( 535 // CHECK: %[[THIS:.*]] = load ptr, ptr % 536 // CHECK: %[[T0:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 40) ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 2) to i64), i32 2, i64 0) 537 // CHECK: %[[SIGNED_VTADDR:[0-9]+]] = inttoptr i64 %[[T0]] to ptr 538 // CHECK: store ptr %[[SIGNED_VTADDR]], ptr %[[THIS]] 539 540 // DARWIN-LABEL: define linkonce_odr noundef ptr @_ZN2D0C2Ev( 541 // ELF-LABEL: define linkonce_odr void @_ZN2D0C2Ev( 542 // CHECK: %[[T0:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 56) ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 2) to i64), i32 2, i64 0) 543 // CHECK: %[[SIGNED_VTADDR:[0-9]+]] = inttoptr i64 %[[T0]] to ptr 544 // CHECK: store ptr %[[SIGNED_VTADDR]], ptr %[[THIS]] 545 546 // DARWIN-LABEL: define linkonce_odr noundef ptr @_ZN2D1C2Ev( 547 // ELF-LABEL: define linkonce_odr void @_ZN2D1C2Ev( 548 // CHECK: %[[T0:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 48) ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 2) to i64), i32 2, i64 0) 549 // CHECK: %[[SIGNED_VTADDR:[0-9]+]] = inttoptr i64 %[[T0]] to ptr 550 // CHECK: store ptr %[[SIGNED_VTADDR]], ptr %[[THIS]] 551 552 // DARWIN-LABEL: define linkonce_odr noundef ptr @_ZN2D2C2Ev( 553 // ELF-LABEL: define linkonce_odr void @_ZN2D2C2Ev( 554 // CHECK: %[[SLOT0:.*]] = load ptr, ptr 555 // CHECK: %[[SIGN_VTADDR0:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 56) ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 2) to i64), i32 2, i64 0) 556 // CHECK: %[[T1:[0-9]+]] = inttoptr i64 %[[SIGN_VTADDR0]] to ptr 557 // CHECK: store ptr %[[T1]], ptr %[[SLOT0]] 558 // CHECK: %[[T3:[a-z0-9.]+]] = getelementptr inbounds i8, ptr %[[SLOT0]], i64 16 559 // CHECK: %[[SIGN_VTADDR1:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 48) ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 2) to i64), i32 2, i64 0) 560 // CHECK: %[[T5:[0-9]+]] = inttoptr i64 %[[SIGN_VTADDR1]] to ptr 561 // CHECK: store ptr %[[T5]], ptr %[[T3]] 562 563 // DARWIN-LABEL: define linkonce_odr noundef ptr @_ZN2V0C2Ev( 564 // ELF-LABEL: define linkonce_odr void @_ZN2V0C2Ev( 565 // CHECK: %[[THIS1]] = load ptr, ptr % 566 // CHECK: %[[VTT:[a-z0-9]+]] = load ptr, ptr %{{.*}} 567 // CHECK: %[[T0:[0-9]+]] = load ptr, ptr %[[VTT]] 568 // CHECK: %[[T1:[0-9]+]] = ptrtoint ptr %[[T0]] to i64 569 // CHECK: %[[T2:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T1]], i32 2, i64 0) 570 // CHECK: %[[T3:[0-9]+]] = inttoptr i64 %[[T2]] to ptr 571 // CHECK: %[[VTADDR0:[0-9]+]] = ptrtoint ptr %[[T3]] to i64 572 // CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 %[[VTADDR0]], i32 2, i64 0) 573 // CHECK: %[[SIGN_VTADDR0:[0-9]+]] = inttoptr i64 %[[T7]] to ptr 574 // CHECK: store ptr %[[SIGN_VTADDR0]], ptr %[[SLOT0]] 575 // CHECK: %[[T9:[0-9]+]] = getelementptr inbounds ptr, ptr %[[VTT]], i64 1 576 // CHECK: %[[T10:[0-9]+]] = load ptr, ptr %[[T9]] 577 // CHECK: %[[T11:[0-9]+]] = ptrtoint ptr %[[T10]] to i64 578 // CHECK: %[[T12:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T11]], i32 2, i64 0) 579 // CHECK: %[[T13:[0-9]+]] = inttoptr i64 %[[T12]] to ptr 580 // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %[[THIS1]] 581 // CHECK: %[[T15:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 582 // CHECK: %[[T16:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T15]], i32 2, i64 0) 583 // CHECK: %[[T17:[0-9]+]] = inttoptr i64 %[[T16]] to ptr 584 // CHECK: %[[VBASE_OFFSET_PTR:[a-z.]+]] = getelementptr i8, ptr %[[T17]], i64 -24 585 // CHECK: %[[VBASE_OFFSET:[a-z.]+]] = load i64, ptr %[[VBASE_OFFSET_PTR]] 586 // CHECK: %[[T20:[a-z.]+]] = getelementptr inbounds i8, ptr %[[THIS1]], i64 %[[VBASE_OFFSET]] 587 // CHECK: %[[VTADDR1:[0-9]+]] = ptrtoint ptr %[[T13]] to i64 588 // CHECK: %[[T23:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 %[[VTADDR1]], i32 2, i64 0) 589 // CHECK: %[[SIGN_VTADDR1:[0-9]+]] = inttoptr i64 %[[T23]] to ptr 590 // CHECK: store ptr %[[SIGN_VTADDR1]], ptr %[[T20]] 591