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