brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.6 KiB · 9c60d39 Raw
639 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=false  8//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//===----------------------------------------------------------------------===18// Declarations19//===----------------------------------------------------------------------===20 21// Some functions are implemented as builtins. These should be #defined as22// BUILTIN(f), which will prepend "__builtin_" if USE_BUILTINS is defined.23 24#ifdef USE_BUILTINS25# define BUILTIN(f) __builtin_ ## f26#else /* USE_BUILTINS */27# define BUILTIN(f) f28#endif /* USE_BUILTINS */29 30typedef __SIZE_TYPE__ size_t;31typedef __WCHAR_TYPE__ wchar_t;32 33void clang_analyzer_eval(int);34 35//===----------------------------------------------------------------------===36// wmemcpy()37//===----------------------------------------------------------------------===38 39#define wmemcpy BUILTIN(wmemcpy)40wchar_t *wmemcpy(wchar_t *restrict s1, const wchar_t *restrict s2, size_t n);41 42void wmemcpy0 (void) {43  wchar_t src[] = {1, 2, 3, 4};44  wchar_t dst[4] = {0};45 46  wmemcpy(dst, src, 4); // no-warning47 48  clang_analyzer_eval(wmemcpy(dst, src, 4) == dst); // expected-warning{{TRUE}}49 50  // If we actually model the copy, we can make this known.51  // The important thing for now is that the old value has been invalidated.52  clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}53}54 55void wmemcpy1 (void) {56  wchar_t src[] = {1, 2, 3, 4};57  wchar_t dst[10];58 59  wmemcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}60}61 62void wmemcpy2 (void) {63  wchar_t src[] = {1, 2, 3, 4};64  wchar_t dst[1];65 66  wmemcpy(dst, src, 4); // expected-warning {{Memory copy function overflows the destination buffer}}67}68 69void wmemcpy3 (void) {70  wchar_t src[] = {1, 2, 3, 4};71  wchar_t dst[3];72 73  wmemcpy(dst+1, src+2, 2); // no-warning74}75 76void wmemcpy4 (void) {77  wchar_t src[] = {1, 2, 3, 4};78  wchar_t dst[10];79 80  wmemcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}81}82 83void wmemcpy5(void) {84  wchar_t src[] = {1, 2, 3, 4};85  wchar_t dst[3];86 87  wmemcpy(dst + 2, src + 2, 2); // expected-warning{{Memory copy function overflows the destination buffer}}88}89 90void wmemcpy6(void) {91  wchar_t a[4] = {0};92  wmemcpy(a, a, 2); // expected-warning{{overlapping}}93}94 95void wmemcpy7(void) {96  wchar_t a[4] = {0};97  wmemcpy(a+2, a+1, 2); // expected-warning{{overlapping}}98}99 100void wmemcpy8(void) {101  wchar_t a[4] = {0};102  wmemcpy(a+1, a+2, 2); // expected-warning{{overlapping}}103}104 105void wmemcpy9(void) {106  wchar_t a[4] = {0};107  wmemcpy(a+2, a+1, 1); // no-warning108  wmemcpy(a+1, a+2, 1); // no-warning109}110 111void wmemcpy10(void) {112  wchar_t a[4] = {0};113  wmemcpy(0, a, 1); // expected-warning{{Null pointer passed as 1st argument to memory copy function}}114}115 116void wmemcpy11(void) {117  wchar_t a[4] = {0};118  wmemcpy(a, 0, 1); // expected-warning{{Null pointer passed as 2nd argument to memory copy function}}119}120 121void wmemcpy12(void) {122  wchar_t a[4] = {0};123  wmemcpy(0, a, 0); // no-warning124}125 126void wmemcpy13(void) {127  wchar_t a[4] = {0};128  wmemcpy(a, 0, 0); // no-warning129}130 131void wmemcpy_unknown_size (size_t n) {132  wchar_t a[4], b[4] = {1};133  clang_analyzer_eval(wmemcpy(a, b, n) == a); // expected-warning{{TRUE}}134}135 136void wmemcpy_unknown_size_warn (size_t n) {137  wchar_t a[4];138  void *result = wmemcpy(a, 0, n); // expected-warning{{Null pointer passed as 2nd argument to memory copy function}}139  clang_analyzer_eval(result == a); // no-warning (above is fatal)140}141 142//===----------------------------------------------------------------------===143// wmempcpy()144//===----------------------------------------------------------------------===145 146wchar_t *wmempcpy(wchar_t *restrict s1, const wchar_t *restrict s2, size_t n);147 148void wmempcpy0 (void) {149  wchar_t src[] = {1, 2, 3, 4};150  wchar_t dst[5] = {0};151 152  wmempcpy(dst, src, 4); // no-warning153 154  clang_analyzer_eval(wmempcpy(dst, src, 4) == &dst[4]); // expected-warning{{TRUE}}155 156  // If we actually model the copy, we can make this known.157  // The important thing for now is that the old value has been invalidated.158  clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}159}160 161void wmempcpy1 (void) {162  wchar_t src[] = {1, 2, 3, 4};163  wchar_t dst[10];164 165  wmempcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}166}167 168void wmempcpy2 (void) {169  wchar_t src[] = {1, 2, 3, 4};170  wchar_t dst[1];171 172  wmempcpy(dst, src, 4); // expected-warning{{Memory copy function overflows the destination buffer}}173}174 175void wmempcpy3 (void) {176  wchar_t src[] = {1, 2, 3, 4};177  wchar_t dst[3];178 179  wmempcpy(dst+1, src+2, 2); // no-warning180}181 182void wmempcpy4 (void) {183  wchar_t src[] = {1, 2, 3, 4};184  wchar_t dst[10];185 186  wmempcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}187}188 189void wmempcpy5(void) {190  wchar_t src[] = {1, 2, 3, 4};191  wchar_t dst[3];192 193  wmempcpy(dst + 2, src + 2, 2); // expected-warning{{Memory copy function overflows the destination buffer}}194}195 196void wmempcpy6(void) {197  wchar_t a[4] = {0};198  wmempcpy(a, a, 2); // expected-warning{{overlapping}}199}200 201void wmempcpy7(void) {202  wchar_t a[4] = {0};203  wmempcpy(a+2, a+1, 2); // expected-warning{{overlapping}}204}205 206void wmempcpy8(void) {207  wchar_t a[4] = {0};208  wmempcpy(a+1, a+2, 2); // expected-warning{{overlapping}}209}210 211void wmempcpy9(void) {212  wchar_t a[4] = {0};213  wmempcpy(a+2, a+1, 1); // no-warning214  wmempcpy(a+1, a+2, 1); // no-warning215}216 217void wmempcpy10(void) {218  wchar_t a[4] = {0};219  wmempcpy(0, a, 1); // expected-warning{{Null pointer passed as 1st argument to memory copy function}}220}221 222void wmempcpy11(void) {223  wchar_t a[4] = {0};224  wmempcpy(a, 0, 1); // expected-warning{{Null pointer passed as 2nd argument to memory copy function}}225}226 227void wmempcpy12(void) {228  wchar_t a[4] = {0};229  wmempcpy(0, a, 0); // no-warning230}231 232void wmempcpy13(void) {233  wchar_t a[4] = {0};234  wmempcpy(a, 0, 0); // no-warning235}236 237void wmempcpy14(void) {238  wchar_t src[] = {1, 2, 3, 4};239  wchar_t dst[5] = {0};240  wchar_t *p;241 242  p = wmempcpy(dst, src, 4);243 244  clang_analyzer_eval(p == &dst[4]); // expected-warning{{TRUE}}245}246 247struct st {248  wchar_t i;249  wchar_t j;250};251 252void wmempcpy15(void) {253  struct st s1 = {0};254  struct st s2;255  struct st *p1;256  struct st *p2;257 258  p1 = (&s2) + 1;259  p2 = (struct st *)wmempcpy((wchar_t *)&s2, (wchar_t *)&s1, 2);260 261  clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}}262}263 264void wmempcpy16(void) {265  struct st s1[10] = {{0}};266  struct st s2[10];267  struct st *p1;268  struct st *p2;269 270  p1 = (&s2[0]) + 5;271  p2 = (struct st *)wmempcpy((wchar_t *)&s2[0], (wchar_t *)&s1[0], 5 * 2);272 273  clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}}274}275 276void wmempcpy_unknown_size_warn (size_t n) {277  wchar_t a[4];278  void *result = wmempcpy(a, 0, n); // expected-warning{{Null pointer passed as 2nd argument to memory copy function}}279  clang_analyzer_eval(result == a); // no-warning (above is fatal)280}281 282void wmempcpy_unknownable_size (wchar_t *src, float n) {283  wchar_t a[4];284  // This used to crash because we don't model floats.285  wmempcpy(a, src, (size_t)n);286}287 288//===----------------------------------------------------------------------===289// wmemmove()290//===----------------------------------------------------------------------===291 292#define wmemmove BUILTIN(wmemmove)293wchar_t *wmemmove(wchar_t *s1, const wchar_t *s2, size_t n);294 295void wmemmove0 (void) {296  wchar_t src[] = {1, 2, 3, 4};297  wchar_t dst[4] = {0};298 299  wmemmove(dst, src, 4); // no-warning300 301  clang_analyzer_eval(wmemmove(dst, src, 4) == dst); // expected-warning{{TRUE}}302 303  clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}304}305 306void wmemmove1 (void) {307  wchar_t src[] = {1, 2, 3, 4};308  wchar_t dst[10];309 310  wmemmove(dst, src, 5); // expected-warning{{out-of-bound}}311}312 313void wmemmove2 (void) {314  wchar_t src[] = {1, 2, 3, 4};315  wchar_t dst[1];316 317  wmemmove(dst, src, 4); // expected-warning{{Memory copy function overflows the destination buffer}}318}319 320//===----------------------------------------------------------------------===321// wmemcmp()322//===----------------------------------------------------------------------===323 324#define wmemcmp BUILTIN(wmemcmp)325int wmemcmp(const wchar_t *s1, const wchar_t *s2, size_t n);326 327void wmemcmp0 (void) {328  wchar_t a[] = {1, 2, 3, 4};329  wchar_t b[4] = { 0 };330 331  wmemcmp(a, b, 4); // no-warning332}333 334void wmemcmp1 (void) {335  wchar_t a[] = {1, 2, 3, 4};336  wchar_t b[10] = { 0 };337 338  wmemcmp(a, b, 5); // expected-warning{{out-of-bound}}339}340 341void wmemcmp2 (void) {342  wchar_t a[] = {1, 2, 3, 4};343  wchar_t b[1] = { 0 };344 345  wmemcmp(a, b, 4); // expected-warning{{out-of-bound}}346}347 348void wmemcmp3 (void) {349  wchar_t a[] = {1, 2, 3, 4};350 351  clang_analyzer_eval(wmemcmp(a, a, 4) == 0); // expected-warning{{TRUE}}352}353 354void wmemcmp4 (wchar_t *input) {355  wchar_t a[] = {1, 2, 3, 4};356 357  clang_analyzer_eval(wmemcmp(a, input, 4) == 0); // expected-warning{{UNKNOWN}}358}359 360void wmemcmp5 (wchar_t *input) {361  wchar_t a[] = {1, 2, 3, 4};362 363  clang_analyzer_eval(wmemcmp(a, 0, 0) == 0); // expected-warning{{TRUE}}364  clang_analyzer_eval(wmemcmp(0, a, 0) == 0); // expected-warning{{TRUE}}365  clang_analyzer_eval(wmemcmp(a, input, 0) == 0); // expected-warning{{TRUE}}366}367 368void wmemcmp6 (wchar_t *a, wchar_t *b, size_t n) {369  int result = wmemcmp(a, b, n);370  if (result != 0)371    clang_analyzer_eval(n != 0); // expected-warning{{TRUE}}372  // else373  //   analyzer_assert_unknown(n == 0);374 375  // We can't do the above comparison because n has already been constrained.376  // On one path n == 0, on the other n != 0.377}378 379int wmemcmp7 (wchar_t *a, size_t x, size_t y, size_t n) {380  // We used to crash when either of the arguments was unknown.381  return wmemcmp(a, &a[x*y], n) +382         wmemcmp(&a[x*y], a, n);383}384 385int wmemcmp8(wchar_t *a, size_t n) {386  wchar_t *b = 0;387  // Do not warn about the first argument!388  return wmemcmp(a, b, n); // expected-warning{{Null pointer passed as 2nd argument to memory comparison function}}389}390 391//===----------------------------------------------------------------------===392// wcslen()393//===----------------------------------------------------------------------===394 395#define wcslen BUILTIN(wcslen)396size_t wcslen(const wchar_t *s);397 398void wcslen_constant0(void) {399  clang_analyzer_eval(wcslen(L"123") == 3); // expected-warning{{TRUE}}400}401 402void wcslen_constant1(void) {403  const wchar_t *a = L"123";404  clang_analyzer_eval(wcslen(a) == 3); // expected-warning{{TRUE}}405}406 407void wcslen_constant2(wchar_t x) {408  wchar_t a[] = L"123";409  clang_analyzer_eval(wcslen(a) == 3); // expected-warning{{TRUE}}410 411  a[0] = x;412  clang_analyzer_eval(wcslen(a) == 3); // expected-warning{{UNKNOWN}}413}414 415size_t wcslen_null(void) {416  return wcslen(0); // expected-warning{{Null pointer passed as 1st argument to string length function}}417}418 419size_t wcslen_fn(void) {420  return wcslen((wchar_t*)&wcslen_fn); // expected-warning{{Argument to string length function is the address of the function 'wcslen_fn', which is not a null-terminated string}}421}422 423size_t wcslen_nonloc(void) {424label:425  return wcslen((wchar_t*)&&label); // expected-warning{{Argument to string length function is the address of the label 'label', which is not a null-terminated string}}426}427 428void wcslen_subregion(void) {429  struct two_strings { wchar_t a[2], b[2]; };430  extern void use_two_strings(struct two_strings *);431 432  struct two_strings z;433  use_two_strings(&z);434 435  size_t a = wcslen(z.a);436  z.b[0] = 5;437  size_t b = wcslen(z.a);438  if (a == 0)439    clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}440 441  use_two_strings(&z);442 443  size_t c = wcslen(z.a);444  if (a == 0)445    clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}446}447 448extern void use_string(wchar_t *);449void wcslen_argument(wchar_t *x) {450  size_t a = wcslen(x);451  size_t b = wcslen(x);452  if (a == 0)453    clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}454 455  use_string(x);456 457  size_t c = wcslen(x);458  if (a == 0)459    clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}460}461 462extern wchar_t global_str[];463void wcslen_global(void) {464  size_t a = wcslen(global_str);465  size_t b = wcslen(global_str);466  if (a == 0) {467    clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}468    // Make sure clang_analyzer_eval does not invalidate globals.469    clang_analyzer_eval(wcslen(global_str) == 0); // expected-warning{{TRUE}}470  }471 472  // Call a function with unknown effects, which should invalidate globals.473  use_string(0);474 475  size_t c = wcslen(global_str);476  if (a == 0)477    clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}478}479 480void wcslen_indirect(wchar_t *x) {481  size_t a = wcslen(x);482  wchar_t *p = x;483  wchar_t **p2 = &p;484  size_t b = wcslen(x);485  if (a == 0)486    clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}487 488  extern void use_string_ptr(wchar_t*const*);489  use_string_ptr(p2);490 491  size_t c = wcslen(x);492  if (a == 0)493    clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}494}495 496void wcslen_indirect2(wchar_t *x) {497  size_t a = wcslen(x);498  wchar_t *p = x;499  wchar_t **p2 = &p;500  extern void use_string_ptr2(wchar_t**);501  use_string_ptr2(p2);502 503  size_t c = wcslen(x);504  if (a == 0)505    clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}506}507 508void wcslen_liveness(const wchar_t *x) {509  if (wcslen(x) < 5)510    return;511  clang_analyzer_eval(wcslen(x) < 5); // expected-warning{{FALSE}}512}513 514 515size_t wcslenWrapper(const wchar_t *str) {516  return wcslen(str);517}518 519extern void invalidate(wchar_t *s);520 521void testwcslenCallee(void) {522  wchar_t str[42];523  invalidate(str);524  size_t lenBefore = wcslenWrapper(str);525  invalidate(str);526  size_t lenAfter = wcslenWrapper(str);527  clang_analyzer_eval(lenBefore == lenAfter); // expected-warning{{UNKNOWN}}528}529 530//===----------------------------------------------------------------------===531// wcsnlen()532//===----------------------------------------------------------------------===533 534size_t wcsnlen(const wchar_t *s, size_t maxlen);535 536void wcsnlen_constant0(void) {537  clang_analyzer_eval(wcsnlen(L"123", 10) == 3); // expected-warning{{TRUE}}538}539 540void wcsnlen_constant1(void) {541  const wchar_t *a = L"123";542  clang_analyzer_eval(wcsnlen(a, 10) == 3); // expected-warning{{TRUE}}543}544 545void wcsnlen_constant2(char x) {546  wchar_t a[] = L"123";547  clang_analyzer_eval(wcsnlen(a, 10) == 3); // expected-warning{{TRUE}}548  a[0] = x;549  clang_analyzer_eval(wcsnlen(a, 10) == 3); // expected-warning{{UNKNOWN}}550}551 552void wcsnlen_constant4(void) {553  clang_analyzer_eval(wcsnlen(L"123456", 3) == 3); // expected-warning{{TRUE}}554}555 556void wcsnlen_constant5(void) {557  const wchar_t *a = L"123456";558  clang_analyzer_eval(wcsnlen(a, 3) == 3); // expected-warning{{TRUE}}559}560 561void wcsnlen_constant6(char x) {562  wchar_t a[] = L"123456";563  clang_analyzer_eval(wcsnlen(a, 3) == 3); // expected-warning{{TRUE}}564  a[0] = x;565  clang_analyzer_eval(wcsnlen(a, 3) == 3); // expected-warning{{UNKNOWN}}566}567 568size_t wcsnlen_null(void) {569  return wcsnlen(0, 3); // expected-warning{{Null pointer passed as 1st argument to string length function}}570}571 572size_t wcsnlen_fn(void) {573  return wcsnlen((wchar_t*)&wcsnlen_fn, 3); // expected-warning{{Argument to string length function is the address of the function 'wcsnlen_fn', which is not a null-terminated string}}574}575 576size_t wcsnlen_nonloc(void) {577label:578  return wcsnlen((wchar_t*)&&label, 3); // expected-warning{{Argument to string length function is the address of the label 'label', which is not a null-terminated string}}579}580 581void wcsnlen_zero(void) {582  clang_analyzer_eval(wcsnlen(L"abc", 0) == 0); // expected-warning{{TRUE}}583  clang_analyzer_eval(wcsnlen(0, 0) == 0); // expected-warning{{TRUE}}584}585 586size_t wcsnlen_compound_literal(void) {587  // This used to crash because we don't model the string lengths of588  // compound literals.589  return wcsnlen((wchar_t[]) { 'a', 'b', 0 }, 1);590}591 592size_t wcsnlen_unknown_limit(float f) {593  // This used to crash because we don't model the integer values of floats.594  return wcsnlen(L"abc", (int)f);595}596 597void wcsnlen_is_not_wcslen(wchar_t *x) {598  clang_analyzer_eval(wcsnlen(x, 10) == wcslen(x)); // expected-warning{{UNKNOWN}}599}600 601void wcsnlen_at_limit(wchar_t *x) {602  size_t len = wcsnlen(x, 10);603  clang_analyzer_eval(len <= 10); // expected-warning{{TRUE}}604  clang_analyzer_eval(len == 10); // expected-warning{{UNKNOWN}}605  clang_analyzer_eval(len < 10); // expected-warning{{UNKNOWN}}606}607 608void wcsnlen_at_actual(size_t limit) {609  size_t len = wcsnlen(L"abc", limit);610  clang_analyzer_eval(len <= 3); // expected-warning{{TRUE}}611  // This is due to eager assertion in wcsnlen.612  if (limit == 0) {613    clang_analyzer_eval(len == 0); // expected-warning{{TRUE}}614  } else {615    clang_analyzer_eval(len == 3); // expected-warning{{UNKNOWN}}616    clang_analyzer_eval(len < 3); // expected-warning{{UNKNOWN}}617  }618}619 620//===----------------------------------------------------------------------===621// other tests622//===----------------------------------------------------------------------===623 624static const wchar_t w_str[] = L"Hello world";625 626void wmemcpy_sizeof(void) {627  wchar_t a[32];628  wmemcpy(a, w_str, sizeof(w_str) / sizeof(w_str[0]));629  wmemcpy(a, w_str, (sizeof(w_str) / sizeof(w_str[0])) + 1); // expected-warning {{Memory copy function accesses out-of-bound array element}}630}631 632void wmemcpy_wcslen(void) {633  wchar_t a[32];634  // FIXME: This should work with 'w_str' instead of 'w_str1'635  const wchar_t w_str1[] = L"Hello world";636  wmemcpy(a, w_str1, wcslen(w_str1) + 1);637  wmemcpy(a, w_str1, wcslen(w_str1) + 2); // expected-warning {{Memory copy function accesses out-of-bound array element}}638}639