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