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