1 // 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 \
4 // RUN:   -std=c++11 -verify  %s
5 
6 // RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.cplusplus.UninitializedObject \
7 // RUN:   -analyzer-config optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
8 // RUN:   -std=c++11 -verify  %s
9 
10 //===----------------------------------------------------------------------===//
11 // Concrete location tests.
12 //===----------------------------------------------------------------------===//
13 
14 struct ConcreteIntLocTest {
15   int *ptr;
16 
ConcreteIntLocTestConcreteIntLocTest17   ConcreteIntLocTest() : ptr(reinterpret_cast<int *>(0xDEADBEEF)) {}
18 };
19 
fConcreteIntLocTest()20 void fConcreteIntLocTest() {
21   ConcreteIntLocTest();
22 }
23 
24 //===----------------------------------------------------------------------===//
25 // nonloc::LocAsInteger tests.
26 //===----------------------------------------------------------------------===//
27 
28 using intptr_t = unsigned long long;
29 
30 struct LocAsIntegerTest {
31   intptr_t ptr; // expected-note{{uninitialized pointee 'reinterpret_cast<char *>(this->ptr)'}}
32   int dontGetFilteredByNonPedanticMode = 0;
33 
LocAsIntegerTestLocAsIntegerTest34   LocAsIntegerTest(void *ptr) : ptr(reinterpret_cast<intptr_t>(ptr)) {} // expected-warning{{1 uninitialized field}}
35 };
36 
fLocAsIntegerTest()37 void fLocAsIntegerTest() {
38   char c;
39   LocAsIntegerTest t(&c);
40 }
41 
42 //===----------------------------------------------------------------------===//
43 // Null pointer tests.
44 //===----------------------------------------------------------------------===//
45 
46 class NullPtrTest {
47   struct RecordType {
48     int x;
49     int y;
50   };
51 
52   float *fptr = nullptr;
53   int *ptr;
54   RecordType *recPtr;
55 
56 public:
NullPtrTest()57   NullPtrTest() : ptr(nullptr), recPtr(nullptr) {
58     // All good!
59   }
60 };
61 
fNullPtrTest()62 void fNullPtrTest() {
63   NullPtrTest();
64 }
65 
66 //===----------------------------------------------------------------------===//
67 // Alloca tests.
68 //===----------------------------------------------------------------------===//
69 
70 struct UntypedAllocaTest {
71   void *allocaPtr;
72   int dontGetFilteredByNonPedanticMode = 0;
73 
UntypedAllocaTestUntypedAllocaTest74   UntypedAllocaTest() : allocaPtr(__builtin_alloca(sizeof(int))) {
75     // All good!
76   }
77 };
78 
fUntypedAllocaTest()79 void fUntypedAllocaTest() {
80   UntypedAllocaTest();
81 }
82 
83 struct TypedAllocaTest1 {
84   int *allocaPtr; // expected-note{{uninitialized pointee 'this->allocaPtr'}}
85   int dontGetFilteredByNonPedanticMode = 0;
86 
TypedAllocaTest1TypedAllocaTest187   TypedAllocaTest1() // expected-warning{{1 uninitialized field}}
88       : allocaPtr(static_cast<int *>(__builtin_alloca(sizeof(int)))) {}
89 };
90 
fTypedAllocaTest1()91 void fTypedAllocaTest1() {
92   TypedAllocaTest1();
93 }
94 
95 struct TypedAllocaTest2 {
96   int *allocaPtr;
97   int dontGetFilteredByNonPedanticMode = 0;
98 
TypedAllocaTest2TypedAllocaTest299   TypedAllocaTest2()
100       : allocaPtr(static_cast<int *>(__builtin_alloca(sizeof(int)))) {
101     *allocaPtr = 55555;
102     // All good!
103   }
104 };
105 
fTypedAllocaTest2()106 void fTypedAllocaTest2() {
107   TypedAllocaTest2();
108 }
109 
110 //===----------------------------------------------------------------------===//
111 // Heap pointer tests.
112 //===----------------------------------------------------------------------===//
113 
114 class HeapPointerTest1 {
115   struct RecordType {
116     // TODO: we'd expect the note: {{uninitialized field 'this->recPtr->y'}}
117     int x; // no-note
118     // TODO: we'd expect the note: {{uninitialized field 'this->recPtr->y'}}
119     int y; // no-note
120   };
121   // TODO: we'd expect the note: {{uninitialized pointee 'this->fptr'}}
122   float *fptr = new float; // no-note
123   // TODO: we'd expect the note: {{uninitialized pointee 'this->ptr'}}
124   int *ptr; // no-note
125   RecordType *recPtr;
126 
127 public:
128   // TODO: we'd expect the warning: {{4 uninitialized fields}}
HeapPointerTest1()129   HeapPointerTest1() : ptr(new int), recPtr(new RecordType) { // no-note
130   }
131 };
132 
fHeapPointerTest1()133 void fHeapPointerTest1() {
134   HeapPointerTest1();
135 }
136 
137 class HeapPointerTest2 {
138   struct RecordType {
139     int x;
140     int y;
141   };
142 
143   float *fptr = new float(); // initializes to 0
144   int *ptr;
145   RecordType *recPtr;
146 
147 public:
HeapPointerTest2()148   HeapPointerTest2() : ptr(new int{25}), recPtr(new RecordType{26, 27}) {
149     // All good!
150   }
151 };
152 
fHeapPointerTest2()153 void fHeapPointerTest2() {
154   HeapPointerTest2();
155 }
156 
157 //===----------------------------------------------------------------------===//
158 // Stack pointer tests.
159 //===----------------------------------------------------------------------===//
160 
161 class StackPointerTest1 {
162 public:
163   struct RecordType {
164     int x;
165     int y;
166   };
167 
168 private:
169   int *ptr;
170   RecordType *recPtr;
171 
172 public:
StackPointerTest1(int * _ptr,StackPointerTest1::RecordType * _recPtr)173   StackPointerTest1(int *_ptr, StackPointerTest1::RecordType *_recPtr) : ptr(_ptr), recPtr(_recPtr) {
174     // All good!
175   }
176 };
177 
fStackPointerTest1()178 void fStackPointerTest1() {
179   int ok_a = 28;
180   StackPointerTest1::RecordType ok_rec{29, 30};
181   StackPointerTest1(&ok_a, &ok_rec); // 'a', 'rec.x', 'rec.y' uninitialized
182 }
183 
184 #ifdef PEDANTIC
185 class StackPointerTest2 {
186 public:
187   struct RecordType {
188     int x; // expected-note{{uninitialized field 'this->recPtr->x'}}
189     int y; // expected-note{{uninitialized field 'this->recPtr->y'}}
190   };
191 
192 private:
193   int *ptr; // expected-note{{uninitialized pointee 'this->ptr'}}
194   RecordType *recPtr;
195 
196 public:
StackPointerTest2(int * _ptr,RecordType * _recPtr)197   StackPointerTest2(int *_ptr, RecordType *_recPtr) : ptr(_ptr), recPtr(_recPtr) { // expected-warning{{3 uninitialized fields}}
198   }
199 };
200 
fStackPointerTest2()201 void fStackPointerTest2() {
202   int a;
203   StackPointerTest2::RecordType rec;
204   StackPointerTest2(&a, &rec); // 'a', 'rec.x', 'rec.y' uninitialized
205 }
206 #else
207 class StackPointerTest2 {
208 public:
209   struct RecordType {
210     int x;
211     int y;
212   };
213 
214 private:
215   int *ptr;
216   RecordType *recPtr;
217 
218 public:
StackPointerTest2(int * _ptr,RecordType * _recPtr)219   StackPointerTest2(int *_ptr, RecordType *_recPtr) : ptr(_ptr), recPtr(_recPtr) {
220   }
221 };
222 
fStackPointerTest2()223 void fStackPointerTest2() {
224   int a;
225   StackPointerTest2::RecordType rec;
226   StackPointerTest2(&a, &rec); // 'a', 'rec.x', 'rec.y' uninitialized
227 }
228 #endif // PEDANTIC
229 
230 class UninitPointerTest {
231   struct RecordType {
232     int x;
233     int y;
234   };
235 
236   int *ptr; // expected-note{{uninitialized pointer 'this->ptr'}}
237   RecordType *recPtr;
238 
239 public:
UninitPointerTest()240   UninitPointerTest() : recPtr(new RecordType{13, 13}) { // expected-warning{{1 uninitialized field}}
241   }
242 };
243 
fUninitPointerTest()244 void fUninitPointerTest() {
245   UninitPointerTest();
246 }
247 
248 struct CharPointerTest {
249   const char *str;
250   int dontGetFilteredByNonPedanticMode = 0;
251 
CharPointerTestCharPointerTest252   CharPointerTest() : str("") {}
253 };
254 
fCharPointerTest()255 void fCharPointerTest() {
256   CharPointerTest();
257 }
258 
259 struct VectorSizePointer {
VectorSizePointerVectorSizePointer260   VectorSizePointer() {} // expected-warning{{1 uninitialized field}}
261   __attribute__((__vector_size__(8))) int *x; // expected-note{{uninitialized pointer 'this->x'}}
262   int dontGetFilteredByNonPedanticMode = 0;
263 };
264 
__vector_size__PointerTest()265 void __vector_size__PointerTest() {
266   VectorSizePointer v;
267 }
268 
269 struct VectorSizePointee {
270   using MyVectorType = __attribute__((__vector_size__(8))) int;
271   MyVectorType *x;
272 
VectorSizePointeeVectorSizePointee273   VectorSizePointee(decltype(x) x) : x(x) {}
274 };
275 
__vector_size__PointeeTest()276 void __vector_size__PointeeTest() {
277   VectorSizePointee::MyVectorType i;
278   // TODO: Report v.x's pointee.
279   VectorSizePointee v(&i);
280 }
281 
282 struct CyclicPointerTest1 {
283   int *ptr; // expected-note{{object references itself 'this->ptr'}}
284   int dontGetFilteredByNonPedanticMode = 0;
285 
CyclicPointerTest1CyclicPointerTest1286   CyclicPointerTest1() : ptr(reinterpret_cast<int *>(&ptr)) {} // expected-warning{{1 uninitialized field}}
287 };
288 
fCyclicPointerTest1()289 void fCyclicPointerTest1() {
290   CyclicPointerTest1();
291 }
292 
293 struct CyclicPointerTest2 {
294   int **pptr; // expected-note{{object references itself 'this->pptr'}}
295   int dontGetFilteredByNonPedanticMode = 0;
296 
CyclicPointerTest2CyclicPointerTest2297   CyclicPointerTest2() : pptr(reinterpret_cast<int **>(&pptr)) {} // expected-warning{{1 uninitialized field}}
298 };
299 
fCyclicPointerTest2()300 void fCyclicPointerTest2() {
301   CyclicPointerTest2();
302 }
303 
304 //===----------------------------------------------------------------------===//
305 // Void pointer tests.
306 //===----------------------------------------------------------------------===//
307 
308 // Void pointer tests are mainly no-crash tests.
309 
310 void *malloc(int size);
311 
312 class VoidPointerTest1 {
313   void *vptr;
314 
315 public:
VoidPointerTest1(void * vptr,char)316   VoidPointerTest1(void *vptr, char) : vptr(vptr) {
317     // All good!
318   }
319 };
320 
fVoidPointerTest1()321 void fVoidPointerTest1() {
322   void *vptr = malloc(sizeof(int));
323   VoidPointerTest1(vptr, char());
324 }
325 
326 class VoidPointerTest2 {
327   void **vpptr;
328 
329 public:
VoidPointerTest2(void ** vpptr,char)330   VoidPointerTest2(void **vpptr, char) : vpptr(vpptr) {
331     // All good!
332   }
333 };
334 
fVoidPointerTest2()335 void fVoidPointerTest2() {
336   void *vptr = malloc(sizeof(int));
337   VoidPointerTest2(&vptr, char());
338 }
339 
340 class VoidPointerRRefTest1 {
341   void *&&vptrrref; // expected-note {{here}}
342 
343 public:
VoidPointerRRefTest1(void * vptr,char)344   VoidPointerRRefTest1(void *vptr, char) : vptrrref(static_cast<void *&&>(vptr)) { // expected-warning {{binding reference member 'vptrrref' to stack allocated parameter 'vptr'}}
345     // All good!
346   }
347 };
348 
fVoidPointerRRefTest1()349 void fVoidPointerRRefTest1() {
350   void *vptr = malloc(sizeof(int));
351   VoidPointerRRefTest1(vptr, char());
352 }
353 
354 class VoidPointerRRefTest2 {
355   void **&&vpptrrref; // expected-note {{here}}
356 
357 public:
VoidPointerRRefTest2(void ** vptr,char)358   VoidPointerRRefTest2(void **vptr, char) : vpptrrref(static_cast<void **&&>(vptr)) { // expected-warning {{binding reference member 'vpptrrref' to stack allocated parameter 'vptr'}}
359     // All good!
360   }
361 };
362 
fVoidPointerRRefTest2()363 void fVoidPointerRRefTest2() {
364   void *vptr = malloc(sizeof(int));
365   VoidPointerRRefTest2(&vptr, char());
366 }
367 
368 class VoidPointerLRefTest {
369   void *&vptrrref; // expected-note {{here}}
370 
371 public:
VoidPointerLRefTest(void * vptr,char)372   VoidPointerLRefTest(void *vptr, char) : vptrrref(static_cast<void *&>(vptr)) { // expected-warning {{binding reference member 'vptrrref' to stack allocated parameter 'vptr'}}
373     // All good!
374   }
375 };
376 
fVoidPointerLRefTest()377 void fVoidPointerLRefTest() {
378   void *vptr = malloc(sizeof(int));
379   VoidPointerLRefTest(vptr, char());
380 }
381 
382 struct CyclicVoidPointerTest {
383   void *vptr; // expected-note{{object references itself 'this->vptr'}}
384   int dontGetFilteredByNonPedanticMode = 0;
385 
CyclicVoidPointerTestCyclicVoidPointerTest386   CyclicVoidPointerTest() : vptr(&vptr) {} // expected-warning{{1 uninitialized field}}
387 };
388 
fCyclicVoidPointerTest()389 void fCyclicVoidPointerTest() {
390   CyclicVoidPointerTest();
391 }
392 
393 struct IntDynTypedVoidPointerTest1 {
394   void *vptr; // expected-note{{uninitialized pointee 'static_cast<int *>(this->vptr)'}}
395   int dontGetFilteredByNonPedanticMode = 0;
396 
IntDynTypedVoidPointerTest1IntDynTypedVoidPointerTest1397   IntDynTypedVoidPointerTest1(void *vptr) : vptr(vptr) {} // expected-warning{{1 uninitialized field}}
398 };
399 
fIntDynTypedVoidPointerTest1()400 void fIntDynTypedVoidPointerTest1() {
401   int a;
402   IntDynTypedVoidPointerTest1 tmp(&a);
403 }
404 
405 struct RecordDynTypedVoidPointerTest {
406   struct RecordType {
407     int x; // expected-note{{uninitialized field 'static_cast<struct RecordDynTypedVoidPointerTest::RecordType *>(this->vptr)->x'}}
408     int y; // expected-note{{uninitialized field 'static_cast<struct RecordDynTypedVoidPointerTest::RecordType *>(this->vptr)->y'}}
409   };
410 
411   void *vptr;
412   int dontGetFilteredByNonPedanticMode = 0;
413 
RecordDynTypedVoidPointerTestRecordDynTypedVoidPointerTest414   RecordDynTypedVoidPointerTest(void *vptr) : vptr(vptr) {} // expected-warning{{2 uninitialized fields}}
415 };
416 
fRecordDynTypedVoidPointerTest()417 void fRecordDynTypedVoidPointerTest() {
418   RecordDynTypedVoidPointerTest::RecordType a;
419   RecordDynTypedVoidPointerTest tmp(&a);
420 }
421 
422 struct NestedNonVoidDynTypedVoidPointerTest {
423   struct RecordType {
424     int x;      // expected-note{{uninitialized field 'static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->x'}}
425     int y;      // expected-note{{uninitialized field 'static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->y'}}
426     void *vptr; // expected-note{{uninitialized pointee 'static_cast<char *>(static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->vptr)'}}
427   };
428 
429   void *vptr;
430   int dontGetFilteredByNonPedanticMode = 0;
431 
NestedNonVoidDynTypedVoidPointerTestNestedNonVoidDynTypedVoidPointerTest432   NestedNonVoidDynTypedVoidPointerTest(void *vptr, void *c) : vptr(vptr) {
433     static_cast<RecordType *>(vptr)->vptr = c; // expected-warning{{3 uninitialized fields}}
434   }
435 };
436 
fNestedNonVoidDynTypedVoidPointerTest()437 void fNestedNonVoidDynTypedVoidPointerTest() {
438   NestedNonVoidDynTypedVoidPointerTest::RecordType a;
439   char c;
440   NestedNonVoidDynTypedVoidPointerTest tmp(&a, &c);
441 }
442 
443 //===----------------------------------------------------------------------===//
444 // Multipointer tests.
445 //===----------------------------------------------------------------------===//
446 
447 #ifdef PEDANTIC
448 class MultiPointerTest1 {
449 public:
450   struct RecordType {
451     int x;
452     int y;
453   };
454 
455 private:
456   RecordType **mptr; // expected-note{{uninitialized pointee 'this->mptr'}}
457 
458 public:
MultiPointerTest1(RecordType ** p,int)459   MultiPointerTest1(RecordType **p, int) : mptr(p) { // expected-warning{{1 uninitialized field}}
460   }
461 };
462 
fMultiPointerTest1()463 void fMultiPointerTest1() {
464   MultiPointerTest1::RecordType *p1;
465   MultiPointerTest1::RecordType **mptr = &p1;
466   MultiPointerTest1(mptr, int()); // '*mptr' uninitialized
467 }
468 #else
469 class MultiPointerTest1 {
470 public:
471   struct RecordType {
472     int x;
473     int y;
474   };
475 
476 private:
477   RecordType **mptr;
478 
479 public:
MultiPointerTest1(RecordType ** p,int)480   MultiPointerTest1(RecordType **p, int) : mptr(p) {}
481 };
482 
fMultiPointerTest1()483 void fMultiPointerTest1() {
484   MultiPointerTest1::RecordType *p1;
485   MultiPointerTest1::RecordType **mptr = &p1;
486   MultiPointerTest1(mptr, int()); // '*mptr' uninitialized
487 }
488 #endif // PEDANTIC
489 
490 #ifdef PEDANTIC
491 class MultiPointerTest2 {
492 public:
493   struct RecordType {
494     int x; // expected-note{{uninitialized field 'this->mptr->x'}}
495     int y; // expected-note{{uninitialized field 'this->mptr->y'}}
496   };
497 
498 private:
499   RecordType **mptr;
500 
501 public:
MultiPointerTest2(RecordType ** p,int)502   MultiPointerTest2(RecordType **p, int) : mptr(p) { // expected-warning{{2 uninitialized fields}}
503   }
504 };
505 
fMultiPointerTest2()506 void fMultiPointerTest2() {
507   MultiPointerTest2::RecordType i;
508   MultiPointerTest2::RecordType *p1 = &i;
509   MultiPointerTest2::RecordType **mptr = &p1;
510   MultiPointerTest2(mptr, int()); // '**mptr' uninitialized
511 }
512 #else
513 class MultiPointerTest2 {
514 public:
515   struct RecordType {
516     int x;
517     int y;
518   };
519 
520 private:
521   RecordType **mptr;
522 
523 public:
MultiPointerTest2(RecordType ** p,int)524   MultiPointerTest2(RecordType **p, int) : mptr(p) {
525   }
526 };
527 
fMultiPointerTest2()528 void fMultiPointerTest2() {
529   MultiPointerTest2::RecordType i;
530   MultiPointerTest2::RecordType *p1 = &i;
531   MultiPointerTest2::RecordType **mptr = &p1;
532   MultiPointerTest2(mptr, int()); // '**mptr' uninitialized
533 }
534 #endif // PEDANTIC
535 
536 class MultiPointerTest3 {
537 public:
538   struct RecordType {
539     int x;
540     int y;
541   };
542 
543 private:
544   RecordType **mptr;
545 
546 public:
MultiPointerTest3(RecordType ** p,int)547   MultiPointerTest3(RecordType **p, int) : mptr(p) {
548     // All good!
549   }
550 };
551 
fMultiPointerTest3()552 void fMultiPointerTest3() {
553   MultiPointerTest3::RecordType i{31, 32};
554   MultiPointerTest3::RecordType *p1 = &i;
555   MultiPointerTest3::RecordType **mptr = &p1;
556   MultiPointerTest3(mptr, int()); // '**mptr' uninitialized
557 }
558 
559 //===----------------------------------------------------------------------===//
560 // Incomplete pointee tests.
561 //===----------------------------------------------------------------------===//
562 
563 class IncompleteType;
564 
565 struct IncompletePointeeTypeTest {
566   IncompleteType *pImpl; //no-crash
567   int dontGetFilteredByNonPedanticMode = 0;
568 
IncompletePointeeTypeTestIncompletePointeeTypeTest569   IncompletePointeeTypeTest(IncompleteType *A) : pImpl(A) {}
570 };
571 
fIncompletePointeeTypeTest(void * ptr)572 void fIncompletePointeeTypeTest(void *ptr) {
573   IncompletePointeeTypeTest(reinterpret_cast<IncompleteType *>(ptr));
574 }
575 
576 //===----------------------------------------------------------------------===//
577 // Function pointer tests.
578 //===----------------------------------------------------------------------===//
579 
580 struct FunctionPointerWithDifferentDynTypeTest {
581   using Func1 = void *(*)();
582   using Func2 = int *(*)();
583 
584   Func1 f; // no-crash
FunctionPointerWithDifferentDynTypeTestFunctionPointerWithDifferentDynTypeTest585   FunctionPointerWithDifferentDynTypeTest(Func2 f) : f((Func1)f) {}
586 };
587 
588 // Note that there isn't a function calling the constructor of
589 // FunctionPointerWithDifferentDynTypeTest, because a crash could only be
590 // reproduced without it.
591 
592 //===----------------------------------------------------------------------===//
593 // Member pointer tests.
594 //===----------------------------------------------------------------------===//
595 
596 struct UsefulFunctions {
597   int a, b;
598 
printUsefulFunctions599   void print() {}
dumpUsefulFunctions600   void dump() {}
601 };
602 
603 #ifdef PEDANTIC
604 struct PointerToMemberFunctionTest1 {
605   void (UsefulFunctions::*f)(void); // expected-note{{uninitialized field 'this->f'}}
PointerToMemberFunctionTest1PointerToMemberFunctionTest1606   PointerToMemberFunctionTest1() {}
607 };
608 
fPointerToMemberFunctionTest1()609 void fPointerToMemberFunctionTest1() {
610   PointerToMemberFunctionTest1(); // expected-warning{{1 uninitialized field}}
611 }
612 
613 struct PointerToMemberFunctionTest2 {
614   void (UsefulFunctions::*f)(void);
PointerToMemberFunctionTest2PointerToMemberFunctionTest2615   PointerToMemberFunctionTest2(void (UsefulFunctions::*f)(void)) : f(f) {
616     // All good!
617   }
618 };
619 
fPointerToMemberFunctionTest2()620 void fPointerToMemberFunctionTest2() {
621   void (UsefulFunctions::*f)(void) = &UsefulFunctions::print;
622   PointerToMemberFunctionTest2 a(f);
623 }
624 
625 struct MultiPointerToMemberFunctionTest1 {
626   void (UsefulFunctions::**f)(void); // expected-note{{uninitialized pointer 'this->f'}}
MultiPointerToMemberFunctionTest1MultiPointerToMemberFunctionTest1627   MultiPointerToMemberFunctionTest1() {}
628 };
629 
fMultiPointerToMemberFunctionTest1()630 void fMultiPointerToMemberFunctionTest1() {
631   MultiPointerToMemberFunctionTest1(); // expected-warning{{1 uninitialized field}}
632 }
633 
634 struct MultiPointerToMemberFunctionTest2 {
635   void (UsefulFunctions::**f)(void);
MultiPointerToMemberFunctionTest2MultiPointerToMemberFunctionTest2636   MultiPointerToMemberFunctionTest2(void (UsefulFunctions::**f)(void)) : f(f) {
637     // All good!
638   }
639 };
640 
fMultiPointerToMemberFunctionTest2()641 void fMultiPointerToMemberFunctionTest2() {
642   void (UsefulFunctions::*f)(void) = &UsefulFunctions::print;
643   MultiPointerToMemberFunctionTest2 a(&f);
644 }
645 
646 struct PointerToMemberDataTest1 {
647   int UsefulFunctions::*d; // expected-note{{uninitialized field 'this->d'}}
PointerToMemberDataTest1PointerToMemberDataTest1648   PointerToMemberDataTest1() {}
649 };
650 
fPointerToMemberDataTest1()651 void fPointerToMemberDataTest1() {
652   PointerToMemberDataTest1(); // expected-warning{{1 uninitialized field}}
653 }
654 
655 struct PointerToMemberDataTest2 {
656   int UsefulFunctions::*d;
PointerToMemberDataTest2PointerToMemberDataTest2657   PointerToMemberDataTest2(int UsefulFunctions::*d) : d(d) {
658     // All good!
659   }
660 };
661 
fPointerToMemberDataTest2()662 void fPointerToMemberDataTest2() {
663   int UsefulFunctions::*d = &UsefulFunctions::a;
664   PointerToMemberDataTest2 a(d);
665 }
666 
667 struct MultiPointerToMemberDataTest1 {
668   int UsefulFunctions::**d; // expected-note{{uninitialized pointer 'this->d'}}
MultiPointerToMemberDataTest1MultiPointerToMemberDataTest1669   MultiPointerToMemberDataTest1() {}
670 };
671 
fMultiPointerToMemberDataTest1()672 void fMultiPointerToMemberDataTest1() {
673   MultiPointerToMemberDataTest1(); // expected-warning{{1 uninitialized field}}
674 }
675 
676 struct MultiPointerToMemberDataTest2 {
677   int UsefulFunctions::**d;
MultiPointerToMemberDataTest2MultiPointerToMemberDataTest2678   MultiPointerToMemberDataTest2(int UsefulFunctions::**d) : d(d) {
679     // All good!
680   }
681 };
682 
fMultiPointerToMemberDataTest2()683 void fMultiPointerToMemberDataTest2() {
684   int UsefulFunctions::*d = &UsefulFunctions::a;
685   MultiPointerToMemberDataTest2 a(&d);
686 }
687 #endif // PEDANTIC
688 
689 //===----------------------------------------------------------------------===//
690 // Tests for list-like records.
691 //===----------------------------------------------------------------------===//
692 
693 class ListTest1 {
694 public:
695   struct Node {
696     Node *next = nullptr; // no crash
697     int i;
698   };
699 
700 private:
701   Node *head = nullptr;
702 
703 public:
ListTest1()704   ListTest1() {
705     // All good!
706   }
707 };
708 
fListTest1()709 void fListTest1() {
710   ListTest1();
711 }
712 
713 class ListTest2 {
714 public:
715   struct Node {
716     Node *next = nullptr;
717     int i; // expected-note{{uninitialized field 'this->head->i'}}
718   };
719 
720 private:
721   Node *head = nullptr;
722 
723 public:
ListTest2(Node * node,int)724   ListTest2(Node *node, int) : head(node) { // expected-warning{{1 uninitialized field}}
725   }
726 };
727 
fListTest2()728 void fListTest2() {
729   ListTest2::Node n;
730   ListTest2(&n, int());
731 }
732 
733 class CyclicList {
734 public:
735   struct Node {
736     Node *next = nullptr;
737     int i; // expected-note{{uninitialized field 'this->head->i'}}
738   };
739 
740 private:
741   Node *head = nullptr;
742 
743 public:
CyclicList(Node * node,int)744   CyclicList(Node *node, int) : head(node) { // expected-warning{{1 uninitialized field}}
745   }
746 };
747 
fCyclicList()748 void fCyclicList() {
749   /*
750                n3
751               /  \
752     this -- n1 -- n2
753   */
754 
755   CyclicList::Node n1;
756   CyclicList::Node n2;
757   n2.next = &n1;
758   n2.i = 50;
759   CyclicList::Node n3;
760   n3.next = &n2;
761   n3.i = 50;
762   n1.next = &n3;
763   // note that n1.i is uninitialized
764   CyclicList(&n1, int());
765 }
766 
767 struct RingListTest {
768   RingListTest *next; // no-crash
RingListTestRingListTest769   RingListTest() : next(this) {}
770 };
771 
fRingListTest()772 void fRingListTest() {
773   RingListTest();
774 }
775 
776 //===----------------------------------------------------------------------===//
777 // Tests for classes containing references.
778 //===----------------------------------------------------------------------===//
779 
780 class ReferenceTest1 {
781 public:
782   struct RecordType {
783     int x;
784     int y;
785   };
786 
787 private:
788   RecordType &lref;
789   RecordType &&rref;
790 
791 public:
ReferenceTest1(RecordType & lref,RecordType & rref)792   ReferenceTest1(RecordType &lref, RecordType &rref) : lref(lref), rref(static_cast<RecordType &&>(rref)) {
793     // All good!
794   }
795 };
796 
fReferenceTest1()797 void fReferenceTest1() {
798   ReferenceTest1::RecordType d{33, 34};
799   ReferenceTest1(d, d);
800 }
801 
802 #ifdef PEDANTIC
803 class ReferenceTest2 {
804 public:
805   struct RecordType {
806     int x; // expected-note{{uninitialized field 'this->lref.x'}}
807     int y; // expected-note{{uninitialized field 'this->lref.y'}}
808   };
809 
810 private:
811   RecordType &lref;
812   RecordType &&rref;
813 
814 public:
ReferenceTest2(RecordType & lref,RecordType & rref)815   ReferenceTest2(RecordType &lref, RecordType &rref)
816       : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}}
817   }
818 };
819 
fReferenceTest2()820 void fReferenceTest2() {
821   ReferenceTest2::RecordType c;
822   ReferenceTest2(c, c);
823 }
824 #else
825 class ReferenceTest2 {
826 public:
827   struct RecordType {
828     int x;
829     int y;
830   };
831 
832 private:
833   RecordType &lref;
834   RecordType &&rref;
835 
836 public:
ReferenceTest2(RecordType & lref,RecordType & rref)837   ReferenceTest2(RecordType &lref, RecordType &rref)
838       : lref(lref), rref(static_cast<RecordType &&>(rref)) {
839   }
840 };
841 
fReferenceTest2()842 void fReferenceTest2() {
843   ReferenceTest2::RecordType c;
844   ReferenceTest2(c, c);
845 }
846 #endif // PEDANTIC
847 
848 class ReferenceTest3 {
849 public:
850   struct RecordType {
851     int x; // expected-note{{uninitialized field 'this->lref.x'}}
852     int y; // expected-note{{uninitialized field 'this->lref.y'}}
853   };
854 
855 private:
856   RecordType &lref;
857   RecordType &&rref;
858 
859 public:
ReferenceTest3(RecordType & lref,RecordType & rref)860   ReferenceTest3(RecordType &lref, RecordType &rref)
861       : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}}
862   }
863 };
864 
fReferenceTest3()865 void fReferenceTest3() {
866   ReferenceTest3::RecordType c, d{35, 36};
867   ReferenceTest3(c, d);
868 }
869 
870 class ReferenceTest4 {
871 public:
872   struct RecordType {
873     int x; // expected-note{{uninitialized field 'this->rref.x'}}
874     int y; // expected-note{{uninitialized field 'this->rref.y'}}
875   };
876 
877 private:
878   RecordType &lref;
879   RecordType &&rref;
880 
881 public:
ReferenceTest4(RecordType & lref,RecordType & rref)882   ReferenceTest4(RecordType &lref, RecordType &rref)
883       : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}}
884   }
885 };
886 
fReferenceTest5()887 void fReferenceTest5() {
888   ReferenceTest4::RecordType c, d{37, 38};
889   ReferenceTest4(d, c);
890 }
891 
892 //===----------------------------------------------------------------------===//
893 // Tests for objects containing multiple references to the same object.
894 //===----------------------------------------------------------------------===//
895 
896 struct IntMultipleReferenceToSameObjectTest {
897   int *iptr; // expected-note{{uninitialized pointee 'this->iptr'}}
898   int &iref; // no-note, pointee of this->iref was already reported
899 
900   int dontGetFilteredByNonPedanticMode = 0;
901 
IntMultipleReferenceToSameObjectTestIntMultipleReferenceToSameObjectTest902   IntMultipleReferenceToSameObjectTest(int *i) : iptr(i), iref(*i) {} // expected-warning{{1 uninitialized field}}
903 };
904 
fIntMultipleReferenceToSameObjectTest()905 void fIntMultipleReferenceToSameObjectTest() {
906   int a;
907   IntMultipleReferenceToSameObjectTest Test(&a);
908 }
909 
910 struct IntReferenceWrapper1 {
911   int &a; // expected-note{{uninitialized pointee 'this->a'}}
912 
913   int dontGetFilteredByNonPedanticMode = 0;
914 
IntReferenceWrapper1IntReferenceWrapper1915   IntReferenceWrapper1(int &a) : a(a) {} // expected-warning{{1 uninitialized field}}
916 };
917 
918 struct IntReferenceWrapper2 {
919   int &a; // no-note, pointee of this->a was already reported
920 
921   int dontGetFilteredByNonPedanticMode = 0;
922 
IntReferenceWrapper2IntReferenceWrapper2923   IntReferenceWrapper2(int &a) : a(a) {} // no-warning
924 };
925 
fMultipleObjectsReferencingTheSameObjectTest()926 void fMultipleObjectsReferencingTheSameObjectTest() {
927   int a;
928 
929   IntReferenceWrapper1 T1(a);
930   IntReferenceWrapper2 T2(a);
931 }
932