Clang Project

clang_source_code/test/Analysis/uninit-vals.c
1// RUN: %clang_analyze_cc1 -analyzer-checker=core -fblocks -verify -analyzer-output=text %s
2
3struct FPRec {
4  void (*my_func)(int * x);  
5};
6
7int bar(int x);
8
9int f1_a(struct FPRec* foo) {
10  int x;
11  (*foo->my_func)(&x);
12  return bar(x)+1; // no-warning
13}
14
15int f1_b() {
16  int x; // expected-note{{'x' declared without an initial value}}
17  return bar(x)+1;  // expected-warning{{1st function call argument is an uninitialized value}}
18                    // expected-note@-1{{1st function call argument is an uninitialized value}}
19}
20
21int f2() {
22  
23  int x; // expected-note{{'x' declared without an initial value}}
24  
25  if (x+1)  // expected-warning{{The left operand of '+' is a garbage value}}
26            // expected-note@-1{{The left operand of '+' is a garbage value}}
27    return 1;
28    
29  return 2;  
30}
31
32int f2_b() {
33  int x; // expected-note{{'x' declared without an initial value}}
34  
35  return ((1+x)+2+((x))) + 1 ? 1 : 2; // expected-warning{{The right operand of '+' is a garbage value}}
36                                      // expected-note@-1{{The right operand of '+' is a garbage value}}
37}
38
39int f3(void) {
40  int i; // expected-note{{'i' declared without an initial value}}
41  int *p = &i;
42  if (*p > 0) // expected-warning{{The left operand of '>' is a garbage value}}
43              // expected-note@-1{{The left operand of '>' is a garbage value}}
44    return 0;
45  else
46    return 1;
47}
48
49void f4_aux(float* x);
50float f4(void) {
51  float x;
52  f4_aux(&x);
53  return x;  // no-warning
54}
55
56struct f5_struct { int x; };
57void f5_aux(struct f5_struct* s);
58int f5(void) {
59  struct f5_struct s;
60  f5_aux(&s);
61  return s.x; // no-warning
62}
63
64void f6(int x) {
65  int a[20];
66  if (x == 25) {} // expected-note{{Assuming 'x' is equal to 25}}
67                  // expected-note@-1{{Taking true branch}}
68  if (a[x] == 123) {} // expected-warning{{The left operand of '==' is a garbage value due to array index out of bounds}}
69                      // expected-note@-1{{The left operand of '==' is a garbage value due to array index out of bounds}}
70}
71
72int ret_uninit() {
73  int i; // expected-note{{'i' declared without an initial value}}
74  int *p = &i;
75  return *p;  // expected-warning{{Undefined or garbage value returned to caller}}
76              // expected-note@-1{{Undefined or garbage value returned to caller}}
77}
78
79// <rdar://problem/6451816>
80typedef unsigned char Boolean;
81typedef const struct __CFNumber * CFNumberRef;
82typedef signed long CFIndex;
83typedef CFIndex CFNumberType;
84typedef unsigned long UInt32;
85typedef UInt32 CFStringEncoding;
86typedef const struct __CFString * CFStringRef;
87extern Boolean CFNumberGetValue(CFNumberRef number, CFNumberType theType, void *valuePtr);
88extern CFStringRef CFStringConvertEncodingToIANACharSetName(CFStringEncoding encoding);
89
90CFStringRef rdar_6451816(CFNumberRef nr) {
91  CFStringEncoding encoding;
92  // &encoding is casted to void*.  This test case tests whether or not
93  // we properly invalidate the value of 'encoding'.
94  CFNumberGetValue(nr, 9, &encoding);
95  return CFStringConvertEncodingToIANACharSetName(encoding); // no-warning
96}
97
98// PR 4630 - false warning with nonnull attribute
99//  This false positive (due to a regression) caused the analyzer to falsely
100//  flag a "return of uninitialized value" warning in the first branch due to
101//  the nonnull attribute.
102void pr_4630_aux(char *x, int *y) __attribute__ ((nonnull (1)));
103void pr_4630_aux_2(char *x, int *y);
104int pr_4630(char *a, int y) {
105  int x;
106  if (y) {
107    pr_4630_aux(a, &x);
108    return x;   // no-warning
109  }
110  else {
111    pr_4630_aux_2(a, &x);
112    return x;   // no-warning
113  }
114}
115
116// PR 4631 - False positive with union initializer
117//  Previously the analyzer didn't examine the compound initializers of unions,
118//  resulting in some false positives for initializers with side-effects.
119union u_4631 { int a; };
120struct s_4631 { int a; };
121int pr4631_f2(int *p);
122int pr4631_f3(void *q);
123int pr4631_f1(void)
124{
125  int x;
126  union u_4631 m = { pr4631_f2(&x) };
127  pr4631_f3(&m); // tell analyzer that we use m
128  return x;  // no-warning
129}
130int pr4631_f1_b(void)
131{
132  int x;
133  struct s_4631 m = { pr4631_f2(&x) };
134  pr4631_f3(&m); // tell analyzer that we use m
135  return x;  // no-warning
136}
137
138// <rdar://problem/12278788> - FP when returning a void-valued expression from
139// a void function...or block.
140void foo_radar12278788() { return; }
141void test_radar12278788() {
142  return foo_radar12278788(); // no-warning
143}
144
145void foo_radar12278788_fp() { return; }
146typedef int (*RetIntFuncType)();
147typedef void (*RetVoidFuncType)();
148int test_radar12278788_FP() {
149  RetVoidFuncType f = foo_radar12278788_fp;
150  return ((RetIntFuncType)f)(); //expected-warning {{Undefined or garbage value returned to caller}}
151                                //expected-note@-1 {{Undefined or garbage value returned to caller}}
152                                //expected-note@-2 {{Calling 'foo_radar12278788_fp'}}
153                                //expected-note@-3 {{Returning from 'foo_radar12278788_fp'}}
154}
155
156void rdar13665798() {
157  ^() {
158    return foo_radar12278788(); // no-warning
159  }();
160  ^void() {
161    return foo_radar12278788(); // no-warning
162  }();
163  ^int() { // expected-note{{Calling anonymous block}}
164    RetVoidFuncType f = foo_radar12278788_fp;
165    return ((RetIntFuncType)f)(); //expected-warning {{Undefined or garbage value returned to caller}}
166                                  //expected-note@-1 {{Undefined or garbage value returned to caller}}
167                                  //expected-note@-2 {{Calling 'foo_radar12278788_fp'}}
168                                  //expected-note@-3 {{Returning from 'foo_radar12278788_fp'}}
169  }();
170}
171
172struct Point {
173  int x, y;
174};
175
176struct Point getHalfPoint() {
177  struct Point p;
178  p.x = 0;
179  return p;
180}
181
182void use(struct Point p); 
183
184void testUseHalfPoint() {
185  struct Point p = getHalfPoint(); // expected-note{{Calling 'getHalfPoint'}}
186                                   // expected-note@-1{{Returning from 'getHalfPoint'}}
187                                   // expected-note@-2{{'p' initialized here}}
188  use(p); // expected-warning{{uninitialized}}
189          // expected-note@-1{{uninitialized}}
190}
191
192void testUseHalfPoint2() {
193  struct Point p;
194  p = getHalfPoint(); // expected-note{{Calling 'getHalfPoint'}}
195                      // expected-note@-1{{Returning from 'getHalfPoint'}}
196                      // expected-note@-2{{Value assigned to 'p'}}
197  use(p); // expected-warning{{uninitialized}}
198          // expected-note@-1{{uninitialized}}
199}
200