brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.4 KiB · b617812 Raw
114 lines · c
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,debug.ExprInspection -verify %s2// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,debug.ExprInspection -verify %s3// XFAIL: *4 5// This file is for tests that may eventually go into string.c, or may be6// deleted outright. At one point these tests passed, but only because we7// weren't correctly modelling the behavior of the relevant string functions.8// The tests aren't incorrect, but require the analyzer to be smarter about9// conjured values than it currently is.10 11//===----------------------------------------------------------------------===12// Declarations13//===----------------------------------------------------------------------===14 15// Some functions are so similar to each other that they follow the same code16// path, such as memcpy and __memcpy_chk, or memcmp and bcmp. If VARIANT is17// defined, make sure to use the variants instead to make sure they are still18// checked by the analyzer.19 20// Some functions are implemented as builtins. These should be #defined as21// BUILTIN(f), which will prepend "__builtin_" if USE_BUILTINS is defined.22 23// Functions that have variants and are also available as builtins should be24// declared carefully! See memcpy() for an example.25 26#ifdef USE_BUILTINS27# define BUILTIN(f) __builtin_ ## f28#else /* USE_BUILTINS */29# define BUILTIN(f) f30#endif /* USE_BUILTINS */31 32#define NULL 033typedef typeof(sizeof(int)) size_t;34 35void clang_analyzer_eval(int);36 37//===----------------------------------------------------------------------===38// strnlen()39//===----------------------------------------------------------------------===40 41#define strnlen BUILTIN(strnlen)42size_t strnlen(const char *s, size_t maxlen);43 44void strnlen_liveness(const char *x) {45  if (strnlen(x, 10) < 5)46    return;47  clang_analyzer_eval(strnlen(x, 10) < 5); // expected-warning{{FALSE}}48}49 50void strnlen_subregion() {51  struct two_stringsn { char a[2], b[2]; };52  extern void use_two_stringsn(struct two_stringsn *);53 54  struct two_stringsn z;55  use_two_stringsn(&z);56 57  size_t a = strnlen(z.a, 10);58  z.b[0] = 5;59  size_t b = strnlen(z.a, 10);60  if (a == 0)61    clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}62 63  use_two_stringsn(&z);64 65  size_t c = strnlen(z.a, 10);66  if (a == 0)67    clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}68}69 70extern void use_stringn(char *);71void strnlen_argument(char *x) {72  size_t a = strnlen(x, 10);73  size_t b = strnlen(x, 10);74  if (a == 0)75    clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}76 77  use_stringn(x);78 79  size_t c = strnlen(x, 10);80  if (a == 0)81    clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}82}83 84extern char global_strn[];85void strnlen_global() {86  size_t a = strnlen(global_strn, 10);87  size_t b = strnlen(global_strn, 10);88  if (a == 0)89    clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}90 91  // Call a function with unknown effects, which should invalidate globals.92  use_stringn(0);93 94  size_t c = strnlen(global_strn, 10);95  if (a == 0)96    clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}97}98 99void strnlen_indirect(char *x) {100  size_t a = strnlen(x, 10);101  char *p = x;102  char **p2 = &p;103  size_t b = strnlen(x, 10);104  if (a == 0)105    clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}106 107  extern void use_stringn_ptr(char*const*);108  use_stringn_ptr(p2);109 110  size_t c = strnlen(x, 10);111  if (a == 0)112    clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}113}114