blob: 467b87b8788369c1fbe1375a96e1821796723805 [file] [log] [blame]
Jordy Roseccbf7ee2010-07-06 23:11:01 +00001// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
2// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
Jordy Rosea6b808c2010-07-07 07:48:06 +00003// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
4// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
Jordy Roseccbf7ee2010-07-06 23:11:01 +00005
6//===----------------------------------------------------------------------===
7// Declarations
8//===----------------------------------------------------------------------===
9
Jordy Rosea6b808c2010-07-07 07:48:06 +000010// Some functions are so similar to each other that they follow the same code
11// path, such as memcpy and __memcpy_chk. If VARIANT is defined, make sure to
12// use the variants instead to make sure they are still checked by the analyzer.
Jordy Roseccbf7ee2010-07-06 23:11:01 +000013
14// Some functions are implemented as builtins. These should be #defined as
15// BUILTIN(f), which will prepend "__builtin_" if USE_BUILTINS is defined.
16
Jordy Rosea6b808c2010-07-07 07:48:06 +000017// Functions that have variants and are also availabe as builtins should be
18// declared carefully! See memcpy() for an example.
Jordy Roseccbf7ee2010-07-06 23:11:01 +000019
20#ifdef USE_BUILTINS
21# define BUILTIN(f) __builtin_ ## f
22#else /* USE_BUILTINS */
23# define BUILTIN(f) f
24#endif /* USE_BUILTINS */
25
26typedef typeof(sizeof(int)) size_t;
27
28//===----------------------------------------------------------------------===
29// memcpy()
30//===----------------------------------------------------------------------===
31
Jordy Rosea6b808c2010-07-07 07:48:06 +000032#ifdef VARIANT
Jordy Roseccbf7ee2010-07-06 23:11:01 +000033
34#define __memcpy_chk BUILTIN(__memcpy_chk)
35void *__memcpy_chk(void *restrict s1, const void *restrict s2, size_t n,
36 size_t destlen);
37
38#define memcpy(a,b,c) __memcpy_chk(a,b,c,(size_t)-1)
39
Jordy Rosea6b808c2010-07-07 07:48:06 +000040#else /* VARIANT */
Jordy Roseccbf7ee2010-07-06 23:11:01 +000041
42#define memcpy BUILTIN(memcpy)
43void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
44
Jordy Rosea6b808c2010-07-07 07:48:06 +000045#endif /* VARIANT */
Jordy Roseccbf7ee2010-07-06 23:11:01 +000046
47
48void memcpy0 () {
49 char src[] = {1, 2, 3, 4};
50 char dst[4];
51
52 memcpy(dst, src, 4); // no-warning
53
54 if (memcpy(dst, src, 4) != dst) {
55 (void)*(char*)0; // no-warning -- should be unreachable
56 }
57}
58
59void memcpy1 () {
60 char src[] = {1, 2, 3, 4};
61 char dst[10];
62
63 memcpy(dst, src, 5); // expected-warning{{out-of-bound}}
64}
65
66void memcpy2 () {
67 char src[] = {1, 2, 3, 4};
68 char dst[1];
69
70 memcpy(dst, src, 4); // expected-warning{{out-of-bound}}
71}
72
73void memcpy3 () {
74 char src[] = {1, 2, 3, 4};
75 char dst[3];
76
77 memcpy(dst+1, src+2, 2); // no-warning
78}
79
80void memcpy4 () {
81 char src[] = {1, 2, 3, 4};
82 char dst[10];
83
84 memcpy(dst+2, src+2, 3); // expected-warning{{out-of-bound}}
85}
86
87void memcpy5() {
88 char src[] = {1, 2, 3, 4};
89 char dst[3];
90
91 memcpy(dst+2, src+2, 2); // expected-warning{{out-of-bound}}
92}
93
94void memcpy6() {
95 int a[4] = {0};
96 memcpy(a, a, 8); // expected-warning{{overlapping}}
97}
98
99void memcpy7() {
100 int a[4] = {0};
101 memcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
102}
103
104void memcpy8() {
105 int a[4] = {0};
106 memcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
107}
108
109void memcpy9() {
110 int a[4] = {0};
111 memcpy(a+2, a+1, 4); // no-warning
112 memcpy(a+1, a+2, 4); // no-warning
113}
114
Jordy Rosea6b808c2010-07-07 07:48:06 +0000115void memcpy10() {
116 char a[4] = {0};
117 memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to byte string function}}
118}
119
120void memcpy11() {
121 char a[4] = {0};
122 memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to byte string function}}
123}
124
125void memcpy12() {
126 char a[4] = {0};
127 memcpy(0, a, 0); // no-warning
128 memcpy(a, 0, 0); // no-warning
129}
130
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000131//===----------------------------------------------------------------------===
132// memmove()
133//===----------------------------------------------------------------------===
134
Jordy Rosea6b808c2010-07-07 07:48:06 +0000135#ifdef VARIANT
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000136
137#define __memmove_chk BUILTIN(__memmove_chk)
138void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen);
139
140#define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1)
141
Jordy Rosea6b808c2010-07-07 07:48:06 +0000142#else /* VARIANT */
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000143
144#define memmove BUILTIN(memmove)
145void *memmove(void *s1, const void *s2, size_t n);
146
Jordy Rosea6b808c2010-07-07 07:48:06 +0000147#endif /* VARIANT */
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000148
149
150void memmove0 () {
151 char src[] = {1, 2, 3, 4};
152 char dst[4];
153
154 memmove(dst, src, 4); // no-warning
155
156 if (memmove(dst, src, 4) != dst) {
157 (void)*(char*)0; // no-warning -- should be unreachable
158 }
159}
160
161void memmove1 () {
162 char src[] = {1, 2, 3, 4};
163 char dst[10];
164
165 memmove(dst, src, 5); // expected-warning{{out-of-bound}}
166}
167
168void memmove2 () {
169 char src[] = {1, 2, 3, 4};
170 char dst[1];
171
172 memmove(dst, src, 4); // expected-warning{{out-of-bound}}
173}
174
175//===----------------------------------------------------------------------===
176// bcopy()
177//===----------------------------------------------------------------------===
178
179#define bcopy BUILTIN(bcopy)
180// __builtin_bcopy is not defined with const in Builtins.def.
181void bcopy(/*const*/ void *s1, void *s2, size_t n);
182
183
184void bcopy0 () {
185 char src[] = {1, 2, 3, 4};
186 char dst[4];
187
188 bcopy(src, dst, 4); // no-warning
189}
190
191void bcopy1 () {
192 char src[] = {1, 2, 3, 4};
193 char dst[10];
194
195 bcopy(src, dst, 5); // expected-warning{{out-of-bound}}
196}
197
198void bcopy2 () {
199 char src[] = {1, 2, 3, 4};
200 char dst[1];
201
202 bcopy(src, dst, 4); // expected-warning{{out-of-bound}}
203}