blob: 4ee113c9e8f4c8be581ad78803d645be1435e968 [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//===----------------------------------------------------------------------===//
25// Null pointer tests.
26//===----------------------------------------------------------------------===//
27
28class NullPtrTest {
29 struct RecordType {
30 int x;
31 int y;
32 };
33
34 float *fptr = nullptr;
35 int *ptr;
36 RecordType *recPtr;
37
38public:
39 NullPtrTest() : ptr(nullptr), recPtr(nullptr) {
40 // All good!
41 }
42};
43
44void fNullPtrTest() {
45 NullPtrTest();
46}
47
48//===----------------------------------------------------------------------===//
Kristof Umannf0dd1012018-09-14 08:58:21 +000049// Alloca tests.
50//===----------------------------------------------------------------------===//
51
52struct UntypedAllocaTest {
53 void *allocaPtr;
54 int dontGetFilteredByNonPedanticMode = 0;
55
56 UntypedAllocaTest() : allocaPtr(__builtin_alloca(sizeof(int))) {
57 // All good!
58 }
59};
60
61void fUntypedAllocaTest() {
62 UntypedAllocaTest();
63}
64
65struct TypedAllocaTest1 {
66 int *allocaPtr; // expected-note{{uninitialized pointee 'this->allocaPtr'}}
67 int dontGetFilteredByNonPedanticMode = 0;
68
69 TypedAllocaTest1() // expected-warning{{1 uninitialized field}}
70 : allocaPtr(static_cast<int *>(__builtin_alloca(sizeof(int)))) {}
71};
72
73void fTypedAllocaTest1() {
74 TypedAllocaTest1();
75}
76
77struct TypedAllocaTest2 {
78 int *allocaPtr;
79 int dontGetFilteredByNonPedanticMode = 0;
80
81 TypedAllocaTest2()
82 : allocaPtr(static_cast<int *>(__builtin_alloca(sizeof(int)))) {
83 *allocaPtr = 55555;
84 // All good!
85 }
86};
87
88void fTypedAllocaTest2() {
89 TypedAllocaTest2();
90}
91
92//===----------------------------------------------------------------------===//
Kristof Umann30f08652018-06-18 11:50:17 +000093// Heap pointer tests.
94//===----------------------------------------------------------------------===//
95
96class HeapPointerTest1 {
97 struct RecordType {
98 // TODO: we'd expect the note: {{uninitialized field 'this->recPtr->y'}}
99 int x; // no-note
100 // TODO: we'd expect the note: {{uninitialized field 'this->recPtr->y'}}
101 int y; // no-note
102 };
103 // TODO: we'd expect the note: {{uninitialized pointee 'this->fptr'}}
104 float *fptr = new float; // no-note
105 // TODO: we'd expect the note: {{uninitialized pointee 'this->ptr'}}
106 int *ptr; // no-note
107 RecordType *recPtr;
108
109public:
110 // TODO: we'd expect the warning: {{4 uninitialized fields}}
111 HeapPointerTest1() : ptr(new int), recPtr(new RecordType) { // no-note
112 }
113};
114
115void fHeapPointerTest1() {
116 HeapPointerTest1();
117}
118
119class HeapPointerTest2 {
120 struct RecordType {
121 int x;
122 int y;
123 };
124
125 float *fptr = new float(); // initializes to 0
126 int *ptr;
127 RecordType *recPtr;
128
129public:
130 HeapPointerTest2() : ptr(new int{25}), recPtr(new RecordType{26, 27}) {
131 // All good!
132 }
133};
134
135void fHeapPointerTest2() {
136 HeapPointerTest2();
137}
138
139//===----------------------------------------------------------------------===//
140// Stack pointer tests.
141//===----------------------------------------------------------------------===//
142
143class StackPointerTest1 {
144public:
145 struct RecordType {
146 int x;
147 int y;
148 };
149
150private:
151 int *ptr;
152 RecordType *recPtr;
153
154public:
155 StackPointerTest1(int *_ptr, StackPointerTest1::RecordType *_recPtr) : ptr(_ptr), recPtr(_recPtr) {
156 // All good!
157 }
158};
159
160void fStackPointerTest1() {
161 int ok_a = 28;
162 StackPointerTest1::RecordType ok_rec{29, 30};
163 StackPointerTest1(&ok_a, &ok_rec); // 'a', 'rec.x', 'rec.y' uninitialized
164}
165
166#ifdef PEDANTIC
167class StackPointerTest2 {
168public:
169 struct RecordType {
170 int x; // expected-note{{uninitialized field 'this->recPtr->x'}}
171 int y; // expected-note{{uninitialized field 'this->recPtr->y'}}
172 };
173
174private:
175 int *ptr; // expected-note{{uninitialized pointee 'this->ptr'}}
176 RecordType *recPtr;
177
178public:
179 StackPointerTest2(int *_ptr, RecordType *_recPtr) : ptr(_ptr), recPtr(_recPtr) { // expected-warning{{3 uninitialized fields}}
180 }
181};
182
183void fStackPointerTest2() {
184 int a;
185 StackPointerTest2::RecordType rec;
186 StackPointerTest2(&a, &rec); // 'a', 'rec.x', 'rec.y' uninitialized
187}
188#else
189class StackPointerTest2 {
190public:
191 struct RecordType {
192 int x;
193 int y;
194 };
195
196private:
197 int *ptr;
198 RecordType *recPtr;
199
200public:
201 StackPointerTest2(int *_ptr, RecordType *_recPtr) : ptr(_ptr), recPtr(_recPtr) {
202 }
203};
204
205void fStackPointerTest2() {
206 int a;
207 StackPointerTest2::RecordType rec;
208 StackPointerTest2(&a, &rec); // 'a', 'rec.x', 'rec.y' uninitialized
209}
210#endif // PEDANTIC
211
212class UninitPointerTest {
213 struct RecordType {
214 int x;
215 int y;
216 };
217
218 int *ptr; // expected-note{{uninitialized pointer 'this->ptr'}}
219 RecordType *recPtr;
220
221public:
222 UninitPointerTest() : recPtr(new RecordType{13, 13}) { // expected-warning{{1 uninitialized field}}
223 }
224};
225
226void fUninitPointerTest() {
227 UninitPointerTest();
228}
229
230struct CharPointerTest {
231 const char *str;
232 int dontGetFilteredByNonPedanticMode = 0;
233
234 CharPointerTest() : str("") {}
235};
236
237void fCharPointerTest() {
238 CharPointerTest();
239}
240
Kristof Umann64601962018-08-21 10:45:21 +0000241struct CyclicPointerTest1 {
Kristof Umann30f08652018-06-18 11:50:17 +0000242 int *ptr;
Kristof Umann64601962018-08-21 10:45:21 +0000243 CyclicPointerTest1() : ptr(reinterpret_cast<int *>(&ptr)) {}
Kristof Umann30f08652018-06-18 11:50:17 +0000244};
245
Kristof Umann64601962018-08-21 10:45:21 +0000246void fCyclicPointerTest1() {
247 CyclicPointerTest1();
Kristof Umann30f08652018-06-18 11:50:17 +0000248}
249
Kristof Umann64601962018-08-21 10:45:21 +0000250struct CyclicPointerTest2 {
Kristof Umannf0dd1012018-09-14 08:58:21 +0000251 int **pptr; // no-crash
Kristof Umann64601962018-08-21 10:45:21 +0000252 CyclicPointerTest2() : pptr(reinterpret_cast<int **>(&pptr)) {}
253};
254
255void fCyclicPointerTest2() {
256 CyclicPointerTest2();
257}
Kristof Umann64601962018-08-21 10:45:21 +0000258
Kristof Umann30f08652018-06-18 11:50:17 +0000259//===----------------------------------------------------------------------===//
260// Void pointer tests.
261//===----------------------------------------------------------------------===//
262
263// Void pointer tests are mainly no-crash tests.
264
265void *malloc(int size);
266
267class VoidPointerTest1 {
268 void *vptr;
269
270public:
271 VoidPointerTest1(void *vptr, char) : vptr(vptr) {
272 // All good!
273 }
274};
275
276void fVoidPointerTest1() {
277 void *vptr = malloc(sizeof(int));
278 VoidPointerTest1(vptr, char());
279}
280
281class VoidPointerTest2 {
282 void **vpptr;
283
284public:
285 VoidPointerTest2(void **vpptr, char) : vpptr(vpptr) {
286 // All good!
287 }
288};
289
290void fVoidPointerTest2() {
291 void *vptr = malloc(sizeof(int));
292 VoidPointerTest2(&vptr, char());
293}
294
295class VoidPointerRRefTest1 {
Richard Smithca975b22018-07-23 18:50:26 +0000296 void *&&vptrrref; // expected-note {{here}}
Kristof Umann30f08652018-06-18 11:50:17 +0000297
298public:
Richard Smithca975b22018-07-23 18:50:26 +0000299 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 +0000300 // All good!
301 }
302};
303
304void fVoidPointerRRefTest1() {
305 void *vptr = malloc(sizeof(int));
306 VoidPointerRRefTest1(vptr, char());
307}
308
309class VoidPointerRRefTest2 {
Richard Smithca975b22018-07-23 18:50:26 +0000310 void **&&vpptrrref; // expected-note {{here}}
Kristof Umann30f08652018-06-18 11:50:17 +0000311
312public:
Richard Smithca975b22018-07-23 18:50:26 +0000313 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 +0000314 // All good!
315 }
316};
317
318void fVoidPointerRRefTest2() {
319 void *vptr = malloc(sizeof(int));
320 VoidPointerRRefTest2(&vptr, char());
321}
322
323class VoidPointerLRefTest {
Richard Smithca975b22018-07-23 18:50:26 +0000324 void *&vptrrref; // expected-note {{here}}
Kristof Umann30f08652018-06-18 11:50:17 +0000325
326public:
Richard Smithca975b22018-07-23 18:50:26 +0000327 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 +0000328 // All good!
329 }
330};
331
332void fVoidPointerLRefTest() {
333 void *vptr = malloc(sizeof(int));
334 VoidPointerLRefTest(vptr, char());
335}
336
337struct CyclicVoidPointerTest {
338 void *vptr; // no-crash
339
340 CyclicVoidPointerTest() : vptr(&vptr) {}
Kristof Umann30f08652018-06-18 11:50:17 +0000341};
342
343void fCyclicVoidPointerTest() {
344 CyclicVoidPointerTest();
345}
346
Kristof Umannef9af052018-08-08 13:18:53 +0000347struct IntDynTypedVoidPointerTest1 {
Kristof Umann5a424412018-08-14 08:20:51 +0000348 void *vptr; // expected-note{{uninitialized pointee 'static_cast<int *>(this->vptr)'}}
Kristof Umannef9af052018-08-08 13:18:53 +0000349 int dontGetFilteredByNonPedanticMode = 0;
350
351 IntDynTypedVoidPointerTest1(void *vptr) : vptr(vptr) {} // expected-warning{{1 uninitialized field}}
352};
353
354void fIntDynTypedVoidPointerTest1() {
355 int a;
356 IntDynTypedVoidPointerTest1 tmp(&a);
357}
358
359struct RecordDynTypedVoidPointerTest {
360 struct RecordType {
Kristof Umann5a424412018-08-14 08:20:51 +0000361 int x; // expected-note{{uninitialized field 'static_cast<struct RecordDynTypedVoidPointerTest::RecordType *>(this->vptr)->x'}}
362 int y; // expected-note{{uninitialized field 'static_cast<struct RecordDynTypedVoidPointerTest::RecordType *>(this->vptr)->y'}}
Kristof Umannef9af052018-08-08 13:18:53 +0000363 };
364
365 void *vptr;
366 int dontGetFilteredByNonPedanticMode = 0;
367
368 RecordDynTypedVoidPointerTest(void *vptr) : vptr(vptr) {} // expected-warning{{2 uninitialized fields}}
369};
370
371void fRecordDynTypedVoidPointerTest() {
372 RecordDynTypedVoidPointerTest::RecordType a;
373 RecordDynTypedVoidPointerTest tmp(&a);
374}
375
376struct NestedNonVoidDynTypedVoidPointerTest {
377 struct RecordType {
Kristof Umann5a424412018-08-14 08:20:51 +0000378 int x; // expected-note{{uninitialized field 'static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->x'}}
379 int y; // expected-note{{uninitialized field 'static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->y'}}
380 void *vptr; // expected-note{{uninitialized pointee 'static_cast<char *>(static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->vptr)'}}
Kristof Umannef9af052018-08-08 13:18:53 +0000381 };
382
383 void *vptr;
384 int dontGetFilteredByNonPedanticMode = 0;
385
386 NestedNonVoidDynTypedVoidPointerTest(void *vptr, void *c) : vptr(vptr) {
387 static_cast<RecordType *>(vptr)->vptr = c; // expected-warning{{3 uninitialized fields}}
388 }
389};
390
391void fNestedNonVoidDynTypedVoidPointerTest() {
392 NestedNonVoidDynTypedVoidPointerTest::RecordType a;
393 char c;
394 NestedNonVoidDynTypedVoidPointerTest tmp(&a, &c);
395}
396
Kristof Umann30f08652018-06-18 11:50:17 +0000397//===----------------------------------------------------------------------===//
398// Multipointer tests.
399//===----------------------------------------------------------------------===//
400
401#ifdef PEDANTIC
402class MultiPointerTest1 {
403public:
404 struct RecordType {
405 int x;
406 int y;
407 };
408
409private:
410 RecordType **mptr; // expected-note{{uninitialized pointee 'this->mptr'}}
411
412public:
413 MultiPointerTest1(RecordType **p, int) : mptr(p) { // expected-warning{{1 uninitialized field}}
414 }
415};
416
417void fMultiPointerTest1() {
418 MultiPointerTest1::RecordType *p1;
419 MultiPointerTest1::RecordType **mptr = &p1;
420 MultiPointerTest1(mptr, int()); // '*mptr' uninitialized
421}
422#else
423class MultiPointerTest1 {
424public:
425 struct RecordType {
426 int x;
427 int y;
428 };
429
430private:
431 RecordType **mptr;
432
433public:
434 MultiPointerTest1(RecordType **p, int) : mptr(p) {}
435};
436
437void fMultiPointerTest1() {
438 MultiPointerTest1::RecordType *p1;
439 MultiPointerTest1::RecordType **mptr = &p1;
440 MultiPointerTest1(mptr, int()); // '*mptr' uninitialized
441}
442#endif // PEDANTIC
443
444#ifdef PEDANTIC
445class MultiPointerTest2 {
446public:
447 struct RecordType {
448 int x; // expected-note{{uninitialized field 'this->mptr->x'}}
449 int y; // expected-note{{uninitialized field 'this->mptr->y'}}
450 };
451
452private:
453 RecordType **mptr;
454
455public:
456 MultiPointerTest2(RecordType **p, int) : mptr(p) { // expected-warning{{2 uninitialized fields}}
457 }
458};
459
460void fMultiPointerTest2() {
461 MultiPointerTest2::RecordType i;
462 MultiPointerTest2::RecordType *p1 = &i;
463 MultiPointerTest2::RecordType **mptr = &p1;
464 MultiPointerTest2(mptr, int()); // '**mptr' uninitialized
465}
466#else
467class MultiPointerTest2 {
468public:
469 struct RecordType {
470 int x;
471 int y;
472 };
473
474private:
475 RecordType **mptr;
476
477public:
478 MultiPointerTest2(RecordType **p, int) : mptr(p) {
479 }
480};
481
482void fMultiPointerTest2() {
483 MultiPointerTest2::RecordType i;
484 MultiPointerTest2::RecordType *p1 = &i;
485 MultiPointerTest2::RecordType **mptr = &p1;
486 MultiPointerTest2(mptr, int()); // '**mptr' uninitialized
487}
488#endif // PEDANTIC
489
490class MultiPointerTest3 {
491public:
492 struct RecordType {
493 int x;
494 int y;
495 };
496
497private:
498 RecordType **mptr;
499
500public:
501 MultiPointerTest3(RecordType **p, int) : mptr(p) {
502 // All good!
503 }
504};
505
506void fMultiPointerTest3() {
507 MultiPointerTest3::RecordType i{31, 32};
508 MultiPointerTest3::RecordType *p1 = &i;
509 MultiPointerTest3::RecordType **mptr = &p1;
510 MultiPointerTest3(mptr, int()); // '**mptr' uninitialized
511}
512
513//===----------------------------------------------------------------------===//
Kristof Umannf0dd1012018-09-14 08:58:21 +0000514// Incomplete pointee tests.
515//===----------------------------------------------------------------------===//
516
517class IncompleteType;
518
519struct IncompletePointeeTypeTest {
520 IncompleteType *pImpl; //no-crash
521 int dontGetFilteredByNonPedanticMode = 0;
522
523 IncompletePointeeTypeTest(IncompleteType *A) : pImpl(A) {}
524};
525
526void fIncompletePointeeTypeTest(void *ptr) {
527 IncompletePointeeTypeTest(reinterpret_cast<IncompleteType *>(ptr));
528}
529
530//===----------------------------------------------------------------------===//
531// Function pointer tests.
532//===----------------------------------------------------------------------===//
533
534struct FunctionPointerWithDifferentDynTypeTest {
535 using Func1 = void *(*)();
536 using Func2 = int *(*)();
537
538 Func1 f; // no-crash
539 FunctionPointerWithDifferentDynTypeTest(Func2 f) : f((Func1)f) {}
540};
541
542// Note that there isn't a function calling the constructor of
543// FunctionPointerWithDifferentDynTypeTest, because a crash could only be
544// reproduced without it.
545
546//===----------------------------------------------------------------------===//
Kristof Umann30f08652018-06-18 11:50:17 +0000547// Member pointer tests.
548//===----------------------------------------------------------------------===//
549
550struct UsefulFunctions {
551 int a, b;
552
553 void print() {}
554 void dump() {}
555};
556
557#ifdef PEDANTIC
558struct PointerToMemberFunctionTest1 {
Kristof Umann7212cc02018-07-13 12:21:38 +0000559 void (UsefulFunctions::*f)(void); // expected-note{{uninitialized field 'this->f'}}
Kristof Umann30f08652018-06-18 11:50:17 +0000560 PointerToMemberFunctionTest1() {}
561};
562
563void fPointerToMemberFunctionTest1() {
Kristof Umann7212cc02018-07-13 12:21:38 +0000564 PointerToMemberFunctionTest1(); // expected-warning{{1 uninitialized field}}
Kristof Umann30f08652018-06-18 11:50:17 +0000565}
566
567struct PointerToMemberFunctionTest2 {
568 void (UsefulFunctions::*f)(void);
569 PointerToMemberFunctionTest2(void (UsefulFunctions::*f)(void)) : f(f) {
570 // All good!
571 }
572};
573
574void fPointerToMemberFunctionTest2() {
575 void (UsefulFunctions::*f)(void) = &UsefulFunctions::print;
576 PointerToMemberFunctionTest2 a(f);
577}
578
579struct MultiPointerToMemberFunctionTest1 {
580 void (UsefulFunctions::**f)(void); // expected-note{{uninitialized pointer 'this->f'}}
581 MultiPointerToMemberFunctionTest1() {}
582};
583
584void fMultiPointerToMemberFunctionTest1() {
585 MultiPointerToMemberFunctionTest1(); // expected-warning{{1 uninitialized field}}
586}
587
588struct MultiPointerToMemberFunctionTest2 {
589 void (UsefulFunctions::**f)(void);
590 MultiPointerToMemberFunctionTest2(void (UsefulFunctions::**f)(void)) : f(f) {
591 // All good!
592 }
593};
594
595void fMultiPointerToMemberFunctionTest2() {
596 void (UsefulFunctions::*f)(void) = &UsefulFunctions::print;
597 MultiPointerToMemberFunctionTest2 a(&f);
598}
599
600struct PointerToMemberDataTest1 {
Kristof Umann7212cc02018-07-13 12:21:38 +0000601 int UsefulFunctions::*d; // expected-note{{uninitialized field 'this->d'}}
Kristof Umann30f08652018-06-18 11:50:17 +0000602 PointerToMemberDataTest1() {}
603};
604
605void fPointerToMemberDataTest1() {
Kristof Umann7212cc02018-07-13 12:21:38 +0000606 PointerToMemberDataTest1(); // expected-warning{{1 uninitialized field}}
Kristof Umann30f08652018-06-18 11:50:17 +0000607}
608
609struct PointerToMemberDataTest2 {
610 int UsefulFunctions::*d;
611 PointerToMemberDataTest2(int UsefulFunctions::*d) : d(d) {
612 // All good!
613 }
614};
615
616void fPointerToMemberDataTest2() {
617 int UsefulFunctions::*d = &UsefulFunctions::a;
618 PointerToMemberDataTest2 a(d);
619}
620
621struct MultiPointerToMemberDataTest1 {
622 int UsefulFunctions::**d; // expected-note{{uninitialized pointer 'this->d'}}
623 MultiPointerToMemberDataTest1() {}
624};
625
626void fMultiPointerToMemberDataTest1() {
627 MultiPointerToMemberDataTest1(); // expected-warning{{1 uninitialized field}}
628}
629
630struct MultiPointerToMemberDataTest2 {
631 int UsefulFunctions::**d;
632 MultiPointerToMemberDataTest2(int UsefulFunctions::**d) : d(d) {
633 // All good!
634 }
635};
636
637void fMultiPointerToMemberDataTest2() {
638 int UsefulFunctions::*d = &UsefulFunctions::a;
639 MultiPointerToMemberDataTest2 a(&d);
640}
641#endif // PEDANTIC
642
643//===----------------------------------------------------------------------===//
644// Tests for list-like records.
645//===----------------------------------------------------------------------===//
646
647class ListTest1 {
648public:
649 struct Node {
650 Node *next = nullptr; // no crash
651 int i;
652 };
653
654private:
655 Node *head = nullptr;
656
657public:
658 ListTest1() {
659 // All good!
660 }
661};
662
663void fListTest1() {
664 ListTest1();
665}
666
667class ListTest2 {
668public:
669 struct Node {
670 Node *next = nullptr;
671 int i; // expected-note{{uninitialized field 'this->head->i'}}
672 };
673
674private:
675 Node *head = nullptr;
676
677public:
678 ListTest2(Node *node, int) : head(node) { // expected-warning{{1 uninitialized field}}
679 }
680};
681
682void fListTest2() {
683 ListTest2::Node n;
684 ListTest2(&n, int());
685}
686
687class CyclicList {
688public:
689 struct Node {
690 Node *next = nullptr;
691 int i; // expected-note{{uninitialized field 'this->head->i'}}
692 };
693
694private:
695 Node *head = nullptr;
696
697public:
698 CyclicList(Node *node, int) : head(node) { // expected-warning{{1 uninitialized field}}
699 }
700};
701
702void fCyclicList() {
703 /*
704 n3
705 / \
706 this -- n1 -- n2
707 */
708
709 CyclicList::Node n1;
710 CyclicList::Node n2;
711 n2.next = &n1;
712 n2.i = 50;
713 CyclicList::Node n3;
714 n3.next = &n2;
715 n3.i = 50;
716 n1.next = &n3;
717 // note that n1.i is uninitialized
718 CyclicList(&n1, int());
719}
720
Kristof Umannf0dd1012018-09-14 08:58:21 +0000721struct RingListTest {
722 RingListTest *next; // no-crash
723 RingListTest() : next(this) {}
724};
725
726void fRingListTest() {
727 RingListTest();
728}
729
Kristof Umann30f08652018-06-18 11:50:17 +0000730//===----------------------------------------------------------------------===//
731// Tests for classes containing references.
732//===----------------------------------------------------------------------===//
733
734class ReferenceTest1 {
735public:
736 struct RecordType {
737 int x;
738 int y;
739 };
740
741private:
742 RecordType &lref;
743 RecordType &&rref;
744
745public:
746 ReferenceTest1(RecordType &lref, RecordType &rref) : lref(lref), rref(static_cast<RecordType &&>(rref)) {
747 // All good!
748 }
749};
750
751void fReferenceTest1() {
752 ReferenceTest1::RecordType d{33, 34};
753 ReferenceTest1(d, d);
754}
755
756#ifdef PEDANTIC
757class ReferenceTest2 {
758public:
759 struct RecordType {
760 int x; // expected-note{{uninitialized field 'this->lref.x'}}
761 int y; // expected-note{{uninitialized field 'this->lref.y'}}
762 };
763
764private:
765 RecordType &lref;
766 RecordType &&rref;
767
768public:
769 ReferenceTest2(RecordType &lref, RecordType &rref)
770 : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}}
771 }
772};
773
774void fReferenceTest2() {
775 ReferenceTest2::RecordType c;
776 ReferenceTest2(c, c);
777}
778#else
779class ReferenceTest2 {
780public:
781 struct RecordType {
782 int x;
783 int y;
784 };
785
786private:
787 RecordType &lref;
788 RecordType &&rref;
789
790public:
791 ReferenceTest2(RecordType &lref, RecordType &rref)
792 : lref(lref), rref(static_cast<RecordType &&>(rref)) {
793 }
794};
795
796void fReferenceTest2() {
797 ReferenceTest2::RecordType c;
798 ReferenceTest2(c, c);
799}
800#endif // PEDANTIC
801
802class ReferenceTest3 {
803public:
804 struct RecordType {
805 int x; // expected-note{{uninitialized field 'this->lref.x'}}
806 int y; // expected-note{{uninitialized field 'this->lref.y'}}
807 };
808
809private:
810 RecordType &lref;
811 RecordType &&rref;
812
813public:
814 ReferenceTest3(RecordType &lref, RecordType &rref)
815 : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}}
816 }
817};
818
819void fReferenceTest3() {
820 ReferenceTest3::RecordType c, d{35, 36};
821 ReferenceTest3(c, d);
822}
823
824class ReferenceTest4 {
825public:
826 struct RecordType {
827 int x; // expected-note{{uninitialized field 'this->rref.x'}}
828 int y; // expected-note{{uninitialized field 'this->rref.y'}}
829 };
830
831private:
832 RecordType &lref;
833 RecordType &&rref;
834
835public:
836 ReferenceTest4(RecordType &lref, RecordType &rref)
837 : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}}
838 }
839};
840
841void fReferenceTest5() {
842 ReferenceTest4::RecordType c, d{37, 38};
843 ReferenceTest4(d, c);
844}