170c6e79eSDaniil Kovalev // RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -o - %s | FileCheck -check-prefixes=CHECK,NODEBUG,DARWIN %s 2*485c80e1SAkira Hatanaka // RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++17 -O1 -disable-llvm-passes -o - %s | FileCheck -check-prefixes=CHECK,NODEBUG,DARWIN,CXX17 %s 370c6e79eSDaniil Kovalev // RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -debug-info-kind=limited -o - %s | FileCheck -check-prefixes=CHECK,DARWIN %s 44dcd91aeSOliver Hunt // RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 1 -o - %s | FileCheck %s -check-prefix=STACK-PROT 54dcd91aeSOliver Hunt // RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 2 -o - %s | FileCheck %s -check-prefix=STACK-PROT 64dcd91aeSOliver Hunt // RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 3 -o - %s | FileCheck %s -check-prefix=STACK-PROT 74dcd91aeSOliver Hunt 870c6e79eSDaniil Kovalev // RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -o - %s | FileCheck -check-prefixes=CHECK,NODEBUG,ELF %s 9*485c80e1SAkira Hatanaka // RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++17 -O1 -disable-llvm-passes -o - %s | FileCheck -check-prefixes=CHECK,NODEBUG,ELF,CXX17 %s 1070c6e79eSDaniil Kovalev // RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -debug-info-kind=limited -o - %s | FileCheck -check-prefixes=CHECK,ELF %s 1170c6e79eSDaniil Kovalev // RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 1 -o - %s | FileCheck %s -check-prefix=STACK-PROT 1270c6e79eSDaniil Kovalev // RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 2 -o - %s | FileCheck %s -check-prefix=STACK-PROT 1370c6e79eSDaniil Kovalev // RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 3 -o - %s | FileCheck %s -check-prefix=STACK-PROT 1470c6e79eSDaniil Kovalev 154dcd91aeSOliver Hunt 164dcd91aeSOliver Hunt // CHECK: @gmethod0 = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 [[TYPEDISC1:35591]]) to i64), i64 0 }, align 8 174dcd91aeSOliver Hunt // CHECK: @gmethod1 = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived011nonvirtual5Ev, i32 0, i64 [[TYPEDISC0:22163]]) to i64), i64 0 }, align 8 184dcd91aeSOliver Hunt // CHECK: @gmethod2 = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 [[TYPEDISC0]]) to i64), i64 0 }, align 8 194dcd91aeSOliver Hunt 204dcd91aeSOliver Hunt // CHECK: @__const._Z13testArrayInitv.p0 = private unnamed_addr constant [1 x { i64, i64 }] [{ i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 35591) to i64), i64 0 }], align 8 214dcd91aeSOliver Hunt // CHECK: @__const._Z13testArrayInitv.p1 = private unnamed_addr constant [1 x { i64, i64 }] [{ i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 35591) to i64), i64 0 }], align 8 224dcd91aeSOliver Hunt // CHECK: @__const._Z13testArrayInitv.c0 = private unnamed_addr constant %struct.Class0 { { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 35591) to i64), i64 0 } }, align 8 234dcd91aeSOliver Hunt // CHECK: @__const._Z13testArrayInitv.c1 = private unnamed_addr constant %struct.Class0 { { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 35591) to i64), i64 0 } }, align 8 244dcd91aeSOliver Hunt 25*485c80e1SAkira Hatanaka // CHECK: @_ZN22testNoexceptConversion6mfptr1E = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S19nonvirtual_noexceptEv, i32 0, i64 [[TYPEDISC3:.*]]) to i64), i64 0 }, 26*485c80e1SAkira Hatanaka // CHECK: @_ZN22testNoexceptConversion6mfptr2E = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S16virtual_noexceptEv_vfpthunk_, i32 0, i64 [[TYPEDISC3]]) to i64), i64 0 }, 27*485c80e1SAkira Hatanaka // CHECK: @_ZN22testNoexceptConversion15mfptr3_noexceptE = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S19nonvirtual_noexceptEv, i32 0, i64 [[TYPEDISC3]]) to i64), i64 0 }, 28*485c80e1SAkira Hatanaka 294dcd91aeSOliver Hunt // CHECK: @_ZTV5Base0 = unnamed_addr constant { [5 x ptr] } { [5 x ptr] [ptr null, ptr @_ZTI5Base0, 304dcd91aeSOliver Hunt // CHECK-SAME: ptr ptrauth (ptr @_ZN5Base08virtual1Ev, i32 0, i64 55600, ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV5Base0, i32 0, i32 0, i32 2)), 314dcd91aeSOliver Hunt // CHECK-SAME: ptr ptrauth (ptr @_ZN5Base08virtual3Ev, i32 0, i64 53007, ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV5Base0, i32 0, i32 0, i32 3)), 324dcd91aeSOliver Hunt // CHECK-SAME: ptr ptrauth (ptr @_ZN5Base016virtual_variadicEiz, i32 0, i64 7464, ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV5Base0, i32 0, i32 0, i32 4))] }, align 8 334dcd91aeSOliver Hunt 344dcd91aeSOliver Hunt typedef __SIZE_TYPE__ size_t; 354dcd91aeSOliver Hunt 364dcd91aeSOliver Hunt namespace std { 374dcd91aeSOliver Hunt template <typename _Ep> 384dcd91aeSOliver Hunt class initializer_list { 394dcd91aeSOliver Hunt const _Ep *__begin_; 404dcd91aeSOliver Hunt size_t __size_; 414dcd91aeSOliver Hunt 424dcd91aeSOliver Hunt initializer_list(const _Ep *__b, size_t __s); 434dcd91aeSOliver Hunt }; 444dcd91aeSOliver Hunt } // namespace std 454dcd91aeSOliver Hunt 464dcd91aeSOliver Hunt struct Base0 { 474dcd91aeSOliver Hunt void nonvirtual0(); 484dcd91aeSOliver Hunt virtual void virtual1(); 494dcd91aeSOliver Hunt virtual void virtual3(); 504dcd91aeSOliver Hunt virtual void virtual_variadic(int, ...); 514dcd91aeSOliver Hunt }; 524dcd91aeSOliver Hunt 534dcd91aeSOliver Hunt struct A0 { 544dcd91aeSOliver Hunt int d[4]; 554dcd91aeSOliver Hunt }; 564dcd91aeSOliver Hunt 574dcd91aeSOliver Hunt struct A1 { 584dcd91aeSOliver Hunt int d[8]; 594dcd91aeSOliver Hunt }; 604dcd91aeSOliver Hunt 614dcd91aeSOliver Hunt struct __attribute__((trivial_abi)) TrivialS { 624dcd91aeSOliver Hunt TrivialS(const TrivialS &); 634dcd91aeSOliver Hunt ~TrivialS(); 644dcd91aeSOliver Hunt int p[4]; 654dcd91aeSOliver Hunt }; 664dcd91aeSOliver Hunt 674dcd91aeSOliver Hunt struct Derived0 : Base0 { 684dcd91aeSOliver Hunt void virtual1() override; 694dcd91aeSOliver Hunt void nonvirtual5(); 704dcd91aeSOliver Hunt virtual void virtual6(); 714dcd91aeSOliver Hunt virtual A0 return_agg(); 724dcd91aeSOliver Hunt virtual A1 sret(); 734dcd91aeSOliver Hunt virtual void trivial_abi(TrivialS); 744dcd91aeSOliver Hunt }; 754dcd91aeSOliver Hunt 764dcd91aeSOliver Hunt struct Base1 { 774dcd91aeSOliver Hunt virtual void virtual7(); 784dcd91aeSOliver Hunt }; 794dcd91aeSOliver Hunt 804dcd91aeSOliver Hunt struct Derived1 : Base0, Base1 { 814dcd91aeSOliver Hunt void virtual1() override; 824dcd91aeSOliver Hunt void virtual7() override; 834dcd91aeSOliver Hunt }; 844dcd91aeSOliver Hunt 854dcd91aeSOliver Hunt typedef void (Base0::*MethodTy0)(); 86*485c80e1SAkira Hatanaka #if __cplusplus >= 201703L 87*485c80e1SAkira Hatanaka typedef void (Base0::*NoExceptMethodTy0)() noexcept; 88*485c80e1SAkira Hatanaka #endif 894dcd91aeSOliver Hunt typedef void (Base0::*VariadicMethodTy0)(int, ...); 904dcd91aeSOliver Hunt typedef void (Derived0::*MethodTy1)(); 914dcd91aeSOliver Hunt 924dcd91aeSOliver Hunt struct Class0 { 934dcd91aeSOliver Hunt MethodTy1 m0; 944dcd91aeSOliver Hunt }; 954dcd91aeSOliver Hunt 9670c6e79eSDaniil Kovalev // CHECK: define{{.*}} void @_ZN5Base08virtual1Ev( 974dcd91aeSOliver Hunt 9870c6e79eSDaniil Kovalev // CHECK: define{{.*}} void @_Z5test0v() 994dcd91aeSOliver Hunt // CHECK: %[[METHOD0:.*]] = alloca { i64, i64 }, align 8 1004dcd91aeSOliver Hunt // CHECK-NEXT: %[[VARMETHOD1:.*]] = alloca { i64, i64 }, align 8 1014dcd91aeSOliver Hunt // CHECK-NEXT: %[[METHOD2:.*]] = alloca { i64, i64 }, align 8 1024dcd91aeSOliver Hunt // CHECK-NEXT: %[[METHOD3:.*]] = alloca { i64, i64 }, align 8 1034dcd91aeSOliver Hunt // CHECK-NEXT: %[[METHOD4:.*]] = alloca { i64, i64 }, align 8 1044dcd91aeSOliver Hunt // CHECK-NEXT: %[[METHOD5:.*]] = alloca { i64, i64 }, align 8 1054dcd91aeSOliver Hunt // CHECK-NEXT: %[[METHOD6:.*]] = alloca { i64, i64 }, align 8 1064dcd91aeSOliver Hunt // CHECK-NEXT: %[[METHOD7:.*]] = alloca { i64, i64 }, align 8 1074dcd91aeSOliver Hunt // CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 [[TYPEDISC0]]) to i64), i64 0 }, ptr %[[METHOD0]], align 8 1084dcd91aeSOliver Hunt // CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 [[TYPEDISC0]]) to i64), i64 0 }, ptr %[[METHOD0]], align 8 1094dcd91aeSOliver Hunt // CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual3Ev_vfpthunk_, i32 0, i64 [[TYPEDISC0]]) to i64), i64 0 }, ptr %[[METHOD0]], align 8 1104dcd91aeSOliver Hunt // CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base016virtual_variadicEiz_vfpthunk_, i32 0, i64 34368) to i64), i64 0 }, ptr %[[VARMETHOD1]], align 8 1114dcd91aeSOliver Hunt // CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 1124dcd91aeSOliver Hunt // CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 1134dcd91aeSOliver Hunt // CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual3Ev_vfpthunk_, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 1144dcd91aeSOliver Hunt // CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived011nonvirtual5Ev, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 1154dcd91aeSOliver Hunt // CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived08virtual6Ev_vfpthunk_, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 1164dcd91aeSOliver Hunt // CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived010return_aggEv_vfpthunk_, i32 0, i64 64418) to i64), i64 0 }, ptr %[[METHOD3]], align 8 1174dcd91aeSOliver Hunt // CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived04sretEv_vfpthunk_, i32 0, i64 28187) to i64), i64 0 }, ptr %[[METHOD4]], align 8 1184dcd91aeSOliver Hunt // CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived011trivial_abiE8TrivialS_vfpthunk_, i32 0, i64 8992) to i64), i64 0 }, ptr %[[METHOD5]], align 8 1194dcd91aeSOliver Hunt // CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base18virtual7Ev_vfpthunk_, i32 0, i64 [[TYPEDISC2:61596]]) to i64), i64 0 }, ptr %[[METHOD6]], align 8 1204dcd91aeSOliver Hunt // CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived18virtual7Ev_vfpthunk_, i32 0, i64 25206) to i64), i64 0 }, ptr %[[METHOD7]], align 8 1214dcd91aeSOliver Hunt // CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 25206) to i64), i64 0 }, ptr %[[METHOD7]], align 8 1224dcd91aeSOliver Hunt // CHECK: ret void 1234dcd91aeSOliver Hunt 1244dcd91aeSOliver Hunt // CHECK: define linkonce_odr hidden void @_ZN5Base08virtual1Ev_vfpthunk_(ptr noundef %[[THIS:.*]]) 1254dcd91aeSOliver Hunt // CHECK: %[[THIS_ADDR:.*]] = alloca ptr, align 8 1264dcd91aeSOliver Hunt // CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]], align 8 1274dcd91aeSOliver Hunt // CHECK: %[[THIS1:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 1284dcd91aeSOliver Hunt // CHECK-NEXT: %[[V0:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 1294dcd91aeSOliver Hunt // CHECK-NEXT: %[[VTABLE:.*]] = load ptr, ptr %[[THIS1]], align 8 1304dcd91aeSOliver Hunt // CHECK-NEXT: %[[V2:.*]] = ptrtoint ptr %[[VTABLE]] to i64 1314dcd91aeSOliver Hunt // CHECK-NEXT: %[[V3:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V2]], i32 2, i64 0) 1324dcd91aeSOliver Hunt // CHECK-NEXT: %[[V4:.*]] = inttoptr i64 %[[V3]] to ptr 1334dcd91aeSOliver Hunt // CHECK-NEXT: %[[VFN:.*]] = getelementptr inbounds ptr, ptr %[[V4]], i64 0 1344dcd91aeSOliver Hunt // CHECK-NEXT: %[[V5:.*]] = load ptr, ptr %[[VFN]], align 8 1354dcd91aeSOliver Hunt // CHECK-NEXT: %[[V6:.*]] = ptrtoint ptr %[[VFN]] to i64 1364dcd91aeSOliver Hunt // CHECK-NEXT: %[[V7:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V6]], i64 55600) 1374dcd91aeSOliver Hunt // CHECK-NEXT: musttail call void %[[V5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %[[V0]]) [ "ptrauth"(i32 0, i64 %[[V7]]) ] 1384dcd91aeSOliver Hunt // CHECK-NEXT: ret void 1394dcd91aeSOliver Hunt 1404dcd91aeSOliver Hunt // CHECK: define linkonce_odr hidden void @_ZN5Base08virtual3Ev_vfpthunk_(ptr noundef %{{.*}}) 1414dcd91aeSOliver Hunt // CHECK: load ptr, ptr %{{.*}}, align 8 1424dcd91aeSOliver Hunt // CHECK: load ptr, ptr %{{.*}}, align 8 1434dcd91aeSOliver Hunt // CHECK: %[[VTABLE:.*]] = load ptr, ptr %{{.*}}, align 8 1444dcd91aeSOliver Hunt // CHECK: %[[V2:.*]] = ptrtoint ptr %[[VTABLE]] to i64 1454dcd91aeSOliver Hunt // CHECK: %[[V3:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V2]], i32 2, i64 0) 1464dcd91aeSOliver Hunt // CHECK: %[[V4:.*]] = inttoptr i64 %[[V3]] to ptr 1474dcd91aeSOliver Hunt // CHECK: getelementptr inbounds ptr, ptr %[[V4]], i64 1 1484dcd91aeSOliver Hunt // CHECK: call i64 @llvm.ptrauth.blend(i64 %{{.*}}, i64 53007) 1494dcd91aeSOliver Hunt 1504dcd91aeSOliver Hunt // CHECK: define linkonce_odr hidden void @_ZN5Base016virtual_variadicEiz_vfpthunk_(ptr noundef %[[THIS:.*]], i32 noundef %0, ...) 1514dcd91aeSOliver Hunt // CHECK: %[[THIS_ADDR:.*]] = alloca ptr, align 8 1524dcd91aeSOliver Hunt // CHECK-NEXT: %[[_ADDR:.*]] = alloca i32, align 4 1534dcd91aeSOliver Hunt // CHECK-NEXT: store ptr %[[THIS]], ptr %[[THIS_ADDR]], align 8 1544dcd91aeSOliver Hunt // CHECK: store i32 %0, ptr %[[_ADDR]], align 4 1554dcd91aeSOliver Hunt // CHECK: %[[THIS1:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 1564dcd91aeSOliver Hunt // CHECK-NEXT: %[[V1:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 1574dcd91aeSOliver Hunt // CHECK-NEXT: %[[V2:.*]] = load i32, ptr %[[_ADDR]], align 4 1584dcd91aeSOliver Hunt // CHECK-NEXT: %[[VTABLE:.*]] = load ptr, ptr %[[THIS1]], align 8 1594dcd91aeSOliver Hunt // CHECK-NEXT: %[[V4:.*]] = ptrtoint ptr %[[VTABLE]] to i64 1604dcd91aeSOliver Hunt // CHECK-NEXT: %[[V5:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V4]], i32 2, i64 0) 1614dcd91aeSOliver Hunt // CHECK-NEXT: %[[V6:.*]] = inttoptr i64 %[[V5]] to ptr 1624dcd91aeSOliver Hunt // CHECK-NEXT: %[[VFN:.*]] = getelementptr inbounds ptr, ptr %[[V6]], i64 2 1634dcd91aeSOliver Hunt // CHECK-NEXT: %[[V7:.*]] = load ptr, ptr %[[VFN]], align 8 1644dcd91aeSOliver Hunt // CHECK-NEXT: %[[V8:.*]] = ptrtoint ptr %[[VFN]] to i64 1654dcd91aeSOliver Hunt // CHECK-NEXT: %[[V9:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V8]], i64 7464) 1664dcd91aeSOliver Hunt // CHECK-NEXT: musttail call void (ptr, i32, ...) %[[V7]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %[[V1]], i32 noundef %[[V2]], ...) [ "ptrauth"(i32 0, i64 %[[V9]]) ] 1674dcd91aeSOliver Hunt // CHECK-NEXT: ret void 1684dcd91aeSOliver Hunt 1694dcd91aeSOliver Hunt // CHECK: define linkonce_odr hidden void @_ZN8Derived08virtual6Ev_vfpthunk_(ptr noundef %[[THIS:.*]]) 1704dcd91aeSOliver Hunt // CHECK: %[[THIS_ADDR:.*]] = alloca ptr, align 8 1714dcd91aeSOliver Hunt // CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]], align 8 1724dcd91aeSOliver Hunt // CHECK: %[[THIS1:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 1734dcd91aeSOliver Hunt // CHECK: %[[V0:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 1744dcd91aeSOliver Hunt // CHECK: %[[VTABLE:.*]] = load ptr, ptr %[[THIS1]], align 8 1754dcd91aeSOliver Hunt // CHECK: %[[V1:.*]] = ptrtoint ptr %[[VTABLE]] to i64 1764dcd91aeSOliver Hunt // CHECK: %[[V2:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V1]], i32 2, i64 0) 1774dcd91aeSOliver Hunt // CHECK: %[[V3:.*]] = inttoptr i64 %[[V2]] to ptr 1784dcd91aeSOliver Hunt // CHECK: %[[VFN:.*]] = getelementptr inbounds ptr, ptr %[[V3]], i64 3 1794dcd91aeSOliver Hunt // CHECK: %[[V5:.*]] = ptrtoint ptr %[[VFN]] to i64 1804dcd91aeSOliver Hunt // CHECK: call i64 @llvm.ptrauth.blend(i64 %[[V5]], i64 55535) 1814dcd91aeSOliver Hunt 1824dcd91aeSOliver Hunt // Check that the return value of the musttail call isn't copied to a temporary. 1834dcd91aeSOliver Hunt 1844dcd91aeSOliver Hunt // CHECK: define linkonce_odr hidden [2 x i64] @_ZN8Derived010return_aggEv_vfpthunk_(ptr noundef %{{.*}}) 1854dcd91aeSOliver Hunt // CHECK: %[[CALL:.*]] = musttail call [2 x i64] %{{.*}}(ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %{{.*}}) [ "ptrauth"(i32 0, i64 %{{.*}}) ] 1864dcd91aeSOliver Hunt // CHECK-NEXT: ret [2 x i64] %[[CALL]] 1874dcd91aeSOliver Hunt 1884dcd91aeSOliver Hunt // Check that the sret pointer passed to the caller is forwarded to the musttail 1894dcd91aeSOliver Hunt // call. 1904dcd91aeSOliver Hunt 1914dcd91aeSOliver Hunt // CHECK: define linkonce_odr hidden void @_ZN8Derived04sretEv_vfpthunk_(ptr dead_on_unwind noalias writable sret(%struct.A1) align 4 %[[AGG_RESULT:.*]], ptr noundef %{{.*}}) 1924dcd91aeSOliver Hunt // CHECK: musttail call void %{{.*}}(ptr dead_on_unwind writable sret(%struct.A1) align 4 %[[AGG_RESULT]], ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %{{.*}}) [ "ptrauth"(i32 0, i64 %{{.*}}) ] 1934dcd91aeSOliver Hunt // CHECK-NEXT: ret void 1944dcd91aeSOliver Hunt 1954dcd91aeSOliver Hunt // Check that the thunk function doesn't destruct the trivial_abi argument. 1964dcd91aeSOliver Hunt 1974dcd91aeSOliver Hunt // CHECK: define linkonce_odr hidden void @_ZN8Derived011trivial_abiE8TrivialS_vfpthunk_(ptr noundef %{{.*}}, [2 x i64] %{{.*}}) 1984dcd91aeSOliver Hunt // NODEBUG-NOT: call 1994dcd91aeSOliver Hunt // CHECK: call i64 @llvm.ptrauth.auth( 2004dcd91aeSOliver Hunt // NODEBUG-NOT: call 2014dcd91aeSOliver Hunt // CHECK: call i64 @llvm.ptrauth.blend( 2024dcd91aeSOliver Hunt // NODEBUG-NOT: call 2034dcd91aeSOliver Hunt // CHECK: musttail call void 2044dcd91aeSOliver Hunt // CHECK-NEXT: ret void 2054dcd91aeSOliver Hunt 2064dcd91aeSOliver Hunt // CHECK: define linkonce_odr hidden void @_ZN5Base18virtual7Ev_vfpthunk_(ptr noundef %[[THIS:.*]]) 2074dcd91aeSOliver Hunt // CHECK: entry: 2084dcd91aeSOliver Hunt // CHECK: %[[THIS_ADDR:.*]] = alloca ptr, align 8 2094dcd91aeSOliver Hunt // CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]], align 8 2104dcd91aeSOliver Hunt // CHECK: %[[THIS1:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 2114dcd91aeSOliver Hunt // CHECK: %[[V0:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 2124dcd91aeSOliver Hunt // CHECK: %[[VTABLE:.*]] = load ptr, ptr %[[THIS1]], align 8 2134dcd91aeSOliver Hunt // CHECK: %[[V1:.*]] = ptrtoint ptr %[[VTABLE]] to i64 2144dcd91aeSOliver Hunt // CHECK: %[[V2:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V1]], i32 2, i64 0) 2154dcd91aeSOliver Hunt // CHECK: %[[V3:.*]] = inttoptr i64 %[[V2]] to ptr 2164dcd91aeSOliver Hunt // CHECK: getelementptr inbounds ptr, ptr %[[V3]], i64 0 2174dcd91aeSOliver Hunt 2184dcd91aeSOliver Hunt // CHECK: define linkonce_odr hidden void @_ZN8Derived18virtual7Ev_vfpthunk_(ptr noundef %[[THIS:.*]]) 2194dcd91aeSOliver Hunt // CHECK: %[[THIS_ADDR:.*]] = alloca ptr, align 8 2204dcd91aeSOliver Hunt // CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]], align 8 2214dcd91aeSOliver Hunt // CHECK: %[[THIS1:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 2224dcd91aeSOliver Hunt // CHECK: load ptr, ptr %[[THIS_ADDR]], align 8 2234dcd91aeSOliver Hunt // CHECK: %[[VTABLE:.*]] = load ptr, ptr %[[THIS1]], align 8 2244dcd91aeSOliver Hunt // CHECK: %[[V1:.*]] = ptrtoint ptr %[[VTABLE]] to i64 2254dcd91aeSOliver Hunt // CHECK: %[[V2:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V1]], i32 2, i64 0) 2264dcd91aeSOliver Hunt // CHECK: %[[V3:.*]] = inttoptr i64 %[[V2]] to ptr 2274dcd91aeSOliver Hunt // CHECK: getelementptr inbounds ptr, ptr %[[V3]], i64 3 2284dcd91aeSOliver Hunt 2294dcd91aeSOliver Hunt void Base0::virtual1() {} 2304dcd91aeSOliver Hunt 2314dcd91aeSOliver Hunt void test0() { 2324dcd91aeSOliver Hunt MethodTy0 method0; 2334dcd91aeSOliver Hunt method0 = &Base0::nonvirtual0; 2344dcd91aeSOliver Hunt method0 = &Base0::virtual1; 2354dcd91aeSOliver Hunt method0 = &Base0::virtual3; 2364dcd91aeSOliver Hunt 2374dcd91aeSOliver Hunt VariadicMethodTy0 varmethod1; 2384dcd91aeSOliver Hunt varmethod1 = &Base0::virtual_variadic; 2394dcd91aeSOliver Hunt 2404dcd91aeSOliver Hunt MethodTy1 method2; 2414dcd91aeSOliver Hunt method2 = &Derived0::nonvirtual0; 2424dcd91aeSOliver Hunt method2 = &Derived0::virtual1; 2434dcd91aeSOliver Hunt method2 = &Derived0::virtual3; 2444dcd91aeSOliver Hunt method2 = &Derived0::nonvirtual5; 2454dcd91aeSOliver Hunt method2 = &Derived0::virtual6; 2464dcd91aeSOliver Hunt 2474dcd91aeSOliver Hunt A0 (Derived0::*method3)(); 2484dcd91aeSOliver Hunt method3 = &Derived0::return_agg; 2494dcd91aeSOliver Hunt 2504dcd91aeSOliver Hunt A1 (Derived0::*method4)(); 2514dcd91aeSOliver Hunt method4 = &Derived0::sret; 2524dcd91aeSOliver Hunt 2534dcd91aeSOliver Hunt void (Derived0::*method5)(TrivialS); 2544dcd91aeSOliver Hunt method5 = &Derived0::trivial_abi; 2554dcd91aeSOliver Hunt 2564dcd91aeSOliver Hunt void (Base1::*method6)(); 2574dcd91aeSOliver Hunt method6 = &Base1::virtual7; 2584dcd91aeSOliver Hunt 2594dcd91aeSOliver Hunt void (Derived1::*method7)(); 2604dcd91aeSOliver Hunt method7 = &Derived1::virtual7; 2614dcd91aeSOliver Hunt method7 = &Derived1::virtual1; 2624dcd91aeSOliver Hunt } 2634dcd91aeSOliver Hunt 26470c6e79eSDaniil Kovalev // CHECK: define{{.*}} void @_Z5test1P5Base0MS_FvvE(ptr noundef %[[A0:.*]], [2 x i64] %[[A1_COERCE:.*]]) 2654dcd91aeSOliver Hunt // CHECK: %[[A1:.*]] = alloca { i64, i64 }, align 8 2664dcd91aeSOliver Hunt // CHECK: %[[A0_ADDR:.*]] = alloca ptr, align 8 2674dcd91aeSOliver Hunt // CHECK: %[[A1_ADDR:.*]] = alloca { i64, i64 }, align 8 2684dcd91aeSOliver Hunt // CHECK: store [2 x i64] %[[A1_COERCE]], ptr %[[A1]], align 8 2694dcd91aeSOliver Hunt // CHECK: %[[A11:.*]] = load { i64, i64 }, ptr %[[A1]], align 8 2704dcd91aeSOliver Hunt // CHECK: store ptr %[[A0]], ptr %[[A0_ADDR]], align 8 2714dcd91aeSOliver Hunt // CHECK: store { i64, i64 } %[[A11]], ptr %[[A1_ADDR]], align 8 2724dcd91aeSOliver Hunt // CHECK: %[[V1:.*]] = load ptr, ptr %[[A0_ADDR]], align 8 2734dcd91aeSOliver Hunt // CHECK: %[[V2:.*]] = load { i64, i64 }, ptr %[[A1_ADDR]], align 8 2744dcd91aeSOliver Hunt // CHECK: %[[MEMPTR_ADJ:.*]] = extractvalue { i64, i64 } %[[V2]], 1 2754dcd91aeSOliver Hunt // CHECK: %[[MEMPTR_ADJ_SHIFTED:.*]] = ashr i64 %[[MEMPTR_ADJ]], 1 2764dcd91aeSOliver Hunt // CHECK: %[[V4:.*]] = getelementptr inbounds i8, ptr %[[V1]], i64 %[[MEMPTR_ADJ_SHIFTED]] 2774dcd91aeSOliver Hunt // CHECK: %[[MEMPTR_PTR:.*]] = extractvalue { i64, i64 } %[[V2]], 0 2784dcd91aeSOliver Hunt // CHECK: %[[V5:.*]] = and i64 %[[MEMPTR_ADJ]], 1 2794dcd91aeSOliver Hunt // CHECK: %[[MEMPTR_ISVIRTUAL:.*]] = icmp ne i64 %[[V5]], 0 2804dcd91aeSOliver Hunt // CHECK: br i1 %[[MEMPTR_ISVIRTUAL]] 2814dcd91aeSOliver Hunt 2824dcd91aeSOliver Hunt // CHECK: %[[VTABLE:.*]] = load ptr, ptr %[[V4]], align 8 2834dcd91aeSOliver Hunt // CHECK: %[[V7:.*]] = ptrtoint ptr %[[VTABLE]] to i64 2844dcd91aeSOliver Hunt // CHECK: %[[V8:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V7]], i32 2, i64 0) 2854dcd91aeSOliver Hunt // CHECK: %[[V9:.*]] = inttoptr i64 %[[V8]] to ptr 28670c6e79eSDaniil Kovalev // DARWIN: %[[V10:.*]] = trunc i64 %[[MEMPTR_PTR]] to i32 28770c6e79eSDaniil Kovalev // DARWIN: %[[V11:.*]] = zext i32 %[[V10]] to i64 28870c6e79eSDaniil Kovalev // DARWIN: %[[V12:.*]] = getelementptr i8, ptr %[[V9]], i64 %[[V11]] 28970c6e79eSDaniil Kovalev // ELF: %[[V12:.*]] = getelementptr i8, ptr %[[V9]], i64 %[[MEMPTR_PTR]] 2904dcd91aeSOliver Hunt // CHECK: %[[MEMPTR_VIRTUALFN:.*]] = load ptr, ptr %[[V12]], align 8 2914dcd91aeSOliver Hunt // CHECK: br 2924dcd91aeSOliver Hunt 2934dcd91aeSOliver Hunt // CHECK: %[[MEMPTR_NONVIRTUALFN:.*]] = inttoptr i64 %[[MEMPTR_PTR]] to ptr 2944dcd91aeSOliver Hunt // CHECK: br 2954dcd91aeSOliver Hunt 2964dcd91aeSOliver Hunt // CHECK: %[[V14:.*]] = phi ptr [ %[[MEMPTR_VIRTUALFN]], {{.*}} ], [ %[[MEMPTR_NONVIRTUALFN]], {{.*}} ] 2974dcd91aeSOliver Hunt // CHECK: %[[V15:.*]] = phi i64 [ 0, {{.*}} ], [ [[TYPEDISC0]], {{.*}} ] 2984dcd91aeSOliver Hunt // CHECK: call void %[[V14]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %[[V4]]) [ "ptrauth"(i32 0, i64 %[[V15]]) ] 2994dcd91aeSOliver Hunt // CHECK: ret void 3004dcd91aeSOliver Hunt 3014dcd91aeSOliver Hunt void test1(Base0 *a0, MethodTy0 a1) { 3024dcd91aeSOliver Hunt (a0->*a1)(); 3034dcd91aeSOliver Hunt } 3044dcd91aeSOliver Hunt 305*485c80e1SAkira Hatanaka // CXX17: define{{.*}} void @_Z14test1_noexceptP5Base0MS_DoFvvE( 306*485c80e1SAkira Hatanaka // CXX17: %[[V14:.*]] = phi ptr [ %{{.*}}, {{.*}} ], [ %{{.*}}, {{.*}} ] 307*485c80e1SAkira Hatanaka // CXX17: %[[V15:.*]] = phi i64 [ 0, {{.*}} ], [ [[TYPEDISC0]], {{.*}} ] 308*485c80e1SAkira Hatanaka // CXX17: call void %[[V14]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %{{.*}}) {{.*}}[ "ptrauth"(i32 0, i64 %[[V15]]) ] 309*485c80e1SAkira Hatanaka #if __cplusplus >= 201703L 310*485c80e1SAkira Hatanaka void test1_noexcept(Base0 *a0, NoExceptMethodTy0 a1) { 311*485c80e1SAkira Hatanaka (a0->*a1)(); 312*485c80e1SAkira Hatanaka } 313*485c80e1SAkira Hatanaka #endif 314*485c80e1SAkira Hatanaka 31570c6e79eSDaniil Kovalev // CHECK: define{{.*}} void @_Z15testConversion0M5Base0FvvEM8Derived0FvvE([2 x i64] %[[METHOD0_COERCE:.*]], [2 x i64] %[[METHOD1_COERCE:.*]]) 3164dcd91aeSOliver Hunt // CHECK: %[[METHOD0:.*]] = alloca { i64, i64 }, align 8 3174dcd91aeSOliver Hunt // CHECK: %[[METHOD1:.*]] = alloca { i64, i64 }, align 8 3184dcd91aeSOliver Hunt // CHECK: %[[METHOD0_ADDR:.*]] = alloca { i64, i64 }, align 8 3194dcd91aeSOliver Hunt // CHECK: %[[METHOD1_ADDR:.*]] = alloca { i64, i64 }, align 8 3204dcd91aeSOliver Hunt // CHECK: store [2 x i64] %[[METHOD0_COERCE]], ptr %[[METHOD0]], align 8 3214dcd91aeSOliver Hunt // CHECK: %[[METHOD01:.*]] = load { i64, i64 }, ptr %[[METHOD0]], align 8 3224dcd91aeSOliver Hunt // CHECK: store [2 x i64] %[[METHOD1_COERCE]], ptr %[[METHOD1]], align 8 3234dcd91aeSOliver Hunt // CHECK: %[[METHOD12:.*]] = load { i64, i64 }, ptr %[[METHOD1]], align 8 3244dcd91aeSOliver Hunt // CHECK: store { i64, i64 } %[[METHOD01]], ptr %[[METHOD0_ADDR]], align 8 3254dcd91aeSOliver Hunt // CHECK: store { i64, i64 } %[[METHOD12]], ptr %[[METHOD1_ADDR]], align 8 3264dcd91aeSOliver Hunt // CHECK: %[[V2:.*]] = load { i64, i64 }, ptr %[[METHOD0_ADDR]], align 8 3274dcd91aeSOliver Hunt // CHECK: %[[MEMPTR_PTR:.*]] = extractvalue { i64, i64 } %[[V2]], 0 3284dcd91aeSOliver Hunt // CHECK: %[[MEMPTR_ADJ:.*]] = extractvalue { i64, i64 } %[[V2]], 1 3294dcd91aeSOliver Hunt // CHECK: %[[V3:.*]] = and i64 %[[MEMPTR_ADJ]], 1 3304dcd91aeSOliver Hunt // CHECK: %[[IS_VIRTUAL_OFFSET:.*]] = icmp ne i64 %[[V3]], 0 3314dcd91aeSOliver Hunt // CHECK: br i1 %[[IS_VIRTUAL_OFFSET]] 3324dcd91aeSOliver Hunt 3334dcd91aeSOliver Hunt // CHECK: %[[V4:.*]] = inttoptr i64 %[[MEMPTR_PTR]] to ptr 3344dcd91aeSOliver Hunt // CHECK: %[[V5:.*]] = icmp ne ptr %[[V4]], null 3354dcd91aeSOliver Hunt // CHECK: br i1 %[[V5]] 3364dcd91aeSOliver Hunt 3374dcd91aeSOliver Hunt // CHECK: %[[V6:.*]] = ptrtoint ptr %[[V4]] to i64 3384dcd91aeSOliver Hunt // CHECK: %[[V7:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V6]], i32 0, i64 [[TYPEDISC0]], i32 0, i64 [[TYPEDISC1]]) 3394dcd91aeSOliver Hunt // CHECK: %[[V8:.*]] = inttoptr i64 %[[V7]] to ptr 3404dcd91aeSOliver Hunt // CHECK: br 3414dcd91aeSOliver Hunt 3424dcd91aeSOliver Hunt // CHECK: %[[V9:.*]] = phi ptr [ null, {{.*}} ], [ %[[V8]], {{.*}} ] 3434dcd91aeSOliver Hunt // CHECK: %[[V1:.*]] = ptrtoint ptr %[[V9]] to i64 3444dcd91aeSOliver Hunt // CHECK: %[[V11:.*]] = insertvalue { i64, i64 } %[[V2]], i64 %[[V1]], 0 3454dcd91aeSOliver Hunt // CHECK: br 3464dcd91aeSOliver Hunt 3474dcd91aeSOliver Hunt // CHECK: %[[V12:.*]] = phi { i64, i64 } [ %[[V2]], {{.*}} ], [ %[[V11]], {{.*}} ] 3484dcd91aeSOliver Hunt // CHECK: store { i64, i64 } %[[V12]], ptr %[[METHOD1_ADDR]], align 8 3494dcd91aeSOliver Hunt // CHECK: ret void 3504dcd91aeSOliver Hunt 3514dcd91aeSOliver Hunt void testConversion0(MethodTy0 method0, MethodTy1 method1) { 3524dcd91aeSOliver Hunt method1 = method0; 3534dcd91aeSOliver Hunt } 3544dcd91aeSOliver Hunt 35570c6e79eSDaniil Kovalev // CHECK: define{{.*}} void @_Z15testConversion1M5Base0FvvE( 3564dcd91aeSOliver Hunt // CHECK: call i64 @llvm.ptrauth.resign(i64 %{{.*}}, i32 0, i64 [[TYPEDISC0]], i32 0, i64 [[TYPEDISC1]]) 3574dcd91aeSOliver Hunt 3584dcd91aeSOliver Hunt void testConversion1(MethodTy0 method0) { 3594dcd91aeSOliver Hunt MethodTy1 method1 = reinterpret_cast<MethodTy1>(method0); 3604dcd91aeSOliver Hunt } 3614dcd91aeSOliver Hunt 36270c6e79eSDaniil Kovalev // CHECK: define{{.*}} void @_Z15testConversion2M8Derived0FvvE( 3634dcd91aeSOliver Hunt // CHECK: call i64 @llvm.ptrauth.resign(i64 %{{.*}}, i32 0, i64 [[TYPEDISC1]], i32 0, i64 [[TYPEDISC0]]) 3644dcd91aeSOliver Hunt 3654dcd91aeSOliver Hunt void testConversion2(MethodTy1 method1) { 3664dcd91aeSOliver Hunt MethodTy0 method0 = static_cast<MethodTy0>(method1); 3674dcd91aeSOliver Hunt } 3684dcd91aeSOliver Hunt 36970c6e79eSDaniil Kovalev // CHECK: define{{.*}} void @_Z15testConversion3M8Derived0FvvE( 3704dcd91aeSOliver Hunt // CHECK: call i64 @llvm.ptrauth.resign(i64 %{{.*}}, i32 0, i64 [[TYPEDISC1]], i32 0, i64 [[TYPEDISC0]]) 3714dcd91aeSOliver Hunt 3724dcd91aeSOliver Hunt void testConversion3(MethodTy1 method1) { 3734dcd91aeSOliver Hunt MethodTy0 method0 = reinterpret_cast<MethodTy0>(method1); 3744dcd91aeSOliver Hunt } 3754dcd91aeSOliver Hunt 3764dcd91aeSOliver Hunt // No need to call @llvm.ptrauth.resign if the source member function 3774dcd91aeSOliver Hunt // pointer is a constant. 3784dcd91aeSOliver Hunt 37970c6e79eSDaniil Kovalev // CHECK: define{{.*}} void @_Z15testConversion4v( 3804dcd91aeSOliver Hunt // CHECK: %[[METHOD0:.*]] = alloca { i64, i64 }, align 8 3814dcd91aeSOliver Hunt // CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 [[TYPEDISC0]]) to i64), i64 0 }, ptr %[[METHOD0]], align 8 3824dcd91aeSOliver Hunt // CHECK: ret void 3834dcd91aeSOliver Hunt 3844dcd91aeSOliver Hunt void testConversion4() { 3854dcd91aeSOliver Hunt MethodTy0 method0 = reinterpret_cast<MethodTy0>(&Derived0::virtual1); 3864dcd91aeSOliver Hunt } 3874dcd91aeSOliver Hunt 3884dcd91aeSOliver Hunt // This code used to crash. 3894dcd91aeSOliver Hunt namespace testNonVirtualThunk { 3904dcd91aeSOliver Hunt struct R {}; 3914dcd91aeSOliver Hunt 3924dcd91aeSOliver Hunt struct B0 { 3934dcd91aeSOliver Hunt virtual void bar(); 3944dcd91aeSOliver Hunt }; 3954dcd91aeSOliver Hunt 3964dcd91aeSOliver Hunt struct B1 { 3974dcd91aeSOliver Hunt virtual R foo(); 3984dcd91aeSOliver Hunt }; 3994dcd91aeSOliver Hunt 4004dcd91aeSOliver Hunt struct D : B0, B1 { 4014dcd91aeSOliver Hunt virtual R foo(); 4024dcd91aeSOliver Hunt }; 4034dcd91aeSOliver Hunt 4044dcd91aeSOliver Hunt D d; 4054dcd91aeSOliver Hunt } 4064dcd91aeSOliver Hunt 4074dcd91aeSOliver Hunt // CHECK: define internal void @_ZN22TestAnonymousNamespace12_GLOBAL__N_11S3fooEv_vfpthunk_( 4084dcd91aeSOliver Hunt 4094dcd91aeSOliver Hunt namespace TestAnonymousNamespace { 4104dcd91aeSOliver Hunt namespace { 4114dcd91aeSOliver Hunt struct S { 4124dcd91aeSOliver Hunt virtual void foo(){}; 4134dcd91aeSOliver Hunt }; 4144dcd91aeSOliver Hunt } // namespace 4154dcd91aeSOliver Hunt 4164dcd91aeSOliver Hunt void test() { 4174dcd91aeSOliver Hunt auto t = &S::foo; 4184dcd91aeSOliver Hunt } 4194dcd91aeSOliver Hunt } // namespace TestAnonymousNamespace 4204dcd91aeSOliver Hunt 4214dcd91aeSOliver Hunt MethodTy1 gmethod0 = reinterpret_cast<MethodTy1>(&Base0::nonvirtual0); 4224dcd91aeSOliver Hunt MethodTy0 gmethod1 = reinterpret_cast<MethodTy0>(&Derived0::nonvirtual5); 4234dcd91aeSOliver Hunt MethodTy0 gmethod2 = reinterpret_cast<MethodTy0>(&Derived0::virtual1); 4244dcd91aeSOliver Hunt 42570c6e79eSDaniil Kovalev // CHECK-LABEL: define{{.*}} void @_Z13testArrayInitv() 4264dcd91aeSOliver Hunt // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %p0, ptr align 8 @__const._Z13testArrayInitv.p0, i64 16, i1 false) 4274dcd91aeSOliver Hunt // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %p1, ptr align 8 @__const._Z13testArrayInitv.p1, i64 16, i1 false) 4284dcd91aeSOliver Hunt // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %c0, ptr align 8 @__const._Z13testArrayInitv.c0, i64 16, i1 false) 4294dcd91aeSOliver Hunt // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %c1, ptr align 8 @__const._Z13testArrayInitv.c1, i64 16, i1 false) 4304dcd91aeSOliver Hunt // CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %{{.*}} align 8 4314dcd91aeSOliver Hunt // CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %{{.*}}, align 8 4324dcd91aeSOliver Hunt 4334dcd91aeSOliver Hunt void initList(std::initializer_list<MethodTy1>); 4344dcd91aeSOliver Hunt 4354dcd91aeSOliver Hunt void testArrayInit() { 4364dcd91aeSOliver Hunt MethodTy1 p0[] = {&Base0::nonvirtual0}; 4374dcd91aeSOliver Hunt MethodTy1 p1[] = {&Base0::virtual1}; 4384dcd91aeSOliver Hunt Class0 c0{&Base0::nonvirtual0}; 4394dcd91aeSOliver Hunt Class0 c1{&Base0::virtual1}; 4404dcd91aeSOliver Hunt initList({&Base0::nonvirtual0}); 4414dcd91aeSOliver Hunt initList({&Base0::virtual1}); 4424dcd91aeSOliver Hunt } 4434dcd91aeSOliver Hunt 4444dcd91aeSOliver Hunt 4454dcd91aeSOliver Hunt 4464dcd91aeSOliver Hunt // STACK-PROT: define {{.*}}_vfpthunk{{.*}}[[ATTRS:#[0-9]+]] 4474dcd91aeSOliver Hunt // STACK-PROT: attributes [[ATTRS]] = 4484dcd91aeSOliver Hunt // STACK-PROT-NOT: ssp 4494dcd91aeSOliver Hunt // STACK-PROT-NOT: sspstrong 4504dcd91aeSOliver Hunt // STACK-PROT-NOT: sspreq 4514dcd91aeSOliver Hunt // STACK-PROT-NEXT: attributes 4524dcd91aeSOliver Hunt 45370c6e79eSDaniil Kovalev // CHECK: define{{.*}} void @_Z15testConvertNullv( 4544dcd91aeSOliver Hunt // CHECK: %[[T:.*]] = alloca { i64, i64 }, 4554dcd91aeSOliver Hunt // store { i64, i64 } zeroinitializer, { i64, i64 }* %[[T]], 4564dcd91aeSOliver Hunt 4574dcd91aeSOliver Hunt void testConvertNull() { 4584dcd91aeSOliver Hunt VariadicMethodTy0 t = (VariadicMethodTy0)(MethodTy0{}); 4594dcd91aeSOliver Hunt } 460*485c80e1SAkira Hatanaka 461*485c80e1SAkira Hatanaka namespace testNoexceptConversion { 462*485c80e1SAkira Hatanaka 463*485c80e1SAkira Hatanaka // CHECK-LABEL: define internal void @__cxx_global_var_init() 464*485c80e1SAkira Hatanaka // CHECK: %[[V0:.*]] = load { i64, i64 }, ptr @_ZN22testNoexceptConversion15mfptr0_noexceptE, align 8 465*485c80e1SAkira Hatanaka // CHECK: store { i64, i64 } %[[V0]], ptr @_ZN22testNoexceptConversion6mfptr4E, align 8 466*485c80e1SAkira Hatanaka 467*485c80e1SAkira Hatanaka // CHECK: define {{.*}}void @_ZN22testNoexceptConversion5test0Ev() 468*485c80e1SAkira Hatanaka // CHECK: %[[P0:.*]] = alloca { i64, i64 }, align 8 469*485c80e1SAkira Hatanaka // CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S19nonvirtual_noexceptEv, i32 0, i64 [[TYPEDISC3]]) to i64), i64 0 }, ptr %[[P0]], align 8, 470*485c80e1SAkira Hatanaka 471*485c80e1SAkira Hatanaka // CHECK: define {{.*}}void @_ZN22testNoexceptConversion5test1Ev() 472*485c80e1SAkira Hatanaka // CHECK: %[[P0:.*]] = alloca { i64, i64 }, align 8 473*485c80e1SAkira Hatanaka // CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S16virtual_noexceptEv_vfpthunk_, i32 0, i64 [[TYPEDISC3]]) to i64), i64 0 }, ptr %[[P0]], align 8, 474*485c80e1SAkira Hatanaka 475*485c80e1SAkira Hatanaka // CHECK: define {{.*}}void @_ZN22testNoexceptConversion5test2Ev() 476*485c80e1SAkira Hatanaka // CHECK: %[[P0:.*]] = alloca { i64, i64 }, align 8 477*485c80e1SAkira Hatanaka // CHECK: %[[V0:.*]] = load { i64, i64 }, ptr @_ZN22testNoexceptConversion15mfptr0_noexceptE, align 8 478*485c80e1SAkira Hatanaka // CHECK: store { i64, i64 } %[[V0]], ptr %[[P0]], align 8, 479*485c80e1SAkira Hatanaka 480*485c80e1SAkira Hatanaka struct S { 481*485c80e1SAkira Hatanaka void nonvirtual_noexcept() noexcept; 482*485c80e1SAkira Hatanaka virtual void virtual_noexcept() noexcept; 483*485c80e1SAkira Hatanaka }; 484*485c80e1SAkira Hatanaka 485*485c80e1SAkira Hatanaka void (S::*mfptr0_noexcept)() noexcept; 486*485c80e1SAkira Hatanaka void (S::*mfptr1)() = &S::nonvirtual_noexcept; 487*485c80e1SAkira Hatanaka void (S::*mfptr2)() = &S::virtual_noexcept; 488*485c80e1SAkira Hatanaka void (S::*mfptr3_noexcept)() noexcept = &S::nonvirtual_noexcept; 489*485c80e1SAkira Hatanaka void (S::*mfptr4)() = mfptr0_noexcept; 490*485c80e1SAkira Hatanaka 491*485c80e1SAkira Hatanaka void test0() { 492*485c80e1SAkira Hatanaka void (S::*p0)() = &S::nonvirtual_noexcept; 493*485c80e1SAkira Hatanaka } 494*485c80e1SAkira Hatanaka 495*485c80e1SAkira Hatanaka void test1() { 496*485c80e1SAkira Hatanaka void (S::*p0)() = &S::virtual_noexcept; 497*485c80e1SAkira Hatanaka } 498*485c80e1SAkira Hatanaka 499*485c80e1SAkira Hatanaka void test2() { 500*485c80e1SAkira Hatanaka void (S::*p0)() = mfptr0_noexcept; 501*485c80e1SAkira Hatanaka } 502*485c80e1SAkira Hatanaka 503*485c80e1SAkira Hatanaka } 504