1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-output=text -verify %s
3 typedef unsigned int NSUInteger;
4 typedef __typeof__(sizeof(int)) size_t;
7 void *calloc(size_t nmemb, size_t size);
10 void clang_analyzer_eval(int);
24 if (global.data == 0) // When the true branch is feasible 'a = 3'.
29 // Test uninitialized value due to part of the structure being uninitialized.
30 struct TestUninit { int x; int y; };
31 struct TestUninit test_uninit_aux(void);
32 void test_unit_aux2(int);
33 void test_uninit_pos(void) {
34 struct TestUninit v1 = { 0, 0 };
35 struct TestUninit v2 = test_uninit_aux();
36 int z; // expected-note{{'z' declared without an initial value}}
37 v1.y = z; // expected-warning{{Assigned value is garbage or undefined}}
38 // expected-note@-1{{Assigned value is garbage or undefined}}
39 test_unit_aux2(v2.x + v1.y);
41 void test_uninit_pos_2(void) {
42 struct TestUninit v1 = { 0, 0 };
44 test_unit_aux2(v2.x + v1.y); // expected-warning{{The left operand of '+' is a garbage value}}
45 // expected-note@-1{{The left operand of '+' is a garbage value}}
47 void test_uninit_pos_3(void) {
48 struct TestUninit v1 = { 0, 0 };
50 test_unit_aux2(v1.y + v2.x); // expected-warning{{The right operand of '+' is a garbage value}}
51 // expected-note@-1{{The right operand of '+' is a garbage value}}
54 void test_uninit_neg(void) {
55 struct TestUninit v1 = { 0, 0 };
56 struct TestUninit v2 = test_uninit_aux();
57 test_unit_aux2(v2.x + v1.y);
60 extern void test_uninit_struct_arg_aux(struct TestUninit arg);
61 void test_uninit_struct_arg(void) {
62 struct TestUninit x; // expected-note{{'x' initialized here}}
63 test_uninit_struct_arg_aux(x); // expected-warning{{Passed-by-value struct argument contains uninitialized data (e.g., field: 'x')}}
64 // expected-note@-1{{Passed-by-value struct argument contains uninitialized data (e.g., field: 'x')}}
68 - (void) passVal:(struct TestUninit)arg;
70 void testFoo(Foo *o) {
71 struct TestUninit x; // expected-note{{'x' initialized here}}
72 [o passVal:x]; // expected-warning{{Passed-by-value struct argument contains uninitialized data (e.g., field: 'x')}}
73 // expected-note@-1{{Passed-by-value struct argument contains uninitialized data (e.g., field: 'x')}}
76 // Test case shows an uninitialized value being used in the LHS of a compound
78 void rdar_7780304(void) {
79 typedef struct s_r7780304 { int x; } s_r7780304;
81 b.x |= 1; // expected-warning{{The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage}}
82 // expected-note@-1{{The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage}}
86 // The flip side of PR10163 -- float arrays that are actually uninitialized
87 void test_PR10163(float);
90 test_PR10163(x[1]); // expected-warning{{uninitialized value}}
91 // expected-note@-1{{1st function call argument is an uninitialized value}}
94 // PR10163 -- don't warn for default-initialized float arrays.
95 void PR10163_default_initialized_arrays(void) {
97 test_PR10163(x[1]); // no-warning
104 void swap(struct MyStr *To, struct MyStr *From) {
105 // This is not really a swap but close enough for our test.
107 To->y = From->y; // expected-note{{Uninitialized value stored to field 'y'}}
109 int test_undefined_member_assignment_in_swap(struct MyStr *s2) {
112 swap(s2, &s1); // expected-note{{Calling 'swap'}}
113 // expected-note@-1{{Returning from 'swap'}}
114 return s2->y; // expected-warning{{Undefined or garbage value returned to caller}}
115 // expected-note@-1{{Undefined or garbage value returned to caller}}
123 const NSUInteger n = [x foo];
126 if (n > 0) { // tests const cast transfer function logic
129 for (i = 0; i < n; ++i)
132 if (bogus) // no-warning
152 Point makePoint(float x, float y) {
160 void PR14765_test(void) {
161 Circle *testObj = calloc(sizeof(Circle), 1);
163 clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}
164 // expected-note@-1{{TRUE}}
166 testObj->origin = makePoint(0.0, 0.0);
167 if (testObj->size > 0) { ; } // expected-note{{Assuming field 'size' is <= 0}}
168 // expected-note@-1{{Taking false branch}}
170 // FIXME: Assigning to 'testObj->origin' kills the default binding for the
171 // whole region, meaning that we've forgotten that testObj->size should also
173 // This should be TRUE.
174 clang_analyzer_eval(testObj->size == 0); // expected-warning{{UNKNOWN}}
175 // expected-note@-1{{UNKNOWN}}
180 void PR14765_argument(Circle *testObj) {
181 int oldSize = testObj->size;
182 clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
183 // expected-note@-1{{TRUE}}
185 testObj->origin = makePoint(0.0, 0.0);
186 clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
187 // expected-note@-1{{TRUE}}
201 IntPoint makeIntPoint(int x, int y) {
209 void PR14765_test_int(void) {
210 IntCircle *testObj = calloc(sizeof(IntCircle), 1);
212 clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}
213 // expected-note@-1{{TRUE}}
214 clang_analyzer_eval(testObj->origin.x == 0); // expected-warning{{TRUE}}
215 // expected-note@-1{{TRUE}}
216 clang_analyzer_eval(testObj->origin.y == 0); // expected-warning{{TRUE}}
217 // expected-note@-1{{TRUE}}
218 clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}}
219 // expected-note@-1{{TRUE}}
221 testObj->origin = makeIntPoint(1, 2);
222 if (testObj->size > 0) { ; } // expected-note{{Assuming field 'size' is <= 0}}
223 // expected-note@-1{{Taking false branch}}
224 // expected-note@-2{{Assuming field 'size' is <= 0}}
225 // expected-note@-3{{Taking false branch}}
226 // expected-note@-4{{Assuming field 'size' is <= 0}}
227 // expected-note@-5{{Taking false branch}}
228 // expected-note@-6{{Assuming field 'size' is <= 0}}
229 // expected-note@-7{{Taking false branch}}
231 // FIXME: Assigning to 'testObj->origin' kills the default binding for the
232 // whole region, meaning that we've forgotten that testObj->size should also
234 // This should be TRUE.
235 clang_analyzer_eval(testObj->size == 0); // expected-warning{{UNKNOWN}}
236 // expected-note@-1{{UNKNOWN}}
237 clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}
238 // expected-note@-1{{TRUE}}
239 clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}
240 // expected-note@-1{{TRUE}}
241 clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}}
242 // expected-note@-1{{TRUE}}
247 void PR14765_argument_int(IntCircle *testObj) {
248 int oldSize = testObj->size;
249 clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
250 // expected-note@-1{{TRUE}}
252 testObj->origin = makeIntPoint(1, 2);
253 clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
254 // expected-note@-1{{TRUE}}
255 clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}
256 // expected-note@-1{{TRUE}}
257 clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}
258 // expected-note@-1{{TRUE}}
259 clang_analyzer_eval(testObj->origin.z == 0); // expected-warning{{TRUE}}
260 // expected-note@-1{{TRUE}}
264 void rdar13292559(Circle input) {
265 extern void useCircle(Circle);
268 useCircle(obj); // no-warning
270 // This generated an "uninitialized 'size' field" warning for a (short) while.
271 obj.origin = makePoint(0.0, 0.0);
272 useCircle(obj); // no-warning
285 IntPoint2D makeIntPoint2D(int x, int y) {
292 void testSmallStructsCopiedPerField(void) {
297 extern void useInt(int);
298 useInt(b.x); // no-warning
299 useInt(b.y); // expected-warning{{uninitialized}}
300 // expected-note@-1{{uninitialized}}
303 void testLargeStructsNotCopiedPerField(void) {
308 extern void useInt(int);
309 useInt(b.x); // no-warning
310 useInt(b.y); // no-warning
313 void testSmallStructInLargerStruct(void) {
314 IntCircle2D *testObj = calloc(sizeof(IntCircle2D), 1);
316 clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}
317 // expected-note@-1{{TRUE}}
318 clang_analyzer_eval(testObj->origin.x == 0); // expected-warning{{TRUE}}
319 // expected-note@-1{{TRUE}}
320 clang_analyzer_eval(testObj->origin.y == 0); // expected-warning{{TRUE}}
321 // expected-note@-1{{TRUE}}
323 testObj->origin = makeIntPoint2D(1, 2);
324 if (testObj->size > 0) { ; } // expected-note{{Field 'size' is <= 0}}
325 // expected-note@-1{{Taking false branch}}
326 // expected-note@-2{{Field 'size' is <= 0}}
327 // expected-note@-3{{Taking false branch}}
328 // expected-note@-4{{Field 'size' is <= 0}}
329 // expected-note@-5{{Taking false branch}}
331 clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}
332 // expected-note@-1{{TRUE}}
333 clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}
334 // expected-note@-1{{TRUE}}
335 clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}
336 // expected-note@-1{{TRUE}}
341 void testCopySmallStructIntoArgument(IntCircle2D *testObj) {
342 int oldSize = testObj->size;
343 clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
344 // expected-note@-1{{TRUE}}
346 testObj->origin = makeIntPoint2D(1, 2);
347 clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
348 // expected-note@-1{{TRUE}}
349 clang_analyzer_eval(testObj->origin.x == 1); // expected-warning{{TRUE}}
350 // expected-note@-1{{TRUE}}
351 clang_analyzer_eval(testObj->origin.y == 2); // expected-warning{{TRUE}}
352 // expected-note@-1{{TRUE}}
355 void testSmallStructBitfields(void) {
365 clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}}
366 // expected-note@-1{{TRUE}}
367 clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}}
368 // expected-note@-1{{TRUE}}
371 void testSmallStructBitfieldsFirstUndef(void) {
380 clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}}
381 // expected-note@-1{{TRUE}}
382 clang_analyzer_eval(b.x == 1); // expected-warning{{garbage}}
383 // expected-note@-1{{garbage}}
386 void testSmallStructBitfieldsSecondUndef(void) {
395 clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}}
396 // expected-note@-1{{TRUE}}
397 clang_analyzer_eval(b.y == 2); // expected-warning{{garbage}}
398 // expected-note@-1{{garbage}}
401 void testSmallStructBitfieldsFirstUnnamed(void) {
405 } a, b, c; // expected-note{{'c' initialized here}}
410 clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}}
411 // expected-note@-1{{TRUE}}
413 b = c; // expected-note{{Uninitialized value stored to 'b.y'}}
414 clang_analyzer_eval(b.y == 2); // expected-warning{{garbage}}
415 // expected-note@-1{{garbage}}
418 void testSmallStructBitfieldsSecondUnnamed(void) {
422 } a, b, c; // expected-note{{'c' initialized here}}
427 clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}}
428 // expected-note@-1{{TRUE}}
430 b = c; // expected-note{{Uninitialized value stored to 'b.x'}}
431 clang_analyzer_eval(b.x == 1); // expected-warning{{garbage}}
432 // expected-note@-1{{garbage}}