1 // RUN: %clang_analyze_cc1 -x c++ -analyzer-checker=core -analyzer-output=text -verify %s
2 
3 int initializer1(int &p, int x) {
4   if (x) { // expected-note{{Taking false branch}}
5     p = 1;
6     return 0;
7   } else {
8     return 1; // expected-note {{Returning without writing to 'p'}}
9   }
10 }
11 
12 int param_not_initialized_by_func() {
13   int p;                        // expected-note {{'p' declared without an initial value}}
14   int out = initializer1(p, 0); // expected-note{{Calling 'initializer1'}}
15                                 // expected-note@-1{{Returning from 'initializer1'}}
16   return p;                     // expected-note{{Undefined or garbage value returned to caller}}
17                                 // expected-warning@-1{{Undefined or garbage value returned to caller}}
18 }
19 
20 struct S {
21   int initialize(int *p, int param) {
22     if (param) { //expected-note{{Taking false branch}}
23       *p = 1;
24       return 1;
25     }
26     return 0; // expected-note{{Returning without writing to '*p'}}
27   }
28 };
29 
30 int use(S *s) {
31   int p;                //expected-note{{'p' declared without an initial value}}
32   s->initialize(&p, 0); //expected-note{{Calling 'S::initialize'}}
33                         //expected-note@-1{{Returning from 'S::initialize'}}
34   return p;             // expected-warning{{Undefined or garbage value returned to caller}}
35                         // expected-note@-1{{Undefined or garbage value returned to caller}}
36 }
37 
38 int initializer2(const int &p) {
39   return 0;
40 }
41 
42 int no_msg_const_ref() {
43   int p; //expected-note{{'p' declared without an initial value}}
44   initializer2(p);
45   return p; // expected-warning{{Undefined or garbage value returned to caller}}
46             // expected-note@-1{{Undefined or garbage value returned to caller}}
47 }
48 
49 void nested() {}
50 void init_in_nested_func(int **x) {
51   *x = 0; // expected-note{{Null pointer value stored to 'y'}}
52   nested();
53 } // no-note
54 
55 int call_init_nested() {
56   int x = 0;
57   int *y = &x;
58   init_in_nested_func(&y); // expected-note{{Calling 'init_in_nested_func'}}
59                            // expected-note@-1{{Returning from 'init_in_nested_func'}}
60   return *y;               //expected-warning{{Dereference of null pointer (loaded from variable 'y')}}
61                            //expected-note@-1{{Dereference of null pointer (loaded from variable 'y')}}
62 }
63 
64 struct A {
65   int x;
66   int y;
67 };
68 
69 void partial_init_by_reference(A &a) {
70   a.x = 0;
71 } // expected-note {{Returning without writing to 'a.y'}}
72 
73 int use_partial_init_by_reference() {
74   A a;
75   partial_init_by_reference(a); // expected-note{{Calling 'partial_init_by_reference'}}
76                                 // expected-note@-1{{Returning from 'partial_init_by_reference'}}
77   return a.y;                   // expected-warning{{Undefined or garbage value returned to caller}}
78                                 // expected-note@-1{{Undefined or garbage value returned to caller}}
79 }
80 
81 struct B : A {
82 };
83 
84 void partially_init_inherited_struct(B *b) {
85   b->x = 0;
86 } // expected-note{{Returning without writing to 'b->y'}}
87 
88 int use_partially_init_inherited_struct() {
89   B b;
90   partially_init_inherited_struct(&b); // expected-note{{Calling 'partially_init_inherited_struct'}}
91                                        // expected-note@-1{{Returning from 'partially_init_inherited_struct'}}
92   return b.y;                          // expected-warning{{Undefined or garbage value returned to caller}}
93                                        // expected-note@-1{{Undefined or garbage value returned to caller}}
94 }
95 
96 struct C {
97   int x;
98   int y;
99   C(int pX, int pY) : x(pX) {} // expected-note{{Returning without writing to 'this->y'}}
100 };
101 
102 int use_constructor() {
103   C c(0, 0); // expected-note{{Calling constructor for 'C'}}
104              // expected-note@-1{{Returning from constructor for 'C'}}
105   return c.y; // expected-note{{Undefined or garbage value returned to caller}}
106               // expected-warning@-1{{Undefined or garbage value returned to caller}}
107 }
108 
109 struct D {
110   void initialize(int *);
111 };
112 
113 void D::initialize(int *p) {
114 
115 } // expected-note{{Returning without writing to '*p'}}
116 
117 int use_d_initializer(D* d) {
118   int p; // expected-note {{'p' declared without an initial value}}
119   d->initialize(&p); // expected-note{{Calling 'D::initialize'}}
120                      // expected-note@-1{{Returning from 'D::initialize'}}
121   return p;                     // expected-note{{Undefined or garbage value returned to caller}}
122                                 // expected-warning@-1{{Undefined or garbage value returned to caller}}
123 }
124 
125 int coin();
126 
127 struct S2 {
128   int x;
129 };
130 
131 int pointerreference(S2* &s) {
132   if (coin()) // expected-note{{Assuming the condition is true}}
133               // expected-note@-1{{Taking true branch}}
134     return 1; // expected-note{{Returning without writing to 's->x'}}
135 
136   s->x = 0;
137   return 0;
138 }
139 
140 int usepointerreference() {
141   S2 s;
142   S2* p = &s;
143   pointerreference(p); //expected-note{{Calling 'pointerreference'}}
144                          //expected-note@-1{{Returning from 'pointerreference'}}
145   return s.x; // expected-warning{{Undefined or garbage value returned to caller}}
146               // expected-note@-1{{Undefined or garbage value returned to caller}}
147 }
148