[AMDGPU][True16][CodeGen] true16 codegen pattern for v_med3_u/i16 (#121850)
[llvm-project.git] / clang / test / CodeGenCXX / ptrauth-explicit-vtable-pointer-control.cpp
blob1b103719fbe46df0b4223730bad7c45a39075f5c
1 // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \
2 // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,NODISC %s
4 // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \
5 // RUN: -fptrauth-vtable-pointer-type-discrimination \
6 // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,TYPE %s
8 // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \
9 // RUN: -fptrauth-vtable-pointer-address-discrimination \
10 // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,ADDR %s
12 // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \
13 // RUN: -fptrauth-vtable-pointer-type-discrimination \
14 // RUN: -fptrauth-vtable-pointer-address-discrimination \
15 // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,BOTH %s
17 // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
18 // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,NODISC %s
20 // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
21 // RUN: -fptrauth-vtable-pointer-type-discrimination \
22 // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,TYPE %s
24 // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
25 // RUN: -fptrauth-vtable-pointer-address-discrimination \
26 // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,ADDR %s
28 // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
29 // RUN: -fptrauth-vtable-pointer-type-discrimination \
30 // RUN: -fptrauth-vtable-pointer-address-discrimination \
31 // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,BOTH %s
33 #include <ptrauth.h>
35 namespace test1 {
37 #define authenticated(a...) ptrauth_cxx_vtable_pointer(a)
39 struct NoExplicitAuth {
40 virtual ~NoExplicitAuth();
41 virtual void f();
42 virtual void g();
45 struct authenticated(no_authentication, no_address_discrimination, no_extra_discrimination) ExplicitlyDisableAuth {
46 virtual ~ExplicitlyDisableAuth();
47 virtual void f();
48 virtual void g();
51 struct authenticated(default_key, address_discrimination, default_extra_discrimination) ExplicitAddressDiscrimination {
52 virtual ~ExplicitAddressDiscrimination();
53 virtual void f();
54 virtual void g();
57 struct authenticated(default_key, no_address_discrimination, default_extra_discrimination) ExplicitNoAddressDiscrimination {
58 virtual ~ExplicitNoAddressDiscrimination();
59 virtual void f();
60 virtual void g();
63 struct authenticated(default_key, default_address_discrimination, no_extra_discrimination) ExplicitNoExtraDiscrimination {
64 virtual ~ExplicitNoExtraDiscrimination();
65 virtual void f();
66 virtual void g();
69 struct authenticated(default_key, default_address_discrimination, type_discrimination) ExplicitTypeDiscrimination {
70 virtual ~ExplicitTypeDiscrimination();
71 virtual void f();
72 virtual void g();
75 struct authenticated(default_key, default_address_discrimination, custom_discrimination, 42424) ExplicitCustomDiscrimination {
76 virtual ~ExplicitCustomDiscrimination();
77 virtual void f();
78 virtual void g();
81 template <typename T>
82 struct SubClass : T {
83 virtual void g();
84 virtual T *h();
87 template <typename T>
88 SubClass<T> *make_subclass(T *);
90 struct authenticated(default_key, address_discrimination, type_discrimination) BasicStruct {
91 virtual ~BasicStruct();
94 template <typename T>
95 struct PrimaryBasicStruct : BasicStruct, T {};
96 template <typename T>
97 struct PrimaryBasicStruct<T> *make_multiple_primary(T *);
99 template <typename T>
100 struct VirtualSubClass : virtual T {
101 virtual void g();
102 virtual T *h();
104 template <typename T>
105 struct VirtualPrimaryStruct : virtual T, VirtualSubClass<T> {};
106 template <typename T>
107 struct VirtualPrimaryStruct<T> *make_virtual_primary(T *);
109 extern "C" {
111 // CHECK: @TVDisc_NoExplicitAuth = global i32 [[DISC_DEFAULT:49565]], align 4
112 int TVDisc_NoExplicitAuth = ptrauth_string_discriminator("_ZTVN5test114NoExplicitAuthE");
114 // CHECK: @TVDisc_ExplicitlyDisableAuth = global i32 [[DISC_DISABLED:24369]], align 4
115 int TVDisc_ExplicitlyDisableAuth = ptrauth_string_discriminator("_ZTVN5test121ExplicitlyDisableAuthE");
117 // CHECK: @TVDisc_ExplicitAddressDiscrimination = global i32 [[DISC_ADDR:56943]], align 4
118 int TVDisc_ExplicitAddressDiscrimination = ptrauth_string_discriminator("_ZTVN5test129ExplicitAddressDiscriminationE");
120 // CHECK: @TVDisc_ExplicitNoAddressDiscrimination = global i32 [[DISC_NO_ADDR:6022]], align 4
121 int TVDisc_ExplicitNoAddressDiscrimination = ptrauth_string_discriminator("_ZTVN5test131ExplicitNoAddressDiscriminationE");
123 // CHECK: @TVDisc_ExplicitNoExtraDiscrimination = global i32 [[DISC_NO_EXTRA:9072]], align 4
124 int TVDisc_ExplicitNoExtraDiscrimination = ptrauth_string_discriminator("_ZTVN5test129ExplicitNoExtraDiscriminationE");
126 // CHECK: @TVDisc_ExplicitTypeDiscrimination = global i32 [[DISC_TYPE:6177]], align 4
127 int TVDisc_ExplicitTypeDiscrimination = ptrauth_string_discriminator("_ZTVN5test126ExplicitTypeDiscriminationE");
130 // CHECK-LABEL: define{{.*}} void @test_default(ptr noundef {{%.*}}) {{#.*}} {
131 // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8
132 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
134 // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
135 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
137 // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
138 // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_DEFAULT]])
140 // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
141 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
142 // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
144 // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
145 // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_DEFAULT]])
146 // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
147 // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
148 void test_default(NoExplicitAuth *a) {
149 a->f();
152 // CHECK-LABEL: define{{.*}} void @test_disabled(ptr noundef {{%.*}}) {{#.*}} {
153 // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8
154 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
155 // CHECK-NOT: call i64 @llvm.ptrauth.auth
156 void test_disabled(ExplicitlyDisableAuth *a) {
157 a->f();
160 // CHECK-LABEL: define{{.*}} void @test_addr_disc(ptr noundef {{%.*}}) {{#.*}} {
161 // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8
162 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
164 // NODISC: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
165 // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
166 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
168 // TYPE: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
169 // TYPE: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_ADDR]])
170 // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
171 // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
173 // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
174 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
175 // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
177 // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
178 // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_ADDR]])
179 // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
180 // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
181 void test_addr_disc(ExplicitAddressDiscrimination *a) {
182 a->f();
185 // CHECK-LABEL: define{{.*}} void @test_no_addr_disc(ptr noundef {{%.*}}) {{#.*}} {
186 // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8
187 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
189 // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
190 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
192 // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
193 // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_NO_ADDR]])
195 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
196 // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
198 // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
199 // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_NO_ADDR]])
200 void test_no_addr_disc(ExplicitNoAddressDiscrimination *a) {
201 a->f();
204 // CHECK-LABEL: define{{.*}} void @test_no_extra_disc(ptr noundef {{%.*}}) {{#.*}} {
205 // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8
206 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
208 // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
209 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
211 // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
212 // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
214 // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
215 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
216 // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
218 // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
219 // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
220 // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
221 void test_no_extra_disc(ExplicitNoExtraDiscrimination *a) {
222 a->f();
225 // CHECK-LABEL: define{{.*}} void @test_type_disc(ptr noundef {{%.*}}) {{#.*}} {
226 // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8
227 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
229 // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
230 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_TYPE]])
232 // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
233 // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_TYPE]])
235 // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
236 // ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_TYPE]])
237 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
238 // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
240 // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
241 // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_TYPE]])
242 // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
243 // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
244 void test_type_disc(ExplicitTypeDiscrimination *a) {
245 a->f();
248 // CHECK-LABEL: define{{.*}} void @test_custom_disc(ptr noundef {{%.*}}) {{#.*}} {
249 // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8
250 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
252 // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
253 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424)
255 // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
256 // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424)
258 // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
259 // ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424)
260 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
261 // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
263 // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
264 // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424)
265 // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
266 // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
267 void test_custom_disc(ExplicitCustomDiscrimination *a) {
268 a->f();
272 // Test some simple single inheritance cases.
273 // Codegen should be the same as the simple cases above once we have a vtable.
276 // CHECK-LABEL: define{{.*}} void @test_subclass_default(ptr noundef {{%.*}}) {{#.*}} {
277 // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass
278 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
280 // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
281 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
283 // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
284 // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_DEFAULT]])
286 // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
287 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
288 // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
290 // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
291 // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_DEFAULT]])
292 // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
293 // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
294 void test_subclass_default(NoExplicitAuth *a) {
295 make_subclass(a)->f();
298 // CHECK-LABEL: define{{.*}} void @test_subclass_disabled(ptr noundef {{%.*}}) {{#.*}} {
299 // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass
300 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
301 // CHECK-NOT: call i64 @llvm.ptrauth.auth
302 void test_subclass_disabled(ExplicitlyDisableAuth *a) {
303 make_subclass(a)->f();
306 // CHECK-LABEL: define{{.*}} void @test_subclass_addr_disc(ptr noundef {{%.*}}) {{#.*}} {
307 // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass
308 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
310 // NODISC: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
311 // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
312 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
314 // TYPE: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
315 // TYPE: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_ADDR]])
316 // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
317 // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
319 // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
320 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
321 // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
323 // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
324 // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_ADDR]])
325 // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
326 // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
327 void test_subclass_addr_disc(ExplicitAddressDiscrimination *a) {
328 make_subclass(a)->f();
331 // CHECK-LABEL: define{{.*}} void @test_subclass_no_addr_disc(ptr noundef {{%.*}}) {{#.*}} {
332 // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass
333 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
335 // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
336 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
338 // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
339 // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_NO_ADDR]])
341 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
342 // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
344 // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
345 // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_NO_ADDR]])
346 void test_subclass_no_addr_disc(ExplicitNoAddressDiscrimination *a) {
347 make_subclass(a)->f();
350 // CHECK-LABEL: define{{.*}} void @test_subclass_no_extra_disc(ptr noundef {{%.*}}) {{#.*}} {
351 // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass
352 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
354 // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
355 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
357 // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
358 // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
360 // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
361 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
362 // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
364 // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
365 // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
366 // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
367 void test_subclass_no_extra_disc(ExplicitNoExtraDiscrimination *a) {
368 make_subclass(a)->f();
371 // CHECK-LABEL: define{{.*}} void @test_subclass_type_disc(ptr noundef {{%.*}}) {{#.*}} {
372 // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass
373 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
375 // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
376 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_TYPE]])
378 // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
379 // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_TYPE]])
381 // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
382 // ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_TYPE]])
383 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
384 // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
386 // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
387 // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_TYPE]])
388 // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
389 // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
390 void test_subclass_type_disc(ExplicitTypeDiscrimination *a) {
391 make_subclass(a)->f();
394 // CHECK-LABEL: define{{.*}} void @test_subclass_custom_disc(ptr noundef {{%.*}}) {{#.*}} {
395 // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass
396 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
398 // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
399 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424)
401 // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
402 // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424)
404 // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
405 // ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424)
406 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
407 // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
409 // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
410 // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424)
411 // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
412 // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
413 void test_subclass_custom_disc(ExplicitCustomDiscrimination *a) {
414 make_subclass(a)->f();
419 // Test some simple multiple inheritance cases.
420 // Codegen should be the same as the simple cases above once we have a vtable.
423 // CHECK-LABEL: define{{.*}} void @test_multiple_default(ptr noundef {{%.*}}) {{#.*}} {
424 // CHECK: [[CALL:%.*]] = call noundef ptr @_ZN5test121make_multiple_primary
425 // CHECK: [[VTADDR:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8
426 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
428 // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
429 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
431 // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
432 // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_DEFAULT]])
434 // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
435 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
436 // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
438 // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
439 // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_DEFAULT]])
440 // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
441 // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
442 void test_multiple_default(NoExplicitAuth *a) {
443 make_multiple_primary(a)->f();
446 // CHECK-LABEL: define{{.*}} void @test_multiple_disabled(ptr noundef {{%.*}}) {{#.*}} {
447 // CHECK: [[CALL:%.*]] = call noundef ptr @_ZN5test121make_multiple_primary
448 // CHECK: [[VTADDR:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8
449 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
450 // CHECK-NOT: call i64 @llvm.ptrauth.auth
451 void test_multiple_disabled(ExplicitlyDisableAuth *a) {
452 make_multiple_primary(a)->f();
455 // CHECK-LABEL: define{{.*}} void @test_multiple_custom_disc(ptr noundef {{%.*}}) {{#.*}} {
456 // CHECK: [[CALL:%.*]] = call noundef ptr @_ZN5test121make_multiple_primary
457 // CHECK: [[VTADDR:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8
458 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
460 // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
461 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424)
463 // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
464 // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424)
466 // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
467 // ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424)
468 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
469 // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
471 // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
472 // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424)
473 // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
474 // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
475 void test_multiple_custom_disc(ExplicitCustomDiscrimination *a) {
476 make_multiple_primary(a)->f();
480 // Test some virtual inheritance cases.
481 // Codegen should be the same as the simple cases above once we have a vtable,
482 // but twice for vtt/vtable. The names in the vtt version have "VTT" prefixes.
485 // CHECK-LABEL: define{{.*}} void @test_virtual_default(ptr noundef {{%.*}}) {{#.*}} {
486 // CHECK: [[VTTADDR:%.*]] = call noundef ptr @_ZN5test120make_virtual_primary
487 // CHECK: [[VTTABLE:%.*]] = load ptr, ptr [[VTTADDR]], align 8
489 // NODISC: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64
490 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 0)
492 // TYPE: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64
493 // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[DISC_DEFAULT]])
495 // ADDR: [[VTTADDRI64:%.*]] = ptrtoint ptr [[VTTADDR]] to i64
496 // ADDR: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64
497 // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[VTTADDRI64]])
499 // BOTH: [[VTTADDRI64:%.*]] = ptrtoint ptr [[VTTADDR]] to i64
500 // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTTADDRI64]], i64 [[DISC_DEFAULT]])
501 // BOTH: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64
502 // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[BLEND]])
504 // CHECK: [[AUTHEDPTR:%.*]] = inttoptr i64 [[AUTHED]] to ptr
505 // CHECK: [[VBOFFPTR:%.*]] = getelementptr i8, ptr [[AUTHEDPTR]], i64 -48
506 // CHECK: [[VBOFFSET:%.*]] = load i64, ptr [[VBOFFPTR]]
507 // CHECK: [[VTADDR:%.*]] = getelementptr inbounds i8, ptr [[VTTADDR]], i64 [[VBOFFSET]]
508 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
510 // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
511 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
513 // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
514 // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_DEFAULT]])
516 // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
517 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
518 // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
520 // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
521 // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_DEFAULT]])
522 // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
523 // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
524 void test_virtual_default(NoExplicitAuth *a) {
525 make_virtual_primary(a)->f();
528 // CHECK-LABEL: define{{.*}} void @test_virtual_disabled(ptr noundef {{%.*}}) {{#.*}} {
529 // CHECK-NOT: call i64 @llvm.ptrauth.auth
530 void test_virtual_disabled(ExplicitlyDisableAuth *a) {
531 make_virtual_primary(a)->f();
534 // CHECK-LABEL: define{{.*}} void @test_virtual_custom_disc(ptr noundef {{%.*}}) {{#.*}} {
535 // CHECK: [[VTTADDR:%.*]] = call noundef ptr @_ZN5test120make_virtual_primary
536 // CHECK: [[VTTABLE:%.*]] = load ptr, ptr [[VTTADDR]], align 8
538 // NODISC: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64
539 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 42424)
541 // TYPE: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64
542 // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 42424)
544 // ADDR: [[VTTADDRI64:%.*]] = ptrtoint ptr [[VTTADDR]] to i64
545 // ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTTADDRI64]], i64 42424)
546 // ADDR: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64
547 // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[BLEND]])
549 // BOTH: [[VTTADDRI64:%.*]] = ptrtoint ptr [[VTTADDR]] to i64
550 // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTTADDRI64]], i64 42424)
551 // BOTH: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64
552 // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[BLEND]])
554 // CHECK: [[AUTHEDPTR:%.*]] = inttoptr i64 [[AUTHED]] to ptr
555 // CHECK: [[VBOFFPTR:%.*]] = getelementptr i8, ptr [[AUTHEDPTR]], i64 -48
556 // CHECK: [[VBOFFSET:%.*]] = load i64, ptr [[VBOFFPTR]]
557 // CHECK: [[VTADDR:%.*]] = getelementptr inbounds i8, ptr [[VTTADDR]], i64 [[VBOFFSET]]
558 // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
560 // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
561 // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424)
563 // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
564 // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424)
566 // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
567 // ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424)
568 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
569 // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
571 // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
572 // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424)
573 // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
574 // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
575 void test_virtual_custom_disc(ExplicitCustomDiscrimination *a) {
576 make_virtual_primary(a)->f();
579 } // extern "C"
580 } // namespace test1