xref: /llvm-project/clang/test/CodeGenCXX/ptrauth-explicit-vtable-pointer-control.cpp (revision a1d77caaabbb5279b734c061dab36b2138ec476d)
11b8ab2f0SOliver Hunt // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \
21b8ab2f0SOliver Hunt // RUN:   -emit-llvm -o - | FileCheck --check-prefixes=CHECK,NODISC %s
31b8ab2f0SOliver Hunt 
41b8ab2f0SOliver Hunt // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios   -fptrauth-calls -fptrauth-intrinsics \
51b8ab2f0SOliver Hunt // RUN:   -fptrauth-vtable-pointer-type-discrimination \
61b8ab2f0SOliver Hunt // RUN:   -emit-llvm -o - | FileCheck --check-prefixes=CHECK,TYPE %s
71b8ab2f0SOliver Hunt 
81b8ab2f0SOliver Hunt // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios   -fptrauth-calls -fptrauth-intrinsics \
91b8ab2f0SOliver Hunt // RUN:   -fptrauth-vtable-pointer-address-discrimination \
101b8ab2f0SOliver Hunt // RUN:   -emit-llvm -o - | FileCheck --check-prefixes=CHECK,ADDR %s
111b8ab2f0SOliver Hunt 
121b8ab2f0SOliver Hunt // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios   -fptrauth-calls -fptrauth-intrinsics \
131b8ab2f0SOliver Hunt // RUN:   -fptrauth-vtable-pointer-type-discrimination \
141b8ab2f0SOliver Hunt // RUN:   -fptrauth-vtable-pointer-address-discrimination \
151b8ab2f0SOliver Hunt // RUN:   -emit-llvm -o - | FileCheck --check-prefixes=CHECK,BOTH %s
161b8ab2f0SOliver Hunt 
17*a1d77caaSDaniil Kovalev // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
18*a1d77caaSDaniil Kovalev // RUN:   -emit-llvm -o - | FileCheck --check-prefixes=CHECK,NODISC %s
19*a1d77caaSDaniil Kovalev 
20*a1d77caaSDaniil Kovalev // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
21*a1d77caaSDaniil Kovalev // RUN:   -fptrauth-vtable-pointer-type-discrimination \
22*a1d77caaSDaniil Kovalev // RUN:   -emit-llvm -o - | FileCheck --check-prefixes=CHECK,TYPE %s
23*a1d77caaSDaniil Kovalev 
24*a1d77caaSDaniil Kovalev // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
25*a1d77caaSDaniil Kovalev // RUN:   -fptrauth-vtable-pointer-address-discrimination \
26*a1d77caaSDaniil Kovalev // RUN:   -emit-llvm -o - | FileCheck --check-prefixes=CHECK,ADDR %s
27*a1d77caaSDaniil Kovalev 
28*a1d77caaSDaniil Kovalev // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
29*a1d77caaSDaniil Kovalev // RUN:   -fptrauth-vtable-pointer-type-discrimination \
30*a1d77caaSDaniil Kovalev // RUN:   -fptrauth-vtable-pointer-address-discrimination \
31*a1d77caaSDaniil Kovalev // RUN:   -emit-llvm -o - | FileCheck --check-prefixes=CHECK,BOTH %s
32*a1d77caaSDaniil Kovalev 
331b8ab2f0SOliver Hunt #include <ptrauth.h>
341b8ab2f0SOliver Hunt 
351b8ab2f0SOliver Hunt namespace test1 {
361b8ab2f0SOliver Hunt 
371b8ab2f0SOliver Hunt #define authenticated(a...) ptrauth_cxx_vtable_pointer(a)
381b8ab2f0SOliver Hunt 
391b8ab2f0SOliver Hunt struct NoExplicitAuth {
401b8ab2f0SOliver Hunt   virtual ~NoExplicitAuth();
411b8ab2f0SOliver Hunt   virtual void f();
421b8ab2f0SOliver Hunt   virtual void g();
431b8ab2f0SOliver Hunt };
441b8ab2f0SOliver Hunt 
451b8ab2f0SOliver Hunt struct authenticated(no_authentication, no_address_discrimination, no_extra_discrimination) ExplicitlyDisableAuth {
461b8ab2f0SOliver Hunt   virtual ~ExplicitlyDisableAuth();
471b8ab2f0SOliver Hunt   virtual void f();
481b8ab2f0SOliver Hunt   virtual void g();
491b8ab2f0SOliver Hunt };
501b8ab2f0SOliver Hunt 
511b8ab2f0SOliver Hunt struct authenticated(default_key, address_discrimination, default_extra_discrimination) ExplicitAddressDiscrimination {
521b8ab2f0SOliver Hunt   virtual ~ExplicitAddressDiscrimination();
531b8ab2f0SOliver Hunt   virtual void f();
541b8ab2f0SOliver Hunt   virtual void g();
551b8ab2f0SOliver Hunt };
561b8ab2f0SOliver Hunt 
571b8ab2f0SOliver Hunt struct authenticated(default_key, no_address_discrimination, default_extra_discrimination) ExplicitNoAddressDiscrimination {
581b8ab2f0SOliver Hunt   virtual ~ExplicitNoAddressDiscrimination();
591b8ab2f0SOliver Hunt   virtual void f();
601b8ab2f0SOliver Hunt   virtual void g();
611b8ab2f0SOliver Hunt };
621b8ab2f0SOliver Hunt 
631b8ab2f0SOliver Hunt struct authenticated(default_key, default_address_discrimination, no_extra_discrimination) ExplicitNoExtraDiscrimination {
641b8ab2f0SOliver Hunt   virtual ~ExplicitNoExtraDiscrimination();
651b8ab2f0SOliver Hunt   virtual void f();
661b8ab2f0SOliver Hunt   virtual void g();
671b8ab2f0SOliver Hunt };
681b8ab2f0SOliver Hunt 
691b8ab2f0SOliver Hunt struct authenticated(default_key, default_address_discrimination, type_discrimination) ExplicitTypeDiscrimination {
701b8ab2f0SOliver Hunt   virtual ~ExplicitTypeDiscrimination();
711b8ab2f0SOliver Hunt   virtual void f();
721b8ab2f0SOliver Hunt   virtual void g();
731b8ab2f0SOliver Hunt };
741b8ab2f0SOliver Hunt 
751b8ab2f0SOliver Hunt struct authenticated(default_key, default_address_discrimination, custom_discrimination, 42424) ExplicitCustomDiscrimination {
761b8ab2f0SOliver Hunt   virtual ~ExplicitCustomDiscrimination();
771b8ab2f0SOliver Hunt   virtual void f();
781b8ab2f0SOliver Hunt   virtual void g();
791b8ab2f0SOliver Hunt };
801b8ab2f0SOliver Hunt 
811b8ab2f0SOliver Hunt template <typename T>
821b8ab2f0SOliver Hunt struct SubClass : T {
831b8ab2f0SOliver Hunt   virtual void g();
841b8ab2f0SOliver Hunt   virtual T *h();
851b8ab2f0SOliver Hunt };
861b8ab2f0SOliver Hunt 
871b8ab2f0SOliver Hunt template <typename T>
881b8ab2f0SOliver Hunt SubClass<T> *make_subclass(T *);
891b8ab2f0SOliver Hunt 
901b8ab2f0SOliver Hunt struct authenticated(default_key, address_discrimination, type_discrimination) BasicStruct {
911b8ab2f0SOliver Hunt   virtual ~BasicStruct();
921b8ab2f0SOliver Hunt };
931b8ab2f0SOliver Hunt 
941b8ab2f0SOliver Hunt template <typename T>
951b8ab2f0SOliver Hunt struct PrimaryBasicStruct : BasicStruct, T {};
961b8ab2f0SOliver Hunt template <typename T>
971b8ab2f0SOliver Hunt struct PrimaryBasicStruct<T> *make_multiple_primary(T *);
981b8ab2f0SOliver Hunt 
991b8ab2f0SOliver Hunt template <typename T>
1001b8ab2f0SOliver Hunt struct VirtualSubClass : virtual T {
1011b8ab2f0SOliver Hunt   virtual void g();
1021b8ab2f0SOliver Hunt   virtual T *h();
1031b8ab2f0SOliver Hunt };
1041b8ab2f0SOliver Hunt template <typename T>
1051b8ab2f0SOliver Hunt struct VirtualPrimaryStruct : virtual T, VirtualSubClass<T> {};
1061b8ab2f0SOliver Hunt template <typename T>
1071b8ab2f0SOliver Hunt struct VirtualPrimaryStruct<T> *make_virtual_primary(T *);
1081b8ab2f0SOliver Hunt 
1091b8ab2f0SOliver Hunt extern "C" {
1101b8ab2f0SOliver Hunt 
1111b8ab2f0SOliver Hunt // CHECK: @TVDisc_NoExplicitAuth = global i32 [[DISC_DEFAULT:49565]], align 4
1121b8ab2f0SOliver Hunt int TVDisc_NoExplicitAuth = ptrauth_string_discriminator("_ZTVN5test114NoExplicitAuthE");
1131b8ab2f0SOliver Hunt 
1141b8ab2f0SOliver Hunt // CHECK: @TVDisc_ExplicitlyDisableAuth = global i32 [[DISC_DISABLED:24369]], align 4
1151b8ab2f0SOliver Hunt int TVDisc_ExplicitlyDisableAuth = ptrauth_string_discriminator("_ZTVN5test121ExplicitlyDisableAuthE");
1161b8ab2f0SOliver Hunt 
1171b8ab2f0SOliver Hunt // CHECK: @TVDisc_ExplicitAddressDiscrimination = global i32 [[DISC_ADDR:56943]], align 4
1181b8ab2f0SOliver Hunt int TVDisc_ExplicitAddressDiscrimination = ptrauth_string_discriminator("_ZTVN5test129ExplicitAddressDiscriminationE");
1191b8ab2f0SOliver Hunt 
1201b8ab2f0SOliver Hunt // CHECK: @TVDisc_ExplicitNoAddressDiscrimination = global i32 [[DISC_NO_ADDR:6022]], align 4
1211b8ab2f0SOliver Hunt int TVDisc_ExplicitNoAddressDiscrimination = ptrauth_string_discriminator("_ZTVN5test131ExplicitNoAddressDiscriminationE");
1221b8ab2f0SOliver Hunt 
1231b8ab2f0SOliver Hunt // CHECK: @TVDisc_ExplicitNoExtraDiscrimination = global i32 [[DISC_NO_EXTRA:9072]], align 4
1241b8ab2f0SOliver Hunt int TVDisc_ExplicitNoExtraDiscrimination = ptrauth_string_discriminator("_ZTVN5test129ExplicitNoExtraDiscriminationE");
1251b8ab2f0SOliver Hunt 
1261b8ab2f0SOliver Hunt // CHECK: @TVDisc_ExplicitTypeDiscrimination = global i32 [[DISC_TYPE:6177]], align 4
1271b8ab2f0SOliver Hunt int TVDisc_ExplicitTypeDiscrimination = ptrauth_string_discriminator("_ZTVN5test126ExplicitTypeDiscriminationE");
1281b8ab2f0SOliver Hunt 
1291b8ab2f0SOliver Hunt 
130*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_default(ptr noundef {{%.*}}) {{#.*}} {
1311b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8
1321b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
1331b8ab2f0SOliver Hunt //
1341b8ab2f0SOliver Hunt // NODISC:        [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
1351b8ab2f0SOliver Hunt // NODISC:        [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
1361b8ab2f0SOliver Hunt //
1371b8ab2f0SOliver Hunt // TYPE:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
1381b8ab2f0SOliver Hunt // TYPE:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_DEFAULT]])
1391b8ab2f0SOliver Hunt //
1401b8ab2f0SOliver Hunt // ADDR:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
1411b8ab2f0SOliver Hunt // ADDR:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
1421b8ab2f0SOliver Hunt // ADDR:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
1431b8ab2f0SOliver Hunt //
1441b8ab2f0SOliver Hunt // BOTH:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
1451b8ab2f0SOliver Hunt // BOTH:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_DEFAULT]])
1461b8ab2f0SOliver Hunt // BOTH:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
1471b8ab2f0SOliver Hunt // BOTH:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
1481b8ab2f0SOliver Hunt void test_default(NoExplicitAuth *a) {
1491b8ab2f0SOliver Hunt   a->f();
1501b8ab2f0SOliver Hunt }
1511b8ab2f0SOliver Hunt 
152*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_disabled(ptr noundef {{%.*}}) {{#.*}} {
1531b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8
1541b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
1551b8ab2f0SOliver Hunt // CHECK-NOT:     call i64 @llvm.ptrauth.auth
1561b8ab2f0SOliver Hunt void test_disabled(ExplicitlyDisableAuth *a) {
1571b8ab2f0SOliver Hunt   a->f();
1581b8ab2f0SOliver Hunt }
1591b8ab2f0SOliver Hunt 
160*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_addr_disc(ptr noundef {{%.*}}) {{#.*}} {
1611b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8
1621b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
1631b8ab2f0SOliver Hunt //
1641b8ab2f0SOliver Hunt // NODISC:        [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
1651b8ab2f0SOliver Hunt // NODISC:        [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
1661b8ab2f0SOliver Hunt // NODISC:        [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
1671b8ab2f0SOliver Hunt //
1681b8ab2f0SOliver Hunt // TYPE:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
1691b8ab2f0SOliver Hunt // TYPE:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_ADDR]])
1701b8ab2f0SOliver Hunt // TYPE:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
1711b8ab2f0SOliver Hunt // TYPE:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
1721b8ab2f0SOliver Hunt //
1731b8ab2f0SOliver Hunt // ADDR:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
1741b8ab2f0SOliver Hunt // ADDR:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
1751b8ab2f0SOliver Hunt // ADDR:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
1761b8ab2f0SOliver Hunt //
1771b8ab2f0SOliver Hunt // BOTH:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
1781b8ab2f0SOliver Hunt // BOTH:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_ADDR]])
1791b8ab2f0SOliver Hunt // BOTH:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
1801b8ab2f0SOliver Hunt // BOTH:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
1811b8ab2f0SOliver Hunt void test_addr_disc(ExplicitAddressDiscrimination *a) {
1821b8ab2f0SOliver Hunt   a->f();
1831b8ab2f0SOliver Hunt }
1841b8ab2f0SOliver Hunt 
185*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_no_addr_disc(ptr noundef {{%.*}}) {{#.*}} {
1861b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8
1871b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
1881b8ab2f0SOliver Hunt //
1891b8ab2f0SOliver Hunt // NODISC:        [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
1901b8ab2f0SOliver Hunt // NODISC:        [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
1911b8ab2f0SOliver Hunt //
1921b8ab2f0SOliver Hunt // TYPE:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
1931b8ab2f0SOliver Hunt // TYPE:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_NO_ADDR]])
1941b8ab2f0SOliver Hunt //
1951b8ab2f0SOliver Hunt // ADDR:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
1961b8ab2f0SOliver Hunt // ADDR:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
1971b8ab2f0SOliver Hunt //
1981b8ab2f0SOliver Hunt // BOTH:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
1991b8ab2f0SOliver Hunt // BOTH:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_NO_ADDR]])
2001b8ab2f0SOliver Hunt void test_no_addr_disc(ExplicitNoAddressDiscrimination *a) {
2011b8ab2f0SOliver Hunt   a->f();
2021b8ab2f0SOliver Hunt }
2031b8ab2f0SOliver Hunt 
204*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_no_extra_disc(ptr noundef {{%.*}}) {{#.*}} {
2051b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8
2061b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
2071b8ab2f0SOliver Hunt //
2081b8ab2f0SOliver Hunt // NODISC:        [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
2091b8ab2f0SOliver Hunt // NODISC:        [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
2101b8ab2f0SOliver Hunt //
2111b8ab2f0SOliver Hunt // TYPE:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
2121b8ab2f0SOliver Hunt // TYPE:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
2131b8ab2f0SOliver Hunt //
2141b8ab2f0SOliver Hunt // ADDR:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
2151b8ab2f0SOliver Hunt // ADDR:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
2161b8ab2f0SOliver Hunt // ADDR:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
2171b8ab2f0SOliver Hunt //
2181b8ab2f0SOliver Hunt // BOTH:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
2191b8ab2f0SOliver Hunt // BOTH:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
2201b8ab2f0SOliver Hunt // BOTH:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
2211b8ab2f0SOliver Hunt void test_no_extra_disc(ExplicitNoExtraDiscrimination *a) {
2221b8ab2f0SOliver Hunt   a->f();
2231b8ab2f0SOliver Hunt }
2241b8ab2f0SOliver Hunt 
225*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_type_disc(ptr noundef {{%.*}}) {{#.*}} {
2261b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8
2271b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
2281b8ab2f0SOliver Hunt //
2291b8ab2f0SOliver Hunt // NODISC:        [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
2301b8ab2f0SOliver Hunt // NODISC:        [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_TYPE]])
2311b8ab2f0SOliver Hunt //
2321b8ab2f0SOliver Hunt // TYPE:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
2331b8ab2f0SOliver Hunt // TYPE:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_TYPE]])
2341b8ab2f0SOliver Hunt //
2351b8ab2f0SOliver Hunt // ADDR:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
2361b8ab2f0SOliver Hunt // ADDR:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_TYPE]])
2371b8ab2f0SOliver Hunt // ADDR:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
2381b8ab2f0SOliver Hunt // ADDR:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
2391b8ab2f0SOliver Hunt //
2401b8ab2f0SOliver Hunt // BOTH:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
2411b8ab2f0SOliver Hunt // BOTH:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_TYPE]])
2421b8ab2f0SOliver Hunt // BOTH:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
2431b8ab2f0SOliver Hunt // BOTH:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
2441b8ab2f0SOliver Hunt void test_type_disc(ExplicitTypeDiscrimination *a) {
2451b8ab2f0SOliver Hunt   a->f();
2461b8ab2f0SOliver Hunt }
2471b8ab2f0SOliver Hunt 
248*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_custom_disc(ptr noundef {{%.*}}) {{#.*}} {
2491b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8
2501b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
2511b8ab2f0SOliver Hunt //
2521b8ab2f0SOliver Hunt // NODISC:        [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
2531b8ab2f0SOliver Hunt // NODISC:        [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424)
2541b8ab2f0SOliver Hunt //
2551b8ab2f0SOliver Hunt // TYPE:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
2561b8ab2f0SOliver Hunt // TYPE:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424)
2571b8ab2f0SOliver Hunt //
2581b8ab2f0SOliver Hunt // ADDR:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
2591b8ab2f0SOliver Hunt // ADDR:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424)
2601b8ab2f0SOliver Hunt // ADDR:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
2611b8ab2f0SOliver Hunt // ADDR:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
2621b8ab2f0SOliver Hunt //
2631b8ab2f0SOliver Hunt // BOTH:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
2641b8ab2f0SOliver Hunt // BOTH:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424)
2651b8ab2f0SOliver Hunt // BOTH:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
2661b8ab2f0SOliver Hunt // BOTH:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
2671b8ab2f0SOliver Hunt void test_custom_disc(ExplicitCustomDiscrimination *a) {
2681b8ab2f0SOliver Hunt   a->f();
2691b8ab2f0SOliver Hunt }
2701b8ab2f0SOliver Hunt 
2711b8ab2f0SOliver Hunt //
2721b8ab2f0SOliver Hunt // Test some simple single inheritance cases.
2731b8ab2f0SOliver Hunt // Codegen should be the same as the simple cases above once we have a vtable.
2741b8ab2f0SOliver Hunt //
2751b8ab2f0SOliver Hunt 
276*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_subclass_default(ptr noundef {{%.*}}) {{#.*}} {
2771b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass
2781b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
2791b8ab2f0SOliver Hunt //
2801b8ab2f0SOliver Hunt // NODISC:        [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
2811b8ab2f0SOliver Hunt // NODISC:        [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
2821b8ab2f0SOliver Hunt //
2831b8ab2f0SOliver Hunt // TYPE:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
2841b8ab2f0SOliver Hunt // TYPE:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_DEFAULT]])
2851b8ab2f0SOliver Hunt //
2861b8ab2f0SOliver Hunt // ADDR:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
2871b8ab2f0SOliver Hunt // ADDR:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
2881b8ab2f0SOliver Hunt // ADDR:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
2891b8ab2f0SOliver Hunt //
2901b8ab2f0SOliver Hunt // BOTH:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
2911b8ab2f0SOliver Hunt // BOTH:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_DEFAULT]])
2921b8ab2f0SOliver Hunt // BOTH:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
2931b8ab2f0SOliver Hunt // BOTH:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
2941b8ab2f0SOliver Hunt void test_subclass_default(NoExplicitAuth *a) {
2951b8ab2f0SOliver Hunt   make_subclass(a)->f();
2961b8ab2f0SOliver Hunt }
2971b8ab2f0SOliver Hunt 
298*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_subclass_disabled(ptr noundef {{%.*}}) {{#.*}} {
2991b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass
3001b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
3011b8ab2f0SOliver Hunt // CHECK-NOT:     call i64 @llvm.ptrauth.auth
3021b8ab2f0SOliver Hunt void test_subclass_disabled(ExplicitlyDisableAuth *a) {
3031b8ab2f0SOliver Hunt   make_subclass(a)->f();
3041b8ab2f0SOliver Hunt }
3051b8ab2f0SOliver Hunt 
306*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_subclass_addr_disc(ptr noundef {{%.*}}) {{#.*}} {
3071b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass
3081b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
3091b8ab2f0SOliver Hunt //
3101b8ab2f0SOliver Hunt // NODISC:        [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
3111b8ab2f0SOliver Hunt // NODISC:        [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
3121b8ab2f0SOliver Hunt // NODISC:        [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
3131b8ab2f0SOliver Hunt //
3141b8ab2f0SOliver Hunt // TYPE:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
3151b8ab2f0SOliver Hunt // TYPE:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_ADDR]])
3161b8ab2f0SOliver Hunt // TYPE:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
3171b8ab2f0SOliver Hunt // TYPE:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
3181b8ab2f0SOliver Hunt //
3191b8ab2f0SOliver Hunt // ADDR:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
3201b8ab2f0SOliver Hunt // ADDR:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
3211b8ab2f0SOliver Hunt // ADDR:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
3221b8ab2f0SOliver Hunt //
3231b8ab2f0SOliver Hunt // BOTH:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
3241b8ab2f0SOliver Hunt // BOTH:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_ADDR]])
3251b8ab2f0SOliver Hunt // BOTH:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
3261b8ab2f0SOliver Hunt // BOTH:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
3271b8ab2f0SOliver Hunt void test_subclass_addr_disc(ExplicitAddressDiscrimination *a) {
3281b8ab2f0SOliver Hunt   make_subclass(a)->f();
3291b8ab2f0SOliver Hunt }
3301b8ab2f0SOliver Hunt 
331*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_subclass_no_addr_disc(ptr noundef {{%.*}}) {{#.*}} {
3321b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass
3331b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
3341b8ab2f0SOliver Hunt //
3351b8ab2f0SOliver Hunt // NODISC:        [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
3361b8ab2f0SOliver Hunt // NODISC:        [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
3371b8ab2f0SOliver Hunt //
3381b8ab2f0SOliver Hunt // TYPE:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
3391b8ab2f0SOliver Hunt // TYPE:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_NO_ADDR]])
3401b8ab2f0SOliver Hunt //
3411b8ab2f0SOliver Hunt // ADDR:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
3421b8ab2f0SOliver Hunt // ADDR:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
3431b8ab2f0SOliver Hunt //
3441b8ab2f0SOliver Hunt // BOTH:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
3451b8ab2f0SOliver Hunt // BOTH:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_NO_ADDR]])
3461b8ab2f0SOliver Hunt void test_subclass_no_addr_disc(ExplicitNoAddressDiscrimination *a) {
3471b8ab2f0SOliver Hunt   make_subclass(a)->f();
3481b8ab2f0SOliver Hunt }
3491b8ab2f0SOliver Hunt 
350*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_subclass_no_extra_disc(ptr noundef {{%.*}}) {{#.*}} {
3511b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass
3521b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
3531b8ab2f0SOliver Hunt //
3541b8ab2f0SOliver Hunt // NODISC:        [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
3551b8ab2f0SOliver Hunt // NODISC:        [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
3561b8ab2f0SOliver Hunt //
3571b8ab2f0SOliver Hunt // TYPE:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
3581b8ab2f0SOliver Hunt // TYPE:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
3591b8ab2f0SOliver Hunt //
3601b8ab2f0SOliver Hunt // ADDR:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
3611b8ab2f0SOliver Hunt // ADDR:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
3621b8ab2f0SOliver Hunt // ADDR:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
3631b8ab2f0SOliver Hunt //
3641b8ab2f0SOliver Hunt // BOTH:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
3651b8ab2f0SOliver Hunt // BOTH:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
3661b8ab2f0SOliver Hunt // BOTH:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
3671b8ab2f0SOliver Hunt void test_subclass_no_extra_disc(ExplicitNoExtraDiscrimination *a) {
3681b8ab2f0SOliver Hunt   make_subclass(a)->f();
3691b8ab2f0SOliver Hunt }
3701b8ab2f0SOliver Hunt 
371*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_subclass_type_disc(ptr noundef {{%.*}}) {{#.*}} {
3721b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass
3731b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
3741b8ab2f0SOliver Hunt //
3751b8ab2f0SOliver Hunt // NODISC:        [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
3761b8ab2f0SOliver Hunt // NODISC:        [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_TYPE]])
3771b8ab2f0SOliver Hunt //
3781b8ab2f0SOliver Hunt // TYPE:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
3791b8ab2f0SOliver Hunt // TYPE:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_TYPE]])
3801b8ab2f0SOliver Hunt //
3811b8ab2f0SOliver Hunt // ADDR:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
3821b8ab2f0SOliver Hunt // ADDR:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_TYPE]])
3831b8ab2f0SOliver Hunt // ADDR:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
3841b8ab2f0SOliver Hunt // ADDR:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
3851b8ab2f0SOliver Hunt //
3861b8ab2f0SOliver Hunt // BOTH:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
3871b8ab2f0SOliver Hunt // BOTH:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_TYPE]])
3881b8ab2f0SOliver Hunt // BOTH:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
3891b8ab2f0SOliver Hunt // BOTH:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
3901b8ab2f0SOliver Hunt void test_subclass_type_disc(ExplicitTypeDiscrimination *a) {
3911b8ab2f0SOliver Hunt   make_subclass(a)->f();
3921b8ab2f0SOliver Hunt }
3931b8ab2f0SOliver Hunt 
394*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_subclass_custom_disc(ptr noundef {{%.*}}) {{#.*}} {
3951b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass
3961b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
3971b8ab2f0SOliver Hunt //
3981b8ab2f0SOliver Hunt // NODISC:        [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
3991b8ab2f0SOliver Hunt // NODISC:        [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424)
4001b8ab2f0SOliver Hunt //
4011b8ab2f0SOliver Hunt // TYPE:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
4021b8ab2f0SOliver Hunt // TYPE:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424)
4031b8ab2f0SOliver Hunt //
4041b8ab2f0SOliver Hunt // ADDR:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
4051b8ab2f0SOliver Hunt // ADDR:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424)
4061b8ab2f0SOliver Hunt // ADDR:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
4071b8ab2f0SOliver Hunt // ADDR:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
4081b8ab2f0SOliver Hunt //
4091b8ab2f0SOliver Hunt // BOTH:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
4101b8ab2f0SOliver Hunt // BOTH:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424)
4111b8ab2f0SOliver Hunt // BOTH:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
4121b8ab2f0SOliver Hunt // BOTH:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
4131b8ab2f0SOliver Hunt void test_subclass_custom_disc(ExplicitCustomDiscrimination *a) {
4141b8ab2f0SOliver Hunt   make_subclass(a)->f();
4151b8ab2f0SOliver Hunt }
4161b8ab2f0SOliver Hunt 
4171b8ab2f0SOliver Hunt 
4181b8ab2f0SOliver Hunt //
4191b8ab2f0SOliver Hunt // Test some simple multiple inheritance cases.
4201b8ab2f0SOliver Hunt // Codegen should be the same as the simple cases above once we have a vtable.
4211b8ab2f0SOliver Hunt //
4221b8ab2f0SOliver Hunt 
423*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_multiple_default(ptr noundef {{%.*}}) {{#.*}} {
4241b8ab2f0SOliver Hunt // CHECK:         [[CALL:%.*]] = call noundef ptr @_ZN5test121make_multiple_primary
4251b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8
4261b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
4271b8ab2f0SOliver Hunt //
4281b8ab2f0SOliver Hunt // NODISC:        [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
4291b8ab2f0SOliver Hunt // NODISC:        [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
4301b8ab2f0SOliver Hunt //
4311b8ab2f0SOliver Hunt // TYPE:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
4321b8ab2f0SOliver Hunt // TYPE:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_DEFAULT]])
4331b8ab2f0SOliver Hunt //
4341b8ab2f0SOliver Hunt // ADDR:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
4351b8ab2f0SOliver Hunt // ADDR:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
4361b8ab2f0SOliver Hunt // ADDR:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
4371b8ab2f0SOliver Hunt //
4381b8ab2f0SOliver Hunt // BOTH:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
4391b8ab2f0SOliver Hunt // BOTH:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_DEFAULT]])
4401b8ab2f0SOliver Hunt // BOTH:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
4411b8ab2f0SOliver Hunt // BOTH:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
4421b8ab2f0SOliver Hunt void test_multiple_default(NoExplicitAuth *a) {
4431b8ab2f0SOliver Hunt   make_multiple_primary(a)->f();
4441b8ab2f0SOliver Hunt }
4451b8ab2f0SOliver Hunt 
446*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_multiple_disabled(ptr noundef {{%.*}}) {{#.*}} {
4471b8ab2f0SOliver Hunt // CHECK:         [[CALL:%.*]] = call noundef ptr @_ZN5test121make_multiple_primary
4481b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8
4491b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
4501b8ab2f0SOliver Hunt // CHECK-NOT:     call i64 @llvm.ptrauth.auth
4511b8ab2f0SOliver Hunt void test_multiple_disabled(ExplicitlyDisableAuth *a) {
4521b8ab2f0SOliver Hunt   make_multiple_primary(a)->f();
4531b8ab2f0SOliver Hunt }
4541b8ab2f0SOliver Hunt 
455*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_multiple_custom_disc(ptr noundef {{%.*}}) {{#.*}} {
4561b8ab2f0SOliver Hunt // CHECK:         [[CALL:%.*]] = call noundef ptr @_ZN5test121make_multiple_primary
4571b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8
4581b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
4591b8ab2f0SOliver Hunt //
4601b8ab2f0SOliver Hunt // NODISC:        [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
4611b8ab2f0SOliver Hunt // NODISC:        [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424)
4621b8ab2f0SOliver Hunt //
4631b8ab2f0SOliver Hunt // TYPE:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
4641b8ab2f0SOliver Hunt // TYPE:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424)
4651b8ab2f0SOliver Hunt //
4661b8ab2f0SOliver Hunt // ADDR:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
4671b8ab2f0SOliver Hunt // ADDR:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424)
4681b8ab2f0SOliver Hunt // ADDR:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
4691b8ab2f0SOliver Hunt // ADDR:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
4701b8ab2f0SOliver Hunt //
4711b8ab2f0SOliver Hunt // BOTH:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
4721b8ab2f0SOliver Hunt // BOTH:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424)
4731b8ab2f0SOliver Hunt // BOTH:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
4741b8ab2f0SOliver Hunt // BOTH:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
4751b8ab2f0SOliver Hunt void test_multiple_custom_disc(ExplicitCustomDiscrimination *a) {
4761b8ab2f0SOliver Hunt   make_multiple_primary(a)->f();
4771b8ab2f0SOliver Hunt }
4781b8ab2f0SOliver Hunt 
4791b8ab2f0SOliver Hunt //
4801b8ab2f0SOliver Hunt // Test some virtual inheritance cases.
4811b8ab2f0SOliver Hunt // Codegen should be the same as the simple cases above once we have a vtable,
4821b8ab2f0SOliver Hunt // but twice for vtt/vtable.  The names in the vtt version have "VTT" prefixes.
4831b8ab2f0SOliver Hunt //
4841b8ab2f0SOliver Hunt 
485*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_virtual_default(ptr noundef {{%.*}}) {{#.*}} {
4861b8ab2f0SOliver Hunt // CHECK:         [[VTTADDR:%.*]] = call noundef ptr @_ZN5test120make_virtual_primary
4871b8ab2f0SOliver Hunt // CHECK:         [[VTTABLE:%.*]] = load ptr, ptr [[VTTADDR]], align 8
4881b8ab2f0SOliver Hunt //
4891b8ab2f0SOliver Hunt // NODISC:        [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64
4901b8ab2f0SOliver Hunt // NODISC:        [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 0)
4911b8ab2f0SOliver Hunt //
4921b8ab2f0SOliver Hunt // TYPE:          [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64
4931b8ab2f0SOliver Hunt // TYPE:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[DISC_DEFAULT]])
4941b8ab2f0SOliver Hunt //
4951b8ab2f0SOliver Hunt // ADDR:          [[VTTADDRI64:%.*]] = ptrtoint ptr [[VTTADDR]] to i64
4961b8ab2f0SOliver Hunt // ADDR:          [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64
4971b8ab2f0SOliver Hunt // ADDR:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[VTTADDRI64]])
4981b8ab2f0SOliver Hunt //
4991b8ab2f0SOliver Hunt // BOTH:          [[VTTADDRI64:%.*]] = ptrtoint ptr [[VTTADDR]] to i64
5001b8ab2f0SOliver Hunt // BOTH:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTTADDRI64]], i64 [[DISC_DEFAULT]])
5011b8ab2f0SOliver Hunt // BOTH:          [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64
5021b8ab2f0SOliver Hunt // BOTH:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[BLEND]])
5031b8ab2f0SOliver Hunt 
5041b8ab2f0SOliver Hunt // CHECK:         [[AUTHEDPTR:%.*]] = inttoptr i64 [[AUTHED]] to ptr
5051b8ab2f0SOliver Hunt // CHECK:         [[VBOFFPTR:%.*]] = getelementptr i8, ptr [[AUTHEDPTR]], i64 -48
5061b8ab2f0SOliver Hunt // CHECK:         [[VBOFFSET:%.*]] = load i64, ptr [[VBOFFPTR]]
5071b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = getelementptr inbounds i8, ptr [[VTTADDR]], i64 [[VBOFFSET]]
5081b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
5091b8ab2f0SOliver Hunt //
5101b8ab2f0SOliver Hunt // NODISC:        [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
5111b8ab2f0SOliver Hunt // NODISC:        [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0)
5121b8ab2f0SOliver Hunt //
5131b8ab2f0SOliver Hunt // TYPE:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
5141b8ab2f0SOliver Hunt // TYPE:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_DEFAULT]])
5151b8ab2f0SOliver Hunt //
5161b8ab2f0SOliver Hunt // ADDR:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
5171b8ab2f0SOliver Hunt // ADDR:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
5181b8ab2f0SOliver Hunt // ADDR:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]])
5191b8ab2f0SOliver Hunt //
5201b8ab2f0SOliver Hunt // BOTH:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
5211b8ab2f0SOliver Hunt // BOTH:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_DEFAULT]])
5221b8ab2f0SOliver Hunt // BOTH:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
5231b8ab2f0SOliver Hunt // BOTH:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
5241b8ab2f0SOliver Hunt void test_virtual_default(NoExplicitAuth *a) {
5251b8ab2f0SOliver Hunt   make_virtual_primary(a)->f();
5261b8ab2f0SOliver Hunt }
5271b8ab2f0SOliver Hunt 
528*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_virtual_disabled(ptr noundef {{%.*}}) {{#.*}} {
5291b8ab2f0SOliver Hunt // CHECK-NOT:     call i64 @llvm.ptrauth.auth
5301b8ab2f0SOliver Hunt void test_virtual_disabled(ExplicitlyDisableAuth *a) {
5311b8ab2f0SOliver Hunt   make_virtual_primary(a)->f();
5321b8ab2f0SOliver Hunt }
5331b8ab2f0SOliver Hunt 
534*a1d77caaSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @test_virtual_custom_disc(ptr noundef {{%.*}}) {{#.*}} {
5351b8ab2f0SOliver Hunt // CHECK:         [[VTTADDR:%.*]] = call noundef ptr @_ZN5test120make_virtual_primary
5361b8ab2f0SOliver Hunt // CHECK:         [[VTTABLE:%.*]] = load ptr, ptr [[VTTADDR]], align 8
5371b8ab2f0SOliver Hunt //
5381b8ab2f0SOliver Hunt // NODISC:        [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64
5391b8ab2f0SOliver Hunt // NODISC:        [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 42424)
5401b8ab2f0SOliver Hunt //
5411b8ab2f0SOliver Hunt // TYPE:          [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64
5421b8ab2f0SOliver Hunt // TYPE:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 42424)
5431b8ab2f0SOliver Hunt //
5441b8ab2f0SOliver Hunt // ADDR:          [[VTTADDRI64:%.*]] = ptrtoint ptr [[VTTADDR]] to i64
5451b8ab2f0SOliver Hunt // ADDR:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTTADDRI64]], i64 42424)
5461b8ab2f0SOliver Hunt // ADDR:          [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64
5471b8ab2f0SOliver Hunt // ADDR:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[BLEND]])
5481b8ab2f0SOliver Hunt //
5491b8ab2f0SOliver Hunt // BOTH:          [[VTTADDRI64:%.*]] = ptrtoint ptr [[VTTADDR]] to i64
5501b8ab2f0SOliver Hunt // BOTH:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTTADDRI64]], i64 42424)
5511b8ab2f0SOliver Hunt // BOTH:          [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64
5521b8ab2f0SOliver Hunt // BOTH:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[BLEND]])
5531b8ab2f0SOliver Hunt 
5541b8ab2f0SOliver Hunt // CHECK:         [[AUTHEDPTR:%.*]] = inttoptr i64 [[AUTHED]] to ptr
5551b8ab2f0SOliver Hunt // CHECK:         [[VBOFFPTR:%.*]] = getelementptr i8, ptr [[AUTHEDPTR]], i64 -48
5561b8ab2f0SOliver Hunt // CHECK:         [[VBOFFSET:%.*]] = load i64, ptr [[VBOFFPTR]]
5571b8ab2f0SOliver Hunt // CHECK:         [[VTADDR:%.*]] = getelementptr inbounds i8, ptr [[VTTADDR]], i64 [[VBOFFSET]]
5581b8ab2f0SOliver Hunt // CHECK:         [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8
5591b8ab2f0SOliver Hunt //
5601b8ab2f0SOliver Hunt // NODISC:        [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
5611b8ab2f0SOliver Hunt // NODISC:        [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424)
5621b8ab2f0SOliver Hunt //
5631b8ab2f0SOliver Hunt // TYPE:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
5641b8ab2f0SOliver Hunt // TYPE:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424)
5651b8ab2f0SOliver Hunt //
5661b8ab2f0SOliver Hunt // ADDR:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
5671b8ab2f0SOliver Hunt // ADDR:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424)
5681b8ab2f0SOliver Hunt // ADDR:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
5691b8ab2f0SOliver Hunt // ADDR:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
5701b8ab2f0SOliver Hunt //
5711b8ab2f0SOliver Hunt // BOTH:          [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64
5721b8ab2f0SOliver Hunt // BOTH:          [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424)
5731b8ab2f0SOliver Hunt // BOTH:          [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64
5741b8ab2f0SOliver Hunt // BOTH:          [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]])
5751b8ab2f0SOliver Hunt void test_virtual_custom_disc(ExplicitCustomDiscrimination *a) {
5761b8ab2f0SOliver Hunt   make_virtual_primary(a)->f();
5771b8ab2f0SOliver Hunt }
5781b8ab2f0SOliver Hunt 
5791b8ab2f0SOliver Hunt } // extern "C"
5801b8ab2f0SOliver Hunt } // namespace test1
581