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