blob: bcd3d85d0fd04da368f6d733db0f1395a98d9315 [file] [log] [blame]
Kristof Umann85e0ff72019-04-19 23:33:50 +00001// RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.cplusplus.UninitializedObject \
2// RUN: -analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \
3// RUN: -analyzer-config optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
Kristof Umannf0dd1012018-09-14 08:58:21 +00004// RUN: -std=c++14 -verify %s
Kristof Umann30f08652018-06-18 11:50:17 +00005
Kristof Umann85e0ff72019-04-19 23:33:50 +00006// RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.cplusplus.UninitializedObject \
7// RUN: -analyzer-config optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
Kristof Umannf0dd1012018-09-14 08:58:21 +00008// RUN: -std=c++14 -verify %s
Kristof Umann30f08652018-06-18 11:50:17 +00009
10//===----------------------------------------------------------------------===//
11// Default constructor test.
12//===----------------------------------------------------------------------===//
13
14class CompilerGeneratedConstructorTest {
15 int a, b, c, d, e, f, g, h, i, j;
16
17public:
18 CompilerGeneratedConstructorTest() = default;
19};
20
21void fCompilerGeneratedConstructorTest() {
22 CompilerGeneratedConstructorTest();
23}
24
25#ifdef PEDANTIC
26class DefaultConstructorTest {
27 int a; // expected-note{{uninitialized field 'this->a'}}
28
29public:
30 DefaultConstructorTest();
31};
32
33DefaultConstructorTest::DefaultConstructorTest() = default;
34
35void fDefaultConstructorTest() {
36 DefaultConstructorTest(); // expected-warning{{1 uninitialized field}}
37}
38#else
39class DefaultConstructorTest {
40 int a;
41
42public:
43 DefaultConstructorTest();
44};
45
46DefaultConstructorTest::DefaultConstructorTest() = default;
47
48void fDefaultConstructorTest() {
49 DefaultConstructorTest();
50}
51#endif // PEDANTIC
52
53//===----------------------------------------------------------------------===//
54// Initializer list test.
55//===----------------------------------------------------------------------===//
56
57class InitListTest1 {
58 int a;
59 int b;
60
61public:
62 InitListTest1()
63 : a(1),
64 b(2) {
65 // All good!
66 }
67};
68
69void fInitListTest1() {
70 InitListTest1();
71}
72
73class InitListTest2 {
74 int a;
75 int b; // expected-note{{uninitialized field 'this->b'}}
76
77public:
78 InitListTest2()
79 : a(3) {} // expected-warning{{1 uninitialized field}}
80};
81
82void fInitListTest2() {
83 InitListTest2();
84}
85
86class InitListTest3 {
87 int a; // expected-note{{uninitialized field 'this->a'}}
88 int b;
89
90public:
91 InitListTest3()
92 : b(4) {} // expected-warning{{1 uninitialized field}}
93};
94
95void fInitListTest3() {
96 InitListTest3();
97}
98
99//===----------------------------------------------------------------------===//
100// Constructor body test.
101//===----------------------------------------------------------------------===//
102
103class CtorBodyTest1 {
104 int a, b;
105
106public:
107 CtorBodyTest1() {
108 a = 5;
109 b = 6;
110 // All good!
111 }
112};
113
114void fCtorBodyTest1() {
115 CtorBodyTest1();
116}
117
118class CtorBodyTest2 {
119 int a;
120 int b; // expected-note{{uninitialized field 'this->b'}}
121
122public:
123 CtorBodyTest2() {
124 a = 7; // expected-warning{{1 uninitialized field}}
125 }
126};
127
128void fCtorBodyTest2() {
129 CtorBodyTest2();
130}
131
132class CtorBodyTest3 {
133 int a; // expected-note{{uninitialized field 'this->a'}}
134 int b;
135
136public:
137 CtorBodyTest3() {
138 b = 8; // expected-warning{{1 uninitialized field}}
139 }
140};
141
142void fCtorBodyTest3() {
143 CtorBodyTest3();
144}
145
146#ifdef PEDANTIC
147class CtorBodyTest4 {
148 int a; // expected-note{{uninitialized field 'this->a'}}
149 int b; // expected-note{{uninitialized field 'this->b'}}
150
151public:
152 CtorBodyTest4() {}
153};
154
155void fCtorBodyTest4() {
156 CtorBodyTest4(); // expected-warning{{2 uninitialized fields}}
157}
158#else
159class CtorBodyTest4 {
160 int a;
161 int b;
162
163public:
164 CtorBodyTest4() {}
165};
166
167void fCtorBodyTest4() {
168 CtorBodyTest4();
169}
170#endif
171
172//===----------------------------------------------------------------------===//
173// Constructor delegation test.
174//===----------------------------------------------------------------------===//
175
176class CtorDelegationTest1 {
177 int a;
178 int b;
179
180public:
181 CtorDelegationTest1(int)
182 : a(9) {
183 // leaves 'b' unintialized, but we'll never check this function
184 }
185
186 CtorDelegationTest1()
187 : CtorDelegationTest1(int{}) { // Initializing 'a'
188 b = 10;
189 // All good!
190 }
191};
192
193void fCtorDelegationTest1() {
194 CtorDelegationTest1();
195}
196
197class CtorDelegationTest2 {
198 int a; // expected-note{{uninitialized field 'this->a'}}
199 int b;
200
201public:
202 CtorDelegationTest2(int)
203 : b(11) {
204 // leaves 'a' unintialized, but we'll never check this function
205 }
206
207 CtorDelegationTest2()
208 : CtorDelegationTest2(int{}) { // expected-warning{{1 uninitialized field}}
209 }
210};
211
212void fCtorDelegationTest2() {
213 CtorDelegationTest2();
214}
215
216//===----------------------------------------------------------------------===//
217// Tests for classes containing records.
218//===----------------------------------------------------------------------===//
219
220class ContainsRecordTest1 {
221 struct RecordType {
222 int x;
223 int y;
224 } rec;
225 int c, d;
226
227public:
228 ContainsRecordTest1()
229 : rec({12, 13}),
230 c(14),
231 d(15) {
232 // All good!
233 }
234};
235
236void fContainsRecordTest1() {
237 ContainsRecordTest1();
238}
239
240class ContainsRecordTest2 {
241 struct RecordType {
242 int x;
243 int y; // expected-note{{uninitialized field 'this->rec.y'}}
244 } rec;
245 int c, d;
246
247public:
248 ContainsRecordTest2()
249 : c(16),
250 d(17) {
251 rec.x = 18; // expected-warning{{1 uninitialized field}}
252 }
253};
254
255void fContainsRecordTest2() {
256 ContainsRecordTest2();
257}
258
259class 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
266public:
267 ContainsRecordTest3()
268 : c(19),
269 d(20) { // expected-warning{{2 uninitialized fields}}
270 }
271};
272
273void fContainsRecordTest3() {
274 ContainsRecordTest3();
275}
276
277class 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
284public:
285 ContainsRecordTest4()
286 : c(19) { // expected-warning{{3 uninitialized fields}}
287 }
288};
289
290void fContainsRecordTest4() {
291 ContainsRecordTest4();
292}
293
294//===----------------------------------------------------------------------===//
295// Tests for template classes.
296//===----------------------------------------------------------------------===//
297
298template <class T>
299class IntTemplateClassTest1 {
300 T t;
301 int b;
302
303public:
304 IntTemplateClassTest1(T i) {
305 b = 21;
306 t = i;
307 // All good!
308 }
309};
310
311void fIntTemplateClassTest1() {
312 IntTemplateClassTest1<int>(22);
313}
314
315template <class T>
316class IntTemplateClassTest2 {
317 T t; // expected-note{{uninitialized field 'this->t'}}
318 int b;
319
320public:
321 IntTemplateClassTest2() {
322 b = 23; // expected-warning{{1 uninitialized field}}
323 }
324};
325
326void fIntTemplateClassTest2() {
327 IntTemplateClassTest2<int>();
328}
329
330struct Record {
331 int x; // expected-note{{uninitialized field 'this->t.x'}}
332 int y; // expected-note{{uninitialized field 'this->t.y'}}
333};
334
335template <class T>
336class RecordTemplateClassTest {
337 T t;
338 int b;
339
340public:
341 RecordTemplateClassTest() {
342 b = 24; // expected-warning{{2 uninitialized fields}}
343 }
344};
345
346void fRecordTemplateClassTest() {
347 RecordTemplateClassTest<Record>();
348}
349
350//===----------------------------------------------------------------------===//
351// Tests involving functions with unknown implementations.
352//===----------------------------------------------------------------------===//
353
354template <class T>
355void mayInitialize(T &);
356
357template <class T>
358void wontInitialize(const T &);
359
360class PassingToUnknownFunctionTest1 {
Artem Dergachev3d90e7e2019-04-03 18:21:16 +0000361 int a, b;
Kristof Umann30f08652018-06-18 11:50:17 +0000362
363public:
364 PassingToUnknownFunctionTest1() {
365 mayInitialize(a);
366 mayInitialize(b);
367 // All good!
368 }
369
370 PassingToUnknownFunctionTest1(int) {
Artem Dergachev3d90e7e2019-04-03 18:21:16 +0000371 mayInitialize(a);
372 // All good!
Kristof Umann30f08652018-06-18 11:50:17 +0000373 }
374
375 PassingToUnknownFunctionTest1(int, int) {
376 mayInitialize(*this);
377 // All good!
378 }
379};
380
381void fPassingToUnknownFunctionTest1() {
382 PassingToUnknownFunctionTest1();
383 PassingToUnknownFunctionTest1(int());
384 PassingToUnknownFunctionTest1(int(), int());
385}
386
387class PassingToUnknownFunctionTest2 {
388 int a; // expected-note{{uninitialized field 'this->a'}}
389 int b;
390
391public:
392 PassingToUnknownFunctionTest2() {
393 wontInitialize(a);
394 b = 4; // expected-warning{{1 uninitialized field}}
395 }
396};
397
398void 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
411class ContainsSimpleUnionTest1 {
412 union SimpleUnion {
413 float uf;
414 int ui;
415 char uc;
416 } u;
417
418public:
419 ContainsSimpleUnionTest1() {
420 u.uf = 3.14;
421 // All good!
422 }
423};
424
425void fContainsSimpleUnionTest1() {
426 ContainsSimpleUnionTest1();
427}
428
429class 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
437public:
438 ContainsSimpleUnionTest2() {}
439};
440
441void fContainsSimpleUnionTest2() {
442 // TODO: we'd expect the warning: {{1 uninitialized field}}
443 ContainsSimpleUnionTest2(); // no-warning
444}
445
446class UnionPointerTest1 {
447public:
448 union SimpleUnion {
449 float uf;
450 int ui;
451 char uc;
452 };
453
454private:
455 SimpleUnion *uptr;
456
457public:
458 UnionPointerTest1(SimpleUnion *uptr, int) : uptr(uptr) {
459 // All good!
460 }
461};
462
463void fUnionPointerTest1() {
464 UnionPointerTest1::SimpleUnion u;
465 u.uf = 41;
466 UnionPointerTest1(&u, int());
467}
468
469class UnionPointerTest2 {
470public:
471 union SimpleUnion {
472 float uf;
473 int ui;
474 char uc;
475 };
476
477private:
478 // TODO: we'd expect the note: {{uninitialized field 'this->uptr'}}
479 SimpleUnion *uptr; // no-note
480
481public:
482 UnionPointerTest2(SimpleUnion *uptr, char) : uptr(uptr) {}
483};
484
485void fUnionPointerTest2() {
486 UnionPointerTest2::SimpleUnion u;
487 // TODO: we'd expect the warning: {{1 uninitialized field}}
488 UnionPointerTest2(&u, int()); // no-warning
489}
490
491class ContainsUnionWithRecordTest1 {
492 union UnionWithRecord {
493 struct RecordType {
494 int x;
495 int y;
496 } us;
497 double ud;
498 long ul;
499
500 UnionWithRecord(){};
501 } u;
502
503public:
504 ContainsUnionWithRecordTest1() {
505 u.ud = 3.14;
506 // All good!
507 }
508};
509
510void fContainsUnionWithRecordTest1() {
511 ContainsUnionWithRecordTest1();
512}
513
514class ContainsUnionWithRecordTest2 {
515 union UnionWithRecord {
516 struct RecordType {
517 int x;
518 int y;
519 } us;
520 double ud;
521 long ul;
522
523 UnionWithRecord(){};
524 } u;
525
526public:
527 ContainsUnionWithRecordTest2() {
528 u.us = UnionWithRecord::RecordType{42, 43};
529 // All good!
530 }
531};
532
533void fContainsUnionWithRecordTest2() {
534 ContainsUnionWithRecordTest1();
535}
536
537class ContainsUnionWithRecordTest3 {
538 union UnionWithRecord {
539 struct RecordType {
540 int x;
541 int y;
542 } us;
543 double ud;
544 long ul;
545
546 UnionWithRecord(){};
547 // TODO: we'd expect the note: {{uninitialized field 'this->u'}}
548 } u; // no-note
549
550public:
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
559void fContainsUnionWithRecordTest3() {
560 ContainsUnionWithRecordTest3();
561}
562
563class 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
574public:
575 ContainsUnionWithSimpleUnionTest1() {
576 u.usu.ui = 5;
577 // All good!
578 }
579};
580
581void fContainsUnionWithSimpleUnionTest1() {
582 ContainsUnionWithSimpleUnionTest1();
583}
584
585class 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
597public:
598 ContainsUnionWithSimpleUnionTest2() {}
599};
600
601void fContainsUnionWithSimpleUnionTest2() {
602 // TODO: we'd expect the warning: {{1 uninitialized field}}
603 ContainsUnionWithSimpleUnionTest2(); // no-warning
604}
605
606//===----------------------------------------------------------------------===//
607// Zero initialization tests.
608//===----------------------------------------------------------------------===//
609
610struct GlobalVariableTest {
611 int i;
612
613 GlobalVariableTest() {}
614};
615
616GlobalVariableTest gvt; // no-warning
617
618//===----------------------------------------------------------------------===//
619// Copy and move constructor tests.
620//===----------------------------------------------------------------------===//
621
622template <class T>
623void funcToSquelchCompilerWarnings(const T &t);
624
625#ifdef PEDANTIC
626struct CopyConstructorTest {
627 int i; // expected-note{{uninitialized field 'this->i'}}
628
629 CopyConstructorTest() : i(1337) {}
630 CopyConstructorTest(const CopyConstructorTest &other) {}
631};
632
633void fCopyConstructorTest() {
634 CopyConstructorTest cct;
635 CopyConstructorTest copy = cct; // expected-warning{{1 uninitialized field}}
636 funcToSquelchCompilerWarnings(copy);
637}
638#else
639struct CopyConstructorTest {
640 int i;
641
642 CopyConstructorTest() : i(1337) {}
643 CopyConstructorTest(const CopyConstructorTest &other) {}
644};
645
646void fCopyConstructorTest() {
647 CopyConstructorTest cct;
648 CopyConstructorTest copy = cct;
649 funcToSquelchCompilerWarnings(copy);
650}
651#endif // PEDANTIC
652
653struct MoveConstructorTest {
654 // TODO: we'd expect the note: {{uninitialized field 'this->i'}}
655 int i; // no-note
656
657 MoveConstructorTest() : i(1337) {}
658 MoveConstructorTest(const CopyConstructorTest &other) = delete;
659 MoveConstructorTest(const CopyConstructorTest &&other) {}
660};
661
662void 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
673struct IntArrayTest {
674 int arr[256];
675
676 IntArrayTest() {
677 // All good!
678 }
679};
680
681void fIntArrayTest() {
682 IntArrayTest();
683}
684
685struct RecordTypeArrayTest {
686 struct RecordType {
687 int x, y;
688 } arr[256];
689
690 RecordTypeArrayTest() {
691 // All good!
692 }
693};
694
695void fRecordTypeArrayTest() {
696 RecordTypeArrayTest();
697}
698
699template <class T>
700class CharArrayPointerTest {
701 T *t; // no-crash
702
703public:
704 CharArrayPointerTest(T *t, int) : t(t) {}
705};
706
707void fCharArrayPointerTest() {
708 char str[16] = "012345678912345";
709 CharArrayPointerTest<char[16]>(&str, int());
710}
711
712//===----------------------------------------------------------------------===//
713// Memset tests.
714//===----------------------------------------------------------------------===//
715
716struct MemsetTest1 {
717 int a, b, c;
718
719 MemsetTest1() {
720 __builtin_memset(this, 0, sizeof(decltype(*this)));
721 }
722};
723
724void fMemsetTest1() {
725 MemsetTest1();
726}
727
728struct MemsetTest2 {
729 int a;
730
731 MemsetTest2() {
732 __builtin_memset(&a, 0, sizeof(int));
733 }
734};
735
736void fMemsetTest2() {
737 MemsetTest2();
738}
739
740//===----------------------------------------------------------------------===//
741// Lambda tests.
742//===----------------------------------------------------------------------===//
743
744template <class Callable>
Kristof Umann8c119092018-07-13 12:54:47 +0000745struct LambdaThisTest {
746 Callable functor;
747
748 LambdaThisTest(const Callable &functor, int) : functor(functor) {
749 // All good!
750 }
751};
752
753struct HasCapturableThis {
754 void fLambdaThisTest() {
755 auto isEven = [this](int a) { return a % 2 == 0; }; // no-crash
756 LambdaThisTest<decltype(isEven)>(isEven, int());
757 }
758};
759
760template <class Callable>
Kristof Umann30f08652018-06-18 11:50:17 +0000761struct LambdaTest1 {
762 Callable functor;
763
764 LambdaTest1(const Callable &functor, int) : functor(functor) {
765 // All good!
766 }
767};
768
769void fLambdaTest1() {
770 auto isEven = [](int a) { return a % 2 == 0; };
771 LambdaTest1<decltype(isEven)>(isEven, int());
772}
773
774#ifdef PEDANTIC
775template <class Callable>
776struct LambdaTest2 {
777 Callable functor;
778
779 LambdaTest2(const Callable &functor, int) : functor(functor) {} // expected-warning{{1 uninitialized field}}
780};
781
782void fLambdaTest2() {
783 int b;
Kristof Umannf0dd1012018-09-14 08:58:21 +0000784 auto equals = [&b](int a) { return a == b; }; // expected-note{{uninitialized pointee 'this->functor./*captured variable*/b'}}
Kristof Umann30f08652018-06-18 11:50:17 +0000785 LambdaTest2<decltype(equals)>(equals, int());
786}
787#else
788template <class Callable>
789struct LambdaTest2 {
790 Callable functor;
791
792 LambdaTest2(const Callable &functor, int) : functor(functor) {}
793};
794
795void 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
803namespace LT3Detail {
804
805struct RecordType {
Kristof Umannf0dd1012018-09-14 08:58:21 +0000806 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'}}
Kristof Umann30f08652018-06-18 11:50:17 +0000808};
809
810} // namespace LT3Detail
811template <class Callable>
812struct LambdaTest3 {
813 Callable functor;
814
815 LambdaTest3(const Callable &functor, int) : functor(functor) {} // expected-warning{{2 uninitialized fields}}
816};
817
818void 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
826namespace LT3Detail {
827
828struct RecordType {
829 int x;
830 int y;
831};
832
833} // namespace LT3Detail
834template <class Callable>
835struct LambdaTest3 {
836 Callable functor;
837
838 LambdaTest3(const Callable &functor, int) : functor(functor) {}
839};
840
841void 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
Kristof Umann8c119092018-07-13 12:54:47 +0000850template <class Callable>
851struct MultipleLambdaCapturesTest1 {
852 Callable functor;
853 int dontGetFilteredByNonPedanticMode = 0;
854
855 MultipleLambdaCapturesTest1(const Callable &functor, int) : functor(functor) {} // expected-warning{{2 uninitialized field}}
856};
857
858void fMultipleLambdaCapturesTest1() {
859 int b1, b2 = 3, b3;
Kristof Umannf0dd1012018-09-14 08:58:21 +0000860 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'}}
Kristof Umann8c119092018-07-13 12:54:47 +0000862 MultipleLambdaCapturesTest1<decltype(equals)>(equals, int());
863}
864
865template <class Callable>
866struct MultipleLambdaCapturesTest2 {
867 Callable functor;
868 int dontGetFilteredByNonPedanticMode = 0;
869
870 MultipleLambdaCapturesTest2(const Callable &functor, int) : functor(functor) {} // expected-warning{{1 uninitialized field}}
871};
872
873void fMultipleLambdaCapturesTest2() {
874 int b1, b2 = 3, b3;
Kristof Umannf0dd1012018-09-14 08:58:21 +0000875 auto equals = [b1, &b2, &b3](int a) { return a == b1 == b2 == b3; }; // expected-note{{uninitialized pointee 'this->functor./*captured variable*/b3'}}
Kristof Umann8c119092018-07-13 12:54:47 +0000876 MultipleLambdaCapturesTest2<decltype(equals)>(equals, int());
877}
878
Kristof Umannf0dd1012018-09-14 08:58:21 +0000879struct LambdaWrapper {
880 void *func; // no-crash
881 int dontGetFilteredByNonPedanticMode = 0;
882
883 LambdaWrapper(void *ptr) : func(ptr) {} // expected-warning{{1 uninitialized field}}
884};
885
886struct ThisCapturingLambdaFactory {
887 int a; // expected-note{{uninitialized field 'static_cast<decltype(a.ret()) *>(this->func)->/*'this' capture*/->a'}}
888
889 auto ret() {
890 return [this] { (void)this; };
891 }
892};
893
894void fLambdaFieldWithInvalidThisCapture() {
895 void *ptr;
896 {
897 ThisCapturingLambdaFactory a;
898 decltype(a.ret()) lambda = a.ret();
899 ptr = &lambda;
900 }
901 LambdaWrapper t(ptr);
902}
903
Kristof Umann30f08652018-06-18 11:50:17 +0000904//===----------------------------------------------------------------------===//
905// System header tests.
906//===----------------------------------------------------------------------===//
907
908#include "Inputs/system-header-simulator-for-cxx-uninitialized-object.h"
909
910struct SystemHeaderTest1 {
911 RecordInSystemHeader rec; // defined in the system header simulator
912
913 SystemHeaderTest1() {
914 // All good!
915 }
916};
917
918void fSystemHeaderTest1() {
919 SystemHeaderTest1();
920}
921
922#ifdef PEDANTIC
923struct 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
930 SystemHeaderTest2(RecordType &rec, int) : container(rec) {} // expected-warning{{2 uninitialized fields}}
931};
932
933void fSystemHeaderTest2() {
934 SystemHeaderTest2::RecordType rec;
935 SystemHeaderTest2(rec, int());
936}
937#else
938struct SystemHeaderTest2 {
939 struct RecordType {
940 int x;
941 int y;
942 };
943 ContainerInSystemHeader<RecordType> container;
944
945 SystemHeaderTest2(RecordType &rec, int) : container(rec) {}
946};
947
948void fSystemHeaderTest2() {
949 SystemHeaderTest2::RecordType rec;
950 SystemHeaderTest2(rec, int());
951}
952#endif //PEDANTIC
953
954//===----------------------------------------------------------------------===//
955// Incomplete type tests.
956//===----------------------------------------------------------------------===//
957
958struct IncompleteTypeTest1 {
959 struct RecordType;
960 // no-crash
961 RecordType *recptr; // expected-note{{uninitialized pointer 'this->recptr}}
962 int dontGetFilteredByNonPedanticMode = 0;
963
964 IncompleteTypeTest1() {} // expected-warning{{1 uninitialized field}}
965};
966
967void fIncompleteTypeTest1() {
968 IncompleteTypeTest1();
969}
970
971struct IncompleteTypeTest2 {
972 struct RecordType;
973 RecordType *recptr; // no-crash
974 int dontGetFilteredByNonPedanticMode = 0;
975
976 RecordType *recordTypeFactory();
977
978 IncompleteTypeTest2() : recptr(recordTypeFactory()) {}
979};
980
981void fIncompleteTypeTest2() {
982 IncompleteTypeTest2();
983}
984
985struct IncompleteTypeTest3 {
986 struct RecordType;
987 RecordType &recref; // no-crash
988 int dontGetFilteredByNonPedanticMode = 0;
989
990 RecordType &recordTypeFactory();
991
992 IncompleteTypeTest3() : recref(recordTypeFactory()) {}
993};
994
995void fIncompleteTypeTest3() {
996 IncompleteTypeTest3();
997}
998
999//===----------------------------------------------------------------------===//
1000// Builtin type or enumeration type related tests.
1001//===----------------------------------------------------------------------===//
1002
1003struct IntegralTypeTest {
1004 int a; // expected-note{{uninitialized field 'this->a'}}
1005 int dontGetFilteredByNonPedanticMode = 0;
1006
1007 IntegralTypeTest() {} // expected-warning{{1 uninitialized field}}
1008};
1009
1010void fIntegralTypeTest() {
1011 IntegralTypeTest();
1012}
1013
1014struct FloatingTypeTest {
1015 float a; // expected-note{{uninitialized field 'this->a'}}
1016 int dontGetFilteredByNonPedanticMode = 0;
1017
1018 FloatingTypeTest() {} // expected-warning{{1 uninitialized field}}
1019};
1020
1021void fFloatingTypeTest() {
1022 FloatingTypeTest();
1023}
1024
1025struct NullptrTypeTypeTest {
1026 decltype(nullptr) a; // expected-note{{uninitialized field 'this->a'}}
1027 int dontGetFilteredByNonPedanticMode = 0;
1028
1029 NullptrTypeTypeTest() {} // expected-warning{{1 uninitialized field}}
1030};
1031
1032void fNullptrTypeTypeTest() {
1033 NullptrTypeTypeTest();
1034}
1035
1036struct 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
1047 EnumTest() {} // expected-warning{{2 uninitialized fields}}
1048};
1049
1050void 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
1059void halt() __attribute__((__noreturn__));
1060void 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.
1067struct Singleton {
Kristof Umann0735cfb2018-08-08 12:23:02 +00001068 int i; // expected-note{{uninitialized field 'this->i'}}
1069 int dontGetFilteredByNonPedanticMode = 0;
Kristof Umann30f08652018-06-18 11:50:17 +00001070
1071 Singleton() {
1072 assert(!isInstantiated);
Kristof Umann0735cfb2018-08-08 12:23:02 +00001073 isInstantiated = true; // expected-warning{{1 uninitialized field}}
Kristof Umann30f08652018-06-18 11:50:17 +00001074 }
1075
1076 ~Singleton() {
1077 isInstantiated = false;
1078 }
1079
1080 static bool isInstantiated;
1081};
1082
1083bool Singleton::isInstantiated = false;
1084
1085struct SingletonTest {
1086 int dontGetFilteredByNonPedanticMode = 0;
1087
1088 SingletonTest() {
1089 Singleton();
1090 }
1091};
1092
1093void fSingletonTest() {
1094 SingletonTest();
1095}
1096
1097//===----------------------------------------------------------------------===//
1098// C++11 member initializer tests.
1099//===----------------------------------------------------------------------===//
1100
1101struct CXX11MemberInitTest1 {
1102 int a = 3;
1103 int b;
1104 CXX11MemberInitTest1() : b(2) {
1105 // All good!
1106 }
1107};
1108
1109void fCXX11MemberInitTest1() {
1110 CXX11MemberInitTest1();
1111}
1112
1113struct 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
1120 RecordType(int) {}
1121 };
1122
1123 RecordType rec = RecordType(int());
1124 int dontGetFilteredByNonPedanticMode = 0;
1125
1126 CXX11MemberInitTest2() {}
1127};
1128
1129void fCXX11MemberInitTest2() {
1130 // TODO: we'd expect the warning: {{2 uninitializeds field}}
1131 CXX11MemberInitTest2(); // no-warning
1132}