uninit-vals.m revision 9f3495aeaa24da4eacf8f6c274adcef65e2f3617
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s
2
3typedef unsigned int NSUInteger;
4typedef __typeof__(sizeof(int)) size_t;
5
6void *malloc(size_t);
7void *calloc(size_t nmemb, size_t size);
8void free(void *);
9
10void clang_analyzer_eval(int);
11
12@interface A
13- (NSUInteger)foo;
14@end
15
16NSUInteger f8(A* x){
17  const NSUInteger n = [x foo];
18  int* bogus;  
19
20  if (n > 0) {    // tests const cast transfer function logic
21    NSUInteger i;
22    
23    for (i = 0; i < n; ++i)
24      bogus = 0;
25
26    if (bogus)  // no-warning
27      return n+1;
28  }
29  
30  return n;
31}
32
33
34// PR10163 -- don't warn for default-initialized float arrays.
35// (An additional test is in uninit-vals-ps-region.m)
36void test_PR10163(float);
37void PR10163 (void) {
38  float x[2] = {0};
39  test_PR10163(x[1]); // no-warning  
40}
41
42
43typedef struct {
44  float x;
45  float y;
46} Point;
47typedef struct {
48  Point origin;
49  int size;
50} Circle;
51
52Point makePoint(float x, float y) {
53  Point result;
54  result.x = x;
55  result.y = y;
56  return result;
57}
58
59void PR14765_test() {
60  Circle *testObj = calloc(sizeof(Circle), 1);
61
62  clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}
63
64  testObj->origin = makePoint(0.0, 0.0);
65  if (testObj->size > 0) { ; } // warning occurs here
66
67  // FIXME: Assigning to 'testObj->origin' kills the default binding for the
68  // whole region, meaning that we've forgotten that testObj->size should also
69  // default to 0. Tracked by <rdar://problem/12701038>.
70  // This should be TRUE.
71  clang_analyzer_eval(testObj->size == 0); // expected-warning{{UNKNOWN}}
72
73  free(testObj);
74}
75
76void PR14765_incorrectBehavior(Circle *testObj) {
77  int oldSize = testObj->size;
78
79  clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
80
81  testObj->origin = makePoint(0.0, 0.0);
82
83  clang_analyzer_eval(testObj->size == oldSize); // expected-warning{{TRUE}}
84  
85  free(testObj);
86}
87
88void rdar13292559(Circle input) {
89  extern void useCircle(Circle);
90
91  Circle obj = input;
92  useCircle(obj); // no-warning
93
94  // This generated an "uninitialized 'size' field" warning for a (short) while.
95  obj.origin = makePoint(0.0, 0.0);
96  useCircle(obj); // no-warning
97}
98
99