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 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 { 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 { 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 } 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 { 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 } 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; 49 void f() { 50 gptr = &gs; // expected-note {{Value assigned to 'gptr'}} 51 } 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; 61 void *f() { 62 return &gs; 63 } 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(); 72 void g() { 73 long *lp = ::new (f()) long; 74 (void)lp; 75 } 76 } // namespace testNoWarning 77 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; 85 } 86 } // namespace testPtrToArrayAsPlace 87 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; 93 } 94 } // namespace testPtrToArrayWithOffsetAsPlace 95 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; 101 } 102 } // namespace testZeroSize 103 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; 109 } 110 } // namespace testNegativeSize 111 112 namespace testHeapAllocatedBuffer { 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 { 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 { 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 { 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 }; 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 { 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 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 { 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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