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 };
delete_A(A * a)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(%{{.*}}* %[[a]])
30 // CHECK-MSABI64: call void @"??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* %[[a]], i8
31 // CHECK-MSABI32: call void @"??3A@@SAXPAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* %[[a]], %{{.*}}* 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 };
delete_B(B * b)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|i8\*|x86_thiscallcc i8\*}} %[[DTOR]](%{{.*}}* {{[^,]*}} %[[b]]
50 // CHECK-MSABI-SAME: , i32 1)
51 // CHECK-NOT: call
52 // CHECK: }
53 
54 struct Padding {
55   virtual void f();
56 };
57 
58 struct C : Padding, A {};
delete_C(C * c)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(%{{.*}}* %[[a]])
76 // CHECK-MSABI64: call void @"??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* %[[a]], i8
77 // CHECK-MSABI32: call void @"??3A@@SAXPAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* %[[a]], %{{.*}}* byval(%{{.*}}) align 4 %{{.*}})
78 // CHECK-NOT: call
79 // CHECK: }
80 
81 struct VDel { virtual ~VDel(); };
82 struct D : Padding, VDel, B {};
delete_D(D * d)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|i8\*|x86_thiscallcc i8\*}} %[[DTOR]](%{{.*}}* {{[^,]*}} %[[d]]
101 // CHECK-MSABI-SAME: , i32 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@@
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@@
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 
delete_G(G * g)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(%{{.*}}* %[[a]], i64 32, i64 16)
148 // CHECK-MSABI64: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"(%{{.*}}* %[[a]], i8 {{[^,]*}}, i64 32, i64 16)
149 // CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"(%{{.*}}* %[[a]], %{{.*}}* byval(%{{.*}}) align 4 %{{.*}}, i32 16, i32 16)
150 // CHECK-NOT: call
151 // CHECK: }
152 
153 void call_in_dtor();
154 
155 struct H : G { virtual ~H(); } 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 48, i64 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 48, i64 16)
177 // CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"({{.*}}, i32 32, i32 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;
~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 96, i64 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 96, i64 32)
208 // CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"({{.*}}, i32 64, i32 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