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