brintos

brintos / llvm-project-archived public Read only

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