blob: c222f3e6a89b67b2752efc87662a74994f130e9a [file] [log] [blame]
Kristof Umanna3f7b582018-08-07 12:55:26 +00001// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \
2// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \
3// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
4// RUN: -std=c++11 -verify %s
Kristof Umann30f08652018-06-18 11:50:17 +00005
Kristof Umanna3f7b582018-08-07 12:55:26 +00006// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \
7// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
8// 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 Umann64601962018-08-21 10:45:21 +0000259struct CyclicPointerTest1 {
Kristof Umann8e5328b2018-10-11 11:58:53 +0000260 int *ptr; // expected-note{{object references itself 'this->ptr'}}
261 int dontGetFilteredByNonPedanticMode = 0;
262
263 CyclicPointerTest1() : ptr(reinterpret_cast<int *>(&ptr)) {} // expected-warning{{1 uninitialized field}}
Kristof Umann30f08652018-06-18 11:50:17 +0000264};
265
Kristof Umann64601962018-08-21 10:45:21 +0000266void fCyclicPointerTest1() {
267 CyclicPointerTest1();
Kristof Umann30f08652018-06-18 11:50:17 +0000268}
269
Kristof Umann64601962018-08-21 10:45:21 +0000270struct CyclicPointerTest2 {
Kristof Umann8e5328b2018-10-11 11:58:53 +0000271 int **pptr; // expected-note{{object references itself 'this->pptr'}}
272 int dontGetFilteredByNonPedanticMode = 0;
273
274 CyclicPointerTest2() : pptr(reinterpret_cast<int **>(&pptr)) {} // expected-warning{{1 uninitialized field}}
Kristof Umann64601962018-08-21 10:45:21 +0000275};
276
277void fCyclicPointerTest2() {
278 CyclicPointerTest2();
279}
Kristof Umann64601962018-08-21 10:45:21 +0000280
Kristof Umann30f08652018-06-18 11:50:17 +0000281//===----------------------------------------------------------------------===//
282// Void pointer tests.
283//===----------------------------------------------------------------------===//
284
285// Void pointer tests are mainly no-crash tests.
286
287void *malloc(int size);
288
289class VoidPointerTest1 {
290 void *vptr;
291
292public:
293 VoidPointerTest1(void *vptr, char) : vptr(vptr) {
294 // All good!
295 }
296};
297
298void fVoidPointerTest1() {
299 void *vptr = malloc(sizeof(int));
300 VoidPointerTest1(vptr, char());
301}
302
303class VoidPointerTest2 {
304 void **vpptr;
305
306public:
307 VoidPointerTest2(void **vpptr, char) : vpptr(vpptr) {
308 // All good!
309 }
310};
311
312void fVoidPointerTest2() {
313 void *vptr = malloc(sizeof(int));
314 VoidPointerTest2(&vptr, char());
315}
316
317class VoidPointerRRefTest1 {
Richard Smithca975b22018-07-23 18:50:26 +0000318 void *&&vptrrref; // expected-note {{here}}
Kristof Umann30f08652018-06-18 11:50:17 +0000319
320public:
Richard Smithca975b22018-07-23 18:50:26 +0000321 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 +0000322 // All good!
323 }
324};
325
326void fVoidPointerRRefTest1() {
327 void *vptr = malloc(sizeof(int));
328 VoidPointerRRefTest1(vptr, char());
329}
330
331class VoidPointerRRefTest2 {
Richard Smithca975b22018-07-23 18:50:26 +0000332 void **&&vpptrrref; // expected-note {{here}}
Kristof Umann30f08652018-06-18 11:50:17 +0000333
334public:
Richard Smithca975b22018-07-23 18:50:26 +0000335 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 +0000336 // All good!
337 }
338};
339
340void fVoidPointerRRefTest2() {
341 void *vptr = malloc(sizeof(int));
342 VoidPointerRRefTest2(&vptr, char());
343}
344
345class VoidPointerLRefTest {
Richard Smithca975b22018-07-23 18:50:26 +0000346 void *&vptrrref; // expected-note {{here}}
Kristof Umann30f08652018-06-18 11:50:17 +0000347
348public:
Richard Smithca975b22018-07-23 18:50:26 +0000349 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 +0000350 // All good!
351 }
352};
353
354void fVoidPointerLRefTest() {
355 void *vptr = malloc(sizeof(int));
356 VoidPointerLRefTest(vptr, char());
357}
358
359struct CyclicVoidPointerTest {
Kristof Umann8e5328b2018-10-11 11:58:53 +0000360 void *vptr; // expected-note{{object references itself 'this->vptr'}}
361 int dontGetFilteredByNonPedanticMode = 0;
Kristof Umann30f08652018-06-18 11:50:17 +0000362
Kristof Umann8e5328b2018-10-11 11:58:53 +0000363 CyclicVoidPointerTest() : vptr(&vptr) {} // expected-warning{{1 uninitialized field}}
Kristof Umann30f08652018-06-18 11:50:17 +0000364};
365
366void fCyclicVoidPointerTest() {
367 CyclicVoidPointerTest();
368}
369
Kristof Umannef9af052018-08-08 13:18:53 +0000370struct IntDynTypedVoidPointerTest1 {
Kristof Umann5a424412018-08-14 08:20:51 +0000371 void *vptr; // expected-note{{uninitialized pointee 'static_cast<int *>(this->vptr)'}}
Kristof Umannef9af052018-08-08 13:18:53 +0000372 int dontGetFilteredByNonPedanticMode = 0;
373
374 IntDynTypedVoidPointerTest1(void *vptr) : vptr(vptr) {} // expected-warning{{1 uninitialized field}}
375};
376
377void fIntDynTypedVoidPointerTest1() {
378 int a;
379 IntDynTypedVoidPointerTest1 tmp(&a);
380}
381
382struct RecordDynTypedVoidPointerTest {
383 struct RecordType {
Kristof Umann5a424412018-08-14 08:20:51 +0000384 int x; // expected-note{{uninitialized field 'static_cast<struct RecordDynTypedVoidPointerTest::RecordType *>(this->vptr)->x'}}
385 int y; // expected-note{{uninitialized field 'static_cast<struct RecordDynTypedVoidPointerTest::RecordType *>(this->vptr)->y'}}
Kristof Umannef9af052018-08-08 13:18:53 +0000386 };
387
388 void *vptr;
389 int dontGetFilteredByNonPedanticMode = 0;
390
391 RecordDynTypedVoidPointerTest(void *vptr) : vptr(vptr) {} // expected-warning{{2 uninitialized fields}}
392};
393
394void fRecordDynTypedVoidPointerTest() {
395 RecordDynTypedVoidPointerTest::RecordType a;
396 RecordDynTypedVoidPointerTest tmp(&a);
397}
398
399struct NestedNonVoidDynTypedVoidPointerTest {
400 struct RecordType {
Kristof Umann5a424412018-08-14 08:20:51 +0000401 int x; // expected-note{{uninitialized field 'static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->x'}}
402 int y; // expected-note{{uninitialized field 'static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->y'}}
403 void *vptr; // expected-note{{uninitialized pointee 'static_cast<char *>(static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->vptr)'}}
Kristof Umannef9af052018-08-08 13:18:53 +0000404 };
405
406 void *vptr;
407 int dontGetFilteredByNonPedanticMode = 0;
408
409 NestedNonVoidDynTypedVoidPointerTest(void *vptr, void *c) : vptr(vptr) {
410 static_cast<RecordType *>(vptr)->vptr = c; // expected-warning{{3 uninitialized fields}}
411 }
412};
413
414void fNestedNonVoidDynTypedVoidPointerTest() {
415 NestedNonVoidDynTypedVoidPointerTest::RecordType a;
416 char c;
417 NestedNonVoidDynTypedVoidPointerTest tmp(&a, &c);
418}
419
Kristof Umann30f08652018-06-18 11:50:17 +0000420//===----------------------------------------------------------------------===//
421// Multipointer tests.
422//===----------------------------------------------------------------------===//
423
424#ifdef PEDANTIC
425class MultiPointerTest1 {
426public:
427 struct RecordType {
428 int x;
429 int y;
430 };
431
432private:
433 RecordType **mptr; // expected-note{{uninitialized pointee 'this->mptr'}}
434
435public:
436 MultiPointerTest1(RecordType **p, int) : mptr(p) { // expected-warning{{1 uninitialized field}}
437 }
438};
439
440void fMultiPointerTest1() {
441 MultiPointerTest1::RecordType *p1;
442 MultiPointerTest1::RecordType **mptr = &p1;
443 MultiPointerTest1(mptr, int()); // '*mptr' uninitialized
444}
445#else
446class MultiPointerTest1 {
447public:
448 struct RecordType {
449 int x;
450 int y;
451 };
452
453private:
454 RecordType **mptr;
455
456public:
457 MultiPointerTest1(RecordType **p, int) : mptr(p) {}
458};
459
460void fMultiPointerTest1() {
461 MultiPointerTest1::RecordType *p1;
462 MultiPointerTest1::RecordType **mptr = &p1;
463 MultiPointerTest1(mptr, int()); // '*mptr' uninitialized
464}
465#endif // PEDANTIC
466
467#ifdef PEDANTIC
468class MultiPointerTest2 {
469public:
470 struct RecordType {
471 int x; // expected-note{{uninitialized field 'this->mptr->x'}}
472 int y; // expected-note{{uninitialized field 'this->mptr->y'}}
473 };
474
475private:
476 RecordType **mptr;
477
478public:
479 MultiPointerTest2(RecordType **p, int) : mptr(p) { // expected-warning{{2 uninitialized fields}}
480 }
481};
482
483void fMultiPointerTest2() {
484 MultiPointerTest2::RecordType i;
485 MultiPointerTest2::RecordType *p1 = &i;
486 MultiPointerTest2::RecordType **mptr = &p1;
487 MultiPointerTest2(mptr, int()); // '**mptr' uninitialized
488}
489#else
490class MultiPointerTest2 {
491public:
492 struct RecordType {
493 int x;
494 int y;
495 };
496
497private:
498 RecordType **mptr;
499
500public:
501 MultiPointerTest2(RecordType **p, int) : mptr(p) {
502 }
503};
504
505void fMultiPointerTest2() {
506 MultiPointerTest2::RecordType i;
507 MultiPointerTest2::RecordType *p1 = &i;
508 MultiPointerTest2::RecordType **mptr = &p1;
509 MultiPointerTest2(mptr, int()); // '**mptr' uninitialized
510}
511#endif // PEDANTIC
512
513class MultiPointerTest3 {
514public:
515 struct RecordType {
516 int x;
517 int y;
518 };
519
520private:
521 RecordType **mptr;
522
523public:
524 MultiPointerTest3(RecordType **p, int) : mptr(p) {
525 // All good!
526 }
527};
528
529void fMultiPointerTest3() {
530 MultiPointerTest3::RecordType i{31, 32};
531 MultiPointerTest3::RecordType *p1 = &i;
532 MultiPointerTest3::RecordType **mptr = &p1;
533 MultiPointerTest3(mptr, int()); // '**mptr' uninitialized
534}
535
536//===----------------------------------------------------------------------===//
Kristof Umannf0dd1012018-09-14 08:58:21 +0000537// Incomplete pointee tests.
538//===----------------------------------------------------------------------===//
539
540class IncompleteType;
541
542struct IncompletePointeeTypeTest {
543 IncompleteType *pImpl; //no-crash
544 int dontGetFilteredByNonPedanticMode = 0;
545
546 IncompletePointeeTypeTest(IncompleteType *A) : pImpl(A) {}
547};
548
549void fIncompletePointeeTypeTest(void *ptr) {
550 IncompletePointeeTypeTest(reinterpret_cast<IncompleteType *>(ptr));
551}
552
553//===----------------------------------------------------------------------===//
554// Function pointer tests.
555//===----------------------------------------------------------------------===//
556
557struct FunctionPointerWithDifferentDynTypeTest {
558 using Func1 = void *(*)();
559 using Func2 = int *(*)();
560
561 Func1 f; // no-crash
562 FunctionPointerWithDifferentDynTypeTest(Func2 f) : f((Func1)f) {}
563};
564
565// Note that there isn't a function calling the constructor of
566// FunctionPointerWithDifferentDynTypeTest, because a crash could only be
567// reproduced without it.
568
569//===----------------------------------------------------------------------===//
Kristof Umann30f08652018-06-18 11:50:17 +0000570// Member pointer tests.
571//===----------------------------------------------------------------------===//
572
573struct UsefulFunctions {
574 int a, b;
575
576 void print() {}
577 void dump() {}
578};
579
580#ifdef PEDANTIC
581struct PointerToMemberFunctionTest1 {
Kristof Umann7212cc02018-07-13 12:21:38 +0000582 void (UsefulFunctions::*f)(void); // expected-note{{uninitialized field 'this->f'}}
Kristof Umann30f08652018-06-18 11:50:17 +0000583 PointerToMemberFunctionTest1() {}
584};
585
586void fPointerToMemberFunctionTest1() {
Kristof Umann7212cc02018-07-13 12:21:38 +0000587 PointerToMemberFunctionTest1(); // expected-warning{{1 uninitialized field}}
Kristof Umann30f08652018-06-18 11:50:17 +0000588}
589
590struct PointerToMemberFunctionTest2 {
591 void (UsefulFunctions::*f)(void);
592 PointerToMemberFunctionTest2(void (UsefulFunctions::*f)(void)) : f(f) {
593 // All good!
594 }
595};
596
597void fPointerToMemberFunctionTest2() {
598 void (UsefulFunctions::*f)(void) = &UsefulFunctions::print;
599 PointerToMemberFunctionTest2 a(f);
600}
601
602struct MultiPointerToMemberFunctionTest1 {
603 void (UsefulFunctions::**f)(void); // expected-note{{uninitialized pointer 'this->f'}}
604 MultiPointerToMemberFunctionTest1() {}
605};
606
607void fMultiPointerToMemberFunctionTest1() {
608 MultiPointerToMemberFunctionTest1(); // expected-warning{{1 uninitialized field}}
609}
610
611struct MultiPointerToMemberFunctionTest2 {
612 void (UsefulFunctions::**f)(void);
613 MultiPointerToMemberFunctionTest2(void (UsefulFunctions::**f)(void)) : f(f) {
614 // All good!
615 }
616};
617
618void fMultiPointerToMemberFunctionTest2() {
619 void (UsefulFunctions::*f)(void) = &UsefulFunctions::print;
620 MultiPointerToMemberFunctionTest2 a(&f);
621}
622
623struct PointerToMemberDataTest1 {
Kristof Umann7212cc02018-07-13 12:21:38 +0000624 int UsefulFunctions::*d; // expected-note{{uninitialized field 'this->d'}}
Kristof Umann30f08652018-06-18 11:50:17 +0000625 PointerToMemberDataTest1() {}
626};
627
628void fPointerToMemberDataTest1() {
Kristof Umann7212cc02018-07-13 12:21:38 +0000629 PointerToMemberDataTest1(); // expected-warning{{1 uninitialized field}}
Kristof Umann30f08652018-06-18 11:50:17 +0000630}
631
632struct PointerToMemberDataTest2 {
633 int UsefulFunctions::*d;
634 PointerToMemberDataTest2(int UsefulFunctions::*d) : d(d) {
635 // All good!
636 }
637};
638
639void fPointerToMemberDataTest2() {
640 int UsefulFunctions::*d = &UsefulFunctions::a;
641 PointerToMemberDataTest2 a(d);
642}
643
644struct MultiPointerToMemberDataTest1 {
645 int UsefulFunctions::**d; // expected-note{{uninitialized pointer 'this->d'}}
646 MultiPointerToMemberDataTest1() {}
647};
648
649void fMultiPointerToMemberDataTest1() {
650 MultiPointerToMemberDataTest1(); // expected-warning{{1 uninitialized field}}
651}
652
653struct MultiPointerToMemberDataTest2 {
654 int UsefulFunctions::**d;
655 MultiPointerToMemberDataTest2(int UsefulFunctions::**d) : d(d) {
656 // All good!
657 }
658};
659
660void fMultiPointerToMemberDataTest2() {
661 int UsefulFunctions::*d = &UsefulFunctions::a;
662 MultiPointerToMemberDataTest2 a(&d);
663}
664#endif // PEDANTIC
665
666//===----------------------------------------------------------------------===//
667// Tests for list-like records.
668//===----------------------------------------------------------------------===//
669
670class ListTest1 {
671public:
672 struct Node {
673 Node *next = nullptr; // no crash
674 int i;
675 };
676
677private:
678 Node *head = nullptr;
679
680public:
681 ListTest1() {
682 // All good!
683 }
684};
685
686void fListTest1() {
687 ListTest1();
688}
689
690class ListTest2 {
691public:
692 struct Node {
693 Node *next = nullptr;
694 int i; // expected-note{{uninitialized field 'this->head->i'}}
695 };
696
697private:
698 Node *head = nullptr;
699
700public:
701 ListTest2(Node *node, int) : head(node) { // expected-warning{{1 uninitialized field}}
702 }
703};
704
705void fListTest2() {
706 ListTest2::Node n;
707 ListTest2(&n, int());
708}
709
710class CyclicList {
711public:
712 struct Node {
713 Node *next = nullptr;
714 int i; // expected-note{{uninitialized field 'this->head->i'}}
715 };
716
717private:
718 Node *head = nullptr;
719
720public:
721 CyclicList(Node *node, int) : head(node) { // expected-warning{{1 uninitialized field}}
722 }
723};
724
725void fCyclicList() {
726 /*
727 n3
728 / \
729 this -- n1 -- n2
730 */
731
732 CyclicList::Node n1;
733 CyclicList::Node n2;
734 n2.next = &n1;
735 n2.i = 50;
736 CyclicList::Node n3;
737 n3.next = &n2;
738 n3.i = 50;
739 n1.next = &n3;
740 // note that n1.i is uninitialized
741 CyclicList(&n1, int());
742}
743
Kristof Umannf0dd1012018-09-14 08:58:21 +0000744struct RingListTest {
745 RingListTest *next; // no-crash
746 RingListTest() : next(this) {}
747};
748
749void fRingListTest() {
750 RingListTest();
751}
752
Kristof Umann30f08652018-06-18 11:50:17 +0000753//===----------------------------------------------------------------------===//
754// Tests for classes containing references.
755//===----------------------------------------------------------------------===//
756
757class ReferenceTest1 {
758public:
759 struct RecordType {
760 int x;
761 int y;
762 };
763
764private:
765 RecordType &lref;
766 RecordType &&rref;
767
768public:
769 ReferenceTest1(RecordType &lref, RecordType &rref) : lref(lref), rref(static_cast<RecordType &&>(rref)) {
770 // All good!
771 }
772};
773
774void fReferenceTest1() {
775 ReferenceTest1::RecordType d{33, 34};
776 ReferenceTest1(d, d);
777}
778
779#ifdef PEDANTIC
780class ReferenceTest2 {
781public:
782 struct RecordType {
783 int x; // expected-note{{uninitialized field 'this->lref.x'}}
784 int y; // expected-note{{uninitialized field 'this->lref.y'}}
785 };
786
787private:
788 RecordType &lref;
789 RecordType &&rref;
790
791public:
792 ReferenceTest2(RecordType &lref, RecordType &rref)
793 : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}}
794 }
795};
796
797void fReferenceTest2() {
798 ReferenceTest2::RecordType c;
799 ReferenceTest2(c, c);
800}
801#else
802class ReferenceTest2 {
803public:
804 struct RecordType {
805 int x;
806 int y;
807 };
808
809private:
810 RecordType &lref;
811 RecordType &&rref;
812
813public:
814 ReferenceTest2(RecordType &lref, RecordType &rref)
815 : lref(lref), rref(static_cast<RecordType &&>(rref)) {
816 }
817};
818
819void fReferenceTest2() {
820 ReferenceTest2::RecordType c;
821 ReferenceTest2(c, c);
822}
823#endif // PEDANTIC
824
825class ReferenceTest3 {
826public:
827 struct RecordType {
828 int x; // expected-note{{uninitialized field 'this->lref.x'}}
829 int y; // expected-note{{uninitialized field 'this->lref.y'}}
830 };
831
832private:
833 RecordType &lref;
834 RecordType &&rref;
835
836public:
837 ReferenceTest3(RecordType &lref, RecordType &rref)
838 : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}}
839 }
840};
841
842void fReferenceTest3() {
843 ReferenceTest3::RecordType c, d{35, 36};
844 ReferenceTest3(c, d);
845}
846
847class ReferenceTest4 {
848public:
849 struct RecordType {
850 int x; // expected-note{{uninitialized field 'this->rref.x'}}
851 int y; // expected-note{{uninitialized field 'this->rref.y'}}
852 };
853
854private:
855 RecordType &lref;
856 RecordType &&rref;
857
858public:
859 ReferenceTest4(RecordType &lref, RecordType &rref)
860 : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}}
861 }
862};
863
864void fReferenceTest5() {
865 ReferenceTest4::RecordType c, d{37, 38};
866 ReferenceTest4(d, c);
867}