[clang][NFC] simplify the unset check in `ParseLabeledStatement` (#117430)
[llvm-project.git] / clang / test / Analysis / ctor.mm
blob6ac9050fc29f70e3fdd5f7d73b42c87e62ae245c
1 // RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -DI386 -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -std=c++11 -verify -analyzer-config eagerly-assume=false %s
2 // RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -DI386 -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -std=c++11 -verify -DTEST_INLINABLE_ALLOCATORS -analyzer-config eagerly-assume=false %s
3 // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin12 -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -std=c++11 -verify -analyzer-config eagerly-assume=false %s
4 // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin12 -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -std=c++11 -verify -DTEST_INLINABLE_ALLOCATORS -analyzer-config eagerly-assume=false %s
6 #include "Inputs/system-header-simulator-cxx.h"
8 void clang_analyzer_eval(bool);
9 void clang_analyzer_checkInlined(bool);
11 // A simplified version of std::move.
12 template <typename T>
13 T &&move(T &obj) {
14   return static_cast<T &&>(obj);
18 struct Wrapper {
19   __strong id obj;
22 void test() {
23   Wrapper w;
24   // force a diagnostic
25   *(char *)0 = 1; // expected-warning{{Dereference of null pointer}}
29 struct IntWrapper {
30   int x;
33 void testCopyConstructor() {
34   IntWrapper a;
35   a.x = 42;
37   IntWrapper b(a);
38   clang_analyzer_eval(b.x == 42); // expected-warning{{TRUE}}
41 struct NonPODIntWrapper {
42   int x;
44   virtual int get();
47 void testNonPODCopyConstructor() {
48   NonPODIntWrapper a;
49   a.x = 42;
51   NonPODIntWrapper b(a);
52   clang_analyzer_eval(b.x == 42); // expected-warning{{TRUE}}
56 namespace ConstructorVirtualCalls {
57   class A {
58   public:
59     virtual int get() { return 1; }
61     A(int *out1) {
62       *out1 = get();
63     }
64   };
66   class B : public A {
67   public:
68     virtual int get() { return 2; }
70     B(int *out1, int *out2) : A(out1) {
71       *out2 = get();
72     }
73   };
75   class C : public B {
76   public:
77     virtual int get() { return 3; }
79     C(int *out1, int *out2, int *out3) : B(out1, out2) {
80       *out3 = get();
81     }
82   };
84   void test() {
85     int a, b, c;
87     C obj(&a, &b, &c);
88     clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
89     clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
90     clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
92     clang_analyzer_eval(obj.get() == 3); // expected-warning{{TRUE}}
94     // Correctness check for devirtualization.
95     A *base = &obj;
96     clang_analyzer_eval(base->get() == 3); // expected-warning{{TRUE}}
97   }
100 namespace TemporaryConstructor {
101   class BoolWrapper {
102   public:
103     BoolWrapper() {
104       clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
105       value = true;
106     }
107     bool value;
108   };
110   void test() {
111     // PR13717 - Don't crash when a CXXTemporaryObjectExpr is inlined.
112     if (BoolWrapper().value)
113       return;
114   }
118 namespace ConstructorUsedAsRValue {
119   using TemporaryConstructor::BoolWrapper;
121   bool extractValue(BoolWrapper b) {
122     return b.value;
123   }
125   void test() {
126     bool result = extractValue(BoolWrapper());
127     clang_analyzer_eval(result); // expected-warning{{TRUE}}
128   }
131 namespace PODUninitialized {
132   class POD {
133   public:
134     int x, y;
135   };
137   class PODWrapper {
138   public:
139     POD p;
140   };
142   class NonPOD {
143   public:
144     int x, y;
146     NonPOD() {}
147     NonPOD(const NonPOD &Other)
148       : x(Other.x), y(Other.y) // expected-warning {{undefined}}
149     {
150     }
151     NonPOD(NonPOD &&Other)
152     : x(Other.x), y(Other.y) // expected-warning {{undefined}}
153     {
154     }
156     NonPOD &operator=(const NonPOD &Other)
157     {
158       x = Other.x;
159       y = Other.y; // expected-warning {{undefined}}
160       return *this;
161     }
162     NonPOD &operator=(NonPOD &&Other)
163     {
164       x = Other.x;
165       y = Other.y; // expected-warning {{undefined}}
166       return *this;
167     }
168   };
170   class NonPODWrapper {
171   public:
172     class Inner {
173     public:
174       int x, y;
176       Inner() {}
177       Inner(const Inner &Other)
178         : x(Other.x), y(Other.y) // expected-warning {{undefined}}
179       {
180       }
181       Inner(Inner &&Other)
182       : x(Other.x), y(Other.y) // expected-warning {{undefined}}
183       {
184       }
186       Inner &operator=(const Inner &Other)
187       {
188         x = Other.x; // expected-warning {{undefined}}
189         y = Other.y;
190         return *this;
191       }
192       Inner &operator=(Inner &&Other)
193       {
194         x = Other.x; // expected-warning {{undefined}}
195         y = Other.y;
196         return *this;
197       }
198     };
200     Inner p;
201   };
203   void testPOD(const POD &pp) {
204     POD p;
205     p.x = 1;
206     POD p2 = p; // no-warning
207     clang_analyzer_eval(p2.x == 1); // expected-warning{{TRUE}}
208     POD p3 = move(p); // no-warning
209     clang_analyzer_eval(p3.x == 1); // expected-warning{{TRUE}}
211     // Use rvalues as well.
212     clang_analyzer_eval(POD(p3).x == 1); // expected-warning{{TRUE}}
214     // Copy from symbolic references correctly.
215     POD p4 = pp;
216     // Make sure that p4.x contains a symbol after copy.
217     if (p4.x > 0)
218       clang_analyzer_eval(p4.x > 0); // expected-warning{{TRUE}}
219     clang_analyzer_eval(pp.x == p4.x); // expected-warning{{TRUE}}
221     PODWrapper w;
222     w.p.y = 1;
223     PODWrapper w2 = w; // no-warning
224     clang_analyzer_eval(w2.p.y == 1); // expected-warning{{TRUE}}
225     PODWrapper w3 = move(w); // no-warning
226     clang_analyzer_eval(w3.p.y == 1); // expected-warning{{TRUE}}
228     // Use rvalues as well.
229     clang_analyzer_eval(PODWrapper(w3).p.y == 1); // expected-warning{{TRUE}}
230   }
232   void testNonPOD() {
233     NonPOD p;
234     p.x = 1;
235     NonPOD p2 = p;
236   }
238   void testNonPODMove() {
239     NonPOD p;
240     p.x = 1;
241     NonPOD p2 = move(p);
242   }
244   void testNonPODWrapper() {
245     NonPODWrapper w;
246     w.p.y = 1;
247     NonPODWrapper w2 = w;
248   }
250   void testNonPODWrapperMove() {
251     NonPODWrapper w;
252     w.p.y = 1;
253     NonPODWrapper w2 = move(w);
254   }
256   // Not strictly about constructors, but trivial assignment operators should
257   // essentially work the same way.
258   namespace AssignmentOperator {
259     void testPOD() {
260       POD p;
261       p.x = 1;
262       POD p2;
263       p2 = p; // no-warning
264       clang_analyzer_eval(p2.x == 1); // expected-warning{{TRUE}}
265       POD p3;
266       p3 = move(p); // no-warning
267       clang_analyzer_eval(p3.x == 1); // expected-warning{{TRUE}}
269       PODWrapper w;
270       w.p.y = 1;
271       PODWrapper w2;
272       w2 = w; // no-warning
273       clang_analyzer_eval(w2.p.y == 1); // expected-warning{{TRUE}}
274       PODWrapper w3;
275       w3 = move(w); // no-warning
276       clang_analyzer_eval(w3.p.y == 1); // expected-warning{{TRUE}}
277     }
279     void testReturnValue() {
280       POD p;
281       p.x = 1;
282       POD p2;
283       clang_analyzer_eval(&(p2 = p) == &p2); // expected-warning{{TRUE}}
285       PODWrapper w;
286       w.p.y = 1;
287       PODWrapper w2;
288       clang_analyzer_eval(&(w2 = w) == &w2); // expected-warning{{TRUE}}
289     }
291     void testNonPOD() {
292       NonPOD p;
293       p.x = 1;
294       NonPOD p2;
295       p2 = p;
296     }
298     void testNonPODMove() {
299       NonPOD p;
300       p.x = 1;
301       NonPOD p2;
302       p2 = move(p);
303     }
305     void testNonPODWrapper() {
306       NonPODWrapper w;
307       w.p.y = 1;
308       NonPODWrapper w2;
309       w2 = w;
310     }
312     void testNonPODWrapperMove() {
313       NonPODWrapper w;
314       w.p.y = 1;
315       NonPODWrapper w2;
316       w2 = move(w);
317     }
318   }
321 namespace ArrayMembers {
322   struct Primitive {
323     int values[3];
324   };
326   void testPrimitive() {
327     Primitive a = { { 1, 2, 3 } };
329     clang_analyzer_eval(a.values[0] == 1); // expected-warning{{TRUE}}
330     clang_analyzer_eval(a.values[1] == 2); // expected-warning{{TRUE}}
331     clang_analyzer_eval(a.values[2] == 3); // expected-warning{{TRUE}}
333     Primitive b = a;
335     clang_analyzer_eval(b.values[0] == 1); // expected-warning{{TRUE}}
336     clang_analyzer_eval(b.values[1] == 2); // expected-warning{{TRUE}}
337     clang_analyzer_eval(b.values[2] == 3); // expected-warning{{TRUE}}
339     Primitive c;
340     c = b;
342     clang_analyzer_eval(c.values[0] == 1); // expected-warning{{TRUE}}
343     clang_analyzer_eval(c.values[1] == 2); // expected-warning{{TRUE}}
344     clang_analyzer_eval(c.values[2] == 3); // expected-warning{{TRUE}}
345   }
347   struct NestedPrimitive {
348     int values[2][3];
349   };
351   void testNestedPrimitive() {
352     NestedPrimitive a = { { { 0, 0, 0 }, { 1, 2, 3 } } };
354     clang_analyzer_eval(a.values[1][0] == 1); // expected-warning{{TRUE}}
355     clang_analyzer_eval(a.values[1][1] == 2); // expected-warning{{TRUE}}
356     clang_analyzer_eval(a.values[1][2] == 3); // expected-warning{{TRUE}}
358     NestedPrimitive b = a;
360     clang_analyzer_eval(b.values[1][0] == 1); // expected-warning{{TRUE}}
361     clang_analyzer_eval(b.values[1][1] == 2); // expected-warning{{TRUE}}
362     clang_analyzer_eval(b.values[1][2] == 3); // expected-warning{{TRUE}}
364     NestedPrimitive c;
365     c = b;
367     clang_analyzer_eval(c.values[1][0] == 1); // expected-warning{{TRUE}}
368     clang_analyzer_eval(c.values[1][1] == 2); // expected-warning{{TRUE}}
369     clang_analyzer_eval(c.values[1][2] == 3); // expected-warning{{TRUE}}
370   }
372   struct POD {
373     IntWrapper values[3];
374   };
376   void testPOD() {
377     POD a = { { { 1 }, { 2 }, { 3 } } };
379     clang_analyzer_eval(a.values[0].x == 1); // expected-warning{{TRUE}}
380     clang_analyzer_eval(a.values[1].x == 2); // expected-warning{{TRUE}}
381     clang_analyzer_eval(a.values[2].x == 3); // expected-warning{{TRUE}}
383     POD b = a;
385     clang_analyzer_eval(b.values[0].x == 1); // expected-warning{{TRUE}}
386     clang_analyzer_eval(b.values[1].x == 2); // expected-warning{{TRUE}}
387     clang_analyzer_eval(b.values[2].x == 3); // expected-warning{{TRUE}}
389     POD c;
390     c = b;
392     clang_analyzer_eval(c.values[0].x == 1); // expected-warning{{TRUE}}
393     clang_analyzer_eval(c.values[1].x == 2); // expected-warning{{TRUE}}
394     clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{TRUE}}
395   }
397   struct NestedPOD {
398     IntWrapper values[2][3];
399   };
401   void testNestedPOD() {
402     NestedPOD a = { { { { 0 }, { 0 }, { 0 } }, { { 1 }, { 2 }, { 3 } } } };
404     clang_analyzer_eval(a.values[1][0].x == 1); // expected-warning{{TRUE}}
405     clang_analyzer_eval(a.values[1][1].x == 2); // expected-warning{{TRUE}}
406     clang_analyzer_eval(a.values[1][2].x == 3); // expected-warning{{TRUE}}
408     NestedPOD b = a;
410     clang_analyzer_eval(b.values[1][0].x == 1); // expected-warning{{TRUE}}
411     clang_analyzer_eval(b.values[1][1].x == 2); // expected-warning{{TRUE}}
412     clang_analyzer_eval(b.values[1][2].x == 3); // expected-warning{{TRUE}}
414     NestedPOD c;
415     c = b;
417     clang_analyzer_eval(c.values[1][0].x == 1); // expected-warning{{TRUE}}
418     clang_analyzer_eval(c.values[1][1].x == 2); // expected-warning{{TRUE}}
419     clang_analyzer_eval(c.values[1][2].x == 3); // expected-warning{{TRUE}}
420   }
422   struct NonPOD {
423     NonPODIntWrapper values[3];
424   };
426   void testNonPOD() {
427     NonPOD a;
428     a.values[0].x = 1;
429     a.values[1].x = 2;
430     a.values[2].x = 3;
432     clang_analyzer_eval(a.values[0].x == 1); // expected-warning{{TRUE}}
433     clang_analyzer_eval(a.values[1].x == 2); // expected-warning{{TRUE}}
434     clang_analyzer_eval(a.values[2].x == 3); // expected-warning{{TRUE}}
436     NonPOD b = a;
438     clang_analyzer_eval(b.values[0].x == 1); // expected-warning{{TRUE}}
439     clang_analyzer_eval(b.values[1].x == 2); // expected-warning{{TRUE}}
440     clang_analyzer_eval(b.values[2].x == 3); // expected-warning{{TRUE}}
442     NonPOD c;
443     c = b;
445     clang_analyzer_eval(c.values[0].x == 1); // expected-warning{{TRUE}}
446     clang_analyzer_eval(c.values[1].x == 2); // expected-warning{{TRUE}}
447     clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{TRUE}}
448   }
450   struct NestedNonPOD {
451     NonPODIntWrapper values[2][3];
452   };
454   void testNestedNonPOD() {
455     NestedNonPOD a;
456     a.values[0][0].x = 0;
457     a.values[0][1].x = 0;
458     a.values[0][2].x = 0;
459     a.values[1][0].x = 1;
460     a.values[1][1].x = 2;
461     a.values[1][2].x = 3;
463     clang_analyzer_eval(a.values[1][0].x == 1); // expected-warning{{TRUE}}
464     clang_analyzer_eval(a.values[1][1].x == 2); // expected-warning{{TRUE}}
465     clang_analyzer_eval(a.values[1][2].x == 3); // expected-warning{{TRUE}}
467     NestedNonPOD b = a;
469     clang_analyzer_eval(b.values[1][0].x == 1); // expected-warning{{UNKNOWN}}
470     clang_analyzer_eval(b.values[1][1].x == 2); // expected-warning{{UNKNOWN}}
471     clang_analyzer_eval(b.values[1][2].x == 3); // expected-warning{{UNKNOWN}}
473     NestedNonPOD c;
474     c = b;
476     clang_analyzer_eval(c.values[1][0].x == 1); // expected-warning{{UNKNOWN}}
477     clang_analyzer_eval(c.values[1][1].x == 2); // expected-warning{{UNKNOWN}}
478     clang_analyzer_eval(c.values[1][2].x == 3); // expected-warning{{UNKNOWN}}
479   }
480   
481   struct NonPODDefaulted {
482     NonPODIntWrapper values[3];
484     NonPODDefaulted() = default;
485     NonPODDefaulted(const NonPODDefaulted &) = default;
486     NonPODDefaulted &operator=(const NonPODDefaulted &) = default;
487   };
489   void testNonPODDefaulted() {
490     NonPODDefaulted a;
491     a.values[0].x = 1;
492     a.values[1].x = 2;
493     a.values[2].x = 3;
495     clang_analyzer_eval(a.values[0].x == 1); // expected-warning{{TRUE}}
496     clang_analyzer_eval(a.values[1].x == 2); // expected-warning{{TRUE}}
497     clang_analyzer_eval(a.values[2].x == 3); // expected-warning{{TRUE}}
499     NonPODDefaulted b = a;
501     clang_analyzer_eval(b.values[0].x == 1); // expected-warning{{TRUE}}
502     clang_analyzer_eval(b.values[1].x == 2); // expected-warning{{TRUE}}
503     clang_analyzer_eval(b.values[2].x == 3); // expected-warning{{TRUE}}
505     NonPODDefaulted c;
506     c = b;
508     clang_analyzer_eval(c.values[0].x == 1); // expected-warning{{TRUE}}
509     clang_analyzer_eval(c.values[1].x == 2); // expected-warning{{TRUE}}
510     clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{TRUE}}
511   }
514 namespace VirtualInheritance {
515   int counter;
517   struct base {
518     base() {
519       ++counter;
520     }
521   };
523   struct virtual_subclass : public virtual base {
524     virtual_subclass() {}
525   };
527   struct double_subclass : public virtual_subclass {
528     double_subclass() {}
529   };
531   void test() {
532     counter = 0;
533     double_subclass obj;
534     clang_analyzer_eval(counter == 1); // expected-warning{{TRUE}}
535   }
537   struct double_virtual_subclass : public virtual virtual_subclass {
538     double_virtual_subclass() {}
539   };
541   void testVirtual() {
542     counter = 0;
543     double_virtual_subclass obj;
544     clang_analyzer_eval(counter == 1); // expected-warning{{TRUE}}
545   }
548 namespace ZeroInitialization {
549   struct raw_pair {
550     int p1;
551     int p2;
552   };
554   void testVarDecl() {
555     raw_pair p{};
556     clang_analyzer_eval(p.p1 == 0); // expected-warning{{TRUE}}
557     clang_analyzer_eval(p.p2 == 0); // expected-warning{{TRUE}}
558   }
560   void testTemporary() {
561     clang_analyzer_eval(raw_pair().p1 == 0); // expected-warning{{TRUE}}
562     clang_analyzer_eval(raw_pair().p2 == 0); // expected-warning{{TRUE}}
563   }
565   void testArray() {
566     raw_pair p[2] = {};
567     clang_analyzer_eval(p[0].p1 == 0); // expected-warning{{TRUE}}
568     clang_analyzer_eval(p[0].p2 == 0); // expected-warning{{TRUE}}
569     clang_analyzer_eval(p[1].p1 == 0); // expected-warning{{TRUE}}
570     clang_analyzer_eval(p[1].p2 == 0); // expected-warning{{TRUE}}
571   }
573   void testNew() {
574     raw_pair *pp = new raw_pair();
575     clang_analyzer_eval(pp->p1 == 0); // expected-warning{{TRUE}}
576     clang_analyzer_eval(pp->p2 == 0); // expected-warning{{TRUE}}
577   }
579   void testArrayNew() {
580     raw_pair *p = new raw_pair[2]();
581     clang_analyzer_eval(p[0].p1 == 0); // expected-warning{{TRUE}}
582     clang_analyzer_eval(p[0].p2 == 0); // expected-warning{{TRUE}}
583     clang_analyzer_eval(p[1].p1 == 0); // expected-warning{{TRUE}}
584     clang_analyzer_eval(p[1].p2 == 0); // expected-warning{{TRUE}}
585   }
587   struct initializing_pair {
588   public:
589     int x;
590     raw_pair y;
591     initializing_pair() : x(), y() {}
592   };
593   
594   void testFieldInitializers() {
595     initializing_pair p;
596     clang_analyzer_eval(p.x == 0); // expected-warning{{TRUE}}
597     clang_analyzer_eval(p.y.p1 == 0); // expected-warning{{TRUE}}
598     clang_analyzer_eval(p.y.p2 == 0); // expected-warning{{TRUE}}
599   }
601   struct subclass : public raw_pair {
602     subclass() = default;
603   };
605   void testSubclass() {
606     subclass p;
607     clang_analyzer_eval(p.p1 == 0); // expected-warning{{garbage}}
608   }
610   struct initializing_subclass : public raw_pair {
611     initializing_subclass() : raw_pair() {}
612   };
614   void testInitializingSubclass() {
615     initializing_subclass p;
616     clang_analyzer_eval(p.p1 == 0); // expected-warning{{TRUE}}
617     clang_analyzer_eval(p.p2 == 0); // expected-warning{{TRUE}}
618   }
620   struct pair_wrapper {
621     pair_wrapper() : p() {}
622     raw_pair p;
623   };
625   struct virtual_subclass : public virtual pair_wrapper {
626     virtual_subclass() {}
627   };
629   struct double_virtual_subclass : public virtual_subclass {
630     double_virtual_subclass() {
631       // This previously caused a crash because the pair_wrapper subobject was
632       // initialized twice.
633     }
634   };
636   class Empty {
637   public:
638     static int glob;
639     Empty(); // No body.
640     Empty(int x); // Body below.
641   };
643   class PairContainer : public Empty {
644   public:
645     raw_pair p;
646     int q;
647     PairContainer() : Empty(), p() {
648       // This previously caused a crash because the empty base class looked
649       // like an initialization of 'p'.
650     }
651     PairContainer(int) : Empty(), p() {
652       // Test inlining something else here.
653     }
654     PairContainer(double): Empty(1), p() {
655       clang_analyzer_eval(p.p1 == 0); // expected-warning{{TRUE}}
656       clang_analyzer_eval(p.p2 == 0); // expected-warning{{TRUE}}
658       clang_analyzer_eval(q == 1); // expected-warning{{TRUE}}
660       // This one's indeed UNKNOWN. Definitely not TRUE.
661       clang_analyzer_eval(p.p2 == glob); // expected-warning{{UNKNOWN}}
662     }
663   };
665   Empty::Empty(int x) {
666     static_cast<PairContainer *>(this)->p.p1 = x;
667     static_cast<PairContainer *>(this)->q = x;
668     // Our static member will store the old garbage values of fields that aren't
669     // yet initialized. It's not certainly garbage though (i.e. the constructor
670     // could have been called on an initialized piece of memory), so no
671     // uninitialized value warning here, and it should be a symbol, not
672     // undefined value, for later comparison.
673     glob = static_cast<PairContainer *>(this)->p.p2;
674   }
676         class Empty2 {
677         public:
678                 static int glob_p1, glob_p2;
679                 Empty2(); // Body below.
680         };
682         class PairDoubleEmptyContainer: public Empty, public Empty2 {
683         public:
684     raw_pair p;
685                 PairDoubleEmptyContainer(): Empty(), Empty2(), p() {
686       clang_analyzer_eval(p.p1 == 0); // expected-warning{{TRUE}}
687       clang_analyzer_eval(p.p2 == 0); // expected-warning{{TRUE}}
689       // This is indeed UNKNOWN.
690       clang_analyzer_eval(p.p1 == glob_p1); // expected-warning{{UNKNOWN}}
691       clang_analyzer_eval(p.p2 == glob_p2); // expected-warning{{UNKNOWN}}
692                 }
693         };
695         Empty2::Empty2() {
696     glob_p1 = static_cast<PairDoubleEmptyContainer *>(this)->p.p1;
697     glob_p2 = static_cast<PairDoubleEmptyContainer *>(this)->p.p2;
698         }
700   class PairContainerContainer {
701     int padding;
702     PairContainer pc;
703   public:
704     PairContainerContainer() : pc(1) {}
705   };
708 namespace InitializerList {
709   struct List {
710     bool usedInitializerList;
712     List() : usedInitializerList(false) {}
713     List(std::initializer_list<int>) : usedInitializerList(true) {}
714   };
716   void testStatic() {
717     List defaultCtor;
718     clang_analyzer_eval(!defaultCtor.usedInitializerList); // expected-warning{{TRUE}}
720     List list{1, 2};
721     clang_analyzer_eval(list.usedInitializerList); // expected-warning{{TRUE}}
722   }
724   void testDynamic() {
725     List *list = new List{1, 2};
726     clang_analyzer_eval(list->usedInitializerList); // expected-warning{{TRUE}}
727   }
730 namespace PR19579 {
731   class C {};
733   void f() {
734     C();
735     int a;
737     extern void use(int);
738     use(a); // expected-warning{{uninitialized}}
739   }
741   void g() {
742     struct S {
743       C c;
744       int i;
745     };
746     
747     // This order triggers the initialization of the inner "a" after the
748     // constructor for "C" is run, which used to confuse the analyzer
749     // (is "C()" the initialization of "a"?).
750     struct S s = {
751       C(),
752       ({
753         int a, b = 0;
754         0;
755       })
756     };
757   }
760 namespace NoCrashOnEmptyBaseOptimization {
761   struct NonEmptyBase {
762     int X;
763     explicit NonEmptyBase(int X) : X(X) {}
764   };
766   struct EmptyBase {};
768   struct S : NonEmptyBase, EmptyBase {
769     S() : NonEmptyBase(0), EmptyBase() {}
770   };
772   void testSCtorNoCrash() {
773     S s;
774   }
777 namespace EmptyBaseAssign {
778 struct B1 {};
779 struct B2 { int x; };
780 struct D: public B1, public B2 {
781 const D &operator=(const D &d) {
782   *((B2 *)this) = d;
783   *((B1 *)this) = d;
784   return *this;
788 void test() {
789   D d1;
790   d1.x = 1;
791   D d2;
792   d2 = d1;
793   clang_analyzer_eval(d2.x == 1); // expected-warning{{TRUE}}
797 namespace vbase_zero_init {
798 class A {
799   virtual void foo();
802 class B {
803   virtual void bar();
804 public:
805   static int glob_y, glob_z, glob_w;
806   int x;
807   B(); // Body below.
810 class C : virtual public A {
811 public:
812   int y;
815 class D : public B, public C {
816 public:
817   // 'z', unlike 'w', resides in an area that would have been within padding of
818   // base class 'C' if it wasn't part of 'D', but only on 64-bit systems.
819   int z, w;
820   // Initialization order: A(), B(), C().
821   D() : A(), C() {
822     clang_analyzer_eval(x == 1); // expected-warning{{TRUE}}
823     clang_analyzer_eval(y == 0); // expected-warning{{TRUE}}
824 #ifdef I386
825     clang_analyzer_eval(z == 3); // expected-warning{{TRUE}}
826 #else
827     // FIXME: Should be TRUE. Initialized in B().
828     clang_analyzer_eval(z == 3); // expected-warning{{UNKNOWN}}
829 #endif
830     clang_analyzer_eval(w == 4); // expected-warning{{TRUE}}
832     // FIXME: Should be UNKNOWN. Changed in B() since glob_y was assigned.
833     clang_analyzer_eval(y == glob_y); // expected-warning{{TRUE}}
835 #ifdef I386
836     clang_analyzer_eval(z == glob_z); // expected-warning{{UNKNOWN}}
837 #else
838     // FIXME: Should be UNKNOWN. Changed in B() since glob_z was assigned.
839     clang_analyzer_eval(z == glob_z); // expected-warning{{TRUE}}
840 #endif
842     clang_analyzer_eval(w == glob_w); // expected-warning{{UNKNOWN}}
843   } // no-crash
846 B::B() : x(1) {
847   // Our static members will store the old garbage values of fields that aren't
848   // yet initialized. These aren't certainly garbage though (i.e. the
849   // constructor could have been called on an initialized piece of memory),
850   // so no uninitialized value warning here, and these should be symbols, not
851   // undefined values, for later comparison.
852   glob_y = static_cast<D *>(this)->y;
853   glob_z = static_cast<D *>(this)->z;
854   glob_w = static_cast<D *>(this)->w;
855   static_cast<D *>(this)->y = 2;
856   static_cast<D *>(this)->z = 3;
857   static_cast<D *>(this)->w = 4;