1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,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,unix.Malloc,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 typedef __typeof(sizeof(int)) size_t;
320
321 void *calloc(size_t nmemb, size_t size);
322 void free(void *p);
323
324 class VoidPointerTest1 {
325 void *vptr;
326
327 public:
VoidPointerTest1(void * vptr,char)328 VoidPointerTest1(void *vptr, char) : vptr(vptr) {
329 // All good!
330 }
331 };
332
fVoidPointerTest1()333 void fVoidPointerTest1() {
334 void *vptr = calloc(1, sizeof(int));
335 VoidPointerTest1(vptr, char());
336 free(vptr);
337 }
338
339 class VoidPointerTest2 {
340 void **vpptr;
341
342 public:
VoidPointerTest2(void ** vpptr,char)343 VoidPointerTest2(void **vpptr, char) : vpptr(vpptr) {
344 // All good!
345 }
346 };
347
fVoidPointerTest2()348 void fVoidPointerTest2() {
349 void *vptr = calloc(1, sizeof(int));
350 VoidPointerTest2(&vptr, char());
351 free(vptr);
352 }
353
354 class VoidPointerRRefTest1 {
355 void *&&vptrrref; // expected-note {{here}}
356
357 public:
358 // expected-warning@+3 {{Address of stack memory associated with local \
359 variable 'vptr' is still referred to by a temporary object on the stack \
360 upon returning to the caller. This will be a dangling reference}}
VoidPointerRRefTest1(void * vptr,char)361 VoidPointerRRefTest1(void *vptr, char) : vptrrref(static_cast<void *&&>(vptr)) { // expected-warning {{binding reference member 'vptrrref' to stack allocated parameter 'vptr'}}
362 // All good!
363 }
364 };
365
fVoidPointerRRefTest1()366 void fVoidPointerRRefTest1() {
367 void *vptr = calloc(1, sizeof(int));
368 VoidPointerRRefTest1(vptr, char());
369 free(vptr);
370 }
371
372 class VoidPointerRRefTest2 {
373 void **&&vpptrrref; // expected-note {{here}}
374
375 public:
376 // expected-warning@+3 {{Address of stack memory associated with local \
377 variable 'vptr' is still referred to by a temporary object on the stack \
378 upon returning to the caller. This will be a dangling reference}}
VoidPointerRRefTest2(void ** vptr,char)379 VoidPointerRRefTest2(void **vptr, char) : vpptrrref(static_cast<void **&&>(vptr)) { // expected-warning {{binding reference member 'vpptrrref' to stack allocated parameter 'vptr'}}
380 // All good!
381 }
382 };
383
fVoidPointerRRefTest2()384 void fVoidPointerRRefTest2() {
385 void *vptr = calloc(1, sizeof(int));
386 VoidPointerRRefTest2(&vptr, char());
387 free(vptr);
388 }
389
390 class VoidPointerLRefTest {
391 void *&vptrrref; // expected-note {{here}}
392
393 public:
394 // expected-warning@+3 {{Address of stack memory associated with local \
395 variable 'vptr' is still referred to by a temporary object on the stack \
396 upon returning to the caller. This will be a dangling reference}}
VoidPointerLRefTest(void * vptr,char)397 VoidPointerLRefTest(void *vptr, char) : vptrrref(static_cast<void *&>(vptr)) { // expected-warning {{binding reference member 'vptrrref' to stack allocated parameter 'vptr'}}
398 // All good!
399 }
400 };
401
fVoidPointerLRefTest()402 void fVoidPointerLRefTest() {
403 void *vptr = calloc(1, sizeof(int));
404 VoidPointerLRefTest(vptr, char());
405 free(vptr);
406 }
407
408 struct CyclicVoidPointerTest {
409 void *vptr; // expected-note{{object references itself 'this->vptr'}}
410 int dontGetFilteredByNonPedanticMode = 0;
411
CyclicVoidPointerTestCyclicVoidPointerTest412 CyclicVoidPointerTest() : vptr(&vptr) {} // expected-warning{{1 uninitialized field}}
413 };
414
fCyclicVoidPointerTest()415 void fCyclicVoidPointerTest() {
416 CyclicVoidPointerTest();
417 }
418
419 struct IntDynTypedVoidPointerTest1 {
420 void *vptr; // expected-note{{uninitialized pointee 'static_cast<int *>(this->vptr)'}}
421 int dontGetFilteredByNonPedanticMode = 0;
422
IntDynTypedVoidPointerTest1IntDynTypedVoidPointerTest1423 IntDynTypedVoidPointerTest1(void *vptr) : vptr(vptr) {} // expected-warning{{1 uninitialized field}}
424 };
425
fIntDynTypedVoidPointerTest1()426 void fIntDynTypedVoidPointerTest1() {
427 int a;
428 IntDynTypedVoidPointerTest1 tmp(&a);
429 }
430
431 struct RecordDynTypedVoidPointerTest {
432 struct RecordType {
433 int x; // expected-note{{uninitialized field 'static_cast<struct RecordDynTypedVoidPointerTest::RecordType *>(this->vptr)->x'}}
434 int y; // expected-note{{uninitialized field 'static_cast<struct RecordDynTypedVoidPointerTest::RecordType *>(this->vptr)->y'}}
435 };
436
437 void *vptr;
438 int dontGetFilteredByNonPedanticMode = 0;
439
RecordDynTypedVoidPointerTestRecordDynTypedVoidPointerTest440 RecordDynTypedVoidPointerTest(void *vptr) : vptr(vptr) {} // expected-warning{{2 uninitialized fields}}
441 };
442
fRecordDynTypedVoidPointerTest()443 void fRecordDynTypedVoidPointerTest() {
444 RecordDynTypedVoidPointerTest::RecordType a;
445 RecordDynTypedVoidPointerTest tmp(&a);
446 }
447
448 struct NestedNonVoidDynTypedVoidPointerTest {
449 struct RecordType {
450 int x; // expected-note{{uninitialized field 'static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->x'}}
451 int y; // expected-note{{uninitialized field 'static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->y'}}
452 void *vptr; // expected-note{{uninitialized pointee 'static_cast<char *>(static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->vptr)'}}
453 };
454
455 void *vptr;
456 int dontGetFilteredByNonPedanticMode = 0;
457
NestedNonVoidDynTypedVoidPointerTestNestedNonVoidDynTypedVoidPointerTest458 NestedNonVoidDynTypedVoidPointerTest(void *vptr, void *c) : vptr(vptr) {
459 static_cast<RecordType *>(vptr)->vptr = c; // expected-warning{{3 uninitialized fields}}
460 }
461 };
462
fNestedNonVoidDynTypedVoidPointerTest()463 void fNestedNonVoidDynTypedVoidPointerTest() {
464 NestedNonVoidDynTypedVoidPointerTest::RecordType a;
465 char c;
466 NestedNonVoidDynTypedVoidPointerTest tmp(&a, &c);
467 }
468
469 //===----------------------------------------------------------------------===//
470 // Multipointer tests.
471 //===----------------------------------------------------------------------===//
472
473 #ifdef PEDANTIC
474 class MultiPointerTest1 {
475 public:
476 struct RecordType {
477 int x;
478 int y;
479 };
480
481 private:
482 RecordType **mptr; // expected-note{{uninitialized pointee 'this->mptr'}}
483
484 public:
MultiPointerTest1(RecordType ** p,int)485 MultiPointerTest1(RecordType **p, int) : mptr(p) { // expected-warning{{1 uninitialized field}}
486 }
487 };
488
fMultiPointerTest1()489 void fMultiPointerTest1() {
490 MultiPointerTest1::RecordType *p1;
491 MultiPointerTest1::RecordType **mptr = &p1;
492 MultiPointerTest1(mptr, int()); // '*mptr' uninitialized
493 }
494 #else
495 class MultiPointerTest1 {
496 public:
497 struct RecordType {
498 int x;
499 int y;
500 };
501
502 private:
503 RecordType **mptr;
504
505 public:
MultiPointerTest1(RecordType ** p,int)506 MultiPointerTest1(RecordType **p, int) : mptr(p) {}
507 };
508
fMultiPointerTest1()509 void fMultiPointerTest1() {
510 MultiPointerTest1::RecordType *p1;
511 MultiPointerTest1::RecordType **mptr = &p1;
512 MultiPointerTest1(mptr, int()); // '*mptr' uninitialized
513 }
514 #endif // PEDANTIC
515
516 #ifdef PEDANTIC
517 class MultiPointerTest2 {
518 public:
519 struct RecordType {
520 int x; // expected-note{{uninitialized field 'this->mptr->x'}}
521 int y; // expected-note{{uninitialized field 'this->mptr->y'}}
522 };
523
524 private:
525 RecordType **mptr;
526
527 public:
MultiPointerTest2(RecordType ** p,int)528 MultiPointerTest2(RecordType **p, int) : mptr(p) { // expected-warning{{2 uninitialized fields}}
529 }
530 };
531
fMultiPointerTest2()532 void fMultiPointerTest2() {
533 MultiPointerTest2::RecordType i;
534 MultiPointerTest2::RecordType *p1 = &i;
535 MultiPointerTest2::RecordType **mptr = &p1;
536 MultiPointerTest2(mptr, int()); // '**mptr' uninitialized
537 }
538 #else
539 class MultiPointerTest2 {
540 public:
541 struct RecordType {
542 int x;
543 int y;
544 };
545
546 private:
547 RecordType **mptr;
548
549 public:
MultiPointerTest2(RecordType ** p,int)550 MultiPointerTest2(RecordType **p, int) : mptr(p) {
551 }
552 };
553
fMultiPointerTest2()554 void fMultiPointerTest2() {
555 MultiPointerTest2::RecordType i;
556 MultiPointerTest2::RecordType *p1 = &i;
557 MultiPointerTest2::RecordType **mptr = &p1;
558 MultiPointerTest2(mptr, int()); // '**mptr' uninitialized
559 }
560 #endif // PEDANTIC
561
562 class MultiPointerTest3 {
563 public:
564 struct RecordType {
565 int x;
566 int y;
567 };
568
569 private:
570 RecordType **mptr;
571
572 public:
MultiPointerTest3(RecordType ** p,int)573 MultiPointerTest3(RecordType **p, int) : mptr(p) {
574 // All good!
575 }
576 };
577
fMultiPointerTest3()578 void fMultiPointerTest3() {
579 MultiPointerTest3::RecordType i{31, 32};
580 MultiPointerTest3::RecordType *p1 = &i;
581 MultiPointerTest3::RecordType **mptr = &p1;
582 MultiPointerTest3(mptr, int()); // '**mptr' uninitialized
583 }
584
585 //===----------------------------------------------------------------------===//
586 // Incomplete pointee tests.
587 //===----------------------------------------------------------------------===//
588
589 class IncompleteType;
590
591 struct IncompletePointeeTypeTest {
592 IncompleteType *pImpl; //no-crash
593 int dontGetFilteredByNonPedanticMode = 0;
594
IncompletePointeeTypeTestIncompletePointeeTypeTest595 IncompletePointeeTypeTest(IncompleteType *A) : pImpl(A) {}
596 };
597
fIncompletePointeeTypeTest(void * ptr)598 void fIncompletePointeeTypeTest(void *ptr) {
599 IncompletePointeeTypeTest(reinterpret_cast<IncompleteType *>(ptr));
600 }
601
602 //===----------------------------------------------------------------------===//
603 // Function pointer tests.
604 //===----------------------------------------------------------------------===//
605
606 struct FunctionPointerWithDifferentDynTypeTest {
607 using Func1 = void *(*)();
608 using Func2 = int *(*)();
609
610 Func1 f; // no-crash
FunctionPointerWithDifferentDynTypeTestFunctionPointerWithDifferentDynTypeTest611 FunctionPointerWithDifferentDynTypeTest(Func2 f) : f((Func1)f) {}
612 };
613
614 // Note that there isn't a function calling the constructor of
615 // FunctionPointerWithDifferentDynTypeTest, because a crash could only be
616 // reproduced without it.
617
618 //===----------------------------------------------------------------------===//
619 // Member pointer tests.
620 //===----------------------------------------------------------------------===//
621
622 struct UsefulFunctions {
623 int a, b;
624
printUsefulFunctions625 void print() {}
dumpUsefulFunctions626 void dump() {}
627 };
628
629 #ifdef PEDANTIC
630 struct PointerToMemberFunctionTest1 {
631 void (UsefulFunctions::*f)(void); // expected-note{{uninitialized field 'this->f'}}
PointerToMemberFunctionTest1PointerToMemberFunctionTest1632 PointerToMemberFunctionTest1() {}
633 };
634
fPointerToMemberFunctionTest1()635 void fPointerToMemberFunctionTest1() {
636 PointerToMemberFunctionTest1(); // expected-warning{{1 uninitialized field}}
637 }
638
639 struct PointerToMemberFunctionTest2 {
640 void (UsefulFunctions::*f)(void);
PointerToMemberFunctionTest2PointerToMemberFunctionTest2641 PointerToMemberFunctionTest2(void (UsefulFunctions::*f)(void)) : f(f) {
642 // All good!
643 }
644 };
645
fPointerToMemberFunctionTest2()646 void fPointerToMemberFunctionTest2() {
647 void (UsefulFunctions::*f)(void) = &UsefulFunctions::print;
648 PointerToMemberFunctionTest2 a(f);
649 }
650
651 struct MultiPointerToMemberFunctionTest1 {
652 void (UsefulFunctions::**f)(void); // expected-note{{uninitialized pointer 'this->f'}}
MultiPointerToMemberFunctionTest1MultiPointerToMemberFunctionTest1653 MultiPointerToMemberFunctionTest1() {}
654 };
655
fMultiPointerToMemberFunctionTest1()656 void fMultiPointerToMemberFunctionTest1() {
657 MultiPointerToMemberFunctionTest1(); // expected-warning{{1 uninitialized field}}
658 }
659
660 struct MultiPointerToMemberFunctionTest2 {
661 void (UsefulFunctions::**f)(void);
MultiPointerToMemberFunctionTest2MultiPointerToMemberFunctionTest2662 MultiPointerToMemberFunctionTest2(void (UsefulFunctions::**f)(void)) : f(f) {
663 // All good!
664 }
665 };
666
fMultiPointerToMemberFunctionTest2()667 void fMultiPointerToMemberFunctionTest2() {
668 void (UsefulFunctions::*f)(void) = &UsefulFunctions::print;
669 MultiPointerToMemberFunctionTest2 a(&f);
670 }
671
672 struct PointerToMemberDataTest1 {
673 int UsefulFunctions::*d; // expected-note{{uninitialized field 'this->d'}}
PointerToMemberDataTest1PointerToMemberDataTest1674 PointerToMemberDataTest1() {}
675 };
676
fPointerToMemberDataTest1()677 void fPointerToMemberDataTest1() {
678 PointerToMemberDataTest1(); // expected-warning{{1 uninitialized field}}
679 }
680
681 struct PointerToMemberDataTest2 {
682 int UsefulFunctions::*d;
PointerToMemberDataTest2PointerToMemberDataTest2683 PointerToMemberDataTest2(int UsefulFunctions::*d) : d(d) {
684 // All good!
685 }
686 };
687
fPointerToMemberDataTest2()688 void fPointerToMemberDataTest2() {
689 int UsefulFunctions::*d = &UsefulFunctions::a;
690 PointerToMemberDataTest2 a(d);
691 }
692
693 struct MultiPointerToMemberDataTest1 {
694 int UsefulFunctions::**d; // expected-note{{uninitialized pointer 'this->d'}}
MultiPointerToMemberDataTest1MultiPointerToMemberDataTest1695 MultiPointerToMemberDataTest1() {}
696 };
697
fMultiPointerToMemberDataTest1()698 void fMultiPointerToMemberDataTest1() {
699 MultiPointerToMemberDataTest1(); // expected-warning{{1 uninitialized field}}
700 }
701
702 struct MultiPointerToMemberDataTest2 {
703 int UsefulFunctions::**d;
MultiPointerToMemberDataTest2MultiPointerToMemberDataTest2704 MultiPointerToMemberDataTest2(int UsefulFunctions::**d) : d(d) {
705 // All good!
706 }
707 };
708
fMultiPointerToMemberDataTest2()709 void fMultiPointerToMemberDataTest2() {
710 int UsefulFunctions::*d = &UsefulFunctions::a;
711 MultiPointerToMemberDataTest2 a(&d);
712 }
713 #endif // PEDANTIC
714
715 //===----------------------------------------------------------------------===//
716 // Tests for list-like records.
717 //===----------------------------------------------------------------------===//
718
719 class ListTest1 {
720 public:
721 struct Node {
722 Node *next = nullptr; // no crash
723 int i;
724 };
725
726 private:
727 Node *head = nullptr;
728
729 public:
ListTest1()730 ListTest1() {
731 // All good!
732 }
733 };
734
fListTest1()735 void fListTest1() {
736 ListTest1();
737 }
738
739 class ListTest2 {
740 public:
741 struct Node {
742 Node *next = nullptr;
743 int i; // expected-note{{uninitialized field 'this->head->i'}}
744 };
745
746 private:
747 Node *head = nullptr;
748
749 public:
ListTest2(Node * node,int)750 ListTest2(Node *node, int) : head(node) { // expected-warning{{1 uninitialized field}}
751 }
752 };
753
fListTest2()754 void fListTest2() {
755 ListTest2::Node n;
756 ListTest2(&n, int());
757 }
758
759 class CyclicList {
760 public:
761 struct Node {
762 Node *next = nullptr;
763 int i; // expected-note{{uninitialized field 'this->head->i'}}
764 };
765
766 private:
767 Node *head = nullptr;
768
769 public:
CyclicList(Node * node,int)770 CyclicList(Node *node, int) : head(node) { // expected-warning{{1 uninitialized field}}
771 }
772 };
773
fCyclicList()774 void fCyclicList() {
775 /*
776 n3
777 / \
778 this -- n1 -- n2
779 */
780
781 CyclicList::Node n1;
782 CyclicList::Node n2;
783 n2.next = &n1;
784 n2.i = 50;
785 CyclicList::Node n3;
786 n3.next = &n2;
787 n3.i = 50;
788 n1.next = &n3;
789 // note that n1.i is uninitialized
790 CyclicList(&n1, int());
791 }
792
793 struct RingListTest {
794 RingListTest *next; // no-crash
RingListTestRingListTest795 RingListTest() : next(this) {}
796 };
797
fRingListTest()798 void fRingListTest() {
799 RingListTest();
800 }
801
802 //===----------------------------------------------------------------------===//
803 // Tests for classes containing references.
804 //===----------------------------------------------------------------------===//
805
806 class ReferenceTest1 {
807 public:
808 struct RecordType {
809 int x;
810 int y;
811 };
812
813 private:
814 RecordType &lref;
815 RecordType &&rref;
816
817 public:
ReferenceTest1(RecordType & lref,RecordType & rref)818 ReferenceTest1(RecordType &lref, RecordType &rref) : lref(lref), rref(static_cast<RecordType &&>(rref)) {
819 // All good!
820 }
821 };
822
fReferenceTest1()823 void fReferenceTest1() {
824 ReferenceTest1::RecordType d{33, 34};
825 ReferenceTest1(d, d);
826 }
827
828 #ifdef PEDANTIC
829 class ReferenceTest2 {
830 public:
831 struct RecordType {
832 int x; // expected-note{{uninitialized field 'this->lref.x'}}
833 int y; // expected-note{{uninitialized field 'this->lref.y'}}
834 };
835
836 private:
837 RecordType &lref;
838 RecordType &&rref;
839
840 public:
ReferenceTest2(RecordType & lref,RecordType & rref)841 ReferenceTest2(RecordType &lref, RecordType &rref)
842 : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}}
843 }
844 };
845
fReferenceTest2()846 void fReferenceTest2() {
847 ReferenceTest2::RecordType c;
848 ReferenceTest2(c, c);
849 }
850 #else
851 class ReferenceTest2 {
852 public:
853 struct RecordType {
854 int x;
855 int y;
856 };
857
858 private:
859 RecordType &lref;
860 RecordType &&rref;
861
862 public:
ReferenceTest2(RecordType & lref,RecordType & rref)863 ReferenceTest2(RecordType &lref, RecordType &rref)
864 : lref(lref), rref(static_cast<RecordType &&>(rref)) {
865 }
866 };
867
fReferenceTest2()868 void fReferenceTest2() {
869 ReferenceTest2::RecordType c;
870 ReferenceTest2(c, c);
871 }
872 #endif // PEDANTIC
873
874 class ReferenceTest3 {
875 public:
876 struct RecordType {
877 int x; // expected-note{{uninitialized field 'this->lref.x'}}
878 int y; // expected-note{{uninitialized field 'this->lref.y'}}
879 };
880
881 private:
882 RecordType &lref;
883 RecordType &&rref;
884
885 public:
ReferenceTest3(RecordType & lref,RecordType & rref)886 ReferenceTest3(RecordType &lref, RecordType &rref)
887 : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}}
888 }
889 };
890
fReferenceTest3()891 void fReferenceTest3() {
892 ReferenceTest3::RecordType c, d{35, 36};
893 ReferenceTest3(c, d);
894 }
895
896 class ReferenceTest4 {
897 public:
898 struct RecordType {
899 int x; // expected-note{{uninitialized field 'this->rref.x'}}
900 int y; // expected-note{{uninitialized field 'this->rref.y'}}
901 };
902
903 private:
904 RecordType &lref;
905 RecordType &&rref;
906
907 public:
ReferenceTest4(RecordType & lref,RecordType & rref)908 ReferenceTest4(RecordType &lref, RecordType &rref)
909 : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}}
910 }
911 };
912
fReferenceTest5()913 void fReferenceTest5() {
914 ReferenceTest4::RecordType c, d{37, 38};
915 ReferenceTest4(d, c);
916 }
917
918 //===----------------------------------------------------------------------===//
919 // Tests for objects containing multiple references to the same object.
920 //===----------------------------------------------------------------------===//
921
922 struct IntMultipleReferenceToSameObjectTest {
923 int *iptr; // expected-note{{uninitialized pointee 'this->iptr'}}
924 int &iref; // no-note, pointee of this->iref was already reported
925
926 int dontGetFilteredByNonPedanticMode = 0;
927
IntMultipleReferenceToSameObjectTestIntMultipleReferenceToSameObjectTest928 IntMultipleReferenceToSameObjectTest(int *i) : iptr(i), iref(*i) {} // expected-warning{{1 uninitialized field}}
929 };
930
fIntMultipleReferenceToSameObjectTest()931 void fIntMultipleReferenceToSameObjectTest() {
932 int a;
933 IntMultipleReferenceToSameObjectTest Test(&a);
934 }
935
936 struct IntReferenceWrapper1 {
937 int &a; // expected-note{{uninitialized pointee 'this->a'}}
938
939 int dontGetFilteredByNonPedanticMode = 0;
940
IntReferenceWrapper1IntReferenceWrapper1941 IntReferenceWrapper1(int &a) : a(a) {} // expected-warning{{1 uninitialized field}}
942 };
943
944 struct IntReferenceWrapper2 {
945 int &a; // no-note, pointee of this->a was already reported
946
947 int dontGetFilteredByNonPedanticMode = 0;
948
IntReferenceWrapper2IntReferenceWrapper2949 IntReferenceWrapper2(int &a) : a(a) {} // no-warning
950 };
951
fMultipleObjectsReferencingTheSameObjectTest()952 void fMultipleObjectsReferencingTheSameObjectTest() {
953 int a;
954
955 IntReferenceWrapper1 T1(a);
956 IntReferenceWrapper2 T2(a);
957 }
958