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_cc1 -triple x86_64-pc-linux-gnu -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify %s
7
8typedef __typeof(sizeof(int)) size_t;
9
10char *strdup(const char *s);
11void free(void *);
12void *memcpy(void *dst, const void *src, size_t n); // expected-note{{passing argument to parameter 'dst' here}}
13void *malloc(size_t n);
14
15void clang_analyzer_eval(int);
16
17struct aa {
18    char s1[4];
19    char *s2;
20};
21
22// Test different types of structure initialisation.
23int f0() {
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
37int f1() {
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
51int f2() {
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
65int f3() {
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
84struct bb {
85  struct aa a;
86  char * s2;
87};
88
89int f4() {
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.
111int f5() {
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
119int f6() {
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
127int f7() {
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
135int f8() {
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
144int f9() {
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
155int f10() {
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.
167struct cc {
168  char * s1;
169  char * s2;
170};
171
172int f11() {
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.
192struct dd {
193  char *s2;
194  char s1[4];
195};
196
197int f12() {
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.
212struct ee {
213  int a;
214  char b;
215};
216
217struct EE {
218  struct ee s1[2];
219  char * s2;
220};
221
222int f13() {
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.
237struct aa a15 = {{1, 2, 3, 4}, 0};
238
239int f15() {
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.
253struct empty {};
254struct gg {
255  struct empty s1[4];
256  char * s2;
257};
258
259int f16() {
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.
275struct hh {
276  char s1[0];
277  char * s2;
278};
279
280int f17() {
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.
293struct ii {
294  char s1[4];
295  int i;
296  int j;
297  char * s2;
298};
299
300int f18() {
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);
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
317int f181() {
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.
335struct jj {
336  char s1[2];
337  char * s2;
338};
339
340struct JJ {
341  struct jj s1[3];
342  char * s2;
343};
344
345int 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 'J0.s2'}}
356  clang_analyzer_eval(J0.s1[0].s1[1] == 2); // expected-warning{{UNKNOWN}}
357  clang_analyzer_eval(J0.s1[1].s1[0] == 3); // expected-warning{{UNKNOWN}}
358  clang_analyzer_eval(J0.s1[1].s1[1] == 4); // expected-warning{{UNKNOWN}}
359  clang_analyzer_eval(J0.s1[2].s1[0] == 5); // expected-warning{{UNKNOWN}}
360  clang_analyzer_eval(J0.s1[2].s1[1] == 6); // expected-warning{{UNKNOWN}}
361  clang_analyzer_eval(J0.s1[i].s1[0] == 5); // expected-warning{{UNKNOWN}}
362  clang_analyzer_eval(J0.s1[i].s1[1] == 6); // expected-warning{{UNKNOWN}}
363  // FIXME: memory leak warning for J0.s2 should be emitted here instead of after memcpy call.
364  return 0; // no warning
365}
366
367// Test array with its super region having symbolic offseted regions.
368int f20(int i) {
369  struct aa * a20 = malloc(sizeof(struct aa) * 2);
370  a20[0].s1[0] = 1;
371  a20[0].s1[1] = 2;
372  a20[0].s1[2] = 3;
373  a20[0].s1[3] = 4;
374  a20[0].s2 = strdup("hello");
375  a20[1].s1[0] = 5;
376  a20[1].s1[1] = 6;
377  a20[1].s1[2] = 7;
378  a20[1].s1[3] = 8;
379  a20[1].s2 = strdup("world");
380  a20[i].s2 = strdup("hola");
381  char input[] = {'a', 'b', 'c', 'd'};
382  memcpy(a20[0].s1, input, 4);
383  clang_analyzer_eval(a20[0].s1[0] == 1); // expected-warning{{UNKNOWN}}
384  clang_analyzer_eval(a20[0].s1[1] == 1); // expected-warning{{UNKNOWN}}
385  clang_analyzer_eval(a20[0].s1[2] == 1); // expected-warning{{UNKNOWN}}
386  clang_analyzer_eval(a20[0].s1[3] == 1); // expected-warning{{UNKNOWN}}
387  clang_analyzer_eval(a20[0].s2 == 0); // expected-warning{{UNKNOWN}}
388  clang_analyzer_eval(a20[1].s1[0] == 1); // expected-warning{{UNKNOWN}}
389  clang_analyzer_eval(a20[1].s1[1] == 1); // expected-warning{{UNKNOWN}}
390  clang_analyzer_eval(a20[1].s1[2] == 1); // expected-warning{{UNKNOWN}}
391  clang_analyzer_eval(a20[1].s1[3] == 1); // expected-warning{{UNKNOWN}}
392  clang_analyzer_eval(a20[1].s2 == 0); // expected-warning{{UNKNOWN}}
393  clang_analyzer_eval(a20[i].s1[0] == 1); // expected-warning{{UNKNOWN}}
394  clang_analyzer_eval(a20[i].s1[1] == 1); // expected-warning{{UNKNOWN}}
395  clang_analyzer_eval(a20[i].s1[2] == 1); // expected-warning{{UNKNOWN}}
396  clang_analyzer_eval(a20[i].s1[3] == 1); // expected-warning{{UNKNOWN}}
397  clang_analyzer_eval(a20[i].s2 == 0); // expected-warning{{UNKNOWN}}\
398  expected-warning{{Potential leak of memory pointed to by 'a20'}}
399
400  return 0;
401}
402
403// Test array's region and super region both having symbolic offsets.
404int f21(int i) {
405  struct aa * a21 = malloc(sizeof(struct aa) * 2);
406  a21[0].s1[0] = 1;
407  a21[0].s1[1] = 2;
408  a21[0].s1[2] = 3;
409  a21[0].s1[3] = 4;
410  a21[0].s2 = 0;
411  a21[1].s1[0] = 5;
412  a21[1].s1[1] = 6;
413  a21[1].s1[2] = 7;
414  a21[1].s1[3] = 8;
415  a21[1].s2 = 0;
416  a21[i].s2 = strdup("hello");
417  a21[i].s1[0] = 1;
418  a21[i].s1[1] = 2;
419  a21[i].s1[2] = 3;
420  a21[i].s1[3] = 4;
421  char input[] = {'a', 'b', 'c', 'd'};
422  memcpy(a21[i].s1, input, 4);
423  clang_analyzer_eval(a21[0].s1[0] == 1); // expected-warning{{UNKNOWN}}
424  clang_analyzer_eval(a21[0].s1[1] == 1); // expected-warning{{UNKNOWN}}
425  clang_analyzer_eval(a21[0].s1[2] == 1); // expected-warning{{UNKNOWN}}
426  clang_analyzer_eval(a21[0].s1[3] == 1); // expected-warning{{UNKNOWN}}
427  clang_analyzer_eval(a21[0].s2 == 0); // expected-warning{{UNKNOWN}}
428  clang_analyzer_eval(a21[1].s1[0] == 1); // expected-warning{{UNKNOWN}}
429  clang_analyzer_eval(a21[1].s1[1] == 1); // expected-warning{{UNKNOWN}}
430  clang_analyzer_eval(a21[1].s1[2] == 1); // expected-warning{{UNKNOWN}}
431  clang_analyzer_eval(a21[1].s1[3] == 1); // expected-warning{{UNKNOWN}}
432  clang_analyzer_eval(a21[1].s2 == 0); // expected-warning{{UNKNOWN}}
433  clang_analyzer_eval(a21[i].s1[0] == 1); // expected-warning{{UNKNOWN}}
434  clang_analyzer_eval(a21[i].s1[1] == 1); // expected-warning{{UNKNOWN}}
435  clang_analyzer_eval(a21[i].s1[2] == 1); // expected-warning{{UNKNOWN}}
436  clang_analyzer_eval(a21[i].s1[3] == 1); // expected-warning{{UNKNOWN}}
437  clang_analyzer_eval(a21[i].s2 == 0); // expected-warning{{UNKNOWN}}\
438  expected-warning{{Potential leak of memory pointed to by 'a21'}}
439
440  return 0;
441}
442
443// Test regions aliasing other regions.
444struct ll {
445  char s1[4];
446  char * s2;
447};
448
449struct mm {
450  char s3[4];
451  char * s4;
452};
453
454int f24() {
455  struct ll l24 = {{1, 2, 3, 4}, 0};
456  struct mm * m24 = (struct mm *)&l24;
457  m24->s4 = strdup("hello");
458  char input[] = {1, 2, 3, 4};
459  memcpy(m24->s3, input, 4);
460  clang_analyzer_eval(m24->s3[0] == 1); // expected-warning{{UNKNOWN}}
461  clang_analyzer_eval(m24->s3[1] == 1); // expected-warning{{UNKNOWN}}
462  clang_analyzer_eval(m24->s3[2] == 1); // expected-warning{{UNKNOWN}}
463  clang_analyzer_eval(m24->s3[3] == 1); // expected-warning{{UNKNOWN}}
464  clang_analyzer_eval(l24.s1[0] == 1); // expected-warning{{UNKNOWN}}
465  clang_analyzer_eval(l24.s1[1] == 1); // expected-warning{{UNKNOWN}}
466  clang_analyzer_eval(l24.s1[2] == 1); // expected-warning{{UNKNOWN}}
467  clang_analyzer_eval(l24.s1[3] == 1); // expected-warning{{UNKNOWN}}\
468  expected-warning{{Potential leak of memory pointed to by field 's4'}}
469  return 0;
470}
471
472// Test region with potential aliasing and symbolic offsets.
473// Store assumes no aliasing.
474int f25(int i, int j, struct ll * l, struct mm * m) {
475  m->s4 = strdup("hola"); // m->s4 not tracked
476  m->s3[0] = 1;
477  m->s3[1] = 2;
478  m->s3[2] = 3;
479  m->s3[3] = 4;
480  m->s3[j] = 5; // invalidates m->s3
481  l->s2 = strdup("hello"); // l->s2 not tracked
482  l->s1[0] = 6;
483  l->s1[1] = 7;
484  l->s1[2] = 8;
485  l->s1[3] = 9;
486  l->s1[i] = 10; // invalidates l->s1
487  char input[] = {1, 2, 3, 4};
488  memcpy(m->s3, input, 4); // does not invalidate l->s1[i]
489  clang_analyzer_eval(m->s3[0] == 1); // expected-warning{{UNKNOWN}}
490  clang_analyzer_eval(m->s3[1] == 1); // expected-warning{{UNKNOWN}}
491  clang_analyzer_eval(m->s3[2] == 1); // expected-warning{{UNKNOWN}}
492  clang_analyzer_eval(m->s3[3] == 1); // expected-warning{{UNKNOWN}}
493  clang_analyzer_eval(m->s3[i] == 1); // expected-warning{{UNKNOWN}}
494  clang_analyzer_eval(m->s3[j] == 1); // expected-warning{{UNKNOWN}}
495  clang_analyzer_eval(l->s1[0] == 1); // expected-warning{{UNKNOWN}}
496  clang_analyzer_eval(l->s1[1] == 1); // expected-warning{{UNKNOWN}}
497  clang_analyzer_eval(l->s1[2] == 1); // expected-warning{{UNKNOWN}}
498  clang_analyzer_eval(l->s1[3] == 1); // expected-warning{{UNKNOWN}}
499  clang_analyzer_eval(l->s1[i] == 1); // expected-warning{{FALSE}}
500  clang_analyzer_eval(l->s1[j] == 1); // expected-warning{{UNKNOWN}}
501  return 0;
502}
503
504// Test size with symbolic size argument.
505int f26(int i) {
506  struct aa a26 = {{1, 2, 3, 4}, 0};
507  a26.s2 = strdup("hello");
508  char input[] = {'a', 'b', 'c', 'd'};
509  memcpy(a26.s1, input, i); // i assumed in bound
510  clang_analyzer_eval(a26.s1[0] == 1); // expected-warning{{UNKNOWN}}
511  clang_analyzer_eval(a26.s1[1] == 1); // expected-warning{{UNKNOWN}}
512  clang_analyzer_eval(a26.s1[2] == 1); // expected-warning{{UNKNOWN}}
513  clang_analyzer_eval(a26.s1[3] == 1); // expected-warning{{UNKNOWN}}\
514  expected-warning{{Potential leak of memory pointed to by 'a26.s2'}}
515  return 0;
516}
517
518// Test sizeof as a size argument.
519int f261() {
520  struct aa a261 = {{1, 2, 3, 4}, 0};
521  a261.s2 = strdup("hello");
522  char input[] = {'a', 'b', 'c', 'd'};
523  memcpy(a261.s1, input, sizeof(a261.s1));
524  clang_analyzer_eval(a261.s1[0] == 1); // expected-warning{{UNKNOWN}}
525  clang_analyzer_eval(a261.s1[1] == 1); // expected-warning{{UNKNOWN}}
526  clang_analyzer_eval(a261.s1[2] == 1); // expected-warning{{UNKNOWN}}
527  clang_analyzer_eval(a261.s1[3] == 1); // expected-warning{{UNKNOWN}}\
528  expected-warning{{Potential leak of memory pointed to by 'a261.s2'}}
529  return 0;
530}
531
532// Test negative size argument.
533int f262() {
534  struct aa a262 = {{1, 2, 3, 4}, 0};
535  a262.s2 = strdup("hello");
536  char input[] = {'a', 'b', 'c', 'd'};
537  memcpy(a262.s1, input, -1);
538  clang_analyzer_eval(a262.s1[0] == 1); // expected-warning{{UNKNOWN}}\
539  expected-warning{{Potential leak of memory pointed to by 'a262.s2'}}
540  clang_analyzer_eval(a262.s1[1] == 1); // expected-warning{{UNKNOWN}}
541  clang_analyzer_eval(a262.s1[2] == 1); // expected-warning{{UNKNOWN}}
542  clang_analyzer_eval(a262.s1[3] == 1); // expected-warning{{UNKNOWN}}
543  return 0;
544}
545
546// Test size argument being an unknown value.
547struct xx {
548  char s1[4];
549  char * s2;
550};
551
552int f263(int n, char * len) {
553  struct xx x263 = {0};
554  x263.s2 = strdup("hello");
555  char input[] = {'a', 'b', 'c', 'd'};
556  memcpy(x263.s1, input, *(len + n));
557  clang_analyzer_eval(x263.s1[0] == 0); // expected-warning{{UNKNOWN}}
558  clang_analyzer_eval(x263.s1[1] == 0); // expected-warning{{UNKNOWN}}
559  clang_analyzer_eval(x263.s1[2] == 0); // expected-warning{{UNKNOWN}}
560  clang_analyzer_eval(x263.s1[3] == 0); // expected-warning{{UNKNOWN}}
561  clang_analyzer_eval(x263.s2 == 0); // expected-warning{{UNKNOWN}}
562  return 0; // expected-warning{{Potential leak of memory pointed to by 'x263.s2'}}
563}
564
565
566// Test casting regions with symbolic offseted sub regions.
567int f27(int i) {
568  struct mm m27 = {{1, 2, 3, 4}, 0};
569  m27.s4 = strdup("hello");
570  m27.s3[i] = 5;
571  char input[] = {'a', 'b', 'c', 'd'};
572  memcpy(((struct ll*)(&m27))->s1, input, 4);
573  clang_analyzer_eval(m27.s3[0] == 1); // expected-warning{{UNKNOWN}}
574  clang_analyzer_eval(m27.s3[1] == 1); // expected-warning{{UNKNOWN}}
575  clang_analyzer_eval(m27.s3[2] == 1); // expected-warning{{UNKNOWN}}
576  clang_analyzer_eval(m27.s3[3] == 1); // expected-warning{{UNKNOWN}}
577  clang_analyzer_eval(m27.s3[i] == 1); // expected-warning{{UNKNOWN}}\
578  expected-warning{{Potential leak of memory pointed to by 'm27.s4'}}
579  return 0;
580}
581
582int f28(int i, int j, int k, int l) {
583  struct mm m28[2];
584  m28[i].s4 = strdup("hello");
585  m28[j].s3[k] = 1;
586  struct ll * l28 = (struct ll*)(&m28[1]);
587  l28->s1[l] = 2;
588  char input[] = {'a', 'b', 'c', 'd'};
589  memcpy(l28->s1, input, 4);
590  clang_analyzer_eval(m28[0].s3[0] == 1); // expected-warning{{UNKNOWN}}
591  clang_analyzer_eval(m28[0].s3[1] == 1); // expected-warning{{UNKNOWN}}
592  clang_analyzer_eval(m28[0].s3[2] == 1); // expected-warning{{UNKNOWN}}
593  clang_analyzer_eval(m28[0].s3[3] == 1); // expected-warning{{UNKNOWN}}
594  clang_analyzer_eval(m28[1].s3[0] == 1); // expected-warning{{UNKNOWN}}
595  clang_analyzer_eval(m28[1].s3[1] == 1); // expected-warning{{UNKNOWN}}
596  clang_analyzer_eval(m28[1].s3[2] == 1); // expected-warning{{UNKNOWN}}
597  clang_analyzer_eval(m28[1].s3[3] == 1); // expected-warning{{UNKNOWN}}
598  clang_analyzer_eval(m28[i].s3[0] == 1); // expected-warning{{UNKNOWN}}
599  clang_analyzer_eval(m28[i].s3[1] == 1); // expected-warning{{UNKNOWN}}
600  clang_analyzer_eval(m28[i].s3[2] == 1); // expected-warning{{UNKNOWN}}
601  clang_analyzer_eval(m28[i].s3[3] == 1); // expected-warning{{UNKNOWN}}
602  clang_analyzer_eval(m28[j].s3[k] == 1); // expected-warning{{UNKNOWN}}
603  clang_analyzer_eval(l28->s1[l] == 2); // expected-warning{{UNKNOWN}}
604  return 0;
605}
606
607int f29(int i, int j, int k, int l, int m) {
608  struct mm m29[2];
609  m29[i].s4 = strdup("hello");
610  m29[j].s3[k] = 1;
611  struct ll * l29 = (struct ll*)(&m29[l]);
612  l29->s1[m] = 2;
613  char input[] = {'a', 'b', 'c', 'd'};
614  memcpy(l29->s1, input, 4);
615  clang_analyzer_eval(m29[0].s3[0] == 1); // expected-warning{{UNKNOWN}}
616  clang_analyzer_eval(m29[0].s3[1] == 1); // expected-warning{{UNKNOWN}}
617  clang_analyzer_eval(m29[0].s3[2] == 1); // expected-warning{{UNKNOWN}}
618  clang_analyzer_eval(m29[0].s3[3] == 1); // expected-warning{{UNKNOWN}}
619  clang_analyzer_eval(m29[1].s3[0] == 1); // expected-warning{{UNKNOWN}}
620  clang_analyzer_eval(m29[1].s3[1] == 1); // expected-warning{{UNKNOWN}}
621  clang_analyzer_eval(m29[1].s3[2] == 1); // expected-warning{{UNKNOWN}}
622  clang_analyzer_eval(m29[1].s3[3] == 1); // expected-warning{{UNKNOWN}}
623  clang_analyzer_eval(m29[i].s3[0] == 1); // expected-warning{{UNKNOWN}}
624  clang_analyzer_eval(m29[i].s3[1] == 1); // expected-warning{{UNKNOWN}}
625  clang_analyzer_eval(m29[i].s3[2] == 1); // expected-warning{{UNKNOWN}}
626  clang_analyzer_eval(m29[i].s3[3] == 1); // expected-warning{{UNKNOWN}}
627  clang_analyzer_eval(m29[j].s3[k] == 1); // expected-warning{{TRUE}}\
628  expected-warning{{Potential leak of memory pointed to by field 's4'}}
629  clang_analyzer_eval(l29->s1[m] == 2); // expected-warning{{UNKNOWN}}
630  return 0;
631}
632
633// Test unions' fields.
634union uu {
635  char x;
636  char s1[4];
637};
638
639int f30() {
640  union uu u30 = { .s1 = {1, 2, 3, 4}};
641  char input[] = {1, 2, 3, 4};
642  memcpy(u30.s1, input, 4);
643  clang_analyzer_eval(u30.s1[0] == 1); // expected-warning{{UNKNOWN}}
644  clang_analyzer_eval(u30.s1[1] == 1); // expected-warning{{UNKNOWN}}
645  clang_analyzer_eval(u30.s1[2] == 1); // expected-warning{{UNKNOWN}}
646  clang_analyzer_eval(u30.s1[3] == 1); // expected-warning{{UNKNOWN}}
647  clang_analyzer_eval(u30.x == 1); // expected-warning{{UNKNOWN}}
648  return 0;
649}
650
651struct kk {
652  union uu u;
653  char * s2;
654};
655
656int f31() {
657  struct kk k31;
658  k31.s2 = strdup("hello");
659  k31.u.x = 1;
660  char input[] = {'a', 'b', 'c', 'd'};
661  memcpy(k31.u.s1, input, 4);
662  clang_analyzer_eval(k31.u.s1[0] == 1); // expected-warning{{UNKNOWN}}\
663  expected-warning{{Potential leak of memory pointed to by 'k31.s2'}}
664  clang_analyzer_eval(k31.u.s1[1] == 1); // expected-warning{{UNKNOWN}}
665  clang_analyzer_eval(k31.u.s1[2] == 1); // expected-warning{{UNKNOWN}}
666  clang_analyzer_eval(k31.u.s1[3] == 1); // expected-warning{{UNKNOWN}}
667  clang_analyzer_eval(k31.u.x == 1); // expected-warning{{UNKNOWN}}
668  // FIXME: memory leak warning for k31.s2 should be emitted here.
669  return 0;
670}
671
672union vv {
673  int x;
674  char * s2;
675};
676
677int f32() {
678  union vv v32;
679  v32.s2 = strdup("hello");
680  char input[] = {'a', 'b', 'c', 'd'};
681  memcpy(v32.s2, input, 4);
682  clang_analyzer_eval(v32.s2[0] == 1); // expected-warning{{UNKNOWN}}
683  clang_analyzer_eval(v32.s2[1] == 1); // expected-warning{{UNKNOWN}}
684  clang_analyzer_eval(v32.s2[2] == 1); // expected-warning{{UNKNOWN}}
685  clang_analyzer_eval(v32.s2[3] == 1); // expected-warning{{UNKNOWN}}\
686  expected-warning{{Potential leak of memory pointed to by 'v32.s2'}}
687  return 0;
688}
689
690struct nn {
691  int s1;
692  int i;
693  int j;
694  int k;
695  char * s2;
696};
697
698// Test bad types to dest buffer.
699int f33() {
700  struct nn n33 = {1, 2, 3, 4, 0};
701  n33.s2 = strdup("hello");
702  char input[] = {'a', 'b', 'c', 'd'};
703  memcpy(n33.s1, input, 4); // expected-warning{{incompatible integer to pointer conversion passing 'int' to parameter of type 'void *'}}
704  clang_analyzer_eval(n33.i == 2); // expected-warning{{TRUE}}
705  clang_analyzer_eval(n33.j == 3); // expected-warning{{TRUE}}
706  clang_analyzer_eval(n33.k == 4); // expected-warning{{TRUE}}
707  clang_analyzer_eval(((char*)(n33.s1))[0] == 1); // expected-warning{{UNKNOWN}}\
708  expected-warning{{cast to 'char *' from smaller integer type 'int'}}
709  clang_analyzer_eval(((char*)(n33.s1))[1] == 1); // expected-warning{{UNKNOWN}}\
710  expected-warning{{cast to 'char *' from smaller integer type 'int'}}
711  clang_analyzer_eval(((char*)(n33.s1))[2] == 1); // expected-warning{{UNKNOWN}}\
712  expected-warning{{cast to 'char *' from smaller integer type 'int'}}
713  clang_analyzer_eval(((char*)(n33.s1))[3] == 1); // expected-warning{{UNKNOWN}}\
714  expected-warning{{cast to 'char *' from smaller integer type 'int'}}
715  clang_analyzer_eval(n33.s2 == 0); //expected-warning{{UNKNOWN}}
716  return 0; // expected-warning{{Potential leak of memory pointed to by 'n33.s2'}}
717}
718
719// Test destination buffer being an unknown value.
720struct ww {
721  int s1[4];
722  char s2;
723};
724
725int f34(struct ww * w34, int n) {
726  w34->s2 = 3;
727  char input[] = {'a', 'b', 'c', 'd'};
728  memcpy(w34->s1 + n, input , 4);
729  clang_analyzer_eval(w34->s1[0] == 0); // expected-warning{{UNKNOWN}}
730  clang_analyzer_eval(w34->s1[1] == 0); // expected-warning{{UNKNOWN}}
731  clang_analyzer_eval(w34->s1[2] == 0); // expected-warning{{UNKNOWN}}
732  clang_analyzer_eval(w34->s1[3] == 0); // expected-warning{{UNKNOWN}}
733  clang_analyzer_eval(w34->s1[n] == 0); // expected-warning{{UNKNOWN}}
734  clang_analyzer_eval(w34->s2 == 3); // expected-warning{{TRUE}}
735  return 0;
736}
737
738// Test dest buffer as an element region with a symbolic index and size parameter as a symbolic value.
739struct yy {
740  char s1[4];
741  char * s2;
742};
743
744int f35(int i, int n) {
745  struct yy y35 = {{1, 2, 3, 4}, 0};
746  y35.s2 = strdup("hello");
747  char input[] = {'a', 'b', 'c', 'd'};
748  memcpy(&(y35.s1[i]), input, n);
749  clang_analyzer_eval(y35.s1[0] == 0); // expected-warning{{UNKNOWN}}
750  clang_analyzer_eval(y35.s1[1] == 0); // expected-warning{{UNKNOWN}}
751  clang_analyzer_eval(y35.s1[2] == 0); // expected-warning{{UNKNOWN}}
752  clang_analyzer_eval(y35.s1[3] == 0); // expected-warning{{UNKNOWN}}
753  clang_analyzer_eval(y35.s1[i] == 0); // expected-warning{{UNKNOWN}}
754  clang_analyzer_eval(y35.s2 == 0); // expected-warning{{UNKNOWN}}
755  return 0; // expected-warning{{Potential leak of memory pointed to by 'y35.s2'}}
756}
757
758// Test regions with negative offsets.
759struct zz {
760  char s1[4];
761  int s2;
762};
763
764int f36(struct zz * z36) {
765
766  char input[] = {'a', 'b', 'c', 'd'};
767  z36->s1[0] = 0;
768  z36->s1[1] = 1;
769  z36->s1[2] = 2;
770  z36->s1[3] = 3;
771  z36->s2 = 10;
772
773  z36 = z36 - 1; // Decrement by 8 bytes (struct zz is 8 bytes).
774
775  z36->s1[0] = 4;
776  z36->s1[1] = 5;
777  z36->s1[2] = 6;
778  z36->s1[3] = 7;
779  z36->s2 = 11;
780
781  memcpy(z36->s1, input, 4);
782
783  clang_analyzer_eval(z36->s1[0] == 1); // expected-warning{{UNKNOWN}}
784  clang_analyzer_eval(z36->s1[1] == 1); // expected-warning{{UNKNOWN}}
785  clang_analyzer_eval(z36->s1[2] == 1); // expected-warning{{UNKNOWN}}
786  clang_analyzer_eval(z36->s1[3] == 1); // expected-warning{{UNKNOWN}}
787  clang_analyzer_eval(z36->s2 == 11); // expected-warning{{TRUE}}
788
789  z36 = z36 + 1; // Increment back.
790
791  clang_analyzer_eval(z36->s1[0] == 0); // expected-warning{{TRUE}}
792  clang_analyzer_eval(z36->s1[1] == 1); // expected-warning{{TRUE}}
793  clang_analyzer_eval(z36->s1[2] == 2); // expected-warning{{TRUE}}
794  clang_analyzer_eval(z36->s1[3] == 3); // expected-warning{{TRUE}}
795  clang_analyzer_eval(z36->s2 == 10); // expected-warning{{TRUE}}
796
797  return 0;
798}
799
800int f37(struct zz * z37) {
801
802  char input[] = {'a', 'b', 'c', 'd'};
803  z37->s1[0] = 0;
804  z37->s1[1] = 1;
805  z37->s1[2] = 2;
806  z37->s1[3] = 3;
807  z37->s2 = 10;
808
809  z37 = (struct zz *)((char*)(z37) - 4); // Decrement by 4 bytes (struct zz is 8 bytes).
810
811  z37->s1[0] = 4;
812  z37->s1[1] = 5;
813  z37->s1[2] = 6;
814  z37->s1[3] = 7;
815  z37->s2 = 11;
816
817  memcpy(z37->s1, input, 4);
818
819  clang_analyzer_eval(z37->s1[0] == 1); // expected-warning{{UNKNOWN}}
820  clang_analyzer_eval(z37->s1[1] == 1); // expected-warning{{UNKNOWN}}
821  clang_analyzer_eval(z37->s1[2] == 1); // expected-warning{{UNKNOWN}}
822  clang_analyzer_eval(z37->s1[3] == 1); // expected-warning{{UNKNOWN}}
823  clang_analyzer_eval(z37->s2 == 11); // expected-warning{{TRUE}}
824
825  z37 = (struct zz *)((char*)(z37) + 4); // Increment back.
826
827  clang_analyzer_eval(z37->s1[0] == 11); // expected-warning{{TRUE}}
828  clang_analyzer_eval(z37->s1[1] == 1); // expected-warning{{UNKNOWN}}
829  clang_analyzer_eval(z37->s1[2] == 1); // expected-warning{{UNKNOWN}}
830  clang_analyzer_eval(z37->s1[3] == 1); // expected-warning{{UNKNOWN}}
831  clang_analyzer_eval(z37->s2 == 10); // expected-warning{{TRUE}}
832
833  return 0;
834}
835
836int f38(struct zz * z38) {
837
838  char input[] = {'a', 'b', 'c', 'd'};
839  z38->s1[0] = 0;
840  z38->s1[1] = 1;
841  z38->s1[2] = 2;
842  z38->s1[3] = 3;
843  z38->s2 = 10;
844
845  z38 = (struct zz *)((char*)(z38) - 2); // Decrement by 2 bytes (struct zz is 8 bytes).
846
847  z38->s1[0] = 4;
848  z38->s1[1] = 5;
849  z38->s1[2] = 6;
850  z38->s1[3] = 7;
851  z38->s2 = 11;
852
853  memcpy(z38->s1, input, 4);
854
855  clang_analyzer_eval(z38->s1[0] == 1); // expected-warning{{UNKNOWN}}
856  clang_analyzer_eval(z38->s1[1] == 1); // expected-warning{{UNKNOWN}}
857  clang_analyzer_eval(z38->s1[2] == 1); // expected-warning{{UNKNOWN}}
858  clang_analyzer_eval(z38->s1[3] == 1); // expected-warning{{UNKNOWN}}
859  clang_analyzer_eval(z38->s2 == 11); // expected-warning{{TRUE}}
860
861  z38 = (struct zz *)((char*)(z38) + 2); // Increment back.
862
863  clang_analyzer_eval(z38->s1[0] == 1); // expected-warning{{UNKNOWN}}
864  clang_analyzer_eval(z38->s1[1] == 1); // expected-warning{{UNKNOWN}}
865  clang_analyzer_eval(z38->s1[2] == 11); // expected-warning{{TRUE}}
866  clang_analyzer_eval(z38->s1[3] == 1); // expected-warning{{UNKNOWN}}
867  clang_analyzer_eval(z38->s2 == 10); // expected-warning{{UNKNOWN}}
868
869  return 0;
870}
871
872// Test negative offsets with a different structure layout.
873struct z0 {
874  int s2;
875  char s1[4];
876};
877
878int f39(struct z0 * d39) {
879
880  char input[] = {'a', 'b', 'c', 'd'};
881  d39->s1[0] = 0;
882  d39->s1[1] = 1;
883  d39->s1[2] = 2;
884  d39->s1[3] = 3;
885  d39->s2 = 10;
886
887  d39 = (struct z0 *)((char*)(d39) - 2); // Decrement by 2 bytes (struct z0 is 8 bytes).
888
889  d39->s1[0] = 4;
890  d39->s1[1] = 5;
891  d39->s1[2] = 6;
892  d39->s1[3] = 7;
893  d39->s2 = 11;
894
895  memcpy(d39->s1, input, 4);
896
897  clang_analyzer_eval(d39->s1[0] == 1); // expected-warning{{UNKNOWN}}
898  clang_analyzer_eval(d39->s1[1] == 1); // expected-warning{{UNKNOWN}}
899  clang_analyzer_eval(d39->s1[2] == 1); // expected-warning{{UNKNOWN}}
900  clang_analyzer_eval(d39->s1[3] == 1); // expected-warning{{UNKNOWN}}
901  clang_analyzer_eval(d39->s2 == 11); // expected-warning{{TRUE}}
902
903  d39 = (struct z0 *)((char*)(d39) + 2); // Increment back.
904
905  clang_analyzer_eval(d39->s1[0] == 1); // expected-warning{{UNKNOWN}}
906  clang_analyzer_eval(d39->s1[1] == 1); // expected-warning{{UNKNOWN}}
907  clang_analyzer_eval(d39->s1[2] == 2); // expected-warning{{TRUE}}
908  clang_analyzer_eval(d39->s1[3] == 3); // expected-warning{{TRUE}}
909  // FIXME: d39->s2 should evaluate to at least UNKNOWN or FALSE,
910  // 'collectSubRegionBindings(...)' in RegionStore.cpp will need to
911  // handle a regions' upper boundary overflowing.
912  clang_analyzer_eval(d39->s2 == 10); // expected-warning{{TRUE}}
913
914  return 0;
915}
916
917