1 // Check that delete exprs call aligned (de)allocation functions if
2 // -faligned-allocation is passed in both C++11 and C++14.
3 // RUN: %clang_cc1 -std=c++11 -fexceptions -fsized-deallocation -faligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
4 // RUN: %clang_cc1 -std=c++14 -fexceptions -fsized-deallocation -faligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
5 // RUN: %clang_cc1 -std=c++1z -fexceptions -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
6 
7 // Check that we don't used aligned (de)allocation without -faligned-allocation or C++1z.
8 // RUN: %clang_cc1 -std=c++14 -DUNALIGNED -fexceptions %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED
9 // RUN: %clang_cc1 -std=c++1z -DUNALIGNED -fexceptions -fno-aligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED
10 
11 // CHECK-UNALIGNED-NOT: _Znwm_St11align_val_t
12 // CHECK-UNALIGNED-NOT: _Znam_St11align_val_t
13 // CHECK-UNALIGNED-NOT: _ZdlPv_St11align_val_t
14 // CHECK-UNALIGNED-NOT: _ZdaPv_St11align_val_t
15 // CHECK-UNALIGNED-NOT: _ZdlPvm_St11align_val_t
16 // CHECK-UNALIGNED-NOT: _ZdaPvm_St11align_val_t
17 
18 typedef decltype(sizeof(0)) size_t;
19 namespace std { enum class align_val_t : size_t {}; }
20 
21 #define OVERALIGNED alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2)
22 
23 // Global new and delete.
24 // ======================
25 struct OVERALIGNED A { A(); int n[128]; };
26 
27 // CHECK-LABEL: define {{.*}} @_Z2a0v()
28 // CHECK: %[[ALLOC:.*]] = call i8* @_ZnwmSt11align_val_t(i64 512, i64 32)
29 // CHECK: call void @_ZdlPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
30 void *a0() { return new A; }
31 
32 // CHECK-LABEL: define {{.*}} @_Z2a1l(
33 // CHECK: %[[ALLOC:.*]] = call i8* @_ZnamSt11align_val_t(i64 %{{.*}}, i64 32)
34 // No array cookie.
35 // CHECK-NOT: store
36 // CHECK: invoke void @_ZN1AC1Ev(
37 // CHECK: call void @_ZdaPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
38 void *a1(long n) { return new A[n]; }
39 
40 // CHECK-LABEL: define {{.*}} @_Z2a2P1A(
41 // CHECK: call void @_ZdlPvmSt11align_val_t(i8* %{{.*}}, i64 512, i64 32) #9
42 void a2(A *p) { delete p; }
43 
44 // CHECK-LABEL: define {{.*}} @_Z2a3P1A(
45 // CHECK: call void @_ZdaPvSt11align_val_t(i8* %{{.*}}, i64 32) #9
46 void a3(A *p) { delete[] p; }
47 
48 
49 // Class-specific usual new and delete.
50 // ====================================
51 struct OVERALIGNED B {
52   B();
53   // These are just a distraction. We should ignore them.
54   void *operator new(size_t);
55   void operator delete(void*, size_t);
56   void operator delete[](void*, size_t);
57 
58   void *operator new(size_t, std::align_val_t);
59   void operator delete(void*, std::align_val_t);
60   void operator delete[](void*, std::align_val_t);
61 
62   int n[128];
63 };
64 
65 // CHECK-LABEL: define {{.*}} @_Z2b0v()
66 // CHECK: %[[ALLOC:.*]] = call i8* @_ZN1BnwEmSt11align_val_t(i64 512, i64 32)
67 // CHECK: call void @_ZN1BdlEPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
68 void *b0() { return new B; }
69 
70 // CHECK-LABEL: define {{.*}} @_Z2b1l(
71 // CHECK: %[[ALLOC:.*]] = call i8* @_ZnamSt11align_val_t(i64 %{{.*}}, i64 32)
72 // No array cookie.
73 // CHECK-NOT: store
74 // CHECK: invoke void @_ZN1BC1Ev(
75 // CHECK: call void @_ZN1BdaEPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
76 void *b1(long n) { return new B[n]; }
77 
78 // CHECK-LABEL: define {{.*}} @_Z2b2P1B(
79 // CHECK: call void @_ZN1BdlEPvSt11align_val_t(i8* %{{.*}}, i64 32)
80 void b2(B *p) { delete p; }
81 
82 // CHECK-LABEL: define {{.*}} @_Z2b3P1B(
83 // CHECK: call void @_ZN1BdaEPvSt11align_val_t(i8* %{{.*}}, i64 32)
84 void b3(B *p) { delete[] p; }
85 
86 struct OVERALIGNED C {
87   C();
88   void *operator new[](size_t, std::align_val_t);
89   void operator delete[](void*, size_t, std::align_val_t);
90 
91   // It doesn't matter that we have an unaligned operator delete[] that doesn't
92   // want the size. What matters is that the aligned one does.
93   void operator delete[](void*);
94 };
95 
96 // This one has an array cookie.
97 // CHECK-LABEL: define {{.*}} @_Z2b4l(
98 // CHECK: call {{.*}} @llvm.umul.with.overflow{{.*}}i64 32
99 // CHECK: call {{.*}} @llvm.uadd.with.overflow{{.*}}i64 32
100 // CHECK: %[[ALLOC:.*]] = call i8* @_ZN1CnaEmSt11align_val_t(i64 %{{.*}}, i64 32)
101 // CHECK: store
102 // CHECK: call void @_ZN1CC1Ev(
103 //
104 // Note, we're still calling a placement allocation function, and there is no
105 // matching placement operator delete. =(
106 // FIXME: This seems broken.
107 // CHECK-NOT: call void @_ZN1CdaEPvmSt11align_val_t(
108 #ifndef UNALIGNED
109 void *b4(long n) { return new C[n]; }
110 #endif
111 
112 // CHECK-LABEL: define {{.*}} @_Z2b5P1C(
113 // CHECK: mul i64{{.*}} 32
114 // CHECK: add i64{{.*}} 32
115 // CHECK: call void @_ZN1CdaEPvmSt11align_val_t(
116 void b5(C *p) { delete[] p; }
117 
118 
119 // Global placement new.
120 // =====================
121 
122 struct Q { int n; } q;
123 void *operator new(size_t, Q);
124 void *operator new(size_t, std::align_val_t, Q);
125 void operator delete(void*, Q);
126 void operator delete(void*, std::align_val_t, Q);
127 
128 // CHECK-LABEL: define {{.*}} @_Z2c0v(
129 // CHECK: %[[ALLOC:.*]] = call i8* @_ZnwmSt11align_val_t1Q(i64 512, i64 32, i32 %
130 // CHECK: call void @_ZdlPvSt11align_val_t1Q(i8* %[[ALLOC]], i64 32, i32 %
131 void *c0() { return new (q) A; }
132 
133 
134 // Class-specific placement new.
135 // =============================
136 
137 struct OVERALIGNED D {
138   D();
139   void *operator new(size_t, Q);
140   void *operator new(size_t, std::align_val_t, Q);
141   void operator delete(void*, Q);
142   void operator delete(void*, std::align_val_t, Q);
143 };
144 
145 // CHECK-LABEL: define {{.*}} @_Z2d0v(
146 // CHECK: %[[ALLOC:.*]] = call i8* @_ZN1DnwEmSt11align_val_t1Q(i64 32, i64 32, i32 %
147 // CHECK: call void @_ZN1DdlEPvSt11align_val_t1Q(i8* %[[ALLOC]], i64 32, i32 %
148 void *d0() { return new (q) D; }
149 
150 
151 // Calling aligned new with placement syntax.
152 // ==========================================
153 
154 #ifndef UNALIGNED
155 // CHECK-LABEL: define {{.*}} @_Z2e0v(
156 // CHECK: %[[ALLOC:.*]] = call i8* @_ZnwmSt11align_val_t(i64 512, i64 5)
157 // CHECK: call void @_ZdlPvSt11align_val_t(i8* %[[ALLOC]], i64 5)
158 void *e0() { return new (std::align_val_t(5)) A; }
159 
160 // CHECK-LABEL: define {{.*}} @_Z2e1v(
161 // CHECK: %[[ALLOC:.*]] = call i8* @_ZN1BnwEmSt11align_val_t(i64 512, i64 5)
162 // CHECK: call void @_ZN1BdlEPvSt11align_val_t(i8* %[[ALLOC]], i64 5)
163 void *e1() { return new (std::align_val_t(5)) B; }
164 #endif
165 
166 // Variadic placement/non-placement allocation functions.
167 // ======================================================
168 
169 struct OVERALIGNED F {
170   F();
171   void *operator new(size_t, ...);
172   void operator delete(void*, ...);
173   int n[128];
174 };
175 
176 // CHECK-LABEL: define {{.*}} @_Z2f0v(
177 // CHECK: %[[ALLOC:.*]] = call i8* (i64, ...) @_ZN1FnwEmz(i64 512, i64 32)
178 // Non-placement allocation function, uses normal deallocation lookup which
179 // cares about whether a parameter has type std::align_val_t.
180 // CHECK: call void (i8*, ...) @_ZN1FdlEPvz(i8* %[[ALLOC]])
181 void *f0() { return new F; }
182 
183 // CHECK-LABEL: define {{.*}} @_Z2f1v(
184 // CHECK: %[[ALLOC:.*]] = call i8* (i64, ...) @_ZN1FnwEmz(i64 512, i64 32, i32 %
185 // Placement allocation function, uses placement deallocation matching, which
186 // passes same arguments and therefore includes alignment.
187 // CHECK: call void (i8*, ...) @_ZN1FdlEPvz(i8* %[[ALLOC]], i64 32, i32 %
188 void *f1() { return new (q) F; }
189 
190 struct OVERALIGNED G {
191   G();
192   void *operator new(size_t, std::align_val_t, ...);
193   void operator delete(void*, std::align_val_t, ...);
194   int n[128];
195 };
196 #ifndef UNALIGNED
197 // CHECK-LABEL: define {{.*}} @_Z2g0v
198 // CHECK: %[[ALLOC:.*]] = call i8* (i64, i64, ...) @_ZN1GnwEmSt11align_val_tz(i64 512, i64 32)
199 // CHECK: call void (i8*, i64, ...) @_ZN1GdlEPvSt11align_val_tz(i8* %[[ALLOC]], i64 32)
200 void *g0() { return new G; }
201 
202 // CHECK-LABEL: define {{.*}} @_Z2g1v
203 // CHECK: %[[ALLOC:.*]] = call i8* (i64, i64, ...) @_ZN1GnwEmSt11align_val_tz(i64 512, i64 32, i32 %
204 // CHECK: call void (i8*, i64, ...) @_ZN1GdlEPvSt11align_val_tz(i8* %[[ALLOC]], i64 32, i32 %
205 void *g1() { return new (q) G; }
206 #endif
207