diff options
author | dim <dim@FreeBSD.org> | 2011-02-26 22:09:03 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-02-26 22:09:03 +0000 |
commit | a0fb00f9837bd0d2e5948f16f6a6b82a7a628f51 (patch) | |
tree | abae0246ec9156cc1a7cbb947b2b0dfe95fa3189 /test/Analysis/string.c | |
parent | 39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df (diff) | |
download | FreeBSD-src-a0fb00f9837bd0d2e5948f16f6a6b82a7a628f51.zip FreeBSD-src-a0fb00f9837bd0d2e5948f16f6a6b82a7a628f51.tar.gz |
Vendor import of clang trunk r126547:
http://llvm.org/svn/llvm-project/cfe/trunk@126547
Diffstat (limited to 'test/Analysis/string.c')
-rw-r--r-- | test/Analysis/string.c | 208 |
1 files changed, 204 insertions, 4 deletions
diff --git a/test/Analysis/string.c b/test/Analysis/string.c index baf4893..7561151 100644 --- a/test/Analysis/string.c +++ b/test/Analysis/string.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core.experimental.CString -analyzer-checker=core.experimental.UnreachableCode -analyzer-check-objc-mem -analyzer-store=region -verify %s -// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core.experimental.CString -analyzer-checker=core.experimental.UnreachableCode -analyzer-check-objc-mem -analyzer-store=region -verify %s -// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core.experimental.CString -analyzer-checker=core.experimental.UnreachableCode -analyzer-check-objc-mem -analyzer-store=region -verify %s -// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core.experimental.CString -analyzer-checker=core.experimental.UnreachableCode -analyzer-check-objc-mem -analyzer-store=region -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core.experimental.CString,core.experimental.UnreachableCode -analyzer-check-objc-mem -analyzer-store=region -verify %s +// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core.experimental.CString,core.experimental.UnreachableCode -analyzer-check-objc-mem -analyzer-store=region -verify %s +// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core.experimental.CString,core.experimental.UnreachableCode -analyzer-check-objc-mem -analyzer-store=region -verify %s +// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core.experimental.CString,core.experimental.UnreachableCode -analyzer-check-objc-mem -analyzer-store=region -verify %s //===----------------------------------------------------------------------=== // Declarations @@ -140,6 +140,138 @@ void strlen_liveness(const char *x) { } //===----------------------------------------------------------------------=== +// strnlen() +//===----------------------------------------------------------------------=== + +#define strnlen BUILTIN(strnlen) +size_t strnlen(const char *s, size_t maxlen); + +void strnlen_constant0() { + if (strnlen("123", 10) != 3) + (void)*(char*)0; // no-warning +} + +void strnlen_constant1() { + const char *a = "123"; + if (strnlen(a, 10) != 3) + (void)*(char*)0; // no-warning +} + +void strnlen_constant2(char x) { + char a[] = "123"; + if (strnlen(a, 10) != 3) + (void)*(char*)0; // no-warning + a[0] = x; + if (strnlen(a, 10) != 3) + (void)*(char*)0; // expected-warning{{null}} +} + +void strnlen_constant4() { + if (strnlen("123456", 3) != 3) + (void)*(char*)0; // no-warning +} + +void strnlen_constant5() { + const char *a = "123456"; + if (strnlen(a, 3) != 3) + (void)*(char*)0; // no-warning +} + +void strnlen_constant6(char x) { + char a[] = "123456"; + if (strnlen(a, 3) != 3) + (void)*(char*)0; // no-warning + a[0] = x; + if (strnlen(a, 3) != 3) + (void)*(char*)0; // expected-warning{{null}} +} + +size_t strnlen_null() { + return strnlen(0, 3); // expected-warning{{Null pointer argument in call to byte string function}} +} + +size_t strnlen_fn() { + return strnlen((char*)&strlen_fn, 3); // expected-warning{{Argument to byte string function is the address of the function 'strlen_fn', which is not a null-terminated string}} +} + +size_t strnlen_nonloc() { +label: + return strnlen((char*)&&label, 3); // expected-warning{{Argument to byte string function is the address of the label 'label', which is not a null-terminated string}} +} + +void strnlen_subregion() { + struct two_stringsn { char a[2], b[2] }; + extern void use_two_stringsn(struct two_stringsn *); + + struct two_stringsn z; + use_two_stringsn(&z); + + size_t a = strnlen(z.a, 10); + z.b[0] = 5; + size_t b = strnlen(z.a, 10); + if (a == 0 && b != 0) + (void)*(char*)0; // expected-warning{{never executed}} + + use_two_stringsn(&z); + + size_t c = strnlen(z.a, 10); + if (a == 0 && c != 0) + (void)*(char*)0; // expected-warning{{null}} +} + +extern void use_stringn(char *); +void strnlen_argument(char *x) { + size_t a = strnlen(x, 10); + size_t b = strnlen(x, 10); + if (a == 0 && b != 0) + (void)*(char*)0; // expected-warning{{never executed}} + + use_stringn(x); + + size_t c = strnlen(x, 10); + if (a == 0 && c != 0) + (void)*(char*)0; // expected-warning{{null}} +} + +extern char global_strn[]; +void strnlen_global() { + size_t a = strnlen(global_strn, 10); + size_t b = strnlen(global_strn, 10); + if (a == 0 && b != 0) + (void)*(char*)0; // expected-warning{{never executed}} + + // Call a function with unknown effects, which should invalidate globals. + use_stringn(0); + + size_t c = strnlen(global_str, 10); + if (a == 0 && c != 0) + (void)*(char*)0; // expected-warning{{null}} +} + +void strnlen_indirect(char *x) { + size_t a = strnlen(x, 10); + char *p = x; + char **p2 = &p; + size_t b = strnlen(x, 10); + if (a == 0 && b != 0) + (void)*(char*)0; // expected-warning{{never executed}} + + extern void use_stringn_ptr(char*const*); + use_stringn_ptr(p2); + + size_t c = strnlen(x, 10); + if (a == 0 && c != 0) + (void)*(char*)0; // expected-warning{{null}} +} + +void strnlen_liveness(const char *x) { + if (strnlen(x, 10) < 5) + return; + if (strnlen(x, 10) < 5) + (void)*(char*)0; // no-warning +} + +//===----------------------------------------------------------------------=== // strcpy() //===----------------------------------------------------------------------=== @@ -196,6 +328,74 @@ void strcpy_no_overflow(char *y) { } //===----------------------------------------------------------------------=== +// strncpy() +//===----------------------------------------------------------------------=== + +#ifdef VARIANT + +#define __strncpy_chk BUILTIN(__strncpy_chk) +char *__strncpy_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen); + +#define strncpy(a,b,c) __strncpy_chk(a,b,c, (size_t)-1) + +#else /* VARIANT */ + +#define strncpy BUILTIN(strncpy) +char *strncpy(char *restrict s1, const char *restrict s2, size_t n); + +#endif /* VARIANT */ + + +void strncpy_null_dst(char *x) { + strncpy(NULL, x, 1); // expected-warning{{Null pointer argument in call to byte string function}} +} + +void strncpy_null_src(char *x) { + strncpy(x, NULL, 1); // expected-warning{{Null pointer argument in call to byte string function}} +} + +void strncpy_fn(char *x) { + strncpy(x, (char*)&strncpy_fn, 1); // expected-warning{{Argument to byte string function is the address of the function 'strncpy_fn', which is not a null-terminated string}} +} + +void strncpy_effects(char *x, char *y) { + char a = x[0]; + + if (strncpy(x, y, strlen(y)) != x) + (void)*(char*)0; // no-warning + + if (strlen(x) != strlen(y)) + (void)*(char*)0; // no-warning + + if (a != x[0]) + (void)*(char*)0; // expected-warning{{null}} +} + +void strncpy_overflow(char *y) { + char x[4]; + if (strlen(y) == 4) + strncpy(x, y, strlen(y)); // expected-warning{{Byte string function overflows destination buffer}} +} + +void strncpy_len_overflow(char *y) { + char x[4]; + if (strlen(y) == 3) + strncpy(x, y, sizeof(x)); // no-warning +} + +void strncpy_no_overflow(char *y) { + char x[4]; + if (strlen(y) == 3) + strncpy(x, y, strlen(y)); // no-warning +} + +void strncpy_no_len_overflow(char *y) { + char x[4]; + if (strlen(y) == 4) + strncpy(x, y, sizeof(x)-1); // no-warning +} + +//===----------------------------------------------------------------------=== // stpcpy() //===----------------------------------------------------------------------=== |