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