summaryrefslogtreecommitdiffstats
path: root/test/Analysis/string.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/string.c')
-rw-r--r--test/Analysis/string.c402
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
+}
OpenPOWER on IntegriCloud