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 
fCompilerGeneratedConstructorTest()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 
fDefaultConstructorTest()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 
fDefaultConstructorTest()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:
InitListTest1()57   InitListTest1()
58       : a(1),
59         b(2) {
60     // All good!
61   }
62 };
63 
fInitListTest1()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:
InitListTest2()73   InitListTest2()
74       : a(3) {} // expected-warning{{1 uninitialized field}}
75 };
76 
fInitListTest2()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:
InitListTest3()86   InitListTest3()
87       : b(4) {} // expected-warning{{1 uninitialized field}}
88 };
89 
fInitListTest3()90 void fInitListTest3() {
91   InitListTest3();
92 }
93 
94 //===----------------------------------------------------------------------===//
95 // Constructor body test.
96 //===----------------------------------------------------------------------===//
97 
98 class CtorBodyTest1 {
99   int a, b;
100 
101 public:
CtorBodyTest1()102   CtorBodyTest1() {
103     a = 5;
104     b = 6;
105     // All good!
106   }
107 };
108 
fCtorBodyTest1()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:
CtorBodyTest2()118   CtorBodyTest2() {
119     a = 7; // expected-warning{{1 uninitialized field}}
120   }
121 };
122 
fCtorBodyTest2()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:
CtorBodyTest3()132   CtorBodyTest3() {
133     b = 8; // expected-warning{{1 uninitialized field}}
134   }
135 };
136 
fCtorBodyTest3()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:
CtorBodyTest4()147   CtorBodyTest4() {}
148 };
149 
fCtorBodyTest4()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:
CtorBodyTest4()159   CtorBodyTest4() {}
160 };
161 
fCtorBodyTest4()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:
CtorDelegationTest1(int)176   CtorDelegationTest1(int)
177       : a(9) {
178     // leaves 'b' unintialized, but we'll never check this function
179   }
180 
CtorDelegationTest1()181   CtorDelegationTest1()
182       : CtorDelegationTest1(int{}) { // Initializing 'a'
183     b = 10;
184     // All good!
185   }
186 };
187 
fCtorDelegationTest1()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:
CtorDelegationTest2(int)197   CtorDelegationTest2(int)
198       : b(11) {
199     // leaves 'a' unintialized, but we'll never check this function
200   }
201 
CtorDelegationTest2()202   CtorDelegationTest2()
203       : CtorDelegationTest2(int{}) { // expected-warning{{1 uninitialized field}}
204   }
205 };
206 
fCtorDelegationTest2()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:
ContainsRecordTest1()223   ContainsRecordTest1()
224       : rec({12, 13}),
225         c(14),
226         d(15) {
227     // All good!
228   }
229 };
230 
fContainsRecordTest1()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:
ContainsRecordTest2()243   ContainsRecordTest2()
244       : c(16),
245         d(17) {
246     rec.x = 18; // expected-warning{{1 uninitialized field}}
247   }
248 };
249 
fContainsRecordTest2()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:
ContainsRecordTest3()262   ContainsRecordTest3()
263       : c(19),
264         d(20) { // expected-warning{{2 uninitialized fields}}
265   }
266 };
267 
fContainsRecordTest3()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:
ContainsRecordTest4()280   ContainsRecordTest4()
281       : c(19) { // expected-warning{{3 uninitialized fields}}
282   }
283 };
284 
fContainsRecordTest4()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:
IntTemplateClassTest1(T i)299   IntTemplateClassTest1(T i) {
300     b = 21;
301     t = i;
302     // All good!
303   }
304 };
305 
fIntTemplateClassTest1()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:
IntTemplateClassTest2()316   IntTemplateClassTest2() {
317     b = 23; // expected-warning{{1 uninitialized field}}
318   }
319 };
320 
fIntTemplateClassTest2()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:
RecordTemplateClassTest()336   RecordTemplateClassTest() {
337     b = 24; // expected-warning{{2 uninitialized fields}}
338   }
339 };
340 
fRecordTemplateClassTest()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:
PassingToUnknownFunctionTest1()359   PassingToUnknownFunctionTest1() {
360     mayInitialize(a);
361     mayInitialize(b);
362     // All good!
363   }
364 
PassingToUnknownFunctionTest1(int)365   PassingToUnknownFunctionTest1(int) {
366     mayInitialize(a);
367     // All good!
368   }
369 
PassingToUnknownFunctionTest1(int,int)370   PassingToUnknownFunctionTest1(int, int) {
371     mayInitialize(*this);
372     // All good!
373   }
374 };
375 
fPassingToUnknownFunctionTest1()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:
PassingToUnknownFunctionTest2()387   PassingToUnknownFunctionTest2() {
388     wontInitialize(a);
389     b = 4; // expected-warning{{1 uninitialized field}}
390   }
391 };
392 
fPassingToUnknownFunctionTest2()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:
ContainsSimpleUnionTest1()414   ContainsSimpleUnionTest1() {
415     u.uf = 3.14;
416     // All good!
417   }
418 };
419 
fContainsSimpleUnionTest1()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:
ContainsSimpleUnionTest2()433   ContainsSimpleUnionTest2() {}
434 };
435 
fContainsSimpleUnionTest2()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:
UnionPointerTest1(SimpleUnion * uptr,int)453   UnionPointerTest1(SimpleUnion *uptr, int) : uptr(uptr) {
454     // All good!
455   }
456 };
457 
fUnionPointerTest1()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:
UnionPointerTest2(SimpleUnion * uptr,char)477   UnionPointerTest2(SimpleUnion *uptr, char) : uptr(uptr) {}
478 };
479 
fUnionPointerTest2()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 
UnionWithRecord()495     UnionWithRecord(){};
496   } u;
497 
498 public:
ContainsUnionWithRecordTest1()499   ContainsUnionWithRecordTest1() {
500     u.ud = 3.14;
501     // All good!
502   }
503 };
504 
fContainsUnionWithRecordTest1()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 
UnionWithRecord()518     UnionWithRecord(){};
519   } u;
520 
521 public:
ContainsUnionWithRecordTest2()522   ContainsUnionWithRecordTest2() {
523     u.us = UnionWithRecord::RecordType{42, 43};
524     // All good!
525   }
526 };
527 
fContainsUnionWithRecordTest2()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 
UnionWithRecord()541     UnionWithRecord(){};
542     // TODO: we'd expect the note: {{uninitialized field 'this->u'}}
543   } u; // no-note
544 
545 public:
ContainsUnionWithRecordTest3()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 
fContainsUnionWithRecordTest3()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:
ContainsUnionWithSimpleUnionTest1()570   ContainsUnionWithSimpleUnionTest1() {
571     u.usu.ui = 5;
572     // All good!
573   }
574 };
575 
fContainsUnionWithSimpleUnionTest1()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:
ContainsUnionWithSimpleUnionTest2()593   ContainsUnionWithSimpleUnionTest2() {}
594 };
595 
fContainsUnionWithSimpleUnionTest2()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 
GlobalVariableTestGlobalVariableTest608   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 
CopyConstructorTestCopyConstructorTest624   CopyConstructorTest() : i(1337) {}
CopyConstructorTestCopyConstructorTest625   CopyConstructorTest(const CopyConstructorTest &other) {}
626 };
627 
fCopyConstructorTest()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 
CopyConstructorTestCopyConstructorTest637   CopyConstructorTest() : i(1337) {}
CopyConstructorTestCopyConstructorTest638   CopyConstructorTest(const CopyConstructorTest &other) {}
639 };
640 
fCopyConstructorTest()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 
MoveConstructorTestMoveConstructorTest652   MoveConstructorTest() : i(1337) {}
653   MoveConstructorTest(const CopyConstructorTest &other) = delete;
MoveConstructorTestMoveConstructorTest654   MoveConstructorTest(const CopyConstructorTest &&other) {}
655 };
656 
fMoveConstructorTest()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 
IntArrayTestIntArrayTest671   IntArrayTest() {
672     // All good!
673   }
674 };
675 
fIntArrayTest()676 void fIntArrayTest() {
677   IntArrayTest();
678 }
679 
680 struct RecordTypeArrayTest {
681   struct RecordType {
682     int x, y;
683   } arr[256];
684 
RecordTypeArrayTestRecordTypeArrayTest685   RecordTypeArrayTest() {
686     // All good!
687   }
688 };
689 
fRecordTypeArrayTest()690 void fRecordTypeArrayTest() {
691   RecordTypeArrayTest();
692 }
693 
694 template <class T>
695 class CharArrayPointerTest {
696   T *t; // no-crash
697 
698 public:
CharArrayPointerTest(T * t,int)699   CharArrayPointerTest(T *t, int) : t(t) {}
700 };
701 
fCharArrayPointerTest()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 
MemsetTest1MemsetTest1714   MemsetTest1() {
715     __builtin_memset(this, 0, sizeof(decltype(*this)));
716   }
717 };
718 
fMemsetTest1()719 void fMemsetTest1() {
720   MemsetTest1();
721 }
722 
723 struct MemsetTest2 {
724   int a;
725 
MemsetTest2MemsetTest2726   MemsetTest2() {
727     __builtin_memset(&a, 0, sizeof(int));
728   }
729 };
730 
fMemsetTest2()731 void fMemsetTest2() {
732   MemsetTest2();
733 }
734 
735 //===----------------------------------------------------------------------===//
736 // Lambda tests.
737 //===----------------------------------------------------------------------===//
738 
739 template <class Callable>
740 struct LambdaThisTest {
741   Callable functor;
742 
LambdaThisTestLambdaThisTest743   LambdaThisTest(const Callable &functor, int) : functor(functor) {
744     // All good!
745   }
746 };
747 
748 struct HasCapturableThis {
fLambdaThisTestHasCapturableThis749   void fLambdaThisTest() {
750     auto isEven = [this](int a) { return a % 2 == 0; }; // no-crash
751     LambdaThisTest<decltype(isEven)>(isEven, int());
752   }
753 };
754 
755 template <class Callable>
756 struct LambdaTest1 {
757   Callable functor;
758 
LambdaTest1LambdaTest1759   LambdaTest1(const Callable &functor, int) : functor(functor) {
760     // All good!
761   }
762 };
763 
fLambdaTest1()764 void fLambdaTest1() {
765   auto isEven = [](int a) { return a % 2 == 0; };
766   LambdaTest1<decltype(isEven)>(isEven, int());
767 }
768 
769 #ifdef PEDANTIC
770 template <class Callable>
771 struct LambdaTest2 {
772   Callable functor;
773 
LambdaTest2LambdaTest2774   LambdaTest2(const Callable &functor, int) : functor(functor) {} // expected-warning{{1 uninitialized field}}
775 };
776 
fLambdaTest2()777 void fLambdaTest2() {
778   int b;
779   auto equals = [&b](int a) { return a == b; }; // expected-note{{uninitialized field 'this->functor.b'}}
780   LambdaTest2<decltype(equals)>(equals, int());
781 }
782 #else
783 template <class Callable>
784 struct LambdaTest2 {
785   Callable functor;
786 
LambdaTest2LambdaTest2787   LambdaTest2(const Callable &functor, int) : functor(functor) {}
788 };
789 
fLambdaTest2()790 void fLambdaTest2() {
791   int b;
792   auto equals = [&b](int a) { return a == b; };
793   LambdaTest2<decltype(equals)>(equals, int());
794 }
795 #endif //PEDANTIC
796 
797 #ifdef PEDANTIC
798 namespace LT3Detail {
799 
800 struct RecordType {
801   int x; // expected-note{{uninitialized field 'this->functor.rec1.x'}}
802   int y; // expected-note{{uninitialized field 'this->functor.rec1.y'}}
803 };
804 
805 } // namespace LT3Detail
806 template <class Callable>
807 struct LambdaTest3 {
808   Callable functor;
809 
LambdaTest3LambdaTest3810   LambdaTest3(const Callable &functor, int) : functor(functor) {} // expected-warning{{2 uninitialized fields}}
811 };
812 
fLambdaTest3()813 void fLambdaTest3() {
814   LT3Detail::RecordType rec1;
815   auto equals = [&rec1](LT3Detail::RecordType rec2) {
816     return rec1.x == rec2.x;
817   };
818   LambdaTest3<decltype(equals)>(equals, int());
819 }
820 #else
821 namespace LT3Detail {
822 
823 struct RecordType {
824   int x;
825   int y;
826 };
827 
828 } // namespace LT3Detail
829 template <class Callable>
830 struct LambdaTest3 {
831   Callable functor;
832 
LambdaTest3LambdaTest3833   LambdaTest3(const Callable &functor, int) : functor(functor) {}
834 };
835 
fLambdaTest3()836 void fLambdaTest3() {
837   LT3Detail::RecordType rec1;
838   auto equals = [&rec1](LT3Detail::RecordType rec2) {
839     return rec1.x == rec2.x;
840   };
841   LambdaTest3<decltype(equals)>(equals, int());
842 }
843 #endif //PEDANTIC
844 
845 template <class Callable>
846 struct MultipleLambdaCapturesTest1 {
847   Callable functor;
848   int dontGetFilteredByNonPedanticMode = 0;
849 
MultipleLambdaCapturesTest1MultipleLambdaCapturesTest1850   MultipleLambdaCapturesTest1(const Callable &functor, int) : functor(functor) {} // expected-warning{{2 uninitialized field}}
851 };
852 
fMultipleLambdaCapturesTest1()853 void fMultipleLambdaCapturesTest1() {
854   int b1, b2 = 3, b3;
855   auto equals = [&b1, &b2, &b3](int a) { return a == b1 == b2 == b3; }; // expected-note{{uninitialized field 'this->functor.b1'}}
856   // expected-note@-1{{uninitialized field 'this->functor.b3'}}
857   MultipleLambdaCapturesTest1<decltype(equals)>(equals, int());
858 }
859 
860 template <class Callable>
861 struct MultipleLambdaCapturesTest2 {
862   Callable functor;
863   int dontGetFilteredByNonPedanticMode = 0;
864 
MultipleLambdaCapturesTest2MultipleLambdaCapturesTest2865   MultipleLambdaCapturesTest2(const Callable &functor, int) : functor(functor) {} // expected-warning{{1 uninitialized field}}
866 };
867 
fMultipleLambdaCapturesTest2()868 void fMultipleLambdaCapturesTest2() {
869   int b1, b2 = 3, b3;
870   auto equals = [b1, &b2, &b3](int a) { return a == b1 == b2 == b3; }; // expected-note{{uninitialized field 'this->functor.b3'}}
871   MultipleLambdaCapturesTest2<decltype(equals)>(equals, int());
872 }
873 
874 //===----------------------------------------------------------------------===//
875 // System header tests.
876 //===----------------------------------------------------------------------===//
877 
878 #include "Inputs/system-header-simulator-for-cxx-uninitialized-object.h"
879 
880 struct SystemHeaderTest1 {
881   RecordInSystemHeader rec; // defined in the system header simulator
882 
SystemHeaderTest1SystemHeaderTest1883   SystemHeaderTest1() {
884     // All good!
885   }
886 };
887 
fSystemHeaderTest1()888 void fSystemHeaderTest1() {
889   SystemHeaderTest1();
890 }
891 
892 #ifdef PEDANTIC
893 struct SystemHeaderTest2 {
894   struct RecordType {
895     int x; // expected-note{{uninitialized field 'this->container.t.x}}
896     int y; // expected-note{{uninitialized field 'this->container.t.y}}
897   };
898   ContainerInSystemHeader<RecordType> container;
899 
SystemHeaderTest2SystemHeaderTest2900   SystemHeaderTest2(RecordType &rec, int) : container(rec) {} // expected-warning{{2 uninitialized fields}}
901 };
902 
fSystemHeaderTest2()903 void fSystemHeaderTest2() {
904   SystemHeaderTest2::RecordType rec;
905   SystemHeaderTest2(rec, int());
906 }
907 #else
908 struct SystemHeaderTest2 {
909   struct RecordType {
910     int x;
911     int y;
912   };
913   ContainerInSystemHeader<RecordType> container;
914 
SystemHeaderTest2SystemHeaderTest2915   SystemHeaderTest2(RecordType &rec, int) : container(rec) {}
916 };
917 
fSystemHeaderTest2()918 void fSystemHeaderTest2() {
919   SystemHeaderTest2::RecordType rec;
920   SystemHeaderTest2(rec, int());
921 }
922 #endif //PEDANTIC
923 
924 //===----------------------------------------------------------------------===//
925 // Incomplete type tests.
926 //===----------------------------------------------------------------------===//
927 
928 struct IncompleteTypeTest1 {
929   struct RecordType;
930   // no-crash
931   RecordType *recptr; // expected-note{{uninitialized pointer 'this->recptr}}
932   int dontGetFilteredByNonPedanticMode = 0;
933 
IncompleteTypeTest1IncompleteTypeTest1934   IncompleteTypeTest1() {} // expected-warning{{1 uninitialized field}}
935 };
936 
fIncompleteTypeTest1()937 void fIncompleteTypeTest1() {
938   IncompleteTypeTest1();
939 }
940 
941 struct IncompleteTypeTest2 {
942   struct RecordType;
943   RecordType *recptr; // no-crash
944   int dontGetFilteredByNonPedanticMode = 0;
945 
946   RecordType *recordTypeFactory();
947 
IncompleteTypeTest2IncompleteTypeTest2948   IncompleteTypeTest2() : recptr(recordTypeFactory()) {}
949 };
950 
fIncompleteTypeTest2()951 void fIncompleteTypeTest2() {
952   IncompleteTypeTest2();
953 }
954 
955 struct IncompleteTypeTest3 {
956   struct RecordType;
957   RecordType &recref; // no-crash
958   int dontGetFilteredByNonPedanticMode = 0;
959 
960   RecordType &recordTypeFactory();
961 
IncompleteTypeTest3IncompleteTypeTest3962   IncompleteTypeTest3() : recref(recordTypeFactory()) {}
963 };
964 
fIncompleteTypeTest3()965 void fIncompleteTypeTest3() {
966   IncompleteTypeTest3();
967 }
968 
969 //===----------------------------------------------------------------------===//
970 // Builtin type or enumeration type related tests.
971 //===----------------------------------------------------------------------===//
972 
973 struct IntegralTypeTest {
974   int a; // expected-note{{uninitialized field 'this->a'}}
975   int dontGetFilteredByNonPedanticMode = 0;
976 
IntegralTypeTestIntegralTypeTest977   IntegralTypeTest() {} // expected-warning{{1 uninitialized field}}
978 };
979 
fIntegralTypeTest()980 void fIntegralTypeTest() {
981   IntegralTypeTest();
982 }
983 
984 struct FloatingTypeTest {
985   float a; // expected-note{{uninitialized field 'this->a'}}
986   int dontGetFilteredByNonPedanticMode = 0;
987 
FloatingTypeTestFloatingTypeTest988   FloatingTypeTest() {} // expected-warning{{1 uninitialized field}}
989 };
990 
fFloatingTypeTest()991 void fFloatingTypeTest() {
992   FloatingTypeTest();
993 }
994 
995 struct NullptrTypeTypeTest {
996   decltype(nullptr) a; // expected-note{{uninitialized field 'this->a'}}
997   int dontGetFilteredByNonPedanticMode = 0;
998 
NullptrTypeTypeTestNullptrTypeTypeTest999   NullptrTypeTypeTest() {} // expected-warning{{1 uninitialized field}}
1000 };
1001 
fNullptrTypeTypeTest()1002 void fNullptrTypeTypeTest() {
1003   NullptrTypeTypeTest();
1004 }
1005 
1006 struct EnumTest {
1007   enum Enum {
1008     A,
1009     B
1010   } enum1; // expected-note{{uninitialized field 'this->enum1'}}
1011   enum class Enum2 {
1012     A,
1013     B
1014   } enum2; // expected-note{{uninitialized field 'this->enum2'}}
1015   int dontGetFilteredByNonPedanticMode = 0;
1016 
EnumTestEnumTest1017   EnumTest() {} // expected-warning{{2 uninitialized fields}}
1018 };
1019 
fEnumTest()1020 void fEnumTest() {
1021   EnumTest();
1022 }
1023 
1024 //===----------------------------------------------------------------------===//
1025 // Tests for constructor calls within another cunstructor, without the two
1026 // records being in any relation.
1027 //===----------------------------------------------------------------------===//
1028 
1029 void halt() __attribute__((__noreturn__));
assert(int b)1030 void assert(int b) {
1031   if (!b)
1032     halt();
1033 }
1034 
1035 // While a singleton would make more sense as a static variable, that would zero
1036 // initialize all of its fields, hence the not too practical implementation.
1037 struct Singleton {
1038   // TODO: we'd expect the note: {{uninitialized field 'this->i'}}
1039   int i; // no-note
1040 
SingletonSingleton1041   Singleton() {
1042     assert(!isInstantiated);
1043     // TODO: we'd expect the warning: {{1 uninitialized field}}
1044     isInstantiated = true; // no-warning
1045   }
1046 
~SingletonSingleton1047   ~Singleton() {
1048     isInstantiated = false;
1049   }
1050 
1051   static bool isInstantiated;
1052 };
1053 
1054 bool Singleton::isInstantiated = false;
1055 
1056 struct SingletonTest {
1057   int dontGetFilteredByNonPedanticMode = 0;
1058 
SingletonTestSingletonTest1059   SingletonTest() {
1060     Singleton();
1061   }
1062 };
1063 
fSingletonTest()1064 void fSingletonTest() {
1065   SingletonTest();
1066 }
1067 
1068 //===----------------------------------------------------------------------===//
1069 // C++11 member initializer tests.
1070 //===----------------------------------------------------------------------===//
1071 
1072 struct CXX11MemberInitTest1 {
1073   int a = 3;
1074   int b;
CXX11MemberInitTest1CXX11MemberInitTest11075   CXX11MemberInitTest1() : b(2) {
1076     // All good!
1077   }
1078 };
1079 
fCXX11MemberInitTest1()1080 void fCXX11MemberInitTest1() {
1081   CXX11MemberInitTest1();
1082 }
1083 
1084 struct CXX11MemberInitTest2 {
1085   struct RecordType {
1086     // TODO: we'd expect the note: {{uninitialized field 'this->rec.a'}}
1087     int a; // no-note
1088     // TODO: we'd expect the note: {{uninitialized field 'this->rec.b'}}
1089     int b; // no-note
1090 
RecordTypeCXX11MemberInitTest2::RecordType1091     RecordType(int) {}
1092   };
1093 
1094   RecordType rec = RecordType(int());
1095   int dontGetFilteredByNonPedanticMode = 0;
1096 
CXX11MemberInitTest2CXX11MemberInitTest21097   CXX11MemberInitTest2() {}
1098 };
1099 
fCXX11MemberInitTest2()1100 void fCXX11MemberInitTest2() {
1101   // TODO: we'd expect the warning: {{2 uninitializeds field}}
1102   CXX11MemberInitTest2(); // no-warning
1103 }
1104