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