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