aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2017-05-04 23:50:21 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2017-05-04 17:50:21 -0600
commitd9c5a8b98a21ab0091bbe0f3dab93dd59e6c58fb (patch)
tree84e9df2d0bf355d3dd1816f7a7833c5fc6204ff1 /gcc/testsuite
parent0f3587ec0e7af6140ceb75947144baf42676617b (diff)
downloadgcc-d9c5a8b98a21ab0091bbe0f3dab93dd59e6c58fb.zip
gcc-d9c5a8b98a21ab0091bbe0f3dab93dd59e6c58fb.tar.gz
gcc-d9c5a8b98a21ab0091bbe0f3dab93dd59e6c58fb.tar.bz2
PR libstdc++/54924 - Warn for std::string constructor with wrong size
PR libstdc++/54924 - Warn for std::string constructor with wrong size PR middle-end/79234 - warn on past the end reads by library functions gcc/ChangeLog: PR middle-end/79234 * builtins.c (check_sizes): Adjust to handle reading past the end. Avoid printing excessive upper bound of ranges. Use %E to print tree nodes instead of converting them to %wu. (expand_builtin_memchr): New function. (compute_dest_size): Rename... (compute_objsize): ...to this. (expand_builtin_memcpy): Adjust. (expand_builtin_mempcpy): Adjust. (expand_builtin_strcat): Adjust. (expand_builtin_strcpy): Adjust. (check_strncat_sizes): Adjust. (expand_builtin_strncat): Adjust. (expand_builtin_strncpy): Adjust and simplify. (expand_builtin_memset): Adjust. (expand_builtin_bzero): Adjust. (expand_builtin_memcmp): Adjust. (expand_builtin): Handle memcmp. (maybe_emit_chk_warning): Check strncat just once. gcc/testsuite/ChangeLog: PR middle-end/79234 * gcc.dg/builtin-stringop-chk-8.c: New test. * gcc.dg/builtin-stringop-chk-1.c: Adjust. * gcc.dg/builtin-stringop-chk-4.c: Same. * gcc.dg/builtin-strncat-chk-1.c: Same. * g++.dg/ext/strncpy-chk1.C: Same. * g++.dg/torture/Wsizeof-pointer-memaccess1.C: Same. * gcc.dg/out-of-bounds-1.c: Same. * gcc.dg/pr78138.c: Same. * gcc.dg/torture/Wsizeof-pointer-memaccess1.c: Same. * gfortran.dg/mvbits_7.f90: Same. From-SVN: r247622
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/ChangeLog14
-rw-r--r--gcc/testsuite/g++.dg/ext/strncpy-chk1.C2
-rw-r--r--gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C2
-rw-r--r--gcc/testsuite/gcc.dg/builtin-stringop-chk-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/builtin-stringop-chk-4.c85
-rw-r--r--gcc/testsuite/gcc.dg/builtin-stringop-chk-8.c173
-rw-r--r--gcc/testsuite/gcc.dg/builtin-strncat-chk-1.c6
-rw-r--r--gcc/testsuite/gcc.dg/out-of-bounds-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr78138.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c4
-rw-r--r--gcc/testsuite/gfortran.dg/mvbits_7.f902
12 files changed, 235 insertions, 69 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 89ed4db..0d54e4c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,19 @@
2017-05-04 Martin Sebor <msebor@redhat.com>
+ PR middle-end/79234
+ * gcc.dg/builtin-stringop-chk-8.c: New test.
+ * gcc.dg/builtin-stringop-chk-1.c: Adjust.
+ * gcc.dg/builtin-stringop-chk-4.c: Same.
+ * gcc.dg/builtin-strncat-chk-1.c: Same.
+ * g++.dg/ext/strncpy-chk1.C: Same.
+ * g++.dg/torture/Wsizeof-pointer-memaccess1.C: Same.
+ * gcc.dg/out-of-bounds-1.c: Same.
+ * gcc.dg/pr78138.c: Same.
+ * gcc.dg/torture/Wsizeof-pointer-memaccess1.c: Same.
+ * gfortran.dg/mvbits_7.f90: Same.
+
+2017-05-04 Martin Sebor <msebor@redhat.com>
+
PR preprocessor/79214
PR middle-end/79222
PR middle-end/79223
diff --git a/gcc/testsuite/g++.dg/ext/strncpy-chk1.C b/gcc/testsuite/g++.dg/ext/strncpy-chk1.C
index d67d6bf..ff591a0 100644
--- a/gcc/testsuite/g++.dg/ext/strncpy-chk1.C
+++ b/gcc/testsuite/g++.dg/ext/strncpy-chk1.C
@@ -9,7 +9,7 @@ struct B { char z[50]; };
inline void
foo (char *dest, const char *__restrict src, __SIZE_TYPE__ n)
{
- __builtin___strncpy_chk (dest, src, n, __builtin_object_size (dest, 0)); // { dg-warning "specified bound 36 exceeds the size 35 of the destination" }
+ __builtin___strncpy_chk (dest, src, n, __builtin_object_size (dest, 0)); // { dg-warning "specified bound 36 exceeds destination size 35" }
}
void bar (const char *, int);
diff --git a/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C
index 2e6189b..c72532b 100644
--- a/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C
+++ b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C
@@ -1,6 +1,6 @@
// Test -Wsizeof-pointer-memaccess warnings.
// { dg-do compile }
-// { dg-options "-Wall -Wno-sizeof-array-argument" }
+// { dg-options "-Wall -Wno-sizeof-array-argument -Wno-stringop-overflow" }
// Test just twice, once with -O0 non-fortified, once with -O2 fortified.
// { dg-skip-if "" { *-*-* } { "*" } { "-O0" "-O2" } }
// { dg-skip-if "" { *-*-* } { "-flto" } { "" } }
diff --git a/gcc/testsuite/gcc.dg/builtin-stringop-chk-1.c b/gcc/testsuite/gcc.dg/builtin-stringop-chk-1.c
index 3d970d7..ebf6e85 100644
--- a/gcc/testsuite/gcc.dg/builtin-stringop-chk-1.c
+++ b/gcc/testsuite/gcc.dg/builtin-stringop-chk-1.c
@@ -37,9 +37,9 @@ test (int arg, ...)
vx = stpcpy (&buf2[18], "a");
vx = stpcpy (&buf2[18], "ab"); /* { dg-warning "writing 3" "stpcpy" } */
strncpy (&buf2[18], "a", 2);
- strncpy (&buf2[18], "a", 3); /* { dg-warning "specified bound 3 exceeds the size 2 of the destination" "strncpy" } */
+ strncpy (&buf2[18], "a", 3); /* { dg-warning "specified bound 3 exceeds destination size 2" "strncpy" } */
strncpy (&buf2[18], "abc", 2);
- strncpy (&buf2[18], "abc", 3); /* { dg-warning "specified bound 3 exceeds the size 2 of the destination" "strncpy" } */
+ strncpy (&buf2[18], "abc", 3); /* { dg-warning "writing 3 " "strncpy" } */
memset (buf2, '\0', sizeof (buf2));
strcat (&buf2[18], "a");
memset (buf2, '\0', sizeof (buf2));
@@ -54,7 +54,7 @@ test (int arg, ...)
Although this particular call wouldn't overflow buf2,
incorrect buffer size was passed to it and therefore
we want a warning and runtime failure. */
- snprintf (&buf2[18], 3, "%d", x); /* { dg-warning "specified bound 3 exceeds the size 2 of the destination" "snprintf" } */
+ snprintf (&buf2[18], 3, "%d", x); /* { dg-warning "specified bound 3 exceeds destination size 2" "snprintf" } */
va_start (ap, arg);
vsprintf (&buf2[18], "a", ap);
va_end (ap);
@@ -67,7 +67,7 @@ test (int arg, ...)
va_end (ap);
va_start (ap, arg);
/* See snprintf above. */
- vsnprintf (&buf2[18], 3, "%s", ap); /* { dg-warning "specified bound 3 exceeds the size 2 of the destination" "vsnprintf" } */
+ vsnprintf (&buf2[18], 3, "%s", ap); /* { dg-warning "specified bound 3 exceeds destination size 2" "vsnprintf" } */
va_end (ap);
p = p + 10;
@@ -94,7 +94,7 @@ void
test2 (const H h)
{
char c;
- strncpy (&c, str, 3); /* { dg-warning "specified bound 3 exceeds the size 1 of the destination" "strncpy" } */
+ strncpy (&c, str, 3); /* { dg-warning "specified bound 3 exceeds destination size 1" "strncpy" } */
struct { char b[4]; } x;
sprintf (x.b, "%s", "ABCD"); /* { dg-warning "writing 5" "sprintf" } */
diff --git a/gcc/testsuite/gcc.dg/builtin-stringop-chk-4.c b/gcc/testsuite/gcc.dg/builtin-stringop-chk-4.c
index 4857bda..c0110f2 100644
--- a/gcc/testsuite/gcc.dg/builtin-stringop-chk-4.c
+++ b/gcc/testsuite/gcc.dg/builtin-stringop-chk-4.c
@@ -77,32 +77,11 @@ signed_range (ptrdiff_t min, ptrdiff_t max)
#define UR(min, max) unsigned_range (min, max)
#define SR(min, max) signed_range (min, max)
-/* UReturn a pointer to constant string whose length is at least MINLEN
+/* Return a pointer to constant string whose length is at least MINLEN
and at most 10. */
-static inline const char*
-string_range (size_t minlen)
-{
- static const char str[] = "0123456789";
-
- const size_t len = unsigned_range (minlen, sizeof str - 1);
-
- switch (len)
- {
- case 10: return "0123456789";
- case 9: return "012345678";
- case 8: return "01234567";
- case 7: return "0123456";
- case 6: return "012345";
- case 5: return "01234";
- case 4: return "0123";
- case 3: return "012";
- case 2: return "01";
- case 1: return "0";
- case 0: return "";
- }
-}
-
-#define S(minlen) string_range (minlen)
+#define S(minlen) \
+ (minlen == random_unsigned_value () \
+ ? "0123456789" + 10 - minlen : "0123456789")
/* Test memcpy with a number of bytes bounded by a known range. */
@@ -122,7 +101,7 @@ void test_memcpy_range (void *d, const void *s)
memcpy (buf + size_max, s, UR (1, 2)); /* { dg-warning "writing between 1 and 2 bytes into a region of size 0 overflows the destination" "excessive pointer offset" { xfail *-*-* } } */
- memcpy (buf, s, UR (ssize_max, size_max)); /* { dg-warning "writing between \[0-9\]+ and \[0-9\]+ bytes into a region of size 5 overflows the destination" } */
+ memcpy (buf, s, UR (ssize_max, size_max)); /* { dg-warning "writing \[0-9\]+ or more bytes into a region of size 5 overflows the destination" } */
memcpy (buf, s, UR (ssize_max + 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */
memcpy (buf, s, UR (size_max - 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */
@@ -207,7 +186,7 @@ void test_mempcpy_range (void *d, const void *s)
mempcpy (buf, s, UR (6, 7)); /* { dg-warning "writing between 6 and 7 bytes into a region of size 5 overflows the destination" } */
- mempcpy (buf, s, UR (ssize_max, size_max)); /* { dg-warning "writing between \[0-9\]+ and \[0-9\]+ bytes into a region of size 5 overflows the destination" } */
+ mempcpy (buf, s, UR (ssize_max, size_max)); /* { dg-warning "writing \[0-9\]+ or more bytes into a region of size 5 overflows the destination" } */
mempcpy (buf, s, UR (ssize_max + 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */
mempcpy (buf, s, UR (size_max - 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */
@@ -233,7 +212,7 @@ void test_memset_range (void *d)
memset (buf, 0, UR (6, 7)); /* { dg-warning "writing between 6 and 7 bytes into a region of size 5 overflows the destination" } */
- memset (buf, 0, UR (ssize_max, size_max)); /* { dg-warning "writing between \[0-9\]+ and \[0-9\]+ bytes into a region of size 5 overflows the destination" } */
+ memset (buf, 0, UR (ssize_max, size_max)); /* { dg-warning "writing \[0-9\]+ or more bytes into a region of size 5 overflows the destination" } */
memset (buf, 0, UR (ssize_max + 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */
memset (buf, 0, UR (size_max - 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */
@@ -259,7 +238,7 @@ void test_bzero_range (void *d)
bzero (buf, UR (6, 7)); /* { dg-warning "writing between 6 and 7 bytes into a region of size 5 overflows the destination" } */
- bzero (buf, UR (ssize_max, size_max)); /* { dg-warning "writing between \[0-9\]+ and \[0-9\]+ bytes into a region of size 5 overflows the destination" } */
+ bzero (buf, UR (ssize_max, size_max)); /* { dg-warning "writing \[0-9\]+ or more bytes into a region of size 5 overflows the destination" } */
bzero (buf, UR (ssize_max + 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */
bzero (buf, UR (size_max - 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */
@@ -281,7 +260,7 @@ void test_strcat_range (void)
strcat (buf, S (2));
strcat (buf, S (3));
strcat (buf, S (4));
- strcat (buf, S (5)); /* { dg-warning "writing 6 bytes into a region of size 5 " } */
+ strcat (buf, S (5)); /* { dg-warning "writing between 6 and 11 bytes into a region of size 5 " } */
{
/* The implementation of the warning isn't smart enough to determine
@@ -320,10 +299,10 @@ void test_strcpy (const char *src)
strcpy (a.a + 2, src); /* { dg-warning "writing at least 1 byte into a region of size 0 " "strcpy into empty substring" { xfail *-*-* } } */
/* This does work. */
- strcpy (a.a + 5, src); /* { dg-warning "writing at least 1 byte into a region of size 0 " } */
+ strcpy (a.a + 5, src); /* { dg-warning "writing 1 or more bytes into a region of size 0 " } */
/* As does this. */
- strcpy (a.a + 17, src); /* { dg-warning "writing at least 1 byte into a region of size 0 " } */
+ strcpy (a.a + 17, src); /* { dg-warning "writing 1 or more bytes into a region of size 0 " } */
}
/* Test strcpy with a non-constant source string of length in a known
@@ -337,16 +316,16 @@ void test_strcpy_range (void)
strcpy (buf, S (1));
strcpy (buf, S (2));
strcpy (buf, S (4));
- strcpy (buf, S (5)); /* { dg-warning "writing 6 bytes into a region of size 5 " } */
- strcpy (buf, S (6)); /* { dg-warning "writing 7 bytes into a region of size 5 " } */
- strcpy (buf, S (7)); /* { dg-warning "writing 8 bytes into a region of size 5 " } */
- strcpy (buf, S (8)); /* { dg-warning "writing 9 bytes into a region of size 5 " } */
- strcpy (buf, S (9)); /* { dg-warning "writing 10 bytes into a region of size 5 " } */
- strcpy (buf, S (10)); /* { dg-warning "writing 11 bytes into a region of size 5 " } */
+ strcpy (buf, S (5)); /* { dg-warning "writing between 6 and 11 bytes into a region of size 5 " } */
+ strcpy (buf, S (6)); /* { dg-warning "writing between 7 and 11 bytes" } */
+ strcpy (buf, S (7)); /* { dg-warning "writing between 8 and 11 bytes" } */
+ strcpy (buf, S (8)); /* { dg-warning "writing between 9 and 11 bytes" } */
+ strcpy (buf, S (9)); /* { dg-warning "writing between 10 and 11 bytes" } */
+ strcpy (buf, S (10)); /* { dg-warning "writing 11 bytes" } */
- strcpy (buf + 5, S (0)); /* { dg-warning "writing 1 byte into a region of size 0 " } */
+ strcpy (buf + 5, S (0)); /* { dg-warning "writing between 1 and 11 bytes" } */
- strcpy (buf + 17, S (0)); /* { dg-warning "writing 1 byte into a region of size 0 " } */
+ strcpy (buf + 17, S (0)); /* { dg-warning "writing between 1 and 11 bytes " } */
}
/* Test strncat with an argument referencing a non-constant string of
@@ -364,31 +343,31 @@ void test_strncat_range (void)
strncat (buf + 5, S (0), 0);
- strncat (buf + 5, S (0), 1); /* { dg-warning "specified bound 1 exceeds the size 0 of the destination " } */
- strncat (buf + 5, S (1), 1); /* { dg-warning "specified bound 1 exceeds the size 0 of the destination " } */
+ strncat (buf + 5, S (0), 1); /* { dg-warning "specified bound 1 exceeds destination size 0" } */
+ strncat (buf + 5, S (1), 1); /* { dg-warning "specified bound 1 exceeds destination size 0" } */
/* Strncat always appends a terminating null after copying the N
characters so the following triggers a warning pointing out
that specifying sizeof(buf) as the upper bound may cause
the nul to overflow the destination. */
- strncat (buf, S (0), 5); /* { dg-warning "specified bound 5 equals the size of the destination" } */
- strncat (buf, S (0), 6); /* { dg-warning "specified bound 6 exceeds the size 5 of the destination" } */
+ strncat (buf, S (0), 5); /* { dg-warning "specified bound 5 equals destination size" } */
+ strncat (buf, S (0), 6); /* { dg-warning "specified bound 6 exceeds destination size 5" } */
strncat (buf, S (1), 0);
strncat (buf, S (1), 1);
strncat (buf, S (1), 2);
strncat (buf, S (1), 3);
strncat (buf, S (1), 4);
- strncat (buf, S (1), 5); /* { dg-warning "specified bound 5 equals the size of the destination" } */
- strncat (buf, S (1), 6); /* { dg-warning "specified bound 6 exceeds the size 5 of the destination" } */
- strncat (buf, S (2), 6); /* { dg-warning "specified bound 6 exceeds the size 5 of the destination" } */
+ strncat (buf, S (1), 5); /* { dg-warning "specified bound 5 equals destination size" } */
+ strncat (buf, S (1), 6); /* { dg-warning "specified bound 6 exceeds destination size 5" } */
+ strncat (buf, S (2), 6); /* { dg-warning "specified bound 6 exceeds destination size 5" } */
/* The following could just as well say "writing 6 bytes into a region
of size 5. Either would be correct and probably equally as clear
in this case. But when the length of the source string is not known
at all then the bound warning seems clearer. */
- strncat (buf, S (5), 6); /* { dg-warning "specified bound 6 exceeds the size 5 of the destination " } */
- strncat (buf, S (7), 6); /* { dg-warning "specified bound 6 exceeds the size 5 of the destination" } */
+ strncat (buf, S (5), 6); /* { dg-warning "specified bound 6 exceeds destination size 5" } */
+ strncat (buf, S (7), 6); /* { dg-warning "specified bound 6 exceeds destination size 5" } */
{
/* The implementation of the warning isn't smart enough to determine
@@ -413,15 +392,15 @@ void test_strncat_chk_range (char *d)
strncat_chk (buf, S (0), 2);
strncat_chk (buf, S (0), 3);
strncat_chk (buf, S (0), 4);
- strncat_chk (buf, S (0), 5); /* { dg-warning "specified bound 5 equals the size of the destination " } */
+ strncat_chk (buf, S (0), 5); /* { dg-warning "specified bound 5 equals destination size" } */
strncat_chk (buf, S (5), 1);
strncat_chk (buf, S (5), 2);
strncat_chk (buf, S (5), 3);
strncat_chk (buf, S (5), 4);
- strncat_chk (buf, S (5), 5); /* { dg-warning "specified bound 5 equals the size of the destination " } */
+ strncat_chk (buf, S (5), 5); /* { dg-warning "specified bound 5 equals destination size" } */
- strncat_chk (buf, S (5), 10); /* { dg-warning "specified bound \[0-9\]+ exceeds the size 5 of the destination " } */
+ strncat_chk (buf, S (5), 10); /* { dg-warning "specified bound \[0-9\]+ exceeds destination size 5" } */
strncat_chk (d, S (5), size_max); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size " } */
}
@@ -491,7 +470,7 @@ void test_strncpy_string_count_range (char *dst, const char *src)
strncpy (buf, S (0), UR (6, 7)); /* { dg-warning "writing between 6 and 7 bytes into a region of size 5 " } */
strncpy (buf, S (1), UR (7, 8)); /* { dg-warning "writing between 7 and 8 bytes into a region of size 5 " } */
- strncpy (buf, S (2), UR (ssize_max, ssize_max + 1)); /* { dg-warning "writing between \[0-9\]+ and \[0-9\]+ bytes into a region of size 5 " } */
+ strncpy (buf, S (2), UR (ssize_max, ssize_max + 1)); /* { dg-warning "writing \[0-9\]+ or more bytes into a region of size 5 " } */
strncpy (buf, S (2), UR (ssize_max + 1, ssize_max + 2)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */
diff --git a/gcc/testsuite/gcc.dg/builtin-stringop-chk-8.c b/gcc/testsuite/gcc.dg/builtin-stringop-chk-8.c
new file mode 100644
index 0000000..f4056f3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-stringop-chk-8.c
@@ -0,0 +1,173 @@
+/* Test exercising -Wstringop-overflow warnings for reading past the end. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wstringop-overflow=1 -ftrack-macro-expansion=0" } */
+
+#define PTRDIFF_MAX __PTRDIFF_MAX__
+#define SIZE_MAX __SIZE_MAX__
+
+#define offsetof(type, mem) __builtin_offsetof (type, mem)
+
+/* Return the number of bytes from member MEM of TYPE to the end
+ of object OBJ. */
+#define offsetfrom(type, obj, mem) (sizeof (obj) - offsetof (type, mem))
+
+
+typedef __SIZE_TYPE__ size_t;
+extern void* memchr (const void*, int, size_t);
+extern int memcmp (const void*, const void*, size_t);
+extern void* memcpy (void*, const void*, size_t);
+extern void* memmove (void*, const void*, size_t);
+extern void* mempcpy (void*, const void*, size_t);
+
+#define memchr(d, s, n) sink (memchr (d, s, n))
+#define memcmp(d, s, n) sink (d, memcmp (d, s, n))
+#define memcpy(d, s, n) sink (memcpy (d, s, n))
+#define memmove(d, s, n) sink (memmove (d, s, n))
+#define mempcpy(d, s, n) sink (mempcpy (d, s, n))
+
+struct A { char a, b; };
+struct B { struct A a; char c, d; };
+
+/* Function to call to "escape" pointers from tests below to prevent
+ GCC from assuming the values of the objects they point to stay
+ the unchanged. */
+void sink (void*, ...);
+
+/* Function to "generate" a random number each time it's called. Declared
+ (but not defined) and used to prevent GCC from making assumptions about
+ their values based on the variables uses in the tested expressions. */
+size_t random_unsigned_value (void);
+
+/* Return a random unsigned value between MIN and MAX. */
+
+static inline size_t
+range (size_t min, size_t max)
+{
+ const size_t val = random_unsigned_value ();
+ return val < min || max < val ? min : val;
+}
+
+#define R(min, max) range (min, max)
+
+/* Verify that reading beyond the end of a local array is diagnosed. */
+
+void test_memop_warn_local (void *p, const void *q)
+{
+ memcpy (p, "1234", R (6, 7)); /* { dg-warning "reading between 6 and 7 bytes from a region of size 5" } */
+
+ struct A a[2];
+
+ memcpy (p, a, R (7, 8)); /* { dg-warning "reading between 7 and 8 bytes from a region of size 4" } */
+
+ /* At -Wstringop-overflow=1 the destination is considered to be
+ the whole array and its size is therefore sizeof a. */
+ memcpy (p, &a[0], R (8, 9)); /* { dg-warning "reading between 8 and 9 bytes from a region of size 4" } */
+
+ /* Verify the same as above but by reading from the first mmeber
+ of the first element of the array. */
+ memcpy (p, &a[0].a, R (8, 9)); /* { dg-warning "reading between 8 and 9 bytes from a region of size 4" } */
+
+ struct B b[2];
+
+ memcpy (p, &b[0], R (12, 32)); /* { dg-warning "reading between 12 and 32 bytes from a region of size 8" } */
+
+ /* Verify memchr/memcmp. */
+ int i = R (0, 255);
+ memchr ("", i, 2); /* { dg-warning "reading 2 bytes from a region of size 1" } */
+ memchr ("", i, 2); /* { dg-warning "reading 2 bytes from a region of size 1" } */
+ memchr ("123", i, 5); /* { dg-warning "reading 5 bytes from a region of size 4" } */
+ memchr (a, i, sizeof a + 1); /* { dg-warning "reading 5 bytes from a region of size 4" } */
+
+ memcmp (p, "", 2); /* { dg-warning "reading 2 bytes from a region of size 1" } */
+ memcmp (p, "123", 5); /* { dg-warning "reading 5 bytes from a region of size 4" } */
+ memcmp (p, a, sizeof a + 1); /* { dg-warning "reading 5 bytes from a region of size 4" } */
+
+ size_t n = PTRDIFF_MAX + (size_t)1;
+ memchr (p, 1, n); /* { dg-warning "exceeds maximum object size" } */
+ memcmp (p, q, n); /* { dg-warning "exceeds maximum object size" } */
+
+ n = SIZE_MAX;
+ memchr (p, 1, n); /* { dg-warning "exceeds maximum object size" } */
+ memcmp (p, q, n); /* { dg-warning "exceeds maximum object size" } */
+}
+
+/* Verify that reading beyond the end of a dynamically allocated array
+ of known size is diagnosed. */
+
+void test_memop_warn_alloc (void *p)
+{
+ size_t n;
+
+ n = range (8, 32);
+
+ struct A *a = __builtin_malloc (sizeof *a * 2);
+
+ memcpy (p, a, n); /* { dg-warning "reading between 8 and 32 bytes from region of size 4" "memcpy from allocated" { xfail *-*-*} } */
+
+ memcpy (p, &a[0], n); /* { dg-warning "reading between 8 and 32 bytes from a region of size 4" "memcpy from allocated" { xfail *-*-*} } */
+
+ memcpy (p, &a[0].a, n); /* { dg-warning "reading between 8 and 32 bytes from a region of size 4" "memcpy from allocated" { xfail *-*-*} } */
+
+ n = range (12, 32);
+
+ struct B *b = __builtin_malloc (sizeof *b * 2);
+
+ memcpy (p, &b[0], n); /* { dg-warning "reading between 12 and 32 bytes from a region of size 8" "memcpy from allocated" { xfail *-*-*} } */
+
+ /* Verify memchr/memcmp. */
+ n = sizeof *b * 2 + 1;
+
+ memchr (b, 1, n); /* { dg-warning "reading 5 bytes from a region of size 4" "memcmp from allocated" { xfail *-*-* } } */
+ memcmp (p, b, n); /* { dg-warning "reading 5 bytes from a region of size 4" "memcmp from allocated" { xfail *-*-* } } */
+}
+
+
+void test_memop_nowarn (void *p)
+{
+ struct B b[2];
+
+ size_t n = range (sizeof b, 32);
+
+ /* Verify that copying the whole array is not diagnosed regardless
+ of whether the expression pointing to its beginning is obtained
+ from the array itself or its first member(s). */
+ memcpy (p, b, n);
+
+ memcpy (p, &b[0], n);
+
+ memcpy (p, &b[0].a, n);
+
+ memcpy (p, &b[0].a.a, n);
+
+ /* Verify that memchr/memcmp doesn't cause a warning. */
+ memchr (p, 1, n);
+ memchr (b, 2, n);
+ memchr (&b[0], 3, n);
+ memchr (&b[0].a, 4, n);
+ memchr (&b[0].a.a, 5, n);
+ memchr ("01234567", R (0, 255), n);
+
+ memcmp (p, p, n);
+ memcmp (p, b, n);
+ memcmp (p, &b[0], n);
+ memcmp (p, &b[0].a, n);
+ memcmp (p, &b[0].a.a, n);
+ memcmp (p, "01234567", n);
+}
+
+
+/* The following function could specify in its API that it takes
+ an array of exactly two elements, as shown below (or simply be
+ called with such an array). Verify that reading from both
+ elements is not diagnosed. */
+void test_memop_nowarn_arg (void*, const struct A[2]);
+
+void test_memop_nowarn_arg (void *p, const struct A *a)
+{
+ memcpy (p, a, 2 * sizeof *a);
+
+ memcpy (p, a, range (2 * sizeof *a, 123));
+
+ memchr (p, 1, 1234);
+ memcmp (p, a, 1234);
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-strncat-chk-1.c b/gcc/testsuite/gcc.dg/builtin-strncat-chk-1.c
index daff680..851fb74 100644
--- a/gcc/testsuite/gcc.dg/builtin-strncat-chk-1.c
+++ b/gcc/testsuite/gcc.dg/builtin-strncat-chk-1.c
@@ -28,11 +28,11 @@ test (int arg, ...)
*p = 0;
strncat (p, "abcdefgh", 11);
*p = 0;
- strncat (p, "abcdefghijkl", 11); /* { dg-warning "specified bound 11 exceeds the size 10 of the destination" } */
+ strncat (p, "abcdefghijkl", 11); /* { dg-warning "specified bound 11 exceeds destination size 10" } */
*p = 0;
strncat (p, q, 9);
*p = 0;
- strncat (p, q, 10); /* { dg-warning "specified bound 10 equals the size of the destination" } */
+ strncat (p, q, 10); /* { dg-warning "specified bound 10 equals destination size" } */
*p = 0;
- strncat (p, q, 11); /* { dg-warning "specified bound 11 exceeds the size 10 of the destination" } */
+ strncat (p, q, 11); /* { dg-warning "specified bound 11 exceeds destination size 10" } */
}
diff --git a/gcc/testsuite/gcc.dg/out-of-bounds-1.c b/gcc/testsuite/gcc.dg/out-of-bounds-1.c
index 8cdf643..1c76341 100644
--- a/gcc/testsuite/gcc.dg/out-of-bounds-1.c
+++ b/gcc/testsuite/gcc.dg/out-of-bounds-1.c
@@ -9,5 +9,5 @@ void ProjectOverlay(const float localTextureAxis[2], char *lump)
{
const void *d = &localTextureAxis;
int size = sizeof(float)*8 ;
- __builtin_memcpy( &lump[ 0 ], d, size );
+ __builtin_memcpy( &lump[ 0 ], d, size ); /* { dg-warning "reading" } */
}
diff --git a/gcc/testsuite/gcc.dg/pr78138.c b/gcc/testsuite/gcc.dg/pr78138.c
index 5145cb4..c0c861e 100644
--- a/gcc/testsuite/gcc.dg/pr78138.c
+++ b/gcc/testsuite/gcc.dg/pr78138.c
@@ -12,7 +12,7 @@ extern char* strcpy (char*, const char*);
void f (int i, int j)
{
- strcpy (d, j ? "12345" : "123456"); /* { dg-warning ".strcpy. writing 6 bytes into a region of size 5" } */
+ strcpy (d, j ? "12345" : "123456"); /* { dg-warning ".strcpy.: writing between 6 and 7 bytes into a region of size 5 " } */
}
void g (void *p)
diff --git a/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c b/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c
index b5a59f4..a73e45f 100644
--- a/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c
+++ b/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c
@@ -1,6 +1,6 @@
/* Test -Wsizeof-pointer-memaccess warnings. */
/* { dg-do compile } */
-/* { dg-options "-Wall -Wno-sizeof-array-argument" } */
+/* { dg-options "-Wall -Wno-sizeof-array-argument -Wno-stringop-overflow" } */
/* Test just twice, once with -O0 non-fortified, once with -O2 fortified. */
/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" "-O2" } } */
/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c
index b4a9a6e..c4dbf3e 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c
@@ -1576,7 +1576,7 @@ void test_snprintf_chk_c_const (void)
/* Verify that specifying a size of the destination buffer that's
bigger than its actual size (normally determined and passed to
the function by __builtin_object_size) is diagnosed. */
- FUNC (__snprintf_chk)(buffer, 3, 0, 2, " "); /* { dg-warning "specified bound 3 exceeds the size 2 of the destination" } */
+ FUNC (__snprintf_chk)(buffer, 3, 0, 2, " "); /* { dg-warning "specified bound 3 exceeds destination size 2" } */
T (-1, "%c", 0); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
@@ -1717,7 +1717,7 @@ void test_vsnprintf_chk_s (va_list va)
/* Verify that specifying a size of the destination buffer that's
bigger than its actual size (normally determined and passed to
the function by __builtin_object_size) is diagnosed. */
- FUNC (__vsnprintf_chk)(buffer, 123, 0, 122, "%-s", va); /* { dg-warning "specified bound 123 exceeds the size 122 of the destination" } */
+ FUNC (__vsnprintf_chk)(buffer, 123, 0, 122, "%-s", va); /* { dg-warning "specified bound 123 exceeds destination size 122" } */
FUNC (__vsnprintf_chk)(buffer, __SIZE_MAX__, 0, 2, "%-s", va); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
diff --git a/gcc/testsuite/gfortran.dg/mvbits_7.f90 b/gcc/testsuite/gfortran.dg/mvbits_7.f90
index 2c7cab8..104ec67 100644
--- a/gcc/testsuite/gfortran.dg/mvbits_7.f90
+++ b/gcc/testsuite/gfortran.dg/mvbits_7.f90
@@ -25,6 +25,6 @@ contains
SUBROUTINE bar (x, NF4, NF3, NF1, MF1, MF4, MF3)
TYPE(t) x(NF4, NF3) ! Dependency through variable indices
CALL MVBITS (x(NF4:NF1:MF1, NF1:NF3)%i, 1, &
- 6, x(-MF4:-MF1:-NF1, -MF1:-MF3)%i, 9)
+ 6, x(-MF4:-MF1:-NF1, -MF1:-MF3)%i, 9) ! { dg-warning "reading" }
END SUBROUTINE
end