1 // RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm %s -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefixes=CHECK,CHECK-ITANIUM,CHECK-64BIT 2 // RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm %s -triple x86_64-windows -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MSABI,CHECK-MSABI64,CHECK-64BIT 3 // RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm %s -triple i386-windows -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MSABI,CHECK-MSABI32,CHECK-32BIT 4 5 // PR46908: ensure the IR passes the verifier with optimizations enabled. 6 // RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm-only %s -triple x86_64-linux-gnu -O2 7 // RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm-only %s -triple x86_64-windows -O2 8 // RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm-only %s -triple i386-windows -O2 9 10 namespace std { 11 using size_t = decltype(sizeof(0)); 12 enum class align_val_t : size_t; 13 struct destroying_delete_t {}; 14 } 15 16 struct A { 17 void *data; 18 ~A(); 19 void operator delete(A*, std::destroying_delete_t); 20 }; 21 void delete_A(A *a) { delete a; } 22 // CHECK-LABEL: define {{.*}}delete_A 23 // CHECK: %[[a:.*]] = load 24 // CHECK: icmp eq %{{.*}} %[[a]], null 25 // CHECK: br i1 26 // 27 // Ensure that we call the destroying delete and not the destructor. 28 // CHECK-NOT: call 29 // CHECK-ITANIUM: call void @_ZN1AdlEPS_St19destroying_delete_t(%{{.*}}* noundef %[[a]]) 30 // CHECK-MSABI64: call void @"??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* noundef %[[a]], i8 31 // CHECK-MSABI32: call void @"??3A@@SAXPAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* noundef %[[a]], %{{.*}}* noundef byval(%{{.*}}) align 4 %{{.*}}) 32 // CHECK-NOT: call 33 // CHECK: } 34 35 struct B { 36 virtual ~B(); 37 void operator delete(B*, std::destroying_delete_t); 38 }; 39 void delete_B(B *b) { delete b; } 40 // CHECK-LABEL: define {{.*}}delete_B 41 // CHECK: %[[b:.*]] = load 42 // CHECK: icmp eq %{{.*}} %[[b]], null 43 // CHECK: br i1 44 // 45 // Ensure that we call the virtual destructor and not the operator delete. 46 // CHECK-NOT: call 47 // CHECK: %[[VTABLE:.*]] = load 48 // CHECK: %[[DTOR:.*]] = load 49 // CHECK: call {{void|noundef i8\*|x86_thiscallcc noundef i8\*}} %[[DTOR]](%{{.*}}* {{[^,]*}} %[[b]] 50 // CHECK-MSABI-SAME: , i32 noundef 1) 51 // CHECK-NOT: call 52 // CHECK: } 53 54 struct Padding { 55 virtual void f(); 56 }; 57 58 struct C : Padding, A {}; 59 void delete_C(C *c) { delete c; } 60 // Check that we perform a derived-to-base conversion on the parameter to 'operator delete'. 61 // CHECK-LABEL: define {{.*}}delete_C 62 // CHECK: %[[c:.*]] = load 63 // CHECK: icmp eq %{{.*}} %[[c]], null 64 // CHECK: br i1 65 // 66 // CHECK-64BIT: %[[base:.*]] = getelementptr {{.*}}, i64 8 67 // CHECK-32BIT: %[[base:.*]] = getelementptr {{.*}}, i32 4 68 // CHECK: %[[castbase:.*]] = bitcast {{.*}} %[[base]] 69 // 70 // CHECK: %[[a:.*]] = phi {{.*}} %[[castbase]] 71 // CHECK: icmp eq %{{.*}} %[[a]], null 72 // CHECK: br i1 73 // 74 // CHECK-NOT: call 75 // CHECK-ITANIUM: call void @_ZN1AdlEPS_St19destroying_delete_t(%{{.*}}* noundef %[[a]]) 76 // CHECK-MSABI64: call void @"??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* noundef %[[a]], i8 77 // CHECK-MSABI32: call void @"??3A@@SAXPAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* noundef %[[a]], %{{.*}}* noundef byval(%{{.*}}) align 4 %{{.*}}) 78 // CHECK-NOT: call 79 // CHECK: } 80 81 struct VDel { virtual ~VDel(); }; 82 struct D : Padding, VDel, B {}; 83 void delete_D(D *d) { delete d; } 84 // CHECK-LABEL: define {{.*}}delete_D 85 // CHECK: %[[d:.*]] = load 86 // CHECK: icmp eq %{{.*}} %[[d]], null 87 // CHECK: br i1 88 // 89 // CHECK-NOT: call 90 // For MS, we don't add a new vtable slot to the primary vtable for the virtual 91 // destructor. Instead we cast to the VDel base class. 92 // CHECK-MSABI: bitcast {{.*}} %[[d]] 93 // CHECK-MSABI64-NEXT: getelementptr {{.*}}, i64 8 94 // CHECK-MSABI32-NEXT: getelementptr {{.*}}, i32 4 95 // CHECK-MSABI-NEXT: %[[d:.*]] = bitcast i8* 96 // 97 // CHECK: %[[VTABLE:.*]] = load 98 // CHECK: %[[DTOR:.*]] = load 99 // 100 // CHECK: call {{void|noundef i8\*|x86_thiscallcc noundef i8\*}} %[[DTOR]](%{{.*}}* {{[^,]*}} %[[d]] 101 // CHECK-MSABI-SAME: , i32 noundef 1) 102 // CHECK-NOT: call 103 // CHECK: } 104 105 struct J { 106 J(); // might throw 107 void operator delete(J *, std::destroying_delete_t); 108 }; 109 110 // CHECK-ITANIUM-LABEL: define {{.*}}@_Z1j 111 // CHECK-MSABI-LABEL: define {{.*}}@"?j@@ 112 J *j() { 113 // CHECK-ITANIUM: invoke {{.*}}@_ZN1JC1Ev( 114 // CHECK-ITANIUM: call {{.*}}@_ZdlPv( 115 // CHECK-NOT: } 116 // CHECK-MSABI: invoke {{.*}}@"??0J@@Q{{AE|EAA}}@XZ"( 117 // CHECK-MSABI: call {{.*}}@"??3@YAXP{{E?}}AX@Z"( 118 return new J; 119 // CHECK: } 120 } 121 122 struct K { 123 K(); // might throw 124 void operator delete(void *); 125 void operator delete(K *, std::destroying_delete_t); 126 }; 127 128 // CHECK-ITANIUM-LABEL: define {{.*}}@_Z1k 129 // CHECK-MSABI-LABEL: define {{.*}}@"?k@@ 130 K *k() { 131 // CHECK-ITANIUM: invoke {{.*}}@_ZN1KC1Ev( 132 // CHECK-ITANIUM: call {{.*}}@_ZN1KdlEPv( 133 // CHECK-NOT: } 134 // CHECK-MSABI: invoke {{.*}}@"??0K@@Q{{AE|EAA}}@XZ"( 135 // CHECK-MSABI: call {{.*}}@"??3K@@SAXP{{E?}}AX@Z"( 136 return new K; 137 // CHECK: } 138 } 139 140 struct E { void *data; }; 141 struct F { void operator delete(F *, std::destroying_delete_t, std::size_t, std::align_val_t); void *data; }; 142 struct alignas(16) G : E, F { void *data; }; 143 144 void delete_G(G *g) { delete g; } 145 // CHECK-LABEL: define {{.*}}delete_G 146 // CHECK-NOT: call 147 // CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t(%{{.*}}* noundef %[[a]], i64 noundef 32, i64 noundef 16) 148 // CHECK-MSABI64: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"(%{{.*}}* noundef %[[a]], i8 {{[^,]*}}, i64 noundef 32, i64 noundef 16) 149 // CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"(%{{.*}}* noundef %[[a]], %{{.*}}* noundef byval(%{{.*}}) align 4 %{{.*}}, i32 noundef 16, i32 noundef 16) 150 // CHECK-NOT: call 151 // CHECK: } 152 153 void call_in_dtor(); 154 155 struct H : G { virtual ~H(); } h; 156 H::~H() { call_in_dtor(); } 157 // CHECK-ITANIUM-LABEL: define{{.*}} void @_ZN1HD0Ev( 158 // CHECK-ITANIUM-NOT: call 159 // CHECK-ITANIUM: getelementptr {{.*}}, i64 24 160 // CHECK-ITANIUM-NOT: call 161 // CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t({{.*}}, i64 noundef 48, i64 noundef 16) 162 // CHECK-ITANIUM-NOT: call 163 // CHECK-ITANIUM: } 164 165 // CHECK-MSABI64-LABEL: define {{.*}} @"??_GH@@UEAAPEAXI@Z"( 166 // CHECK-MSABI32-LABEL: define {{.*}} @"??_GH@@UAEPAXI@Z"( 167 // CHECK-MSABI-NOT: call{{ }} 168 // CHECK-MSABI: load i32 169 // CHECK-MSABI: icmp eq i32 {{.*}}, 0 170 // CHECK-MSABI: br i1 171 // 172 // CHECK-MSABI-NOT: call{{ }} 173 // CHECK-MSABI64: getelementptr {{.*}}, i64 24 174 // CHECK-MSABI32: getelementptr {{.*}}, i32 20 175 // CHECK-MSABI-NOT: call{{ }} 176 // CHECK-MSABI64: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 noundef 48, i64 noundef 16) 177 // CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"({{.*}}, i32 noundef 32, i32 noundef 16) 178 // CHECK-MSABI: br label %[[RETURN:.*]] 179 // 180 // CHECK-MSABI64: call void @"??1H@@UEAA@XZ"( 181 // CHECK-MSABI32: call x86_thiscallcc void @"??1H@@UAE@XZ"( 182 // CHECK-MSABI: br label %[[RETURN]] 183 // 184 // CHECK-MSABI: } 185 186 struct I : H { virtual ~I(); alignas(32) char buffer[32]; } i; 187 I::~I() { call_in_dtor(); } 188 // CHECK-ITANIUM-LABEL: define{{.*}} void @_ZN1ID0Ev( 189 // CHECK-ITANIUM-NOT: call 190 // CHECK-ITANIUM: getelementptr {{.*}}, i64 24 191 // CHECK-ITANIUM-NOT: call 192 // CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t({{.*}}, i64 noundef 96, i64 noundef 32) 193 // CHECK-ITANIUM-NOT: call 194 // CHECK-ITANIUM: } 195 196 // CHECK-MSABI64-LABEL: define {{.*}} @"??_GI@@UEAAPEAXI@Z"( 197 // CHECK-MSABI32-LABEL: define {{.*}} @"??_GI@@UAEPAXI@Z"( 198 // CHECK-MSABI-NOT: call{{ }} 199 // CHECK-MSABI: load i32 200 // CHECK-MSABI: icmp eq i32 {{.*}}, 0 201 // CHECK-MSABI: br i1 202 // 203 // CHECK-MSABI-NOT: call{{ }} 204 // CHECK-MSABI64: getelementptr {{.*}}, i64 24 205 // CHECK-MSABI32: getelementptr {{.*}}, i32 20 206 // CHECK-MSABI-NOT: call{{ }} 207 // CHECK-MSABI64: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 noundef 96, i64 noundef 32) 208 // CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"({{.*}}, i32 noundef 64, i32 noundef 32) 209 // CHECK-MSABI: br label %[[RETURN:.*]] 210 // 211 // CHECK-MSABI64: call void @"??1I@@UEAA@XZ"( 212 // CHECK-MSABI32: call x86_thiscallcc void @"??1I@@UAE@XZ"( 213 // CHECK-MSABI: br label %[[RETURN]] 214 // 215 // CHECK-MSABI: } 216