brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.1 KiB · 50bbde2 Raw
488 lines · cpp
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-gnu7 8#include "Inputs/system-header-simulator-cxx.h"9 10void 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 16namespace testArrayNew {17void 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 testArrayNew23 24namespace testBufferInOtherFun {25void 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}29void g() {30  short buf; // expected-note {{'buf' declared without an initial value}}31  f(&buf);   // expected-note 2 {{}}32}33} // namespace testBufferInOtherFun34 35namespace testArrayBuffer {36void 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}40void g() {41  char buf[2]; // expected-note {{'buf' initialized here}}42  f(&buf);     // expected-note 2 {{}}43}44} // namespace testArrayBuffer45 46namespace testGlobalPtrAsPlace {47void *gptr = nullptr;48short gs;49void f() {50  gptr = &gs; // expected-note {{Value assigned to 'gptr'}}51}52void 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 testGlobalPtrAsPlace58 59namespace testRvalue {60short gs;61void *f() {62  return &gs;63}64void 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 testRvalue69 70namespace testNoWarning {71void *f();72void g() {73  long *lp = ::new (f()) long;74  (void)lp;75}76} // namespace testNoWarning77 78namespace testPtrToArrayAsPlace {79void 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 testPtrToArrayAsPlace87 88namespace testPtrToArrayWithOffsetAsPlace {89void 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 testPtrToArrayWithOffsetAsPlace95 96namespace testZeroSize {97void 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 testZeroSize103 104namespace testNegativeSize {105void 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 testNegativeSize111 112namespace testHeapAllocatedBuffer {113void g2() {114  char *buf = new char[2];     // expected-note {{'buf' initialized here}}115                               // FIXME: The message is misleading -- we should116                               // state that a pointer to an uninitialized value117                               // 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;121}122} // namespace testHeapAllocatedBuffer123 124namespace testMultiDimensionalArray {125void 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;129}130} // namespace testMultiDimensionalArray131 132namespace testMultiDimensionalArray2 {133void 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;137}138} // namespace testMultiDimensionalArray2139 140namespace testMultiDimensionalArray3 {141void 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;145}146} // namespace testMultiDimensionalArray3147 148namespace testHierarchy {149struct Base {150  char a[2];151};152struct Derived : Base {153  char x[2];154  int y;155};156void 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;160}161} // namespace testHierarchy162 163namespace testArrayTypesAllocation {164void f1() {165  struct S {166    short a;167  };168 169  // On some systems, (notably before MSVC 16.7), a non-allocating placement170  // array new could allocate more memory than the nominal size of the array.171 172  // Since CWG 2382 (implemented in MSVC 16.7), overhead was disallowed for non-allocating placement new.173  //  See:174  //    https://learn.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance?view=msvc-170175  //    https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1969r0.html#2382176 177  // However, as of 17.1, there is a regression when the type comes from a template178  // parameter where MSVC reintroduces overhead.179  //  See:180  //    https://developercommunity.visualstudio.com/t/10777485181  //    https://godbolt.org/z/E1z1Tsfvj182 183  // The checker doesn't warn here because this behavior only affects older184  // MSVC versions (<16.7) or certain specific versions (17.1).185  // Suppressing warnings avoids false positives on standard-compliant compilers186  // and modern MSVC versions, but users of affected MSVC versions should be187  // aware of potential buffer size issues.188 189  const unsigned N = 32;190  alignas(S) unsigned char buffer1[sizeof(S) * N]; 191  ::new (buffer1) S[N]; // no-warning: See comments above192}193 194void f2() {195  struct S {196    short a;197  };198 199  // On some systems, placement array new could allocate more memory than the nominal size of the array.200  // See the comment at f1() above for more details.201  const unsigned N = 32;202  alignas(S) unsigned char buffer2[sizeof(S) * N + sizeof(int)]; 203  ::new (buffer2) S[N]; // no-warning: See comments above204}205} // namespace testArrayTypesAllocation206 207namespace testStructAlign {208void f1() {209  struct X {210    char a[9];211  } Xi; // expected-note {{'Xi' initialized here}}212 213  // bad (struct X is aligned to char).214  ::new (&Xi.a) long; // expected-warning{{Storage type is aligned to 1 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}215}216 217void f2() {218  struct X {219    char a;220    char b;221    long c;222  } Xi;223 224  // ok (struct X is aligned to long).225  ::new (&Xi.a) long;226}227 228void f3() {229  struct X {230    char a;231    char b;232    long c;233  } Xi; // expected-note {{'Xi' initialized here}}234 235  // bad (struct X is aligned to long but field 'b' is aligned to 1 because of its offset)236  ::new (&Xi.b) long; // expected-warning{{Storage type is aligned to 1 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}237}238 239void f4() {240  struct X {241    char a;242    struct alignas(alignof(short)) Y {243      char b;244      char c;245    } y;246    long d;247  } Xi; // expected-note {{'Xi' initialized here}}248 249  // bad. 'b' is aligned to short250  ::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 {{}}251}252 253void f5() {254  short b[10]; // expected-note {{'b' initialized here}}255 256  ::new (&b) long; // expected-warning{{Storage type is aligned to 2 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}257}258 259void f6() {260  short b[10]; // expected-note {{'b' initialized here}}261 262  // bad (same as previous but checks ElementRegion case)263  ::new (&b[0]) long; // expected-warning{{Storage type is aligned to 2 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}264}265 266void f7() {267  alignas(alignof(long)) short b[10];268 269  // ok. aligned to long(ok). offset 4*2(ok)270  ::new (&b[4]) long;271}272 273void f8() {274  alignas(alignof(long)) short b[10]; // expected-note {{'b' initialized here}}275 276  // ok. aligned to long(ok). offset 3*2(ok)277  ::new (&b[3]) long; // expected-warning{{Storage type is aligned to 6 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}278}279 280void f9() {281  struct X {282    char a;283    alignas(alignof(long)) char b[20];284  } Xi; // expected-note {{'Xi' initialized here}}285 286  // ok. aligned to long(ok). offset 8*1(ok)287  ::new (&Xi.b[8]) long;288 289  // bad. aligned to long(ok). offset 1*1(ok)290  ::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 {{}}291}292 293void f10() {294  struct X {295    char a[8];296    alignas(2) char b;297  } Xi; // expected-note {{'Xi' initialized here}}298 299  // bad (struct X is aligned to 2).300  ::new (&Xi.a) long; // expected-warning{{Storage type is aligned to 2 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}}301}302 303void f11() {304  struct X {305    char a;306    char b;307    struct Y {308      long c;309    } d;310  } Xi;311 312  // ok (struct X is aligned to long).313  ::new (&Xi.a) long;314}315 316void f12() {317  struct alignas(alignof(long)) X {318    char a;319    char b;320  } Xi;321 322  // ok (struct X is aligned to long).323  ::new (&Xi.a) long;324}325 326void test13() {327  struct Y {328    char a[10];329  };330 331  struct X {332    Y b[10];333  } Xi; // expected-note {{'Xi' initialized here}}334 335  // bad. X,A are aligned to 'char'336  ::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 {{}}337}338 339void test14() {340  struct Y {341    char a[10];342  };343 344  struct alignas(alignof(long)) X {345    Y b[10];346  } Xi;347 348  // ok. X is aligned to 'long' and field 'a' goes with zero offset349  ::new (&Xi.b[0].a) long;350}351 352void test15() {353  struct alignas(alignof(long)) Y {354    char a[10];355  };356 357  struct X {358    Y b[10];359  } Xi;360 361  // ok. X is aligned to 'long' because it contains struct 'Y' which is aligned to 'long'362  ::new (&Xi.b[0].a) long;363}364 365void test16() {366  struct alignas(alignof(long)) Y {367    char p;368    char a[10];369  };370 371  struct X {372    Y b[10];373  } Xi; // expected-note {{'Xi' initialized here}}374 375  // bad. aligned to long(ok). offset 1(bad)376  ::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 {{}}377}378 379void test17() {380  struct alignas(alignof(long)) Y {381    char p;382    char a[10];383  };384 385  struct X {386    Y b[10];387  } Xi;388 389  // ok. aligned to long(ok). offset 1+7*1(ok)390  ::new (&Xi.b[0].a[7]) long;391}392 393void test18() {394  struct Y {395    char p;396    alignas(alignof(long)) char a[10];397  };398 399  struct X {400    Y b[10];401  } Xi; // expected-note {{'Xi' initialized here}}402 403  // ok. aligned to long(ok). offset 8*1(ok)404  ::new (&Xi.b[0].a[8]) long;405 406  // bad. aligned to long(ok). offset 1(bad)407  ::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 {{}}408}409 410void test19() {411  struct Z {412    char p;413    char c[10];414  };415 416  struct Y {417    char p;418    Z b[10];419  };420 421  struct X {422    Y a[10];423  } Xi; // expected-note {{'Xi' initialized here}}424 425  // bad. all structures X,Y,Z are aligned to char426  ::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 {{}}427}428 429void test20() {430  struct Z {431    char p;432    alignas(alignof(long)) char c[10];433  };434 435  struct Y {436    char p;437    Z b[10];438  };439 440  struct X {441    Y a[10];442  } Xi;443 444  // ok. field 'c' is aligned to 'long'445  ::new (&Xi.a[1].b[1].c) long;446}447 448void test21() {449  struct Z {450    char p;451    char c[10];452  };453 454  struct Y {455    char p;456    Z b[10];457  };458 459  struct alignas(alignof(long)) X {460    Y a[10];461  } Xi; // expected-note {{'Xi' initialized here}}462 463  // ok. aligned to long(ok). offset 1+7*1(ok)464  ::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 {{}}465}466 467void test22() {468  struct alignas(alignof(long)) Y {469    char p;470    char a[10][10];471  };472 473  struct X {474    Y b[10];475  } Xi; // expected-note {{'Xi' initialized here}}476 477  // ok. aligned to long(ok). offset ok. 1(field 'a' offset) + 0*10(index '0' * first dimension size '10') + 7*1(index '7')478  ::new (&Xi.b[0].a[0][7]) long;479 480  // ok. aligned to long(ok). offset ok. 1(field 'a' offset) + 1*10(index '1' * first dimension size '10') + 5*1(index '5')481  ::new (&Xi.b[0].a[1][5]) long;482 483  // bad. aligned to long(ok). offset ok. 1(field 'a' offset) + 1*10(index '1' * first dimension size '10') + 6*1(index '5')484  ::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 {{}}485}486 487} // namespace testStructAlign488