blob: 5363831342fb10d26041535254421641cde6f7fc [file] [log] [blame]
Kristof Umann85e0ff72019-04-19 23:33:50 +00001// 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 \
Kristof Umanna3f7b582018-08-07 12:55:26 +00004// RUN: -std=c++11 -verify %s
Kristof Umann30f08652018-06-18 11:50:17 +00005
Kristof Umann85e0ff72019-04-19 23:33:50 +00006// RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.cplusplus.UninitializedObject \
7// RUN: -analyzer-config optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
Kristof Umanna3f7b582018-08-07 12:55:26 +00008// RUN: -std=c++11 -verify %s
Kristof Umann30f08652018-06-18 11:50:17 +00009
10//===----------------------------------------------------------------------===//
11// Concrete location tests.
12//===----------------------------------------------------------------------===//
13
14struct ConcreteIntLocTest {
15 int *ptr;
16
17 ConcreteIntLocTest() : ptr(reinterpret_cast<int *>(0xDEADBEEF)) {}
18};
19
20void fConcreteIntLocTest() {
21 ConcreteIntLocTest();
22}
23
24//===----------------------------------------------------------------------===//
Kristof Umannf0513792018-09-14 10:18:26 +000025// nonloc::LocAsInteger tests.
26//===----------------------------------------------------------------------===//
27
Kristof Umannf1f05b72018-09-14 11:20:16 +000028using intptr_t = unsigned long long;
Kristof Umannf0513792018-09-14 10:18:26 +000029
30struct LocAsIntegerTest {
31 intptr_t ptr; // expected-note{{uninitialized pointee 'reinterpret_cast<char *>(this->ptr)'}}
32 int dontGetFilteredByNonPedanticMode = 0;
33
34 LocAsIntegerTest(void *ptr) : ptr(reinterpret_cast<intptr_t>(ptr)) {} // expected-warning{{1 uninitialized field}}
35};
36
37void fLocAsIntegerTest() {
38 char c;
39 LocAsIntegerTest t(&c);
40}
41
42//===----------------------------------------------------------------------===//
Kristof Umann30f08652018-06-18 11:50:17 +000043// Null pointer tests.
44//===----------------------------------------------------------------------===//
45
46class NullPtrTest {
47 struct RecordType {
48 int x;
49 int y;
50 };
51
52 float *fptr = nullptr;
53 int *ptr;
54 RecordType *recPtr;
55
56public:
57 NullPtrTest() : ptr(nullptr), recPtr(nullptr) {
58 // All good!
59 }
60};
61
62void fNullPtrTest() {
63 NullPtrTest();
64}
65
66//===----------------------------------------------------------------------===//
Kristof Umannf0dd1012018-09-14 08:58:21 +000067// Alloca tests.
68//===----------------------------------------------------------------------===//
69
70struct UntypedAllocaTest {
71 void *allocaPtr;
72 int dontGetFilteredByNonPedanticMode = 0;
73
74 UntypedAllocaTest() : allocaPtr(__builtin_alloca(sizeof(int))) {
75 // All good!
76 }
77};
78
79void fUntypedAllocaTest() {
80 UntypedAllocaTest();
81}
82
83struct TypedAllocaTest1 {
84 int *allocaPtr; // expected-note{{uninitialized pointee 'this->allocaPtr'}}
85 int dontGetFilteredByNonPedanticMode = 0;
86
87 TypedAllocaTest1() // expected-warning{{1 uninitialized field}}
88 : allocaPtr(static_cast<int *>(__builtin_alloca(sizeof(int)))) {}
89};
90
91void fTypedAllocaTest1() {
92 TypedAllocaTest1();
93}
94
95struct TypedAllocaTest2 {
96 int *allocaPtr;
97 int dontGetFilteredByNonPedanticMode = 0;
98
99 TypedAllocaTest2()
100 : allocaPtr(static_cast<int *>(__builtin_alloca(sizeof(int)))) {
101 *allocaPtr = 55555;
102 // All good!
103 }
104};
105
106void fTypedAllocaTest2() {
107 TypedAllocaTest2();
108}
109
110//===----------------------------------------------------------------------===//
Kristof Umann30f08652018-06-18 11:50:17 +0000111// Heap pointer tests.
112//===----------------------------------------------------------------------===//
113
114class 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
127public:
128 // TODO: we'd expect the warning: {{4 uninitialized fields}}
129 HeapPointerTest1() : ptr(new int), recPtr(new RecordType) { // no-note
130 }
131};
132
133void fHeapPointerTest1() {
134 HeapPointerTest1();
135}
136
137class 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
147public:
148 HeapPointerTest2() : ptr(new int{25}), recPtr(new RecordType{26, 27}) {
149 // All good!
150 }
151};
152
153void fHeapPointerTest2() {
154 HeapPointerTest2();
155}
156
157//===----------------------------------------------------------------------===//
158// Stack pointer tests.
159//===----------------------------------------------------------------------===//
160
161class StackPointerTest1 {
162public:
163 struct RecordType {
164 int x;
165 int y;
166 };
167
168private:
169 int *ptr;
170 RecordType *recPtr;
171
172public:
173 StackPointerTest1(int *_ptr, StackPointerTest1::RecordType *_recPtr) : ptr(_ptr), recPtr(_recPtr) {
174 // All good!
175 }
176};
177
178void 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
185class StackPointerTest2 {
186public:
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
192private:
193 int *ptr; // expected-note{{uninitialized pointee 'this->ptr'}}
194 RecordType *recPtr;
195
196public:
197 StackPointerTest2(int *_ptr, RecordType *_recPtr) : ptr(_ptr), recPtr(_recPtr) { // expected-warning{{3 uninitialized fields}}
198 }
199};
200
201void fStackPointerTest2() {
202 int a;
203 StackPointerTest2::RecordType rec;
204 StackPointerTest2(&a, &rec); // 'a', 'rec.x', 'rec.y' uninitialized
205}
206#else
207class StackPointerTest2 {
208public:
209 struct RecordType {
210 int x;
211 int y;
212 };
213
214private:
215 int *ptr;
216 RecordType *recPtr;
217
218public:
219 StackPointerTest2(int *_ptr, RecordType *_recPtr) : ptr(_ptr), recPtr(_recPtr) {
220 }
221};
222
223void fStackPointerTest2() {
224 int a;
225 StackPointerTest2::RecordType rec;
226 StackPointerTest2(&a, &rec); // 'a', 'rec.x', 'rec.y' uninitialized
227}
228#endif // PEDANTIC
229
230class 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
239public:
240 UninitPointerTest() : recPtr(new RecordType{13, 13}) { // expected-warning{{1 uninitialized field}}
241 }
242};
243
244void fUninitPointerTest() {
245 UninitPointerTest();
246}
247
248struct CharPointerTest {
249 const char *str;
250 int dontGetFilteredByNonPedanticMode = 0;
251
252 CharPointerTest() : str("") {}
253};
254
255void fCharPointerTest() {
256 CharPointerTest();
257}
258
Kristof Umannc21ec002019-04-30 08:47:56 +0000259struct VectorSizePointer {
260 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
265void __vector_size__PointerTest() {
266 VectorSizePointer v;
267}
268
269struct VectorSizePointee {
270 using MyVectorType = __attribute__((__vector_size__(8))) int;
271 MyVectorType *x;
272
273 VectorSizePointee(decltype(x) x) : x(x) {}
274};
275
276void __vector_size__PointeeTest() {
277 VectorSizePointee::MyVectorType i;
278 // TODO: Report v.x's pointee.
279 VectorSizePointee v(&i);
280}
281
Kristof Umann64601962018-08-21 10:45:21 +0000282struct CyclicPointerTest1 {
Kristof Umann8e5328b2018-10-11 11:58:53 +0000283 int *ptr; // expected-note{{object references itself 'this->ptr'}}
284 int dontGetFilteredByNonPedanticMode = 0;
285
286 CyclicPointerTest1() : ptr(reinterpret_cast<int *>(&ptr)) {} // expected-warning{{1 uninitialized field}}
Kristof Umann30f08652018-06-18 11:50:17 +0000287};
288
Kristof Umann64601962018-08-21 10:45:21 +0000289void fCyclicPointerTest1() {
290 CyclicPointerTest1();
Kristof Umann30f08652018-06-18 11:50:17 +0000291}
292
Kristof Umann64601962018-08-21 10:45:21 +0000293struct CyclicPointerTest2 {
Kristof Umann8e5328b2018-10-11 11:58:53 +0000294 int **pptr; // expected-note{{object references itself 'this->pptr'}}
295 int dontGetFilteredByNonPedanticMode = 0;
296
297 CyclicPointerTest2() : pptr(reinterpret_cast<int **>(&pptr)) {} // expected-warning{{1 uninitialized field}}
Kristof Umann64601962018-08-21 10:45:21 +0000298};
299
300void fCyclicPointerTest2() {
301 CyclicPointerTest2();
302}
Kristof Umann64601962018-08-21 10:45:21 +0000303
Kristof Umann30f08652018-06-18 11:50:17 +0000304//===----------------------------------------------------------------------===//
305// Void pointer tests.
306//===----------------------------------------------------------------------===//
307
308// Void pointer tests are mainly no-crash tests.
309
310void *malloc(int size);
311
312class VoidPointerTest1 {
313 void *vptr;
314
315public:
316 VoidPointerTest1(void *vptr, char) : vptr(vptr) {
317 // All good!
318 }
319};
320
321void fVoidPointerTest1() {
322 void *vptr = malloc(sizeof(int));
323 VoidPointerTest1(vptr, char());
324}
325
326class VoidPointerTest2 {
327 void **vpptr;
328
329public:
330 VoidPointerTest2(void **vpptr, char) : vpptr(vpptr) {
331 // All good!
332 }
333};
334
335void fVoidPointerTest2() {
336 void *vptr = malloc(sizeof(int));
337 VoidPointerTest2(&vptr, char());
338}
339
340class VoidPointerRRefTest1 {
Richard Smithca975b22018-07-23 18:50:26 +0000341 void *&&vptrrref; // expected-note {{here}}
Kristof Umann30f08652018-06-18 11:50:17 +0000342
343public:
Richard Smithca975b22018-07-23 18:50:26 +0000344 VoidPointerRRefTest1(void *vptr, char) : vptrrref(static_cast<void *&&>(vptr)) { // expected-warning {{binding reference member 'vptrrref' to stack allocated parameter 'vptr'}}
Kristof Umann30f08652018-06-18 11:50:17 +0000345 // All good!
346 }
347};
348
349void fVoidPointerRRefTest1() {
350 void *vptr = malloc(sizeof(int));
351 VoidPointerRRefTest1(vptr, char());
352}
353
354class VoidPointerRRefTest2 {
Richard Smithca975b22018-07-23 18:50:26 +0000355 void **&&vpptrrref; // expected-note {{here}}
Kristof Umann30f08652018-06-18 11:50:17 +0000356
357public:
Richard Smithca975b22018-07-23 18:50:26 +0000358 VoidPointerRRefTest2(void **vptr, char) : vpptrrref(static_cast<void **&&>(vptr)) { // expected-warning {{binding reference member 'vpptrrref' to stack allocated parameter 'vptr'}}
Kristof Umann30f08652018-06-18 11:50:17 +0000359 // All good!
360 }
361};
362
363void fVoidPointerRRefTest2() {
364 void *vptr = malloc(sizeof(int));
365 VoidPointerRRefTest2(&vptr, char());
366}
367
368class VoidPointerLRefTest {
Richard Smithca975b22018-07-23 18:50:26 +0000369 void *&vptrrref; // expected-note {{here}}
Kristof Umann30f08652018-06-18 11:50:17 +0000370
371public:
Richard Smithca975b22018-07-23 18:50:26 +0000372 VoidPointerLRefTest(void *vptr, char) : vptrrref(static_cast<void *&>(vptr)) { // expected-warning {{binding reference member 'vptrrref' to stack allocated parameter 'vptr'}}
Kristof Umann30f08652018-06-18 11:50:17 +0000373 // All good!
374 }
375};
376
377void fVoidPointerLRefTest() {
378 void *vptr = malloc(sizeof(int));
379 VoidPointerLRefTest(vptr, char());
380}
381
382struct CyclicVoidPointerTest {
Kristof Umann8e5328b2018-10-11 11:58:53 +0000383 void *vptr; // expected-note{{object references itself 'this->vptr'}}
384 int dontGetFilteredByNonPedanticMode = 0;
Kristof Umann30f08652018-06-18 11:50:17 +0000385
Kristof Umann8e5328b2018-10-11 11:58:53 +0000386 CyclicVoidPointerTest() : vptr(&vptr) {} // expected-warning{{1 uninitialized field}}
Kristof Umann30f08652018-06-18 11:50:17 +0000387};
388
389void fCyclicVoidPointerTest() {
390 CyclicVoidPointerTest();
391}
392
Kristof Umannef9af052018-08-08 13:18:53 +0000393struct IntDynTypedVoidPointerTest1 {
Kristof Umann5a424412018-08-14 08:20:51 +0000394 void *vptr; // expected-note{{uninitialized pointee 'static_cast<int *>(this->vptr)'}}
Kristof Umannef9af052018-08-08 13:18:53 +0000395 int dontGetFilteredByNonPedanticMode = 0;
396
397 IntDynTypedVoidPointerTest1(void *vptr) : vptr(vptr) {} // expected-warning{{1 uninitialized field}}
398};
399
400void fIntDynTypedVoidPointerTest1() {
401 int a;
402 IntDynTypedVoidPointerTest1 tmp(&a);
403}
404
405struct RecordDynTypedVoidPointerTest {
406 struct RecordType {
Kristof Umann5a424412018-08-14 08:20:51 +0000407 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'}}
Kristof Umannef9af052018-08-08 13:18:53 +0000409 };
410
411 void *vptr;
412 int dontGetFilteredByNonPedanticMode = 0;
413
414 RecordDynTypedVoidPointerTest(void *vptr) : vptr(vptr) {} // expected-warning{{2 uninitialized fields}}
415};
416
417void fRecordDynTypedVoidPointerTest() {
418 RecordDynTypedVoidPointerTest::RecordType a;
419 RecordDynTypedVoidPointerTest tmp(&a);
420}
421
422struct NestedNonVoidDynTypedVoidPointerTest {
423 struct RecordType {
Kristof Umann5a424412018-08-14 08:20:51 +0000424 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)'}}
Kristof Umannef9af052018-08-08 13:18:53 +0000427 };
428
429 void *vptr;
430 int dontGetFilteredByNonPedanticMode = 0;
431
432 NestedNonVoidDynTypedVoidPointerTest(void *vptr, void *c) : vptr(vptr) {
433 static_cast<RecordType *>(vptr)->vptr = c; // expected-warning{{3 uninitialized fields}}
434 }
435};
436
437void fNestedNonVoidDynTypedVoidPointerTest() {
438 NestedNonVoidDynTypedVoidPointerTest::RecordType a;
439 char c;
440 NestedNonVoidDynTypedVoidPointerTest tmp(&a, &c);
441}
442
Kristof Umann30f08652018-06-18 11:50:17 +0000443//===----------------------------------------------------------------------===//
444// Multipointer tests.
445//===----------------------------------------------------------------------===//
446
447#ifdef PEDANTIC
448class MultiPointerTest1 {
449public:
450 struct RecordType {
451 int x;
452 int y;
453 };
454
455private:
456 RecordType **mptr; // expected-note{{uninitialized pointee 'this->mptr'}}
457
458public:
459 MultiPointerTest1(RecordType **p, int) : mptr(p) { // expected-warning{{1 uninitialized field}}
460 }
461};
462
463void fMultiPointerTest1() {
464 MultiPointerTest1::RecordType *p1;
465 MultiPointerTest1::RecordType **mptr = &p1;
466 MultiPointerTest1(mptr, int()); // '*mptr' uninitialized
467}
468#else
469class MultiPointerTest1 {
470public:
471 struct RecordType {
472 int x;
473 int y;
474 };
475
476private:
477 RecordType **mptr;
478
479public:
480 MultiPointerTest1(RecordType **p, int) : mptr(p) {}
481};
482
483void fMultiPointerTest1() {
484 MultiPointerTest1::RecordType *p1;
485 MultiPointerTest1::RecordType **mptr = &p1;
486 MultiPointerTest1(mptr, int()); // '*mptr' uninitialized
487}
488#endif // PEDANTIC
489
490#ifdef PEDANTIC
491class MultiPointerTest2 {
492public:
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
498private:
499 RecordType **mptr;
500
501public:
502 MultiPointerTest2(RecordType **p, int) : mptr(p) { // expected-warning{{2 uninitialized fields}}
503 }
504};
505
506void fMultiPointerTest2() {
507 MultiPointerTest2::RecordType i;
508 MultiPointerTest2::RecordType *p1 = &i;
509 MultiPointerTest2::RecordType **mptr = &p1;
510 MultiPointerTest2(mptr, int()); // '**mptr' uninitialized
511}
512#else
513class MultiPointerTest2 {
514public:
515 struct RecordType {
516 int x;
517 int y;
518 };
519
520private:
521 RecordType **mptr;
522
523public:
524 MultiPointerTest2(RecordType **p, int) : mptr(p) {
525 }
526};
527
528void 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
536class MultiPointerTest3 {
537public:
538 struct RecordType {
539 int x;
540 int y;
541 };
542
543private:
544 RecordType **mptr;
545
546public:
547 MultiPointerTest3(RecordType **p, int) : mptr(p) {
548 // All good!
549 }
550};
551
552void 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//===----------------------------------------------------------------------===//
Kristof Umannf0dd1012018-09-14 08:58:21 +0000560// Incomplete pointee tests.
561//===----------------------------------------------------------------------===//
562
563class IncompleteType;
564
565struct IncompletePointeeTypeTest {
566 IncompleteType *pImpl; //no-crash
567 int dontGetFilteredByNonPedanticMode = 0;
568
569 IncompletePointeeTypeTest(IncompleteType *A) : pImpl(A) {}
570};
571
572void fIncompletePointeeTypeTest(void *ptr) {
573 IncompletePointeeTypeTest(reinterpret_cast<IncompleteType *>(ptr));
574}
575
576//===----------------------------------------------------------------------===//
577// Function pointer tests.
578//===----------------------------------------------------------------------===//
579
580struct FunctionPointerWithDifferentDynTypeTest {
581 using Func1 = void *(*)();
582 using Func2 = int *(*)();
583
584 Func1 f; // no-crash
585 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//===----------------------------------------------------------------------===//
Kristof Umann30f08652018-06-18 11:50:17 +0000593// Member pointer tests.
594//===----------------------------------------------------------------------===//
595
596struct UsefulFunctions {
597 int a, b;
598
599 void print() {}
600 void dump() {}
601};
602
603#ifdef PEDANTIC
604struct PointerToMemberFunctionTest1 {
Kristof Umann7212cc02018-07-13 12:21:38 +0000605 void (UsefulFunctions::*f)(void); // expected-note{{uninitialized field 'this->f'}}
Kristof Umann30f08652018-06-18 11:50:17 +0000606 PointerToMemberFunctionTest1() {}
607};
608
609void fPointerToMemberFunctionTest1() {
Kristof Umann7212cc02018-07-13 12:21:38 +0000610 PointerToMemberFunctionTest1(); // expected-warning{{1 uninitialized field}}
Kristof Umann30f08652018-06-18 11:50:17 +0000611}
612
613struct PointerToMemberFunctionTest2 {
614 void (UsefulFunctions::*f)(void);
615 PointerToMemberFunctionTest2(void (UsefulFunctions::*f)(void)) : f(f) {
616 // All good!
617 }
618};
619
620void fPointerToMemberFunctionTest2() {
621 void (UsefulFunctions::*f)(void) = &UsefulFunctions::print;
622 PointerToMemberFunctionTest2 a(f);
623}
624
625struct MultiPointerToMemberFunctionTest1 {
626 void (UsefulFunctions::**f)(void); // expected-note{{uninitialized pointer 'this->f'}}
627 MultiPointerToMemberFunctionTest1() {}
628};
629
630void fMultiPointerToMemberFunctionTest1() {
631 MultiPointerToMemberFunctionTest1(); // expected-warning{{1 uninitialized field}}
632}
633
634struct MultiPointerToMemberFunctionTest2 {
635 void (UsefulFunctions::**f)(void);
636 MultiPointerToMemberFunctionTest2(void (UsefulFunctions::**f)(void)) : f(f) {
637 // All good!
638 }
639};
640
641void fMultiPointerToMemberFunctionTest2() {
642 void (UsefulFunctions::*f)(void) = &UsefulFunctions::print;
643 MultiPointerToMemberFunctionTest2 a(&f);
644}
645
646struct PointerToMemberDataTest1 {
Kristof Umann7212cc02018-07-13 12:21:38 +0000647 int UsefulFunctions::*d; // expected-note{{uninitialized field 'this->d'}}
Kristof Umann30f08652018-06-18 11:50:17 +0000648 PointerToMemberDataTest1() {}
649};
650
651void fPointerToMemberDataTest1() {
Kristof Umann7212cc02018-07-13 12:21:38 +0000652 PointerToMemberDataTest1(); // expected-warning{{1 uninitialized field}}
Kristof Umann30f08652018-06-18 11:50:17 +0000653}
654
655struct PointerToMemberDataTest2 {
656 int UsefulFunctions::*d;
657 PointerToMemberDataTest2(int UsefulFunctions::*d) : d(d) {
658 // All good!
659 }
660};
661
662void fPointerToMemberDataTest2() {
663 int UsefulFunctions::*d = &UsefulFunctions::a;
664 PointerToMemberDataTest2 a(d);
665}
666
667struct MultiPointerToMemberDataTest1 {
668 int UsefulFunctions::**d; // expected-note{{uninitialized pointer 'this->d'}}
669 MultiPointerToMemberDataTest1() {}
670};
671
672void fMultiPointerToMemberDataTest1() {
673 MultiPointerToMemberDataTest1(); // expected-warning{{1 uninitialized field}}
674}
675
676struct MultiPointerToMemberDataTest2 {
677 int UsefulFunctions::**d;
678 MultiPointerToMemberDataTest2(int UsefulFunctions::**d) : d(d) {
679 // All good!
680 }
681};
682
683void 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
693class ListTest1 {
694public:
695 struct Node {
696 Node *next = nullptr; // no crash
697 int i;
698 };
699
700private:
701 Node *head = nullptr;
702
703public:
704 ListTest1() {
705 // All good!
706 }
707};
708
709void fListTest1() {
710 ListTest1();
711}
712
713class ListTest2 {
714public:
715 struct Node {
716 Node *next = nullptr;
717 int i; // expected-note{{uninitialized field 'this->head->i'}}
718 };
719
720private:
721 Node *head = nullptr;
722
723public:
724 ListTest2(Node *node, int) : head(node) { // expected-warning{{1 uninitialized field}}
725 }
726};
727
728void fListTest2() {
729 ListTest2::Node n;
730 ListTest2(&n, int());
731}
732
733class CyclicList {
734public:
735 struct Node {
736 Node *next = nullptr;
737 int i; // expected-note{{uninitialized field 'this->head->i'}}
738 };
739
740private:
741 Node *head = nullptr;
742
743public:
744 CyclicList(Node *node, int) : head(node) { // expected-warning{{1 uninitialized field}}
745 }
746};
747
748void 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
Kristof Umannf0dd1012018-09-14 08:58:21 +0000767struct RingListTest {
768 RingListTest *next; // no-crash
769 RingListTest() : next(this) {}
770};
771
772void fRingListTest() {
773 RingListTest();
774}
775
Kristof Umann30f08652018-06-18 11:50:17 +0000776//===----------------------------------------------------------------------===//
777// Tests for classes containing references.
778//===----------------------------------------------------------------------===//
779
780class ReferenceTest1 {
781public:
782 struct RecordType {
783 int x;
784 int y;
785 };
786
787private:
788 RecordType &lref;
789 RecordType &&rref;
790
791public:
792 ReferenceTest1(RecordType &lref, RecordType &rref) : lref(lref), rref(static_cast<RecordType &&>(rref)) {
793 // All good!
794 }
795};
796
797void fReferenceTest1() {
798 ReferenceTest1::RecordType d{33, 34};
799 ReferenceTest1(d, d);
800}
801
802#ifdef PEDANTIC
803class ReferenceTest2 {
804public:
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
810private:
811 RecordType &lref;
812 RecordType &&rref;
813
814public:
815 ReferenceTest2(RecordType &lref, RecordType &rref)
816 : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}}
817 }
818};
819
820void fReferenceTest2() {
821 ReferenceTest2::RecordType c;
822 ReferenceTest2(c, c);
823}
824#else
825class ReferenceTest2 {
826public:
827 struct RecordType {
828 int x;
829 int y;
830 };
831
832private:
833 RecordType &lref;
834 RecordType &&rref;
835
836public:
837 ReferenceTest2(RecordType &lref, RecordType &rref)
838 : lref(lref), rref(static_cast<RecordType &&>(rref)) {
839 }
840};
841
842void fReferenceTest2() {
843 ReferenceTest2::RecordType c;
844 ReferenceTest2(c, c);
845}
846#endif // PEDANTIC
847
848class ReferenceTest3 {
849public:
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
855private:
856 RecordType &lref;
857 RecordType &&rref;
858
859public:
860 ReferenceTest3(RecordType &lref, RecordType &rref)
861 : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}}
862 }
863};
864
865void fReferenceTest3() {
866 ReferenceTest3::RecordType c, d{35, 36};
867 ReferenceTest3(c, d);
868}
869
870class ReferenceTest4 {
871public:
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
877private:
878 RecordType &lref;
879 RecordType &&rref;
880
881public:
882 ReferenceTest4(RecordType &lref, RecordType &rref)
883 : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}}
884 }
885};
886
887void fReferenceTest5() {
888 ReferenceTest4::RecordType c, d{37, 38};
889 ReferenceTest4(d, c);
890}
Kristof Umann4ff77692018-11-18 11:34:10 +0000891
892//===----------------------------------------------------------------------===//
893// Tests for objects containing multiple references to the same object.
894//===----------------------------------------------------------------------===//
895
896struct 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
902 IntMultipleReferenceToSameObjectTest(int *i) : iptr(i), iref(*i) {} // expected-warning{{1 uninitialized field}}
903};
904
905void fIntMultipleReferenceToSameObjectTest() {
906 int a;
907 IntMultipleReferenceToSameObjectTest Test(&a);
908}
909
910struct IntReferenceWrapper1 {
911 int &a; // expected-note{{uninitialized pointee 'this->a'}}
912
913 int dontGetFilteredByNonPedanticMode = 0;
914
915 IntReferenceWrapper1(int &a) : a(a) {} // expected-warning{{1 uninitialized field}}
916};
917
918struct IntReferenceWrapper2 {
919 int &a; // no-note, pointee of this->a was already reported
920
921 int dontGetFilteredByNonPedanticMode = 0;
922
923 IntReferenceWrapper2(int &a) : a(a) {} // no-warning
924};
925
926void fMultipleObjectsReferencingTheSameObjectTest() {
927 int a;
928
929 IntReferenceWrapper1 T1(a);
930 IntReferenceWrapper2 T2(a);
931}