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