1 // RUN: %clang_analyze_cc1 -std=c++11 %s \
2 // RUN: -analyzer-checker=core \
3 // RUN: -analyzer-checker=cplusplus.NewDelete \
4 // RUN: -analyzer-checker=cplusplus.PlacementNew \
5 // RUN: -analyzer-output=text -verify \
6 // RUN: -triple x86_64-unknown-linux-gnu
7
8 #include "Inputs/system-header-simulator-cxx.h"
9
f()10 void f() {
11 short s; // expected-note {{'s' declared without an initial value}}
12 long *lp = ::new (&s) long; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 3 {{}}
13 (void)lp;
14 }
15
16 namespace testArrayNew {
f()17 void f() {
18 short s; // expected-note {{'s' declared without an initial value}}
19 char *buf = ::new (&s) char[8]; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 3 {{}}
20 (void)buf;
21 }
22 } // namespace testArrayNew
23
24 namespace testBufferInOtherFun {
f(void * place)25 void f(void *place) {
26 long *lp = ::new (place) long; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
27 (void)lp;
28 }
g()29 void g() {
30 short buf; // expected-note {{'buf' declared without an initial value}}
31 f(&buf); // expected-note 2 {{}}
32 }
33 } // namespace testBufferInOtherFun
34
35 namespace testArrayBuffer {
f(void * place)36 void f(void *place) {
37 long *lp = ::new (place) long; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
38 (void)lp;
39 }
g()40 void g() {
41 char buf[2]; // expected-note {{'buf' initialized here}}
42 f(&buf); // expected-note 2 {{}}
43 }
44 } // namespace testArrayBuffer
45
46 namespace testGlobalPtrAsPlace {
47 void *gptr = nullptr;
48 short gs;
f()49 void f() {
50 gptr = &gs; // expected-note {{Value assigned to 'gptr'}}
51 }
g()52 void g() {
53 f(); // expected-note 2 {{}}
54 long *lp = ::new (gptr) long; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
55 (void)lp;
56 }
57 } // namespace testGlobalPtrAsPlace
58
59 namespace testRvalue {
60 short gs;
f()61 void *f() {
62 return &gs;
63 }
g()64 void g() {
65 long *lp = ::new (f()) long; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
66 (void)lp;
67 }
68 } // namespace testRvalue
69
70 namespace testNoWarning {
71 void *f();
g()72 void g() {
73 long *lp = ::new (f()) long;
74 (void)lp;
75 }
76 } // namespace testNoWarning
77
78 namespace testPtrToArrayAsPlace {
f()79 void f() {
80 //char *st = new char [8];
81 char buf[3]; // expected-note {{'buf' initialized here}}
82 void *st = buf; // expected-note {{'st' initialized here}}
83 long *lp = ::new (st) long; // expected-warning{{Storage provided to placement new is only 3 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
84 (void)lp;
85 }
86 } // namespace testPtrToArrayAsPlace
87
88 namespace testPtrToArrayWithOffsetAsPlace {
f()89 void f() {
90 int buf[3]; // expected-note {{'buf' initialized here}}
91 long *lp = ::new (buf + 2) long; // expected-warning{{Storage provided to placement new is only 4 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
92 (void)lp;
93 }
94 } // namespace testPtrToArrayWithOffsetAsPlace
95
96 namespace testZeroSize {
f()97 void f() {
98 int buf[3]; // expected-note {{'buf' initialized here}}
99 long *lp = ::new (buf + 3) long; // expected-warning{{Storage provided to placement new is only 0 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
100 (void)lp;
101 }
102 } // namespace testZeroSize
103
104 namespace testNegativeSize {
f()105 void f() {
106 int buf[3]; // expected-note {{'buf' initialized here}}
107 long *lp = ::new (buf + 4) long; // expected-warning{{Storage provided to placement new is only -4 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
108 (void)lp;
109 }
110 } // namespace testNegativeSize
111
112 namespace testHeapAllocatedBuffer {
g2()113 void g2() {
114 char *buf = new char[2]; // expected-note {{'buf' initialized here}}
115 long *lp = ::new (buf) long; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
116 (void)lp;
117 }
118 } // namespace testHeapAllocatedBuffer
119
120 namespace testMultiDimensionalArray {
f()121 void f() {
122 char buf[2][3]; // expected-note {{'buf' initialized here}}
123 long *lp = ::new (buf) long; // expected-warning{{Storage provided to placement new is only 6 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
124 (void)lp;
125 }
126 } // namespace testMultiDimensionalArray
127
128 namespace testMultiDimensionalArray2 {
f()129 void f() {
130 char buf[2][3]; // expected-note {{'buf' initialized here}}
131 long *lp = ::new (buf + 1) long; // expected-warning{{Storage provided to placement new is only 3 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
132 (void)lp;
133 }
134 } // namespace testMultiDimensionalArray2
135
136 namespace testMultiDimensionalArray3 {
f()137 void f() {
138 char buf[2][3]; // expected-note {{'buf' initialized here}}
139 long *lp = ::new (&buf[1][1]) long; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
140 (void)lp;
141 }
142 } // namespace testMultiDimensionalArray3
143
144 namespace testHierarchy {
145 struct Base {
146 char a[2];
147 };
148 struct Derived : Base {
149 char x[2];
150 int y;
151 };
f()152 void f() {
153 Base b; // expected-note {{'b' initialized here}}
154 Derived *dp = ::new (&b) Derived; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
155 (void)dp;
156 }
157 } // namespace testHierarchy
158
159 namespace testArrayTypesAllocation {
f1()160 void f1() {
161 struct S {
162 short a;
163 };
164
165 // bad (not enough space).
166 const unsigned N = 32;
167 alignas(S) unsigned char buffer1[sizeof(S) * N]; // expected-note {{'buffer1' initialized here}}
168 ::new (buffer1) S[N]; // expected-warning{{Storage provided to placement new is only 64 bytes, whereas the allocated array type requires more space for internal needs}} expected-note 1 {{}}
169 }
170
f2()171 void f2() {
172 struct S {
173 short a;
174 };
175
176 // maybe ok but we need to warn.
177 const unsigned N = 32;
178 alignas(S) unsigned char buffer2[sizeof(S) * N + sizeof(int)]; // expected-note {{'buffer2' initialized here}}
179 ::new (buffer2) S[N]; // expected-warning{{68 bytes is possibly not enough for array allocation which requires 64 bytes. Current overhead requires the size of 4 bytes}} expected-note 1 {{}}
180 }
181 } // namespace testArrayTypesAllocation
182
183 namespace testStructAlign {
f1()184 void f1() {
185 struct X {
186 char a[9];
187 } Xi; // expected-note {{'Xi' initialized here}}
188
189 // bad (struct X is aligned to char).
190 ::new (&Xi.a) long; // expected-warning{{Storage type is aligned to 1 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
191 }
192
f2()193 void f2() {
194 struct X {
195 char a;
196 char b;
197 long c;
198 } Xi;
199
200 // ok (struct X is aligned to long).
201 ::new (&Xi.a) long;
202 }
203
f3()204 void f3() {
205 struct X {
206 char a;
207 char b;
208 long c;
209 } Xi; // expected-note {{'Xi' initialized here}}
210
211 // bad (struct X is aligned to long but field 'b' is aligned to 1 because of its offset)
212 ::new (&Xi.b) long; // expected-warning{{Storage type is aligned to 1 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
213 }
214
f4()215 void f4() {
216 struct X {
217 char a;
218 struct alignas(alignof(short)) Y {
219 char b;
220 char c;
221 } y;
222 long d;
223 } Xi; // expected-note {{'Xi' initialized here}}
224
225 // bad. 'b' is aligned to short
226 ::new (&Xi.y.b) long; // expected-warning{{Storage type is aligned to 2 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
227 }
228
f5()229 void f5() {
230 short b[10]; // expected-note {{'b' initialized here}}
231
232 ::new (&b) long; // expected-warning{{Storage type is aligned to 2 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
233 }
234
f6()235 void f6() {
236 short b[10]; // expected-note {{'b' initialized here}}
237
238 // bad (same as previous but checks ElementRegion case)
239 ::new (&b[0]) long; // expected-warning{{Storage type is aligned to 2 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
240 }
241
f7()242 void f7() {
243 alignas(alignof(long)) short b[10];
244
245 // ok. aligned to long(ok). offset 4*2(ok)
246 ::new (&b[4]) long;
247 }
248
f8()249 void f8() {
250 alignas(alignof(long)) short b[10]; // expected-note {{'b' initialized here}}
251
252 // ok. aligned to long(ok). offset 3*2(ok)
253 ::new (&b[3]) long; // expected-warning{{Storage type is aligned to 6 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
254 }
255
f9()256 void f9() {
257 struct X {
258 char a;
259 alignas(alignof(long)) char b[20];
260 } Xi; // expected-note {{'Xi' initialized here}}
261
262 // ok. aligned to long(ok). offset 8*1(ok)
263 ::new (&Xi.b[8]) long;
264
265 // bad. aligned to long(ok). offset 1*1(ok)
266 ::new (&Xi.b[1]) long; // expected-warning{{Storage type is aligned to 1 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
267 }
268
f10()269 void f10() {
270 struct X {
271 char a[8];
272 alignas(2) char b;
273 } Xi; // expected-note {{'Xi' initialized here}}
274
275 // bad (struct X is aligned to 2).
276 ::new (&Xi.a) long; // expected-warning{{Storage type is aligned to 2 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
277 }
278
f11()279 void f11() {
280 struct X {
281 char a;
282 char b;
283 struct Y {
284 long c;
285 } d;
286 } Xi;
287
288 // ok (struct X is aligned to long).
289 ::new (&Xi.a) long;
290 }
291
f12()292 void f12() {
293 struct alignas(alignof(long)) X {
294 char a;
295 char b;
296 } Xi;
297
298 // ok (struct X is aligned to long).
299 ::new (&Xi.a) long;
300 }
301
test13()302 void test13() {
303 struct Y {
304 char a[10];
305 };
306
307 struct X {
308 Y b[10];
309 } Xi; // expected-note {{'Xi' initialized here}}
310
311 // bad. X,A are aligned to 'char'
312 ::new (&Xi.b[0].a) long; // expected-warning{{Storage type is aligned to 1 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
313 }
314
test14()315 void test14() {
316 struct Y {
317 char a[10];
318 };
319
320 struct alignas(alignof(long)) X {
321 Y b[10];
322 } Xi;
323
324 // ok. X is aligned to 'long' and field 'a' goes with zero offset
325 ::new (&Xi.b[0].a) long;
326 }
327
test15()328 void test15() {
329 struct alignas(alignof(long)) Y {
330 char a[10];
331 };
332
333 struct X {
334 Y b[10];
335 } Xi;
336
337 // ok. X is aligned to 'long' because it contains struct 'Y' which is aligned to 'long'
338 ::new (&Xi.b[0].a) long;
339 }
340
test16()341 void test16() {
342 struct alignas(alignof(long)) Y {
343 char p;
344 char a[10];
345 };
346
347 struct X {
348 Y b[10];
349 } Xi; // expected-note {{'Xi' initialized here}}
350
351 // bad. aligned to long(ok). offset 1(bad)
352 ::new (&Xi.b[0].a) long; // expected-warning{{Storage type is aligned to 1 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
353 }
354
test17()355 void test17() {
356 struct alignas(alignof(long)) Y {
357 char p;
358 char a[10];
359 };
360
361 struct X {
362 Y b[10];
363 } Xi;
364
365 // ok. aligned to long(ok). offset 1+7*1(ok)
366 ::new (&Xi.b[0].a[7]) long;
367 }
368
test18()369 void test18() {
370 struct Y {
371 char p;
372 alignas(alignof(long)) char a[10];
373 };
374
375 struct X {
376 Y b[10];
377 } Xi; // expected-note {{'Xi' initialized here}}
378
379 // ok. aligned to long(ok). offset 8*1(ok)
380 ::new (&Xi.b[0].a[8]) long;
381
382 // bad. aligned to long(ok). offset 1(bad)
383 ::new (&Xi.b[0].a[1]) long; // expected-warning{{Storage type is aligned to 1 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
384 }
385
test19()386 void test19() {
387 struct Z {
388 char p;
389 char c[10];
390 };
391
392 struct Y {
393 char p;
394 Z b[10];
395 };
396
397 struct X {
398 Y a[10];
399 } Xi; // expected-note {{'Xi' initialized here}}
400
401 // bad. all structures X,Y,Z are aligned to char
402 ::new (&Xi.a[1].b[1].c) long; // expected-warning{{Storage type is aligned to 1 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
403 }
404
test20()405 void test20() {
406 struct Z {
407 char p;
408 alignas(alignof(long)) char c[10];
409 };
410
411 struct Y {
412 char p;
413 Z b[10];
414 };
415
416 struct X {
417 Y a[10];
418 } Xi;
419
420 // ok. field 'c' is aligned to 'long'
421 ::new (&Xi.a[1].b[1].c) long;
422 }
423
test21()424 void test21() {
425 struct Z {
426 char p;
427 char c[10];
428 };
429
430 struct Y {
431 char p;
432 Z b[10];
433 };
434
435 struct alignas(alignof(long)) X {
436 Y a[10];
437 } Xi; // expected-note {{'Xi' initialized here}}
438
439 // ok. aligned to long(ok). offset 1+7*1(ok)
440 ::new (&Xi.a[0].b[0].c[7]) long; // expected-warning{{Storage type is aligned to 1 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
441 }
442
test22()443 void test22() {
444 struct alignas(alignof(long)) Y {
445 char p;
446 char a[10][10];
447 };
448
449 struct X {
450 Y b[10];
451 } Xi; // expected-note {{'Xi' initialized here}}
452
453 // ok. aligned to long(ok). offset ok. 1(field 'a' offset) + 0*10(index '0' * first dimension size '10') + 7*1(index '7')
454 ::new (&Xi.b[0].a[0][7]) long;
455
456 // ok. aligned to long(ok). offset ok. 1(field 'a' offset) + 1*10(index '1' * first dimension size '10') + 5*1(index '5')
457 ::new (&Xi.b[0].a[1][5]) long;
458
459 // bad. aligned to long(ok). offset ok. 1(field 'a' offset) + 1*10(index '1' * first dimension size '10') + 6*1(index '5')
460 ::new (&Xi.b[0].a[1][6]) long; // expected-warning{{Storage type is aligned to 1 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
461 }
462
463 } // namespace testStructAlign
464