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