661 lines · cpp
1// RUN: %clang_analyze_cc1 -w -verify %s\2// RUN: -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks\3// RUN: -analyzer-checker=debug.ExprInspection -std=c++114// RUN: %clang_analyze_cc1 -w -verify %s\5// RUN: -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks\6// RUN: -analyzer-checker=debug.ExprInspection -std=c++177// RUN: %clang_analyze_cc1 -w -verify %s\8// RUN: -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks\9// RUN: -analyzer-checker=debug.ExprInspection -std=c++11\10// RUN: -DTEST_INLINABLE_ALLOCATORS11// RUN: %clang_analyze_cc1 -w -verify %s\12// RUN: -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks\13// RUN: -analyzer-checker=debug.ExprInspection -std=c++17\14// RUN: -DTEST_INLINABLE_ALLOCATORS15 16void clang_analyzer_eval(bool);17 18#include "Inputs/system-header-simulator-cxx.h"19 20class A {21 int x;22public:23 A();24};25 26A::A() : x(0) {27 clang_analyzer_eval(x == 0); // expected-warning{{TRUE}}28}29 30 31class DirectMember {32 int x;33public:34 DirectMember(int value) : x(value) {}35 36 int getX() { return x; }37};38 39void testDirectMember() {40 DirectMember obj(3);41 clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}}42}43 44 45class IndirectMember {46 struct {47 int x;48 };49public:50 IndirectMember(int value) : x(value) {}51 52 int getX() { return x; }53};54 55void testIndirectMember() {56 IndirectMember obj(3);57 clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}}58}59 60 61struct DelegatingConstructor {62 int x;63 DelegatingConstructor(int y) { x = y; }64 DelegatingConstructor() : DelegatingConstructor(42) {}65};66 67void testDelegatingConstructor() {68 DelegatingConstructor obj;69 clang_analyzer_eval(obj.x == 42); // expected-warning{{TRUE}}70}71 72 73struct RefWrapper {74 RefWrapper(int *p) : x(*p) {}75 RefWrapper(int &r) : x(r) {}76 int &x;77};78 79void testReferenceMember() {80 int *p = 0;81 RefWrapper X(p); // expected-warning@-7 {{Dereference of null pointer}}82}83 84void testReferenceMember2() {85 int *p = 0;86 RefWrapper X(*p); // expected-warning {{Forming reference to null pointer}}87}88 89 90extern "C" char *strdup(const char *);91 92class StringWrapper {93 char *str;94public:95 StringWrapper(const char *input) : str(strdup(input)) {} // no-warning96};97 98 99// PR15070 - Constructing a type containing a non-POD array mistakenly100// tried to perform a bind instead of relying on the CXXConstructExpr,101// which caused a cast<> failure in RegionStore.102namespace DefaultConstructorWithCleanups {103 class Element {104 public:105 int value;106 107 class Helper {108 public:109 ~Helper();110 };111 Element(Helper h = Helper());112 };113 class Wrapper {114 public:115 Element arr[2];116 117 Wrapper();118 };119 120 Wrapper::Wrapper() /* initializers synthesized */ {}121 122 int test() {123 Wrapper w;124 return w.arr[0].value; // no-warning125 }126}127 128namespace DefaultMemberInitializers {129 struct Wrapper {130 int value = 42;131 132 Wrapper() {}133 Wrapper(int x) : value(x) {}134 Wrapper(bool) {}135 };136 137 void test() {138 Wrapper w1;139 clang_analyzer_eval(w1.value == 42); // expected-warning{{TRUE}}140 141 Wrapper w2(50);142 clang_analyzer_eval(w2.value == 50); // expected-warning{{TRUE}}143 144 Wrapper w3(false);145 clang_analyzer_eval(w3.value == 42); // expected-warning{{TRUE}}146 }147 148 struct StringWrapper {149 const char s[4] = "abc";150 const char *p = "xyz";151 152 StringWrapper(bool) {}153 };154 155 void testString() {156 StringWrapper w(true);157 clang_analyzer_eval(w.s[1] == 'b'); // expected-warning{{TRUE}}158 clang_analyzer_eval(w.p[1] == 'y'); // expected-warning{{TRUE}}159 }160}161 162namespace ReferenceInitialization {163 struct OtherStruct {164 OtherStruct(int i);165 ~OtherStruct();166 };167 168 struct MyStruct {169 MyStruct(int i);170 MyStruct(OtherStruct os);171 172 void method() const;173 };174 175 void referenceInitializeLocal() {176 const MyStruct &myStruct(5);177 myStruct.method(); // no-warning178 }179 180 void referenceInitializeMultipleLocals() {181 const MyStruct &myStruct1(5), myStruct2(5), &myStruct3(5);182 myStruct1.method(); // no-warning183 myStruct2.method(); // no-warning184 myStruct3.method(); // no-warning185 }186 187 void referenceInitializeLocalWithCleanup() {188 const MyStruct &myStruct(OtherStruct(5));189 myStruct.method(); // no-warning190 }191};192 193namespace PR31592 {194struct C {195 C() : f("}") { } // no-crash196 const char(&f)[2];197};198}199 200namespace CXX_initializer_lists {201struct C {202 C(std::initializer_list<int *> list);203};204void testPointerEscapeIntoLists() {205 C empty{}; // no-crash206 207 // Do not warn that 'x' leaks. It might have been deleted by208 // the destructor of 'c'.209 int *x = new int;210 C c{x}; // no-warning211}212 213void testPassListsWithExplicitConstructors() {214 (void)(std::initializer_list<int>){12}; // no-crash215}216}217 218namespace CXX17_aggregate_construction {219struct A {220 A();221};222 223struct B: public A {224};225 226struct C: public B {227};228 229struct D: public virtual A {230};231 232// In C++17, classes B and C are aggregates, so they will be constructed233// without actually calling their trivial constructor. Used to crash.234void foo() {235 B b = {}; // no-crash236 const B &bl = {}; // no-crash237 B &&br = {}; // no-crash238 239 C c = {}; // no-crash240 const C &cl = {}; // no-crash241 C &&cr = {}; // no-crash242 243 D d = {}; // no-crash244 245#if __cplusplus >= 201703L246 C cd = {{}}; // no-crash247 const C &cdl = {{}}; // no-crash248 C &&cdr = {{}}; // no-crash249 250 const B &bll = {{}}; // no-crash251 const B &bcl = C({{}}); // no-crash252 B &&bcr = C({{}}); // no-crash253#endif254}255} // namespace CXX17_aggregate_construction256 257namespace newexpr_init_list_initialization {258template <class FirstT, class... Rest>259void escape(FirstT first, Rest... args);260 261struct S {262 int foo;263 int bar;264};265void none_designated() {266 S *s = new S{13,1};267 clang_analyzer_eval(13 == s->foo); // expected-warning{{TRUE}}268 clang_analyzer_eval(1 == s->bar); // expected-warning{{TRUE}}269 delete s;270}271void none_designated_swapped() {272 S *s = new S{1,13};273 clang_analyzer_eval(1 == s->foo); // expected-warning{{TRUE}}274 clang_analyzer_eval(13 == s->bar); // expected-warning{{TRUE}}275 delete s;276}277void one_designated_one_not() {278 S *s = new S{ 1, .bar = 13 };279 clang_analyzer_eval(1 == s->foo); // expected-warning{{TRUE}}280 clang_analyzer_eval(13 == s->bar); // expected-warning{{TRUE}}281 delete s;282}283void all_designated() {284 S *s = new S{285 .foo = 13,286 .bar = 1,287 };288 clang_analyzer_eval(13 == s->foo); // expected-warning{{TRUE}}289 clang_analyzer_eval(1 == s->bar); // expected-warning{{TRUE}}290 delete s;291}292void non_designated_array_of_aggr_struct() {293 S *s = new S[2] { {1, 2}, {3, 4} };294 clang_analyzer_eval(1 == s[0].foo); // expected-warning{{TRUE}}295 clang_analyzer_eval(2 == s[0].bar); // expected-warning{{TRUE}}296 clang_analyzer_eval(3 == s[1].foo); // expected-warning{{TRUE}}297 clang_analyzer_eval(4 == s[1].bar); // expected-warning{{TRUE}}298 delete[] s;299}300 301struct WithGaps {302 int foo;303 int bar;304 int baz;305};306void out_of_order_designated_initializers_with_gaps() {307 WithGaps *s = new WithGaps{308 .foo = 13,309 .baz = 1,310 };311 clang_analyzer_eval(13 == s->foo); // expected-warning{{TRUE}}312 clang_analyzer_eval(0 == s->bar); // expected-warning{{TRUE}}313 clang_analyzer_eval(1 == s->baz); // expected-warning{{TRUE}}314 delete s;315}316 317// https://eel.is/c++draft/dcl.init.aggr#note-6:318// Static data members, non-static data members of anonymous319// union members, and unnamed bit-fields are not considered320// elements of the aggregate.321struct NonConsideredFields {322 int i;323 static int s;324 int j;325 int :17;326 int k;327};328void considered_fields_initd() {329 auto S = new NonConsideredFields { 1, 2, 3 };330 clang_analyzer_eval(1 == S->i); // expected-warning{{TRUE}}331 clang_analyzer_eval(2 == S->j); // expected-warning{{TRUE}}332 clang_analyzer_eval(3 == S->k); // expected-warning{{TRUE}}333 delete S;334}335 336#if __cplusplus >= 201703L337enum Enum : int {338};339void list_init_enum() {340 Enum *E = new Enum{53};341 clang_analyzer_eval(53 == *E); // expected-warning{{TRUE}}342 delete E;343}344#endif // __cplusplus >= 201703L345 346class PubClass {347public:348 int foo;349 int bar;350};351void public_class_designated_initializers() {352 S *s = new S{353 .foo = 13,354 .bar = 1,355 };356 clang_analyzer_eval(13 == s->foo); // expected-warning{{TRUE}}357 clang_analyzer_eval(1 == s->bar); // expected-warning{{TRUE}}358 delete s;359}360 361union UnionTestTy {362 int x;363 char y;364};365void new_expr_aggr_init_union_no_designator() {366 UnionTestTy *u = new UnionTestTy{};367 clang_analyzer_eval(0 == u->x); // expected-warning{{UNKNOWN}} FIXME: should be TRUE368 clang_analyzer_eval(u->y); // expected-warning{{UNKNOWN}} FIXME: should be undefined, warning369 delete u;370}371void new_expr_aggr_init_union_designated_first_field() {372 UnionTestTy *u = new UnionTestTy{ .x = 14 };373 clang_analyzer_eval(14 == u->x); // expected-warning{{UNKNOWN}} FIXME: should be TRUE374 clang_analyzer_eval(u->y); // expected-warning{{UNKNOWN}} FIXME: should be undefined, warning375 delete u;376}377void new_expr_aggr_init_union_designated_non_first_field() {378 UnionTestTy *u = new UnionTestTy{ .y = 3 };379 clang_analyzer_eval(3 == u->y); // expected-warning{{UNKNOWN}} FIXME: should be TRUE380 clang_analyzer_eval(u->x); // expected-warning{{UNKNOWN}} FIXME: should be undefined, warning381 delete u;382}383 384union UnionTestTyWithDefaultMemberInit {385 int x;386 char y = 14;387};388void union_with_default_member_init_empty_init_list() {389 auto U = new UnionTestTyWithDefaultMemberInit{};390 // clang_analyzer_eval(14 == U->y); // FIXME: Should be true391 clang_analyzer_eval(U->x); // expected-warning{{UNKNOWN}} FIXME: should be undefined, warning392 delete U;393}394 395struct Inner {396 int bar;397};398struct Nested {399 int foo;400 Inner inner;401 int baz;402};403void nested_aggregates() {404 auto N = new Nested{};405 clang_analyzer_eval(0 == N->foo); // expected-warning{{TRUE}}406 clang_analyzer_eval(0 == N->inner.bar); // expected-warning{{TRUE}}407 clang_analyzer_eval(0 == N->baz); // expected-warning{{TRUE}}408 409 auto N1 = new Nested{1};410 clang_analyzer_eval(1 == N1->foo); // expected-warning{{TRUE}}411 clang_analyzer_eval(0 == N1->inner.bar); // expected-warning{{TRUE}}412 clang_analyzer_eval(0 == N1->baz); // expected-warning{{TRUE}}413 414 auto N2 = new Nested{.baz = 14};415 clang_analyzer_eval(0 == N2->foo); // expected-warning{{TRUE}}416 clang_analyzer_eval(0 == N2->inner.bar); // expected-warning{{TRUE}}417 clang_analyzer_eval(14 == N2->baz); // expected-warning{{TRUE}}418 419 auto N3 = new Nested{1,2,3};420 clang_analyzer_eval(1 == N3->foo); // expected-warning{{TRUE}}421 clang_analyzer_eval(2 == N3->inner.bar); // expected-warning{{TRUE}}422 clang_analyzer_eval(3 == N3->baz); // expected-warning{{TRUE}}423 424 auto N4 = new Nested{1, {}, 3};425 clang_analyzer_eval(1 == N4->foo); // expected-warning{{TRUE}}426 clang_analyzer_eval(0 == N4->inner.bar); // expected-warning{{TRUE}}427 clang_analyzer_eval(3 == N4->baz); // expected-warning{{TRUE}}428 429 auto N5 = new Nested{{},{},{}};430 clang_analyzer_eval(0 == N5->foo); // expected-warning{{TRUE}}431 clang_analyzer_eval(0 == N5->inner.bar); // expected-warning{{TRUE}}432 clang_analyzer_eval(0 == N5->baz); // expected-warning{{TRUE}}433 434 auto N6 = new Nested{1, {.bar = 2}, 3};435 clang_analyzer_eval(1 == N6->foo); // expected-warning{{TRUE}}436 clang_analyzer_eval(2 == N6->inner.bar); // expected-warning{{TRUE}}437 clang_analyzer_eval(3 == N6->baz); // expected-warning{{TRUE}}438 439 auto N7 = new Nested{1, {2}, 3};440 clang_analyzer_eval(1 == N7->foo); // expected-warning{{TRUE}}441 clang_analyzer_eval(2 == N7->inner.bar); // expected-warning{{TRUE}}442 clang_analyzer_eval(3 == N7->baz); // expected-warning{{TRUE}}443 444 escape(N,N1,N2,N3,N4,N5,N6,N7);445}446} // namespace newexpr_init_list_initialization447 448namespace placement_new_initializer_list_arg {449struct S {450 int x;451};452void aggregate_struct() {453 S s;454 S *s_ptr = new (&s) S{1};455 clang_analyzer_eval(1 == s_ptr->x); // expected-warning{{TRUE}}456 457 S vi;458 S *vi_ptr = new (&vi) S{};459 clang_analyzer_eval(0 == vi_ptr->x); // expected-warning{{TRUE}}460 461 S di;462 S *di_ptr = new (&di) S;463 int z = di_ptr->x + 1; // expected-warning{{The left operand of '+' is a garbage value}}464}465void initialize_non_zeroth_element(S arr[2]) {466 S *s = new (&arr[1]) S{1};467 clang_analyzer_eval(1 == s->x); // expected-warning{{TRUE}}468}469void initialize_non_zeroth_argument_pointers(S *arr[2]) {470 arr[1] = new (arr[1]) S{1};471 clang_analyzer_eval(1 == arr[1]->x); // expected-warning{{TRUE}}472}473} // namespace placement_new_initializer_list_arg474 475namespace CXX17_transparent_init_list_exprs {476class A {};477 478class B: private A {};479 480B boo();481void foo1() {482 B b { boo() }; // no-crash483}484 485class C: virtual public A {};486 487C coo();488void foo2() {489 C c { coo() }; // no-crash490}491 492B foo_recursive() {493 B b { foo_recursive() };494}495} // namespace CXX17_transparent_init_list_exprs496 497namespace skip_vbase_initializer_side_effects {498int glob;499struct S {500 S() { ++glob; }501};502 503struct A {504 A() {}505 A(S s) {}506};507 508struct B : virtual A {509 B() : A(S()) {}510};511 512struct C : B {513 C() {}514};515 516void foo() {517 glob = 0;518 B b;519 clang_analyzer_eval(glob == 1); // expected-warning{{TRUE}}520 C c; // no-crash521 clang_analyzer_eval(glob == 1); // expected-warning{{TRUE}}522}523} // namespace skip_vbase_initializer_side_effects524 525namespace dont_skip_vbase_initializers_in_most_derived_class {526struct A {527 static int a;528 A() { a = 0; }529 A(int x) { a = x; }530};531 532struct B {533 static int b;534 B() { b = 0; }535 B(int y) { b = y; }536};537 538struct C : virtual A {539 C() : A(1) {}540};541struct D : C, virtual B {542 D() : B(2) {}543};544 545void testD() {546 D d;547 clang_analyzer_eval(A::a == 0); // expected-warning{{TRUE}}548 clang_analyzer_eval(B::b == 2); // expected-warning{{TRUE}}549}550 551struct E : virtual B, C {552 E() : B(2) {}553};554 555void testE() {556 E e;557 clang_analyzer_eval(A::a == 0); // expected-warning{{TRUE}}558 clang_analyzer_eval(B::b == 2); // expected-warning{{TRUE}}559}560 561struct F : virtual A, virtual B {562 F() : A(1) {}563};564struct G : F {565 G(): B(2) {}566};567 568void testG() {569 G g;570 clang_analyzer_eval(A::a == 0); // expected-warning{{TRUE}}571 clang_analyzer_eval(B::b == 2); // expected-warning{{TRUE}}572}573 574struct H : virtual B, virtual A {575 H(): A(1) {}576};577struct I : H {578 I(): B(2) {}579};580 581void testI() {582 I i;583 clang_analyzer_eval(A::a == 0); // expected-warning{{TRUE}}584 clang_analyzer_eval(B::b == 2); // expected-warning{{TRUE}}585}586} // namespace dont_skip_vbase_initializers_in_most_derived_class587 588namespace elementwise_copy_small_array_from_post_initializer_of_cctor {589struct String {590 String(const String &) {}591};592 593struct MatchComponent {594 unsigned numbers[2];595 String prerelease;596 MatchComponent(MatchComponent const &) = default;597};598 599MatchComponent get();600void consume(MatchComponent const &);601 602MatchComponent parseMatchComponent() {603 MatchComponent component = get();604 component.numbers[0] = 10;605 component.numbers[1] = 20;606 return component; // We should have no stack addr escape warning here.607}608 609void top() {610 consume(parseMatchComponent());611}612} // namespace elementwise_copy_small_array_from_post_initializer_of_cctor613 614namespace gh147686 {615// The problem reported in https://github.com/llvm/llvm-project/issues/147686616// is sensitive to the initializer form: using parenthesis to initialize m_ptr617// resulted in crashes when analyzing *m_ptr = '\0'; but using braces is fine.618 619struct A {620 A() : m_ptr(m_buf) { *m_ptr = '\0'; } // no-crash621 A(int overload) : m_ptr{m_buf} { *m_ptr = '\0'; }622 A(char src) : m_ptr(m_buf) { *m_ptr = src; } // no-crash623 A(char src, int overload) : m_ptr{m_buf} { *m_ptr = src; }624 char m_buf[64] = {0};625 char * m_ptr;626};627 628void test1() {629 A a;630 clang_analyzer_eval(a.m_buf[0] == 0); // expected-warning{{TRUE}}631 // FIXME The next eval should result in TRUE.632 clang_analyzer_eval(*a.m_ptr == 0); // expected-warning{{UNKNOWN}}633}634 635void test2() {636 A a(314);637 clang_analyzer_eval(a.m_buf[0] == 0); // expected-warning{{TRUE}}638 clang_analyzer_eval(*a.m_ptr == 0); // expected-warning{{TRUE}}639}640 641void test3() {642 A a(0);643 clang_analyzer_eval(a.m_buf[0] == 0); // expected-warning{{TRUE}}644 clang_analyzer_eval(*a.m_ptr == 0); // expected-warning{{TRUE}}645}646 647void test3Bis(char arg) {648 A a(arg);649 // FIXME This test should behave like test3.650 clang_analyzer_eval(a.m_buf[0] == arg); // expected-warning{{FALSE}} // expected-warning{{TRUE}}651 clang_analyzer_eval(*a.m_ptr == arg); // expected-warning{{UNKNOWN}}652}653 654void test4(char arg) {655 A a(arg, 314);656 clang_analyzer_eval(a.m_buf[0] == arg); // expected-warning{{TRUE}}657 clang_analyzer_eval(*a.m_ptr == arg); // expected-warning{{TRUE}}658}659 660} // namespace gh147686661