1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s
3 void clang_analyzer_eval(int);
5 int string_literal_init(void) {
7 char b
[2] = "abc"; // expected-warning{{too long}}
10 clang_analyzer_eval(a
[1] == 'b'); // expected-warning{{TRUE}}
11 clang_analyzer_eval(b
[1] == 'b'); // expected-warning{{TRUE}}
12 clang_analyzer_eval(c
[1] == 'b'); // expected-warning{{TRUE}}
14 clang_analyzer_eval(a
[3] == 0); // expected-warning{{TRUE}}
15 clang_analyzer_eval(c
[3] == 0); // expected-warning{{TRUE}}
17 clang_analyzer_eval(c
[4] == 0); // expected-warning{{TRUE}}
22 void nested_compound_literals(int rad
) {
23 int vec
[6][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, // expected-warning 6 {{implicit conversion from 'double' to 'int' changes value from}}
24 {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}}; // expected-warning 6 {{implicit conversion from 'double' to 'int' changes value from}}
27 for (a
= 0; a
< 6; ++a
) {
28 vec
[a
][0] *= rad
; // no-warning
29 vec
[a
][1] *= rad
; // no-warning
33 void nested_compound_literals_float(float rad
) {
34 float vec
[6][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169},
35 {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
38 for (a
= 0; a
< 6; ++a
) {
39 vec
[a
][0] *= rad
; // no-warning
40 vec
[a
][1] *= rad
; // no-warning
45 void struct_as_array(void) {
46 struct simple
{ int x
; int y
; };
48 struct simple
*p
= &a
;
51 clang_analyzer_eval(a
.x
== 5); // expected-warning{{TRUE}}
52 clang_analyzer_eval(p
[0].x
== 5); // expected-warning{{TRUE}}
55 clang_analyzer_eval(a
.y
== 5); // expected-warning{{TRUE}}
56 clang_analyzer_eval(p
->y
== 5); // expected-warning{{TRUE}}
60 // PR13264 / <rdar://problem/11802440>
61 struct point
{ int x
; int y
; };
62 struct circle
{ struct point o
; int r
; };
63 struct circle
get_circle(void) {
66 result
.o
= (struct point
){0, 0};
70 void struct_in_struct(void) {
73 // This used to think c.r was undefined because c.o is a LazyCompoundVal.
74 clang_analyzer_eval(c
.r
== 5); // expected-warning{{TRUE}}
77 // We also test with floats because we don't model floats right now,
78 // and the original bug report used a float.
79 struct circle_f
{ struct point o
; float r
; };
80 struct circle_f
get_circle_f(void) {
81 struct circle_f result
;
83 result
.o
= (struct point
){0, 0};
87 float struct_in_struct_f(void) {
91 return c
.r
; // no-warning
97 int testSymbolicInvalidation(int index
) {
101 clang_analyzer_eval(vals
[0] == 42); // expected-warning{{TRUE}}
103 vals
[index
] = randomInt();
104 clang_analyzer_eval(vals
[0] == 42); // expected-warning{{UNKNOWN}}
106 return vals
[index
]; // no-warning
109 int testConcreteInvalidation(int index
) {
113 clang_analyzer_eval(vals
[index
] == 42); // expected-warning{{TRUE}}
114 vals
[0] = randomInt();
115 clang_analyzer_eval(vals
[index
] == 42); // expected-warning{{UNKNOWN}}
117 return vals
[0]; // no-warning
127 int testSymbolicInvalidationStruct(int index
) {
131 clang_analyzer_eval(vals
[0].x
== 42); // expected-warning{{TRUE}}
133 vals
[index
] = makeS();
134 clang_analyzer_eval(vals
[0].x
== 42); // expected-warning{{UNKNOWN}}
136 return vals
[index
].x
; // no-warning
139 int testConcreteInvalidationStruct(int index
) {
143 clang_analyzer_eval(vals
[index
].x
== 42); // expected-warning{{TRUE}}
145 clang_analyzer_eval(vals
[index
].x
== 42); // expected-warning{{UNKNOWN}}
147 return vals
[0].x
; // no-warning
155 int testSymbolicInvalidationDoubleStruct(int index
) {
160 clang_analyzer_eval(vals
.a
[0].x
== 42); // expected-warning{{TRUE}}
161 clang_analyzer_eval(vals
.b
[0].x
== 42); // expected-warning{{TRUE}}
163 vals
.a
[index
] = makeS();
164 clang_analyzer_eval(vals
.a
[0].x
== 42); // expected-warning{{UNKNOWN}}
165 clang_analyzer_eval(vals
.b
[0].x
== 42); // expected-warning{{TRUE}}
167 return vals
.b
[index
].x
; // no-warning
170 int testConcreteInvalidationDoubleStruct(int index
) {
173 vals
.a
[index
].x
= 42;
174 vals
.b
[index
].x
= 42;
175 clang_analyzer_eval(vals
.a
[index
].x
== 42); // expected-warning{{TRUE}}
176 clang_analyzer_eval(vals
.b
[index
].x
== 42); // expected-warning{{TRUE}}
179 clang_analyzer_eval(vals
.a
[index
].x
== 42); // expected-warning{{UNKNOWN}}
180 clang_analyzer_eval(vals
.b
[index
].x
== 42); // expected-warning{{TRUE}}
182 return vals
.b
[0].x
; // no-warning
186 int testNonOverlappingStructFieldsSimple(void) {
191 clang_analyzer_eval(val
.x
== 1); // expected-warning{{TRUE}}
192 clang_analyzer_eval(val
.y
== 2); // expected-warning{{TRUE}}
194 return val
.z
; // expected-warning{{garbage}}
197 int testNonOverlappingStructFieldsSymbolicBase(int index
, int anotherIndex
) {
200 vals
.a
[index
].x
= 42;
201 vals
.a
[index
].y
= 42;
202 clang_analyzer_eval(vals
.a
[index
].x
== 42); // expected-warning{{TRUE}}
203 clang_analyzer_eval(vals
.a
[index
].y
== 42); // expected-warning{{TRUE}}
205 vals
.a
[anotherIndex
].x
= 42;
206 clang_analyzer_eval(vals
.a
[index
].x
== 42); // expected-warning{{UNKNOWN}}
207 clang_analyzer_eval(vals
.a
[index
].y
== 42); // expected-warning{{TRUE}}
209 // FIXME: False negative. No bind ever set a field 'z'.
210 return vals
.a
[index
].z
; // no-warning
213 int testStructFieldChains(int index
, int anotherIndex
) {
216 vals
[index
].a
[0].x
= 42;
217 vals
[anotherIndex
].a
[1].y
= 42;
218 clang_analyzer_eval(vals
[index
].a
[0].x
== 42); // expected-warning{{TRUE}}
219 clang_analyzer_eval(vals
[anotherIndex
].a
[1].y
== 42); // expected-warning{{TRUE}}
221 // This doesn't affect anything in the 'a' array field.
222 vals
[anotherIndex
].b
[1].x
= 42;
223 clang_analyzer_eval(vals
[index
].a
[0].x
== 42); // expected-warning{{TRUE}}
224 clang_analyzer_eval(vals
[anotherIndex
].a
[1].y
== 42); // expected-warning{{TRUE}}
225 clang_analyzer_eval(vals
[anotherIndex
].b
[1].x
== 42); // expected-warning{{TRUE}}
227 // This doesn't affect anything in the 'b' array field.
228 vals
[index
].a
[anotherIndex
].x
= 42;
229 clang_analyzer_eval(vals
[index
].a
[0].x
== 42); // expected-warning{{UNKNOWN}}
230 clang_analyzer_eval(vals
[anotherIndex
].a
[0].x
== 42); // expected-warning{{UNKNOWN}}
231 clang_analyzer_eval(vals
[anotherIndex
].a
[1].y
== 42); // expected-warning{{TRUE}}
232 clang_analyzer_eval(vals
[anotherIndex
].b
[1].x
== 42); // expected-warning{{TRUE}}
234 // FIXME: False negative. No bind ever set a field 'z'.
235 return vals
[index
].a
[0].z
; // no-warning
238 int testStructFieldChainsNested(int index
, int anotherIndex
) {
241 vals
[index
].a
[0].x
= 42;
242 clang_analyzer_eval(vals
[index
].a
[0].x
== 42); // expected-warning{{TRUE}}
244 vals
[index
].b
[0] = makeS();
245 clang_analyzer_eval(vals
[index
].a
[0].x
== 42); // expected-warning{{TRUE}}
247 vals
[index
].a
[0] = makeS();
248 clang_analyzer_eval(vals
[index
].a
[0].x
== 42); // expected-warning{{UNKNOWN}}
250 vals
[index
].a
[0].x
= 42;
251 clang_analyzer_eval(vals
[index
].a
[0].x
== 42); // expected-warning{{TRUE}}
261 extern int test13116945(struct point x
);
262 static void radar13116945(struct point centerCoordinate
) {
264 zoomRegion
.zoomLevel
= 0;
265 zoomRegion
.center
= centerCoordinate
;
266 Outer r
= zoomRegion
;
267 test13116945(r
.center
); // no-warning
278 } ShortStringWrapper
;
280 void testArrayStructCopy(void) {
281 ShortString s
= { "abc" };
285 clang_analyzer_eval(s3
.data
[0] == 'a'); // expected-warning{{TRUE}}
286 clang_analyzer_eval(s3
.data
[1] == 'b'); // expected-warning{{TRUE}}
287 clang_analyzer_eval(s3
.data
[2] == 'c'); // expected-warning{{TRUE}}
292 clang_analyzer_eval(s4
.data
[0] == 'z'); // expected-warning{{TRUE}}
293 clang_analyzer_eval(s4
.data
[1] == 'b'); // expected-warning{{TRUE}}
294 clang_analyzer_eval(s4
.data
[2] == 'c'); // expected-warning{{TRUE}}
297 void testArrayStructCopyNested(void) {
298 ShortString s
= { "abc" };
301 ShortStringWrapper w
= { s2
, 0 };
303 clang_analyzer_eval(w
.str
.data
[0] == 'a'); // expected-warning{{TRUE}}
304 clang_analyzer_eval(w
.str
.data
[1] == 'b'); // expected-warning{{TRUE}}
305 clang_analyzer_eval(w
.str
.data
[2] == 'c'); // expected-warning{{TRUE}}
306 clang_analyzer_eval(w
.length
== 0); // expected-warning{{TRUE}}
308 ShortStringWrapper w2
= w
;
309 clang_analyzer_eval(w2
.str
.data
[0] == 'a'); // expected-warning{{TRUE}}
310 clang_analyzer_eval(w2
.str
.data
[1] == 'b'); // expected-warning{{TRUE}}
311 clang_analyzer_eval(w2
.str
.data
[2] == 'c'); // expected-warning{{TRUE}}
312 clang_analyzer_eval(w2
.length
== 0); // expected-warning{{TRUE}}
314 ShortStringWrapper w3
= w2
;
315 clang_analyzer_eval(w3
.str
.data
[0] == 'a'); // expected-warning{{TRUE}}
316 clang_analyzer_eval(w3
.str
.data
[1] == 'b'); // expected-warning{{TRUE}}
317 clang_analyzer_eval(w3
.str
.data
[2] == 'c'); // expected-warning{{TRUE}}
318 clang_analyzer_eval(w3
.length
== 0); // expected-warning{{TRUE}}
321 // --------------------
323 // --------------------
325 int testMixSymbolicAndConcrete(int index
, int anotherIndex
) {
328 vals
.a
[index
].x
= 42;
331 // FIXME: Should be TRUE.
332 clang_analyzer_eval(vals
.a
[index
].x
== 42); // expected-warning{{UNKNOWN}}
333 // Should be TRUE; we set this explicitly.
334 clang_analyzer_eval(vals
.a
[0].y
== 42); // expected-warning{{TRUE}}
336 vals
.a
[anotherIndex
].y
= 42;
338 // Should be UNKNOWN; we set an 'x'.
339 clang_analyzer_eval(vals
.a
[index
].x
== 42); // expected-warning{{UNKNOWN}}
340 // FIXME: Should be TRUE.
341 clang_analyzer_eval(vals
.a
[0].y
== 42); // expected-warning{{UNKNOWN}}
343 return vals
.a
[0].x
; // no-warning
346 void testFieldChainIsNotEnough(int index
) {
349 vals
[index
].a
[0].x
= 42;
350 clang_analyzer_eval(vals
[index
].a
[0].x
== 42); // expected-warning{{TRUE}}
352 vals
[index
].a
[1] = makeS();
353 // FIXME: Should be TRUE.
354 clang_analyzer_eval(vals
[index
].a
[0].x
== 42); // expected-warning{{UNKNOWN}}