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