diff options
Diffstat (limited to 'test/Analysis/string.c')
-rw-r--r-- | test/Analysis/string.c | 402 |
1 files changed, 295 insertions, 107 deletions
diff --git a/test/Analysis/string.c b/test/Analysis/string.c index e6baf51..dc97e1a 100644 --- a/test/Analysis/string.c +++ b/test/Analysis/string.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.experimental.CString,deadcode.experimental.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s -// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,cplusplus.experimental.CString,deadcode.experimental.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s -// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,cplusplus.experimental.CString,deadcode.experimental.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s -// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,cplusplus.experimental.CString,deadcode.experimental.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.experimental.CString,deadcode.experimental.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s +// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.experimental.CString,deadcode.experimental.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s +// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.experimental.CString,deadcode.experimental.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s +// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.experimental.CString,deadcode.experimental.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s //===----------------------------------------------------------------------=== // Declarations @@ -55,16 +55,16 @@ void strlen_constant2(char x) { } size_t strlen_null() { - return strlen(0); // expected-warning{{Null pointer argument in call to byte string function}} + return strlen(0); // expected-warning{{Null pointer argument in call to string length function}} } size_t strlen_fn() { - return strlen((char*)&strlen_fn); // expected-warning{{Argument to byte string function is the address of the function 'strlen_fn', which is not a null-terminated string}} + return strlen((char*)&strlen_fn); // expected-warning{{Argument to string length function is the address of the function 'strlen_fn', which is not a null-terminated string}} } size_t strlen_nonloc() { label: - return strlen((char*)&&label); // expected-warning{{Argument to byte string function is the address of the label 'label', which is not a null-terminated string}} + return strlen((char*)&&label); // expected-warning{{Argument to string length function is the address of the label 'label', which is not a null-terminated string}} } void strlen_subregion() { @@ -143,24 +143,23 @@ 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)*(char*)0; // expected-warning{{never executed}} } void strnlen_constant1() { const char *a = "123"; if (strnlen(a, 10) != 3) - (void)*(char*)0; // no-warning + (void)*(char*)0; // expected-warning{{never executed}} } void strnlen_constant2(char x) { char a[] = "123"; if (strnlen(a, 10) != 3) - (void)*(char*)0; // no-warning + (void)*(char*)0; // expected-warning{{never executed}} a[0] = x; if (strnlen(a, 10) != 3) (void)*(char*)0; // expected-warning{{null}} @@ -168,107 +167,90 @@ void strnlen_constant2(char x) { void strnlen_constant4() { if (strnlen("123456", 3) != 3) - (void)*(char*)0; // no-warning + (void)*(char*)0; // expected-warning{{never executed}} } void strnlen_constant5() { const char *a = "123456"; if (strnlen(a, 3) != 3) - (void)*(char*)0; // no-warning + (void)*(char*)0; // expected-warning{{never executed}} } void strnlen_constant6(char x) { char a[] = "123456"; if (strnlen(a, 3) != 3) - (void)*(char*)0; // no-warning + (void)*(char*)0; // expected-warning{{never executed}} 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}} + return strnlen(0, 3); // expected-warning{{Null pointer argument in call to string length 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}} + return strnlen((char*)&strlen_fn, 3); // expected-warning{{Argument to string length 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}} + return strnlen((char*)&&label, 3); // expected-warning{{Argument to string length 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 strnlen_zero() { + if (strnlen("abc", 0) != 0) (void)*(char*)0; // expected-warning{{never executed}} + if (strnlen(NULL, 0) != 0) // no-warning + (void)*(char*)0; // no-warning +} + +size_t strnlen_compound_literal() { + // This used to crash because we don't model the string lengths of + // compound literals. + return strnlen((char[]) { 'a', 'b', 0 }, 1); +} - use_two_stringsn(&z); +size_t strnlen_unknown_limit(float f) { + // This used to crash because we don't model the integer values of floats. + return strnlen("abc", (int)f); +} - size_t c = strnlen(z.a, 10); - if (a == 0 && c != 0) +void strnlen_is_not_strlen(char *x) { + if (strnlen(x, 10) != strlen(x)) (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 strnlen_at_limit(char *x) { + size_t len = strnlen(x, 10); + if (len > 10) (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}} + if (len == 10) + (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 strnlen_less_than_limit(char *x) { + size_t len = strnlen(x, 10); + if (len > 10) (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}} + if (len < 10) + (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 strnlen_at_actual(size_t limit) { + size_t len = strnlen("abc", limit); + if (len > 3) (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) + if (len == 3) (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 +void strnlen_less_than_actual(size_t limit) { + size_t len = strnlen("abc", limit); + if (len > 3) + (void)*(char*)0; // expected-warning{{never executed}} + if (len < 3) + (void)*(char*)0; // expected-warning{{null}} } //===----------------------------------------------------------------------=== @@ -291,15 +273,15 @@ char *strcpy(char *restrict s1, const char *restrict s2); void strcpy_null_dst(char *x) { - strcpy(NULL, x); // expected-warning{{Null pointer argument in call to byte string function}} + strcpy(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}} } void strcpy_null_src(char *x) { - strcpy(x, NULL); // expected-warning{{Null pointer argument in call to byte string function}} + strcpy(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}} } void strcpy_fn(char *x) { - strcpy(x, (char*)&strcpy_fn); // expected-warning{{Argument to byte string function is the address of the function 'strcpy_fn', which is not a null-terminated string}} + strcpy(x, (char*)&strcpy_fn); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}} } void strcpy_effects(char *x, char *y) { @@ -318,7 +300,7 @@ void strcpy_effects(char *x, char *y) { void strcpy_overflow(char *y) { char x[4]; if (strlen(y) == 4) - strcpy(x, y); // expected-warning{{Byte string function overflows destination buffer}} + strcpy(x, y); // expected-warning{{String copy function overflows destination buffer}} } void strcpy_no_overflow(char *y) { @@ -362,7 +344,7 @@ void stpcpy_effect(char *x, char *y) { void stpcpy_overflow(char *y) { char x[4]; if (strlen(y) == 4) - stpcpy(x, y); // expected-warning{{Byte string function overflows destination buffer}} + stpcpy(x, y); // expected-warning{{String copy function overflows destination buffer}} } void stpcpy_no_overflow(char *y) { @@ -391,15 +373,15 @@ char *strcat(char *restrict s1, const char *restrict s2); void strcat_null_dst(char *x) { - strcat(NULL, x); // expected-warning{{Null pointer argument in call to byte string function}} + strcat(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}} } void strcat_null_src(char *x) { - strcat(x, NULL); // expected-warning{{Null pointer argument in call to byte string function}} + strcat(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}} } void strcat_fn(char *x) { - strcat(x, (char*)&strcat_fn); // expected-warning{{Argument to byte string function is the address of the function 'strcat_fn', which is not a null-terminated string}} + strcat(x, (char*)&strcat_fn); // expected-warning{{Argument to string copy function is the address of the function 'strcat_fn', which is not a null-terminated string}} } void strcat_effects(char *y) { @@ -415,27 +397,24 @@ void strcat_effects(char *y) { if ((int)strlen(x) != (orig_len + strlen(y))) (void)*(char*)0; // no-warning - - if (a != x[0]) - (void)*(char*)0; // expected-warning{{null}} } void strcat_overflow_0(char *y) { char x[4] = "12"; if (strlen(y) == 4) - strcat(x, y); // expected-warning{{Byte string function overflows destination buffer}} + strcat(x, y); // expected-warning{{String copy function overflows destination buffer}} } void strcat_overflow_1(char *y) { char x[4] = "12"; if (strlen(y) == 3) - strcat(x, y); // expected-warning{{Byte string function overflows destination buffer}} + strcat(x, y); // expected-warning{{String copy function overflows destination buffer}} } void strcat_overflow_2(char *y) { char x[4] = "12"; if (strlen(y) == 2) - strcat(x, y); // expected-warning{{Byte string function overflows destination buffer}} + strcat(x, y); // expected-warning{{String copy function overflows destination buffer}} } void strcat_no_overflow(char *y) { @@ -444,6 +423,136 @@ void strcat_no_overflow(char *y) { strcat(x, y); // no-warning } +void strcat_symbolic_dst_length(char *dst) { + strcat(dst, "1234"); + if (strlen(dst) < 4) + (void)*(char*)0; // no-warning +} + +void strcat_symbolic_src_length(char *src) { + char dst[8] = "1234"; + strcat(dst, src); + if (strlen(dst) < 4) + (void)*(char*)0; // no-warning +} + +void strcat_unknown_src_length(char *src, int offset) { + char dst[8] = "1234"; + strcat(dst, &src[offset]); + if (strlen(dst) < 4) + (void)*(char*)0; // no-warning +} + +// There is no strcat_unknown_dst_length because if we can't get a symbolic +// length for the "before" strlen, we won't be able to set one for "after". + +void strcat_too_big(char *dst, char *src) { + if (strlen(dst) != (((size_t)0) - 2)) + return; + if (strlen(src) != 2) + return; + strcat(dst, src); // expected-warning{{This expression will create a string whose length is too big to be represented as a size_t}} +} + + +//===----------------------------------------------------------------------=== +// 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,n) __strncpy_chk(a,b,n,(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, 5); // expected-warning{{Null pointer argument in call to string copy function}} +} + +void strncpy_null_src(char *x) { + strncpy(x, NULL, 5); // expected-warning{{Null pointer argument in call to string copy function}} +} + +void strncpy_fn(char *x) { + strncpy(x, (char*)&strcpy_fn, 5); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}} +} + +void strncpy_effects(char *x, char *y) { + char a = x[0]; + + if (strncpy(x, y, 5) != x) + (void)*(char*)0; // no-warning + + if (strlen(x) != strlen(y)) + (void)*(char*)0; // expected-warning{{null}} + + 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, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}} +} + +void strncpy_no_overflow(char *y) { + char x[4]; + if (strlen(y) == 3) + strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}} +} + +void strncpy_no_overflow2(char *y, int n) { + if (n <= 4) + return; + + char x[4]; + if (strlen(y) == 3) + strncpy(x, y, n); // expected-warning{{Size argument is greater than the length of the destination buffer}} +} + +void strncpy_truncate(char *y) { + char x[4]; + if (strlen(y) == 4) + strncpy(x, y, 3); // no-warning +} + +void strncpy_no_truncate(char *y) { + char x[4]; + if (strlen(y) == 3) + strncpy(x, y, 3); // no-warning +} + +void strncpy_exactly_matching_buffer(char *y) { + char x[4]; + strncpy(x, y, 4); // no-warning + + // strncpy does not null-terminate, so we have no idea what the strlen is + // after this. + if (strlen(x) > 4) + (void)*(int*)0; // expected-warning{{null}} +} + +void strncpy_exactly_matching_buffer2(char *y) { + if (strlen(y) >= 4) + return; + + char x[4]; + strncpy(x, y, 4); // no-warning + + // This time, we know that y fits in x anyway. + if (strlen(x) > 3) + (void)*(int*)0; // no-warning +} //===----------------------------------------------------------------------=== // strncat() @@ -465,15 +574,15 @@ char *strncat(char *restrict s1, const char *restrict s2, size_t n); void strncat_null_dst(char *x) { - strncat(NULL, x, 4); // expected-warning{{Null pointer argument in call to byte string function}} + strncat(NULL, x, 4); // expected-warning{{Null pointer argument in call to string copy function}} } void strncat_null_src(char *x) { - strncat(x, NULL, 4); // expected-warning{{Null pointer argument in call to byte string function}} + strncat(x, NULL, 4); // expected-warning{{Null pointer argument in call to string copy function}} } void strncat_fn(char *x) { - strncat(x, (char*)&strncat_fn, 4); // expected-warning{{Argument to byte string function is the address of the function 'strncat_fn', which is not a null-terminated string}} + strncat(x, (char*)&strncat_fn, 4); // expected-warning{{Argument to string copy function is the address of the function 'strncat_fn', which is not a null-terminated string}} } void strncat_effects(char *y) { @@ -489,33 +598,30 @@ void strncat_effects(char *y) { if (strlen(x) != orig_len + strlen(y)) (void)*(char*)0; // no-warning - - if (a != x[0]) - (void)*(char*)0; // expected-warning{{null}} } void strncat_overflow_0(char *y) { char x[4] = "12"; if (strlen(y) == 4) - strncat(x, y, strlen(y)); // expected-warning{{Byte string function overflows destination buffer}} + strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}} } void strncat_overflow_1(char *y) { char x[4] = "12"; if (strlen(y) == 3) - strncat(x, y, strlen(y)); // expected-warning{{Byte string function overflows destination buffer}} + strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}} } void strncat_overflow_2(char *y) { char x[4] = "12"; if (strlen(y) == 2) - strncat(x, y, strlen(y)); // expected-warning{{Byte string function overflows destination buffer}} + strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}} } void strncat_overflow_3(char *y) { char x[4] = "12"; if (strlen(y) == 4) - strncat(x, y, 2); // expected-warning{{Byte string function overflows destination buffer}} + strncat(x, y, 2); // expected-warning{{Size argument is greater than the free space in the destination buffer}} } void strncat_no_overflow_1(char *y) { char x[5] = "12"; @@ -529,12 +635,69 @@ void strncat_no_overflow_2(char *y) { strncat(x, y, 1); // no-warning } +void strncat_symbolic_dst_length(char *dst) { + strncat(dst, "1234", 5); + if (strlen(dst) < 4) + (void)*(char*)0; // no-warning +} + +void strncat_symbolic_src_length(char *src) { + char dst[8] = "1234"; + strncat(dst, src, 3); + if (strlen(dst) < 4) + (void)*(char*)0; // no-warning + + char dst2[8] = "1234"; + strncat(dst2, src, 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}} +} + +void strncat_unknown_src_length(char *src, int offset) { + char dst[8] = "1234"; + strncat(dst, &src[offset], 3); + if (strlen(dst) < 4) + (void)*(char*)0; // no-warning + + char dst2[8] = "1234"; + strncat(dst2, &src[offset], 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}} +} + +// There is no strncat_unknown_dst_length because if we can't get a symbolic +// length for the "before" strlen, we won't be able to set one for "after". + +void strncat_symbolic_limit(unsigned limit) { + char dst[6] = "1234"; + char src[] = "567"; + strncat(dst, src, limit); // no-warning + if (strlen(dst) < 4) + (void)*(char*)0; // no-warning + if (strlen(dst) == 4) + (void)*(char*)0; // expected-warning{{null}} +} + +void strncat_unknown_limit(float limit) { + char dst[6] = "1234"; + char src[] = "567"; + strncat(dst, src, (size_t)limit); // no-warning + if (strlen(dst) < 4) + (void)*(char*)0; // no-warning + if (strlen(dst) == 4) + (void)*(char*)0; // expected-warning{{null}} +} + +void strncat_too_big(char *dst, char *src) { + if (strlen(dst) != (((size_t)0) - 2)) + return; + if (strlen(src) != 2) + return; + strncat(dst, src, 2); // expected-warning{{This expression will create a string whose length is too big to be represented as a size_t}} +} + //===----------------------------------------------------------------------=== // strcmp() //===----------------------------------------------------------------------=== #define strcmp BUILTIN(strcmp) -int strcmp(const char *restrict s1, const char *restrict s2); +int strcmp(const char * s1, const char * s2); void strcmp_constant0() { if (strcmp("123", "123") != 0) @@ -577,13 +740,13 @@ void strcmp_2() { void strcmp_null_0() { char *x = NULL; char *y = "123"; - strcmp(x, y); // expected-warning{{Null pointer argument in call to byte string function}} + strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} } void strcmp_null_1() { char *x = "123"; char *y = NULL; - strcmp(x, y); // expected-warning{{Null pointer argument in call to byte string function}} + strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} } void strcmp_diff_length_0() { @@ -614,12 +777,22 @@ void strcmp_diff_length_3() { (void)*(char*)0; // no-warning } +void strcmp_embedded_null () { + if (strcmp("\0z", "\0y") != 0) + (void)*(char*)0; // no-warning +} + +void strcmp_unknown_arg (char *unknown) { + if (strcmp(unknown, unknown) != 0) + (void)*(char*)0; // no-warning +} + //===----------------------------------------------------------------------=== // strncmp() //===----------------------------------------------------------------------=== #define strncmp BUILTIN(strncmp) -int strncmp(const char *restrict s1, const char *restrict s2, size_t n); +int strncmp(const char *s1, const char *s2, size_t n); void strncmp_constant0() { if (strncmp("123", "123", 3) != 0) @@ -662,13 +835,13 @@ void strncmp_2() { void strncmp_null_0() { char *x = NULL; char *y = "123"; - strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to byte string function}} + strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} } void strncmp_null_1() { char *x = "123"; char *y = NULL; - strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to byte string function}} + strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} } void strncmp_diff_length_0() { @@ -720,12 +893,17 @@ void strncmp_diff_length_6() { (void)*(char*)0; // no-warning } +void strncmp_embedded_null () { + if (strncmp("ab\0zz", "ab\0yy", 4) != 0) + (void)*(char*)0; // no-warning +} + //===----------------------------------------------------------------------=== // strcasecmp() //===----------------------------------------------------------------------=== #define strcasecmp BUILTIN(strcasecmp) -int strcasecmp(const char *restrict s1, const char *restrict s2); +int strcasecmp(const char *s1, const char *s2); void strcasecmp_constant0() { if (strcasecmp("abc", "Abc") != 0) @@ -768,13 +946,13 @@ void strcasecmp_2() { void strcasecmp_null_0() { char *x = NULL; char *y = "123"; - strcasecmp(x, y); // expected-warning{{Null pointer argument in call to byte string function}} + strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} } void strcasecmp_null_1() { char *x = "123"; char *y = NULL; - strcasecmp(x, y); // expected-warning{{Null pointer argument in call to byte string function}} + strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} } void strcasecmp_diff_length_0() { @@ -805,12 +983,17 @@ void strcasecmp_diff_length_3() { (void)*(char*)0; // no-warning } +void strcasecmp_embedded_null () { + if (strcasecmp("ab\0zz", "ab\0yy") != 0) + (void)*(char*)0; // no-warning +} + //===----------------------------------------------------------------------=== // strncasecmp() //===----------------------------------------------------------------------=== #define strncasecmp BUILTIN(strncasecmp) -int strncasecmp(const char *restrict s1, const char *restrict s2, size_t n); +int strncasecmp(const char *s1, const char *s2, size_t n); void strncasecmp_constant0() { if (strncasecmp("abc", "Abc", 3) != 0) @@ -853,13 +1036,13 @@ void strncasecmp_2() { void strncasecmp_null_0() { char *x = NULL; char *y = "123"; - strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to byte string function}} + strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} } void strncasecmp_null_1() { char *x = "123"; char *y = NULL; - strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to byte string function}} + strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} } void strncasecmp_diff_length_0() { @@ -910,3 +1093,8 @@ void strncasecmp_diff_length_6() { if (strncasecmp(x, y, 3) != 1) (void)*(char*)0; // no-warning } + +void strncasecmp_embedded_null () { + if (strncasecmp("ab\0zz", "ab\0yy", 4) != 0) + (void)*(char*)0; // no-warning +} |