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