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++11 -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++11 -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;
362 
363 public:
364   PassingToUnknownFunctionTest1() {
365     mayInitialize(a);
366     mayInitialize(b);
367     // All good!
368   }
369 
370   PassingToUnknownFunctionTest1(int) {
371     mayInitialize(a);
372     // All good!
373   }
374 
375   PassingToUnknownFunctionTest1(int, int) {
376     mayInitialize(*this);
377     // All good!
378   }
379 };
380 
381 void fPassingToUnknownFunctionTest1() {
382   PassingToUnknownFunctionTest1();
383   PassingToUnknownFunctionTest1(int());
384   PassingToUnknownFunctionTest1(int(), int());
385 }
386 
387 class PassingToUnknownFunctionTest2 {
388   int a; // expected-note{{uninitialized field 'this->a'}}
389   int b;
390 
391 public:
392   PassingToUnknownFunctionTest2() {
393     wontInitialize(a);
394     b = 4; // expected-warning{{1 uninitialized field}}
395   }
396 };
397 
398 void fPassingToUnknownFunctionTest2() {
399   PassingToUnknownFunctionTest2();
400 }
401 
402 //===----------------------------------------------------------------------===//
403 // Tests for classes containing unions.
404 //===----------------------------------------------------------------------===//
405 
406 // FIXME: As of writing this checker, there is no good support for union types
407 // in the Static Analyzer. Here is non-exhaustive list of cases.
408 // Note that the rules for unions are different in C and C++.
409 // http://lists.llvm.org/pipermail/cfe-dev/2017-March/052910.html
410 
411 class ContainsSimpleUnionTest1 {
412   union SimpleUnion {
413     float uf;
414     int ui;
415     char uc;
416   } u;
417 
418 public:
419   ContainsSimpleUnionTest1() {
420     u.uf = 3.14;
421     // All good!
422   }
423 };
424 
425 void fContainsSimpleUnionTest1() {
426   ContainsSimpleUnionTest1();
427 }
428 
429 class ContainsSimpleUnionTest2 {
430   union SimpleUnion {
431     float uf;
432     int ui;
433     char uc;
434     // TODO: we'd expect the note: {{uninitialized field 'this->u'}}
435   } u; // no-note
436 
437 public:
438   ContainsSimpleUnionTest2() {}
439 };
440 
441 void fContainsSimpleUnionTest2() {
442   // TODO: we'd expect the warning: {{1 uninitialized field}}
443   ContainsSimpleUnionTest2(); // no-warning
444 }
445 
446 class UnionPointerTest1 {
447 public:
448   union SimpleUnion {
449     float uf;
450     int ui;
451     char uc;
452   };
453 
454 private:
455   SimpleUnion *uptr;
456 
457 public:
458   UnionPointerTest1(SimpleUnion *uptr, int) : uptr(uptr) {
459     // All good!
460   }
461 };
462 
463 void fUnionPointerTest1() {
464   UnionPointerTest1::SimpleUnion u;
465   u.uf = 41;
466   UnionPointerTest1(&u, int());
467 }
468 
469 class UnionPointerTest2 {
470 public:
471   union SimpleUnion {
472     float uf;
473     int ui;
474     char uc;
475   };
476 
477 private:
478   // TODO: we'd expect the note: {{uninitialized field 'this->uptr'}}
479   SimpleUnion *uptr; // no-note
480 
481 public:
482   UnionPointerTest2(SimpleUnion *uptr, char) : uptr(uptr) {}
483 };
484 
485 void fUnionPointerTest2() {
486   UnionPointerTest2::SimpleUnion u;
487   // TODO: we'd expect the warning: {{1 uninitialized field}}
488   UnionPointerTest2(&u, int()); // no-warning
489 }
490 
491 class ContainsUnionWithRecordTest1 {
492   union UnionWithRecord {
493     struct RecordType {
494       int x;
495       int y;
496     } us;
497     double ud;
498     long ul;
499 
500     UnionWithRecord(){};
501   } u;
502 
503 public:
504   ContainsUnionWithRecordTest1() {
505     u.ud = 3.14;
506     // All good!
507   }
508 };
509 
510 void fContainsUnionWithRecordTest1() {
511   ContainsUnionWithRecordTest1();
512 }
513 
514 class ContainsUnionWithRecordTest2 {
515   union UnionWithRecord {
516     struct RecordType {
517       int x;
518       int y;
519     } us;
520     double ud;
521     long ul;
522 
523     UnionWithRecord(){};
524   } u;
525 
526 public:
527   ContainsUnionWithRecordTest2() {
528     u.us = UnionWithRecord::RecordType{42, 43};
529     // All good!
530   }
531 };
532 
533 void fContainsUnionWithRecordTest2() {
534   ContainsUnionWithRecordTest1();
535 }
536 
537 class ContainsUnionWithRecordTest3 {
538   union UnionWithRecord {
539     struct RecordType {
540       int x;
541       int y;
542     } us;
543     double ud;
544     long ul;
545 
546     UnionWithRecord(){};
547     // TODO: we'd expect the note: {{uninitialized field 'this->u'}}
548   } u; // no-note
549 
550 public:
551   ContainsUnionWithRecordTest3() {
552     UnionWithRecord::RecordType rec;
553     rec.x = 44;
554     // TODO: we'd expect the warning: {{1 uninitialized field}}
555     u.us = rec; // no-warning
556   }
557 };
558 
559 void fContainsUnionWithRecordTest3() {
560   ContainsUnionWithRecordTest3();
561 }
562 
563 class ContainsUnionWithSimpleUnionTest1 {
564   union UnionWithSimpleUnion {
565     union SimpleUnion {
566       float uf;
567       int ui;
568       char uc;
569     } usu;
570     long ul;
571     unsigned uu;
572   } u;
573 
574 public:
575   ContainsUnionWithSimpleUnionTest1() {
576     u.usu.ui = 5;
577     // All good!
578   }
579 };
580 
581 void fContainsUnionWithSimpleUnionTest1() {
582   ContainsUnionWithSimpleUnionTest1();
583 }
584 
585 class ContainsUnionWithSimpleUnionTest2 {
586   union UnionWithSimpleUnion {
587     union SimpleUnion {
588       float uf;
589       int ui;
590       char uc;
591     } usu;
592     long ul;
593     unsigned uu;
594     // TODO: we'd expect the note: {{uninitialized field 'this->u'}}
595   } u; // no-note
596 
597 public:
598   ContainsUnionWithSimpleUnionTest2() {}
599 };
600 
601 void fContainsUnionWithSimpleUnionTest2() {
602   // TODO: we'd expect the warning: {{1 uninitialized field}}
603   ContainsUnionWithSimpleUnionTest2(); // no-warning
604 }
605 
606 //===----------------------------------------------------------------------===//
607 // Zero initialization tests.
608 //===----------------------------------------------------------------------===//
609 
610 struct GlobalVariableTest {
611   int i;
612 
613   GlobalVariableTest() {}
614 };
615 
616 GlobalVariableTest gvt; // no-warning
617 
618 //===----------------------------------------------------------------------===//
619 // Copy and move constructor tests.
620 //===----------------------------------------------------------------------===//
621 
622 template <class T>
623 void funcToSquelchCompilerWarnings(const T &t);
624 
625 #ifdef PEDANTIC
626 struct CopyConstructorTest {
627   int i; // expected-note{{uninitialized field 'this->i'}}
628 
629   CopyConstructorTest() : i(1337) {}
630   CopyConstructorTest(const CopyConstructorTest &other) {}
631 };
632 
633 void fCopyConstructorTest() {
634   CopyConstructorTest cct;
635   CopyConstructorTest copy = cct; // expected-warning{{1 uninitialized field}}
636   funcToSquelchCompilerWarnings(copy);
637 }
638 #else
639 struct CopyConstructorTest {
640   int i;
641 
642   CopyConstructorTest() : i(1337) {}
643   CopyConstructorTest(const CopyConstructorTest &other) {}
644 };
645 
646 void fCopyConstructorTest() {
647   CopyConstructorTest cct;
648   CopyConstructorTest copy = cct;
649   funcToSquelchCompilerWarnings(copy);
650 }
651 #endif // PEDANTIC
652 
653 struct MoveConstructorTest {
654   // TODO: we'd expect the note: {{uninitialized field 'this->i'}}
655   int i; // no-note
656 
657   MoveConstructorTest() : i(1337) {}
658   MoveConstructorTest(const CopyConstructorTest &other) = delete;
659   MoveConstructorTest(const CopyConstructorTest &&other) {}
660 };
661 
662 void fMoveConstructorTest() {
663   MoveConstructorTest cct;
664   // TODO: we'd expect the warning: {{1 uninitialized field}}
665   MoveConstructorTest copy(static_cast<MoveConstructorTest &&>(cct)); // no-warning
666   funcToSquelchCompilerWarnings(copy);
667 }
668 
669 //===----------------------------------------------------------------------===//
670 // Array tests.
671 //===----------------------------------------------------------------------===//
672 
673 struct IntArrayTest {
674   int arr[256];
675 
676   IntArrayTest() {
677     // All good!
678   }
679 };
680 
681 void fIntArrayTest() {
682   IntArrayTest();
683 }
684 
685 struct RecordTypeArrayTest {
686   struct RecordType {
687     int x, y;
688   } arr[256];
689 
690   RecordTypeArrayTest() {
691     // All good!
692   }
693 };
694 
695 void fRecordTypeArrayTest() {
696   RecordTypeArrayTest();
697 }
698 
699 template <class T>
700 class CharArrayPointerTest {
701   T *t; // no-crash
702 
703 public:
704   CharArrayPointerTest(T *t, int) : t(t) {}
705 };
706 
707 void fCharArrayPointerTest() {
708   char str[16] = "012345678912345";
709   CharArrayPointerTest<char[16]>(&str, int());
710 }
711 
712 //===----------------------------------------------------------------------===//
713 // Memset tests.
714 //===----------------------------------------------------------------------===//
715 
716 struct MemsetTest1 {
717   int a, b, c;
718 
719   MemsetTest1() {
720     __builtin_memset(this, 0, sizeof(decltype(*this)));
721   }
722 };
723 
724 void fMemsetTest1() {
725   MemsetTest1();
726 }
727 
728 struct MemsetTest2 {
729   int a;
730 
731   MemsetTest2() {
732     __builtin_memset(&a, 0, sizeof(int));
733   }
734 };
735 
736 void fMemsetTest2() {
737   MemsetTest2();
738 }
739 
740 //===----------------------------------------------------------------------===//
741 // Lambda tests.
742 //===----------------------------------------------------------------------===//
743 
744 template <class Callable>
745 struct LambdaThisTest {
746   Callable functor;
747 
748   LambdaThisTest(const Callable &functor, int) : functor(functor) {
749     // All good!
750   }
751 };
752 
753 struct HasCapturableThis {
754   void fLambdaThisTest() {
755     auto isEven = [this](int a) { return a % 2 == 0; }; // no-crash
756     LambdaThisTest<decltype(isEven)>(isEven, int());
757   }
758 };
759 
760 template <class Callable>
761 struct LambdaTest1 {
762   Callable functor;
763 
764   LambdaTest1(const Callable &functor, int) : functor(functor) {
765     // All good!
766   }
767 };
768 
769 void fLambdaTest1() {
770   auto isEven = [](int a) { return a % 2 == 0; };
771   LambdaTest1<decltype(isEven)>(isEven, int());
772 }
773 
774 #ifdef PEDANTIC
775 template <class Callable>
776 struct LambdaTest2 {
777   Callable functor;
778 
779   LambdaTest2(const Callable &functor, int) : functor(functor) {} // expected-warning{{1 uninitialized field}}
780 };
781 
782 void fLambdaTest2() {
783   int b;
784   auto equals = [&b](int a) { return a == b; }; // expected-note{{uninitialized pointee 'this->functor.b'}}
785   LambdaTest2<decltype(equals)>(equals, int());
786 }
787 #else
788 template <class Callable>
789 struct LambdaTest2 {
790   Callable functor;
791 
792   LambdaTest2(const Callable &functor, int) : functor(functor) {}
793 };
794 
795 void fLambdaTest2() {
796   int b;
797   auto equals = [&b](int a) { return a == b; };
798   LambdaTest2<decltype(equals)>(equals, int());
799 }
800 #endif //PEDANTIC
801 
802 #ifdef PEDANTIC
803 namespace LT3Detail {
804 
805 struct RecordType {
806   int x; // expected-note{{uninitialized field 'this->functor.rec1.x'}}
807   int y; // expected-note{{uninitialized field 'this->functor.rec1.y'}}
808 };
809 
810 } // namespace LT3Detail
811 template <class Callable>
812 struct LambdaTest3 {
813   Callable functor;
814 
815   LambdaTest3(const Callable &functor, int) : functor(functor) {} // expected-warning{{2 uninitialized fields}}
816 };
817 
818 void fLambdaTest3() {
819   LT3Detail::RecordType rec1;
820   auto equals = [&rec1](LT3Detail::RecordType rec2) {
821     return rec1.x == rec2.x;
822   };
823   LambdaTest3<decltype(equals)>(equals, int());
824 }
825 #else
826 namespace LT3Detail {
827 
828 struct RecordType {
829   int x;
830   int y;
831 };
832 
833 } // namespace LT3Detail
834 template <class Callable>
835 struct LambdaTest3 {
836   Callable functor;
837 
838   LambdaTest3(const Callable &functor, int) : functor(functor) {}
839 };
840 
841 void fLambdaTest3() {
842   LT3Detail::RecordType rec1;
843   auto equals = [&rec1](LT3Detail::RecordType rec2) {
844     return rec1.x == rec2.x;
845   };
846   LambdaTest3<decltype(equals)>(equals, int());
847 }
848 #endif //PEDANTIC
849 
850 template <class Callable>
851 struct MultipleLambdaCapturesTest1 {
852   Callable functor;
853   int dontGetFilteredByNonPedanticMode = 0;
854 
855   MultipleLambdaCapturesTest1(const Callable &functor, int) : functor(functor) {} // expected-warning{{2 uninitialized field}}
856 };
857 
858 void fMultipleLambdaCapturesTest1() {
859   int b1, b2 = 3, b3;
860   auto equals = [&b1, &b2, &b3](int a) { return a == b1 == b2 == b3; }; // expected-note{{uninitialized pointee 'this->functor.b1'}}
861   // expected-note@-1{{uninitialized pointee 'this->functor.b3'}}
862   MultipleLambdaCapturesTest1<decltype(equals)>(equals, int());
863 }
864 
865 template <class Callable>
866 struct MultipleLambdaCapturesTest2 {
867   Callable functor;
868   int dontGetFilteredByNonPedanticMode = 0;
869 
870   MultipleLambdaCapturesTest2(const Callable &functor, int) : functor(functor) {} // expected-warning{{1 uninitialized field}}
871 };
872 
873 void fMultipleLambdaCapturesTest2() {
874   int b1, b2 = 3, b3;
875   auto equals = [b1, &b2, &b3](int a) { return a == b1 == b2 == b3; }; // expected-note{{uninitialized pointee 'this->functor.b3'}}
876   MultipleLambdaCapturesTest2<decltype(equals)>(equals, int());
877 }
878 
879 //===----------------------------------------------------------------------===//
880 // System header tests.
881 //===----------------------------------------------------------------------===//
882 
883 #include "Inputs/system-header-simulator-for-cxx-uninitialized-object.h"
884 
885 struct SystemHeaderTest1 {
886   RecordInSystemHeader rec; // defined in the system header simulator
887 
888   SystemHeaderTest1() {
889     // All good!
890   }
891 };
892 
893 void fSystemHeaderTest1() {
894   SystemHeaderTest1();
895 }
896 
897 #ifdef PEDANTIC
898 struct SystemHeaderTest2 {
899   struct RecordType {
900     int x; // expected-note{{uninitialized field 'this->container.t.x}}
901     int y; // expected-note{{uninitialized field 'this->container.t.y}}
902   };
903   ContainerInSystemHeader<RecordType> container;
904 
905   SystemHeaderTest2(RecordType &rec, int) : container(rec) {} // expected-warning{{2 uninitialized fields}}
906 };
907 
908 void fSystemHeaderTest2() {
909   SystemHeaderTest2::RecordType rec;
910   SystemHeaderTest2(rec, int());
911 }
912 #else
913 struct SystemHeaderTest2 {
914   struct RecordType {
915     int x;
916     int y;
917   };
918   ContainerInSystemHeader<RecordType> container;
919 
920   SystemHeaderTest2(RecordType &rec, int) : container(rec) {}
921 };
922 
923 void fSystemHeaderTest2() {
924   SystemHeaderTest2::RecordType rec;
925   SystemHeaderTest2(rec, int());
926 }
927 #endif //PEDANTIC
928 
929 //===----------------------------------------------------------------------===//
930 // Incomplete type tests.
931 //===----------------------------------------------------------------------===//
932 
933 struct IncompleteTypeTest1 {
934   struct RecordType;
935   // no-crash
936   RecordType *recptr; // expected-note{{uninitialized pointer 'this->recptr}}
937   int dontGetFilteredByNonPedanticMode = 0;
938 
939   IncompleteTypeTest1() {} // expected-warning{{1 uninitialized field}}
940 };
941 
942 void fIncompleteTypeTest1() {
943   IncompleteTypeTest1();
944 }
945 
946 struct IncompleteTypeTest2 {
947   struct RecordType;
948   RecordType *recptr; // no-crash
949   int dontGetFilteredByNonPedanticMode = 0;
950 
951   RecordType *recordTypeFactory();
952 
953   IncompleteTypeTest2() : recptr(recordTypeFactory()) {}
954 };
955 
956 void fIncompleteTypeTest2() {
957   IncompleteTypeTest2();
958 }
959 
960 struct IncompleteTypeTest3 {
961   struct RecordType;
962   RecordType &recref; // no-crash
963   int dontGetFilteredByNonPedanticMode = 0;
964 
965   RecordType &recordTypeFactory();
966 
967   IncompleteTypeTest3() : recref(recordTypeFactory()) {}
968 };
969 
970 void fIncompleteTypeTest3() {
971   IncompleteTypeTest3();
972 }
973 
974 //===----------------------------------------------------------------------===//
975 // Builtin type or enumeration type related tests.
976 //===----------------------------------------------------------------------===//
977 
978 struct IntegralTypeTest {
979   int a; // expected-note{{uninitialized field 'this->a'}}
980   int dontGetFilteredByNonPedanticMode = 0;
981 
982   IntegralTypeTest() {} // expected-warning{{1 uninitialized field}}
983 };
984 
985 void fIntegralTypeTest() {
986   IntegralTypeTest();
987 }
988 
989 struct FloatingTypeTest {
990   float a; // expected-note{{uninitialized field 'this->a'}}
991   int dontGetFilteredByNonPedanticMode = 0;
992 
993   FloatingTypeTest() {} // expected-warning{{1 uninitialized field}}
994 };
995 
996 void fFloatingTypeTest() {
997   FloatingTypeTest();
998 }
999 
1000 struct NullptrTypeTypeTest {
1001   decltype(nullptr) a; // expected-note{{uninitialized field 'this->a'}}
1002   int dontGetFilteredByNonPedanticMode = 0;
1003 
1004   NullptrTypeTypeTest() {} // expected-warning{{1 uninitialized field}}
1005 };
1006 
1007 void fNullptrTypeTypeTest() {
1008   NullptrTypeTypeTest();
1009 }
1010 
1011 struct EnumTest {
1012   enum Enum {
1013     A,
1014     B
1015   } enum1; // expected-note{{uninitialized field 'this->enum1'}}
1016   enum class Enum2 {
1017     A,
1018     B
1019   } enum2; // expected-note{{uninitialized field 'this->enum2'}}
1020   int dontGetFilteredByNonPedanticMode = 0;
1021 
1022   EnumTest() {} // expected-warning{{2 uninitialized fields}}
1023 };
1024 
1025 void fEnumTest() {
1026   EnumTest();
1027 }
1028 
1029 //===----------------------------------------------------------------------===//
1030 // Tests for constructor calls within another cunstructor, without the two
1031 // records being in any relation.
1032 //===----------------------------------------------------------------------===//
1033 
1034 void halt() __attribute__((__noreturn__));
1035 void assert(int b) {
1036   if (!b)
1037     halt();
1038 }
1039 
1040 // While a singleton would make more sense as a static variable, that would zero
1041 // initialize all of its fields, hence the not too practical implementation.
1042 struct Singleton {
1043   int i; // expected-note{{uninitialized field 'this->i'}}
1044   int dontGetFilteredByNonPedanticMode = 0;
1045 
1046   Singleton() {
1047     assert(!isInstantiated);
1048     isInstantiated = true; // expected-warning{{1 uninitialized field}}
1049   }
1050 
1051   ~Singleton() {
1052     isInstantiated = false;
1053   }
1054 
1055   static bool isInstantiated;
1056 };
1057 
1058 bool Singleton::isInstantiated = false;
1059 
1060 struct SingletonTest {
1061   int dontGetFilteredByNonPedanticMode = 0;
1062 
1063   SingletonTest() {
1064     Singleton();
1065   }
1066 };
1067 
1068 void fSingletonTest() {
1069   SingletonTest();
1070 }
1071 
1072 //===----------------------------------------------------------------------===//
1073 // C++11 member initializer tests.
1074 //===----------------------------------------------------------------------===//
1075 
1076 struct CXX11MemberInitTest1 {
1077   int a = 3;
1078   int b;
1079   CXX11MemberInitTest1() : b(2) {
1080     // All good!
1081   }
1082 };
1083 
1084 void fCXX11MemberInitTest1() {
1085   CXX11MemberInitTest1();
1086 }
1087 
1088 struct CXX11MemberInitTest2 {
1089   struct RecordType {
1090     // TODO: we'd expect the note: {{uninitialized field 'this->rec.a'}}
1091     int a; // no-note
1092     // TODO: we'd expect the note: {{uninitialized field 'this->rec.b'}}
1093     int b; // no-note
1094 
1095     RecordType(int) {}
1096   };
1097 
1098   RecordType rec = RecordType(int());
1099   int dontGetFilteredByNonPedanticMode = 0;
1100 
1101   CXX11MemberInitTest2() {}
1102 };
1103 
1104 void fCXX11MemberInitTest2() {
1105   // TODO: we'd expect the warning: {{2 uninitializeds field}}
1106   CXX11MemberInitTest2(); // no-warning
1107 }
1108