| // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \ |
| // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,NODISC %s |
| |
| // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \ |
| // RUN: -fptrauth-vtable-pointer-type-discrimination \ |
| // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,TYPE %s |
| |
| // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \ |
| // RUN: -fptrauth-vtable-pointer-address-discrimination \ |
| // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,ADDR %s |
| |
| // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \ |
| // RUN: -fptrauth-vtable-pointer-type-discrimination \ |
| // RUN: -fptrauth-vtable-pointer-address-discrimination \ |
| // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,BOTH %s |
| |
| // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \ |
| // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,NODISC %s |
| |
| // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \ |
| // RUN: -fptrauth-vtable-pointer-type-discrimination \ |
| // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,TYPE %s |
| |
| // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \ |
| // RUN: -fptrauth-vtable-pointer-address-discrimination \ |
| // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,ADDR %s |
| |
| // RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \ |
| // RUN: -fptrauth-vtable-pointer-type-discrimination \ |
| // RUN: -fptrauth-vtable-pointer-address-discrimination \ |
| // RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,BOTH %s |
| |
| #include <ptrauth.h> |
| |
| namespace test1 { |
| |
| #define authenticated(a...) ptrauth_cxx_vtable_pointer(a) |
| |
| struct NoExplicitAuth { |
| virtual ~NoExplicitAuth(); |
| virtual void f(); |
| virtual void g(); |
| }; |
| |
| struct authenticated(no_authentication, no_address_discrimination, no_extra_discrimination) ExplicitlyDisableAuth { |
| virtual ~ExplicitlyDisableAuth(); |
| virtual void f(); |
| virtual void g(); |
| }; |
| |
| struct authenticated(default_key, address_discrimination, default_extra_discrimination) ExplicitAddressDiscrimination { |
| virtual ~ExplicitAddressDiscrimination(); |
| virtual void f(); |
| virtual void g(); |
| }; |
| |
| struct authenticated(default_key, no_address_discrimination, default_extra_discrimination) ExplicitNoAddressDiscrimination { |
| virtual ~ExplicitNoAddressDiscrimination(); |
| virtual void f(); |
| virtual void g(); |
| }; |
| |
| struct authenticated(default_key, default_address_discrimination, no_extra_discrimination) ExplicitNoExtraDiscrimination { |
| virtual ~ExplicitNoExtraDiscrimination(); |
| virtual void f(); |
| virtual void g(); |
| }; |
| |
| struct authenticated(default_key, default_address_discrimination, type_discrimination) ExplicitTypeDiscrimination { |
| virtual ~ExplicitTypeDiscrimination(); |
| virtual void f(); |
| virtual void g(); |
| }; |
| |
| struct authenticated(default_key, default_address_discrimination, custom_discrimination, 42424) ExplicitCustomDiscrimination { |
| virtual ~ExplicitCustomDiscrimination(); |
| virtual void f(); |
| virtual void g(); |
| }; |
| |
| template <typename T> |
| struct SubClass : T { |
| virtual void g(); |
| virtual T *h(); |
| }; |
| |
| template <typename T> |
| SubClass<T> *make_subclass(T *); |
| |
| struct authenticated(default_key, address_discrimination, type_discrimination) BasicStruct { |
| virtual ~BasicStruct(); |
| }; |
| |
| template <typename T> |
| struct PrimaryBasicStruct : BasicStruct, T {}; |
| template <typename T> |
| struct PrimaryBasicStruct<T> *make_multiple_primary(T *); |
| |
| template <typename T> |
| struct VirtualSubClass : virtual T { |
| virtual void g(); |
| virtual T *h(); |
| }; |
| template <typename T> |
| struct VirtualPrimaryStruct : virtual T, VirtualSubClass<T> {}; |
| template <typename T> |
| struct VirtualPrimaryStruct<T> *make_virtual_primary(T *); |
| |
| extern "C" { |
| |
| // CHECK: @TVDisc_NoExplicitAuth = global i32 [[DISC_DEFAULT:49565]], align 4 |
| int TVDisc_NoExplicitAuth = ptrauth_string_discriminator("_ZTVN5test114NoExplicitAuthE"); |
| |
| // CHECK: @TVDisc_ExplicitlyDisableAuth = global i32 [[DISC_DISABLED:24369]], align 4 |
| int TVDisc_ExplicitlyDisableAuth = ptrauth_string_discriminator("_ZTVN5test121ExplicitlyDisableAuthE"); |
| |
| // CHECK: @TVDisc_ExplicitAddressDiscrimination = global i32 [[DISC_ADDR:56943]], align 4 |
| int TVDisc_ExplicitAddressDiscrimination = ptrauth_string_discriminator("_ZTVN5test129ExplicitAddressDiscriminationE"); |
| |
| // CHECK: @TVDisc_ExplicitNoAddressDiscrimination = global i32 [[DISC_NO_ADDR:6022]], align 4 |
| int TVDisc_ExplicitNoAddressDiscrimination = ptrauth_string_discriminator("_ZTVN5test131ExplicitNoAddressDiscriminationE"); |
| |
| // CHECK: @TVDisc_ExplicitNoExtraDiscrimination = global i32 [[DISC_NO_EXTRA:9072]], align 4 |
| int TVDisc_ExplicitNoExtraDiscrimination = ptrauth_string_discriminator("_ZTVN5test129ExplicitNoExtraDiscriminationE"); |
| |
| // CHECK: @TVDisc_ExplicitTypeDiscrimination = global i32 [[DISC_TYPE:6177]], align 4 |
| int TVDisc_ExplicitTypeDiscrimination = ptrauth_string_discriminator("_ZTVN5test126ExplicitTypeDiscriminationE"); |
| |
| |
| // CHECK-LABEL: define{{.*}} void @test_default(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8 |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // |
| // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) |
| // |
| // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_DEFAULT]]) |
| // |
| // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) |
| // |
| // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_DEFAULT]]) |
| // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| void test_default(NoExplicitAuth *a) { |
| a->f(); |
| } |
| |
| // CHECK-LABEL: define{{.*}} void @test_disabled(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8 |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // CHECK-NOT: call i64 @llvm.ptrauth.auth |
| void test_disabled(ExplicitlyDisableAuth *a) { |
| a->f(); |
| } |
| |
| // CHECK-LABEL: define{{.*}} void @test_addr_disc(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8 |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // |
| // NODISC: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) |
| // |
| // TYPE: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // TYPE: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_ADDR]]) |
| // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| // |
| // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) |
| // |
| // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_ADDR]]) |
| // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| void test_addr_disc(ExplicitAddressDiscrimination *a) { |
| a->f(); |
| } |
| |
| // CHECK-LABEL: define{{.*}} void @test_no_addr_disc(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8 |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // |
| // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) |
| // |
| // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_NO_ADDR]]) |
| // |
| // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) |
| // |
| // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_NO_ADDR]]) |
| void test_no_addr_disc(ExplicitNoAddressDiscrimination *a) { |
| a->f(); |
| } |
| |
| // CHECK-LABEL: define{{.*}} void @test_no_extra_disc(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8 |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // |
| // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) |
| // |
| // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) |
| // |
| // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) |
| // |
| // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) |
| void test_no_extra_disc(ExplicitNoExtraDiscrimination *a) { |
| a->f(); |
| } |
| |
| // CHECK-LABEL: define{{.*}} void @test_type_disc(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8 |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // |
| // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_TYPE]]) |
| // |
| // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_TYPE]]) |
| // |
| // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_TYPE]]) |
| // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| // |
| // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_TYPE]]) |
| // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| void test_type_disc(ExplicitTypeDiscrimination *a) { |
| a->f(); |
| } |
| |
| // CHECK-LABEL: define{{.*}} void @test_custom_disc(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[VTADDR:%.*]] = load ptr, ptr {{%.*}}, align 8 |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // |
| // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424) |
| // |
| // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424) |
| // |
| // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424) |
| // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| // |
| // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424) |
| // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| void test_custom_disc(ExplicitCustomDiscrimination *a) { |
| a->f(); |
| } |
| |
| // |
| // Test some simple single inheritance cases. |
| // Codegen should be the same as the simple cases above once we have a vtable. |
| // |
| |
| // CHECK-LABEL: define{{.*}} void @test_subclass_default(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // |
| // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) |
| // |
| // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_DEFAULT]]) |
| // |
| // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) |
| // |
| // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_DEFAULT]]) |
| // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| void test_subclass_default(NoExplicitAuth *a) { |
| make_subclass(a)->f(); |
| } |
| |
| // CHECK-LABEL: define{{.*}} void @test_subclass_disabled(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // CHECK-NOT: call i64 @llvm.ptrauth.auth |
| void test_subclass_disabled(ExplicitlyDisableAuth *a) { |
| make_subclass(a)->f(); |
| } |
| |
| // CHECK-LABEL: define{{.*}} void @test_subclass_addr_disc(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // |
| // NODISC: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) |
| // |
| // TYPE: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // TYPE: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_ADDR]]) |
| // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| // |
| // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) |
| // |
| // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_ADDR]]) |
| // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| void test_subclass_addr_disc(ExplicitAddressDiscrimination *a) { |
| make_subclass(a)->f(); |
| } |
| |
| // CHECK-LABEL: define{{.*}} void @test_subclass_no_addr_disc(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // |
| // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) |
| // |
| // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_NO_ADDR]]) |
| // |
| // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) |
| // |
| // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_NO_ADDR]]) |
| void test_subclass_no_addr_disc(ExplicitNoAddressDiscrimination *a) { |
| make_subclass(a)->f(); |
| } |
| |
| // CHECK-LABEL: define{{.*}} void @test_subclass_no_extra_disc(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // |
| // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) |
| // |
| // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) |
| // |
| // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) |
| // |
| // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) |
| void test_subclass_no_extra_disc(ExplicitNoExtraDiscrimination *a) { |
| make_subclass(a)->f(); |
| } |
| |
| // CHECK-LABEL: define{{.*}} void @test_subclass_type_disc(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // |
| // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_TYPE]]) |
| // |
| // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_TYPE]]) |
| // |
| // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_TYPE]]) |
| // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| // |
| // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_TYPE]]) |
| // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| void test_subclass_type_disc(ExplicitTypeDiscrimination *a) { |
| make_subclass(a)->f(); |
| } |
| |
| // CHECK-LABEL: define{{.*}} void @test_subclass_custom_disc(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[VTADDR:%.*]] = call noundef ptr @_ZN5test113make_subclass |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // |
| // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424) |
| // |
| // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424) |
| // |
| // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424) |
| // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| // |
| // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424) |
| // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| void test_subclass_custom_disc(ExplicitCustomDiscrimination *a) { |
| make_subclass(a)->f(); |
| } |
| |
| |
| // |
| // Test some simple multiple inheritance cases. |
| // Codegen should be the same as the simple cases above once we have a vtable. |
| // |
| |
| // CHECK-LABEL: define{{.*}} void @test_multiple_default(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[CALL:%.*]] = call noundef ptr @_ZN5test121make_multiple_primary |
| // CHECK: [[VTADDR:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8 |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // |
| // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) |
| // |
| // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_DEFAULT]]) |
| // |
| // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) |
| // |
| // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_DEFAULT]]) |
| // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| void test_multiple_default(NoExplicitAuth *a) { |
| make_multiple_primary(a)->f(); |
| } |
| |
| // CHECK-LABEL: define{{.*}} void @test_multiple_disabled(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[CALL:%.*]] = call noundef ptr @_ZN5test121make_multiple_primary |
| // CHECK: [[VTADDR:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8 |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // CHECK-NOT: call i64 @llvm.ptrauth.auth |
| void test_multiple_disabled(ExplicitlyDisableAuth *a) { |
| make_multiple_primary(a)->f(); |
| } |
| |
| // CHECK-LABEL: define{{.*}} void @test_multiple_custom_disc(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[CALL:%.*]] = call noundef ptr @_ZN5test121make_multiple_primary |
| // CHECK: [[VTADDR:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8 |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // |
| // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424) |
| // |
| // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424) |
| // |
| // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424) |
| // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| // |
| // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424) |
| // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| void test_multiple_custom_disc(ExplicitCustomDiscrimination *a) { |
| make_multiple_primary(a)->f(); |
| } |
| |
| // |
| // Test some virtual inheritance cases. |
| // Codegen should be the same as the simple cases above once we have a vtable, |
| // but twice for vtt/vtable. The names in the vtt version have "VTT" prefixes. |
| // |
| |
| // CHECK-LABEL: define{{.*}} void @test_virtual_default(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[VTTADDR:%.*]] = call noundef ptr @_ZN5test120make_virtual_primary |
| // CHECK: [[VTTABLE:%.*]] = load ptr, ptr [[VTTADDR]], align 8 |
| // |
| // NODISC: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64 |
| // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 0) |
| // |
| // TYPE: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64 |
| // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[DISC_DEFAULT]]) |
| // |
| // ADDR: [[VTTADDRI64:%.*]] = ptrtoint ptr [[VTTADDR]] to i64 |
| // ADDR: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64 |
| // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[VTTADDRI64]]) |
| // |
| // BOTH: [[VTTADDRI64:%.*]] = ptrtoint ptr [[VTTADDR]] to i64 |
| // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTTADDRI64]], i64 [[DISC_DEFAULT]]) |
| // BOTH: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64 |
| // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[BLEND]]) |
| |
| // CHECK: [[AUTHEDPTR:%.*]] = inttoptr i64 [[AUTHED]] to ptr |
| // CHECK: [[VBOFFPTR:%.*]] = getelementptr i8, ptr [[AUTHEDPTR]], i64 -48 |
| // CHECK: [[VBOFFSET:%.*]] = load i64, ptr [[VBOFFPTR]] |
| // CHECK: [[VTADDR:%.*]] = getelementptr inbounds i8, ptr [[VTTADDR]], i64 [[VBOFFSET]] |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // |
| // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) |
| // |
| // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_DEFAULT]]) |
| // |
| // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) |
| // |
| // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_DEFAULT]]) |
| // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| void test_virtual_default(NoExplicitAuth *a) { |
| make_virtual_primary(a)->f(); |
| } |
| |
| // CHECK-LABEL: define{{.*}} void @test_virtual_disabled(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK-NOT: call i64 @llvm.ptrauth.auth |
| void test_virtual_disabled(ExplicitlyDisableAuth *a) { |
| make_virtual_primary(a)->f(); |
| } |
| |
| // CHECK-LABEL: define{{.*}} void @test_virtual_custom_disc(ptr noundef {{%.*}}) {{#.*}} { |
| // CHECK: [[VTTADDR:%.*]] = call noundef ptr @_ZN5test120make_virtual_primary |
| // CHECK: [[VTTABLE:%.*]] = load ptr, ptr [[VTTADDR]], align 8 |
| // |
| // NODISC: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64 |
| // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 42424) |
| // |
| // TYPE: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64 |
| // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 42424) |
| // |
| // ADDR: [[VTTADDRI64:%.*]] = ptrtoint ptr [[VTTADDR]] to i64 |
| // ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTTADDRI64]], i64 42424) |
| // ADDR: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64 |
| // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[BLEND]]) |
| // |
| // BOTH: [[VTTADDRI64:%.*]] = ptrtoint ptr [[VTTADDR]] to i64 |
| // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTTADDRI64]], i64 42424) |
| // BOTH: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64 |
| // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[BLEND]]) |
| |
| // CHECK: [[AUTHEDPTR:%.*]] = inttoptr i64 [[AUTHED]] to ptr |
| // CHECK: [[VBOFFPTR:%.*]] = getelementptr i8, ptr [[AUTHEDPTR]], i64 -48 |
| // CHECK: [[VBOFFSET:%.*]] = load i64, ptr [[VBOFFPTR]] |
| // CHECK: [[VTADDR:%.*]] = getelementptr inbounds i8, ptr [[VTTADDR]], i64 [[VBOFFSET]] |
| // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 |
| // |
| // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424) |
| // |
| // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424) |
| // |
| // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424) |
| // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| // |
| // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 |
| // BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424) |
| // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
| // BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) |
| void test_virtual_custom_disc(ExplicitCustomDiscrimination *a) { |
| make_virtual_primary(a)->f(); |
| } |
| |
| } // extern "C" |
| } // namespace test1 |