1 // RUN: %clang_cc1 -std=c++2a -emit-llvm %s -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ITANIUM 2 // RUN: %clang_cc1 -std=c++2a -emit-llvm %s -triple x86_64-windows -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-MSABI 3 4 namespace std { 5 using size_t = decltype(sizeof(0)); 6 enum class align_val_t : size_t; 7 struct destroying_delete_t {}; 8 } 9 10 struct A { 11 void *data; 12 ~A(); 13 void operator delete(A*, std::destroying_delete_t); 14 }; 15 void delete_A(A *a) { delete a; } 16 // CHECK-LABEL: define {{.*}}delete_A 17 // CHECK: %[[a:.*]] = load 18 // CHECK: icmp eq %{{.*}} %[[a]], null 19 // CHECK: br i1 20 // 21 // Ensure that we call the destroying delete and not the destructor. 22 // CHECK-NOT: call 23 // CHECK-ITANIUM: call void @_ZN1AdlEPS_St19destroying_delete_t(%{{.*}}* %[[a]]) 24 // CHECK-MSABI: call void @"\01??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* %[[a]], i8 25 // CHECK-NOT: call 26 // CHECK: } 27 28 struct B { 29 virtual ~B(); 30 void operator delete(B*, std::destroying_delete_t); 31 }; 32 void delete_B(B *b) { delete b; } 33 // CHECK-LABEL: define {{.*}}delete_B 34 // CHECK: %[[b:.*]] = load 35 // CHECK: icmp eq %{{.*}} %[[b]], null 36 // CHECK: br i1 37 // 38 // Ensure that we call the virtual destructor and not the operator delete. 39 // CHECK-NOT: call 40 // CHECK: %[[VTABLE:.*]] = load 41 // CHECK: %[[DTOR:.*]] = load 42 // CHECK: call {{void|i8\*}} %[[DTOR]](%{{.*}}* %[[b]] 43 // CHECK-MSABI-SAME: , i32 1) 44 // CHECK-NOT: call 45 // CHECK: } 46 47 struct Padding { 48 virtual void f(); 49 }; 50 51 struct C : Padding, A {}; 52 void delete_C(C *c) { delete c; } 53 // Check that we perform a derived-to-base conversion on the parameter to 'operator delete'. 54 // CHECK-LABEL: define {{.*}}delete_C 55 // CHECK: %[[c:.*]] = load 56 // CHECK: icmp eq %{{.*}} %[[c]], null 57 // CHECK: br i1 58 // 59 // CHECK: %[[base:.*]] = getelementptr {{.*}}, i64 8 60 // CHECK: %[[castbase:.*]] = bitcast {{.*}} %[[base]] 61 // 62 // CHECK: %[[a:.*]] = phi {{.*}} %[[castbase]] 63 // CHECK: icmp eq %{{.*}} %[[a]], null 64 // CHECK: br i1 65 // 66 // CHECK-NOT: call 67 // CHECK-ITANIUM: call void @_ZN1AdlEPS_St19destroying_delete_t(%{{.*}}* %[[a]]) 68 // CHECK-MSABI: call void @"\01??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* %[[a]], i8 69 // CHECK-NOT: call 70 // CHECK: } 71 72 struct VDel { virtual ~VDel(); }; 73 struct D : Padding, VDel, B {}; 74 void delete_D(D *d) { delete d; } 75 // CHECK-LABEL: define {{.*}}delete_D 76 // CHECK: %[[d:.*]] = load 77 // CHECK: icmp eq %{{.*}} %[[d]], null 78 // CHECK: br i1 79 // 80 // CHECK-NOT: call 81 // CHECK: %[[VTABLE:.*]] = load 82 // CHECK: %[[DTOR:.*]] = load 83 // 84 // For MS, we don't add a new vtable slot to the primary vtable for the virtual 85 // destructor. Instead we cast to the VDel base class. 86 // CHECK-MSABI: bitcast {{.*}} %[[d]] 87 // CHECK-MSABI-NEXT: getelementptr {{.*}}, i64 8 88 // CHECK-MSABI-NEXT: %[[d:.*]] = bitcast i8* 89 // 90 // CHECK: call {{void|i8\*}} %[[DTOR]](%{{.*}}* %[[d]] 91 // CHECK-MSABI-SAME: , i32 1) 92 // CHECK-NOT: call 93 // CHECK: } 94 95 struct E { void *data; }; 96 struct F { void operator delete(F *, std::destroying_delete_t, std::size_t, std::align_val_t); void *data; }; 97 struct alignas(16) G : E, F { void *data; }; 98 99 void delete_G(G *g) { delete g; } 100 // CHECK-LABEL: define {{.*}}delete_G 101 // CHECK-NOT: call 102 // CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t(%{{.*}}* %[[a]], i64 32, i64 16) 103 // CHECK-MSABI: call void @"\01??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"(%{{.*}}* %[[a]], i8 {{[^,]*}}, i64 32, i64 16) 104 // CHECK-NOT: call 105 // CHECK: } 106 107 void call_in_dtor(); 108 109 struct H : G { virtual ~H(); } h; 110 H::~H() { call_in_dtor(); } 111 // CHECK-ITANIUM-LABEL: define void @_ZN1HD0Ev( 112 // CHECK-ITANIUM-NOT: call 113 // CHECK-ITANIUM: getelementptr {{.*}}, i64 24 114 // CHECK-ITANIUM-NOT: call 115 // CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t({{.*}}, i64 48, i64 16) 116 // CHECK-ITANIUM-NOT: call 117 // CHECK-ITANIUM: } 118 119 // CHECK-MSABI: define {{.*}} @"\01??_GH@@UEAAPEAXI@Z"( 120 // CHECK-MSABI-NOT: call{{ }} 121 // CHECK-MSABI: load i32 122 // CHECK-MSABI: icmp eq i32 {{.*}}, 0 123 // CHECK-MSABI: br i1 124 // 125 // CHECK-MSABI-NOT: call{{ }} 126 // CHECK-MSABI: getelementptr {{.*}}, i64 24 127 // CHECK-MSABI-NOT: call{{ }} 128 // CHECK-MSABI: call void @"\01??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 48, i64 16) 129 // CHECK-MSABI: br label %[[RETURN:.*]] 130 // 131 // CHECK-MSABI: call void @"\01??_DH@@QEAAXXZ"( 132 // CHECK-MSABI: br label %[[RETURN]] 133 // 134 // CHECK-MSABI: } 135 136 struct I : H { virtual ~I(); alignas(32) char buffer[32]; } i; 137 I::~I() { call_in_dtor(); } 138 // CHECK-ITANIUM-LABEL: define void @_ZN1ID0Ev( 139 // CHECK-ITANIUM-NOT: call 140 // CHECK-ITANIUM: getelementptr {{.*}}, i64 24 141 // CHECK-ITANIUM-NOT: call 142 // CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t({{.*}}, i64 96, i64 32) 143 // CHECK-ITANIUM-NOT: call 144 // CHECK-ITANIUM: } 145 146 // CHECK-MSABI: define {{.*}} @"\01??_GI@@UEAAPEAXI@Z"( 147 // CHECK-MSABI-NOT: call{{ }} 148 // CHECK-MSABI: load i32 149 // CHECK-MSABI: icmp eq i32 {{.*}}, 0 150 // CHECK-MSABI: br i1 151 // 152 // CHECK-MSABI-NOT: call{{ }} 153 // CHECK-MSABI: getelementptr {{.*}}, i64 24 154 // CHECK-MSABI-NOT: call{{ }} 155 // CHECK-MSABI: call void @"\01??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 96, i64 32) 156 // CHECK-MSABI: br label %[[RETURN:.*]] 157 // 158 // CHECK-MSABI: call void @"\01??_DI@@QEAAXXZ"( 159 // CHECK-MSABI: br label %[[RETURN]] 160 // 161 // CHECK-MSABI: } 162