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