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