[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / Analysis / placement-new.cpp
blob766b11cf84c5feecc34de3a75cfc589a019a014c
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
8 #include "Inputs/system-header-simulator-cxx.h"
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;
16 namespace testArrayNew {
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;
22 } // namespace testArrayNew
24 namespace testBufferInOtherFun {
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;
29 void g() {
30 short buf; // expected-note {{'buf' declared without an initial value}}
31 f(&buf); // expected-note 2 {{}}
33 } // namespace testBufferInOtherFun
35 namespace testArrayBuffer {
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;
40 void g() {
41 char buf[2]; // expected-note {{'buf' initialized here}}
42 f(&buf); // expected-note 2 {{}}
44 } // namespace testArrayBuffer
46 namespace testGlobalPtrAsPlace {
47 void *gptr = nullptr;
48 short gs;
49 void f() {
50 gptr = &gs; // expected-note {{Value assigned to 'gptr'}}
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;
57 } // namespace testGlobalPtrAsPlace
59 namespace testRvalue {
60 short gs;
61 void *f() {
62 return &gs;
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;
68 } // namespace testRvalue
70 namespace testNoWarning {
71 void *f();
72 void g() {
73 long *lp = ::new (f()) long;
74 (void)lp;
76 } // namespace testNoWarning
78 namespace testPtrToArrayAsPlace {
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;
86 } // namespace testPtrToArrayAsPlace
88 namespace testPtrToArrayWithOffsetAsPlace {
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;
94 } // namespace testPtrToArrayWithOffsetAsPlace
96 namespace testZeroSize {
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;
102 } // namespace testZeroSize
104 namespace testNegativeSize {
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;
110 } // namespace testNegativeSize
112 namespace testHeapAllocatedBuffer {
113 void g2() {
114 char *buf = new char[2]; // expected-note {{'buf' initialized here}}
115 // FIXME: The message is misleading -- we should
116 // state that a pointer to an uninitialized value
117 // is stored.
118 // expected-note@-4{{Storing uninitialized value}}
119 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 {{}}
120 (void)lp;
122 } // namespace testHeapAllocatedBuffer
124 namespace testMultiDimensionalArray {
125 void f() {
126 char buf[2][3]; // expected-note {{'buf' initialized here}}
127 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 {{}}
128 (void)lp;
130 } // namespace testMultiDimensionalArray
132 namespace testMultiDimensionalArray2 {
133 void f() {
134 char buf[2][3]; // expected-note {{'buf' initialized here}}
135 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 {{}}
136 (void)lp;
138 } // namespace testMultiDimensionalArray2
140 namespace testMultiDimensionalArray3 {
141 void f() {
142 char buf[2][3]; // expected-note {{'buf' initialized here}}
143 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 {{}}
144 (void)lp;
146 } // namespace testMultiDimensionalArray3
148 namespace testHierarchy {
149 struct Base {
150 char a[2];
152 struct Derived : Base {
153 char x[2];
154 int y;
156 void f() {
157 Base b; // expected-note {{'b' initialized here}}
158 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 {{}}
159 (void)dp;
161 } // namespace testHierarchy
163 namespace testArrayTypesAllocation {
164 void f1() {
165 struct S {
166 short a;
169 // bad (not enough space).
170 const unsigned N = 32;
171 alignas(S) unsigned char buffer1[sizeof(S) * N]; // expected-note {{'buffer1' initialized here}}
172 ::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 {{}}
175 void f2() {
176 struct S {
177 short a;
180 // maybe ok but we need to warn.
181 const unsigned N = 32;
182 alignas(S) unsigned char buffer2[sizeof(S) * N + sizeof(int)]; // expected-note {{'buffer2' initialized here}}
183 ::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 {{}}
185 } // namespace testArrayTypesAllocation
187 namespace testStructAlign {
188 void f1() {
189 struct X {
190 char a[9];
191 } Xi; // expected-note {{'Xi' initialized here}}
193 // bad (struct X is aligned to char).
194 ::new (&Xi.a) long; // expected-warning{{Storage type is aligned to 1 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
197 void f2() {
198 struct X {
199 char a;
200 char b;
201 long c;
202 } Xi;
204 // ok (struct X is aligned to long).
205 ::new (&Xi.a) long;
208 void f3() {
209 struct X {
210 char a;
211 char b;
212 long c;
213 } Xi; // expected-note {{'Xi' initialized here}}
215 // bad (struct X is aligned to long but field 'b' is aligned to 1 because of its offset)
216 ::new (&Xi.b) long; // expected-warning{{Storage type is aligned to 1 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
219 void f4() {
220 struct X {
221 char a;
222 struct alignas(alignof(short)) Y {
223 char b;
224 char c;
225 } y;
226 long d;
227 } Xi; // expected-note {{'Xi' initialized here}}
229 // bad. 'b' is aligned to short
230 ::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 {{}}
233 void f5() {
234 short b[10]; // expected-note {{'b' initialized here}}
236 ::new (&b) long; // expected-warning{{Storage type is aligned to 2 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
239 void f6() {
240 short b[10]; // expected-note {{'b' initialized here}}
242 // bad (same as previous but checks ElementRegion case)
243 ::new (&b[0]) long; // expected-warning{{Storage type is aligned to 2 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
246 void f7() {
247 alignas(alignof(long)) short b[10];
249 // ok. aligned to long(ok). offset 4*2(ok)
250 ::new (&b[4]) long;
253 void f8() {
254 alignas(alignof(long)) short b[10]; // expected-note {{'b' initialized here}}
256 // ok. aligned to long(ok). offset 3*2(ok)
257 ::new (&b[3]) long; // expected-warning{{Storage type is aligned to 6 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
260 void f9() {
261 struct X {
262 char a;
263 alignas(alignof(long)) char b[20];
264 } Xi; // expected-note {{'Xi' initialized here}}
266 // ok. aligned to long(ok). offset 8*1(ok)
267 ::new (&Xi.b[8]) long;
269 // bad. aligned to long(ok). offset 1*1(ok)
270 ::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 {{}}
273 void f10() {
274 struct X {
275 char a[8];
276 alignas(2) char b;
277 } Xi; // expected-note {{'Xi' initialized here}}
279 // bad (struct X is aligned to 2).
280 ::new (&Xi.a) long; // expected-warning{{Storage type is aligned to 2 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}
283 void f11() {
284 struct X {
285 char a;
286 char b;
287 struct Y {
288 long c;
289 } d;
290 } Xi;
292 // ok (struct X is aligned to long).
293 ::new (&Xi.a) long;
296 void f12() {
297 struct alignas(alignof(long)) X {
298 char a;
299 char b;
300 } Xi;
302 // ok (struct X is aligned to long).
303 ::new (&Xi.a) long;
306 void test13() {
307 struct Y {
308 char a[10];
311 struct X {
312 Y b[10];
313 } Xi; // expected-note {{'Xi' initialized here}}
315 // bad. X,A are aligned to 'char'
316 ::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 {{}}
319 void test14() {
320 struct Y {
321 char a[10];
324 struct alignas(alignof(long)) X {
325 Y b[10];
326 } Xi;
328 // ok. X is aligned to 'long' and field 'a' goes with zero offset
329 ::new (&Xi.b[0].a) long;
332 void test15() {
333 struct alignas(alignof(long)) Y {
334 char a[10];
337 struct X {
338 Y b[10];
339 } Xi;
341 // ok. X is aligned to 'long' because it contains struct 'Y' which is aligned to 'long'
342 ::new (&Xi.b[0].a) long;
345 void test16() {
346 struct alignas(alignof(long)) Y {
347 char p;
348 char a[10];
351 struct X {
352 Y b[10];
353 } Xi; // expected-note {{'Xi' initialized here}}
355 // bad. aligned to long(ok). offset 1(bad)
356 ::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 {{}}
359 void test17() {
360 struct alignas(alignof(long)) Y {
361 char p;
362 char a[10];
365 struct X {
366 Y b[10];
367 } Xi;
369 // ok. aligned to long(ok). offset 1+7*1(ok)
370 ::new (&Xi.b[0].a[7]) long;
373 void test18() {
374 struct Y {
375 char p;
376 alignas(alignof(long)) char a[10];
379 struct X {
380 Y b[10];
381 } Xi; // expected-note {{'Xi' initialized here}}
383 // ok. aligned to long(ok). offset 8*1(ok)
384 ::new (&Xi.b[0].a[8]) long;
386 // bad. aligned to long(ok). offset 1(bad)
387 ::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 {{}}
390 void test19() {
391 struct Z {
392 char p;
393 char c[10];
396 struct Y {
397 char p;
398 Z b[10];
401 struct X {
402 Y a[10];
403 } Xi; // expected-note {{'Xi' initialized here}}
405 // bad. all structures X,Y,Z are aligned to char
406 ::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 {{}}
409 void test20() {
410 struct Z {
411 char p;
412 alignas(alignof(long)) char c[10];
415 struct Y {
416 char p;
417 Z b[10];
420 struct X {
421 Y a[10];
422 } Xi;
424 // ok. field 'c' is aligned to 'long'
425 ::new (&Xi.a[1].b[1].c) long;
428 void test21() {
429 struct Z {
430 char p;
431 char c[10];
434 struct Y {
435 char p;
436 Z b[10];
439 struct alignas(alignof(long)) X {
440 Y a[10];
441 } Xi; // expected-note {{'Xi' initialized here}}
443 // ok. aligned to long(ok). offset 1+7*1(ok)
444 ::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 {{}}
447 void test22() {
448 struct alignas(alignof(long)) Y {
449 char p;
450 char a[10][10];
453 struct X {
454 Y b[10];
455 } Xi; // expected-note {{'Xi' initialized here}}
457 // ok. aligned to long(ok). offset ok. 1(field 'a' offset) + 0*10(index '0' * first dimension size '10') + 7*1(index '7')
458 ::new (&Xi.b[0].a[0][7]) long;
460 // ok. aligned to long(ok). offset ok. 1(field 'a' offset) + 1*10(index '1' * first dimension size '10') + 5*1(index '5')
461 ::new (&Xi.b[0].a[1][5]) long;
463 // bad. aligned to long(ok). offset ok. 1(field 'a' offset) + 1*10(index '1' * first dimension size '10') + 6*1(index '5')
464 ::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 {{}}
467 } // namespace testStructAlign