]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
Vendor import of clang trunk r338150:
[FreeBSD/FreeBSD.git] / test / Analysis / cxx-uninitialized-object-ptr-ref.cpp
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -std=c++11 -DPEDANTIC -verify %s
2
3 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject -std=c++11 -verify %s
4
5 //===----------------------------------------------------------------------===//
6 // Concrete location tests.
7 //===----------------------------------------------------------------------===//
8
9 struct ConcreteIntLocTest {
10   int *ptr;
11
12   ConcreteIntLocTest() : ptr(reinterpret_cast<int *>(0xDEADBEEF)) {}
13 };
14
15 void fConcreteIntLocTest() {
16   ConcreteIntLocTest();
17 }
18
19 //===----------------------------------------------------------------------===//
20 // Null pointer tests.
21 //===----------------------------------------------------------------------===//
22
23 class NullPtrTest {
24   struct RecordType {
25     int x;
26     int y;
27   };
28
29   float *fptr = nullptr;
30   int *ptr;
31   RecordType *recPtr;
32
33 public:
34   NullPtrTest() : ptr(nullptr), recPtr(nullptr) {
35     // All good!
36   }
37 };
38
39 void fNullPtrTest() {
40   NullPtrTest();
41 }
42
43 //===----------------------------------------------------------------------===//
44 // Heap pointer tests.
45 //===----------------------------------------------------------------------===//
46
47 class HeapPointerTest1 {
48   struct RecordType {
49     // TODO: we'd expect the note: {{uninitialized field 'this->recPtr->y'}}
50     int x; // no-note
51     // TODO: we'd expect the note: {{uninitialized field 'this->recPtr->y'}}
52     int y; // no-note
53   };
54   // TODO: we'd expect the note: {{uninitialized pointee 'this->fptr'}}
55   float *fptr = new float; // no-note
56   // TODO: we'd expect the note: {{uninitialized pointee 'this->ptr'}}
57   int *ptr; // no-note
58   RecordType *recPtr;
59
60 public:
61   // TODO: we'd expect the warning: {{4 uninitialized fields}}
62   HeapPointerTest1() : ptr(new int), recPtr(new RecordType) { // no-note
63   }
64 };
65
66 void fHeapPointerTest1() {
67   HeapPointerTest1();
68 }
69
70 class HeapPointerTest2 {
71   struct RecordType {
72     int x;
73     int y;
74   };
75
76   float *fptr = new float(); // initializes to 0
77   int *ptr;
78   RecordType *recPtr;
79
80 public:
81   HeapPointerTest2() : ptr(new int{25}), recPtr(new RecordType{26, 27}) {
82     // All good!
83   }
84 };
85
86 void fHeapPointerTest2() {
87   HeapPointerTest2();
88 }
89
90 //===----------------------------------------------------------------------===//
91 // Stack pointer tests.
92 //===----------------------------------------------------------------------===//
93
94 class StackPointerTest1 {
95 public:
96   struct RecordType {
97     int x;
98     int y;
99   };
100
101 private:
102   int *ptr;
103   RecordType *recPtr;
104
105 public:
106   StackPointerTest1(int *_ptr, StackPointerTest1::RecordType *_recPtr) : ptr(_ptr), recPtr(_recPtr) {
107     // All good!
108   }
109 };
110
111 void fStackPointerTest1() {
112   int ok_a = 28;
113   StackPointerTest1::RecordType ok_rec{29, 30};
114   StackPointerTest1(&ok_a, &ok_rec); // 'a', 'rec.x', 'rec.y' uninitialized
115 }
116
117 #ifdef PEDANTIC
118 class StackPointerTest2 {
119 public:
120   struct RecordType {
121     int x; // expected-note{{uninitialized field 'this->recPtr->x'}}
122     int y; // expected-note{{uninitialized field 'this->recPtr->y'}}
123   };
124
125 private:
126   int *ptr; // expected-note{{uninitialized pointee 'this->ptr'}}
127   RecordType *recPtr;
128
129 public:
130   StackPointerTest2(int *_ptr, RecordType *_recPtr) : ptr(_ptr), recPtr(_recPtr) { // expected-warning{{3 uninitialized fields}}
131   }
132 };
133
134 void fStackPointerTest2() {
135   int a;
136   StackPointerTest2::RecordType rec;
137   StackPointerTest2(&a, &rec); // 'a', 'rec.x', 'rec.y' uninitialized
138 }
139 #else
140 class StackPointerTest2 {
141 public:
142   struct RecordType {
143     int x;
144     int y;
145   };
146
147 private:
148   int *ptr;
149   RecordType *recPtr;
150
151 public:
152   StackPointerTest2(int *_ptr, RecordType *_recPtr) : ptr(_ptr), recPtr(_recPtr) {
153   }
154 };
155
156 void fStackPointerTest2() {
157   int a;
158   StackPointerTest2::RecordType rec;
159   StackPointerTest2(&a, &rec); // 'a', 'rec.x', 'rec.y' uninitialized
160 }
161 #endif // PEDANTIC
162
163 class UninitPointerTest {
164   struct RecordType {
165     int x;
166     int y;
167   };
168
169   int *ptr; // expected-note{{uninitialized pointer 'this->ptr'}}
170   RecordType *recPtr;
171
172 public:
173   UninitPointerTest() : recPtr(new RecordType{13, 13}) { // expected-warning{{1 uninitialized field}}
174   }
175 };
176
177 void fUninitPointerTest() {
178   UninitPointerTest();
179 }
180
181 struct CharPointerTest {
182   const char *str;
183   int dontGetFilteredByNonPedanticMode = 0;
184
185   CharPointerTest() : str("") {}
186 };
187
188 void fCharPointerTest() {
189   CharPointerTest();
190 }
191
192 struct CyclicPointerTest {
193   int *ptr;
194   CyclicPointerTest() : ptr(reinterpret_cast<int*>(&ptr)) {}
195 };
196
197 void fCyclicPointerTest() {
198   CyclicPointerTest();
199 }
200
201 //===----------------------------------------------------------------------===//
202 // Void pointer tests.
203 //===----------------------------------------------------------------------===//
204
205 // Void pointer tests are mainly no-crash tests.
206
207 void *malloc(int size);
208
209 class VoidPointerTest1 {
210   void *vptr;
211
212 public:
213   VoidPointerTest1(void *vptr, char) : vptr(vptr) {
214     // All good!
215   }
216 };
217
218 void fVoidPointerTest1() {
219   void *vptr = malloc(sizeof(int));
220   VoidPointerTest1(vptr, char());
221 }
222
223 class VoidPointerTest2 {
224   void **vpptr;
225
226 public:
227   VoidPointerTest2(void **vpptr, char) : vpptr(vpptr) {
228     // All good!
229   }
230 };
231
232 void fVoidPointerTest2() {
233   void *vptr = malloc(sizeof(int));
234   VoidPointerTest2(&vptr, char());
235 }
236
237 class VoidPointerRRefTest1 {
238   void *&&vptrrref; // expected-note {{here}}
239
240 public:
241   VoidPointerRRefTest1(void *vptr, char) : vptrrref(static_cast<void *&&>(vptr)) { // expected-warning {{binding reference member 'vptrrref' to stack allocated parameter 'vptr'}}
242     // All good!
243   }
244 };
245
246 void fVoidPointerRRefTest1() {
247   void *vptr = malloc(sizeof(int));
248   VoidPointerRRefTest1(vptr, char());
249 }
250
251 class VoidPointerRRefTest2 {
252   void **&&vpptrrref; // expected-note {{here}}
253
254 public:
255   VoidPointerRRefTest2(void **vptr, char) : vpptrrref(static_cast<void **&&>(vptr)) { // expected-warning {{binding reference member 'vpptrrref' to stack allocated parameter 'vptr'}}
256     // All good!
257   }
258 };
259
260 void fVoidPointerRRefTest2() {
261   void *vptr = malloc(sizeof(int));
262   VoidPointerRRefTest2(&vptr, char());
263 }
264
265 class VoidPointerLRefTest {
266   void *&vptrrref; // expected-note {{here}}
267
268 public:
269   VoidPointerLRefTest(void *vptr, char) : vptrrref(static_cast<void *&>(vptr)) { // expected-warning {{binding reference member 'vptrrref' to stack allocated parameter 'vptr'}}
270     // All good!
271   }
272 };
273
274 void fVoidPointerLRefTest() {
275   void *vptr = malloc(sizeof(int));
276   VoidPointerLRefTest(vptr, char());
277 }
278
279 struct CyclicVoidPointerTest {
280   void *vptr; // no-crash
281
282   CyclicVoidPointerTest() : vptr(&vptr) {}
283
284 };
285
286 void fCyclicVoidPointerTest() {
287   CyclicVoidPointerTest();
288 }
289
290 //===----------------------------------------------------------------------===//
291 // Multipointer tests.
292 //===----------------------------------------------------------------------===//
293
294 #ifdef PEDANTIC
295 class MultiPointerTest1 {
296 public:
297   struct RecordType {
298     int x;
299     int y;
300   };
301
302 private:
303   RecordType **mptr; // expected-note{{uninitialized pointee 'this->mptr'}}
304
305 public:
306   MultiPointerTest1(RecordType **p, int) : mptr(p) { // expected-warning{{1 uninitialized field}}
307   }
308 };
309
310 void fMultiPointerTest1() {
311   MultiPointerTest1::RecordType *p1;
312   MultiPointerTest1::RecordType **mptr = &p1;
313   MultiPointerTest1(mptr, int()); // '*mptr' uninitialized
314 }
315 #else
316 class MultiPointerTest1 {
317 public:
318   struct RecordType {
319     int x;
320     int y;
321   };
322
323 private:
324   RecordType **mptr;
325
326 public:
327   MultiPointerTest1(RecordType **p, int) : mptr(p) {}
328 };
329
330 void fMultiPointerTest1() {
331   MultiPointerTest1::RecordType *p1;
332   MultiPointerTest1::RecordType **mptr = &p1;
333   MultiPointerTest1(mptr, int()); // '*mptr' uninitialized
334 }
335 #endif // PEDANTIC
336
337 #ifdef PEDANTIC
338 class MultiPointerTest2 {
339 public:
340   struct RecordType {
341     int x; // expected-note{{uninitialized field 'this->mptr->x'}}
342     int y; // expected-note{{uninitialized field 'this->mptr->y'}}
343   };
344
345 private:
346   RecordType **mptr;
347
348 public:
349   MultiPointerTest2(RecordType **p, int) : mptr(p) { // expected-warning{{2 uninitialized fields}}
350   }
351 };
352
353 void fMultiPointerTest2() {
354   MultiPointerTest2::RecordType i;
355   MultiPointerTest2::RecordType *p1 = &i;
356   MultiPointerTest2::RecordType **mptr = &p1;
357   MultiPointerTest2(mptr, int()); // '**mptr' uninitialized
358 }
359 #else
360 class MultiPointerTest2 {
361 public:
362   struct RecordType {
363     int x;
364     int y;
365   };
366
367 private:
368   RecordType **mptr;
369
370 public:
371   MultiPointerTest2(RecordType **p, int) : mptr(p) {
372   }
373 };
374
375 void fMultiPointerTest2() {
376   MultiPointerTest2::RecordType i;
377   MultiPointerTest2::RecordType *p1 = &i;
378   MultiPointerTest2::RecordType **mptr = &p1;
379   MultiPointerTest2(mptr, int()); // '**mptr' uninitialized
380 }
381 #endif // PEDANTIC
382
383 class MultiPointerTest3 {
384 public:
385   struct RecordType {
386     int x;
387     int y;
388   };
389
390 private:
391   RecordType **mptr;
392
393 public:
394   MultiPointerTest3(RecordType **p, int) : mptr(p) {
395     // All good!
396   }
397 };
398
399 void fMultiPointerTest3() {
400   MultiPointerTest3::RecordType i{31, 32};
401   MultiPointerTest3::RecordType *p1 = &i;
402   MultiPointerTest3::RecordType **mptr = &p1;
403   MultiPointerTest3(mptr, int()); // '**mptr' uninitialized
404 }
405
406 //===----------------------------------------------------------------------===//
407 // Member pointer tests.
408 //===----------------------------------------------------------------------===//
409
410 struct UsefulFunctions {
411   int a, b;
412
413   void print() {}
414   void dump() {}
415 };
416
417 #ifdef PEDANTIC
418 struct PointerToMemberFunctionTest1 {
419   void (UsefulFunctions::*f)(void); // expected-note{{uninitialized field 'this->f'}}
420   PointerToMemberFunctionTest1() {}
421 };
422
423 void fPointerToMemberFunctionTest1() {
424   PointerToMemberFunctionTest1(); // expected-warning{{1 uninitialized field}}
425 }
426
427 struct PointerToMemberFunctionTest2 {
428   void (UsefulFunctions::*f)(void);
429   PointerToMemberFunctionTest2(void (UsefulFunctions::*f)(void)) : f(f) {
430     // All good!
431   }
432 };
433
434 void fPointerToMemberFunctionTest2() {
435   void (UsefulFunctions::*f)(void) = &UsefulFunctions::print;
436   PointerToMemberFunctionTest2 a(f);
437 }
438
439 struct MultiPointerToMemberFunctionTest1 {
440   void (UsefulFunctions::**f)(void); // expected-note{{uninitialized pointer 'this->f'}}
441   MultiPointerToMemberFunctionTest1() {}
442 };
443
444 void fMultiPointerToMemberFunctionTest1() {
445   MultiPointerToMemberFunctionTest1(); // expected-warning{{1 uninitialized field}}
446 }
447
448 struct MultiPointerToMemberFunctionTest2 {
449   void (UsefulFunctions::**f)(void);
450   MultiPointerToMemberFunctionTest2(void (UsefulFunctions::**f)(void)) : f(f) {
451     // All good!
452   }
453 };
454
455 void fMultiPointerToMemberFunctionTest2() {
456   void (UsefulFunctions::*f)(void) = &UsefulFunctions::print;
457   MultiPointerToMemberFunctionTest2 a(&f);
458 }
459
460 struct PointerToMemberDataTest1 {
461   int UsefulFunctions::*d; // expected-note{{uninitialized field 'this->d'}}
462   PointerToMemberDataTest1() {}
463 };
464
465 void fPointerToMemberDataTest1() {
466   PointerToMemberDataTest1(); // expected-warning{{1 uninitialized field}}
467 }
468
469 struct PointerToMemberDataTest2 {
470   int UsefulFunctions::*d;
471   PointerToMemberDataTest2(int UsefulFunctions::*d) : d(d) {
472     // All good!
473   }
474 };
475
476 void fPointerToMemberDataTest2() {
477   int UsefulFunctions::*d = &UsefulFunctions::a;
478   PointerToMemberDataTest2 a(d);
479 }
480
481 struct MultiPointerToMemberDataTest1 {
482   int UsefulFunctions::**d; // expected-note{{uninitialized pointer 'this->d'}}
483   MultiPointerToMemberDataTest1() {}
484 };
485
486 void fMultiPointerToMemberDataTest1() {
487   MultiPointerToMemberDataTest1(); // expected-warning{{1 uninitialized field}}
488 }
489
490 struct MultiPointerToMemberDataTest2 {
491   int UsefulFunctions::**d;
492   MultiPointerToMemberDataTest2(int UsefulFunctions::**d) : d(d) {
493     // All good!
494   }
495 };
496
497 void fMultiPointerToMemberDataTest2() {
498   int UsefulFunctions::*d = &UsefulFunctions::a;
499   MultiPointerToMemberDataTest2 a(&d);
500 }
501 #endif // PEDANTIC
502
503 //===----------------------------------------------------------------------===//
504 // Tests for list-like records.
505 //===----------------------------------------------------------------------===//
506
507 class ListTest1 {
508 public:
509   struct Node {
510     Node *next = nullptr; // no crash
511     int i;
512   };
513
514 private:
515   Node *head = nullptr;
516
517 public:
518   ListTest1() {
519     // All good!
520   }
521 };
522
523 void fListTest1() {
524   ListTest1();
525 }
526
527 class ListTest2 {
528 public:
529   struct Node {
530     Node *next = nullptr;
531     int i; // expected-note{{uninitialized field 'this->head->i'}}
532   };
533
534 private:
535   Node *head = nullptr;
536
537 public:
538   ListTest2(Node *node, int) : head(node) { // expected-warning{{1 uninitialized field}}
539   }
540 };
541
542 void fListTest2() {
543   ListTest2::Node n;
544   ListTest2(&n, int());
545 }
546
547 class CyclicList {
548 public:
549   struct Node {
550     Node *next = nullptr;
551     int i; // expected-note{{uninitialized field 'this->head->i'}}
552   };
553
554 private:
555   Node *head = nullptr;
556
557 public:
558   CyclicList(Node *node, int) : head(node) { // expected-warning{{1 uninitialized field}}
559   }
560 };
561
562 void fCyclicList() {
563   /*
564                n3
565               /  \
566     this -- n1 -- n2
567   */
568
569   CyclicList::Node n1;
570   CyclicList::Node n2;
571   n2.next = &n1;
572   n2.i = 50;
573   CyclicList::Node n3;
574   n3.next = &n2;
575   n3.i = 50;
576   n1.next = &n3;
577   // note that n1.i is uninitialized
578   CyclicList(&n1, int());
579 }
580
581 //===----------------------------------------------------------------------===//
582 // Tests for classes containing references.
583 //===----------------------------------------------------------------------===//
584
585 class ReferenceTest1 {
586 public:
587   struct RecordType {
588     int x;
589     int y;
590   };
591
592 private:
593   RecordType &lref;
594   RecordType &&rref;
595
596 public:
597   ReferenceTest1(RecordType &lref, RecordType &rref) : lref(lref), rref(static_cast<RecordType &&>(rref)) {
598     // All good!
599   }
600 };
601
602 void fReferenceTest1() {
603   ReferenceTest1::RecordType d{33, 34};
604   ReferenceTest1(d, d);
605 }
606
607 #ifdef PEDANTIC
608 class ReferenceTest2 {
609 public:
610   struct RecordType {
611     int x; // expected-note{{uninitialized field 'this->lref.x'}}
612     int y; // expected-note{{uninitialized field 'this->lref.y'}}
613   };
614
615 private:
616   RecordType &lref;
617   RecordType &&rref;
618
619 public:
620   ReferenceTest2(RecordType &lref, RecordType &rref)
621       : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}}
622   }
623 };
624
625 void fReferenceTest2() {
626   ReferenceTest2::RecordType c;
627   ReferenceTest2(c, c);
628 }
629 #else
630 class ReferenceTest2 {
631 public:
632   struct RecordType {
633     int x;
634     int y;
635   };
636
637 private:
638   RecordType &lref;
639   RecordType &&rref;
640
641 public:
642   ReferenceTest2(RecordType &lref, RecordType &rref)
643       : lref(lref), rref(static_cast<RecordType &&>(rref)) {
644   }
645 };
646
647 void fReferenceTest2() {
648   ReferenceTest2::RecordType c;
649   ReferenceTest2(c, c);
650 }
651 #endif // PEDANTIC
652
653 class ReferenceTest3 {
654 public:
655   struct RecordType {
656     int x; // expected-note{{uninitialized field 'this->lref.x'}}
657     int y; // expected-note{{uninitialized field 'this->lref.y'}}
658   };
659
660 private:
661   RecordType &lref;
662   RecordType &&rref;
663
664 public:
665   ReferenceTest3(RecordType &lref, RecordType &rref)
666       : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}}
667   }
668 };
669
670 void fReferenceTest3() {
671   ReferenceTest3::RecordType c, d{35, 36};
672   ReferenceTest3(c, d);
673 }
674
675 class ReferenceTest4 {
676 public:
677   struct RecordType {
678     int x; // expected-note{{uninitialized field 'this->rref.x'}}
679     int y; // expected-note{{uninitialized field 'this->rref.y'}}
680   };
681
682 private:
683   RecordType &lref;
684   RecordType &&rref;
685
686 public:
687   ReferenceTest4(RecordType &lref, RecordType &rref)
688       : lref(lref), rref(static_cast<RecordType &&>(rref)) { // expected-warning{{2 uninitialized fields}}
689   }
690 };
691
692 void fReferenceTest5() {
693   ReferenceTest4::RecordType c, d{37, 38};
694   ReferenceTest4(d, c);
695 }