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
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
11 using size_t = decltype(sizeof(0));
12 enum class align_val_t
: size_t;
13 struct destroying_delete_t
{};
19 void operator delete(A
*, std::destroying_delete_t
);
21 void delete_A(A
*a
) { delete a
; }
22 // CHECK-LABEL: define {{.*}}delete_A
23 // CHECK: %[[a:.*]] = load
24 // CHECK: icmp eq ptr %[[a]], null
27 // Ensure that we call the destroying delete and not the destructor.
29 // CHECK-ITANIUM: call void @_ZN1AdlEPS_St19destroying_delete_t(ptr noundef %[[a]])
30 // CHECK-MSABI64: call void @"??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(ptr noundef %[[a]], i8
31 // CHECK-MSABI32: call void @"??3A@@SAXPAU0@Udestroying_delete_t@std@@@Z"(ptr noundef %[[a]], ptr noundef byval(%{{.*}}) align 4 %{{.*}})
37 void operator delete(B
*, std::destroying_delete_t
);
39 void delete_B(B
*b
) { delete b
; }
40 // CHECK-LABEL: define {{.*}}delete_B
41 // CHECK: %[[b:.*]] = load
42 // CHECK: icmp eq ptr %[[b]], null
45 // Ensure that we call the virtual destructor and not the operator delete.
47 // CHECK: %[[VTABLE:.*]] = load
48 // CHECK: %[[DTOR:.*]] = load
49 // CHECK: call {{void|noundef ptr|x86_thiscallcc noundef ptr}} %[[DTOR]](ptr {{[^,]*}} %[[b]]
50 // CHECK-MSABI-SAME: , i32 noundef 1)
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 ptr %[[c]], null
66 // CHECK-64BIT: %[[base:.*]] = getelementptr {{.*}}, i64 8
67 // CHECK-32BIT: %[[base:.*]] = getelementptr {{.*}}, i32 4
69 // CHECK: %[[a:.*]] = phi {{.*}} %[[base]]
70 // CHECK: icmp eq ptr %[[a]], null
74 // CHECK-ITANIUM: call void @_ZN1AdlEPS_St19destroying_delete_t(ptr noundef %[[a]])
75 // CHECK-MSABI64: call void @"??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(ptr noundef %[[a]], i8
76 // CHECK-MSABI32: call void @"??3A@@SAXPAU0@Udestroying_delete_t@std@@@Z"(ptr noundef %[[a]], ptr noundef byval(%{{.*}}) align 4 %{{.*}})
80 struct VDel
{ virtual ~VDel(); };
81 struct D
: Padding
, VDel
, B
{};
82 void delete_D(D
*d
) { delete d
; }
83 // CHECK-LABEL: define {{.*}}delete_D
84 // CHECK: %[[d:.*]] = load
85 // CHECK: icmp eq ptr %[[d]], null
89 // For MS, we don't add a new vtable slot to the primary vtable for the virtual
90 // destructor. Instead we cast to the VDel base class.
91 // CHECK-MSABI64: %[[d:.*]] = getelementptr {{.*}}, i64 8
92 // CHECK-MSABI32: %[[d:.*]] = getelementptr {{.*}}, i32 4
94 // CHECK: %[[VTABLE:.*]] = load
95 // CHECK: %[[DTOR:.*]] = load
97 // CHECK: call {{void|noundef ptr|x86_thiscallcc noundef ptr}} %[[DTOR]](ptr{{[^,]*}} %[[d]]
98 // CHECK-MSABI-SAME: , i32 noundef 1)
104 void operator delete(J
*, std::destroying_delete_t
);
107 // CHECK-ITANIUM-LABEL: define {{.*}}@_Z1j
108 // CHECK-MSABI-LABEL: define {{.*}}@"?j@@
110 // CHECK-ITANIUM: invoke {{.*}}@_ZN1JC1Ev(
111 // CHECK-ITANIUM: call {{.*}}@_ZdlPv(
113 // CHECK-MSABI: invoke {{.*}}@"??0J@@Q{{AE|EAA}}@XZ"(
114 // CHECK-MSABI: call {{.*}}@"??3@YAXP{{E?}}AX@Z"(
121 void operator delete(void *);
122 void operator delete(K
*, std::destroying_delete_t
);
125 // CHECK-ITANIUM-LABEL: define {{.*}}@_Z1k
126 // CHECK-MSABI-LABEL: define {{.*}}@"?k@@
128 // CHECK-ITANIUM: invoke {{.*}}@_ZN1KC1Ev(
129 // CHECK-ITANIUM: call {{.*}}@_ZN1KdlEPv(
131 // CHECK-MSABI: invoke {{.*}}@"??0K@@Q{{AE|EAA}}@XZ"(
132 // CHECK-MSABI: call {{.*}}@"??3K@@SAXP{{E?}}AX@Z"(
137 struct E
{ void *data
; };
138 struct F
{ void operator delete(F
*, std::destroying_delete_t
, std::size_t, std::align_val_t
); void *data
; };
139 struct alignas(16) G
: E
, F
{ void *data
; };
141 void delete_G(G
*g
) { delete g
; }
142 // CHECK-LABEL: define {{.*}}delete_G
144 // CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t(ptr noundef %[[a]], i64 noundef 32, i64 noundef 16)
145 // CHECK-MSABI64: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"(ptr noundef %[[a]], i8 {{[^,]*}}, i64 noundef 32, i64 noundef 16)
146 // CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"(ptr noundef %[[a]], ptr noundef byval(%{{.*}}) align 4 %{{.*}}, i32 noundef 16, i32 noundef 16)
152 struct H
: G
{ virtual ~H(); } h
;
153 H::~H() { call_in_dtor(); }
154 // CHECK-ITANIUM-LABEL: define{{.*}} void @_ZN1HD0Ev(
155 // CHECK-ITANIUM-NOT: call
156 // CHECK-ITANIUM: getelementptr {{.*}}, i64 24
157 // CHECK-ITANIUM-NOT: call
158 // CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t({{.*}}, i64 noundef 48, i64 noundef 16)
159 // CHECK-ITANIUM-NOT: call
162 // CHECK-MSABI64-LABEL: define {{.*}} @"??_GH@@UEAAPEAXI@Z"(
163 // CHECK-MSABI32-LABEL: define {{.*}} @"??_GH@@UAEPAXI@Z"(
164 // CHECK-MSABI-NOT: call{{ }}
165 // CHECK-MSABI: load i32
166 // CHECK-MSABI: icmp eq i32 {{.*}}, 0
167 // CHECK-MSABI: br i1
169 // CHECK-MSABI-NOT: call{{ }}
170 // CHECK-MSABI64: getelementptr {{.*}}, i64 24
171 // CHECK-MSABI32: getelementptr {{.*}}, i32 20
172 // CHECK-MSABI-NOT: call{{ }}
173 // CHECK-MSABI64: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 noundef 48, i64 noundef 16)
174 // CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"({{.*}}, i32 noundef 32, i32 noundef 16)
175 // CHECK-MSABI: br label %[[RETURN:.*]]
177 // CHECK-MSABI64: call void @"??1H@@UEAA@XZ"(
178 // CHECK-MSABI32: call x86_thiscallcc void @"??1H@@UAE@XZ"(
179 // CHECK-MSABI: br label %[[RETURN]]
183 struct I
: H
{ virtual ~I(); alignas(32) char buffer
[32]; } i
;
184 I::~I() { call_in_dtor(); }
185 // CHECK-ITANIUM-LABEL: define{{.*}} void @_ZN1ID0Ev(
186 // CHECK-ITANIUM-NOT: call
187 // CHECK-ITANIUM: getelementptr {{.*}}, i64 24
188 // CHECK-ITANIUM-NOT: call
189 // CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t({{.*}}, i64 noundef 96, i64 noundef 32)
190 // CHECK-ITANIUM-NOT: call
193 // CHECK-MSABI64-LABEL: define {{.*}} @"??_GI@@UEAAPEAXI@Z"(
194 // CHECK-MSABI32-LABEL: define {{.*}} @"??_GI@@UAEPAXI@Z"(
195 // CHECK-MSABI-NOT: call{{ }}
196 // CHECK-MSABI: load i32
197 // CHECK-MSABI: icmp eq i32 {{.*}}, 0
198 // CHECK-MSABI: br i1
200 // CHECK-MSABI-NOT: call{{ }}
201 // CHECK-MSABI64: getelementptr {{.*}}, i64 24
202 // CHECK-MSABI32: getelementptr {{.*}}, i32 20
203 // CHECK-MSABI-NOT: call{{ }}
204 // CHECK-MSABI64: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 noundef 96, i64 noundef 32)
205 // CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"({{.*}}, i32 noundef 64, i32 noundef 32)
206 // CHECK-MSABI: br label %[[RETURN:.*]]
208 // CHECK-MSABI64: call void @"??1I@@UEAA@XZ"(
209 // CHECK-MSABI32: call x86_thiscallcc void @"??1I@@UAE@XZ"(
210 // CHECK-MSABI: br label %[[RETURN]]