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 
fCompilerGeneratedConstructorTest()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 
fDefaultConstructorTest()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 
fDefaultConstructorTest()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:
InitListTest1()62   InitListTest1()
63       : a(1),
64         b(2) {
65     // All good!
66   }
67 };
68 
fInitListTest1()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:
InitListTest2()78   InitListTest2()
79       : a(3) {} // expected-warning{{1 uninitialized field}}
80 };
81 
fInitListTest2()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:
InitListTest3()91   InitListTest3()
92       : b(4) {} // expected-warning{{1 uninitialized field}}
93 };
94 
fInitListTest3()95 void fInitListTest3() {
96   InitListTest3();
97 }
98 
99 //===----------------------------------------------------------------------===//
100 // Constructor body test.
101 //===----------------------------------------------------------------------===//
102 
103 class CtorBodyTest1 {
104   int a, b;
105 
106 public:
CtorBodyTest1()107   CtorBodyTest1() {
108     a = 5;
109     b = 6;
110     // All good!
111   }
112 };
113 
fCtorBodyTest1()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:
CtorBodyTest2()123   CtorBodyTest2() {
124     a = 7; // expected-warning{{1 uninitialized field}}
125   }
126 };
127 
fCtorBodyTest2()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:
CtorBodyTest3()137   CtorBodyTest3() {
138     b = 8; // expected-warning{{1 uninitialized field}}
139   }
140 };
141 
fCtorBodyTest3()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:
CtorBodyTest4()152   CtorBodyTest4() {}
153 };
154 
fCtorBodyTest4()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:
CtorBodyTest4()164   CtorBodyTest4() {}
165 };
166 
fCtorBodyTest4()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:
CtorDelegationTest1(int)181   CtorDelegationTest1(int)
182       : a(9) {
183     // leaves 'b' unintialized, but we'll never check this function
184   }
185 
CtorDelegationTest1()186   CtorDelegationTest1()
187       : CtorDelegationTest1(int{}) { // Initializing 'a'
188     b = 10;
189     // All good!
190   }
191 };
192 
fCtorDelegationTest1()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:
CtorDelegationTest2(int)202   CtorDelegationTest2(int)
203       : b(11) {
204     // leaves 'a' unintialized, but we'll never check this function
205   }
206 
CtorDelegationTest2()207   CtorDelegationTest2()
208       : CtorDelegationTest2(int{}) { // expected-warning{{1 uninitialized field}}
209   }
210 };
211 
fCtorDelegationTest2()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:
ContainsRecordTest1()228   ContainsRecordTest1()
229       : rec({12, 13}),
230         c(14),
231         d(15) {
232     // All good!
233   }
234 };
235 
fContainsRecordTest1()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:
ContainsRecordTest2()248   ContainsRecordTest2()
249       : c(16),
250         d(17) {
251     rec.x = 18; // expected-warning{{1 uninitialized field}}
252   }
253 };
254 
fContainsRecordTest2()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:
ContainsRecordTest3()267   ContainsRecordTest3()
268       : c(19),
269         d(20) { // expected-warning{{2 uninitialized fields}}
270   }
271 };
272 
fContainsRecordTest3()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:
ContainsRecordTest4()285   ContainsRecordTest4()
286       : c(19) { // expected-warning{{3 uninitialized fields}}
287   }
288 };
289 
fContainsRecordTest4()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:
IntTemplateClassTest1(T i)304   IntTemplateClassTest1(T i) {
305     b = 21;
306     t = i;
307     // All good!
308   }
309 };
310 
fIntTemplateClassTest1()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:
IntTemplateClassTest2()321   IntTemplateClassTest2() {
322     b = 23; // expected-warning{{1 uninitialized field}}
323   }
324 };
325 
fIntTemplateClassTest2()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:
RecordTemplateClassTest()341   RecordTemplateClassTest() {
342     b = 24; // expected-warning{{2 uninitialized fields}}
343   }
344 };
345 
fRecordTemplateClassTest()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:
PassingToUnknownFunctionTest1()364   PassingToUnknownFunctionTest1() {
365     mayInitialize(a);
366     mayInitialize(b);
367     // All good!
368   }
369 
PassingToUnknownFunctionTest1(int)370   PassingToUnknownFunctionTest1(int) {
371     mayInitialize(a);
372     // All good!
373   }
374 
PassingToUnknownFunctionTest1(int,int)375   PassingToUnknownFunctionTest1(int, int) {
376     mayInitialize(*this);
377     // All good!
378   }
379 };
380 
fPassingToUnknownFunctionTest1()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:
PassingToUnknownFunctionTest2()392   PassingToUnknownFunctionTest2() {
393     wontInitialize(a);
394     b = 4; // expected-warning{{1 uninitialized field}}
395   }
396 };
397 
fPassingToUnknownFunctionTest2()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:
ContainsSimpleUnionTest1()419   ContainsSimpleUnionTest1() {
420     u.uf = 3.14;
421     // All good!
422   }
423 };
424 
fContainsSimpleUnionTest1()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:
ContainsSimpleUnionTest2()438   ContainsSimpleUnionTest2() {}
439 };
440 
fContainsSimpleUnionTest2()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:
UnionPointerTest1(SimpleUnion * uptr,int)458   UnionPointerTest1(SimpleUnion *uptr, int) : uptr(uptr) {
459     // All good!
460   }
461 };
462 
fUnionPointerTest1()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:
UnionPointerTest2(SimpleUnion * uptr,char)482   UnionPointerTest2(SimpleUnion *uptr, char) : uptr(uptr) {}
483 };
484 
fUnionPointerTest2()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 
UnionWithRecord()500     UnionWithRecord(){};
501   } u;
502 
503 public:
ContainsUnionWithRecordTest1()504   ContainsUnionWithRecordTest1() {
505     u.ud = 3.14;
506     // All good!
507   }
508 };
509 
fContainsUnionWithRecordTest1()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 
UnionWithRecord()523     UnionWithRecord(){};
524   } u;
525 
526 public:
ContainsUnionWithRecordTest2()527   ContainsUnionWithRecordTest2() {
528     u.us = UnionWithRecord::RecordType{42, 43};
529     // All good!
530   }
531 };
532 
fContainsUnionWithRecordTest2()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 
UnionWithRecord()546     UnionWithRecord(){};
547     // TODO: we'd expect the note: {{uninitialized field 'this->u'}}
548   } u; // no-note
549 
550 public:
ContainsUnionWithRecordTest3()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 
fContainsUnionWithRecordTest3()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:
ContainsUnionWithSimpleUnionTest1()575   ContainsUnionWithSimpleUnionTest1() {
576     u.usu.ui = 5;
577     // All good!
578   }
579 };
580 
fContainsUnionWithSimpleUnionTest1()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:
ContainsUnionWithSimpleUnionTest2()598   ContainsUnionWithSimpleUnionTest2() {}
599 };
600 
fContainsUnionWithSimpleUnionTest2()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 
GlobalVariableTestGlobalVariableTest613   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 
CopyConstructorTestCopyConstructorTest629   CopyConstructorTest() : i(1337) {}
CopyConstructorTestCopyConstructorTest630   CopyConstructorTest(const CopyConstructorTest &other) {}
631 };
632 
fCopyConstructorTest()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 
CopyConstructorTestCopyConstructorTest642   CopyConstructorTest() : i(1337) {}
CopyConstructorTestCopyConstructorTest643   CopyConstructorTest(const CopyConstructorTest &other) {}
644 };
645 
fCopyConstructorTest()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 
MoveConstructorTestMoveConstructorTest657   MoveConstructorTest() : i(1337) {}
658   MoveConstructorTest(const CopyConstructorTest &other) = delete;
MoveConstructorTestMoveConstructorTest659   MoveConstructorTest(const CopyConstructorTest &&other) {}
660 };
661 
fMoveConstructorTest()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 
IntArrayTestIntArrayTest676   IntArrayTest() {
677     // All good!
678   }
679 };
680 
fIntArrayTest()681 void fIntArrayTest() {
682   IntArrayTest();
683 }
684 
685 struct RecordTypeArrayTest {
686   struct RecordType {
687     int x, y;
688   } arr[256];
689 
RecordTypeArrayTestRecordTypeArrayTest690   RecordTypeArrayTest() {
691     // All good!
692   }
693 };
694 
fRecordTypeArrayTest()695 void fRecordTypeArrayTest() {
696   RecordTypeArrayTest();
697 }
698 
699 template <class T>
700 class CharArrayPointerTest {
701   T *t; // no-crash
702 
703 public:
CharArrayPointerTest(T * t,int)704   CharArrayPointerTest(T *t, int) : t(t) {}
705 };
706 
fCharArrayPointerTest()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 
MemsetTest1MemsetTest1719   MemsetTest1() {
720     __builtin_memset(this, 0, sizeof(decltype(*this)));
721   }
722 };
723 
fMemsetTest1()724 void fMemsetTest1() {
725   MemsetTest1();
726 }
727 
728 struct MemsetTest2 {
729   int a;
730 
MemsetTest2MemsetTest2731   MemsetTest2() {
732     __builtin_memset(&a, 0, sizeof(int));
733   }
734 };
735 
fMemsetTest2()736 void fMemsetTest2() {
737   MemsetTest2();
738 }
739 
740 //===----------------------------------------------------------------------===//
741 // Lambda tests.
742 //===----------------------------------------------------------------------===//
743 
744 template <class Callable>
745 struct LambdaThisTest {
746   Callable functor;
747 
LambdaThisTestLambdaThisTest748   LambdaThisTest(const Callable &functor, int) : functor(functor) {
749     // All good!
750   }
751 };
752 
753 struct HasCapturableThis {
fLambdaThisTestHasCapturableThis754   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 
LambdaTest1LambdaTest1764   LambdaTest1(const Callable &functor, int) : functor(functor) {
765     // All good!
766   }
767 };
768 
fLambdaTest1()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 
LambdaTest2LambdaTest2779   LambdaTest2(const Callable &functor, int) : functor(functor) {} // expected-warning{{1 uninitialized field}}
780 };
781 
fLambdaTest2()782 void fLambdaTest2() {
783   int b;
784   auto equals = [&b](int a) { return a == b; }; // expected-note{{uninitialized pointee 'this->functor./*captured variable*/b'}}
785   LambdaTest2<decltype(equals)>(equals, int());
786 }
787 #else
788 template <class Callable>
789 struct LambdaTest2 {
790   Callable functor;
791 
LambdaTest2LambdaTest2792   LambdaTest2(const Callable &functor, int) : functor(functor) {}
793 };
794 
fLambdaTest2()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./*captured variable*/rec1.x'}}
807   int y; // expected-note{{uninitialized field 'this->functor./*captured variable*/rec1.y'}}
808 };
809 
810 } // namespace LT3Detail
811 template <class Callable>
812 struct LambdaTest3 {
813   Callable functor;
814 
LambdaTest3LambdaTest3815   LambdaTest3(const Callable &functor, int) : functor(functor) {} // expected-warning{{2 uninitialized fields}}
816 };
817 
fLambdaTest3()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 
LambdaTest3LambdaTest3838   LambdaTest3(const Callable &functor, int) : functor(functor) {}
839 };
840 
fLambdaTest3()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 
MultipleLambdaCapturesTest1MultipleLambdaCapturesTest1855   MultipleLambdaCapturesTest1(const Callable &functor, int) : functor(functor) {} // expected-warning{{2 uninitialized field}}
856 };
857 
fMultipleLambdaCapturesTest1()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./*captured variable*/b1'}}
861   // expected-note@-1{{uninitialized pointee 'this->functor./*captured variable*/b3'}}
862   MultipleLambdaCapturesTest1<decltype(equals)>(equals, int());
863 }
864 
865 template <class Callable>
866 struct MultipleLambdaCapturesTest2 {
867   Callable functor;
868   int dontGetFilteredByNonPedanticMode = 0;
869 
MultipleLambdaCapturesTest2MultipleLambdaCapturesTest2870   MultipleLambdaCapturesTest2(const Callable &functor, int) : functor(functor) {} // expected-warning{{1 uninitialized field}}
871 };
872 
fMultipleLambdaCapturesTest2()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./*captured variable*/b3'}}
876   MultipleLambdaCapturesTest2<decltype(equals)>(equals, int());
877 }
878 
879 struct LambdaWrapper {
880   void *func; // no-crash
881   int dontGetFilteredByNonPedanticMode = 0;
882 
LambdaWrapperLambdaWrapper883   LambdaWrapper(void *ptr) : func(ptr) {} // expected-warning{{1 uninitialized field}}
884 };
885 
886 struct ThisCapturingLambdaFactory {
887   int a; // expected-note{{uninitialized field 'static_cast<decltype(a.ret()) *>(this->func)->/*'this' capture*/->a'}}
888 
retThisCapturingLambdaFactory889   auto ret() {
890     return [this] { (void)this; };
891   }
892 };
893 
fLambdaFieldWithInvalidThisCapture()894 void fLambdaFieldWithInvalidThisCapture() {
895   void *ptr;
896   {
897     ThisCapturingLambdaFactory a;
898     decltype(a.ret()) lambda = a.ret();
899     ptr = &lambda;
900   }
901   LambdaWrapper t(ptr);
902 }
903 
904 //===----------------------------------------------------------------------===//
905 // System header tests.
906 //===----------------------------------------------------------------------===//
907 
908 #include "Inputs/system-header-simulator-for-cxx-uninitialized-object.h"
909 
910 struct SystemHeaderTest1 {
911   RecordInSystemHeader rec; // defined in the system header simulator
912 
SystemHeaderTest1SystemHeaderTest1913   SystemHeaderTest1() {
914     // All good!
915   }
916 };
917 
fSystemHeaderTest1()918 void fSystemHeaderTest1() {
919   SystemHeaderTest1();
920 }
921 
922 #ifdef PEDANTIC
923 struct SystemHeaderTest2 {
924   struct RecordType {
925     int x; // expected-note{{uninitialized field 'this->container.t.x}}
926     int y; // expected-note{{uninitialized field 'this->container.t.y}}
927   };
928   ContainerInSystemHeader<RecordType> container;
929 
SystemHeaderTest2SystemHeaderTest2930   SystemHeaderTest2(RecordType &rec, int) : container(rec) {} // expected-warning{{2 uninitialized fields}}
931 };
932 
fSystemHeaderTest2()933 void fSystemHeaderTest2() {
934   SystemHeaderTest2::RecordType rec;
935   SystemHeaderTest2(rec, int());
936 }
937 #else
938 struct SystemHeaderTest2 {
939   struct RecordType {
940     int x;
941     int y;
942   };
943   ContainerInSystemHeader<RecordType> container;
944 
SystemHeaderTest2SystemHeaderTest2945   SystemHeaderTest2(RecordType &rec, int) : container(rec) {}
946 };
947 
fSystemHeaderTest2()948 void fSystemHeaderTest2() {
949   SystemHeaderTest2::RecordType rec;
950   SystemHeaderTest2(rec, int());
951 }
952 #endif //PEDANTIC
953 
954 //===----------------------------------------------------------------------===//
955 // Incomplete type tests.
956 //===----------------------------------------------------------------------===//
957 
958 struct IncompleteTypeTest1 {
959   struct RecordType;
960   // no-crash
961   RecordType *recptr; // expected-note{{uninitialized pointer 'this->recptr}}
962   int dontGetFilteredByNonPedanticMode = 0;
963 
IncompleteTypeTest1IncompleteTypeTest1964   IncompleteTypeTest1() {} // expected-warning{{1 uninitialized field}}
965 };
966 
fIncompleteTypeTest1()967 void fIncompleteTypeTest1() {
968   IncompleteTypeTest1();
969 }
970 
971 struct IncompleteTypeTest2 {
972   struct RecordType;
973   RecordType *recptr; // no-crash
974   int dontGetFilteredByNonPedanticMode = 0;
975 
976   RecordType *recordTypeFactory();
977 
IncompleteTypeTest2IncompleteTypeTest2978   IncompleteTypeTest2() : recptr(recordTypeFactory()) {}
979 };
980 
fIncompleteTypeTest2()981 void fIncompleteTypeTest2() {
982   IncompleteTypeTest2();
983 }
984 
985 struct IncompleteTypeTest3 {
986   struct RecordType;
987   RecordType &recref; // no-crash
988   int dontGetFilteredByNonPedanticMode = 0;
989 
990   RecordType &recordTypeFactory();
991 
IncompleteTypeTest3IncompleteTypeTest3992   IncompleteTypeTest3() : recref(recordTypeFactory()) {}
993 };
994 
fIncompleteTypeTest3()995 void fIncompleteTypeTest3() {
996   IncompleteTypeTest3();
997 }
998 
999 //===----------------------------------------------------------------------===//
1000 // Builtin type or enumeration type related tests.
1001 //===----------------------------------------------------------------------===//
1002 
1003 struct IntegralTypeTest {
1004   int a; // expected-note{{uninitialized field 'this->a'}}
1005   int dontGetFilteredByNonPedanticMode = 0;
1006 
IntegralTypeTestIntegralTypeTest1007   IntegralTypeTest() {} // expected-warning{{1 uninitialized field}}
1008 };
1009 
fIntegralTypeTest()1010 void fIntegralTypeTest() {
1011   IntegralTypeTest();
1012 }
1013 
1014 struct FloatingTypeTest {
1015   float a; // expected-note{{uninitialized field 'this->a'}}
1016   int dontGetFilteredByNonPedanticMode = 0;
1017 
FloatingTypeTestFloatingTypeTest1018   FloatingTypeTest() {} // expected-warning{{1 uninitialized field}}
1019 };
1020 
fFloatingTypeTest()1021 void fFloatingTypeTest() {
1022   FloatingTypeTest();
1023 }
1024 
1025 struct NullptrTypeTypeTest {
1026   decltype(nullptr) a; // expected-note{{uninitialized field 'this->a'}}
1027   int dontGetFilteredByNonPedanticMode = 0;
1028 
NullptrTypeTypeTestNullptrTypeTypeTest1029   NullptrTypeTypeTest() {} // expected-warning{{1 uninitialized field}}
1030 };
1031 
fNullptrTypeTypeTest()1032 void fNullptrTypeTypeTest() {
1033   NullptrTypeTypeTest();
1034 }
1035 
1036 struct EnumTest {
1037   enum Enum {
1038     A,
1039     B
1040   } enum1; // expected-note{{uninitialized field 'this->enum1'}}
1041   enum class Enum2 {
1042     A,
1043     B
1044   } enum2; // expected-note{{uninitialized field 'this->enum2'}}
1045   int dontGetFilteredByNonPedanticMode = 0;
1046 
EnumTestEnumTest1047   EnumTest() {} // expected-warning{{2 uninitialized fields}}
1048 };
1049 
fEnumTest()1050 void fEnumTest() {
1051   EnumTest();
1052 }
1053 
1054 //===----------------------------------------------------------------------===//
1055 // Tests for constructor calls within another cunstructor, without the two
1056 // records being in any relation.
1057 //===----------------------------------------------------------------------===//
1058 
1059 void halt() __attribute__((__noreturn__));
assert(int b)1060 void assert(int b) {
1061   if (!b)
1062     halt();
1063 }
1064 
1065 // While a singleton would make more sense as a static variable, that would zero
1066 // initialize all of its fields, hence the not too practical implementation.
1067 struct Singleton {
1068   int i; // expected-note{{uninitialized field 'this->i'}}
1069   int dontGetFilteredByNonPedanticMode = 0;
1070 
SingletonSingleton1071   Singleton() {
1072     assert(!isInstantiated);
1073     isInstantiated = true; // expected-warning{{1 uninitialized field}}
1074   }
1075 
~SingletonSingleton1076   ~Singleton() {
1077     isInstantiated = false;
1078   }
1079 
1080   static bool isInstantiated;
1081 };
1082 
1083 bool Singleton::isInstantiated = false;
1084 
1085 struct SingletonTest {
1086   int dontGetFilteredByNonPedanticMode = 0;
1087 
SingletonTestSingletonTest1088   SingletonTest() {
1089     Singleton();
1090   }
1091 };
1092 
fSingletonTest()1093 void fSingletonTest() {
1094   SingletonTest();
1095 }
1096 
1097 //===----------------------------------------------------------------------===//
1098 // C++11 member initializer tests.
1099 //===----------------------------------------------------------------------===//
1100 
1101 struct CXX11MemberInitTest1 {
1102   int a = 3;
1103   int b;
CXX11MemberInitTest1CXX11MemberInitTest11104   CXX11MemberInitTest1() : b(2) {
1105     // All good!
1106   }
1107 };
1108 
fCXX11MemberInitTest1()1109 void fCXX11MemberInitTest1() {
1110   CXX11MemberInitTest1();
1111 }
1112 
1113 struct CXX11MemberInitTest2 {
1114   struct RecordType {
1115     // TODO: we'd expect the note: {{uninitialized field 'this->rec.a'}}
1116     int a; // no-note
1117     // TODO: we'd expect the note: {{uninitialized field 'this->rec.b'}}
1118     int b; // no-note
1119 
RecordTypeCXX11MemberInitTest2::RecordType1120     RecordType(int) {}
1121   };
1122 
1123   RecordType rec = RecordType(int());
1124   int dontGetFilteredByNonPedanticMode = 0;
1125 
CXX11MemberInitTest2CXX11MemberInitTest21126   CXX11MemberInitTest2() {}
1127 };
1128 
fCXX11MemberInitTest2()1129 void fCXX11MemberInitTest2() {
1130   // TODO: we'd expect the warning: {{2 uninitializeds field}}
1131   CXX11MemberInitTest2(); // no-warning
1132 }
1133