Clang Project

clang_source_code/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
1// 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
5
6// 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
9
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// nonloc::LocAsInteger tests.
26//===----------------------------------------------------------------------===//
27
28using intptr_t = unsigned long 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//===----------------------------------------------------------------------===//
43// 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//===----------------------------------------------------------------------===//
67// 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//===----------------------------------------------------------------------===//
111// 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
259struct CyclicPointerTest1 {
260  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}}
264};
265
266void fCyclicPointerTest1() {
267  CyclicPointerTest1();
268}
269
270struct CyclicPointerTest2 {
271  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}}
275};
276
277void fCyclicPointerTest2() {
278  CyclicPointerTest2();
279}
280
281//===----------------------------------------------------------------------===//
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 {
318  void *&&vptrrref; // expected-note {{here}}
319
320public:
321  VoidPointerRRefTest1(void *vptr, char) : vptrrref(static_cast<void *&&>(vptr)) { // expected-warning {{binding reference member 'vptrrref' to stack allocated parameter 'vptr'}}
322    // All good!
323  }
324};
325
326void fVoidPointerRRefTest1() {
327  void *vptr = malloc(sizeof(int));
328  VoidPointerRRefTest1(vptr, char());
329}
330
331class VoidPointerRRefTest2 {
332  void **&&vpptrrref; // expected-note {{here}}
333
334public:
335  VoidPointerRRefTest2(void **vptr, char) : vpptrrref(static_cast<void **&&>(vptr)) { // expected-warning {{binding reference member 'vpptrrref' to stack allocated parameter 'vptr'}}
336    // All good!
337  }
338};
339
340void fVoidPointerRRefTest2() {
341  void *vptr = malloc(sizeof(int));
342  VoidPointerRRefTest2(&vptr, char());
343}
344
345class VoidPointerLRefTest {
346  void *&vptrrref; // expected-note {{here}}
347
348public:
349  VoidPointerLRefTest(void *vptr, char) : vptrrref(static_cast<void *&>(vptr)) { // expected-warning {{binding reference member 'vptrrref' to stack allocated parameter 'vptr'}}
350    // All good!
351  }
352};
353
354void fVoidPointerLRefTest() {
355  void *vptr = malloc(sizeof(int));
356  VoidPointerLRefTest(vptr, char());
357}
358
359struct CyclicVoidPointerTest {
360  void *vptr; // expected-note{{object references itself 'this->vptr'}}
361  int dontGetFilteredByNonPedanticMode = 0;
362
363  CyclicVoidPointerTest() : vptr(&vptr) {} // expected-warning{{1 uninitialized field}}
364};
365
366void fCyclicVoidPointerTest() {
367  CyclicVoidPointerTest();
368}
369
370struct IntDynTypedVoidPointerTest1 {
371  void *vptr; // expected-note{{uninitialized pointee 'static_cast<int *>(this->vptr)'}}
372  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 {
384    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'}}
386  };
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 {
401    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)'}}
404  };
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
420//===----------------------------------------------------------------------===//
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//===----------------------------------------------------------------------===//
537// 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//===----------------------------------------------------------------------===//
570// 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 {
582  void (UsefulFunctions::*f)(void); // expected-note{{uninitialized field 'this->f'}}
583  PointerToMemberFunctionTest1() {}
584};
585
586void fPointerToMemberFunctionTest1() {
587  PointerToMemberFunctionTest1(); // expected-warning{{1 uninitialized field}}
588}
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 {
624  int UsefulFunctions::*d; // expected-note{{uninitialized field 'this->d'}}
625  PointerToMemberDataTest1() {}
626};
627
628void fPointerToMemberDataTest1() {
629  PointerToMemberDataTest1(); // expected-warning{{1 uninitialized field}}
630}
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
744struct RingListTest {
745  RingListTest *next; // no-crash
746  RingListTest() : next(this) {}
747};
748
749void fRingListTest() {
750  RingListTest();
751}
752
753//===----------------------------------------------------------------------===//
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}
868
869//===----------------------------------------------------------------------===//
870// Tests for objects containing multiple references to the same object.
871//===----------------------------------------------------------------------===//
872
873struct IntMultipleReferenceToSameObjectTest {
874  int *iptr; // expected-note{{uninitialized pointee 'this->iptr'}}
875  int &iref; // no-note, pointee of this->iref was already reported
876
877  int dontGetFilteredByNonPedanticMode = 0;
878
879  IntMultipleReferenceToSameObjectTest(int *i) : iptr(i), iref(*i) {} // expected-warning{{1 uninitialized field}}
880};
881
882void fIntMultipleReferenceToSameObjectTest() {
883  int a;
884  IntMultipleReferenceToSameObjectTest Test(&a);
885}
886
887struct IntReferenceWrapper1 {
888  int &a; // expected-note{{uninitialized pointee 'this->a'}}
889
890  int dontGetFilteredByNonPedanticMode = 0;
891
892  IntReferenceWrapper1(int &a) : a(a) {} // expected-warning{{1 uninitialized field}}
893};
894
895struct IntReferenceWrapper2 {
896  int &a; // no-note, pointee of this->a was already reported
897
898  int dontGetFilteredByNonPedanticMode = 0;
899
900  IntReferenceWrapper2(int &a) : a(a) {} // no-warning
901};
902
903void fMultipleObjectsReferencingTheSameObjectTest() {
904  int a;
905
906  IntReferenceWrapper1 T1(a);
907  IntReferenceWrapper2 T2(a);
908}
909