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 argument in call to memory copy function}} 152 } 153 154 void memcpy11() { 155 char a[4] = {0}; 156 memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call 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 argument in call 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 } 226 227 void mempcpy3 () { 228 char src[] = {1, 2, 3, 4}; 229 char dst[3]; 230 231 mempcpy(dst+1, src+2, 2); // no-warning 232 } 233 234 void mempcpy4 () { 235 char src[] = {1, 2, 3, 4}; 236 char dst[10]; 237 238 mempcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}} 239 } 240 241 void mempcpy5() { 242 char src[] = {1, 2, 3, 4}; 243 char dst[3]; 244 245 mempcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}} 246 } 247 248 void mempcpy6() { 249 int a[4] = {0}; 250 mempcpy(a, a, 8); // expected-warning{{overlapping}} 251 } 252 253 void mempcpy7() { 254 int a[4] = {0}; 255 mempcpy(a+2, a+1, 8); // expected-warning{{overlapping}} 256 } 257 258 void mempcpy8() { 259 int a[4] = {0}; 260 mempcpy(a+1, a+2, 8); // expected-warning{{overlapping}} 261 } 262 263 void mempcpy9() { 264 int a[4] = {0}; 265 mempcpy(a+2, a+1, 4); // no-warning 266 mempcpy(a+1, a+2, 4); // no-warning 267 } 268 269 void mempcpy10() { 270 char a[4] = {0}; 271 mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}} 272 } 273 274 void mempcpy11() { 275 char a[4] = {0}; 276 mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}} 277 } 278 279 void mempcpy12() { 280 char a[4] = {0}; 281 mempcpy(0, a, 0); // no-warning 282 } 283 284 void mempcpy13() { 285 char a[4] = {0}; 286 mempcpy(a, 0, 0); // no-warning 287 } 288 289 void mempcpy14() { 290 int src[] = {1, 2, 3, 4}; 291 int dst[5] = {0}; 292 int *p; 293 294 p = mempcpy(dst, src, 4 * sizeof(int)); 295 296 clang_analyzer_eval(p == &dst[4]); // expected-warning{{TRUE}} 297 } 298 299 struct st { 300 int i; 301 int j; 302 }; 303 304 void mempcpy15() { 305 struct st s1 = {0}; 306 struct st s2; 307 struct st *p1; 308 struct st *p2; 309 310 p1 = (&s2) + 1; 311 p2 = mempcpy(&s2, &s1, sizeof(struct st)); 312 313 clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}} 314 } 315 316 void mempcpy16() { 317 struct st s1[10] = {{0}}; 318 struct st s2[10]; 319 struct st *p1; 320 struct st *p2; 321 322 p1 = (&s2[0]) + 5; 323 p2 = mempcpy(&s2[0], &s1[0], 5 * sizeof(struct st)); 324 325 clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}} 326 } 327 328 void mempcpy_unknown_size_warn (size_t n) { 329 char a[4]; 330 void *result = mempcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}} 331 clang_analyzer_eval(result == a); // no-warning (above is fatal) 332 } 333 334 void mempcpy_unknownable_size (char *src, float n) { 335 char a[4]; 336 // This used to crash because we don't model floats. 337 mempcpy(a, src, (size_t)n); 338 } 339 340 //===----------------------------------------------------------------------=== 341 // memmove() 342 //===----------------------------------------------------------------------=== 343 344 #ifdef VARIANT 345 346 #define __memmove_chk BUILTIN(__memmove_chk) 347 void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen); 348 349 #define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1) 350 351 #else /* VARIANT */ 352 353 #define memmove BUILTIN(memmove) 354 void *memmove(void *s1, const void *s2, size_t n); 355 356 #endif /* VARIANT */ 357 358 359 void memmove0 () { 360 char src[] = {1, 2, 3, 4}; 361 char dst[4] = {0}; 362 363 memmove(dst, src, 4); // no-warning 364 365 clang_analyzer_eval(memmove(dst, src, 4) == dst); // expected-warning{{TRUE}} 366 367 // If we actually model the copy, we can make this known. 368 // The important thing for now is that the old value has been invalidated. 369 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}} 370 } 371 372 void memmove1 () { 373 char src[] = {1, 2, 3, 4}; 374 char dst[10]; 375 376 memmove(dst, src, 5); // expected-warning{{out-of-bound}} 377 } 378 379 void memmove2 () { 380 char src[] = {1, 2, 3, 4}; 381 char dst[1]; 382 383 memmove(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}} 384 #ifndef VARIANT 385 // expected-warning@-2{{memmove' will always overflow; destination buffer has size 1, but size argument is 4}} 386 #endif 387 } 388 389 //===----------------------------------------------------------------------=== 390 // memcmp() 391 //===----------------------------------------------------------------------=== 392 393 #ifdef VARIANT 394 395 #define bcmp BUILTIN(bcmp) 396 int bcmp(const void *s1, const void *s2, size_t n); 397 #define memcmp bcmp 398 // 399 #else /* VARIANT */ 400 401 #define memcmp BUILTIN(memcmp) 402 int memcmp(const void *s1, const void *s2, size_t n); 403 404 #endif /* VARIANT */ 405 406 407 void memcmp0 () { 408 char a[] = {1, 2, 3, 4}; 409 char b[4] = { 0 }; 410 411 memcmp(a, b, 4); // no-warning 412 } 413 414 void memcmp1 () { 415 char a[] = {1, 2, 3, 4}; 416 char b[10] = { 0 }; 417 418 memcmp(a, b, 5); // expected-warning{{out-of-bound}} 419 } 420 421 void memcmp2 () { 422 char a[] = {1, 2, 3, 4}; 423 char b[1] = { 0 }; 424 425 memcmp(a, b, 4); // expected-warning{{out-of-bound}} 426 } 427 428 void memcmp3 () { 429 char a[] = {1, 2, 3, 4}; 430 431 clang_analyzer_eval(memcmp(a, a, 4) == 0); // expected-warning{{TRUE}} 432 } 433 434 void memcmp4 (char *input) { 435 char a[] = {1, 2, 3, 4}; 436 437 clang_analyzer_eval(memcmp(a, input, 4) == 0); // expected-warning{{UNKNOWN}} 438 } 439 440 void memcmp5 (char *input) { 441 char a[] = {1, 2, 3, 4}; 442 443 clang_analyzer_eval(memcmp(a, 0, 0) == 0); // expected-warning{{TRUE}} 444 clang_analyzer_eval(memcmp(0, a, 0) == 0); // expected-warning{{TRUE}} 445 clang_analyzer_eval(memcmp(a, input, 0) == 0); // expected-warning{{TRUE}} 446 } 447 448 void memcmp6 (char *a, char *b, size_t n) { 449 int result = memcmp(a, b, n); 450 if (result != 0) 451 clang_analyzer_eval(n != 0); // expected-warning{{TRUE}} 452 // else 453 // analyzer_assert_unknown(n == 0); 454 455 // We can't do the above comparison because n has already been constrained. 456 // On one path n == 0, on the other n != 0. 457 } 458 459 int memcmp7 (char *a, size_t x, size_t y, size_t n) { 460 // We used to crash when either of the arguments was unknown. 461 return memcmp(a, &a[x*y], n) + 462 memcmp(&a[x*y], a, n); 463 } 464 465 //===----------------------------------------------------------------------=== 466 // bcopy() 467 //===----------------------------------------------------------------------=== 468 469 #define bcopy BUILTIN(bcopy) 470 // __builtin_bcopy is not defined with const in Builtins.def. 471 void bcopy(/*const*/ void *s1, void *s2, size_t n); 472 473 474 void bcopy0 () { 475 char src[] = {1, 2, 3, 4}; 476 char dst[4] = {0}; 477 478 bcopy(src, dst, 4); // no-warning 479 480 // If we actually model the copy, we can make this known. 481 // The important thing for now is that the old value has been invalidated. 482 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}} 483 } 484 485 void bcopy1 () { 486 char src[] = {1, 2, 3, 4}; 487 char dst[10]; 488 489 bcopy(src, dst, 5); // expected-warning{{out-of-bound}} 490 } 491 492 void bcopy2 () { 493 char src[] = {1, 2, 3, 4}; 494 char dst[1]; 495 496 bcopy(src, dst, 4); // expected-warning{{overflow}} 497 } 498 499 void *malloc(size_t); 500 void free(void *); 501 char radar_11125445_memcopythenlogfirstbyte(const char *input, size_t length) { 502 char *bytes = malloc(sizeof(char) * (length + 1)); 503 memcpy(bytes, input, length); 504 char x = bytes[0]; // no warning 505 free(bytes); 506 return x; 507 } 508 509 struct S { 510 char f; 511 }; 512 513 void nocrash_on_locint_offset(void *addr, void* from, struct S s) { 514 int iAdd = (int) addr; 515 memcpy(((void *) &(s.f)), from, iAdd); 516 } 517