Clang Project

clang_source_code/test/Analysis/cxx-uninitialized-object.cpp
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
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 {
361  int a, b; // expected-note{{uninitialized field 'this->b'}}
362
363public:
364  PassingToUnknownFunctionTest1() {
365    mayInitialize(a);
366    mayInitialize(b);
367    // All good!
368  }
369
370  PassingToUnknownFunctionTest1(int) {
371    mayInitialize(a); // expected-warning{{1 uninitialized field at the end of the constructor call}}
372  }
373
374  PassingToUnknownFunctionTest1(int, int) {
375    mayInitialize(*this);
376    // All good!
377  }
378};
379
380void fPassingToUnknownFunctionTest1() {
381  PassingToUnknownFunctionTest1();
382  PassingToUnknownFunctionTest1(int());
383  PassingToUnknownFunctionTest1(int(), int());
384}
385
386class PassingToUnknownFunctionTest2 {
387  int a; // expected-note{{uninitialized field 'this->a'}}
388  int b;
389
390public:
391  PassingToUnknownFunctionTest2() {
392    wontInitialize(a);
393    b = 4; // expected-warning{{1 uninitialized field}}
394  }
395};
396
397void fPassingToUnknownFunctionTest2() {
398  PassingToUnknownFunctionTest2();
399}
400
401//===----------------------------------------------------------------------===//
402// Tests for classes containing unions.
403//===----------------------------------------------------------------------===//
404
405// FIXME: As of writing this checker, there is no good support for union types
406// in the Static Analyzer. Here is non-exhaustive list of cases.
407// Note that the rules for unions are different in C and C++.
408// http://lists.llvm.org/pipermail/cfe-dev/2017-March/052910.html
409
410class ContainsSimpleUnionTest1 {
411  union SimpleUnion {
412    float uf;
413    int ui;
414    char uc;
415  } u;
416
417public:
418  ContainsSimpleUnionTest1() {
419    u.uf = 3.14;
420    // All good!
421  }
422};
423
424void fContainsSimpleUnionTest1() {
425  ContainsSimpleUnionTest1();
426}
427
428class ContainsSimpleUnionTest2 {
429  union SimpleUnion {
430    float uf;
431    int ui;
432    char uc;
433    // TODO: we'd expect the note: {{uninitialized field 'this->u'}}
434  } u; // no-note
435
436public:
437  ContainsSimpleUnionTest2() {}
438};
439
440void fContainsSimpleUnionTest2() {
441  // TODO: we'd expect the warning: {{1 uninitialized field}}
442  ContainsSimpleUnionTest2(); // no-warning
443}
444
445class UnionPointerTest1 {
446public:
447  union SimpleUnion {
448    float uf;
449    int ui;
450    char uc;
451  };
452
453private:
454  SimpleUnion *uptr;
455
456public:
457  UnionPointerTest1(SimpleUnion *uptr, int) : uptr(uptr) {
458    // All good!
459  }
460};
461
462void fUnionPointerTest1() {
463  UnionPointerTest1::SimpleUnion u;
464  u.uf = 41;
465  UnionPointerTest1(&u, int());
466}
467
468class UnionPointerTest2 {
469public:
470  union SimpleUnion {
471    float uf;
472    int ui;
473    char uc;
474  };
475
476private:
477  // TODO: we'd expect the note: {{uninitialized field 'this->uptr'}}
478  SimpleUnion *uptr; // no-note
479
480public:
481  UnionPointerTest2(SimpleUnion *uptr, char) : uptr(uptr) {}
482};
483
484void fUnionPointerTest2() {
485  UnionPointerTest2::SimpleUnion u;
486  // TODO: we'd expect the warning: {{1 uninitialized field}}
487  UnionPointerTest2(&u, int()); // no-warning
488}
489
490class ContainsUnionWithRecordTest1 {
491  union UnionWithRecord {
492    struct RecordType {
493      int x;
494      int y;
495    } us;
496    double ud;
497    long ul;
498
499    UnionWithRecord(){};
500  } u;
501
502public:
503  ContainsUnionWithRecordTest1() {
504    u.ud = 3.14;
505    // All good!
506  }
507};
508
509void fContainsUnionWithRecordTest1() {
510  ContainsUnionWithRecordTest1();
511}
512
513class ContainsUnionWithRecordTest2 {
514  union UnionWithRecord {
515    struct RecordType {
516      int x;
517      int y;
518    } us;
519    double ud;
520    long ul;
521
522    UnionWithRecord(){};
523  } u;
524
525public:
526  ContainsUnionWithRecordTest2() {
527    u.us = UnionWithRecord::RecordType{42, 43};
528    // All good!
529  }
530};
531
532void fContainsUnionWithRecordTest2() {
533  ContainsUnionWithRecordTest1();
534}
535
536class ContainsUnionWithRecordTest3 {
537  union UnionWithRecord {
538    struct RecordType {
539      int x;
540      int y;
541    } us;
542    double ud;
543    long ul;
544
545    UnionWithRecord(){};
546    // TODO: we'd expect the note: {{uninitialized field 'this->u'}}
547  } u; // no-note
548
549public:
550  ContainsUnionWithRecordTest3() {
551    UnionWithRecord::RecordType rec;
552    rec.x = 44;
553    // TODO: we'd expect the warning: {{1 uninitialized field}}
554    u.us = rec; // no-warning
555  }
556};
557
558void fContainsUnionWithRecordTest3() {
559  ContainsUnionWithRecordTest3();
560}
561
562class ContainsUnionWithSimpleUnionTest1 {
563  union UnionWithSimpleUnion {
564    union SimpleUnion {
565      float uf;
566      int ui;
567      char uc;
568    } usu;
569    long ul;
570    unsigned uu;
571  } u;
572
573public:
574  ContainsUnionWithSimpleUnionTest1() {
575    u.usu.ui = 5;
576    // All good!
577  }
578};
579
580void fContainsUnionWithSimpleUnionTest1() {
581  ContainsUnionWithSimpleUnionTest1();
582}
583
584class ContainsUnionWithSimpleUnionTest2 {
585  union UnionWithSimpleUnion {
586    union SimpleUnion {
587      float uf;
588      int ui;
589      char uc;
590    } usu;
591    long ul;
592    unsigned uu;
593    // TODO: we'd expect the note: {{uninitialized field 'this->u'}}
594  } u; // no-note
595
596public:
597  ContainsUnionWithSimpleUnionTest2() {}
598};
599
600void fContainsUnionWithSimpleUnionTest2() {
601  // TODO: we'd expect the warning: {{1 uninitialized field}}
602  ContainsUnionWithSimpleUnionTest2(); // no-warning
603}
604
605//===----------------------------------------------------------------------===//
606// Zero initialization tests.
607//===----------------------------------------------------------------------===//
608
609struct GlobalVariableTest {
610  int i;
611
612  GlobalVariableTest() {}
613};
614
615GlobalVariableTest gvt; // no-warning
616
617//===----------------------------------------------------------------------===//
618// Copy and move constructor tests.
619//===----------------------------------------------------------------------===//
620
621template <class T>
622void funcToSquelchCompilerWarnings(const T &t);
623
624#ifdef PEDANTIC
625struct CopyConstructorTest {
626  int i; // expected-note{{uninitialized field 'this->i'}}
627
628  CopyConstructorTest() : i(1337) {}
629  CopyConstructorTest(const CopyConstructorTest &other) {}
630};
631
632void fCopyConstructorTest() {
633  CopyConstructorTest cct;
634  CopyConstructorTest copy = cct; // expected-warning{{1 uninitialized field}}
635  funcToSquelchCompilerWarnings(copy);
636}
637#else
638struct CopyConstructorTest {
639  int i;
640
641  CopyConstructorTest() : i(1337) {}
642  CopyConstructorTest(const CopyConstructorTest &other) {}
643};
644
645void fCopyConstructorTest() {
646  CopyConstructorTest cct;
647  CopyConstructorTest copy = cct;
648  funcToSquelchCompilerWarnings(copy);
649}
650#endif // PEDANTIC
651
652struct MoveConstructorTest {
653  // TODO: we'd expect the note: {{uninitialized field 'this->i'}}
654  int i; // no-note
655
656  MoveConstructorTest() : i(1337) {}
657  MoveConstructorTest(const CopyConstructorTest &other) = delete;
658  MoveConstructorTest(const CopyConstructorTest &&other) {}
659};
660
661void fMoveConstructorTest() {
662  MoveConstructorTest cct;
663  // TODO: we'd expect the warning: {{1 uninitialized field}}
664  MoveConstructorTest copy(static_cast<MoveConstructorTest &&>(cct)); // no-warning
665  funcToSquelchCompilerWarnings(copy);
666}
667
668//===----------------------------------------------------------------------===//
669// Array tests.
670//===----------------------------------------------------------------------===//
671
672struct IntArrayTest {
673  int arr[256];
674
675  IntArrayTest() {
676    // All good!
677  }
678};
679
680void fIntArrayTest() {
681  IntArrayTest();
682}
683
684struct RecordTypeArrayTest {
685  struct RecordType {
686    int x, y;
687  } arr[256];
688
689  RecordTypeArrayTest() {
690    // All good!
691  }
692};
693
694void fRecordTypeArrayTest() {
695  RecordTypeArrayTest();
696}
697
698template <class T>
699class CharArrayPointerTest {
700  T *t; // no-crash
701
702public:
703  CharArrayPointerTest(T *t, int) : t(t) {}
704};
705
706void fCharArrayPointerTest() {
707  char str[16] = "012345678912345";
708  CharArrayPointerTest<char[16]>(&str, int());
709}
710
711//===----------------------------------------------------------------------===//
712// Memset tests.
713//===----------------------------------------------------------------------===//
714
715struct MemsetTest1 {
716  int a, b, c;
717
718  MemsetTest1() {
719    __builtin_memset(this, 0, sizeof(decltype(*this)));
720  }
721};
722
723void fMemsetTest1() {
724  MemsetTest1();
725}
726
727struct MemsetTest2 {
728  int a;
729
730  MemsetTest2() {
731    __builtin_memset(&a, 0, sizeof(int));
732  }
733};
734
735void fMemsetTest2() {
736  MemsetTest2();
737}
738
739//===----------------------------------------------------------------------===//
740// Lambda tests.
741//===----------------------------------------------------------------------===//
742
743template <class Callable>
744struct LambdaThisTest {
745  Callable functor;
746
747  LambdaThisTest(const Callable &functor, int) : functor(functor) {
748    // All good!
749  }
750};
751
752struct HasCapturableThis {
753  void fLambdaThisTest() {
754    auto isEven = [this](int a) { return a % 2 == 0; }; // no-crash
755    LambdaThisTest<decltype(isEven)>(isEven, int());
756  }
757};
758
759template <class Callable>
760struct LambdaTest1 {
761  Callable functor;
762
763  LambdaTest1(const Callable &functor, int) : functor(functor) {
764    // All good!
765  }
766};
767
768void fLambdaTest1() {
769  auto isEven = [](int a) { return a % 2 == 0; };
770  LambdaTest1<decltype(isEven)>(isEven, int());
771}
772
773#ifdef PEDANTIC
774template <class Callable>
775struct LambdaTest2 {
776  Callable functor;
777
778  LambdaTest2(const Callable &functor, int) : functor(functor) {} // expected-warning{{1 uninitialized field}}
779};
780
781void fLambdaTest2() {
782  int b;
783  auto equals = [&b](int a) { return a == b; }; // expected-note{{uninitialized pointee 'this->functor./*captured variable*/b'}}
784  LambdaTest2<decltype(equals)>(equals, int());
785}
786#else
787template <class Callable>
788struct LambdaTest2 {
789  Callable functor;
790
791  LambdaTest2(const Callable &functor, int) : functor(functor) {}
792};
793
794void fLambdaTest2() {
795  int b;
796  auto equals = [&b](int a) { return a == b; };
797  LambdaTest2<decltype(equals)>(equals, int());
798}
799#endif //PEDANTIC
800
801#ifdef PEDANTIC
802namespace LT3Detail {
803
804struct RecordType {
805  int x; // expected-note{{uninitialized field 'this->functor./*captured variable*/rec1.x'}}
806  int y; // expected-note{{uninitialized field 'this->functor./*captured variable*/rec1.y'}}
807};
808
809} // namespace LT3Detail
810template <class Callable>
811struct LambdaTest3 {
812  Callable functor;
813
814  LambdaTest3(const Callable &functor, int) : functor(functor) {} // expected-warning{{2 uninitialized fields}}
815};
816
817void fLambdaTest3() {
818  LT3Detail::RecordType rec1;
819  auto equals = [&rec1](LT3Detail::RecordType rec2) {
820    return rec1.x == rec2.x;
821  };
822  LambdaTest3<decltype(equals)>(equals, int());
823}
824#else
825namespace LT3Detail {
826
827struct RecordType {
828  int x;
829  int y;
830};
831
832} // namespace LT3Detail
833template <class Callable>
834struct LambdaTest3 {
835  Callable functor;
836
837  LambdaTest3(const Callable &functor, int) : functor(functor) {}
838};
839
840void fLambdaTest3() {
841  LT3Detail::RecordType rec1;
842  auto equals = [&rec1](LT3Detail::RecordType rec2) {
843    return rec1.x == rec2.x;
844  };
845  LambdaTest3<decltype(equals)>(equals, int());
846}
847#endif //PEDANTIC
848
849template <class Callable>
850struct MultipleLambdaCapturesTest1 {
851  Callable functor;
852  int dontGetFilteredByNonPedanticMode = 0;
853
854  MultipleLambdaCapturesTest1(const Callable &functor, int) : functor(functor) {} // expected-warning{{2 uninitialized field}}
855};
856
857void fMultipleLambdaCapturesTest1() {
858  int b1, b2 = 3, b3;
859  auto equals = [&b1, &b2, &b3](int a) { return a == b1 == b2 == b3; }; // expected-note{{uninitialized pointee 'this->functor./*captured variable*/b1'}}
860  // expected-note@-1{{uninitialized pointee 'this->functor./*captured variable*/b3'}}
861  MultipleLambdaCapturesTest1<decltype(equals)>(equals, int());
862}
863
864template <class Callable>
865struct MultipleLambdaCapturesTest2 {
866  Callable functor;
867  int dontGetFilteredByNonPedanticMode = 0;
868
869  MultipleLambdaCapturesTest2(const Callable &functor, int) : functor(functor) {} // expected-warning{{1 uninitialized field}}
870};
871
872void fMultipleLambdaCapturesTest2() {
873  int b1, b2 = 3, b3;
874  auto equals = [b1, &b2, &b3](int a) { return a == b1 == b2 == b3; }; // expected-note{{uninitialized pointee 'this->functor./*captured variable*/b3'}}
875  MultipleLambdaCapturesTest2<decltype(equals)>(equals, int());
876}
877
878struct LambdaWrapper {
879  void *func; // no-crash
880  int dontGetFilteredByNonPedanticMode = 0;
881
882  LambdaWrapper(void *ptr) : func(ptr) {} // expected-warning{{1 uninitialized field}}
883};
884
885struct ThisCapturingLambdaFactory {
886  int a; // expected-note{{uninitialized field 'static_cast<decltype(a.ret()) *>(this->func)->/*'this' capture*/->a'}}
887
888  auto ret() {
889    return [this] { (void)this; };
890  }
891};
892
893void fLambdaFieldWithInvalidThisCapture() {
894  void *ptr;
895  {
896    ThisCapturingLambdaFactory a;
897    decltype(a.ret()) lambda = a.ret();
898    ptr = &lambda;
899  }
900  LambdaWrapper t(ptr);
901}
902
903//===----------------------------------------------------------------------===//
904// System header tests.
905//===----------------------------------------------------------------------===//
906
907#include "Inputs/system-header-simulator-for-cxx-uninitialized-object.h"
908
909struct SystemHeaderTest1 {
910  RecordInSystemHeader rec; // defined in the system header simulator
911
912  SystemHeaderTest1() {
913    // All good!
914  }
915};
916
917void fSystemHeaderTest1() {
918  SystemHeaderTest1();
919}
920
921#ifdef PEDANTIC
922struct SystemHeaderTest2 {
923  struct RecordType {
924    int x; // expected-note{{uninitialized field 'this->container.t.x}}
925    int y; // expected-note{{uninitialized field 'this->container.t.y}}
926  };
927  ContainerInSystemHeader<RecordType> container;
928
929  SystemHeaderTest2(RecordType &rec, int) : container(rec) {} // expected-warning{{2 uninitialized fields}}
930};
931
932void fSystemHeaderTest2() {
933  SystemHeaderTest2::RecordType rec;
934  SystemHeaderTest2(rec, int());
935}
936#else
937struct SystemHeaderTest2 {
938  struct RecordType {
939    int x;
940    int y;
941  };
942  ContainerInSystemHeader<RecordType> container;
943
944  SystemHeaderTest2(RecordType &rec, int) : container(rec) {}
945};
946
947void fSystemHeaderTest2() {
948  SystemHeaderTest2::RecordType rec;
949  SystemHeaderTest2(rec, int());
950}
951#endif //PEDANTIC
952
953//===----------------------------------------------------------------------===//
954// Incomplete type tests.
955//===----------------------------------------------------------------------===//
956
957struct IncompleteTypeTest1 {
958  struct RecordType;
959  // no-crash
960  RecordType *recptr; // expected-note{{uninitialized pointer 'this->recptr}}
961  int dontGetFilteredByNonPedanticMode = 0;
962
963  IncompleteTypeTest1() {} // expected-warning{{1 uninitialized field}}
964};
965
966void fIncompleteTypeTest1() {
967  IncompleteTypeTest1();
968}
969
970struct IncompleteTypeTest2 {
971  struct RecordType;
972  RecordType *recptr; // no-crash
973  int dontGetFilteredByNonPedanticMode = 0;
974
975  RecordType *recordTypeFactory();
976
977  IncompleteTypeTest2() : recptr(recordTypeFactory()) {}
978};
979
980void fIncompleteTypeTest2() {
981  IncompleteTypeTest2();
982}
983
984struct IncompleteTypeTest3 {
985  struct RecordType;
986  RecordType &recref; // no-crash
987  int dontGetFilteredByNonPedanticMode = 0;
988
989  RecordType &recordTypeFactory();
990
991  IncompleteTypeTest3() : recref(recordTypeFactory()) {}
992};
993
994void fIncompleteTypeTest3() {
995  IncompleteTypeTest3();
996}
997
998//===----------------------------------------------------------------------===//
999// Builtin type or enumeration type related tests.
1000//===----------------------------------------------------------------------===//
1001
1002struct IntegralTypeTest {
1003  int a; // expected-note{{uninitialized field 'this->a'}}
1004  int dontGetFilteredByNonPedanticMode = 0;
1005
1006  IntegralTypeTest() {} // expected-warning{{1 uninitialized field}}
1007};
1008
1009void fIntegralTypeTest() {
1010  IntegralTypeTest();
1011}
1012
1013struct FloatingTypeTest {
1014  float a; // expected-note{{uninitialized field 'this->a'}}
1015  int dontGetFilteredByNonPedanticMode = 0;
1016
1017  FloatingTypeTest() {} // expected-warning{{1 uninitialized field}}
1018};
1019
1020void fFloatingTypeTest() {
1021  FloatingTypeTest();
1022}
1023
1024struct NullptrTypeTypeTest {
1025  decltype(nullptr) a; // expected-note{{uninitialized field 'this->a'}}
1026  int dontGetFilteredByNonPedanticMode = 0;
1027
1028  NullptrTypeTypeTest() {} // expected-warning{{1 uninitialized field}}
1029};
1030
1031void fNullptrTypeTypeTest() {
1032  NullptrTypeTypeTest();
1033}
1034
1035struct EnumTest {
1036  enum Enum {
1037    A,
1038    B
1039  } enum1; // expected-note{{uninitialized field 'this->enum1'}}
1040  enum class Enum2 {
1041    A,
1042    B
1043  } enum2; // expected-note{{uninitialized field 'this->enum2'}}
1044  int dontGetFilteredByNonPedanticMode = 0;
1045
1046  EnumTest() {} // expected-warning{{2 uninitialized fields}}
1047};
1048
1049void fEnumTest() {
1050  EnumTest();
1051}
1052
1053//===----------------------------------------------------------------------===//
1054// Tests for constructor calls within another cunstructor, without the two
1055// records being in any relation.
1056//===----------------------------------------------------------------------===//
1057
1058void halt() __attribute__((__noreturn__));
1059void assert(int b) {
1060  if (!b)
1061    halt();
1062}
1063
1064// While a singleton would make more sense as a static variable, that would zero
1065// initialize all of its fields, hence the not too practical implementation.
1066struct Singleton {
1067  int i; // expected-note{{uninitialized field 'this->i'}}
1068  int dontGetFilteredByNonPedanticMode = 0;
1069
1070  Singleton() {
1071    assert(!isInstantiated);
1072    isInstantiated = true; // expected-warning{{1 uninitialized field}}
1073  }
1074
1075  ~Singleton() {
1076    isInstantiated = false;
1077  }
1078
1079  static bool isInstantiated;
1080};
1081
1082bool Singleton::isInstantiated = false;
1083
1084struct SingletonTest {
1085  int dontGetFilteredByNonPedanticMode = 0;
1086
1087  SingletonTest() {
1088    Singleton();
1089  }
1090};
1091
1092void fSingletonTest() {
1093  SingletonTest();
1094}
1095
1096//===----------------------------------------------------------------------===//
1097// C++11 member initializer tests.
1098//===----------------------------------------------------------------------===//
1099
1100struct CXX11MemberInitTest1 {
1101  int a = 3;
1102  int b;
1103  CXX11MemberInitTest1() : b(2) {
1104    // All good!
1105  }
1106};
1107
1108void fCXX11MemberInitTest1() {
1109  CXX11MemberInitTest1();
1110}
1111
1112struct CXX11MemberInitTest2 {
1113  struct RecordType {
1114    // TODO: we'd expect the note: {{uninitialized field 'this->rec.a'}}
1115    int a; // no-note
1116    // TODO: we'd expect the note: {{uninitialized field 'this->rec.b'}}
1117    int b; // no-note
1118
1119    RecordType(int) {}
1120  };
1121
1122  RecordType rec = RecordType(int());
1123  int dontGetFilteredByNonPedanticMode = 0;
1124
1125  CXX11MemberInitTest2() {}
1126};
1127
1128void fCXX11MemberInitTest2() {
1129  // TODO: we'd expect the warning: {{2 uninitializeds field}}
1130  CXX11MemberInitTest2(); // no-warning
1131}
1132