1 // RUN: %clang_analyze_cc1 -x c++ -std=c++14 -analyzer-checker=core -analyzer-output=text -verify %s
2
initializer1(int & p,int x)3 int initializer1(int &p, int x) {
4 if (x) { // expected-note{{'x' is 0}}
5 // expected-note@-1{{Taking false branch}}
6 p = 1;
7 return 0;
8 } else {
9 return 1; // expected-note {{Returning without writing to 'p'}}
10 }
11 }
12
param_not_initialized_by_func()13 int param_not_initialized_by_func() {
14 int outP; // expected-note {{'outP' declared without an initial value}}
15 int out = initializer1(outP, 0); // expected-note{{Calling 'initializer1'}}
16 // expected-note@-1{{Returning from 'initializer1'}}
17 return outP; // expected-note{{Undefined or garbage value returned to caller}}
18 // expected-warning@-1{{Undefined or garbage value returned to caller}}
19 }
20
21 struct S {
initializeS22 int initialize(int *p, int param) {
23 if (param) { // expected-note{{'param' is 0}}
24 // expected-note@-1{{Taking false branch}}
25 *p = 1;
26 return 1;
27 }
28 return 0; // expected-note{{Returning without writing to '*p'}}
29 }
30 };
31
use(S * s)32 int use(S *s) {
33 int p; //expected-note{{'p' declared without an initial value}}
34 s->initialize(&p, 0); //expected-note{{Calling 'S::initialize'}}
35 //expected-note@-1{{Returning from 'S::initialize'}}
36 return p; // expected-warning{{Undefined or garbage value returned to caller}}
37 // expected-note@-1{{Undefined or garbage value returned to caller}}
38 }
39
initializer2(const int & p)40 int initializer2(const int &p) {
41 return 0;
42 }
43
no_msg_const_ref()44 int no_msg_const_ref() {
45 int p; //expected-note{{'p' declared without an initial value}}
46 initializer2(p);
47 return p; // expected-warning{{Undefined or garbage value returned to caller}}
48 // expected-note@-1{{Undefined or garbage value returned to caller}}
49 }
50
nested()51 void nested() {}
init_in_nested_func(int ** x)52 void init_in_nested_func(int **x) {
53 *x = 0; // expected-note{{Null pointer value stored to 'y'}}
54 nested();
55 } // no-note
56
call_init_nested()57 int call_init_nested() {
58 int x = 0;
59 int *y = &x;
60 init_in_nested_func(&y); // expected-note{{Calling 'init_in_nested_func'}}
61 // expected-note@-1{{Returning from 'init_in_nested_func'}}
62 return *y; //expected-warning{{Dereference of null pointer (loaded from variable 'y')}}
63 //expected-note@-1{{Dereference of null pointer (loaded from variable 'y')}}
64 }
65
66 struct A {
67 int x;
68 int y;
69 };
70
partial_init_by_reference(A & a)71 void partial_init_by_reference(A &a) {
72 a.x = 0;
73 } // expected-note {{Returning without writing to 'a.y'}}
74
use_partial_init_by_reference()75 int use_partial_init_by_reference() {
76 A a;
77 partial_init_by_reference(a); // expected-note{{Calling 'partial_init_by_reference'}}
78 // expected-note@-1{{Returning from 'partial_init_by_reference'}}
79 return a.y; // expected-warning{{Undefined or garbage value returned to caller}}
80 // expected-note@-1{{Undefined or garbage value returned to caller}}
81 }
82
83 struct B : A {
84 };
85
partially_init_inherited_struct(B * b)86 void partially_init_inherited_struct(B *b) {
87 b->x = 0;
88 } // expected-note{{Returning without writing to 'b->y'}}
89
use_partially_init_inherited_struct()90 int use_partially_init_inherited_struct() {
91 B b;
92 partially_init_inherited_struct(&b); // expected-note{{Calling 'partially_init_inherited_struct'}}
93 // expected-note@-1{{Returning from 'partially_init_inherited_struct'}}
94 return b.y; // expected-warning{{Undefined or garbage value returned to caller}}
95 // expected-note@-1{{Undefined or garbage value returned to caller}}
96 }
97
98 struct C {
99 int x;
100 int y;
CC101 C(int pX, int pY) : x(pX) {} // expected-note{{Returning without writing to 'this->y'}}
102
CC103 C(int pX, int pY, bool Flag) {
104 x = pX;
105 if (Flag) // expected-note{{Assuming 'Flag' is true}}
106 // expected-note@-1{{Taking true branch}}
107 return; // expected-note{{Returning without writing to 'this->y'}}
108 y = pY;
109 }
110 };
111
use_constructor()112 int use_constructor() {
113 C c(0, 0); // expected-note{{Calling constructor for 'C'}}
114 // expected-note@-1{{Returning from constructor for 'C'}}
115 return c.y; // expected-note{{Undefined or garbage value returned to caller}}
116 // expected-warning@-1{{Undefined or garbage value returned to caller}}
117 }
118
119 int coin();
120
use_other_constructor()121 int use_other_constructor() {
122 C c(0, 0, coin()); // expected-note{{Calling constructor for 'C'}}
123 // expected-note@-1{{Returning from constructor for 'C'}}
124 return c.y; // expected-note{{Undefined or garbage value returned to caller}}
125 // expected-warning@-1{{Undefined or garbage value returned to caller}}
126 }
127
128 struct D {
129 void initialize(int *);
130 };
131
initialize(int * p)132 void D::initialize(int *p) {
133
134 } // expected-note{{Returning without writing to '*p'}}
135
use_d_initializer(D * d)136 int use_d_initializer(D* d) {
137 int p; // expected-note {{'p' declared without an initial value}}
138 d->initialize(&p); // expected-note{{Calling 'D::initialize'}}
139 // expected-note@-1{{Returning from 'D::initialize'}}
140 return p; // expected-note{{Undefined or garbage value returned to caller}}
141 // expected-warning@-1{{Undefined or garbage value returned to caller}}
142 }
143
144 struct S2 {
145 int x;
146 };
147
pointerreference(S2 * & s)148 int pointerreference(S2* &s) {
149 if (coin()) // expected-note{{Assuming the condition is true}}
150 // expected-note@-1{{Taking true branch}}
151 return 1; // expected-note{{Returning without writing to 's->x'}}
152
153 s->x = 0;
154 return 0;
155 }
156
usepointerreference()157 int usepointerreference() {
158 S2 s;
159 S2* p = &s;
160 pointerreference(p); //expected-note{{Calling 'pointerreference'}}
161 //expected-note@-1{{Returning from 'pointerreference'}}
162 return s.x; // expected-warning{{Undefined or garbage value returned to caller}}
163 // expected-note@-1{{Undefined or garbage value returned to caller}}
164 }
165
has_no_argument_and_returns_null(void)166 void *has_no_argument_and_returns_null(void) {
167 return 0;
168 }
169
rdar40335545()170 void rdar40335545() {
171 int local; // expected-note{{}}
172 void (*takes_int_ptr_argument)(int *) = (void (*)(int*))has_no_argument_and_returns_null;
173
174 takes_int_ptr_argument(&local); // no-crash
175
176 int useLocal = local; //expected-warning{{}}
177 //expected-note@-1{{}}
178 (void)useLocal;
179 }
180
181 ////////
182
183 struct HasRef {
184 int &a;
HasRefHasRef185 HasRef(int &a) : a(a) {}
186 };
187
188
maybeInitialize(const HasRef && pA)189 void maybeInitialize(const HasRef &&pA) {
190 if (coin()) // expected-note{{Assuming the condition is false}}
191 // expected-note@-1{{Taking false branch}}
192 pA.a = 120;
193 } // expected-note{{Returning without writing to 'pA.a'}}
194
useMaybeInitializerWritingIntoField()195 int useMaybeInitializerWritingIntoField() {
196 int z; // expected-note{{'z' declared without an initial value}}
197 maybeInitialize(HasRef(z)); // expected-note{{Calling constructor for 'HasRef'}}
198 // expected-note@-1{{Returning from constructor for 'HasRef'}}
199 // expected-note@-2{{Calling 'maybeInitialize'}}
200 // expected-note@-3{{Returning from 'maybeInitialize'}}
201 return z; // expected-warning{{Undefined or garbage value returned to caller}}
202 // expected-note@-1{{Undefined or garbage value returned to caller}}
203 }
204
205 ////////
206
207 struct HasRefToItself {
208 HasRefToItself &Ref; // no infinite loop
209 int &z;
HasRefToItselfHasRefToItself210 HasRefToItself(int &z) : Ref(*this), z(z) {}
211 };
212
maybeInitialize(const HasRefToItself && pA)213 void maybeInitialize(const HasRefToItself &&pA) {
214 if (coin()) // expected-note{{Assuming the condition is false}}
215 // expected-note@-1{{Taking false branch}}
216 pA.z = 120;
217 } // expected-note{{Returning without writing to 'pA.Ref.z'}}
218
useMaybeInitializerWritingIntoFieldWithRefToItself()219 int useMaybeInitializerWritingIntoFieldWithRefToItself() {
220 int z; // expected-note{{'z' declared without an initial value}}
221 maybeInitialize(HasRefToItself(z)); // expected-note{{Calling constructor for 'HasRefToItself'}}
222 // expected-note@-1{{Returning from constructor for 'HasRefToItself'}}
223 // expected-note@-2{{Calling 'maybeInitialize'}}
224 // expected-note@-3{{Returning from 'maybeInitialize'}}
225 return z; // expected-warning{{Undefined or garbage value returned to caller}}
226 // expected-note@-1{{Undefined or garbage value returned to caller}}
227 }
228
229 ////
230
maybeInitialize(const HasRef * pA)231 void maybeInitialize(const HasRef *pA) {
232 if (coin()) // expected-note{{Assuming the condition is false}}
233 // expected-note@-1{{Taking false branch}}
234 pA->a = 120;
235 } // expected-note{{Returning without writing to 'pA->a'}}
236
useMaybeInitializerStructByPointer()237 int useMaybeInitializerStructByPointer() {
238 int z; // expected-note{{'z' declared without an initial value}}
239 HasRef wrapper(z); // expected-note{{Calling constructor for 'HasRef'}}
240 // expected-note@-1{{Returning from constructor for 'HasRef'}}
241 maybeInitialize(&wrapper); // expected-note{{Calling 'maybeInitialize'}}
242 // expected-note@-1{{Returning from 'maybeInitialize'}}
243 return z; // expected-warning{{Undefined or garbage value returned to caller}}
244 // expected-note@-1{{Undefined or garbage value returned to caller}}
245 }
246
247 ////////
248
249 struct HasParentWithRef : public HasRef {
HasParentWithRefHasParentWithRef250 HasParentWithRef(int &a) : HasRef(a) {} // expected-note{{Calling constructor for 'HasRef'}}
251 // expected-note@-1{{Returning from constructor for 'HasRef'}}
252 };
253
maybeInitializeWithParent(const HasParentWithRef & pA)254 void maybeInitializeWithParent(const HasParentWithRef &pA) {
255 if (coin()) // expected-note{{Assuming the condition is false}}
256 // expected-note@-1{{Taking false branch}}
257 pA.a = 120;
258 } // expected-note{{Returning without writing to 'pA.a'}}
259
useMaybeInitializerWritingIntoParentField()260 int useMaybeInitializerWritingIntoParentField() {
261 int z; // expected-note{{'z' declared without an initial value}}
262 maybeInitializeWithParent(HasParentWithRef(z)); // expected-note{{Calling constructor for 'HasParentWithRef'}}
263 // expected-note@-1{{Returning from constructor for 'HasParentWithRef'}}
264 // expected-note@-2{{Calling 'maybeInitializeWithParent'}}
265 // expected-note@-3{{Returning from 'maybeInitializeWithParent'}}
266 return z; // expected-warning{{Undefined or garbage value returned to caller}}
267 // expected-note@-1{{Undefined or garbage value returned to caller}}
268 }
269
270 ////////
271
272 struct HasIndirectRef {
273 HasRef &Ref;
HasIndirectRefHasIndirectRef274 HasIndirectRef(HasRef &Ref) : Ref(Ref) {}
275 };
276
maybeInitializeIndirectly(const HasIndirectRef & pA)277 void maybeInitializeIndirectly(const HasIndirectRef &pA) {
278 if (coin()) // expected-note{{Assuming the condition is false}}
279 // expected-note@-1{{Taking false branch}}
280 pA.Ref.a = 120;
281 } // expected-note{{Returning without writing to 'pA.Ref.a'}}
282
useMaybeInitializeIndirectly()283 int useMaybeInitializeIndirectly() {
284 int z; // expected-note{{'z' declared without an initial value}}
285 HasRef r(z); // expected-note{{Calling constructor for 'HasRef'}}
286 // expected-note@-1{{Returning from constructor for 'HasRef'}}
287 maybeInitializeIndirectly(HasIndirectRef(r)); // expected-note{{Calling 'maybeInitializeIndirectly'}}
288 // expected-note@-1{{Returning from 'maybeInitializeIndirectly'}}
289 return z; // expected-warning{{Undefined or garbage value returned to caller}}
290 // expected-note@-1{{Undefined or garbage value returned to caller}}
291 }
292
293 ////////
294
295 struct HasIndirectRefByValue {
296 HasRef Ref;
HasIndirectRefByValueHasIndirectRefByValue297 HasIndirectRefByValue(HasRef Ref) : Ref(Ref) {}
298 };
299
maybeInitializeIndirectly(const HasIndirectRefByValue & pA)300 void maybeInitializeIndirectly(const HasIndirectRefByValue &pA) {
301 if (coin()) // expected-note{{Assuming the condition is false}}
302 // expected-note@-1{{Taking false branch}}
303 pA.Ref.a = 120;
304 } // expected-note{{Returning without writing to 'pA.Ref.a'}}
305
useMaybeInitializeIndirectlyIndirectRefByValue()306 int useMaybeInitializeIndirectlyIndirectRefByValue() {
307 int z; // expected-note{{'z' declared without an initial value}}
308 HasRef r(z); // expected-note{{Calling constructor for 'HasRef'}}
309 // expected-note@-1{{Returning from constructor for 'HasRef'}}
310 maybeInitializeIndirectly(HasIndirectRefByValue(r)); // expected-note{{Calling 'maybeInitializeIndirectly'}}
311 // expected-note@-1{{Returning from 'maybeInitializeIndirectly'}}
312 return z; // expected-warning{{Undefined or garbage value returned to caller}}
313 // expected-note@-1{{Undefined or garbage value returned to caller}}
314 }
315
316 ////////
317
318 struct HasIndirectPointerRef {
319 HasRef *Ref;
HasIndirectPointerRefHasIndirectPointerRef320 HasIndirectPointerRef(HasRef *Ref) : Ref(Ref) {}
321 };
322
maybeInitializeIndirectly(const HasIndirectPointerRef & pA)323 void maybeInitializeIndirectly(const HasIndirectPointerRef &pA) {
324 if (coin()) // expected-note{{Assuming the condition is false}}
325 // expected-note@-1{{Taking false branch}}
326 pA.Ref->a = 120;
327 } // expected-note{{Returning without writing to 'pA.Ref->a'}}
328
useMaybeInitializeIndirectlyWithPointer()329 int useMaybeInitializeIndirectlyWithPointer() {
330 int z; // expected-note{{'z' declared without an initial value}}
331 HasRef r(z); // expected-note{{Calling constructor for 'HasRef'}}
332 // expected-note@-1{{Returning from constructor for 'HasRef'}}
333 maybeInitializeIndirectly(HasIndirectPointerRef(&r)); // expected-note{{Calling 'maybeInitializeIndirectly'}}
334 // expected-note@-1{{Returning from 'maybeInitializeIndirectly'}}
335 return z; // expected-warning{{Undefined or garbage value returned to caller}}
336 // expected-note@-1{{Undefined or garbage value returned to caller}}
337 }
338
339 ////////
340
341 struct HasFieldA {
342 int x;
343 };
344
345 struct HasFieldB {
346 int x;
347 };
348
maybeInitializeHasField(HasFieldA * b)349 void maybeInitializeHasField(HasFieldA *b) {
350 if (coin()) // expected-note{{Assuming the condition is false}}
351 // expected-note@-1{{Taking false branch}}
352 ((HasFieldB*)b)->x = 120;
353 }
354
forceElementRegionApperence()355 int forceElementRegionApperence() {
356 HasFieldA a;
357 maybeInitializeHasField(&a); // expected-note{{Calling 'maybeInitializeHasField'}}
358 // expected-note@-1{{Returning from 'maybeInitializeHasField'}}
359 return ((HasFieldB*)&a)->x; // expected-warning{{Undefined or garbage value returned to caller}}
360 // expected-note@-1{{Undefined or garbage value returned to caller}}
361 }
362
363 ////////
364
365 struct HasForgottenField {
366 int x;
HasForgottenFieldHasForgottenField367 HasForgottenField() {} // expected-note{{Returning without writing to 'this->x'}}
368 };
369
370 // Test that tracking across exclamation mark works.
tracksThroughExclamationMark()371 bool tracksThroughExclamationMark() {
372 HasForgottenField a; // expected-note{{Calling default constructor for 'HasForgottenField'}}
373 // expected-note@-1{{Returning from default constructor for 'HasForgottenField'}}
374 return !a.x; // expected-warning{{Undefined or garbage value returned to caller}}
375 // expected-note@-1{{Undefined or garbage value returned to caller}}
376 }
377