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