|  | // RUN: %clang_analyze_cc1 %s -verify -analyzer-checker=core,debug.ExprInspection | 
|  |  | 
|  | // Refer to https://github.com/llvm/llvm-project/issues/70464 for more details. | 
|  | // | 
|  | // When the base class does not have a declared constructor, the base | 
|  | // initializer in the constructor of the derived class should use the given | 
|  | // initializer list to finish the initialization of the base class. | 
|  | // | 
|  | // Also testing base constructor and delegate constructor to make sure this | 
|  | // change will not break these two cases when a CXXConstructExpr is available. | 
|  |  | 
|  | void clang_analyzer_dump(int); | 
|  |  | 
|  | namespace init_list { | 
|  |  | 
|  | struct Base { | 
|  | int foox; | 
|  | }; | 
|  |  | 
|  | class Derived : public Base { | 
|  | public: | 
|  | Derived() : Base{42} { | 
|  | // The dereference to this->foox below should be initialized properly. | 
|  | clang_analyzer_dump(this->foox); // expected-warning{{42 S32b}} | 
|  | clang_analyzer_dump(foox); // expected-warning{{42 S32b}} | 
|  | } | 
|  | }; | 
|  |  | 
|  | void entry() { Derived test; } | 
|  |  | 
|  | } // namespace init_list | 
|  |  | 
|  | namespace base_ctor_call { | 
|  |  | 
|  | struct Base { | 
|  | int foox; | 
|  | Base(int x) : foox(x) {} | 
|  | }; | 
|  |  | 
|  | class Derived : public Base { | 
|  | public: | 
|  | Derived() : Base{42} { | 
|  | clang_analyzer_dump(this->foox); // expected-warning{{42 S32b}} | 
|  | clang_analyzer_dump(foox); // expected-warning{{42 S32b}} | 
|  | } | 
|  | }; | 
|  |  | 
|  | void entry() { Derived test; } | 
|  |  | 
|  | } // namespace base_ctor_call | 
|  |  | 
|  | namespace delegate_ctor_call { | 
|  |  | 
|  | struct Base { | 
|  | int foox; | 
|  | }; | 
|  |  | 
|  | struct Derived : Base { | 
|  | Derived(int parx) { this->foox = parx; } | 
|  | Derived() : Derived{42} { | 
|  | clang_analyzer_dump(this->foox); // expected-warning{{42 S32b}} | 
|  | clang_analyzer_dump(foox); // expected-warning{{42 S32b}} | 
|  | } | 
|  | }; | 
|  |  | 
|  | void entry() { Derived test; } | 
|  |  | 
|  | } // namespace delegate_ctor_call | 
|  |  | 
|  | // Additional test case from issue #59493 | 
|  | namespace init_list_array { | 
|  |  | 
|  | struct Base { | 
|  | int foox[5]; | 
|  | }; | 
|  |  | 
|  | class Derived1 : public Base { | 
|  | public: | 
|  | Derived1() : Base{{1,4,5,3,2}} { | 
|  | // The dereference to this->foox below should be initialized properly. | 
|  | clang_analyzer_dump(this->foox[0]); // expected-warning{{1 S32b}} | 
|  | clang_analyzer_dump(this->foox[1]); // expected-warning{{4 S32b}} | 
|  | clang_analyzer_dump(this->foox[2]); // expected-warning{{5 S32b}} | 
|  | clang_analyzer_dump(this->foox[3]); // expected-warning{{3 S32b}} | 
|  | clang_analyzer_dump(this->foox[4]); // expected-warning{{2 S32b}} | 
|  | clang_analyzer_dump(foox[0]); // expected-warning{{1 S32b}} | 
|  | clang_analyzer_dump(foox[1]); // expected-warning{{4 S32b}} | 
|  | clang_analyzer_dump(foox[2]); // expected-warning{{5 S32b}} | 
|  | clang_analyzer_dump(foox[3]); // expected-warning{{3 S32b}} | 
|  | clang_analyzer_dump(foox[4]); // expected-warning{{2 S32b}} | 
|  | } | 
|  | }; | 
|  |  | 
|  | void entry1() { Derived1 test; } | 
|  |  | 
|  | class Derived2 : public Base { | 
|  | public: | 
|  | Derived2() : Base{{0}} { | 
|  | // The dereference to this->foox below should be initialized properly. | 
|  | clang_analyzer_dump(this->foox[0]); // expected-warning{{0 S32b}} | 
|  | clang_analyzer_dump(this->foox[1]); // expected-warning{{0 S32b}} | 
|  | clang_analyzer_dump(this->foox[2]); // expected-warning{{0 S32b}} | 
|  | clang_analyzer_dump(this->foox[3]); // expected-warning{{0 S32b}} | 
|  | clang_analyzer_dump(this->foox[4]); // expected-warning{{0 S32b}} | 
|  | clang_analyzer_dump(foox[0]); // expected-warning{{0 S32b}} | 
|  | clang_analyzer_dump(foox[1]); // expected-warning{{0 S32b}} | 
|  | clang_analyzer_dump(foox[2]); // expected-warning{{0 S32b}} | 
|  | clang_analyzer_dump(foox[3]); // expected-warning{{0 S32b}} | 
|  | clang_analyzer_dump(foox[4]); // expected-warning{{0 S32b}} | 
|  | } | 
|  | }; | 
|  |  | 
|  | void entry2() { Derived2 test; } | 
|  |  | 
|  | } // namespace init_list_array | 
|  |  | 
|  | namespace init_list_struct { | 
|  |  | 
|  | struct Base { | 
|  | struct { int a; int b; } foox; | 
|  | }; | 
|  |  | 
|  | class Derived : public Base { | 
|  | public: | 
|  | Derived() : Base{{42, 24}} { | 
|  | // The dereference to this->foox below should be initialized properly. | 
|  | clang_analyzer_dump(this->foox.a); // expected-warning{{42 S32b}} | 
|  | clang_analyzer_dump(this->foox.b); // expected-warning{{24 S32b}} | 
|  | clang_analyzer_dump(foox.a); // expected-warning{{42 S32b}} | 
|  | clang_analyzer_dump(foox.b); // expected-warning{{24 S32b}} | 
|  | } | 
|  | }; | 
|  |  | 
|  | } // namespace init_list_struct | 
|  |  | 
|  | // Additional test case from issue 54533 | 
|  | namespace init_list_enum { | 
|  |  | 
|  | struct Base { | 
|  | enum : unsigned char { ZERO = 0, FORTY_TWO = 42 } foox; | 
|  | }; | 
|  |  | 
|  | class Derived : public Base { | 
|  | public: | 
|  | Derived() : Base{FORTY_TWO} { | 
|  | // The dereference to this->foox below should be initialized properly. | 
|  | clang_analyzer_dump(this->foox); // expected-warning{{42 S32b}} | 
|  | clang_analyzer_dump(foox); // expected-warning{{42 S32b}} | 
|  | } | 
|  | }; | 
|  |  | 
|  | void entry() { Derived test; } | 
|  |  | 
|  | } // namespace init_list_enum |