bstring.c revision cdc3a89d5de90b2299c56f4a46c3de590c5184d1
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s 2// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s 3// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s 4// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -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 29void clang_analyzer_eval(int); 30 31//===----------------------------------------------------------------------=== 32// memcpy() 33//===----------------------------------------------------------------------=== 34 35#ifdef VARIANT 36 37#define __memcpy_chk BUILTIN(__memcpy_chk) 38void *__memcpy_chk(void *restrict s1, const void *restrict s2, size_t n, 39 size_t destlen); 40 41#define memcpy(a,b,c) __memcpy_chk(a,b,c,(size_t)-1) 42 43#else /* VARIANT */ 44 45#define memcpy BUILTIN(memcpy) 46void *memcpy(void *restrict s1, const void *restrict s2, size_t n); 47 48#endif /* VARIANT */ 49 50 51void memcpy0 () { 52 char src[] = {1, 2, 3, 4}; 53 char dst[4] = {0}; 54 55 memcpy(dst, src, 4); // no-warning 56 57 clang_analyzer_eval(memcpy(dst, src, 4) == dst); // expected-warning{{TRUE}} 58 59 // If we actually model the copy, we can make this known. 60 // The important thing for now is that the old value has been invalidated. 61 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}} 62} 63 64void memcpy1 () { 65 char src[] = {1, 2, 3, 4}; 66 char dst[10]; 67 68 memcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}} 69} 70 71void memcpy2 () { 72 char src[] = {1, 2, 3, 4}; 73 char dst[1]; 74 75 memcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}} 76} 77 78void memcpy3 () { 79 char src[] = {1, 2, 3, 4}; 80 char dst[3]; 81 82 memcpy(dst+1, src+2, 2); // no-warning 83} 84 85void memcpy4 () { 86 char src[] = {1, 2, 3, 4}; 87 char dst[10]; 88 89 memcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}} 90} 91 92void memcpy5() { 93 char src[] = {1, 2, 3, 4}; 94 char dst[3]; 95 96 memcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}} 97} 98 99void memcpy6() { 100 int a[4] = {0}; 101 memcpy(a, a, 8); // expected-warning{{overlapping}} 102} 103 104void memcpy7() { 105 int a[4] = {0}; 106 memcpy(a+2, a+1, 8); // expected-warning{{overlapping}} 107} 108 109void memcpy8() { 110 int a[4] = {0}; 111 memcpy(a+1, a+2, 8); // expected-warning{{overlapping}} 112} 113 114void memcpy9() { 115 int a[4] = {0}; 116 memcpy(a+2, a+1, 4); // no-warning 117 memcpy(a+1, a+2, 4); // no-warning 118} 119 120void memcpy10() { 121 char a[4] = {0}; 122 memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}} 123} 124 125void memcpy11() { 126 char a[4] = {0}; 127 memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}} 128} 129 130void memcpy12() { 131 char a[4] = {0}; 132 memcpy(0, a, 0); // no-warning 133} 134 135void memcpy13() { 136 char a[4] = {0}; 137 memcpy(a, 0, 0); // no-warning 138} 139 140void memcpy_unknown_size (size_t n) { 141 char a[4], b[4] = {1}; 142 clang_analyzer_eval(memcpy(a, b, n) == a); // expected-warning{{TRUE}} 143} 144 145void memcpy_unknown_size_warn (size_t n) { 146 char a[4]; 147 void *result = memcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}} 148 clang_analyzer_eval(result == a); // no-warning (above is fatal) 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 clang_analyzer_eval(mempcpy(dst, src, 4) == &dst[4]); // expected-warning{{TRUE}} 178 179 // If we actually model the copy, we can make this known. 180 // The important thing for now is that the old value has been invalidated. 181 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}} 182} 183 184void mempcpy1 () { 185 char src[] = {1, 2, 3, 4}; 186 char dst[10]; 187 188 mempcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}} 189} 190 191void mempcpy2 () { 192 char src[] = {1, 2, 3, 4}; 193 char dst[1]; 194 195 mempcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}} 196} 197 198void mempcpy3 () { 199 char src[] = {1, 2, 3, 4}; 200 char dst[3]; 201 202 mempcpy(dst+1, src+2, 2); // no-warning 203} 204 205void mempcpy4 () { 206 char src[] = {1, 2, 3, 4}; 207 char dst[10]; 208 209 mempcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}} 210} 211 212void mempcpy5() { 213 char src[] = {1, 2, 3, 4}; 214 char dst[3]; 215 216 mempcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}} 217} 218 219void mempcpy6() { 220 int a[4] = {0}; 221 mempcpy(a, a, 8); // expected-warning{{overlapping}} 222} 223 224void mempcpy7() { 225 int a[4] = {0}; 226 mempcpy(a+2, a+1, 8); // expected-warning{{overlapping}} 227} 228 229void mempcpy8() { 230 int a[4] = {0}; 231 mempcpy(a+1, a+2, 8); // expected-warning{{overlapping}} 232} 233 234void mempcpy9() { 235 int a[4] = {0}; 236 mempcpy(a+2, a+1, 4); // no-warning 237 mempcpy(a+1, a+2, 4); // no-warning 238} 239 240void mempcpy10() { 241 char a[4] = {0}; 242 mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}} 243} 244 245void mempcpy11() { 246 char a[4] = {0}; 247 mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}} 248} 249 250void mempcpy12() { 251 char a[4] = {0}; 252 mempcpy(0, a, 0); // no-warning 253} 254 255void mempcpy13() { 256 char a[4] = {0}; 257 mempcpy(a, 0, 0); // no-warning 258} 259 260void mempcpy_unknown_size_warn (size_t n) { 261 char a[4]; 262 void *result = mempcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}} 263 clang_analyzer_eval(result == a); // no-warning (above is fatal) 264} 265 266void mempcpy_unknownable_size (char *src, float n) { 267 char a[4]; 268 // This used to crash because we don't model floats. 269 mempcpy(a, src, (size_t)n); 270} 271 272//===----------------------------------------------------------------------=== 273// memmove() 274//===----------------------------------------------------------------------=== 275 276#ifdef VARIANT 277 278#define __memmove_chk BUILTIN(__memmove_chk) 279void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen); 280 281#define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1) 282 283#else /* VARIANT */ 284 285#define memmove BUILTIN(memmove) 286void *memmove(void *s1, const void *s2, size_t n); 287 288#endif /* VARIANT */ 289 290 291void memmove0 () { 292 char src[] = {1, 2, 3, 4}; 293 char dst[4] = {0}; 294 295 memmove(dst, src, 4); // no-warning 296 297 clang_analyzer_eval(memmove(dst, src, 4) == dst); // expected-warning{{TRUE}} 298 299 // If we actually model the copy, we can make this known. 300 // The important thing for now is that the old value has been invalidated. 301 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}} 302} 303 304void memmove1 () { 305 char src[] = {1, 2, 3, 4}; 306 char dst[10]; 307 308 memmove(dst, src, 5); // expected-warning{{out-of-bound}} 309} 310 311void memmove2 () { 312 char src[] = {1, 2, 3, 4}; 313 char dst[1]; 314 315 memmove(dst, src, 4); // expected-warning{{overflow}} 316} 317 318//===----------------------------------------------------------------------=== 319// memcmp() 320//===----------------------------------------------------------------------=== 321 322#ifdef VARIANT 323 324#define bcmp BUILTIN(bcmp) 325// __builtin_bcmp is not defined with const in Builtins.def. 326int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n); 327#define memcmp bcmp 328// 329#else /* VARIANT */ 330 331#define memcmp BUILTIN(memcmp) 332int memcmp(const void *s1, const void *s2, size_t n); 333 334#endif /* VARIANT */ 335 336 337void memcmp0 () { 338 char a[] = {1, 2, 3, 4}; 339 char b[4] = { 0 }; 340 341 memcmp(a, b, 4); // no-warning 342} 343 344void memcmp1 () { 345 char a[] = {1, 2, 3, 4}; 346 char b[10] = { 0 }; 347 348 memcmp(a, b, 5); // expected-warning{{out-of-bound}} 349} 350 351void memcmp2 () { 352 char a[] = {1, 2, 3, 4}; 353 char b[1] = { 0 }; 354 355 memcmp(a, b, 4); // expected-warning{{out-of-bound}} 356} 357 358void memcmp3 () { 359 char a[] = {1, 2, 3, 4}; 360 361 clang_analyzer_eval(memcmp(a, a, 4) == 0); // expected-warning{{TRUE}} 362} 363 364void memcmp4 (char *input) { 365 char a[] = {1, 2, 3, 4}; 366 367 clang_analyzer_eval(memcmp(a, input, 4) == 0); // expected-warning{{UNKNOWN}} 368} 369 370void memcmp5 (char *input) { 371 char a[] = {1, 2, 3, 4}; 372 373 clang_analyzer_eval(memcmp(a, 0, 0) == 0); // expected-warning{{TRUE}} 374 clang_analyzer_eval(memcmp(0, a, 0) == 0); // expected-warning{{TRUE}} 375 clang_analyzer_eval(memcmp(a, input, 0) == 0); // expected-warning{{TRUE}} 376} 377 378void memcmp6 (char *a, char *b, size_t n) { 379 int result = memcmp(a, b, n); 380 if (result != 0) 381 clang_analyzer_eval(n != 0); // expected-warning{{TRUE}} 382 // else 383 // analyzer_assert_unknown(n == 0); 384 385 // We can't do the above comparison because n has already been constrained. 386 // On one path n == 0, on the other n != 0. 387} 388 389int memcmp7 (char *a, size_t x, size_t y, size_t n) { 390 // We used to crash when either of the arguments was unknown. 391 return memcmp(a, &a[x*y], n) + 392 memcmp(&a[x*y], a, n); 393} 394 395//===----------------------------------------------------------------------=== 396// bcopy() 397//===----------------------------------------------------------------------=== 398 399#define bcopy BUILTIN(bcopy) 400// __builtin_bcopy is not defined with const in Builtins.def. 401void bcopy(/*const*/ void *s1, void *s2, size_t n); 402 403 404void bcopy0 () { 405 char src[] = {1, 2, 3, 4}; 406 char dst[4] = {0}; 407 408 bcopy(src, dst, 4); // no-warning 409 410 // If we actually model the copy, we can make this known. 411 // The important thing for now is that the old value has been invalidated. 412 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}} 413} 414 415void bcopy1 () { 416 char src[] = {1, 2, 3, 4}; 417 char dst[10]; 418 419 bcopy(src, dst, 5); // expected-warning{{out-of-bound}} 420} 421 422void bcopy2 () { 423 char src[] = {1, 2, 3, 4}; 424 char dst[1]; 425 426 bcopy(src, dst, 4); // expected-warning{{overflow}} 427} 428 429void *malloc(size_t); 430void free(void *); 431char radar_11125445_memcopythenlogfirstbyte(const char *input, size_t length) { 432 char *bytes = malloc(sizeof(char) * (length + 1)); 433 memcpy(bytes, input, length); 434 char x = bytes[0]; // no warning 435 free(bytes); 436 return x; 437} 438