xref: /llvm-project/clang/test/Analysis/pr22954.c (revision 1bd2d335b649f2e09d7e4bdd0b92c78489ded022)
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