1 // RUN: %clang_analyze_cc1 %s -verify -analyzer-checker=core,debug.ExprInspection 2 3 // Refer to https://github.com/llvm/llvm-project/issues/70464 for more details. 4 // 5 // When the base class does not have a declared constructor, the base 6 // initializer in the constructor of the derived class should use the given 7 // initializer list to finish the initialization of the base class. 8 // 9 // Also testing base constructor and delegate constructor to make sure this 10 // change will not break these two cases when a CXXConstructExpr is available. 11 12 void clang_analyzer_dump(int); 13 14 namespace init_list { 15 16 struct Base { 17 int foox; 18 }; 19 20 class Derived : public Base { 21 public: Derived()22 Derived() : Base{42} { 23 // The dereference to this->foox below should be initialized properly. 24 clang_analyzer_dump(this->foox); // expected-warning{{42 S32b}} 25 clang_analyzer_dump(foox); // expected-warning{{42 S32b}} 26 } 27 }; 28 entry()29void entry() { Derived test; } 30 31 } // namespace init_list 32 33 namespace base_ctor_call { 34 35 struct Base { 36 int foox; Basebase_ctor_call::Base37 Base(int x) : foox(x) {} 38 }; 39 40 class Derived : public Base { 41 public: Derived()42 Derived() : Base{42} { 43 clang_analyzer_dump(this->foox); // expected-warning{{42 S32b}} 44 clang_analyzer_dump(foox); // expected-warning{{42 S32b}} 45 } 46 }; 47 entry()48void entry() { Derived test; } 49 50 } // namespace base_ctor_call 51 52 namespace delegate_ctor_call { 53 54 struct Base { 55 int foox; 56 }; 57 58 struct Derived : Base { Deriveddelegate_ctor_call::Derived59 Derived(int parx) { this->foox = parx; } Deriveddelegate_ctor_call::Derived60 Derived() : Derived{42} { 61 clang_analyzer_dump(this->foox); // expected-warning{{42 S32b}} 62 clang_analyzer_dump(foox); // expected-warning{{42 S32b}} 63 } 64 }; 65 entry()66void entry() { Derived test; } 67 68 } // namespace delegate_ctor_call 69 70 // Additional test case from issue #59493 71 namespace init_list_array { 72 73 struct Base { 74 int foox[5]; 75 }; 76 77 class Derived1 : public Base { 78 public: Derived1()79 Derived1() : Base{{1,4,5,3,2}} { 80 // The dereference to this->foox below should be initialized properly. 81 clang_analyzer_dump(this->foox[0]); // expected-warning{{1 S32b}} 82 clang_analyzer_dump(this->foox[1]); // expected-warning{{4 S32b}} 83 clang_analyzer_dump(this->foox[2]); // expected-warning{{5 S32b}} 84 clang_analyzer_dump(this->foox[3]); // expected-warning{{3 S32b}} 85 clang_analyzer_dump(this->foox[4]); // expected-warning{{2 S32b}} 86 clang_analyzer_dump(foox[0]); // expected-warning{{1 S32b}} 87 clang_analyzer_dump(foox[1]); // expected-warning{{4 S32b}} 88 clang_analyzer_dump(foox[2]); // expected-warning{{5 S32b}} 89 clang_analyzer_dump(foox[3]); // expected-warning{{3 S32b}} 90 clang_analyzer_dump(foox[4]); // expected-warning{{2 S32b}} 91 } 92 }; 93 entry1()94void entry1() { Derived1 test; } 95 96 class Derived2 : public Base { 97 public: Derived2()98 Derived2() : Base{{0}} { 99 // The dereference to this->foox below should be initialized properly. 100 clang_analyzer_dump(this->foox[0]); // expected-warning{{0 S32b}} 101 clang_analyzer_dump(this->foox[1]); // expected-warning{{0 S32b}} 102 clang_analyzer_dump(this->foox[2]); // expected-warning{{0 S32b}} 103 clang_analyzer_dump(this->foox[3]); // expected-warning{{0 S32b}} 104 clang_analyzer_dump(this->foox[4]); // expected-warning{{0 S32b}} 105 clang_analyzer_dump(foox[0]); // expected-warning{{0 S32b}} 106 clang_analyzer_dump(foox[1]); // expected-warning{{0 S32b}} 107 clang_analyzer_dump(foox[2]); // expected-warning{{0 S32b}} 108 clang_analyzer_dump(foox[3]); // expected-warning{{0 S32b}} 109 clang_analyzer_dump(foox[4]); // expected-warning{{0 S32b}} 110 } 111 }; 112 entry2()113void entry2() { Derived2 test; } 114 115 } // namespace init_list_array 116 117 namespace init_list_struct { 118 119 struct Base { 120 struct { int a; int b; } foox; 121 }; 122 123 class Derived : public Base { 124 public: Derived()125 Derived() : Base{{42, 24}} { 126 // The dereference to this->foox below should be initialized properly. 127 clang_analyzer_dump(this->foox.a); // expected-warning{{42 S32b}} 128 clang_analyzer_dump(this->foox.b); // expected-warning{{24 S32b}} 129 clang_analyzer_dump(foox.a); // expected-warning{{42 S32b}} 130 clang_analyzer_dump(foox.b); // expected-warning{{24 S32b}} 131 } 132 }; 133 134 } // namespace init_list_struct 135 136 // Additional test case from issue 54533 137 namespace init_list_enum { 138 139 struct Base { 140 enum : unsigned char { ZERO = 0, FORTY_TWO = 42 } foox; 141 }; 142 143 class Derived : public Base { 144 public: Derived()145 Derived() : Base{FORTY_TWO} { 146 // The dereference to this->foox below should be initialized properly. 147 clang_analyzer_dump(this->foox); // expected-warning{{42 S32b}} 148 clang_analyzer_dump(foox); // expected-warning{{42 S32b}} 149 } 150 }; 151 entry()152void entry() { Derived test; } 153 154 } // namespace init_list_enum 155