| // 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 |