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