[analyzer] Finish size argument checking for strncat (and strncpy).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133472 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Analysis/string.c b/test/Analysis/string.c
index c755d5e..250989f 100644
--- a/test/Analysis/string.c
+++ b/test/Analysis/string.c
@@ -604,25 +604,25 @@
void strncat_overflow_0(char *y) {
char x[4] = "12";
if (strlen(y) == 4)
- strncat(x, y, strlen(y)); // expected-warning{{String copy 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{{String copy 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{{String copy 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{{String copy 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";
@@ -636,6 +636,63 @@
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()
//===----------------------------------------------------------------------===