xref: /minix3/external/bsd/llvm/dist/clang/test/Analysis/array-struct-region.c (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-constraints=range -verify %s
2*f4a2713aSLionel Sambuc 
3*f4a2713aSLionel Sambuc void clang_analyzer_eval(int);
4*f4a2713aSLionel Sambuc 
string_literal_init()5*f4a2713aSLionel Sambuc int string_literal_init() {
6*f4a2713aSLionel Sambuc   char a[] = "abc";
7*f4a2713aSLionel Sambuc   char b[2] = "abc"; // expected-warning{{too long}}
8*f4a2713aSLionel Sambuc   char c[5] = "abc";
9*f4a2713aSLionel Sambuc 
10*f4a2713aSLionel Sambuc   clang_analyzer_eval(a[1] == 'b'); // expected-warning{{TRUE}}
11*f4a2713aSLionel Sambuc   clang_analyzer_eval(b[1] == 'b'); // expected-warning{{TRUE}}
12*f4a2713aSLionel Sambuc   clang_analyzer_eval(c[1] == 'b'); // expected-warning{{TRUE}}
13*f4a2713aSLionel Sambuc 
14*f4a2713aSLionel Sambuc   clang_analyzer_eval(a[3] == 0); // expected-warning{{TRUE}}
15*f4a2713aSLionel Sambuc   clang_analyzer_eval(c[3] == 0); // expected-warning{{TRUE}}
16*f4a2713aSLionel Sambuc 
17*f4a2713aSLionel Sambuc   clang_analyzer_eval(c[4] == 0); // expected-warning{{TRUE}}
18*f4a2713aSLionel Sambuc 
19*f4a2713aSLionel Sambuc   return 42;
20*f4a2713aSLionel Sambuc }
21*f4a2713aSLionel Sambuc 
nested_compound_literals(int rad)22*f4a2713aSLionel Sambuc void nested_compound_literals(int rad) {
23*f4a2713aSLionel Sambuc   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*f4a2713aSLionel Sambuc                    {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}}; // expected-warning 6 {{implicit conversion from 'double' to 'int' changes value from}}
25*f4a2713aSLionel Sambuc   int a;
26*f4a2713aSLionel Sambuc 
27*f4a2713aSLionel Sambuc   for (a = 0; a < 6; ++a) {
28*f4a2713aSLionel Sambuc       vec[a][0] *= rad; // no-warning
29*f4a2713aSLionel Sambuc       vec[a][1] *= rad; // no-warning
30*f4a2713aSLionel Sambuc   }
31*f4a2713aSLionel Sambuc }
32*f4a2713aSLionel Sambuc 
nested_compound_literals_float(float rad)33*f4a2713aSLionel Sambuc void nested_compound_literals_float(float rad) {
34*f4a2713aSLionel Sambuc   float vec[6][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169},
35*f4a2713aSLionel Sambuc                      {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
36*f4a2713aSLionel Sambuc   int a;
37*f4a2713aSLionel Sambuc 
38*f4a2713aSLionel Sambuc   for (a = 0; a < 6; ++a) {
39*f4a2713aSLionel Sambuc       vec[a][0] *= rad; // no-warning
40*f4a2713aSLionel Sambuc       vec[a][1] *= rad; // no-warning
41*f4a2713aSLionel Sambuc   }
42*f4a2713aSLionel Sambuc }
43*f4a2713aSLionel Sambuc 
44*f4a2713aSLionel Sambuc 
struct_as_array()45*f4a2713aSLionel Sambuc void struct_as_array() {
46*f4a2713aSLionel Sambuc   struct simple { int x; int y; };
47*f4a2713aSLionel Sambuc   struct simple a;
48*f4a2713aSLionel Sambuc   struct simple *p = &a;
49*f4a2713aSLionel Sambuc 
50*f4a2713aSLionel Sambuc   p->x = 5;
51*f4a2713aSLionel Sambuc   clang_analyzer_eval(a.x == 5); // expected-warning{{TRUE}}
52*f4a2713aSLionel Sambuc   clang_analyzer_eval(p[0].x == 5); // expected-warning{{TRUE}}
53*f4a2713aSLionel Sambuc 
54*f4a2713aSLionel Sambuc   p[0].y = 5;
55*f4a2713aSLionel Sambuc   clang_analyzer_eval(a.y == 5); // expected-warning{{TRUE}}
56*f4a2713aSLionel Sambuc   clang_analyzer_eval(p->y == 5); // expected-warning{{TRUE}}
57*f4a2713aSLionel Sambuc }
58*f4a2713aSLionel Sambuc 
59*f4a2713aSLionel Sambuc 
60*f4a2713aSLionel Sambuc // PR13264 / <rdar://problem/11802440>
61*f4a2713aSLionel Sambuc struct point { int x; int y; };
62*f4a2713aSLionel Sambuc struct circle { struct point o; int r; };
get_circle()63*f4a2713aSLionel Sambuc struct circle get_circle() {
64*f4a2713aSLionel Sambuc   struct circle result;
65*f4a2713aSLionel Sambuc   result.r = 5;
66*f4a2713aSLionel Sambuc   result.o = (struct point){0, 0};
67*f4a2713aSLionel Sambuc   return result;
68*f4a2713aSLionel Sambuc }
69*f4a2713aSLionel Sambuc 
struct_in_struct()70*f4a2713aSLionel Sambuc void struct_in_struct() {
71*f4a2713aSLionel Sambuc   struct circle c;
72*f4a2713aSLionel Sambuc   c = get_circle();
73*f4a2713aSLionel Sambuc   // This used to think c.r was undefined because c.o is a LazyCompoundVal.
74*f4a2713aSLionel Sambuc   clang_analyzer_eval(c.r == 5); // expected-warning{{TRUE}}
75*f4a2713aSLionel Sambuc }
76*f4a2713aSLionel Sambuc 
77*f4a2713aSLionel Sambuc // We also test with floats because we don't model floats right now,
78*f4a2713aSLionel Sambuc // and the original bug report used a float.
79*f4a2713aSLionel Sambuc struct circle_f { struct point o; float r; };
get_circle_f()80*f4a2713aSLionel Sambuc struct circle_f get_circle_f() {
81*f4a2713aSLionel Sambuc   struct circle_f result;
82*f4a2713aSLionel Sambuc   result.r = 5.0;
83*f4a2713aSLionel Sambuc   result.o = (struct point){0, 0};
84*f4a2713aSLionel Sambuc   return result;
85*f4a2713aSLionel Sambuc }
86*f4a2713aSLionel Sambuc 
struct_in_struct_f()87*f4a2713aSLionel Sambuc float struct_in_struct_f() {
88*f4a2713aSLionel Sambuc   struct circle_f c;
89*f4a2713aSLionel Sambuc   c = get_circle_f();
90*f4a2713aSLionel Sambuc 
91*f4a2713aSLionel Sambuc   return c.r; // no-warning
92*f4a2713aSLionel Sambuc }
93*f4a2713aSLionel Sambuc 
94*f4a2713aSLionel Sambuc 
95*f4a2713aSLionel Sambuc int randomInt();
96*f4a2713aSLionel Sambuc 
testSymbolicInvalidation(int index)97*f4a2713aSLionel Sambuc int testSymbolicInvalidation(int index) {
98*f4a2713aSLionel Sambuc   int vals[10];
99*f4a2713aSLionel Sambuc 
100*f4a2713aSLionel Sambuc   vals[0] = 42;
101*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[0] == 42); // expected-warning{{TRUE}}
102*f4a2713aSLionel Sambuc 
103*f4a2713aSLionel Sambuc   vals[index] = randomInt();
104*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[0] == 42); // expected-warning{{UNKNOWN}}
105*f4a2713aSLionel Sambuc 
106*f4a2713aSLionel Sambuc   return vals[index]; // no-warning
107*f4a2713aSLionel Sambuc }
108*f4a2713aSLionel Sambuc 
testConcreteInvalidation(int index)109*f4a2713aSLionel Sambuc int testConcreteInvalidation(int index) {
110*f4a2713aSLionel Sambuc   int vals[10];
111*f4a2713aSLionel Sambuc 
112*f4a2713aSLionel Sambuc   vals[index] = 42;
113*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[index] == 42); // expected-warning{{TRUE}}
114*f4a2713aSLionel Sambuc   vals[0] = randomInt();
115*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[index] == 42); // expected-warning{{UNKNOWN}}
116*f4a2713aSLionel Sambuc 
117*f4a2713aSLionel Sambuc   return vals[0]; // no-warning
118*f4a2713aSLionel Sambuc }
119*f4a2713aSLionel Sambuc 
120*f4a2713aSLionel Sambuc 
121*f4a2713aSLionel Sambuc typedef struct {
122*f4a2713aSLionel Sambuc   int x, y, z;
123*f4a2713aSLionel Sambuc } S;
124*f4a2713aSLionel Sambuc 
125*f4a2713aSLionel Sambuc S makeS();
126*f4a2713aSLionel Sambuc 
testSymbolicInvalidationStruct(int index)127*f4a2713aSLionel Sambuc int testSymbolicInvalidationStruct(int index) {
128*f4a2713aSLionel Sambuc   S vals[10];
129*f4a2713aSLionel Sambuc 
130*f4a2713aSLionel Sambuc   vals[0].x = 42;
131*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[0].x == 42); // expected-warning{{TRUE}}
132*f4a2713aSLionel Sambuc 
133*f4a2713aSLionel Sambuc   vals[index] = makeS();
134*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[0].x == 42); // expected-warning{{UNKNOWN}}
135*f4a2713aSLionel Sambuc 
136*f4a2713aSLionel Sambuc   return vals[index].x; // no-warning
137*f4a2713aSLionel Sambuc }
138*f4a2713aSLionel Sambuc 
testConcreteInvalidationStruct(int index)139*f4a2713aSLionel Sambuc int testConcreteInvalidationStruct(int index) {
140*f4a2713aSLionel Sambuc   S vals[10];
141*f4a2713aSLionel Sambuc 
142*f4a2713aSLionel Sambuc   vals[index].x = 42;
143*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[index].x == 42); // expected-warning{{TRUE}}
144*f4a2713aSLionel Sambuc   vals[0] = makeS();
145*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[index].x == 42); // expected-warning{{UNKNOWN}}
146*f4a2713aSLionel Sambuc 
147*f4a2713aSLionel Sambuc   return vals[0].x; // no-warning
148*f4a2713aSLionel Sambuc }
149*f4a2713aSLionel Sambuc 
150*f4a2713aSLionel Sambuc typedef struct {
151*f4a2713aSLionel Sambuc   S a[5];
152*f4a2713aSLionel Sambuc   S b[5];
153*f4a2713aSLionel Sambuc } SS;
154*f4a2713aSLionel Sambuc 
testSymbolicInvalidationDoubleStruct(int index)155*f4a2713aSLionel Sambuc int testSymbolicInvalidationDoubleStruct(int index) {
156*f4a2713aSLionel Sambuc   SS vals;
157*f4a2713aSLionel Sambuc 
158*f4a2713aSLionel Sambuc   vals.a[0].x = 42;
159*f4a2713aSLionel Sambuc   vals.b[0].x = 42;
160*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals.a[0].x == 42); // expected-warning{{TRUE}}
161*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals.b[0].x == 42); // expected-warning{{TRUE}}
162*f4a2713aSLionel Sambuc 
163*f4a2713aSLionel Sambuc   vals.a[index] = makeS();
164*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals.a[0].x == 42); // expected-warning{{UNKNOWN}}
165*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals.b[0].x == 42); // expected-warning{{TRUE}}
166*f4a2713aSLionel Sambuc 
167*f4a2713aSLionel Sambuc   return vals.b[index].x; // no-warning
168*f4a2713aSLionel Sambuc }
169*f4a2713aSLionel Sambuc 
testConcreteInvalidationDoubleStruct(int index)170*f4a2713aSLionel Sambuc int testConcreteInvalidationDoubleStruct(int index) {
171*f4a2713aSLionel Sambuc   SS vals;
172*f4a2713aSLionel Sambuc 
173*f4a2713aSLionel Sambuc   vals.a[index].x = 42;
174*f4a2713aSLionel Sambuc   vals.b[index].x = 42;
175*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals.a[index].x == 42); // expected-warning{{TRUE}}
176*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals.b[index].x == 42); // expected-warning{{TRUE}}
177*f4a2713aSLionel Sambuc 
178*f4a2713aSLionel Sambuc   vals.a[0] = makeS();
179*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals.a[index].x == 42); // expected-warning{{UNKNOWN}}
180*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals.b[index].x == 42); // expected-warning{{TRUE}}
181*f4a2713aSLionel Sambuc 
182*f4a2713aSLionel Sambuc   return vals.b[0].x; // no-warning
183*f4a2713aSLionel Sambuc }
184*f4a2713aSLionel Sambuc 
185*f4a2713aSLionel Sambuc 
testNonOverlappingStructFieldsSimple()186*f4a2713aSLionel Sambuc int testNonOverlappingStructFieldsSimple() {
187*f4a2713aSLionel Sambuc   S val;
188*f4a2713aSLionel Sambuc 
189*f4a2713aSLionel Sambuc   val.x = 1;
190*f4a2713aSLionel Sambuc   val.y = 2;
191*f4a2713aSLionel Sambuc   clang_analyzer_eval(val.x == 1); // expected-warning{{TRUE}}
192*f4a2713aSLionel Sambuc   clang_analyzer_eval(val.y == 2); // expected-warning{{TRUE}}
193*f4a2713aSLionel Sambuc 
194*f4a2713aSLionel Sambuc   return val.z; // expected-warning{{garbage}}
195*f4a2713aSLionel Sambuc }
196*f4a2713aSLionel Sambuc 
testNonOverlappingStructFieldsSymbolicBase(int index,int anotherIndex)197*f4a2713aSLionel Sambuc int testNonOverlappingStructFieldsSymbolicBase(int index, int anotherIndex) {
198*f4a2713aSLionel Sambuc   SS vals;
199*f4a2713aSLionel Sambuc 
200*f4a2713aSLionel Sambuc   vals.a[index].x = 42;
201*f4a2713aSLionel Sambuc   vals.a[index].y = 42;
202*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals.a[index].x == 42); // expected-warning{{TRUE}}
203*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals.a[index].y == 42); // expected-warning{{TRUE}}
204*f4a2713aSLionel Sambuc 
205*f4a2713aSLionel Sambuc   vals.a[anotherIndex].x = 42;
206*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals.a[index].x == 42); // expected-warning{{UNKNOWN}}
207*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals.a[index].y == 42); // expected-warning{{TRUE}}
208*f4a2713aSLionel Sambuc 
209*f4a2713aSLionel Sambuc   // FIXME: False negative. No bind ever set a field 'z'.
210*f4a2713aSLionel Sambuc   return vals.a[index].z; // no-warning
211*f4a2713aSLionel Sambuc }
212*f4a2713aSLionel Sambuc 
testStructFieldChains(int index,int anotherIndex)213*f4a2713aSLionel Sambuc int testStructFieldChains(int index, int anotherIndex) {
214*f4a2713aSLionel Sambuc   SS vals[4];
215*f4a2713aSLionel Sambuc 
216*f4a2713aSLionel Sambuc   vals[index].a[0].x = 42;
217*f4a2713aSLionel Sambuc   vals[anotherIndex].a[1].y = 42;
218*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[index].a[0].x == 42); // expected-warning{{TRUE}}
219*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[anotherIndex].a[1].y == 42); // expected-warning{{TRUE}}
220*f4a2713aSLionel Sambuc 
221*f4a2713aSLionel Sambuc   // This doesn't affect anything in the 'a' array field.
222*f4a2713aSLionel Sambuc   vals[anotherIndex].b[1].x = 42;
223*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[index].a[0].x == 42); // expected-warning{{TRUE}}
224*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[anotherIndex].a[1].y == 42); // expected-warning{{TRUE}}
225*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[anotherIndex].b[1].x == 42); // expected-warning{{TRUE}}
226*f4a2713aSLionel Sambuc 
227*f4a2713aSLionel Sambuc   // This doesn't affect anything in the 'b' array field.
228*f4a2713aSLionel Sambuc   vals[index].a[anotherIndex].x = 42;
229*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[index].a[0].x == 42); // expected-warning{{UNKNOWN}}
230*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[anotherIndex].a[0].x == 42); // expected-warning{{UNKNOWN}}
231*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[anotherIndex].a[1].y == 42); // expected-warning{{TRUE}}
232*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[anotherIndex].b[1].x == 42); // expected-warning{{TRUE}}
233*f4a2713aSLionel Sambuc 
234*f4a2713aSLionel Sambuc   // FIXME: False negative. No bind ever set a field 'z'.
235*f4a2713aSLionel Sambuc   return vals[index].a[0].z; // no-warning
236*f4a2713aSLionel Sambuc }
237*f4a2713aSLionel Sambuc 
testStructFieldChainsNested(int index,int anotherIndex)238*f4a2713aSLionel Sambuc int testStructFieldChainsNested(int index, int anotherIndex) {
239*f4a2713aSLionel Sambuc   SS vals[4];
240*f4a2713aSLionel Sambuc 
241*f4a2713aSLionel Sambuc   vals[index].a[0].x = 42;
242*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[index].a[0].x == 42); // expected-warning{{TRUE}}
243*f4a2713aSLionel Sambuc 
244*f4a2713aSLionel Sambuc   vals[index].b[0] = makeS();
245*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[index].a[0].x == 42); // expected-warning{{TRUE}}
246*f4a2713aSLionel Sambuc 
247*f4a2713aSLionel Sambuc   vals[index].a[0] = makeS();
248*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[index].a[0].x == 42); // expected-warning{{UNKNOWN}}
249*f4a2713aSLionel Sambuc 
250*f4a2713aSLionel Sambuc   vals[index].a[0].x = 42;
251*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[index].a[0].x == 42); // expected-warning{{TRUE}}
252*f4a2713aSLionel Sambuc 
253*f4a2713aSLionel Sambuc   return 0;
254*f4a2713aSLionel Sambuc }
255*f4a2713aSLionel Sambuc 
256*f4a2713aSLionel Sambuc typedef struct {
257*f4a2713aSLionel Sambuc   int zoomLevel;
258*f4a2713aSLionel Sambuc   struct point center;
259*f4a2713aSLionel Sambuc } Outer;
260*f4a2713aSLionel Sambuc 
261*f4a2713aSLionel Sambuc extern int test13116945(struct point x);
radar13116945(struct point centerCoordinate)262*f4a2713aSLionel Sambuc static void radar13116945(struct point centerCoordinate) {
263*f4a2713aSLionel Sambuc   Outer zoomRegion;
264*f4a2713aSLionel Sambuc   zoomRegion.zoomLevel = 0;
265*f4a2713aSLionel Sambuc   zoomRegion.center = centerCoordinate;
266*f4a2713aSLionel Sambuc   Outer r = zoomRegion;
267*f4a2713aSLionel Sambuc   test13116945(r.center); // no-warning
268*f4a2713aSLionel Sambuc }
269*f4a2713aSLionel Sambuc 
270*f4a2713aSLionel Sambuc 
271*f4a2713aSLionel Sambuc typedef struct {
272*f4a2713aSLionel Sambuc   char data[4];
273*f4a2713aSLionel Sambuc } ShortString;
274*f4a2713aSLionel Sambuc 
275*f4a2713aSLionel Sambuc typedef struct {
276*f4a2713aSLionel Sambuc   ShortString str;
277*f4a2713aSLionel Sambuc   int length;
278*f4a2713aSLionel Sambuc } ShortStringWrapper;
279*f4a2713aSLionel Sambuc 
testArrayStructCopy()280*f4a2713aSLionel Sambuc void testArrayStructCopy() {
281*f4a2713aSLionel Sambuc   ShortString s = { "abc" };
282*f4a2713aSLionel Sambuc   ShortString s2 = s;
283*f4a2713aSLionel Sambuc   ShortString s3 = s2;
284*f4a2713aSLionel Sambuc 
285*f4a2713aSLionel Sambuc   clang_analyzer_eval(s3.data[0] == 'a'); // expected-warning{{TRUE}}
286*f4a2713aSLionel Sambuc   clang_analyzer_eval(s3.data[1] == 'b'); // expected-warning{{TRUE}}
287*f4a2713aSLionel Sambuc   clang_analyzer_eval(s3.data[2] == 'c'); // expected-warning{{TRUE}}
288*f4a2713aSLionel Sambuc 
289*f4a2713aSLionel Sambuc   s3.data[0] = 'z';
290*f4a2713aSLionel Sambuc   ShortString s4 = s3;
291*f4a2713aSLionel Sambuc 
292*f4a2713aSLionel Sambuc   clang_analyzer_eval(s4.data[0] == 'z'); // expected-warning{{TRUE}}
293*f4a2713aSLionel Sambuc   clang_analyzer_eval(s4.data[1] == 'b'); // expected-warning{{TRUE}}
294*f4a2713aSLionel Sambuc   clang_analyzer_eval(s4.data[2] == 'c'); // expected-warning{{TRUE}}
295*f4a2713aSLionel Sambuc }
296*f4a2713aSLionel Sambuc 
testArrayStructCopyNested()297*f4a2713aSLionel Sambuc void testArrayStructCopyNested() {
298*f4a2713aSLionel Sambuc   ShortString s = { "abc" };
299*f4a2713aSLionel Sambuc   ShortString s2 = s;
300*f4a2713aSLionel Sambuc 
301*f4a2713aSLionel Sambuc   ShortStringWrapper w = { s2, 0 };
302*f4a2713aSLionel Sambuc 
303*f4a2713aSLionel Sambuc   clang_analyzer_eval(w.str.data[0] == 'a'); // expected-warning{{TRUE}}
304*f4a2713aSLionel Sambuc   clang_analyzer_eval(w.str.data[1] == 'b'); // expected-warning{{TRUE}}
305*f4a2713aSLionel Sambuc   clang_analyzer_eval(w.str.data[2] == 'c'); // expected-warning{{TRUE}}
306*f4a2713aSLionel Sambuc   clang_analyzer_eval(w.length == 0); // expected-warning{{TRUE}}
307*f4a2713aSLionel Sambuc 
308*f4a2713aSLionel Sambuc   ShortStringWrapper w2 = w;
309*f4a2713aSLionel Sambuc   clang_analyzer_eval(w2.str.data[0] == 'a'); // expected-warning{{TRUE}}
310*f4a2713aSLionel Sambuc   clang_analyzer_eval(w2.str.data[1] == 'b'); // expected-warning{{TRUE}}
311*f4a2713aSLionel Sambuc   clang_analyzer_eval(w2.str.data[2] == 'c'); // expected-warning{{TRUE}}
312*f4a2713aSLionel Sambuc   clang_analyzer_eval(w2.length == 0); // expected-warning{{TRUE}}
313*f4a2713aSLionel Sambuc 
314*f4a2713aSLionel Sambuc   ShortStringWrapper w3 = w2;
315*f4a2713aSLionel Sambuc   clang_analyzer_eval(w3.str.data[0] == 'a'); // expected-warning{{TRUE}}
316*f4a2713aSLionel Sambuc   clang_analyzer_eval(w3.str.data[1] == 'b'); // expected-warning{{TRUE}}
317*f4a2713aSLionel Sambuc   clang_analyzer_eval(w3.str.data[2] == 'c'); // expected-warning{{TRUE}}
318*f4a2713aSLionel Sambuc   clang_analyzer_eval(w3.length == 0); // expected-warning{{TRUE}}
319*f4a2713aSLionel Sambuc }
320*f4a2713aSLionel Sambuc 
321*f4a2713aSLionel Sambuc // --------------------
322*f4a2713aSLionel Sambuc // False positives
323*f4a2713aSLionel Sambuc // --------------------
324*f4a2713aSLionel Sambuc 
testMixSymbolicAndConcrete(int index,int anotherIndex)325*f4a2713aSLionel Sambuc int testMixSymbolicAndConcrete(int index, int anotherIndex) {
326*f4a2713aSLionel Sambuc   SS vals;
327*f4a2713aSLionel Sambuc 
328*f4a2713aSLionel Sambuc   vals.a[index].x = 42;
329*f4a2713aSLionel Sambuc   vals.a[0].y = 42;
330*f4a2713aSLionel Sambuc 
331*f4a2713aSLionel Sambuc   // FIXME: Should be TRUE.
332*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals.a[index].x == 42); // expected-warning{{UNKNOWN}}
333*f4a2713aSLionel Sambuc   // Should be TRUE; we set this explicitly.
334*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals.a[0].y == 42); // expected-warning{{TRUE}}
335*f4a2713aSLionel Sambuc 
336*f4a2713aSLionel Sambuc   vals.a[anotherIndex].y = 42;
337*f4a2713aSLionel Sambuc 
338*f4a2713aSLionel Sambuc   // Should be UNKNOWN; we set an 'x'.
339*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals.a[index].x == 42); // expected-warning{{UNKNOWN}}
340*f4a2713aSLionel Sambuc   // FIXME: Should be TRUE.
341*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals.a[0].y == 42); // expected-warning{{UNKNOWN}}
342*f4a2713aSLionel Sambuc 
343*f4a2713aSLionel Sambuc   return vals.a[0].x; // no-warning
344*f4a2713aSLionel Sambuc }
345*f4a2713aSLionel Sambuc 
testFieldChainIsNotEnough(int index)346*f4a2713aSLionel Sambuc void testFieldChainIsNotEnough(int index) {
347*f4a2713aSLionel Sambuc   SS vals[4];
348*f4a2713aSLionel Sambuc 
349*f4a2713aSLionel Sambuc   vals[index].a[0].x = 42;
350*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[index].a[0].x == 42); // expected-warning{{TRUE}}
351*f4a2713aSLionel Sambuc 
352*f4a2713aSLionel Sambuc   vals[index].a[1] = makeS();
353*f4a2713aSLionel Sambuc   // FIXME: Should be TRUE.
354*f4a2713aSLionel Sambuc   clang_analyzer_eval(vals[index].a[0].x == 42); // expected-warning{{UNKNOWN}}
355*f4a2713aSLionel Sambuc }
356