1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \
2 // RUN:   -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \
3 // RUN:   -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
4 // RUN:   -std=c++14 -verify  %s
5 
6 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \
7 // RUN:   -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
8 // RUN:   -std=c++14 -verify  %s
9 
10 //===----------------------------------------------------------------------===//
11 // Default constructor test.
12 //===----------------------------------------------------------------------===//
13 
14 class CompilerGeneratedConstructorTest {
15   int a, b, c, d, e, f, g, h, i, j;
16 
17 public:
18   CompilerGeneratedConstructorTest() = default;
19 };
20 
21 void fCompilerGeneratedConstructorTest() {
22   CompilerGeneratedConstructorTest();
23 }
24 
25 #ifdef PEDANTIC
26 class DefaultConstructorTest {
27   int a; // expected-note{{uninitialized field 'this->a'}}
28 
29 public:
30   DefaultConstructorTest();
31 };
32 
33 DefaultConstructorTest::DefaultConstructorTest() = default;
34 
35 void fDefaultConstructorTest() {
36   DefaultConstructorTest(); // expected-warning{{1 uninitialized field}}
37 }
38 #else
39 class DefaultConstructorTest {
40   int a;
41 
42 public:
43   DefaultConstructorTest();
44 };
45 
46 DefaultConstructorTest::DefaultConstructorTest() = default;
47 
48 void fDefaultConstructorTest() {
49   DefaultConstructorTest();
50 }
51 #endif // PEDANTIC
52 
53 //===----------------------------------------------------------------------===//
54 // Initializer list test.
55 //===----------------------------------------------------------------------===//
56 
57 class InitListTest1 {
58   int a;
59   int b;
60 
61 public:
62   InitListTest1()
63       : a(1),
64         b(2) {
65     // All good!
66   }
67 };
68 
69 void fInitListTest1() {
70   InitListTest1();
71 }
72 
73 class InitListTest2 {
74   int a;
75   int b; // expected-note{{uninitialized field 'this->b'}}
76 
77 public:
78   InitListTest2()
79       : a(3) {} // expected-warning{{1 uninitialized field}}
80 };
81 
82 void fInitListTest2() {
83   InitListTest2();
84 }
85 
86 class InitListTest3 {
87   int a; // expected-note{{uninitialized field 'this->a'}}
88   int b;
89 
90 public:
91   InitListTest3()
92       : b(4) {} // expected-warning{{1 uninitialized field}}
93 };
94 
95 void fInitListTest3() {
96   InitListTest3();
97 }
98 
99 //===----------------------------------------------------------------------===//
100 // Constructor body test.
101 //===----------------------------------------------------------------------===//
102 
103 class CtorBodyTest1 {
104   int a, b;
105 
106 public:
107   CtorBodyTest1() {
108     a = 5;
109     b = 6;
110     // All good!
111   }
112 };
113 
114 void fCtorBodyTest1() {
115   CtorBodyTest1();
116 }
117 
118 class CtorBodyTest2 {
119   int a;
120   int b; // expected-note{{uninitialized field 'this->b'}}
121 
122 public:
123   CtorBodyTest2() {
124     a = 7; // expected-warning{{1 uninitialized field}}
125   }
126 };
127 
128 void fCtorBodyTest2() {
129   CtorBodyTest2();
130 }
131 
132 class CtorBodyTest3 {
133   int a; // expected-note{{uninitialized field 'this->a'}}
134   int b;
135 
136 public:
137   CtorBodyTest3() {
138     b = 8; // expected-warning{{1 uninitialized field}}
139   }
140 };
141 
142 void fCtorBodyTest3() {
143   CtorBodyTest3();
144 }
145 
146 #ifdef PEDANTIC
147 class CtorBodyTest4 {
148   int a; // expected-note{{uninitialized field 'this->a'}}
149   int b; // expected-note{{uninitialized field 'this->b'}}
150 
151 public:
152   CtorBodyTest4() {}
153 };
154 
155 void fCtorBodyTest4() {
156   CtorBodyTest4(); // expected-warning{{2 uninitialized fields}}
157 }
158 #else
159 class CtorBodyTest4 {
160   int a;
161   int b;
162 
163 public:
164   CtorBodyTest4() {}
165 };
166 
167 void fCtorBodyTest4() {
168   CtorBodyTest4();
169 }
170 #endif
171 
172 //===----------------------------------------------------------------------===//
173 // Constructor delegation test.
174 //===----------------------------------------------------------------------===//
175 
176 class CtorDelegationTest1 {
177   int a;
178   int b;
179 
180 public:
181   CtorDelegationTest1(int)
182       : a(9) {
183     // leaves 'b' unintialized, but we'll never check this function
184   }
185 
186   CtorDelegationTest1()
187       : CtorDelegationTest1(int{}) { // Initializing 'a'
188     b = 10;
189     // All good!
190   }
191 };
192 
193 void fCtorDelegationTest1() {
194   CtorDelegationTest1();
195 }
196 
197 class CtorDelegationTest2 {
198   int a; // expected-note{{uninitialized field 'this->a'}}
199   int b;
200 
201 public:
202   CtorDelegationTest2(int)
203       : b(11) {
204     // leaves 'a' unintialized, but we'll never check this function
205   }
206 
207   CtorDelegationTest2()
208       : CtorDelegationTest2(int{}) { // expected-warning{{1 uninitialized field}}
209   }
210 };
211 
212 void fCtorDelegationTest2() {
213   CtorDelegationTest2();
214 }
215 
216 //===----------------------------------------------------------------------===//
217 // Tests for classes containing records.
218 //===----------------------------------------------------------------------===//
219 
220 class ContainsRecordTest1 {
221   struct RecordType {
222     int x;
223     int y;
224   } rec;
225   int c, d;
226 
227 public:
228   ContainsRecordTest1()
229       : rec({12, 13}),
230         c(14),
231         d(15) {
232     // All good!
233   }
234 };
235 
236 void fContainsRecordTest1() {
237   ContainsRecordTest1();
238 }
239 
240 class ContainsRecordTest2 {
241   struct RecordType {
242     int x;
243     int y; // expected-note{{uninitialized field 'this->rec.y'}}
244   } rec;
245   int c, d;
246 
247 public:
248   ContainsRecordTest2()
249       : c(16),
250         d(17) {
251     rec.x = 18; // expected-warning{{1 uninitialized field}}
252   }
253 };
254 
255 void fContainsRecordTest2() {
256   ContainsRecordTest2();
257 }
258 
259 class ContainsRecordTest3 {
260   struct RecordType {
261     int x; // expected-note{{uninitialized field 'this->rec.x'}}
262     int y; // expected-note{{uninitialized field 'this->rec.y'}}
263   } rec;
264   int c, d;
265 
266 public:
267   ContainsRecordTest3()
268       : c(19),
269         d(20) { // expected-warning{{2 uninitialized fields}}
270   }
271 };
272 
273 void fContainsRecordTest3() {
274   ContainsRecordTest3();
275 }
276 
277 class ContainsRecordTest4 {
278   struct RecordType {
279     int x; // expected-note{{uninitialized field 'this->rec.x'}}
280     int y; // expected-note{{uninitialized field 'this->rec.y'}}
281   } rec;
282   int c, d; // expected-note{{uninitialized field 'this->d'}}
283 
284 public:
285   ContainsRecordTest4()
286       : c(19) { // expected-warning{{3 uninitialized fields}}
287   }
288 };
289 
290 void fContainsRecordTest4() {
291   ContainsRecordTest4();
292 }
293 
294 //===----------------------------------------------------------------------===//
295 // Tests for template classes.
296 //===----------------------------------------------------------------------===//
297 
298 template <class T>
299 class IntTemplateClassTest1 {
300   T t;
301   int b;
302 
303 public:
304   IntTemplateClassTest1(T i) {
305     b = 21;
306     t = i;
307     // All good!
308   }
309 };
310 
311 void fIntTemplateClassTest1() {
312   IntTemplateClassTest1<int>(22);
313 }
314 
315 template <class T>
316 class IntTemplateClassTest2 {
317   T t; // expected-note{{uninitialized field 'this->t'}}
318   int b;
319 
320 public:
321   IntTemplateClassTest2() {
322     b = 23; // expected-warning{{1 uninitialized field}}
323   }
324 };
325 
326 void fIntTemplateClassTest2() {
327   IntTemplateClassTest2<int>();
328 }
329 
330 struct Record {
331   int x; // expected-note{{uninitialized field 'this->t.x'}}
332   int y; // expected-note{{uninitialized field 'this->t.y'}}
333 };
334 
335 template <class T>
336 class RecordTemplateClassTest {
337   T t;
338   int b;
339 
340 public:
341   RecordTemplateClassTest() {
342     b = 24; // expected-warning{{2 uninitialized fields}}
343   }
344 };
345 
346 void fRecordTemplateClassTest() {
347   RecordTemplateClassTest<Record>();
348 }
349 
350 //===----------------------------------------------------------------------===//
351 // Tests involving functions with unknown implementations.
352 //===----------------------------------------------------------------------===//
353 
354 template <class T>
355 void mayInitialize(T &);
356 
357 template <class T>
358 void wontInitialize(const T &);
359 
360 class PassingToUnknownFunctionTest1 {
361   int a, b; // expected-note{{uninitialized field 'this->b'}}
362 
363 public:
364   PassingToUnknownFunctionTest1() {
365     mayInitialize(a);
366     mayInitialize(b);
367     // All good!
368   }
369 
370   PassingToUnknownFunctionTest1(int) {
371     mayInitialize(a); // expected-warning{{1 uninitialized field at the end of the constructor call}}
372   }
373 
374   PassingToUnknownFunctionTest1(int, int) {
375     mayInitialize(*this);
376     // All good!
377   }
378 };
379 
380 void fPassingToUnknownFunctionTest1() {
381   PassingToUnknownFunctionTest1();
382   PassingToUnknownFunctionTest1(int());
383   PassingToUnknownFunctionTest1(int(), int());
384 }
385 
386 class PassingToUnknownFunctionTest2 {
387   int a; // expected-note{{uninitialized field 'this->a'}}
388   int b;
389 
390 public:
391   PassingToUnknownFunctionTest2() {
392     wontInitialize(a);
393     b = 4; // expected-warning{{1 uninitialized field}}
394   }
395 };
396 
397 void fPassingToUnknownFunctionTest2() {
398   PassingToUnknownFunctionTest2();
399 }
400 
401 //===----------------------------------------------------------------------===//
402 // Tests for classes containing unions.
403 //===----------------------------------------------------------------------===//
404 
405 // FIXME: As of writing this checker, there is no good support for union types
406 // in the Static Analyzer. Here is non-exhaustive list of cases.
407 // Note that the rules for unions are different in C and C++.
408 // http://lists.llvm.org/pipermail/cfe-dev/2017-March/052910.html
409 
410 class ContainsSimpleUnionTest1 {
411   union SimpleUnion {
412     float uf;
413     int ui;
414     char uc;
415   } u;
416 
417 public:
418   ContainsSimpleUnionTest1() {
419     u.uf = 3.14;
420     // All good!
421   }
422 };
423 
424 void fContainsSimpleUnionTest1() {
425   ContainsSimpleUnionTest1();
426 }
427 
428 class ContainsSimpleUnionTest2 {
429   union SimpleUnion {
430     float uf;
431     int ui;
432     char uc;
433     // TODO: we'd expect the note: {{uninitialized field 'this->u'}}
434   } u; // no-note
435 
436 public:
437   ContainsSimpleUnionTest2() {}
438 };
439 
440 void fContainsSimpleUnionTest2() {
441   // TODO: we'd expect the warning: {{1 uninitialized field}}
442   ContainsSimpleUnionTest2(); // no-warning
443 }
444 
445 class UnionPointerTest1 {
446 public:
447   union SimpleUnion {
448     float uf;
449     int ui;
450     char uc;
451   };
452 
453 private:
454   SimpleUnion *uptr;
455 
456 public:
457   UnionPointerTest1(SimpleUnion *uptr, int) : uptr(uptr) {
458     // All good!
459   }
460 };
461 
462 void fUnionPointerTest1() {
463   UnionPointerTest1::SimpleUnion u;
464   u.uf = 41;
465   UnionPointerTest1(&u, int());
466 }
467 
468 class UnionPointerTest2 {
469 public:
470   union SimpleUnion {
471     float uf;
472     int ui;
473     char uc;
474   };
475 
476 private:
477   // TODO: we'd expect the note: {{uninitialized field 'this->uptr'}}
478   SimpleUnion *uptr; // no-note
479 
480 public:
481   UnionPointerTest2(SimpleUnion *uptr, char) : uptr(uptr) {}
482 };
483 
484 void fUnionPointerTest2() {
485   UnionPointerTest2::SimpleUnion u;
486   // TODO: we'd expect the warning: {{1 uninitialized field}}
487   UnionPointerTest2(&u, int()); // no-warning
488 }
489 
490 class ContainsUnionWithRecordTest1 {
491   union UnionWithRecord {
492     struct RecordType {
493       int x;
494       int y;
495     } us;
496     double ud;
497     long ul;
498 
499     UnionWithRecord(){};
500   } u;
501 
502 public:
503   ContainsUnionWithRecordTest1() {
504     u.ud = 3.14;
505     // All good!
506   }
507 };
508 
509 void fContainsUnionWithRecordTest1() {
510   ContainsUnionWithRecordTest1();
511 }
512 
513 class ContainsUnionWithRecordTest2 {
514   union UnionWithRecord {
515     struct RecordType {
516       int x;
517       int y;
518     } us;
519     double ud;
520     long ul;
521 
522     UnionWithRecord(){};
523   } u;
524 
525 public:
526   ContainsUnionWithRecordTest2() {
527     u.us = UnionWithRecord::RecordType{42, 43};
528     // All good!
529   }
530 };
531 
532 void fContainsUnionWithRecordTest2() {
533   ContainsUnionWithRecordTest1();
534 }
535 
536 class ContainsUnionWithRecordTest3 {
537   union UnionWithRecord {
538     struct RecordType {
539       int x;
540       int y;
541     } us;
542     double ud;
543     long ul;
544 
545     UnionWithRecord(){};
546     // TODO: we'd expect the note: {{uninitialized field 'this->u'}}
547   } u; // no-note
548 
549 public:
550   ContainsUnionWithRecordTest3() {
551     UnionWithRecord::RecordType rec;
552     rec.x = 44;
553     // TODO: we'd expect the warning: {{1 uninitialized field}}
554     u.us = rec; // no-warning
555   }
556 };
557 
558 void fContainsUnionWithRecordTest3() {
559   ContainsUnionWithRecordTest3();
560 }
561 
562 class ContainsUnionWithSimpleUnionTest1 {
563   union UnionWithSimpleUnion {
564     union SimpleUnion {
565       float uf;
566       int ui;
567       char uc;
568     } usu;
569     long ul;
570     unsigned uu;
571   } u;
572 
573 public:
574   ContainsUnionWithSimpleUnionTest1() {
575     u.usu.ui = 5;
576     // All good!
577   }
578 };
579 
580 void fContainsUnionWithSimpleUnionTest1() {
581   ContainsUnionWithSimpleUnionTest1();
582 }
583 
584 class ContainsUnionWithSimpleUnionTest2 {
585   union UnionWithSimpleUnion {
586     union SimpleUnion {
587       float uf;
588       int ui;
589       char uc;
590     } usu;
591     long ul;
592     unsigned uu;
593     // TODO: we'd expect the note: {{uninitialized field 'this->u'}}
594   } u; // no-note
595 
596 public:
597   ContainsUnionWithSimpleUnionTest2() {}
598 };
599 
600 void fContainsUnionWithSimpleUnionTest2() {
601   // TODO: we'd expect the warning: {{1 uninitialized field}}
602   ContainsUnionWithSimpleUnionTest2(); // no-warning
603 }
604 
605 //===----------------------------------------------------------------------===//
606 // Zero initialization tests.
607 //===----------------------------------------------------------------------===//
608 
609 struct GlobalVariableTest {
610   int i;
611 
612   GlobalVariableTest() {}
613 };
614 
615 GlobalVariableTest gvt; // no-warning
616 
617 //===----------------------------------------------------------------------===//
618 // Copy and move constructor tests.
619 //===----------------------------------------------------------------------===//
620 
621 template <class T>
622 void funcToSquelchCompilerWarnings(const T &t);
623 
624 #ifdef PEDANTIC
625 struct CopyConstructorTest {
626   int i; // expected-note{{uninitialized field 'this->i'}}
627 
628   CopyConstructorTest() : i(1337) {}
629   CopyConstructorTest(const CopyConstructorTest &other) {}
630 };
631 
632 void fCopyConstructorTest() {
633   CopyConstructorTest cct;
634   CopyConstructorTest copy = cct; // expected-warning{{1 uninitialized field}}
635   funcToSquelchCompilerWarnings(copy);
636 }
637 #else
638 struct CopyConstructorTest {
639   int i;
640 
641   CopyConstructorTest() : i(1337) {}
642   CopyConstructorTest(const CopyConstructorTest &other) {}
643 };
644 
645 void fCopyConstructorTest() {
646   CopyConstructorTest cct;
647   CopyConstructorTest copy = cct;
648   funcToSquelchCompilerWarnings(copy);
649 }
650 #endif // PEDANTIC
651 
652 struct MoveConstructorTest {
653   // TODO: we'd expect the note: {{uninitialized field 'this->i'}}
654   int i; // no-note
655 
656   MoveConstructorTest() : i(1337) {}
657   MoveConstructorTest(const CopyConstructorTest &other) = delete;
658   MoveConstructorTest(const CopyConstructorTest &&other) {}
659 };
660 
661 void fMoveConstructorTest() {
662   MoveConstructorTest cct;
663   // TODO: we'd expect the warning: {{1 uninitialized field}}
664   MoveConstructorTest copy(static_cast<MoveConstructorTest &&>(cct)); // no-warning
665   funcToSquelchCompilerWarnings(copy);
666 }
667 
668 //===----------------------------------------------------------------------===//
669 // Array tests.
670 //===----------------------------------------------------------------------===//
671 
672 struct IntArrayTest {
673   int arr[256];
674 
675   IntArrayTest() {
676     // All good!
677   }
678 };
679 
680 void fIntArrayTest() {
681   IntArrayTest();
682 }
683 
684 struct RecordTypeArrayTest {
685   struct RecordType {
686     int x, y;
687   } arr[256];
688 
689   RecordTypeArrayTest() {
690     // All good!
691   }
692 };
693 
694 void fRecordTypeArrayTest() {
695   RecordTypeArrayTest();
696 }
697 
698 template <class T>
699 class CharArrayPointerTest {
700   T *t; // no-crash
701 
702 public:
703   CharArrayPointerTest(T *t, int) : t(t) {}
704 };
705 
706 void fCharArrayPointerTest() {
707   char str[16] = "012345678912345";
708   CharArrayPointerTest<char[16]>(&str, int());
709 }
710 
711 //===----------------------------------------------------------------------===//
712 // Memset tests.
713 //===----------------------------------------------------------------------===//
714 
715 struct MemsetTest1 {
716   int a, b, c;
717 
718   MemsetTest1() {
719     __builtin_memset(this, 0, sizeof(decltype(*this)));
720   }
721 };
722 
723 void fMemsetTest1() {
724   MemsetTest1();
725 }
726 
727 struct MemsetTest2 {
728   int a;
729 
730   MemsetTest2() {
731     __builtin_memset(&a, 0, sizeof(int));
732   }
733 };
734 
735 void fMemsetTest2() {
736   MemsetTest2();
737 }
738 
739 //===----------------------------------------------------------------------===//
740 // Lambda tests.
741 //===----------------------------------------------------------------------===//
742 
743 template <class Callable>
744 struct LambdaThisTest {
745   Callable functor;
746 
747   LambdaThisTest(const Callable &functor, int) : functor(functor) {
748     // All good!
749   }
750 };
751 
752 struct HasCapturableThis {
753   void fLambdaThisTest() {
754     auto isEven = [this](int a) { return a % 2 == 0; }; // no-crash
755     LambdaThisTest<decltype(isEven)>(isEven, int());
756   }
757 };
758 
759 template <class Callable>
760 struct LambdaTest1 {
761   Callable functor;
762 
763   LambdaTest1(const Callable &functor, int) : functor(functor) {
764     // All good!
765   }
766 };
767 
768 void fLambdaTest1() {
769   auto isEven = [](int a) { return a % 2 == 0; };
770   LambdaTest1<decltype(isEven)>(isEven, int());
771 }
772 
773 #ifdef PEDANTIC
774 template <class Callable>
775 struct LambdaTest2 {
776   Callable functor;
777 
778   LambdaTest2(const Callable &functor, int) : functor(functor) {} // expected-warning{{1 uninitialized field}}
779 };
780 
781 void fLambdaTest2() {
782   int b;
783   auto equals = [&b](int a) { return a == b; }; // expected-note{{uninitialized pointee 'this->functor./*captured variable*/b'}}
784   LambdaTest2<decltype(equals)>(equals, int());
785 }
786 #else
787 template <class Callable>
788 struct LambdaTest2 {
789   Callable functor;
790 
791   LambdaTest2(const Callable &functor, int) : functor(functor) {}
792 };
793 
794 void fLambdaTest2() {
795   int b;
796   auto equals = [&b](int a) { return a == b; };
797   LambdaTest2<decltype(equals)>(equals, int());
798 }
799 #endif //PEDANTIC
800 
801 #ifdef PEDANTIC
802 namespace LT3Detail {
803 
804 struct RecordType {
805   int x; // expected-note{{uninitialized field 'this->functor./*captured variable*/rec1.x'}}
806   int y; // expected-note{{uninitialized field 'this->functor./*captured variable*/rec1.y'}}
807 };
808 
809 } // namespace LT3Detail
810 template <class Callable>
811 struct LambdaTest3 {
812   Callable functor;
813 
814   LambdaTest3(const Callable &functor, int) : functor(functor) {} // expected-warning{{2 uninitialized fields}}
815 };
816 
817 void fLambdaTest3() {
818   LT3Detail::RecordType rec1;
819   auto equals = [&rec1](LT3Detail::RecordType rec2) {
820     return rec1.x == rec2.x;
821   };
822   LambdaTest3<decltype(equals)>(equals, int());
823 }
824 #else
825 namespace LT3Detail {
826 
827 struct RecordType {
828   int x;
829   int y;
830 };
831 
832 } // namespace LT3Detail
833 template <class Callable>
834 struct LambdaTest3 {
835   Callable functor;
836 
837   LambdaTest3(const Callable &functor, int) : functor(functor) {}
838 };
839 
840 void fLambdaTest3() {
841   LT3Detail::RecordType rec1;
842   auto equals = [&rec1](LT3Detail::RecordType rec2) {
843     return rec1.x == rec2.x;
844   };
845   LambdaTest3<decltype(equals)>(equals, int());
846 }
847 #endif //PEDANTIC
848 
849 template <class Callable>
850 struct MultipleLambdaCapturesTest1 {
851   Callable functor;
852   int dontGetFilteredByNonPedanticMode = 0;
853 
854   MultipleLambdaCapturesTest1(const Callable &functor, int) : functor(functor) {} // expected-warning{{2 uninitialized field}}
855 };
856 
857 void fMultipleLambdaCapturesTest1() {
858   int b1, b2 = 3, b3;
859   auto equals = [&b1, &b2, &b3](int a) { return a == b1 == b2 == b3; }; // expected-note{{uninitialized pointee 'this->functor./*captured variable*/b1'}}
860   // expected-note@-1{{uninitialized pointee 'this->functor./*captured variable*/b3'}}
861   MultipleLambdaCapturesTest1<decltype(equals)>(equals, int());
862 }
863 
864 template <class Callable>
865 struct MultipleLambdaCapturesTest2 {
866   Callable functor;
867   int dontGetFilteredByNonPedanticMode = 0;
868 
869   MultipleLambdaCapturesTest2(const Callable &functor, int) : functor(functor) {} // expected-warning{{1 uninitialized field}}
870 };
871 
872 void fMultipleLambdaCapturesTest2() {
873   int b1, b2 = 3, b3;
874   auto equals = [b1, &b2, &b3](int a) { return a == b1 == b2 == b3; }; // expected-note{{uninitialized pointee 'this->functor./*captured variable*/b3'}}
875   MultipleLambdaCapturesTest2<decltype(equals)>(equals, int());
876 }
877 
878 struct LambdaWrapper {
879   void *func; // no-crash
880   int dontGetFilteredByNonPedanticMode = 0;
881 
882   LambdaWrapper(void *ptr) : func(ptr) {} // expected-warning{{1 uninitialized field}}
883 };
884 
885 struct ThisCapturingLambdaFactory {
886   int a; // expected-note{{uninitialized field 'static_cast<decltype(a.ret()) *>(this->func)->/*'this' capture*/->a'}}
887 
888   auto ret() {
889     return [this] { (void)this; };
890   }
891 };
892 
893 void fLambdaFieldWithInvalidThisCapture() {
894   void *ptr;
895   {
896     ThisCapturingLambdaFactory a;
897     decltype(a.ret()) lambda = a.ret();
898     ptr = &lambda;
899   }
900   LambdaWrapper t(ptr);
901 }
902 
903 //===----------------------------------------------------------------------===//
904 // System header tests.
905 //===----------------------------------------------------------------------===//
906 
907 #include "Inputs/system-header-simulator-for-cxx-uninitialized-object.h"
908 
909 struct SystemHeaderTest1 {
910   RecordInSystemHeader rec; // defined in the system header simulator
911 
912   SystemHeaderTest1() {
913     // All good!
914   }
915 };
916 
917 void fSystemHeaderTest1() {
918   SystemHeaderTest1();
919 }
920 
921 #ifdef PEDANTIC
922 struct SystemHeaderTest2 {
923   struct RecordType {
924     int x; // expected-note{{uninitialized field 'this->container.t.x}}
925     int y; // expected-note{{uninitialized field 'this->container.t.y}}
926   };
927   ContainerInSystemHeader<RecordType> container;
928 
929   SystemHeaderTest2(RecordType &rec, int) : container(rec) {} // expected-warning{{2 uninitialized fields}}
930 };
931 
932 void fSystemHeaderTest2() {
933   SystemHeaderTest2::RecordType rec;
934   SystemHeaderTest2(rec, int());
935 }
936 #else
937 struct SystemHeaderTest2 {
938   struct RecordType {
939     int x;
940     int y;
941   };
942   ContainerInSystemHeader<RecordType> container;
943 
944   SystemHeaderTest2(RecordType &rec, int) : container(rec) {}
945 };
946 
947 void fSystemHeaderTest2() {
948   SystemHeaderTest2::RecordType rec;
949   SystemHeaderTest2(rec, int());
950 }
951 #endif //PEDANTIC
952 
953 //===----------------------------------------------------------------------===//
954 // Incomplete type tests.
955 //===----------------------------------------------------------------------===//
956 
957 struct IncompleteTypeTest1 {
958   struct RecordType;
959   // no-crash
960   RecordType *recptr; // expected-note{{uninitialized pointer 'this->recptr}}
961   int dontGetFilteredByNonPedanticMode = 0;
962 
963   IncompleteTypeTest1() {} // expected-warning{{1 uninitialized field}}
964 };
965 
966 void fIncompleteTypeTest1() {
967   IncompleteTypeTest1();
968 }
969 
970 struct IncompleteTypeTest2 {
971   struct RecordType;
972   RecordType *recptr; // no-crash
973   int dontGetFilteredByNonPedanticMode = 0;
974 
975   RecordType *recordTypeFactory();
976 
977   IncompleteTypeTest2() : recptr(recordTypeFactory()) {}
978 };
979 
980 void fIncompleteTypeTest2() {
981   IncompleteTypeTest2();
982 }
983 
984 struct IncompleteTypeTest3 {
985   struct RecordType;
986   RecordType &recref; // no-crash
987   int dontGetFilteredByNonPedanticMode = 0;
988 
989   RecordType &recordTypeFactory();
990 
991   IncompleteTypeTest3() : recref(recordTypeFactory()) {}
992 };
993 
994 void fIncompleteTypeTest3() {
995   IncompleteTypeTest3();
996 }
997 
998 //===----------------------------------------------------------------------===//
999 // Builtin type or enumeration type related tests.
1000 //===----------------------------------------------------------------------===//
1001 
1002 struct IntegralTypeTest {
1003   int a; // expected-note{{uninitialized field 'this->a'}}
1004   int dontGetFilteredByNonPedanticMode = 0;
1005 
1006   IntegralTypeTest() {} // expected-warning{{1 uninitialized field}}
1007 };
1008 
1009 void fIntegralTypeTest() {
1010   IntegralTypeTest();
1011 }
1012 
1013 struct FloatingTypeTest {
1014   float a; // expected-note{{uninitialized field 'this->a'}}
1015   int dontGetFilteredByNonPedanticMode = 0;
1016 
1017   FloatingTypeTest() {} // expected-warning{{1 uninitialized field}}
1018 };
1019 
1020 void fFloatingTypeTest() {
1021   FloatingTypeTest();
1022 }
1023 
1024 struct NullptrTypeTypeTest {
1025   decltype(nullptr) a; // expected-note{{uninitialized field 'this->a'}}
1026   int dontGetFilteredByNonPedanticMode = 0;
1027 
1028   NullptrTypeTypeTest() {} // expected-warning{{1 uninitialized field}}
1029 };
1030 
1031 void fNullptrTypeTypeTest() {
1032   NullptrTypeTypeTest();
1033 }
1034 
1035 struct EnumTest {
1036   enum Enum {
1037     A,
1038     B
1039   } enum1; // expected-note{{uninitialized field 'this->enum1'}}
1040   enum class Enum2 {
1041     A,
1042     B
1043   } enum2; // expected-note{{uninitialized field 'this->enum2'}}
1044   int dontGetFilteredByNonPedanticMode = 0;
1045 
1046   EnumTest() {} // expected-warning{{2 uninitialized fields}}
1047 };
1048 
1049 void fEnumTest() {
1050   EnumTest();
1051 }
1052 
1053 //===----------------------------------------------------------------------===//
1054 // Tests for constructor calls within another cunstructor, without the two
1055 // records being in any relation.
1056 //===----------------------------------------------------------------------===//
1057 
1058 void halt() __attribute__((__noreturn__));
1059 void assert(int b) {
1060   if (!b)
1061     halt();
1062 }
1063 
1064 // While a singleton would make more sense as a static variable, that would zero
1065 // initialize all of its fields, hence the not too practical implementation.
1066 struct Singleton {
1067   int i; // expected-note{{uninitialized field 'this->i'}}
1068   int dontGetFilteredByNonPedanticMode = 0;
1069 
1070   Singleton() {
1071     assert(!isInstantiated);
1072     isInstantiated = true; // expected-warning{{1 uninitialized field}}
1073   }
1074 
1075   ~Singleton() {
1076     isInstantiated = false;
1077   }
1078 
1079   static bool isInstantiated;
1080 };
1081 
1082 bool Singleton::isInstantiated = false;
1083 
1084 struct SingletonTest {
1085   int dontGetFilteredByNonPedanticMode = 0;
1086 
1087   SingletonTest() {
1088     Singleton();
1089   }
1090 };
1091 
1092 void fSingletonTest() {
1093   SingletonTest();
1094 }
1095 
1096 //===----------------------------------------------------------------------===//
1097 // C++11 member initializer tests.
1098 //===----------------------------------------------------------------------===//
1099 
1100 struct CXX11MemberInitTest1 {
1101   int a = 3;
1102   int b;
1103   CXX11MemberInitTest1() : b(2) {
1104     // All good!
1105   }
1106 };
1107 
1108 void fCXX11MemberInitTest1() {
1109   CXX11MemberInitTest1();
1110 }
1111 
1112 struct CXX11MemberInitTest2 {
1113   struct RecordType {
1114     // TODO: we'd expect the note: {{uninitialized field 'this->rec.a'}}
1115     int a; // no-note
1116     // TODO: we'd expect the note: {{uninitialized field 'this->rec.b'}}
1117     int b; // no-note
1118 
1119     RecordType(int) {}
1120   };
1121 
1122   RecordType rec = RecordType(int());
1123   int dontGetFilteredByNonPedanticMode = 0;
1124 
1125   CXX11MemberInitTest2() {}
1126 };
1127 
1128 void fCXX11MemberInitTest2() {
1129   // TODO: we'd expect the warning: {{2 uninitializeds field}}
1130   CXX11MemberInitTest2(); // no-warning
1131 }
1132