1*67e74705SXin Li // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
2*67e74705SXin Li // RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
3*67e74705SXin Li // RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
4*67e74705SXin Li // RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
5*67e74705SXin Li
6*67e74705SXin Li //===----------------------------------------------------------------------===
7*67e74705SXin Li // Declarations
8*67e74705SXin Li //===----------------------------------------------------------------------===
9*67e74705SXin Li
10*67e74705SXin Li // Some functions are so similar to each other that they follow the same code
11*67e74705SXin Li // path, such as memcpy and __memcpy_chk, or memcmp and bcmp. If VARIANT is
12*67e74705SXin Li // defined, make sure to use the variants instead to make sure they are still
13*67e74705SXin Li // checked by the analyzer.
14*67e74705SXin Li
15*67e74705SXin Li // Some functions are implemented as builtins. These should be #defined as
16*67e74705SXin Li // BUILTIN(f), which will prepend "__builtin_" if USE_BUILTINS is defined.
17*67e74705SXin Li
18*67e74705SXin Li // Functions that have variants and are also available as builtins should be
19*67e74705SXin Li // declared carefully! See memcpy() for an example.
20*67e74705SXin Li
21*67e74705SXin Li #ifdef USE_BUILTINS
22*67e74705SXin Li # define BUILTIN(f) __builtin_ ## f
23*67e74705SXin Li #else /* USE_BUILTINS */
24*67e74705SXin Li # define BUILTIN(f) f
25*67e74705SXin Li #endif /* USE_BUILTINS */
26*67e74705SXin Li
27*67e74705SXin Li typedef typeof(sizeof(int)) size_t;
28*67e74705SXin Li
29*67e74705SXin Li void clang_analyzer_eval(int);
30*67e74705SXin Li
31*67e74705SXin Li //===----------------------------------------------------------------------===
32*67e74705SXin Li // memcpy()
33*67e74705SXin Li //===----------------------------------------------------------------------===
34*67e74705SXin Li
35*67e74705SXin Li #ifdef VARIANT
36*67e74705SXin Li
37*67e74705SXin Li #define __memcpy_chk BUILTIN(__memcpy_chk)
38*67e74705SXin Li void *__memcpy_chk(void *restrict s1, const void *restrict s2, size_t n,
39*67e74705SXin Li size_t destlen);
40*67e74705SXin Li
41*67e74705SXin Li #define memcpy(a,b,c) __memcpy_chk(a,b,c,(size_t)-1)
42*67e74705SXin Li
43*67e74705SXin Li #else /* VARIANT */
44*67e74705SXin Li
45*67e74705SXin Li #define memcpy BUILTIN(memcpy)
46*67e74705SXin Li void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
47*67e74705SXin Li
48*67e74705SXin Li #endif /* VARIANT */
49*67e74705SXin Li
50*67e74705SXin Li
memcpy0()51*67e74705SXin Li void memcpy0 () {
52*67e74705SXin Li char src[] = {1, 2, 3, 4};
53*67e74705SXin Li char dst[4] = {0};
54*67e74705SXin Li
55*67e74705SXin Li memcpy(dst, src, 4); // no-warning
56*67e74705SXin Li
57*67e74705SXin Li clang_analyzer_eval(memcpy(dst, src, 4) == dst); // expected-warning{{TRUE}}
58*67e74705SXin Li
59*67e74705SXin Li // If we actually model the copy, we can make this known.
60*67e74705SXin Li // The important thing for now is that the old value has been invalidated.
61*67e74705SXin Li clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
62*67e74705SXin Li }
63*67e74705SXin Li
memcpy1()64*67e74705SXin Li void memcpy1 () {
65*67e74705SXin Li char src[] = {1, 2, 3, 4};
66*67e74705SXin Li char dst[10];
67*67e74705SXin Li
68*67e74705SXin Li memcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
69*67e74705SXin Li }
70*67e74705SXin Li
memcpy2()71*67e74705SXin Li void memcpy2 () {
72*67e74705SXin Li char src[] = {1, 2, 3, 4};
73*67e74705SXin Li char dst[1];
74*67e74705SXin Li
75*67e74705SXin Li memcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
76*67e74705SXin Li }
77*67e74705SXin Li
memcpy3()78*67e74705SXin Li void memcpy3 () {
79*67e74705SXin Li char src[] = {1, 2, 3, 4};
80*67e74705SXin Li char dst[3];
81*67e74705SXin Li
82*67e74705SXin Li memcpy(dst+1, src+2, 2); // no-warning
83*67e74705SXin Li }
84*67e74705SXin Li
memcpy4()85*67e74705SXin Li void memcpy4 () {
86*67e74705SXin Li char src[] = {1, 2, 3, 4};
87*67e74705SXin Li char dst[10];
88*67e74705SXin Li
89*67e74705SXin Li memcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
90*67e74705SXin Li }
91*67e74705SXin Li
memcpy5()92*67e74705SXin Li void memcpy5() {
93*67e74705SXin Li char src[] = {1, 2, 3, 4};
94*67e74705SXin Li char dst[3];
95*67e74705SXin Li
96*67e74705SXin Li memcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
97*67e74705SXin Li }
98*67e74705SXin Li
memcpy6()99*67e74705SXin Li void memcpy6() {
100*67e74705SXin Li int a[4] = {0};
101*67e74705SXin Li memcpy(a, a, 8); // expected-warning{{overlapping}}
102*67e74705SXin Li }
103*67e74705SXin Li
memcpy7()104*67e74705SXin Li void memcpy7() {
105*67e74705SXin Li int a[4] = {0};
106*67e74705SXin Li memcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
107*67e74705SXin Li }
108*67e74705SXin Li
memcpy8()109*67e74705SXin Li void memcpy8() {
110*67e74705SXin Li int a[4] = {0};
111*67e74705SXin Li memcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
112*67e74705SXin Li }
113*67e74705SXin Li
memcpy9()114*67e74705SXin Li void memcpy9() {
115*67e74705SXin Li int a[4] = {0};
116*67e74705SXin Li memcpy(a+2, a+1, 4); // no-warning
117*67e74705SXin Li memcpy(a+1, a+2, 4); // no-warning
118*67e74705SXin Li }
119*67e74705SXin Li
memcpy10()120*67e74705SXin Li void memcpy10() {
121*67e74705SXin Li char a[4] = {0};
122*67e74705SXin Li memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
123*67e74705SXin Li }
124*67e74705SXin Li
memcpy11()125*67e74705SXin Li void memcpy11() {
126*67e74705SXin Li char a[4] = {0};
127*67e74705SXin Li memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
128*67e74705SXin Li }
129*67e74705SXin Li
memcpy12()130*67e74705SXin Li void memcpy12() {
131*67e74705SXin Li char a[4] = {0};
132*67e74705SXin Li memcpy(0, a, 0); // no-warning
133*67e74705SXin Li }
134*67e74705SXin Li
memcpy13()135*67e74705SXin Li void memcpy13() {
136*67e74705SXin Li char a[4] = {0};
137*67e74705SXin Li memcpy(a, 0, 0); // no-warning
138*67e74705SXin Li }
139*67e74705SXin Li
memcpy_unknown_size(size_t n)140*67e74705SXin Li void memcpy_unknown_size (size_t n) {
141*67e74705SXin Li char a[4], b[4] = {1};
142*67e74705SXin Li clang_analyzer_eval(memcpy(a, b, n) == a); // expected-warning{{TRUE}}
143*67e74705SXin Li }
144*67e74705SXin Li
memcpy_unknown_size_warn(size_t n)145*67e74705SXin Li void memcpy_unknown_size_warn (size_t n) {
146*67e74705SXin Li char a[4];
147*67e74705SXin Li void *result = memcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}}
148*67e74705SXin Li clang_analyzer_eval(result == a); // no-warning (above is fatal)
149*67e74705SXin Li }
150*67e74705SXin Li
151*67e74705SXin Li //===----------------------------------------------------------------------===
152*67e74705SXin Li // mempcpy()
153*67e74705SXin Li //===----------------------------------------------------------------------===
154*67e74705SXin Li
155*67e74705SXin Li #ifdef VARIANT
156*67e74705SXin Li
157*67e74705SXin Li #define __mempcpy_chk BUILTIN(__mempcpy_chk)
158*67e74705SXin Li void *__mempcpy_chk(void *restrict s1, const void *restrict s2, size_t n,
159*67e74705SXin Li size_t destlen);
160*67e74705SXin Li
161*67e74705SXin Li #define mempcpy(a,b,c) __mempcpy_chk(a,b,c,(size_t)-1)
162*67e74705SXin Li
163*67e74705SXin Li #else /* VARIANT */
164*67e74705SXin Li
165*67e74705SXin Li #define mempcpy BUILTIN(mempcpy)
166*67e74705SXin Li void *mempcpy(void *restrict s1, const void *restrict s2, size_t n);
167*67e74705SXin Li
168*67e74705SXin Li #endif /* VARIANT */
169*67e74705SXin Li
170*67e74705SXin Li
mempcpy0()171*67e74705SXin Li void mempcpy0 () {
172*67e74705SXin Li char src[] = {1, 2, 3, 4};
173*67e74705SXin Li char dst[5] = {0};
174*67e74705SXin Li
175*67e74705SXin Li mempcpy(dst, src, 4); // no-warning
176*67e74705SXin Li
177*67e74705SXin Li clang_analyzer_eval(mempcpy(dst, src, 4) == &dst[4]); // expected-warning{{TRUE}}
178*67e74705SXin Li
179*67e74705SXin Li // If we actually model the copy, we can make this known.
180*67e74705SXin Li // The important thing for now is that the old value has been invalidated.
181*67e74705SXin Li clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
182*67e74705SXin Li }
183*67e74705SXin Li
mempcpy1()184*67e74705SXin Li void mempcpy1 () {
185*67e74705SXin Li char src[] = {1, 2, 3, 4};
186*67e74705SXin Li char dst[10];
187*67e74705SXin Li
188*67e74705SXin Li mempcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
189*67e74705SXin Li }
190*67e74705SXin Li
mempcpy2()191*67e74705SXin Li void mempcpy2 () {
192*67e74705SXin Li char src[] = {1, 2, 3, 4};
193*67e74705SXin Li char dst[1];
194*67e74705SXin Li
195*67e74705SXin Li mempcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
196*67e74705SXin Li }
197*67e74705SXin Li
mempcpy3()198*67e74705SXin Li void mempcpy3 () {
199*67e74705SXin Li char src[] = {1, 2, 3, 4};
200*67e74705SXin Li char dst[3];
201*67e74705SXin Li
202*67e74705SXin Li mempcpy(dst+1, src+2, 2); // no-warning
203*67e74705SXin Li }
204*67e74705SXin Li
mempcpy4()205*67e74705SXin Li void mempcpy4 () {
206*67e74705SXin Li char src[] = {1, 2, 3, 4};
207*67e74705SXin Li char dst[10];
208*67e74705SXin Li
209*67e74705SXin Li mempcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
210*67e74705SXin Li }
211*67e74705SXin Li
mempcpy5()212*67e74705SXin Li void mempcpy5() {
213*67e74705SXin Li char src[] = {1, 2, 3, 4};
214*67e74705SXin Li char dst[3];
215*67e74705SXin Li
216*67e74705SXin Li mempcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
217*67e74705SXin Li }
218*67e74705SXin Li
mempcpy6()219*67e74705SXin Li void mempcpy6() {
220*67e74705SXin Li int a[4] = {0};
221*67e74705SXin Li mempcpy(a, a, 8); // expected-warning{{overlapping}}
222*67e74705SXin Li }
223*67e74705SXin Li
mempcpy7()224*67e74705SXin Li void mempcpy7() {
225*67e74705SXin Li int a[4] = {0};
226*67e74705SXin Li mempcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
227*67e74705SXin Li }
228*67e74705SXin Li
mempcpy8()229*67e74705SXin Li void mempcpy8() {
230*67e74705SXin Li int a[4] = {0};
231*67e74705SXin Li mempcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
232*67e74705SXin Li }
233*67e74705SXin Li
mempcpy9()234*67e74705SXin Li void mempcpy9() {
235*67e74705SXin Li int a[4] = {0};
236*67e74705SXin Li mempcpy(a+2, a+1, 4); // no-warning
237*67e74705SXin Li mempcpy(a+1, a+2, 4); // no-warning
238*67e74705SXin Li }
239*67e74705SXin Li
mempcpy10()240*67e74705SXin Li void mempcpy10() {
241*67e74705SXin Li char a[4] = {0};
242*67e74705SXin Li mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
243*67e74705SXin Li }
244*67e74705SXin Li
mempcpy11()245*67e74705SXin Li void mempcpy11() {
246*67e74705SXin Li char a[4] = {0};
247*67e74705SXin Li mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
248*67e74705SXin Li }
249*67e74705SXin Li
mempcpy12()250*67e74705SXin Li void mempcpy12() {
251*67e74705SXin Li char a[4] = {0};
252*67e74705SXin Li mempcpy(0, a, 0); // no-warning
253*67e74705SXin Li }
254*67e74705SXin Li
mempcpy13()255*67e74705SXin Li void mempcpy13() {
256*67e74705SXin Li char a[4] = {0};
257*67e74705SXin Li mempcpy(a, 0, 0); // no-warning
258*67e74705SXin Li }
259*67e74705SXin Li
mempcpy14()260*67e74705SXin Li void mempcpy14() {
261*67e74705SXin Li int src[] = {1, 2, 3, 4};
262*67e74705SXin Li int dst[5] = {0};
263*67e74705SXin Li int *p;
264*67e74705SXin Li
265*67e74705SXin Li p = mempcpy(dst, src, 4 * sizeof(int));
266*67e74705SXin Li
267*67e74705SXin Li clang_analyzer_eval(p == &dst[4]); // expected-warning{{TRUE}}
268*67e74705SXin Li }
269*67e74705SXin Li
270*67e74705SXin Li struct st {
271*67e74705SXin Li int i;
272*67e74705SXin Li int j;
273*67e74705SXin Li };
274*67e74705SXin Li
mempcpy15()275*67e74705SXin Li void mempcpy15() {
276*67e74705SXin Li struct st s1 = {0};
277*67e74705SXin Li struct st s2;
278*67e74705SXin Li struct st *p1;
279*67e74705SXin Li struct st *p2;
280*67e74705SXin Li
281*67e74705SXin Li p1 = (&s2) + 1;
282*67e74705SXin Li p2 = mempcpy(&s2, &s1, sizeof(struct st));
283*67e74705SXin Li
284*67e74705SXin Li clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}}
285*67e74705SXin Li }
286*67e74705SXin Li
mempcpy16()287*67e74705SXin Li void mempcpy16() {
288*67e74705SXin Li struct st s1[10] = {{0}};
289*67e74705SXin Li struct st s2[10];
290*67e74705SXin Li struct st *p1;
291*67e74705SXin Li struct st *p2;
292*67e74705SXin Li
293*67e74705SXin Li p1 = (&s2[0]) + 5;
294*67e74705SXin Li p2 = mempcpy(&s2[0], &s1[0], 5 * sizeof(struct st));
295*67e74705SXin Li
296*67e74705SXin Li clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}}
297*67e74705SXin Li }
298*67e74705SXin Li
mempcpy_unknown_size_warn(size_t n)299*67e74705SXin Li void mempcpy_unknown_size_warn (size_t n) {
300*67e74705SXin Li char a[4];
301*67e74705SXin Li void *result = mempcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}}
302*67e74705SXin Li clang_analyzer_eval(result == a); // no-warning (above is fatal)
303*67e74705SXin Li }
304*67e74705SXin Li
mempcpy_unknownable_size(char * src,float n)305*67e74705SXin Li void mempcpy_unknownable_size (char *src, float n) {
306*67e74705SXin Li char a[4];
307*67e74705SXin Li // This used to crash because we don't model floats.
308*67e74705SXin Li mempcpy(a, src, (size_t)n);
309*67e74705SXin Li }
310*67e74705SXin Li
311*67e74705SXin Li //===----------------------------------------------------------------------===
312*67e74705SXin Li // memmove()
313*67e74705SXin Li //===----------------------------------------------------------------------===
314*67e74705SXin Li
315*67e74705SXin Li #ifdef VARIANT
316*67e74705SXin Li
317*67e74705SXin Li #define __memmove_chk BUILTIN(__memmove_chk)
318*67e74705SXin Li void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen);
319*67e74705SXin Li
320*67e74705SXin Li #define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1)
321*67e74705SXin Li
322*67e74705SXin Li #else /* VARIANT */
323*67e74705SXin Li
324*67e74705SXin Li #define memmove BUILTIN(memmove)
325*67e74705SXin Li void *memmove(void *s1, const void *s2, size_t n);
326*67e74705SXin Li
327*67e74705SXin Li #endif /* VARIANT */
328*67e74705SXin Li
329*67e74705SXin Li
memmove0()330*67e74705SXin Li void memmove0 () {
331*67e74705SXin Li char src[] = {1, 2, 3, 4};
332*67e74705SXin Li char dst[4] = {0};
333*67e74705SXin Li
334*67e74705SXin Li memmove(dst, src, 4); // no-warning
335*67e74705SXin Li
336*67e74705SXin Li clang_analyzer_eval(memmove(dst, src, 4) == dst); // expected-warning{{TRUE}}
337*67e74705SXin Li
338*67e74705SXin Li // If we actually model the copy, we can make this known.
339*67e74705SXin Li // The important thing for now is that the old value has been invalidated.
340*67e74705SXin Li clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
341*67e74705SXin Li }
342*67e74705SXin Li
memmove1()343*67e74705SXin Li void memmove1 () {
344*67e74705SXin Li char src[] = {1, 2, 3, 4};
345*67e74705SXin Li char dst[10];
346*67e74705SXin Li
347*67e74705SXin Li memmove(dst, src, 5); // expected-warning{{out-of-bound}}
348*67e74705SXin Li }
349*67e74705SXin Li
memmove2()350*67e74705SXin Li void memmove2 () {
351*67e74705SXin Li char src[] = {1, 2, 3, 4};
352*67e74705SXin Li char dst[1];
353*67e74705SXin Li
354*67e74705SXin Li memmove(dst, src, 4); // expected-warning{{overflow}}
355*67e74705SXin Li }
356*67e74705SXin Li
357*67e74705SXin Li //===----------------------------------------------------------------------===
358*67e74705SXin Li // memcmp()
359*67e74705SXin Li //===----------------------------------------------------------------------===
360*67e74705SXin Li
361*67e74705SXin Li #ifdef VARIANT
362*67e74705SXin Li
363*67e74705SXin Li #define bcmp BUILTIN(bcmp)
364*67e74705SXin Li // __builtin_bcmp is not defined with const in Builtins.def.
365*67e74705SXin Li int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n);
366*67e74705SXin Li #define memcmp bcmp
367*67e74705SXin Li //
368*67e74705SXin Li #else /* VARIANT */
369*67e74705SXin Li
370*67e74705SXin Li #define memcmp BUILTIN(memcmp)
371*67e74705SXin Li int memcmp(const void *s1, const void *s2, size_t n);
372*67e74705SXin Li
373*67e74705SXin Li #endif /* VARIANT */
374*67e74705SXin Li
375*67e74705SXin Li
memcmp0()376*67e74705SXin Li void memcmp0 () {
377*67e74705SXin Li char a[] = {1, 2, 3, 4};
378*67e74705SXin Li char b[4] = { 0 };
379*67e74705SXin Li
380*67e74705SXin Li memcmp(a, b, 4); // no-warning
381*67e74705SXin Li }
382*67e74705SXin Li
memcmp1()383*67e74705SXin Li void memcmp1 () {
384*67e74705SXin Li char a[] = {1, 2, 3, 4};
385*67e74705SXin Li char b[10] = { 0 };
386*67e74705SXin Li
387*67e74705SXin Li memcmp(a, b, 5); // expected-warning{{out-of-bound}}
388*67e74705SXin Li }
389*67e74705SXin Li
memcmp2()390*67e74705SXin Li void memcmp2 () {
391*67e74705SXin Li char a[] = {1, 2, 3, 4};
392*67e74705SXin Li char b[1] = { 0 };
393*67e74705SXin Li
394*67e74705SXin Li memcmp(a, b, 4); // expected-warning{{out-of-bound}}
395*67e74705SXin Li }
396*67e74705SXin Li
memcmp3()397*67e74705SXin Li void memcmp3 () {
398*67e74705SXin Li char a[] = {1, 2, 3, 4};
399*67e74705SXin Li
400*67e74705SXin Li clang_analyzer_eval(memcmp(a, a, 4) == 0); // expected-warning{{TRUE}}
401*67e74705SXin Li }
402*67e74705SXin Li
memcmp4(char * input)403*67e74705SXin Li void memcmp4 (char *input) {
404*67e74705SXin Li char a[] = {1, 2, 3, 4};
405*67e74705SXin Li
406*67e74705SXin Li clang_analyzer_eval(memcmp(a, input, 4) == 0); // expected-warning{{UNKNOWN}}
407*67e74705SXin Li }
408*67e74705SXin Li
memcmp5(char * input)409*67e74705SXin Li void memcmp5 (char *input) {
410*67e74705SXin Li char a[] = {1, 2, 3, 4};
411*67e74705SXin Li
412*67e74705SXin Li clang_analyzer_eval(memcmp(a, 0, 0) == 0); // expected-warning{{TRUE}}
413*67e74705SXin Li clang_analyzer_eval(memcmp(0, a, 0) == 0); // expected-warning{{TRUE}}
414*67e74705SXin Li clang_analyzer_eval(memcmp(a, input, 0) == 0); // expected-warning{{TRUE}}
415*67e74705SXin Li }
416*67e74705SXin Li
memcmp6(char * a,char * b,size_t n)417*67e74705SXin Li void memcmp6 (char *a, char *b, size_t n) {
418*67e74705SXin Li int result = memcmp(a, b, n);
419*67e74705SXin Li if (result != 0)
420*67e74705SXin Li clang_analyzer_eval(n != 0); // expected-warning{{TRUE}}
421*67e74705SXin Li // else
422*67e74705SXin Li // analyzer_assert_unknown(n == 0);
423*67e74705SXin Li
424*67e74705SXin Li // We can't do the above comparison because n has already been constrained.
425*67e74705SXin Li // On one path n == 0, on the other n != 0.
426*67e74705SXin Li }
427*67e74705SXin Li
memcmp7(char * a,size_t x,size_t y,size_t n)428*67e74705SXin Li int memcmp7 (char *a, size_t x, size_t y, size_t n) {
429*67e74705SXin Li // We used to crash when either of the arguments was unknown.
430*67e74705SXin Li return memcmp(a, &a[x*y], n) +
431*67e74705SXin Li memcmp(&a[x*y], a, n);
432*67e74705SXin Li }
433*67e74705SXin Li
434*67e74705SXin Li //===----------------------------------------------------------------------===
435*67e74705SXin Li // bcopy()
436*67e74705SXin Li //===----------------------------------------------------------------------===
437*67e74705SXin Li
438*67e74705SXin Li #define bcopy BUILTIN(bcopy)
439*67e74705SXin Li // __builtin_bcopy is not defined with const in Builtins.def.
440*67e74705SXin Li void bcopy(/*const*/ void *s1, void *s2, size_t n);
441*67e74705SXin Li
442*67e74705SXin Li
bcopy0()443*67e74705SXin Li void bcopy0 () {
444*67e74705SXin Li char src[] = {1, 2, 3, 4};
445*67e74705SXin Li char dst[4] = {0};
446*67e74705SXin Li
447*67e74705SXin Li bcopy(src, dst, 4); // no-warning
448*67e74705SXin Li
449*67e74705SXin Li // If we actually model the copy, we can make this known.
450*67e74705SXin Li // The important thing for now is that the old value has been invalidated.
451*67e74705SXin Li clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
452*67e74705SXin Li }
453*67e74705SXin Li
bcopy1()454*67e74705SXin Li void bcopy1 () {
455*67e74705SXin Li char src[] = {1, 2, 3, 4};
456*67e74705SXin Li char dst[10];
457*67e74705SXin Li
458*67e74705SXin Li bcopy(src, dst, 5); // expected-warning{{out-of-bound}}
459*67e74705SXin Li }
460*67e74705SXin Li
bcopy2()461*67e74705SXin Li void bcopy2 () {
462*67e74705SXin Li char src[] = {1, 2, 3, 4};
463*67e74705SXin Li char dst[1];
464*67e74705SXin Li
465*67e74705SXin Li bcopy(src, dst, 4); // expected-warning{{overflow}}
466*67e74705SXin Li }
467*67e74705SXin Li
468*67e74705SXin Li void *malloc(size_t);
469*67e74705SXin Li void free(void *);
radar_11125445_memcopythenlogfirstbyte(const char * input,size_t length)470*67e74705SXin Li char radar_11125445_memcopythenlogfirstbyte(const char *input, size_t length) {
471*67e74705SXin Li char *bytes = malloc(sizeof(char) * (length + 1));
472*67e74705SXin Li memcpy(bytes, input, length);
473*67e74705SXin Li char x = bytes[0]; // no warning
474*67e74705SXin Li free(bytes);
475*67e74705SXin Li return x;
476*67e74705SXin Li }
477