bstring.c revision 22d27178bf795145439b9588e260ccceab79a088
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 139void memcpy_unknown_size (size_t n) { 140 char a[4], b[4] = {1}; 141 if (memcpy(a, b, n) != a) 142 (void)*(char*)0; // no-warning 143} 144 145void memcpy_unknown_size_warn (size_t n) { 146 char a[4]; 147 if (memcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to byte string function}} 148 (void)*(char*)0; // no-warning 149} 150 151//===----------------------------------------------------------------------=== 152// mempcpy() 153//===----------------------------------------------------------------------=== 154 155#ifdef VARIANT 156 157#define __mempcpy_chk BUILTIN(__mempcpy_chk) 158void *__mempcpy_chk(void *restrict s1, const void *restrict s2, size_t n, 159 size_t destlen); 160 161#define mempcpy(a,b,c) __mempcpy_chk(a,b,c,(size_t)-1) 162 163#else /* VARIANT */ 164 165#define mempcpy BUILTIN(mempcpy) 166void *mempcpy(void *restrict s1, const void *restrict s2, size_t n); 167 168#endif /* VARIANT */ 169 170 171void mempcpy0 () { 172 char src[] = {1, 2, 3, 4}; 173 char dst[5] = {0}; 174 175 mempcpy(dst, src, 4); // no-warning 176 177 if (mempcpy(dst, src, 4) != &dst[4]) { 178 (void)*(char*)0; // no-warning 179 } 180 181 if (dst[0] != 0) 182 (void)*(char*)0; // expected-warning{{null}} 183} 184 185void mempcpy1 () { 186 char src[] = {1, 2, 3, 4}; 187 char dst[10]; 188 189 mempcpy(dst, src, 5); // expected-warning{{Byte string function accesses out-of-bound array element}} 190} 191 192void mempcpy2 () { 193 char src[] = {1, 2, 3, 4}; 194 char dst[1]; 195 196 mempcpy(dst, src, 4); // expected-warning{{Byte string function overflows destination buffer}} 197} 198 199void mempcpy3 () { 200 char src[] = {1, 2, 3, 4}; 201 char dst[3]; 202 203 mempcpy(dst+1, src+2, 2); // no-warning 204} 205 206void mempcpy4 () { 207 char src[] = {1, 2, 3, 4}; 208 char dst[10]; 209 210 mempcpy(dst+2, src+2, 3); // expected-warning{{Byte string function accesses out-of-bound array element}} 211} 212 213void mempcpy5() { 214 char src[] = {1, 2, 3, 4}; 215 char dst[3]; 216 217 mempcpy(dst+2, src+2, 2); // expected-warning{{Byte string function overflows destination buffer}} 218} 219 220void mempcpy6() { 221 int a[4] = {0}; 222 mempcpy(a, a, 8); // expected-warning{{overlapping}} 223} 224 225void mempcpy7() { 226 int a[4] = {0}; 227 mempcpy(a+2, a+1, 8); // expected-warning{{overlapping}} 228} 229 230void mempcpy8() { 231 int a[4] = {0}; 232 mempcpy(a+1, a+2, 8); // expected-warning{{overlapping}} 233} 234 235void mempcpy9() { 236 int a[4] = {0}; 237 mempcpy(a+2, a+1, 4); // no-warning 238 mempcpy(a+1, a+2, 4); // no-warning 239} 240 241void mempcpy10() { 242 char a[4] = {0}; 243 mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to byte string function}} 244} 245 246void mempcpy11() { 247 char a[4] = {0}; 248 mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to byte string function}} 249} 250 251void mempcpy12() { 252 char a[4] = {0}; 253 mempcpy(0, a, 0); // no-warning 254} 255 256void mempcpy13() { 257 char a[4] = {0}; 258 mempcpy(a, 0, 0); // no-warning 259} 260 261void mempcpy_unknown_size_warn (size_t n) { 262 char a[4]; 263 if (mempcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to byte string function}} 264 (void)*(char*)0; // no-warning 265} 266 267//===----------------------------------------------------------------------=== 268// memmove() 269//===----------------------------------------------------------------------=== 270 271#ifdef VARIANT 272 273#define __memmove_chk BUILTIN(__memmove_chk) 274void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen); 275 276#define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1) 277 278#else /* VARIANT */ 279 280#define memmove BUILTIN(memmove) 281void *memmove(void *s1, const void *s2, size_t n); 282 283#endif /* VARIANT */ 284 285 286void memmove0 () { 287 char src[] = {1, 2, 3, 4}; 288 char dst[4] = {0}; 289 290 memmove(dst, src, 4); // no-warning 291 292 if (memmove(dst, src, 4) != dst) { 293 (void)*(char*)0; // no-warning 294 } 295 296 if (dst[0] != 0) 297 (void)*(char*)0; // expected-warning{{null}} 298} 299 300void memmove1 () { 301 char src[] = {1, 2, 3, 4}; 302 char dst[10]; 303 304 memmove(dst, src, 5); // expected-warning{{out-of-bound}} 305} 306 307void memmove2 () { 308 char src[] = {1, 2, 3, 4}; 309 char dst[1]; 310 311 memmove(dst, src, 4); // expected-warning{{overflow}} 312} 313 314//===----------------------------------------------------------------------=== 315// memcmp() 316//===----------------------------------------------------------------------=== 317 318#ifdef VARIANT 319 320#define bcmp BUILTIN(bcmp) 321// __builtin_bcmp is not defined with const in Builtins.def. 322int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n); 323#define memcmp bcmp 324 325#else /* VARIANT */ 326 327#define memcmp BUILTIN(memcmp) 328int memcmp(const void *s1, const void *s2, size_t n); 329 330#endif /* VARIANT */ 331 332 333void memcmp0 () { 334 char a[] = {1, 2, 3, 4}; 335 char b[4] = { 0 }; 336 337 memcmp(a, b, 4); // no-warning 338} 339 340void memcmp1 () { 341 char a[] = {1, 2, 3, 4}; 342 char b[10] = { 0 }; 343 344 memcmp(a, b, 5); // expected-warning{{out-of-bound}} 345} 346 347void memcmp2 () { 348 char a[] = {1, 2, 3, 4}; 349 char b[1] = { 0 }; 350 351 memcmp(a, b, 4); // expected-warning{{out-of-bound}} 352} 353 354void memcmp3 () { 355 char a[] = {1, 2, 3, 4}; 356 357 if (memcmp(a, a, 4)) 358 (void)*(char*)0; // no-warning 359} 360 361void memcmp4 (char *input) { 362 char a[] = {1, 2, 3, 4}; 363 364 if (memcmp(a, input, 4)) 365 (void)*(char*)0; // expected-warning{{null}} 366} 367 368void memcmp5 (char *input) { 369 char a[] = {1, 2, 3, 4}; 370 371 if (memcmp(a, 0, 0)) // no-warning 372 (void)*(char*)0; // no-warning 373 if (memcmp(0, a, 0)) // no-warning 374 (void)*(char*)0; // no-warning 375 if (memcmp(a, input, 0)) // no-warning 376 (void)*(char*)0; // no-warning 377} 378 379void memcmp6 (char *a, char *b, size_t n) { 380 int result = memcmp(a, b, n); 381 if (result != 0) 382 return; 383 if (n == 0) 384 (void)*(char*)0; // expected-warning{{null}} 385} 386 387int memcmp7 (char *a, size_t x, size_t y, size_t n) { 388 // We used to crash when either of the arguments was unknown. 389 return memcmp(a, &a[x*y], n) + 390 memcmp(&a[x*y], a, n); 391} 392 393//===----------------------------------------------------------------------=== 394// bcopy() 395//===----------------------------------------------------------------------=== 396 397#define bcopy BUILTIN(bcopy) 398// __builtin_bcopy is not defined with const in Builtins.def. 399void bcopy(/*const*/ void *s1, void *s2, size_t n); 400 401 402void bcopy0 () { 403 char src[] = {1, 2, 3, 4}; 404 char dst[4] = {0}; 405 406 bcopy(src, dst, 4); // no-warning 407 408 if (dst[0] != 0) 409 (void)*(char*)0; // expected-warning{{null}} 410} 411 412void bcopy1 () { 413 char src[] = {1, 2, 3, 4}; 414 char dst[10]; 415 416 bcopy(src, dst, 5); // expected-warning{{out-of-bound}} 417} 418 419void bcopy2 () { 420 char src[] = {1, 2, 3, 4}; 421 char dst[1]; 422 423 bcopy(src, dst, 4); // expected-warning{{overflow}} 424} 425