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