// RUN: %clang_analyze_cc1 -std=c++11 %s \ // RUN: -analyzer-checker=core \ // RUN: -analyzer-checker=cplusplus.NewDelete \ // RUN: -analyzer-checker=cplusplus.PlacementNew \ // RUN: -analyzer-output=text -verify \ // RUN: -triple x86_64-unknown-linux-gnu #include "Inputs/system-header-simulator-cxx.h" void f() { short s; // expected-note {{'s' declared without an initial value}} 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 {{}} (void)lp; } namespace testArrayNew { void f() { short s; // expected-note {{'s' declared without an initial value}} 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 {{}} (void)buf; } } // namespace testArrayNew namespace testBufferInOtherFun { void f(void *place) { 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 {{}} (void)lp; } void g() { short buf; // expected-note {{'buf' declared without an initial value}} f(&buf); // expected-note 2 {{}} } } // namespace testBufferInOtherFun namespace testArrayBuffer { void f(void *place) { 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 {{}} (void)lp; } void g() { char buf[2]; // expected-note {{'buf' initialized here}} f(&buf); // expected-note 2 {{}} } } // namespace testArrayBuffer namespace testGlobalPtrAsPlace { void *gptr = nullptr; short gs; void f() { gptr = &gs; // expected-note {{Value assigned to 'gptr'}} } void g() { f(); // expected-note 2 {{}} 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 {{}} (void)lp; } } // namespace testGlobalPtrAsPlace namespace testRvalue { short gs; void *f() { return &gs; } void g() { 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 {{}} (void)lp; } } // namespace testRvalue namespace testNoWarning { void *f(); void g() { long *lp = ::new (f()) long; (void)lp; } } // namespace testNoWarning namespace testPtrToArrayAsPlace { void f() { //char *st = new char [8]; char buf[3]; // expected-note {{'buf' initialized here}} void *st = buf; // expected-note {{'st' initialized here}} 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 {{}} (void)lp; } } // namespace testPtrToArrayAsPlace namespace testPtrToArrayWithOffsetAsPlace { void f() { int buf[3]; // expected-note {{'buf' initialized here}} 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 {{}} (void)lp; } } // namespace testPtrToArrayWithOffsetAsPlace namespace testZeroSize { void f() { int buf[3]; // expected-note {{'buf' initialized here}} 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 {{}} (void)lp; } } // namespace testZeroSize namespace testNegativeSize { void f() { int buf[3]; // expected-note {{'buf' initialized here}} 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 {{}} (void)lp; } } // namespace testNegativeSize namespace testHeapAllocatedBuffer { void g2() { char *buf = new char[2]; // expected-note {{'buf' initialized here}} 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 {{}} (void)lp; } } // namespace testHeapAllocatedBuffer namespace testMultiDimensionalArray { void f() { char buf[2][3]; // expected-note {{'buf' initialized here}} 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 {{}} (void)lp; } } // namespace testMultiDimensionalArray namespace testMultiDimensionalArray2 { void f() { char buf[2][3]; // expected-note {{'buf' initialized here}} 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 {{}} (void)lp; } } // namespace testMultiDimensionalArray2 namespace testMultiDimensionalArray3 { void f() { char buf[2][3]; // expected-note {{'buf' initialized here}} 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 {{}} (void)lp; } } // namespace testMultiDimensionalArray3 namespace testHierarchy { struct Base { char a[2]; }; struct Derived : Base { char x[2]; int y; }; void f() { Base b; // expected-note {{'b' initialized here}} 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 {{}} (void)dp; } } // namespace testHierarchy namespace testArrayTypesAllocation { void f1() { struct S { short a; }; // bad (not enough space). const unsigned N = 32; alignas(S) unsigned char buffer1[sizeof(S) * N]; // expected-note {{'buffer1' initialized here}} ::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 {{}} } void f2() { struct S { short a; }; // maybe ok but we need to warn. const unsigned N = 32; alignas(S) unsigned char buffer2[sizeof(S) * N + sizeof(int)]; // expected-note {{'buffer2' initialized here}} ::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 {{}} } } // namespace testArrayTypesAllocation namespace testStructAlign { void f1() { struct X { char a[9]; } Xi; // expected-note {{'Xi' initialized here}} // bad (struct X is aligned to char). ::new (&Xi.a) long; // expected-warning{{Storage type is aligned to 1 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}} } void f2() { struct X { char a; char b; long c; } Xi; // ok (struct X is aligned to long). ::new (&Xi.a) long; } void f3() { struct X { char a; char b; long c; } Xi; // expected-note {{'Xi' initialized here}} // bad (struct X is aligned to long but field 'b' is aligned to 1 because of its offset) ::new (&Xi.b) long; // expected-warning{{Storage type is aligned to 1 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}} } void f4() { struct X { char a; struct alignas(alignof(short)) Y { char b; char c; } y; long d; } Xi; // expected-note {{'Xi' initialized here}} // bad. 'b' is aligned to short ::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 {{}} } void f5() { short b[10]; // expected-note {{'b' initialized here}} ::new (&b) long; // expected-warning{{Storage type is aligned to 2 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}} } void f6() { short b[10]; // expected-note {{'b' initialized here}} // bad (same as previous but checks ElementRegion case) ::new (&b[0]) long; // expected-warning{{Storage type is aligned to 2 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}} } void f7() { alignas(alignof(long)) short b[10]; // ok. aligned to long(ok). offset 4*2(ok) ::new (&b[4]) long; } void f8() { alignas(alignof(long)) short b[10]; // expected-note {{'b' initialized here}} // ok. aligned to long(ok). offset 3*2(ok) ::new (&b[3]) long; // expected-warning{{Storage type is aligned to 6 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}} } void f9() { struct X { char a; alignas(alignof(long)) char b[20]; } Xi; // expected-note {{'Xi' initialized here}} // ok. aligned to long(ok). offset 8*1(ok) ::new (&Xi.b[8]) long; // bad. aligned to long(ok). offset 1*1(ok) ::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 {{}} } void f10() { struct X { char a[8]; alignas(2) char b; } Xi; // expected-note {{'Xi' initialized here}} // bad (struct X is aligned to 2). ::new (&Xi.a) long; // expected-warning{{Storage type is aligned to 2 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}} } void f11() { struct X { char a; char b; struct Y { long c; } d; } Xi; // ok (struct X is aligned to long). ::new (&Xi.a) long; } void f12() { struct alignas(alignof(long)) X { char a; char b; } Xi; // ok (struct X is aligned to long). ::new (&Xi.a) long; } void test13() { struct Y { char a[10]; }; struct X { Y b[10]; } Xi; // expected-note {{'Xi' initialized here}} // bad. X,A are aligned to 'char' ::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 {{}} } void test14() { struct Y { char a[10]; }; struct alignas(alignof(long)) X { Y b[10]; } Xi; // ok. X is aligned to 'long' and field 'a' goes with zero offset ::new (&Xi.b[0].a) long; } void test15() { struct alignas(alignof(long)) Y { char a[10]; }; struct X { Y b[10]; } Xi; // ok. X is aligned to 'long' because it contains struct 'Y' which is aligned to 'long' ::new (&Xi.b[0].a) long; } void test16() { struct alignas(alignof(long)) Y { char p; char a[10]; }; struct X { Y b[10]; } Xi; // expected-note {{'Xi' initialized here}} // bad. aligned to long(ok). offset 1(bad) ::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 {{}} } void test17() { struct alignas(alignof(long)) Y { char p; char a[10]; }; struct X { Y b[10]; } Xi; // ok. aligned to long(ok). offset 1+7*1(ok) ::new (&Xi.b[0].a[7]) long; } void test18() { struct Y { char p; alignas(alignof(long)) char a[10]; }; struct X { Y b[10]; } Xi; // expected-note {{'Xi' initialized here}} // ok. aligned to long(ok). offset 8*1(ok) ::new (&Xi.b[0].a[8]) long; // bad. aligned to long(ok). offset 1(bad) ::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 {{}} } void test19() { struct Z { char p; char c[10]; }; struct Y { char p; Z b[10]; }; struct X { Y a[10]; } Xi; // expected-note {{'Xi' initialized here}} // bad. all structures X,Y,Z are aligned to char ::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 {{}} } void test20() { struct Z { char p; alignas(alignof(long)) char c[10]; }; struct Y { char p; Z b[10]; }; struct X { Y a[10]; } Xi; // ok. field 'c' is aligned to 'long' ::new (&Xi.a[1].b[1].c) long; } void test21() { struct Z { char p; char c[10]; }; struct Y { char p; Z b[10]; }; struct alignas(alignof(long)) X { Y a[10]; } Xi; // expected-note {{'Xi' initialized here}} // ok. aligned to long(ok). offset 1+7*1(ok) ::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 {{}} } void test22() { struct alignas(alignof(long)) Y { char p; char a[10][10]; }; struct X { Y b[10]; } Xi; // expected-note {{'Xi' initialized here}} // ok. aligned to long(ok). offset ok. 1(field 'a' offset) + 0*10(index '0' * first dimension size '10') + 7*1(index '7') ::new (&Xi.b[0].a[0][7]) long; // ok. aligned to long(ok). offset ok. 1(field 'a' offset) + 1*10(index '1' * first dimension size '10') + 5*1(index '5') ::new (&Xi.b[0].a[1][5]) long; // bad. aligned to long(ok). offset ok. 1(field 'a' offset) + 1*10(index '1' * first dimension size '10') + 6*1(index '5') ::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 {{}} } } // namespace testStructAlign