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 = λ
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