xref: /llvm-project/clang/test/Analysis/initializer.cpp (revision 820403c4e04db1f4adc8528bec33d393a5be3856)
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++11
4 // RUN: %clang_analyze_cc1 -w -verify %s\
5 // RUN:   -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks\
6 // RUN:   -analyzer-checker=debug.ExprInspection -std=c++17
7 // 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_ALLOCATORS
11 // 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_ALLOCATORS
15 
16 void clang_analyzer_eval(bool);
17 
18 #include "Inputs/system-header-simulator-cxx.h"
19 
20 class A {
21   int x;
22 public:
23   A();
24 };
25 
26 A::A() : x(0) {
27   clang_analyzer_eval(x == 0); // expected-warning{{TRUE}}
28 }
29 
30 
31 class DirectMember {
32   int x;
33 public:
34   DirectMember(int value) : x(value) {}
35 
36   int getX() { return x; }
37 };
38 
39 void testDirectMember() {
40   DirectMember obj(3);
41   clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}}
42 }
43 
44 
45 class IndirectMember {
46   struct {
47     int x;
48   };
49 public:
50   IndirectMember(int value) : x(value) {}
51 
52   int getX() { return x; }
53 };
54 
55 void testIndirectMember() {
56   IndirectMember obj(3);
57   clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}}
58 }
59 
60 
61 struct DelegatingConstructor {
62   int x;
63   DelegatingConstructor(int y) { x = y; }
64   DelegatingConstructor() : DelegatingConstructor(42) {}
65 };
66 
67 void testDelegatingConstructor() {
68   DelegatingConstructor obj;
69   clang_analyzer_eval(obj.x == 42); // expected-warning{{TRUE}}
70 }
71 
72 
73 struct RefWrapper {
74   RefWrapper(int *p) : x(*p) {}
75   RefWrapper(int &r) : x(r) {}
76   int &x;
77 };
78 
79 void testReferenceMember() {
80   int *p = 0;
81   RefWrapper X(p); // expected-warning@-7 {{Dereference of null pointer}}
82 }
83 
84 void testReferenceMember2() {
85   int *p = 0;
86   RefWrapper X(*p); // expected-warning {{Forming reference to null pointer}}
87 }
88 
89 
90 extern "C" char *strdup(const char *);
91 
92 class StringWrapper {
93   char *str;
94 public:
95   StringWrapper(const char *input) : str(strdup(input)) {} // no-warning
96 };
97 
98 
99 // PR15070 - Constructing a type containing a non-POD array mistakenly
100 // tried to perform a bind instead of relying on the CXXConstructExpr,
101 // which caused a cast<> failure in RegionStore.
102 namespace 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-warning
125   }
126 }
127 
128 namespace 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 
162 namespace 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-warning
178   }
179 
180   void referenceInitializeMultipleLocals() {
181     const MyStruct &myStruct1(5), myStruct2(5), &myStruct3(5);
182     myStruct1.method(); // no-warning
183     myStruct2.method(); // no-warning
184     myStruct3.method(); // no-warning
185   }
186 
187   void referenceInitializeLocalWithCleanup() {
188     const MyStruct &myStruct(OtherStruct(5));
189     myStruct.method(); // no-warning
190   }
191 };
192 
193 namespace PR31592 {
194 struct C {
195    C() : f("}") { } // no-crash
196    const char(&f)[2];
197 };
198 }
199 
200 namespace CXX_initializer_lists {
201 struct C {
202   C(std::initializer_list<int *> list);
203 };
204 void testPointerEscapeIntoLists() {
205   C empty{}; // no-crash
206 
207   // Do not warn that 'x' leaks. It might have been deleted by
208   // the destructor of 'c'.
209   int *x = new int;
210   C c{x}; // no-warning
211 }
212 
213 void testPassListsWithExplicitConstructors() {
214   (void)(std::initializer_list<int>){12}; // no-crash
215 }
216 }
217 
218 namespace CXX17_aggregate_construction {
219 struct A {
220   A();
221 };
222 
223 struct B: public A {
224 };
225 
226 struct C: public B {
227 };
228 
229 struct D: public virtual A {
230 };
231 
232 // In C++17, classes B and C are aggregates, so they will be constructed
233 // without actually calling their trivial constructor. Used to crash.
234 void foo() {
235   B b = {}; // no-crash
236   const B &bl = {}; // no-crash
237   B &&br = {}; // no-crash
238 
239   C c = {}; // no-crash
240   const C &cl = {}; // no-crash
241   C &&cr = {}; // no-crash
242 
243   D d = {}; // no-crash
244 
245 #if __cplusplus >= 201703L
246   C cd = {{}}; // no-crash
247   const C &cdl = {{}}; // no-crash
248   C &&cdr = {{}}; // no-crash
249 
250   const B &bll = {{}}; // no-crash
251   const B &bcl = C({{}}); // no-crash
252   B &&bcr = C({{}}); // no-crash
253 #endif
254 }
255 } // namespace CXX17_aggregate_construction
256 
257 namespace CXX17_transparent_init_list_exprs {
258 class A {};
259 
260 class B: private A {};
261 
262 B boo();
263 void foo1() {
264   B b { boo() }; // no-crash
265 }
266 
267 class C: virtual public A {};
268 
269 C coo();
270 void foo2() {
271   C c { coo() }; // no-crash
272 }
273 
274 B foo_recursive() {
275   B b { foo_recursive() };
276 }
277 } // namespace CXX17_transparent_init_list_exprs
278 
279 namespace skip_vbase_initializer_side_effects {
280 int glob;
281 struct S {
282   S() { ++glob; }
283 };
284 
285 struct A {
286   A() {}
287   A(S s) {}
288 };
289 
290 struct B : virtual A {
291   B() : A(S()) {}
292 };
293 
294 struct C : B {
295   C() {}
296 };
297 
298 void foo() {
299   glob = 0;
300   B b;
301   clang_analyzer_eval(glob == 1); // expected-warning{{TRUE}}
302   C c; // no-crash
303   clang_analyzer_eval(glob == 1); // expected-warning{{TRUE}}
304 }
305 } // namespace skip_vbase_initializer_side_effects
306 
307 namespace dont_skip_vbase_initializers_in_most_derived_class {
308 struct A {
309   static int a;
310   A() { a = 0; }
311   A(int x) { a = x; }
312 };
313 
314 struct B {
315   static int b;
316   B() { b = 0; }
317   B(int y) { b = y; }
318 };
319 
320 struct C : virtual A {
321   C() : A(1) {}
322 };
323 struct D : C, virtual B {
324   D() : B(2) {}
325 };
326 
327 void testD() {
328   D d;
329   clang_analyzer_eval(A::a == 0); // expected-warning{{TRUE}}
330   clang_analyzer_eval(B::b == 2); // expected-warning{{TRUE}}
331 }
332 
333 struct E : virtual B, C {
334   E() : B(2) {}
335 };
336 
337 void testE() {
338   E e;
339   clang_analyzer_eval(A::a == 0); // expected-warning{{TRUE}}
340   clang_analyzer_eval(B::b == 2); // expected-warning{{TRUE}}
341 }
342 
343 struct F : virtual A, virtual B {
344   F() : A(1) {}
345 };
346 struct G : F {
347   G(): B(2) {}
348 };
349 
350 void testG() {
351   G g;
352   clang_analyzer_eval(A::a == 0); // expected-warning{{TRUE}}
353   clang_analyzer_eval(B::b == 2); // expected-warning{{TRUE}}
354 }
355 
356 struct H : virtual B, virtual A {
357   H(): A(1) {}
358 };
359 struct I : H {
360   I(): B(2) {}
361 };
362 
363 void testI() {
364   I i;
365   clang_analyzer_eval(A::a == 0); // expected-warning{{TRUE}}
366   clang_analyzer_eval(B::b == 2); // expected-warning{{TRUE}}
367 }
368 } // namespace dont_skip_vbase_initializers_in_most_derived_class
369 
370 namespace elementwise_copy_small_array_from_post_initializer_of_cctor {
371 struct String {
372   String(const String &) {}
373 };
374 
375 struct MatchComponent {
376   unsigned numbers[2];
377   String prerelease;
378   MatchComponent(MatchComponent const &) = default;
379 };
380 
381 MatchComponent get();
382 void consume(MatchComponent const &);
383 
384 MatchComponent parseMatchComponent() {
385   MatchComponent component = get();
386   component.numbers[0] = 10;
387   component.numbers[1] = 20;
388   return component; // We should have no stack addr escape warning here.
389 }
390 
391 void top() {
392   consume(parseMatchComponent());
393 }
394 } // namespace elementwise_copy_small_array_from_post_initializer_of_cctor
395