On 1/21/19 1:18 AM, Richard Biener wrote:
On Sat, Jan 19, 2019 at 12:25 AM Martin Sebor <mse...@gmail.com> wrote:
Some of the -Warray-bounds and -Wrestrict tests are prone to failing
on targets like arm-eabi and others that use different parameters to
decide which memcpy calls should be folded to MEM_REF (those that do
are copies of small power-of-two sizes where the power tends to vary
from target to target and may be as little as 1). The failures then
waste the time of those who maintain those secondary targets reporting
failures (see * below), as well as those who wrote the tests debugging
the problems and working around them.
To reduce this effort (and ideally avoid these regressions going
forward) the attached patch adds a new effective-target to the test
harness: fold_memcpy_N. It detects the target's willingness to fold
memcpy call of the given size (N). While testing this with the arm
cross-compiler I also tweaked the tests that #include standard
headers to only do so when __has_include says the header exists.
This lets the tests pass even when using a cross-compiler without
library headers installed (my default MO). If/when the warnings
are improved to detect the problems regardless of the folding as
I'm hoping to eventually do, this new effective-target feature
can be removed.
But all the memcpy folding does is see whether the target can
access unaligned {2,4,8,<max-int-mode-size>} memory. So
a effective target unaligned_move_{2,4,8...} would be better and
possibly useful in other contexts? memcpy folding might be indeed
a nice vehicle to test this property.
Thus, I guess I'm only asking to rename the effective target keyword.
I did this but after some more reading I no longer think we need it.
Btw, new effective targets need documenting in sourcebuild.texi
Thanks for the reminder! While adding the new keyword I came across
non_strict_align. It looks like it's pretty much same thing as what
I'm trying to add. It's used in gcc.dg/memmove-4.c and memcpy-3.c
(besides a few other tests) to test the folding whose absence
the warnings depend on.
So I've simplified the patch to make use of non_strict_align instead.
I've verified the tests pass with arm-eabi, sparc-solaris2.11, and
x86_64.
Martin
Richard.
Martin
[*] https://gcc.gnu.org/ml/gcc-patches/2019-01/msg01056.html
gcc/testsuite/ChangeLog:
* c-c++-common/Warray-bounds-2.c: Include headers only if they exist.
* c-c++-common/Warray-bounds-3.c: Make xfails conditional on target
non_strict_align.
* c-c++-common/Wrestrict-2.c: Include headers only if they exist.
* c-c++-common/Wrestrict.c: Make xfails conditional on target
non_strict_align.
Index: gcc/testsuite/c-c++-common/Warray-bounds-2.c
===================================================================
--- gcc/testsuite/c-c++-common/Warray-bounds-2.c (revision 268086)
+++ gcc/testsuite/c-c++-common/Warray-bounds-2.c (working copy)
@@ -8,13 +8,28 @@
{ dg-do compile }
{ dg-options "-O2 -Warray-bounds -Wno-stringop-overflow" } */
-#include <stddef.h>
-#include <string.h>
+#if __has_include (<stddef.h>)
+# include <stddef.h>
+#else
+/* For cross-compilers. */
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+typedef __SIZE_TYPE__ size_t;
+#endif
-#undef memcpy
-#undef strcpy
-#undef strncpy
+#if __has_include (<string.h>)
+# include <string.h>
+# undef memcpy
+# undef strcat
+# undef strcpy
+# undef strncpy
+#else
+extern void* memcpy (void*, const void*, size_t);
+extern char* strcat (char*, const char*);
+extern char* strcpy (char*, const char*);
+extern char* strncpy (char*, const char*, size_t);
+#endif
+
#define MAX (__SIZE_MAX__ / 2)
void sink (void*);
Index: gcc/testsuite/c-c++-common/Warray-bounds-3.c
===================================================================
--- gcc/testsuite/c-c++-common/Warray-bounds-3.c (revision 268086)
+++ gcc/testsuite/c-c++-common/Warray-bounds-3.c (working copy)
@@ -158,7 +158,7 @@ void test_memcpy_overflow (char *d, const char *s,
but known access size is detected. This works except with small
sizes that are powers of 2 due to bug . */
T (char, 1, arr + SR (DIFF_MAX - 1, DIFF_MAX), s, 1);
- T (char, 1, arr + SR (DIFF_MAX - 1, DIFF_MAX), s, 2); /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 2 accessing array " "bug " { xfail *-*-* } } */
+ T (char, 1, arr + SR (DIFF_MAX - 1, DIFF_MAX), s, 2); /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 2 accessing array " "bug " { xfail non_strict_align } } */
T (char, 1, arr + SR (DIFF_MAX - 2, DIFF_MAX), s, 3); /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 3 accessing array " "memcpy" } */
T (char, 1, arr + SR (DIFF_MAX - 4, DIFF_MAX), s, 5); /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 5 accessing array " "memcpy" } */
}
Index: gcc/testsuite/c-c++-common/Wrestrict-2.c
===================================================================
--- gcc/testsuite/c-c++-common/Wrestrict-2.c (revision 268086)
+++ gcc/testsuite/c-c++-common/Wrestrict-2.c (working copy)
@@ -8,8 +8,30 @@
{ dg-do compile }
{ dg-options "-O2 -Wrestrict" } */
-#include <string.h>
+#if __has_include (<stddef.h>)
+# include <stddef.h>
+#else
+/* For cross-compilers. */
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+typedef __SIZE_TYPE__ size_t;
+#endif
+#if __has_include (<string.h>)
+# include <string.h>
+# undef memcpy
+# undef strcat
+# undef strcpy
+# undef strncat
+# undef strncpy
+#else
+extern void* memcpy (void*, const void*, size_t);
+extern char* strcat (char*, const char*);
+extern char* strcpy (char*, const char*);
+extern char* strncat (char*, const char*, size_t);
+extern char* strncpy (char*, const char*, size_t);
+#endif
+
+
static void wrap_memcpy (void *d, const void *s, size_t n)
{
memcpy (d, s, n); /* { dg-warning "accessing 2 bytes at offsets 0 and 1 overlaps 1 byte at offset 1" "memcpy" } */
Index: gcc/testsuite/c-c++-common/Wrestrict.c
===================================================================
--- gcc/testsuite/c-c++-common/Wrestrict.c (revision 268086)
+++ gcc/testsuite/c-c++-common/Wrestrict.c (working copy)
@@ -53,8 +53,11 @@ void test_memcpy_cst (void *d, const void *s)
T (a, a, 0);
- /* This isn't detected because memcpy calls with small power-of-2 sizes
- are intentionally folded into safe copies equivalent to memmove.
+ /* This isn't detected because memcpy calls with size of 1 are
+ intentionally folded into safe copies equivalent to memmove,
+ regardless of the target (larger power-of-2 copies may or
+ may not be folded depending on the target -- see non_strict_align
+ below, for example).
It's marked xfail only because there is value in detecting such
invalid calls for portability, and as a reminder of why it isn't
diagnosed. */
@@ -192,7 +195,7 @@ void test_memcpy_range (char *d, size_t sz)
T (a + ir, a, 2);
T (a + ir, a, 3);
/* The following fails because the size is a small power of 2. */
- T (a + ir, a, 4); /* { dg-warning "accessing 4 bytes at offsets \\\[2, 3] and 0 overlaps between 1 and 2 bytes at offset \\\[3, 2]" "memcpy" { xfail *-*-*} } */
+ T (a + ir, a, 4); /* { dg-warning "accessing 4 bytes at offsets \\\[2, 3] and 0 overlaps between 1 and 2 bytes at offset \(\\\[3, 2]|\\\[2, 3]\)" "pr79220" { xfail non_strict_align } } */
T (a + ir, a, 5); /* { dg-warning "accessing 5 bytes at offsets \\\[2, 3] and 0 overlaps between 2 and 3 bytes at offset \\\[2, 3]" "memcpy" } */
T (d + ir, d, 0);
@@ -199,12 +202,12 @@ void test_memcpy_range (char *d, size_t sz)
T (d + ir, d, 1);
T (d + ir, d, 2);
T (d + ir, d, 3);
- T (d + ir, d, 4); /* { dg-warning "accessing 4 bytes at offsets \\\[2, 3] and 0 overlaps 1 byte at offset 3" "bug 79220" { xfail *-*-* } } */
+ T (d + ir, d, 4); /* { dg-warning "accessing 4 bytes at offsets \\\[2, 3] and 0 overlaps between 1 and 2 bytes at offset \\\[2, 3]" "pr79220" { xfail non_strict_align } } */
T (d + ir, d, 5); /* { dg-warning "accessing 5 bytes at offsets \\\[2, 3] and 0 overlaps between 2 and 3 bytes at offset \\\[2, 3]" "memcpy" } */
/* Because the size is constant and a power of 2 the following is
folded too early to detect the overlap. */
- T (d + ir, d, 4); /* { dg-warning "accessing 4 bytes at offsets \\\[2, 3] and 0 overlaps 2 byte at offset 2" "memcpy" { xfail *-*-* } } */
+ T (d + ir, d, 4); /* { dg-warning "accessing 4 bytes at offsets \\\[2, 3] and 0 overlaps between 1 and 2 bytes at offset \\\[2, 3]" "pr79220" { xfail non_strict_align } } */
T (d + ir, d, 5); /* { dg-warning "accessing 5 bytes at offsets \\\[2, 3] and 0 overlaps between 2 and 3 bytes at offset \\\[2, 3]" "memcpy" } */
/* Exercise the full range of size_t. */