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