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