1 // Given code 'struct aa { char s1[4]; char * s2;} a; memcpy(a.s1, ...);',
2 // this test checks that the CStringChecker only invalidates the destination buffer array a.s1 (instead of a.s1 and a.s2).
3 // At the moment the whole of the destination array content is invalidated.
4 // If a.s1 region has a symbolic offset, the whole region of 'a' is invalidated.
5 // Specific triple set to test structures of size 0.
6 // RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,unix.Malloc,debug.ExprInspection -Wno-error=int-conversion -verify -analyzer-config eagerly-assume=false %s
7
8 typedef __typeof(sizeof(int)) size_t;
9
10 char *strdup(const char *s);
11 void free(void *);
12 void *memcpy(void *dst, const void *src, size_t n); // expected-note{{passing argument to parameter 'dst' here}}
13 void *malloc(size_t n);
14
15 void clang_analyzer_eval(int);
16
17 struct aa {
18 char s1[4];
19 char *s2;
20 };
21
22 // Test different types of structure initialisation.
f0(void)23 int f0(void) {
24 struct aa a0 = {{1, 2, 3, 4}, 0};
25 a0.s2 = strdup("hello");
26 char input[] = {'a', 'b', 'c', 'd'};
27 memcpy(a0.s1, input, 4);
28 clang_analyzer_eval(a0.s1[0] == 'a'); // expected-warning{{UNKNOWN}}
29 clang_analyzer_eval(a0.s1[1] == 'b'); // expected-warning{{UNKNOWN}}
30 clang_analyzer_eval(a0.s1[2] == 'c'); // expected-warning{{UNKNOWN}}
31 clang_analyzer_eval(a0.s1[3] == 'd'); // expected-warning{{UNKNOWN}}
32 clang_analyzer_eval(a0.s2 == 0); // expected-warning{{UNKNOWN}}
33 free(a0.s2); // no warning
34 return 0;
35 }
36
f1(void)37 int f1(void) {
38 struct aa a1;
39 a1.s2 = strdup("hello");
40 char input[] = {'a', 'b', 'c', 'd'};
41 memcpy(a1.s1, input, 4);
42 clang_analyzer_eval(a1.s1[0] == 'a'); // expected-warning{{UNKNOWN}}
43 clang_analyzer_eval(a1.s1[1] == 'b'); // expected-warning{{UNKNOWN}}
44 clang_analyzer_eval(a1.s1[2] == 'c'); // expected-warning{{UNKNOWN}}
45 clang_analyzer_eval(a1.s1[3] == 'd'); // expected-warning{{UNKNOWN}}
46 clang_analyzer_eval(a1.s2 == 0); // expected-warning{{UNKNOWN}}
47 free(a1.s2); // no warning
48 return 0;
49 }
50
f2(void)51 int f2(void) {
52 struct aa a2 = {{1, 2}};
53 a2.s2 = strdup("hello");
54 char input[] = {'a', 'b', 'c', 'd'};
55 memcpy(a2.s1, input, 4);
56 clang_analyzer_eval(a2.s1[0] == 'a'); // expected-warning{{UNKNOWN}}
57 clang_analyzer_eval(a2.s1[1] == 'b'); // expected-warning{{UNKNOWN}}
58 clang_analyzer_eval(a2.s1[2] == 'c'); // expected-warning{{UNKNOWN}}
59 clang_analyzer_eval(a2.s1[3] == 'd'); // expected-warning{{UNKNOWN}}
60 clang_analyzer_eval(a2.s2 == 0); // expected-warning{{UNKNOWN}}
61 free(a2.s2); // no warning
62 return 0;
63 }
64
f3(void)65 int f3(void) {
66 struct aa a3 = {{1, 2, 3, 4}, 0};
67 a3.s2 = strdup("hello");
68 char input[] = {'a', 'b', 'c', 'd'};
69 int * dest = (int*)a3.s1;
70 memcpy(dest, input, 4);
71 clang_analyzer_eval(a3.s1[0] == 'a'); // expected-warning{{UNKNOWN}}
72 clang_analyzer_eval(dest[0] == 'a'); // expected-warning{{UNKNOWN}}
73 clang_analyzer_eval(a3.s1[1] == 'b'); // expected-warning{{UNKNOWN}}
74 clang_analyzer_eval(dest[1] == 'b'); // expected-warning{{UNKNOWN}}
75 clang_analyzer_eval(a3.s1[2] == 'c'); // expected-warning{{UNKNOWN}}
76 clang_analyzer_eval(dest[2] == 'c'); // expected-warning{{UNKNOWN}}
77 clang_analyzer_eval(a3.s1[3] == 'd'); // expected-warning{{UNKNOWN}}
78 clang_analyzer_eval(dest[3] == 'd'); // expected-warning{{UNKNOWN}}
79 clang_analyzer_eval(a3.s2 == 0); // expected-warning{{UNKNOWN}}
80 free(a3.s2); // no warning
81 return 0;
82 }
83
84 struct bb {
85 struct aa a;
86 char * s2;
87 };
88
f4(void)89 int f4(void) {
90 struct bb b0 = {{1, 2, 3, 4}, 0};
91 b0.s2 = strdup("hello");
92 b0.a.s2 = strdup("hola");
93 char input[] = {'a', 'b', 'c', 'd'};
94 char * dest = (char*)(b0.a.s1);
95 memcpy(dest, input, 4);
96 clang_analyzer_eval(b0.a.s1[0] == 'a'); // expected-warning{{UNKNOWN}}
97 clang_analyzer_eval(dest[0] == 'a'); // expected-warning{{UNKNOWN}}
98 clang_analyzer_eval(b0.a.s1[1] == 'b'); // expected-warning{{UNKNOWN}}
99 clang_analyzer_eval(dest[1] == 'b'); // expected-warning{{UNKNOWN}}
100 clang_analyzer_eval(b0.a.s1[2] == 'c'); // expected-warning{{UNKNOWN}}
101 clang_analyzer_eval(dest[2] == 'c'); // expected-warning{{UNKNOWN}}
102 clang_analyzer_eval(b0.a.s1[3] == 'd'); // expected-warning{{UNKNOWN}}
103 clang_analyzer_eval(dest[3] == 'd'); // expected-warning{{UNKNOWN}}
104 clang_analyzer_eval(b0.s2 == 0); // expected-warning{{UNKNOWN}}
105 free(b0.a.s2); // no warning
106 free(b0.s2); // no warning
107 return 0;
108 }
109
110 // Test that memory leaks are caught.
f5(void)111 int f5(void) {
112 struct aa a0 = {{1, 2, 3, 4}, 0};
113 a0.s2 = strdup("hello");
114 char input[] = {'a', 'b', 'c', 'd'};
115 memcpy(a0.s1, input, 4);
116 return 0; // expected-warning{{Potential leak of memory pointed to by 'a0.s2'}}
117 }
118
f6(void)119 int f6(void) {
120 struct aa a1;
121 a1.s2 = strdup("hello");
122 char input[] = {'a', 'b', 'c', 'd'};
123 memcpy(a1.s1, input, 4);
124 return 0; // expected-warning{{Potential leak of memory pointed to by 'a1.s2'}}
125 }
126
f7(void)127 int f7(void) {
128 struct aa a2 = {{1, 2}};
129 a2.s2 = strdup("hello");
130 char input[] = {'a', 'b', 'c', 'd'};
131 memcpy(a2.s1, input, 4);
132 return 0; // expected-warning{{Potential leak of memory pointed to by 'a2.s2'}}
133 }
134
f8(void)135 int f8(void) {
136 struct aa a3 = {{1, 2, 3, 4}, 0};
137 a3.s2 = strdup("hello");
138 char input[] = {'a', 'b', 'c', 'd'};
139 int * dest = (int*)a3.s1;
140 memcpy(dest, input, 4);
141 return 0; // expected-warning{{Potential leak of memory pointed to by 'a3.s2'}}
142 }
143
f9(void)144 int f9(void) {
145 struct bb b0 = {{1, 2, 3, 4}, 0};
146 b0.s2 = strdup("hello");
147 b0.a.s2 = strdup("hola");
148 char input[] = {'a', 'b', 'c', 'd'};
149 char * dest = (char*)(b0.a.s1);
150 memcpy(dest, input, 4);
151 free(b0.a.s2); // expected-warning{{Potential leak of memory pointed to by 'b0.s2'}}
152 return 0;
153 }
154
f10(void)155 int f10(void) {
156 struct bb b0 = {{1, 2, 3, 4}, 0};
157 b0.s2 = strdup("hello");
158 b0.a.s2 = strdup("hola");
159 char input[] = {'a', 'b', 'c', 'd'};
160 char * dest = (char*)(b0.a.s1);
161 memcpy(dest, input, 4);
162 free(b0.s2); // expected-warning{{Potential leak of memory pointed to by 'b0.a.s2'}}
163 return 0;
164 }
165
166 // Test invalidating fields being addresses of array.
167 struct cc {
168 char * s1;
169 char * s2;
170 };
171
f11(void)172 int f11(void) {
173 char x[4] = {1, 2};
174 x[0] = 1;
175 x[1] = 2;
176 struct cc c0;
177 c0.s2 = strdup("hello");
178 c0.s1 = &x[0];
179 char input[] = {'a', 'b', 'c', 'd'};
180 memcpy(c0.s1, input, 4);
181 clang_analyzer_eval(x[0] == 1); // expected-warning{{UNKNOWN}}
182 clang_analyzer_eval(x[1] == 2); // expected-warning{{UNKNOWN}}
183 clang_analyzer_eval(c0.s1[0] == 'a'); // expected-warning{{UNKNOWN}}
184 clang_analyzer_eval(c0.s1[1] == 'b'); // expected-warning{{UNKNOWN}}
185 clang_analyzer_eval(c0.s1[2] == 'c'); // expected-warning{{UNKNOWN}}
186 clang_analyzer_eval(c0.s1[3] == 'd'); // expected-warning{{UNKNOWN}}
187 free(c0.s2); // no-warning
188 return 0;
189 }
190
191 // Test inverting field position between s1 and s2.
192 struct dd {
193 char *s2;
194 char s1[4];
195 };
196
f12(void)197 int f12(void) {
198 struct dd d0 = {0, {1, 2, 3, 4}};
199 d0.s2 = strdup("hello");
200 char input[] = {'a', 'b', 'c', 'd'};
201 memcpy(d0.s1, input, 4);
202 clang_analyzer_eval(d0.s1[0] == 'a'); // expected-warning{{UNKNOWN}}
203 clang_analyzer_eval(d0.s1[1] == 'b'); // expected-warning{{UNKNOWN}}
204 clang_analyzer_eval(d0.s1[2] == 'c'); // expected-warning{{UNKNOWN}}
205 clang_analyzer_eval(d0.s1[3] == 'd'); // expected-warning{{UNKNOWN}}
206 clang_analyzer_eval(d0.s2 == 0); // expected-warning{{UNKNOWN}}
207 free(d0.s2); // no warning
208 return 0;
209 }
210
211 // Test arrays of structs.
212 struct ee {
213 int a;
214 char b;
215 };
216
217 struct EE {
218 struct ee s1[2];
219 char * s2;
220 };
221
f13(void)222 int f13(void) {
223 struct EE E0 = {{{1, 2}, {3, 4}}, 0};
224 E0.s2 = strdup("hello");
225 char input[] = {'a', 'b', 'c', 'd'};
226 memcpy(E0.s1, input, 4);
227 clang_analyzer_eval(E0.s1[0].a == 'a'); // expected-warning{{UNKNOWN}}
228 clang_analyzer_eval(E0.s1[0].b == 'b'); // expected-warning{{UNKNOWN}}
229 clang_analyzer_eval(E0.s1[1].a == 'c'); // expected-warning{{UNKNOWN}}
230 clang_analyzer_eval(E0.s1[1].b == 'd'); // expected-warning{{UNKNOWN}}
231 clang_analyzer_eval(E0.s2 == 0); // expected-warning{{UNKNOWN}}
232 free(E0.s2); // no warning
233 return 0;
234 }
235
236 // Test global parameters.
237 struct aa a15 = {{1, 2, 3, 4}, 0};
238
f15(void)239 int f15(void) {
240 a15.s2 = strdup("hello");
241 char input[] = {'a', 'b', 'c', 'd'};
242 memcpy(a15.s1, input, 4);
243 clang_analyzer_eval(a15.s1[0] == 'a'); // expected-warning{{UNKNOWN}}
244 clang_analyzer_eval(a15.s1[1] == 'b'); // expected-warning{{UNKNOWN}}
245 clang_analyzer_eval(a15.s1[2] == 'c'); // expected-warning{{UNKNOWN}}
246 clang_analyzer_eval(a15.s1[3] == 'd'); // expected-warning{{UNKNOWN}}
247 clang_analyzer_eval(a15.s2 == 0); // expected-warning{{UNKNOWN}}
248 free(a15.s2); // no warning
249 return 0;
250 }
251
252 // Test array of 0 sized elements.
253 struct empty {};
254 struct gg {
255 struct empty s1[4];
256 char * s2;
257 };
258
f16(void)259 int f16(void) {
260 struct gg g0 = {{}, 0};
261 g0.s2 = strdup("hello");
262 char input[] = {'a', 'b', 'c', 'd'};
263 memcpy(g0.s1, input, 4);
264 clang_analyzer_eval(*(int*)(&g0.s1[0]) == 'a'); // expected-warning{{UNKNOWN}}\
265 expected-warning{{Potential leak of memory pointed to by 'g0.s2'}}
266 clang_analyzer_eval(*(int*)(&g0.s1[1]) == 'b'); // expected-warning{{UNKNOWN}}
267 clang_analyzer_eval(*(int*)(&g0.s1[2]) == 'c'); // expected-warning{{UNKNOWN}}
268 clang_analyzer_eval(*(int*)(&g0.s1[3]) == 'd'); // expected-warning{{UNKNOWN}}
269 clang_analyzer_eval(g0.s2 == 0); // expected-warning{{UNKNOWN}}
270 free(g0.s2); // no warning
271 return 0;
272 }
273
274 // Test array of 0 elements.
275 struct hh {
276 char s1[0];
277 char * s2;
278 };
279
f17(void)280 int f17(void) {
281 struct hh h0;
282 h0.s2 = strdup("hello");
283 char input[] = {'a', 'b', 'c', 'd'};
284 memcpy(h0.s1, input, 4);
285 clang_analyzer_eval(h0.s1[0] == 'a'); // expected-warning{{UNKNOWN}}\
286 expected-warning{{Potential leak of memory pointed to by 'h0.s2'}}
287 clang_analyzer_eval(h0.s2 == 0); // expected-warning{{UNKNOWN}}
288 free(h0.s2); // no warning
289 return 0;
290 }
291
292 // Test writing past the array.
293 struct ii {
294 char s1[4];
295 int i;
296 int j;
297 char * s2;
298 };
299
f18(void)300 int f18(void) {
301 struct ii i18 = {{1, 2, 3, 4}, 5, 6};
302 i18.i = 10;
303 i18.j = 11;
304 i18.s2 = strdup("hello");
305 char input[100] = {3};
306 memcpy(i18.s1, input, 100); // expected-warning {{'memcpy' will always overflow; destination buffer has size 24, but size argument is 100}}
307 clang_analyzer_eval(i18.s1[0] == 1); // expected-warning{{UNKNOWN}}\
308 expected-warning{{Potential leak of memory pointed to by 'i18.s2'}}
309 clang_analyzer_eval(i18.s1[1] == 2); // expected-warning{{UNKNOWN}}
310 clang_analyzer_eval(i18.s1[2] == 3); // expected-warning{{UNKNOWN}}
311 clang_analyzer_eval(i18.s1[3] == 4); // expected-warning{{UNKNOWN}}
312 clang_analyzer_eval(i18.i == 10); // expected-warning{{UNKNOWN}}
313 clang_analyzer_eval(i18.j == 11); // expected-warning{{UNKNOWN}}
314 return 0;
315 }
316
f181(void)317 int f181(void) {
318 struct ii i181 = {{1, 2, 3, 4}, 5, 6};
319 i181.i = 10;
320 i181.j = 11;
321 i181.s2 = strdup("hello");
322 char input[100] = {3};
323 memcpy(i181.s1, input, 5); // invalidate the whole region of i181
324 clang_analyzer_eval(i181.s1[0] == 1); // expected-warning{{UNKNOWN}}\
325 expected-warning{{Potential leak of memory pointed to by 'i181.s2'}}
326 clang_analyzer_eval(i181.s1[1] == 2); // expected-warning{{UNKNOWN}}
327 clang_analyzer_eval(i181.s1[2] == 3); // expected-warning{{UNKNOWN}}
328 clang_analyzer_eval(i181.s1[3] == 4); // expected-warning{{UNKNOWN}}
329 clang_analyzer_eval(i181.i == 10); // expected-warning{{UNKNOWN}}
330 clang_analyzer_eval(i181.j == 11); // expected-warning{{UNKNOWN}}
331 return 0;
332 }
333
334 // Test array with a symbolic offset.
335 struct jj {
336 char s1[2];
337 char * s2;
338 };
339
340 struct JJ {
341 struct jj s1[3];
342 char * s2;
343 };
344
f19(int i)345 int f19(int i) {
346 struct JJ J0 = {{{1, 2, 0}, {3, 4, 0}, {5, 6, 0}}, 0};
347 J0.s2 = strdup("hello");
348 J0.s1[0].s2 = strdup("hello");
349 J0.s1[1].s2 = strdup("hi");
350 J0.s1[2].s2 = strdup("world");
351 char input[2] = {'a', 'b'};
352 memcpy(J0.s1[i].s1, input, 2);
353 clang_analyzer_eval(J0.s1[0].s1[0] == 1); // expected-warning{{UNKNOWN}}\
354 expected-warning{{Potential leak of memory pointed to by field 's2'}}\
355 expected-warning{{Potential leak of memory pointed to by field 's2'}}\
356 expected-warning{{Potential leak of memory pointed to by field 's2'}}\
357 expected-warning{{Potential leak of memory pointed to by 'J0.s2'}}
358 clang_analyzer_eval(J0.s1[0].s1[1] == 2); // expected-warning{{UNKNOWN}}
359 clang_analyzer_eval(J0.s1[1].s1[0] == 3); // expected-warning{{UNKNOWN}}
360 clang_analyzer_eval(J0.s1[1].s1[1] == 4); // expected-warning{{UNKNOWN}}
361 clang_analyzer_eval(J0.s1[2].s1[0] == 5); // expected-warning{{UNKNOWN}}
362 clang_analyzer_eval(J0.s1[2].s1[1] == 6); // expected-warning{{UNKNOWN}}
363 clang_analyzer_eval(J0.s1[i].s1[0] == 5); // expected-warning{{UNKNOWN}}
364 clang_analyzer_eval(J0.s1[i].s1[1] == 6); // expected-warning{{UNKNOWN}}
365 // FIXME: memory leak warning for J0.s2 should be emitted here instead of after memcpy call.
366 return 0; // no warning
367 }
368
369 // Test array with its super region having symbolic offseted regions.
f20(int i)370 int f20(int i) {
371 struct aa * a20 = malloc(sizeof(struct aa) * 2);
372 a20[0].s1[0] = 1;
373 a20[0].s1[1] = 2;
374 a20[0].s1[2] = 3;
375 a20[0].s1[3] = 4;
376 a20[0].s2 = strdup("hello");
377 a20[1].s1[0] = 5;
378 a20[1].s1[1] = 6;
379 a20[1].s1[2] = 7;
380 a20[1].s1[3] = 8;
381 a20[1].s2 = strdup("world");
382 a20[i].s2 = strdup("hola");
383 char input[] = {'a', 'b', 'c', 'd'};
384 memcpy(a20[0].s1, input, 4);
385 clang_analyzer_eval(a20[0].s1[0] == 1); // expected-warning{{UNKNOWN}}
386 clang_analyzer_eval(a20[0].s1[1] == 1); // expected-warning{{UNKNOWN}}
387 clang_analyzer_eval(a20[0].s1[2] == 1); // expected-warning{{UNKNOWN}}
388 clang_analyzer_eval(a20[0].s1[3] == 1); // expected-warning{{UNKNOWN}}
389 clang_analyzer_eval(a20[0].s2 == 0); // expected-warning{{UNKNOWN}}
390 clang_analyzer_eval(a20[1].s1[0] == 1); // expected-warning{{UNKNOWN}}
391 clang_analyzer_eval(a20[1].s1[1] == 1); // expected-warning{{UNKNOWN}}
392 clang_analyzer_eval(a20[1].s1[2] == 1); // expected-warning{{UNKNOWN}}
393 clang_analyzer_eval(a20[1].s1[3] == 1); // expected-warning{{UNKNOWN}}
394 clang_analyzer_eval(a20[1].s2 == 0); // expected-warning{{UNKNOWN}}
395 clang_analyzer_eval(a20[i].s1[0] == 1); // expected-warning{{UNKNOWN}}
396 clang_analyzer_eval(a20[i].s1[1] == 1); // expected-warning{{UNKNOWN}}
397 clang_analyzer_eval(a20[i].s1[2] == 1); // expected-warning{{UNKNOWN}}
398 clang_analyzer_eval(a20[i].s1[3] == 1); // expected-warning{{UNKNOWN}}
399 clang_analyzer_eval(a20[i].s2 == 0); // expected-warning{{UNKNOWN}}\
400 expected-warning{{Potential leak of memory pointed to by 'a20'}}
401
402 return 0;
403 }
404
405 // Test array's region and super region both having symbolic offsets.
f21(int i)406 int f21(int i) {
407 struct aa * a21 = malloc(sizeof(struct aa) * 2);
408 a21[0].s1[0] = 1;
409 a21[0].s1[1] = 2;
410 a21[0].s1[2] = 3;
411 a21[0].s1[3] = 4;
412 a21[0].s2 = 0;
413 a21[1].s1[0] = 5;
414 a21[1].s1[1] = 6;
415 a21[1].s1[2] = 7;
416 a21[1].s1[3] = 8;
417 a21[1].s2 = 0;
418 a21[i].s2 = strdup("hello");
419 a21[i].s1[0] = 1;
420 a21[i].s1[1] = 2;
421 a21[i].s1[2] = 3;
422 a21[i].s1[3] = 4;
423 char input[] = {'a', 'b', 'c', 'd'};
424 memcpy(a21[i].s1, input, 4);
425 clang_analyzer_eval(a21[0].s1[0] == 1); // expected-warning{{UNKNOWN}}
426 clang_analyzer_eval(a21[0].s1[1] == 1); // expected-warning{{UNKNOWN}}
427 clang_analyzer_eval(a21[0].s1[2] == 1); // expected-warning{{UNKNOWN}}
428 clang_analyzer_eval(a21[0].s1[3] == 1); // expected-warning{{UNKNOWN}}
429 clang_analyzer_eval(a21[0].s2 == 0); // expected-warning{{UNKNOWN}}
430 clang_analyzer_eval(a21[1].s1[0] == 1); // expected-warning{{UNKNOWN}}
431 clang_analyzer_eval(a21[1].s1[1] == 1); // expected-warning{{UNKNOWN}}
432 clang_analyzer_eval(a21[1].s1[2] == 1); // expected-warning{{UNKNOWN}}
433 clang_analyzer_eval(a21[1].s1[3] == 1); // expected-warning{{UNKNOWN}}
434 clang_analyzer_eval(a21[1].s2 == 0); // expected-warning{{UNKNOWN}}
435 clang_analyzer_eval(a21[i].s1[0] == 1); // expected-warning{{UNKNOWN}}
436 clang_analyzer_eval(a21[i].s1[1] == 1); // expected-warning{{UNKNOWN}}
437 clang_analyzer_eval(a21[i].s1[2] == 1); // expected-warning{{UNKNOWN}}
438 clang_analyzer_eval(a21[i].s1[3] == 1); // expected-warning{{UNKNOWN}}
439 clang_analyzer_eval(a21[i].s2 == 0); // expected-warning{{UNKNOWN}}\
440 expected-warning{{Potential leak of memory pointed to by 'a21'}}
441
442 return 0;
443 }
444
445 // Test regions aliasing other regions.
446 struct ll {
447 char s1[4];
448 char * s2;
449 };
450
451 struct mm {
452 char s3[4];
453 char * s4;
454 };
455
f24(void)456 int f24(void) {
457 struct ll l24 = {{1, 2, 3, 4}, 0};
458 struct mm * m24 = (struct mm *)&l24;
459 m24->s4 = strdup("hello");
460 char input[] = {1, 2, 3, 4};
461 memcpy(m24->s3, input, 4);
462 clang_analyzer_eval(m24->s3[0] == 1); // expected-warning{{UNKNOWN}}
463 clang_analyzer_eval(m24->s3[1] == 1); // expected-warning{{UNKNOWN}}
464 clang_analyzer_eval(m24->s3[2] == 1); // expected-warning{{UNKNOWN}}
465 clang_analyzer_eval(m24->s3[3] == 1); // expected-warning{{UNKNOWN}}
466 clang_analyzer_eval(l24.s1[0] == 1); // expected-warning{{UNKNOWN}}
467 clang_analyzer_eval(l24.s1[1] == 1); // expected-warning{{UNKNOWN}}
468 clang_analyzer_eval(l24.s1[2] == 1); // expected-warning{{UNKNOWN}}
469 clang_analyzer_eval(l24.s1[3] == 1); // expected-warning{{UNKNOWN}}\
470 expected-warning{{Potential leak of memory pointed to by field 's4'}}
471 return 0;
472 }
473
474 // Test region with potential aliasing and symbolic offsets.
475 // Store assumes no aliasing.
f25(int i,int j,struct ll * l,struct mm * m)476 int f25(int i, int j, struct ll * l, struct mm * m) {
477 m->s4 = strdup("hola"); // m->s4 not tracked
478 m->s3[0] = 1;
479 m->s3[1] = 2;
480 m->s3[2] = 3;
481 m->s3[3] = 4;
482 m->s3[j] = 5; // invalidates m->s3
483 l->s2 = strdup("hello"); // l->s2 not tracked
484 l->s1[0] = 6;
485 l->s1[1] = 7;
486 l->s1[2] = 8;
487 l->s1[3] = 9;
488 l->s1[i] = 10; // invalidates l->s1
489 char input[] = {1, 2, 3, 4};
490 memcpy(m->s3, input, 4); // does not invalidate l->s1[i]
491 clang_analyzer_eval(m->s3[0] == 1); // expected-warning{{UNKNOWN}}
492 clang_analyzer_eval(m->s3[1] == 1); // expected-warning{{UNKNOWN}}
493 clang_analyzer_eval(m->s3[2] == 1); // expected-warning{{UNKNOWN}}
494 clang_analyzer_eval(m->s3[3] == 1); // expected-warning{{UNKNOWN}}
495 clang_analyzer_eval(m->s3[i] == 1); // expected-warning{{UNKNOWN}}
496 clang_analyzer_eval(m->s3[j] == 1); // expected-warning{{UNKNOWN}}
497 clang_analyzer_eval(l->s1[0] == 1); // expected-warning{{UNKNOWN}}
498 clang_analyzer_eval(l->s1[1] == 1); // expected-warning{{UNKNOWN}}
499 clang_analyzer_eval(l->s1[2] == 1); // expected-warning{{UNKNOWN}}
500 clang_analyzer_eval(l->s1[3] == 1); // expected-warning{{UNKNOWN}}
501 clang_analyzer_eval(l->s1[i] == 1); // expected-warning{{FALSE}}
502 clang_analyzer_eval(l->s1[j] == 1); // expected-warning{{UNKNOWN}}
503 return 0;
504 }
505
506 // Test size with symbolic size argument.
f26(int i)507 int f26(int i) {
508 struct aa a26 = {{1, 2, 3, 4}, 0};
509 a26.s2 = strdup("hello");
510 char input[] = {'a', 'b', 'c', 'd'};
511 memcpy(a26.s1, input, i); // i assumed in bound
512 clang_analyzer_eval(a26.s1[0] == 1); // expected-warning{{UNKNOWN}}
513 clang_analyzer_eval(a26.s1[1] == 1); // expected-warning{{UNKNOWN}}
514 clang_analyzer_eval(a26.s1[2] == 1); // expected-warning{{UNKNOWN}}
515 clang_analyzer_eval(a26.s1[3] == 1); // expected-warning{{UNKNOWN}}\
516 expected-warning{{Potential leak of memory pointed to by 'a26.s2'}}
517 return 0;
518 }
519
520 // Test sizeof as a size argument.
f261(void)521 int f261(void) {
522 struct aa a261 = {{1, 2, 3, 4}, 0};
523 a261.s2 = strdup("hello");
524 char input[] = {'a', 'b', 'c', 'd'};
525 memcpy(a261.s1, input, sizeof(a261.s1));
526 clang_analyzer_eval(a261.s1[0] == 1); // expected-warning{{UNKNOWN}}
527 clang_analyzer_eval(a261.s1[1] == 1); // expected-warning{{UNKNOWN}}
528 clang_analyzer_eval(a261.s1[2] == 1); // expected-warning{{UNKNOWN}}
529 clang_analyzer_eval(a261.s1[3] == 1); // expected-warning{{UNKNOWN}}\
530 expected-warning{{Potential leak of memory pointed to by 'a261.s2'}}
531 return 0;
532 }
533
534 // Test negative size argument.
f262(void)535 int f262(void) {
536 struct aa a262 = {{1, 2, 3, 4}, 0};
537 a262.s2 = strdup("hello");
538 char input[] = {'a', 'b', 'c', 'd'};
539 memcpy(a262.s1, input, -1); // expected-warning{{'memcpy' will always overflow; destination buffer has size 16, but size argument is 18446744073709551615}}
540 clang_analyzer_eval(a262.s1[0] == 1); // expected-warning{{UNKNOWN}}\
541 expected-warning{{Potential leak of memory pointed to by 'a262.s2'}}
542 clang_analyzer_eval(a262.s1[1] == 1); // expected-warning{{UNKNOWN}}
543 clang_analyzer_eval(a262.s1[2] == 1); // expected-warning{{UNKNOWN}}
544 clang_analyzer_eval(a262.s1[3] == 1); // expected-warning{{UNKNOWN}}
545 return 0;
546 }
547
548 // Test size argument being an unknown value.
549 struct xx {
550 char s1[4];
551 char * s2;
552 };
553
f263(int n,char * len)554 int f263(int n, char * len) {
555 struct xx x263 = {0};
556 x263.s2 = strdup("hello");
557 char input[] = {'a', 'b', 'c', 'd'};
558 memcpy(x263.s1, input, *(len + n));
559 clang_analyzer_eval(x263.s1[0] == 0); // expected-warning{{UNKNOWN}}\
560 expected-warning{{Potential leak of memory pointed to by 'x263.s2'}}
561 clang_analyzer_eval(x263.s1[1] == 0); // expected-warning{{UNKNOWN}}
562 clang_analyzer_eval(x263.s1[2] == 0); // expected-warning{{UNKNOWN}}
563 clang_analyzer_eval(x263.s1[3] == 0); // expected-warning{{UNKNOWN}}
564 clang_analyzer_eval(x263.s2 == 0); // expected-warning{{UNKNOWN}}
565 return 0;
566 }
567
568
569 // Test casting regions with symbolic offseted sub regions.
f27(int i)570 int f27(int i) {
571 struct mm m27 = {{1, 2, 3, 4}, 0};
572 m27.s4 = strdup("hello");
573 m27.s3[i] = 5;
574 char input[] = {'a', 'b', 'c', 'd'};
575 memcpy(((struct ll*)(&m27))->s1, input, 4);
576 clang_analyzer_eval(m27.s3[0] == 1); // expected-warning{{UNKNOWN}}
577 clang_analyzer_eval(m27.s3[1] == 1); // expected-warning{{UNKNOWN}}
578 clang_analyzer_eval(m27.s3[2] == 1); // expected-warning{{UNKNOWN}}
579 clang_analyzer_eval(m27.s3[3] == 1); // expected-warning{{UNKNOWN}}
580 clang_analyzer_eval(m27.s3[i] == 1); // expected-warning{{UNKNOWN}}\
581 expected-warning{{Potential leak of memory pointed to by 'm27.s4'}}
582 return 0;
583 }
584
f28(int i,int j,int k,int l)585 int f28(int i, int j, int k, int l) {
586 struct mm m28[2];
587 m28[i].s4 = strdup("hello");
588 m28[j].s3[k] = 1;
589 struct ll * l28 = (struct ll*)(&m28[1]);
590 l28->s1[l] = 2;
591 char input[] = {'a', 'b', 'c', 'd'}; // expected-warning{{Potential leak of memory pointed to by field 's4'}}
592 memcpy(l28->s1, input, 4);
593 clang_analyzer_eval(m28[0].s3[0] == 1); // expected-warning{{UNKNOWN}}
594 clang_analyzer_eval(m28[0].s3[1] == 1); // expected-warning{{UNKNOWN}}
595 clang_analyzer_eval(m28[0].s3[2] == 1); // expected-warning{{UNKNOWN}}
596 clang_analyzer_eval(m28[0].s3[3] == 1); // expected-warning{{UNKNOWN}}
597 clang_analyzer_eval(m28[1].s3[0] == 1); // expected-warning{{UNKNOWN}}
598 clang_analyzer_eval(m28[1].s3[1] == 1); // expected-warning{{UNKNOWN}}
599 clang_analyzer_eval(m28[1].s3[2] == 1); // expected-warning{{UNKNOWN}}
600 clang_analyzer_eval(m28[1].s3[3] == 1); // expected-warning{{UNKNOWN}}
601 clang_analyzer_eval(m28[i].s3[0] == 1); // expected-warning{{UNKNOWN}}
602 clang_analyzer_eval(m28[i].s3[1] == 1); // expected-warning{{UNKNOWN}}
603 clang_analyzer_eval(m28[i].s3[2] == 1); // expected-warning{{UNKNOWN}}
604 clang_analyzer_eval(m28[i].s3[3] == 1); // expected-warning{{UNKNOWN}}
605 clang_analyzer_eval(m28[j].s3[k] == 1); // expected-warning{{UNKNOWN}}
606 clang_analyzer_eval(l28->s1[l] == 2); // expected-warning{{UNKNOWN}}
607 return 0;
608 }
609
f29(int i,int j,int k,int l,int m)610 int f29(int i, int j, int k, int l, int m) {
611 struct mm m29[2];
612 m29[i].s4 = strdup("hello");
613 m29[j].s3[k] = 1;
614 struct ll * l29 = (struct ll*)(&m29[l]);
615 l29->s1[m] = 2;
616 char input[] = {'a', 'b', 'c', 'd'};
617 memcpy(l29->s1, input, 4);
618 clang_analyzer_eval(m29[0].s3[0] == 1); // expected-warning{{UNKNOWN}}
619 clang_analyzer_eval(m29[0].s3[1] == 1); // expected-warning{{UNKNOWN}}
620 clang_analyzer_eval(m29[0].s3[2] == 1); // expected-warning{{UNKNOWN}}
621 clang_analyzer_eval(m29[0].s3[3] == 1); // expected-warning{{UNKNOWN}}
622 clang_analyzer_eval(m29[1].s3[0] == 1); // expected-warning{{UNKNOWN}}
623 clang_analyzer_eval(m29[1].s3[1] == 1); // expected-warning{{UNKNOWN}}
624 clang_analyzer_eval(m29[1].s3[2] == 1); // expected-warning{{UNKNOWN}}
625 clang_analyzer_eval(m29[1].s3[3] == 1); // expected-warning{{UNKNOWN}}
626 clang_analyzer_eval(m29[i].s3[0] == 1); // expected-warning{{UNKNOWN}}
627 clang_analyzer_eval(m29[i].s3[1] == 1); // expected-warning{{UNKNOWN}}
628 clang_analyzer_eval(m29[i].s3[2] == 1); // expected-warning{{UNKNOWN}}
629 clang_analyzer_eval(m29[i].s3[3] == 1); // expected-warning{{UNKNOWN}}
630 clang_analyzer_eval(m29[j].s3[k] == 1); // expected-warning{{TRUE}}
631 clang_analyzer_eval(l29->s1[m] == 2); // expected-warning{{UNKNOWN}}
632 // FIXME: Should warn that m29[i].s4 leaks. But not on the previous line,
633 // because l29 and m29 alias.
634 return 0;
635 }
636
637 // Test unions' fields.
638 union uu {
639 char x;
640 char s1[4];
641 };
642
f30(void)643 int f30(void) {
644 union uu u30 = { .s1 = {1, 2, 3, 4}};
645 char input[] = {1, 2, 3, 4};
646 memcpy(u30.s1, input, 4);
647 clang_analyzer_eval(u30.s1[0] == 1); // expected-warning{{UNKNOWN}}
648 clang_analyzer_eval(u30.s1[1] == 1); // expected-warning{{UNKNOWN}}
649 clang_analyzer_eval(u30.s1[2] == 1); // expected-warning{{UNKNOWN}}
650 clang_analyzer_eval(u30.s1[3] == 1); // expected-warning{{UNKNOWN}}
651 clang_analyzer_eval(u30.x == 1); // expected-warning{{UNKNOWN}}
652 return 0;
653 }
654
655 struct kk {
656 union uu u;
657 char * s2;
658 };
659
f31(void)660 int f31(void) {
661 struct kk k31;
662 k31.s2 = strdup("hello");
663 k31.u.x = 1;
664 char input[] = {'a', 'b', 'c', 'd'};
665 memcpy(k31.u.s1, input, 4);
666 clang_analyzer_eval(k31.u.s1[0] == 1); // expected-warning{{UNKNOWN}}\
667 expected-warning{{Potential leak of memory pointed to by 'k31.s2'}}
668 clang_analyzer_eval(k31.u.s1[1] == 1); // expected-warning{{UNKNOWN}}
669 clang_analyzer_eval(k31.u.s1[2] == 1); // expected-warning{{UNKNOWN}}
670 clang_analyzer_eval(k31.u.s1[3] == 1); // expected-warning{{UNKNOWN}}
671 clang_analyzer_eval(k31.u.x == 1); // expected-warning{{UNKNOWN}}
672 // FIXME: memory leak warning for k31.s2 should be emitted here.
673 return 0;
674 }
675
676 union vv {
677 int x;
678 char * s2;
679 };
680
f32(void)681 int f32(void) {
682 union vv v32;
683 v32.s2 = strdup("hello");
684 char input[] = {'a', 'b', 'c', 'd'};
685 memcpy(v32.s2, input, 4);
686 clang_analyzer_eval(v32.s2[0] == 1); // expected-warning{{UNKNOWN}}
687 clang_analyzer_eval(v32.s2[1] == 1); // expected-warning{{UNKNOWN}}
688 clang_analyzer_eval(v32.s2[2] == 1); // expected-warning{{UNKNOWN}}
689 clang_analyzer_eval(v32.s2[3] == 1); // expected-warning{{UNKNOWN}}\
690 expected-warning{{Potential leak of memory pointed to by 'v32.s2'}}
691 return 0;
692 }
693
694 struct nn {
695 int s1;
696 int i;
697 int j;
698 int k;
699 char * s2;
700 };
701
702 // Test bad types to dest buffer.
f33(void)703 int f33(void) {
704 struct nn n33 = {1, 2, 3, 4, 0};
705 n33.s2 = strdup("hello");
706 char input[] = {'a', 'b', 'c', 'd'};
707 memcpy(n33.s1, input, 4); // expected-warning{{incompatible integer to pointer conversion passing 'int' to parameter of type 'void *'}}
708 clang_analyzer_eval(n33.i == 2); // expected-warning{{TRUE}}
709 clang_analyzer_eval(n33.j == 3); // expected-warning{{TRUE}}
710 clang_analyzer_eval(n33.k == 4); // expected-warning{{TRUE}}
711 clang_analyzer_eval(((char*)(n33.s1))[0] == 1); // expected-warning{{UNKNOWN}}\
712 expected-warning{{cast to 'char *' from smaller integer type 'int'}}
713 clang_analyzer_eval(((char*)(n33.s1))[1] == 1); // expected-warning{{UNKNOWN}}\
714 expected-warning{{cast to 'char *' from smaller integer type 'int'}}
715 clang_analyzer_eval(((char*)(n33.s1))[2] == 1); // expected-warning{{UNKNOWN}}\
716 expected-warning{{cast to 'char *' from smaller integer type 'int'}}
717 clang_analyzer_eval(((char*)(n33.s1))[3] == 1); // expected-warning{{UNKNOWN}}\
718 expected-warning{{cast to 'char *' from smaller integer type 'int'}}
719 clang_analyzer_eval(n33.s2 == 0); //expected-warning{{UNKNOWN}}
720 return 0; // expected-warning{{Potential leak of memory pointed to by 'n33.s2'}}
721 }
722
723 // Test destination buffer being an unknown value.
724 struct ww {
725 int s1[4];
726 char s2;
727 };
728
f34(struct ww * w34,int n)729 int f34(struct ww * w34, int n) {
730 w34->s2 = 3;
731 char input[] = {'a', 'b', 'c', 'd'};
732 memcpy(w34->s1 + n, input , 4);
733 clang_analyzer_eval(w34->s1[0] == 0); // expected-warning{{UNKNOWN}}
734 clang_analyzer_eval(w34->s1[1] == 0); // expected-warning{{UNKNOWN}}
735 clang_analyzer_eval(w34->s1[2] == 0); // expected-warning{{UNKNOWN}}
736 clang_analyzer_eval(w34->s1[3] == 0); // expected-warning{{UNKNOWN}}
737 clang_analyzer_eval(w34->s1[n] == 0); // expected-warning{{UNKNOWN}}
738 clang_analyzer_eval(w34->s2 == 3); // expected-warning{{TRUE}}
739 return 0;
740 }
741
742 // Test dest buffer as an element region with a symbolic index and size parameter as a symbolic value.
743 struct yy {
744 char s1[4];
745 char * s2;
746 };
747
f35(int i,int n)748 int f35(int i, int n) {
749 struct yy y35 = {{1, 2, 3, 4}, 0};
750 y35.s2 = strdup("hello");
751 char input[] = {'a', 'b', 'c', 'd'};
752 memcpy(&(y35.s1[i]), input, n);
753 clang_analyzer_eval(y35.s1[0] == 0); // expected-warning{{UNKNOWN}}
754 clang_analyzer_eval(y35.s1[1] == 0); // expected-warning{{UNKNOWN}}
755 clang_analyzer_eval(y35.s1[2] == 0); // expected-warning{{UNKNOWN}}
756 clang_analyzer_eval(y35.s1[3] == 0); // expected-warning{{UNKNOWN}}
757 clang_analyzer_eval(y35.s1[i] == 0); // expected-warning{{UNKNOWN}}
758 clang_analyzer_eval(y35.s2 == 0); // expected-warning{{UNKNOWN}}
759 return 0; // expected-warning{{Potential leak of memory pointed to by 'y35.s2'}}
760 }
761
762 // Test regions with negative offsets.
763 struct zz {
764 char s1[4];
765 int s2;
766 };
767
f36(struct zz * z36)768 int f36(struct zz * z36) {
769
770 char input[] = {'a', 'b', 'c', 'd'};
771 z36->s1[0] = 0;
772 z36->s1[1] = 1;
773 z36->s1[2] = 2;
774 z36->s1[3] = 3;
775 z36->s2 = 10;
776
777 z36 = z36 - 1; // Decrement by 8 bytes (struct zz is 8 bytes).
778
779 z36->s1[0] = 4;
780 z36->s1[1] = 5;
781 z36->s1[2] = 6;
782 z36->s1[3] = 7;
783 z36->s2 = 11;
784
785 memcpy(z36->s1, input, 4);
786
787 clang_analyzer_eval(z36->s1[0] == 1); // expected-warning{{UNKNOWN}}
788 clang_analyzer_eval(z36->s1[1] == 1); // expected-warning{{UNKNOWN}}
789 clang_analyzer_eval(z36->s1[2] == 1); // expected-warning{{UNKNOWN}}
790 clang_analyzer_eval(z36->s1[3] == 1); // expected-warning{{UNKNOWN}}
791 clang_analyzer_eval(z36->s2 == 11); // expected-warning{{TRUE}}
792
793 z36 = z36 + 1; // Increment back.
794
795 clang_analyzer_eval(z36->s1[0] == 0); // expected-warning{{TRUE}}
796 clang_analyzer_eval(z36->s1[1] == 1); // expected-warning{{TRUE}}
797 clang_analyzer_eval(z36->s1[2] == 2); // expected-warning{{TRUE}}
798 clang_analyzer_eval(z36->s1[3] == 3); // expected-warning{{TRUE}}
799 clang_analyzer_eval(z36->s2 == 10); // expected-warning{{TRUE}}
800
801 return 0;
802 }
803
f37(struct zz * z37)804 int f37(struct zz * z37) {
805
806 char input[] = {'a', 'b', 'c', 'd'};
807 z37->s1[0] = 0;
808 z37->s1[1] = 1;
809 z37->s1[2] = 2;
810 z37->s1[3] = 3;
811 z37->s2 = 10;
812
813 z37 = (struct zz *)((char*)(z37) - 4); // Decrement by 4 bytes (struct zz is 8 bytes).
814
815 z37->s1[0] = 4;
816 z37->s1[1] = 5;
817 z37->s1[2] = 6;
818 z37->s1[3] = 7;
819 z37->s2 = 11;
820
821 memcpy(z37->s1, input, 4);
822
823 clang_analyzer_eval(z37->s1[0] == 1); // expected-warning{{UNKNOWN}}
824 clang_analyzer_eval(z37->s1[1] == 1); // expected-warning{{UNKNOWN}}
825 clang_analyzer_eval(z37->s1[2] == 1); // expected-warning{{UNKNOWN}}
826 clang_analyzer_eval(z37->s1[3] == 1); // expected-warning{{UNKNOWN}}
827 clang_analyzer_eval(z37->s2 == 11); // expected-warning{{TRUE}}
828
829 z37 = (struct zz *)((char*)(z37) + 4); // Increment back.
830
831 clang_analyzer_eval(z37->s1[0] == 11); // expected-warning{{TRUE}}
832 clang_analyzer_eval(z37->s1[1] == 1); // expected-warning{{UNKNOWN}}
833 clang_analyzer_eval(z37->s1[2] == 1); // expected-warning{{UNKNOWN}}
834 clang_analyzer_eval(z37->s1[3] == 1); // expected-warning{{UNKNOWN}}
835 clang_analyzer_eval(z37->s2 == 10); // expected-warning{{TRUE}}
836
837 return 0;
838 }
839
f38(struct zz * z38)840 int f38(struct zz * z38) {
841
842 char input[] = {'a', 'b', 'c', 'd'};
843 z38->s1[0] = 0;
844 z38->s1[1] = 1;
845 z38->s1[2] = 2;
846 z38->s1[3] = 3;
847 z38->s2 = 10;
848
849 z38 = (struct zz *)((char*)(z38) - 2); // Decrement by 2 bytes (struct zz is 8 bytes).
850
851 z38->s1[0] = 4;
852 z38->s1[1] = 5;
853 z38->s1[2] = 6;
854 z38->s1[3] = 7;
855 z38->s2 = 11;
856
857 memcpy(z38->s1, input, 4);
858
859 clang_analyzer_eval(z38->s1[0] == 1); // expected-warning{{UNKNOWN}}
860 clang_analyzer_eval(z38->s1[1] == 1); // expected-warning{{UNKNOWN}}
861 clang_analyzer_eval(z38->s1[2] == 1); // expected-warning{{UNKNOWN}}
862 clang_analyzer_eval(z38->s1[3] == 1); // expected-warning{{UNKNOWN}}
863 clang_analyzer_eval(z38->s2 == 11); // expected-warning{{TRUE}}
864
865 z38 = (struct zz *)((char*)(z38) + 2); // Increment back.
866
867 clang_analyzer_eval(z38->s1[0] == 1); // expected-warning{{UNKNOWN}}
868 clang_analyzer_eval(z38->s1[1] == 1); // expected-warning{{UNKNOWN}}
869 clang_analyzer_eval(z38->s1[2] == 11); // expected-warning{{TRUE}}
870 clang_analyzer_eval(z38->s1[3] == 1); // expected-warning{{UNKNOWN}}
871 clang_analyzer_eval(z38->s2 == 10); // expected-warning{{UNKNOWN}}
872
873 return 0;
874 }
875
876 // Test negative offsets with a different structure layout.
877 struct z0 {
878 int s2;
879 char s1[4];
880 };
881
f39(struct z0 * d39)882 int f39(struct z0 * d39) {
883
884 char input[] = {'a', 'b', 'c', 'd'};
885 d39->s1[0] = 0;
886 d39->s1[1] = 1;
887 d39->s1[2] = 2;
888 d39->s1[3] = 3;
889 d39->s2 = 10;
890
891 d39 = (struct z0 *)((char*)(d39) - 2); // Decrement by 2 bytes (struct z0 is 8 bytes).
892
893 d39->s1[0] = 4;
894 d39->s1[1] = 5;
895 d39->s1[2] = 6;
896 d39->s1[3] = 7;
897 d39->s2 = 11;
898
899 memcpy(d39->s1, input, 4);
900
901 clang_analyzer_eval(d39->s1[0] == 1); // expected-warning{{UNKNOWN}}
902 clang_analyzer_eval(d39->s1[1] == 1); // expected-warning{{UNKNOWN}}
903 clang_analyzer_eval(d39->s1[2] == 1); // expected-warning{{UNKNOWN}}
904 clang_analyzer_eval(d39->s1[3] == 1); // expected-warning{{UNKNOWN}}
905 clang_analyzer_eval(d39->s2 == 11); // expected-warning{{TRUE}}
906
907 d39 = (struct z0 *)((char*)(d39) + 2); // Increment back.
908
909 clang_analyzer_eval(d39->s1[0] == 1); // expected-warning{{UNKNOWN}}
910 clang_analyzer_eval(d39->s1[1] == 1); // expected-warning{{UNKNOWN}}
911 clang_analyzer_eval(d39->s1[2] == 2); // expected-warning{{TRUE}}
912 clang_analyzer_eval(d39->s1[3] == 3); // expected-warning{{TRUE}}
913 // FIXME: d39->s2 should evaluate to at least UNKNOWN or FALSE,
914 // 'collectSubRegionBindings(...)' in RegionStore.cpp will need to
915 // handle a regions' upper boundary overflowing.
916 clang_analyzer_eval(d39->s2 == 10); // expected-warning{{TRUE}}
917
918 return 0;
919 }
920
921