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
8 typedef __typeof(sizeof(int)) size_t;
10 char *strdup(const char *s
);
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
);
15 void clang_analyzer_eval(int);
22 // Test different types of structure initialisation.
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
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
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
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
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
110 // Test that memory leaks are caught.
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'}}
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'}}
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'}}
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'}}
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'}}
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'}}
166 // Test invalidating fields being addresses of array.
177 c0
.s2
= strdup("hello");
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
191 // Test inverting field position between s1 and s2.
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
211 // Test arrays of structs.
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
236 // Test global parameters.
237 struct aa a15
= {{1, 2, 3, 4}, 0};
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
252 // Test array of 0 sized elements.
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
274 // Test array of 0 elements.
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
292 // Test writing past the array.
301 struct ii i18
= {{1, 2, 3, 4}, 5, 6};
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}}
318 struct ii i181
= {{1, 2, 3, 4}, 5, 6};
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}}
334 // Test array with a symbolic offset.
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
369 // Test array with its super region having symbolic offseted regions.
371 struct aa
* a20
= malloc(sizeof(struct aa
) * 2);
376 a20
[0].s2
= strdup("hello");
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'}}
405 // Test array's region and super region both having symbolic offsets.
407 struct aa
* a21
= malloc(sizeof(struct aa
) * 2);
418 a21
[i
].s2
= strdup("hello");
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'}}
445 // Test regions aliasing other regions.
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'}}
474 // Test region with potential aliasing and symbolic offsets.
475 // Store assumes no aliasing.
476 int f25(int i
, int j
, struct ll
* l
, struct mm
* m
) {
477 m
->s4
= strdup("hola"); // m->s4 not tracked
482 m
->s3
[j
] = 5; // invalidates m->s3
483 l
->s2
= strdup("hello"); // l->s2 not tracked
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}}
506 // Test size with symbolic size argument.
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'}}
520 // Test sizeof as a size argument.
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'}}
534 // Test negative size argument.
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}}
548 // Test size argument being an unknown value.
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}}
569 // Test casting regions with symbolic offseted sub regions.
571 struct mm m27
= {{1, 2, 3, 4}, 0};
572 m27
.s4
= strdup("hello");
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'}}
585 int f28(int i
, int j
, int k
, int l
) {
587 m28
[i
].s4
= strdup("hello");
589 struct ll
* l28
= (struct ll
*)(&m28
[1]);
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}}
610 int f29(int i
, int j
, int k
, int l
, int m
) {
612 m29
[i
].s4
= strdup("hello");
614 struct ll
* l29
= (struct ll
*)(&m29
[l
]);
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.
637 // Test unions' fields.
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}}
662 k31
.s2
= strdup("hello");
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.
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'}}
702 // Test bad types to dest buffer.
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'}}
723 // Test destination buffer being an unknown value.
729 int f34(struct ww
* w34
, int n
) {
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}}
742 // Test dest buffer as an element region with a symbolic index and size parameter as a symbolic value.
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'}}
762 // Test regions with negative offsets.
768 int f36(struct zz
* z36
) {
770 char input
[] = {'a', 'b', 'c', 'd'};
777 z36
= z36
- 1; // Decrement by 8 bytes (struct zz is 8 bytes).
785 memcpy(z36
->s1
, input
, 4);
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}}
793 z36
= z36
+ 1; // Increment back.
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}}
804 int f37(struct zz
* z37
) {
806 char input
[] = {'a', 'b', 'c', 'd'};
813 z37
= (struct zz
*)((char*)(z37
) - 4); // Decrement by 4 bytes (struct zz is 8 bytes).
821 memcpy(z37
->s1
, input
, 4);
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}}
829 z37
= (struct zz
*)((char*)(z37
) + 4); // Increment back.
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}}
840 int f38(struct zz
* z38
) {
842 char input
[] = {'a', 'b', 'c', 'd'};
849 z38
= (struct zz
*)((char*)(z38
) - 2); // Decrement by 2 bytes (struct zz is 8 bytes).
857 memcpy(z38
->s1
, input
, 4);
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}}
865 z38
= (struct zz
*)((char*)(z38
) + 2); // Increment back.
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}}
876 // Test negative offsets with a different structure layout.
882 int f39(struct z0
* d39
) {
884 char input
[] = {'a', 'b', 'c', 'd'};
891 d39
= (struct z0
*)((char*)(d39
) - 2); // Decrement by 2 bytes (struct z0 is 8 bytes).
899 memcpy(d39
->s1
, input
, 4);
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}}
907 d39
= (struct z0
*)((char*)(d39
) + 2); // Increment back.
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}}