Commit 5e27f0d5 by Martin Sebor Committed by Martin Sebor

PR middle-end/84095 - false-positive -Wrestrict warnings for memcpy within array

gcc/ChangeLog:

	PR middle-end/84095
	* gimple-ssa-warn-restrict.c (builtin_memref::extend_offset_range): New.
	(builtin_memref::set_base_and_offset): Same.  Handle inner references.
	(builtin_memref::builtin_memref): Factor out parts into
	set_base_and_offset and call it.

gcc/testsuite/ChangeLog:

	PR middle-end/84095
	* c-c++-common/Warray-bounds-3.c: Adjust text of expected warnings.
	* c-c++-common/Wrestrict.c: Same.
	* gcc.dg/Wrestrict-6.c: Same.
	* gcc.dg/Warray-bounds-27.c: New test.
	* gcc.dg/Wrestrict-8.c: New test.
	* gcc.dg/Wrestrict-9.c: New test.
	* gcc.dg/pr84095.c: New test.

From-SVN: r257860
parent 75b81dcd
2018-02-20 Martin Sebor <msebor@redhat.com>
PR middle-end/84095
* gimple-ssa-warn-restrict.c (builtin_memref::extend_offset_range): New.
(builtin_memref::set_base_and_offset): Same. Handle inner references.
(builtin_memref::builtin_memref): Factor out parts into
set_base_and_offset and call it.
2018-02-20 Richard Sandiford <richard.sandiford@linaro.org>
PR middle-end/84406
......
2018-02-20 Martin Sebor <msebor@redhat.com>
PR middle-end/84095
* c-c++-common/Warray-bounds-3.c: Adjust text of expected warnings.
* c-c++-common/Wrestrict.c: Same.
* gcc.dg/Wrestrict-6.c: Same.
* gcc.dg/Warray-bounds-27.c: New test.
* gcc.dg/Wrestrict-8.c: New test.
* gcc.dg/Wrestrict-9.c: New test.
* gcc.dg/pr84095.c: New test.
2018-02-20 Thomas Koenig <tkoenig@gcc.gnu.org>
* gfortran.dg/structure_constructor_14.f90: Adjust STOP number.
......
......@@ -61,7 +61,7 @@ void test_memcpy_bounds (char *d, const char *s, size_t n)
they appear as large positive in the source. It would be nice
if they retained their type but unfortunately that's not how
it works so be prepared for both in case it even gets fixed. */
T (char, 1, a + UR (3, SIZE_MAX - 1), s, n); /* { dg-warning "offset \\\[3, -2] is out of the bounds \\\[0, 1] of object" "memcpy" } */
T (char, 1, a + UR (3, SIZE_MAX - 1), s, n); /* { dg-warning "offset \\\[3, -?\[0-9\]+] is out of the bounds \\\[0, 1] of object" "memcpy" } */
/* Verify that invalid offsets into an array of unknown size are
detected. */
......@@ -226,7 +226,7 @@ T (char, 1, a + SR (-2, -1), s, n); /* { dg-warning "offset \\\[-2, -1] is o
they appear as large positive in the source. It would be nice
if they retained their type but unfortunately that's not how
it works so be prepared for both in case it ever gets fixed. */
T (char, 1, a + UR (3, SIZE_MAX), s, n); /* { dg-warning "offset \\\[3, -1] is out of the bounds \\\[0, 1] of object " "mempcpy" } */
T (char, 1, a + UR (3, SIZE_MAX), s, n); /* { dg-warning "offset \\\[3, -?\[0-9\]+] is out of the bounds \\\[0, 1] of object " "mempcpy" } */
/* Verify that invalid offsets into an array of unknown size are
detected. */
......
......@@ -223,7 +223,7 @@ void test_memcpy_range (char *d, size_t sz)
/* 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" "" { xfail *-*-* } } */
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, 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. */
......@@ -325,11 +325,11 @@ void test_memcpy_anti_range (char *d, const char *s)
T (d, d + SAR (0, 3), 1);
T (d, d + SAR (0, 3), 2);
T (d, d + SAR (0, 3), 3);
T (d, d + SAR (0, 3), DIFF_MAX - 2); /* { dg-warning "overlaps \[0-9\]+ bytes at offset 2" } */
T (d, d + SAR (0, 3), DIFF_MAX - 1); /* { dg-warning "overlaps \[0-9\]+ bytes at offset 1" } */
T (d, d + SAR (0, 3), DIFF_MAX); /* { dg-warning "overlaps \[0-9\]+ bytes at offset 0" } */
T (d, d + SAR (0, 3), DIFF_MAX - 2); /* { dg-warning "overlaps \[0-9\]+ bytes at offset 2" "memcpy" } */
T (d, d + SAR (0, 3), DIFF_MAX - 1); /* { dg-warning "overlaps \[0-9\]+ bytes at offset 1" "memcpy" } */
T (d, d + SAR (0, 3), DIFF_MAX); /* { dg-warning "overlaps \[0-9\]+ bytes at offset 0" "memcpy" } */
T (d, d + SAR (0, 3), UR (DIFF_MAX - 2, DIFF_MAX)); /* { dg-warning "accessing \[0-9\]+ or more bytes at offsets 0 and \\\[-?\[0-9\]+, -?\[0-9\]+] overlaps \[0-9\]+ bytes at offset 2" } */
T (d, d + SAR (0, 3), UR (DIFF_MAX - 2, DIFF_MAX)); /* { dg-warning "accessing \[0-9\]+ or more bytes at offsets 0 and \\\[-?\[0-9\]+, -?\[0-9\]+] overlaps \[0-9\]+ bytes at offset 2" "memcpy" } */
/* Verify that a size in an anti-range ~[0, N] where N >= PTRDIFF_MAX
doesn't trigger a warning. */
......@@ -399,7 +399,7 @@ void test_memcpy_range_exceed (char *d, const char *s)
T (d + i, s, 5); /* { dg-warning "accessing 5 bytes at offsets \\\[9223372036854775805, 9223372036854775807] and 0 overlaps 3 bytes at offset 9223372036854775802" "LP64" { target lp64 } } */
#elif __SIZEOF_SIZE_T__ == 4
T (d, d + i, 5); /* { dg-warning "accessing 5 bytes at offsets 0 and \\\[2147483645, 2147483647] overlaps 3 bytes at offset 2147483642" "ILP32" { target ilp32 } } */
T (d + i, d, 5); /* { dg-warning "accessing 5 bytes at offsets \\\[2147483645, 2147483647] and 0 overlaps 3 bytes at offset 2147483642" "ILP32" { target ilp32} } */
T (d + i, d, 5); /* { dg-warning "accessing 5 bytes at offsets \\\[2147483645, 2147483647] and 0 overlaps 3 bytes at offset 2147483642" "ILP32" { target ilp32 } } */
T (d, s + i, 5); /* { dg-warning "accessing 5 bytes at offsets 0 and \\\[2147483645, 2147483647] overlaps 3 bytes at offset 2147483642" "ILP32" { target ilp32 } } */
T (d + i, s, 5); /* { dg-warning "accessing 5 bytes at offsets \\\[2147483645, 2147483647] and 0 overlaps 3 bytes at offset 2147483642" "ILP32" { target ilp32} } */
......@@ -523,7 +523,7 @@ void test_memcpy_memarrray (struct MemArrays *p)
T (p->a8, p->a8 + 2, 2);
T (p->a8, p->a8 + 8, 1);
T (p->a8, p->a8 + 2, 3); /* { dg-warning "accessing 3 bytes at offsets 0 and 2 overlaps 1 byte at offset 2" } */
T (p->a8, p->a8 + 2, 3); /* { dg-warning "accessing 3 bytes at offsets 0 and 2 overlaps 1 byte at offset 2" "memcpy" } */
}
/* Exercise the absence of warnings with memmove. */
......@@ -768,13 +768,13 @@ void test_strcpy_range (void)
/* The overlap in the cases below isn't inevitable but it is diagnosed
because it is possible and so the code is considered unsafe. */
T (8, "", a, a + r); /* { dg-warning "accessing 1 byte may overlap 1 byte" "strcpy" } */
T (8, "0", a + r, a); /* { dg-warning "accessing 2 bytes may overlap up to 2 bytes" "strcpy" } */
T (8, "012", a + r, a); /* { dg-warning "accessing 4 bytes may overlap up to 4 bytes" "strcpy" } */
T (8, "", a, a + r); /* { dg-warning "accessing 1 byte at offsets 0 and \\\[0, 8] may overlap 1 byte" "strcpy" } */
T (8, "0", a + r, a); /* { dg-warning "accessing 2 bytes at offsets \\\[0, 8] and 0 may overlap up to 2 bytes" "strcpy" } */
T (8, "012", a + r, a); /* { dg-warning "accessing 4 bytes at offsets \\\[0, 8] and 0 may overlap up to 4 bytes" "strcpy" } */
T (8, "", a, a + r); /* { dg-warning "accessing 1 byte may overlap" "strcpy" } */
T (8, "0", a, a + r); /* { dg-warning "accessing between 0 and 2 bytes may overlap up to 2 bytes" "strcpy" } */
T (8, "012", a, a + r); /* { dg-warning "accessing between 0 and 4 bytes may overlap up to 4 bytes" "strcpy" } */
T (8, "", a, a + r); /* { dg-warning "accessing 1 byte at offsets 0 and \\\[0, 8] may overlap" "strcpy" } */
T (8, "0", a, a + r); /* { dg-warning "accessing between 0 and 2 bytes at offsets 0 and \\\[0, 8] may overlap up to 2 bytes" "strcpy" } */
T (8, "012", a, a + r); /* { dg-warning "accessing between 0 and 4 bytes at offsets 0 and \\\[0, 8] may overlap up to 4 bytes" "strcpy" } */
}
/* Exercise strcpy with destination and/or source of unknown lengthu. */
......
/* { dg-do compile }
{ dg-options "-O2 -Wall -Wextra -Warray-bounds -Wrestrict" } */
typedef __SIZE_TYPE__ size_t;
extern void* memcpy (void* restrict, const void* restrict, size_t);
extern void sink (void*, ...);
struct Data {
size_t n;
void *p;
};
void test_copy (void)
{
struct Data d;
sink (&d);
char dp1[sizeof d + 1];
char d2x[2 * sizeof d];
char d2xp1[2 * sizeof d + 1];
/* During development the following would incorrectly trigger:
warning: 'memcpy' forming offset [17, 25] is out of the bounds [0, 16]
of object ‘d’ with type 'struct Data' [-Warray-bounds]
that wasn't caught by the test suite. Make sure it is. */
memcpy (&dp1, d.p, sizeof dp1); /* { dg-bogus "\\\[-Warray-bounds" } */
/* Likewise. */
memcpy (&d2x, d.p, sizeof d2x); /* { dg-bogus "\\\[-Warray-bounds" } */
memcpy (&d2xp1, d.p, sizeof d2xp1); /* { dg-bogus "\\\[-Warray-bounds" } */
sink (&d, &dp1, &d2x, &d2xp1);
}
......@@ -21,7 +21,7 @@ void warn_2_smax_p2 (void)
ptrdiff_t i = UR (2, DIFF_MAX + (size_t)2);
strcpy (d, d + i); /* { dg-warning "accessing between 0 and 4 bytes at offsets 0 and \\\[2, -\[0-9\]+] may overlap up to 2 bytes at offset 2" } */
strcpy (d, d + i); /* { dg-warning "accessing between 0 and 4 bytes at offsets 0 and \\\[2, 7] may overlap up to 2 bytes at offset 2" } */
sink (d);
}
......@@ -47,7 +47,7 @@ void warn_2u_smax_p2 (void)
size_t i = UR (2, DIFF_MAX + (size_t)2);
strcpy (d, d + i); /* { dg-warning "accessing between 0 and 4 bytes at offsets 0 and \\\[2, -\[0-9\]+] may overlap up to 2 bytes at offset 2" } */
strcpy (d, d + i); /* { dg-warning "accessing between 0 and 4 bytes at offsets 0 and \\\[2, 7] may overlap up to 2 bytes at offset 2" } */
sink (d);
}
......
/* PR tree-optimization/84095 - false-positive -Wrestrict warnings for
memcpy within array
{ dg-do compile }
{ dg-options "-O2 -Wrestrict -ftrack-macro-expansion=0" } */
typedef __SIZE_TYPE__ size_t;
extern void* memcpy (void* restrict, const void* restrict, size_t);
#define T(d, s, n) memcpy (d, s, n)
struct S1 { char c; } a8_1[8];
void test_1_dim_var (int i, int j)
{
/* Variable destination index and constant source index. */
T (&a8_1[i], &a8_1[0], 1);
T (&a8_1[i], &a8_1[0], 2);
T (&a8_1[i], &a8_1[0], 3);
T (&a8_1[i], &a8_1[0], 4);
T (&a8_1[i], &a8_1[0], 5); /* { dg-warning "accessing 5 bytes at offsets \\\[0, 8] and 0 overlaps between 2 and 5 bytes at offset \\\[0, 3\\\]" } */
T (&a8_1[i], &a8_1[0], 6); /* { dg-warning "accessing 6 bytes at offsets \\\[0, 8] and 0 overlaps between 4 and 6 bytes at offset \\\[0, 2\\\]" } */
T (&a8_1[i], &a8_1[0], 7); /* { dg-warning "accessing 7 bytes at offsets \\\[0, 8] and 0 overlaps between 6 and 7 bytes at offset \\\[0, 1\\\]" } */
T (&a8_1[i], &a8_1[0], 8); /* { dg-warning "accessing 8 bytes at offsets \\\[0, 8] and 0 overlaps 8 bytes at offset 0" } */
/* The following is diagnosed by -Warray-bounds when it's enabled
rather than by -Wrestrict. */
T (&a8_1[i], &a8_1[0], 9); /* { dg-warning "accessing 9 bytes at offsets \\\[0, 8] and 0 overlaps 9 bytes at offset 0" } */
/* Same as above but with constant destination index and variable
source index. */
T (&a8_1[0], &a8_1[i], 1);
T (&a8_1[0], &a8_1[i], 2);
T (&a8_1[0], &a8_1[i], 3);
T (&a8_1[0], &a8_1[i], 4);
T (&a8_1[0], &a8_1[i], 5); /* { dg-warning "accessing 5 bytes at offsets 0 and \\\[0, 8] overlaps between 2 and 5 bytes at offset \\\[0, 3\\\]" } */
T (&a8_1[0], &a8_1[i], 6); /* { dg-warning "accessing 6 bytes at offsets 0 and \\\[0, 8] overlaps between 4 and 6 bytes at offset \\\[0, 2\\\]" } */
T (&a8_1[0], &a8_1[i], 7); /* { dg-warning "accessing 7 bytes at offsets 0 and \\\[0, 8] overlaps between 6 and 7 bytes at offset \\\[0, 1\\\]" } */
T (&a8_1[0], &a8_1[i], 8); /* { dg-warning "accessing 8 bytes at offsets 0 and \\\[0, 8] overlaps 8 bytes at offset 0" } */
T (&a8_1[0], &a8_1[i], 9); /* { dg-warning "accessing 9 bytes at offsets 0 and \\\[0, 8] overlaps 9 bytes at offset 0" } */
/* Variable destination and source indices. */
T (&a8_1[i], &a8_1[j], 1);
T (&a8_1[i], &a8_1[j], 2);
T (&a8_1[i], &a8_1[j], 3);
T (&a8_1[i], &a8_1[j], 4);
T (&a8_1[i], &a8_1[j], 5); /* { dg-warning "accessing 5 bytes at offsets \\\[0, 8] and \\\[0, 8] overlaps between 2 and 5 bytes at offset \\\[0, 3\\\]" } */
T (&a8_1[i], &a8_1[j], 6); /* { dg-warning "accessing 6 bytes at offsets \\\[0, 8] and \\\[0, 8] overlaps between 4 and 6 bytes at offset \\\[0, 2\\\]" } */
T (&a8_1[i], &a8_1[j], 7); /* { dg-warning "accessing 7 bytes at offsets \\\[0, 8] and \\\[0, 8] overlaps between 6 and 7 bytes at offset \\\[0, 1\\\]" } */
T (&a8_1[i], &a8_1[j], 8); /* { dg-warning "accessing 8 bytes at offsets \\\[0, 8] and \\\[0, 8] overlaps 8 bytes at offset 0" } */
/* The following is diagnosed by -Warray-bounds when it's enabled
rather than by -Wrestrict. */
T (&a8_1[i], &a8_1[j], 9); /* { dg-warning "accessing 9 bytes at offsets \\\[0, 8] and \\\[0, 8] overlaps 9 bytes at offset 0" } */
}
struct S4 { char a4[4]; } a2_4[2];
void test_2_dim (int i, int j)
{
T (&a2_4[i], &a2_4[0], 1);
T (&a2_4[i], &a2_4[0], 4);
T (&a2_4[i], &a2_4[0], 5); /* { dg-warning "accessing 5 bytes at offsets \\\[0, 8] and 0 overlaps between 2 and 5 bytes at offset \\\[0, 3]" } */
T (&a2_4[i], &a2_4[0], 6); /* { dg-warning "accessing 6 bytes at offsets \\\[0, 8] and 0 overlaps between 4 and 6 bytes at offset \\\[0, 2]" } */
T (&a2_4[i], &a2_4[0], 7); /* { dg-warning "accessing 7 bytes at offsets \\\[0, 8] and 0 overlaps between 6 and 7 bytes at offset \\\[0, 1]" } */
T (&a2_4[i], &a2_4[0], 8); /* { dg-warning "accessing 8 bytes at offsets \\\[0, 8] and 0 overlaps 8 bytes at offset 0" } */
T (a2_4[i].a4, a2_4[0].a4, 1);
T (a2_4[i].a4, a2_4[0].a4, 4);
T (a2_4[i].a4, a2_4[0].a4, 5); /* { dg-warning "accessing 5 bytes at offsets \\\[0, 8] and 0 overlaps between 2 and 5 bytes at offset \\\[0, 3]" } */
T (a2_4[i].a4, a2_4[0].a4, 8); /* { dg-warning "accessing 8 bytes at offsets \\\[0, 8] and 0 overlaps 8 bytes at offset 0" } */
T (a2_4[i].a4, a2_4[j].a4, 1);
T (a2_4[i].a4, a2_4[j].a4, 4);
/* The destination and source offsets printed below ignore the size
of the copy and only indicate the values that are valid for each
of the destination and source arguments on its own, without
considering the size of the overlapping access. */
T (a2_4[i].a4, a2_4[j].a4, 5); /* { dg-warning "accessing 5 bytes at offsets \\\[0, 8] and \\\[0, 8] overlaps between 2 and 5 bytes at offset \\\[0, 3]" } */
T (a2_4[i].a4, a2_4[j].a4, 8); /* { dg-warning "accessing 8 bytes at offsets \\\[0, 8] and \\\[0, 8] overlaps 8 bytes at offset 0" } */
/* Same as above but referencing the first elements of each array. */
T (&a2_4[i].a4[0], &a2_4[j].a4[0], 1);
T (&a2_4[i].a4[0], &a2_4[j].a4[0], 4);
T (&a2_4[i].a4[0], &a2_4[j].a4[0], 5); /* { dg-warning "accessing 5 bytes at offsets \\\[0, 8] and \\\[0, 8] overlaps between 2 and 5 bytes at offset \\\[0, 3]" } */
T (&a2_4[i].a4[0], &a2_4[j].a4[0], 8); /* { dg-warning "accessing 8 bytes at offsets \\\[0, 8] and \\\[0, 8] overlaps 8 bytes at offset 0" } */
T (&a2_4[i].a4[0], &a2_4[j].a4[1], 3);
T (&a2_4[i].a4[0], &a2_4[j].a4[2], 2);
T (&a2_4[i].a4[0], &a2_4[j].a4[3], 1);
}
struct { int i; } a2[2][8];
void test_single_2_dim_major (int i)
{
memcpy (&a2[i], &a2[0], sizeof *a2); /* { dg-bogus "\\\[-Wrestrict]" } */
}
void test_single_2_dim_minor (int i)
{
memcpy (&a2[i][0], &a2[0][0], sizeof a2[0][0]); /* { dg-bogus "\\\[-Wrestrict]" } */
}
void test_single_2_dim_major_minor (int i, int j)
{
memcpy (&a2[i][j], &a2[0][0], sizeof a2[0][0]); /* { dg-bogus "\\\[-Wrestrict]" } */
}
/* PR tree-optimization/84095 - false-positive -Wrestrict warnings for
strcpy within array
{ dg-do compile }
{ dg-options "-O2 -Wrestrict -ftrack-macro-expansion=0" } */
typedef __SIZE_TYPE__ size_t;
extern void* memcpy (void* restrict, const void* restrict, size_t);
extern char* strcpy (char* restrict, const char* restrict);
#define T(d, s) strcpy (d, s)
struct MemArrays {
char pad[8];
char a2[3][9];
char a3[3][4][9];
} a[2];
struct NestedMemArrays {
struct MemArrays ma;
struct MemArrays ma1[2];
} nma[2];
/* Use a variable as the source of a copy to verify that VAR_DECL
is handled correctly when it's the source of GIMPLE assignment. */
const char *str = "1234567";
void test_obj_2_dim_const (void)
{
const char *s = strcpy (a[0].a2[0], "1234567");
T (a[0].a2[1], s);
T (a[0].a2[2], s);
/* Ideally, the offsets in the warning below would be relative to
the beginning of the accessed array member. Unfortunately, when
the offset is represented as
MEM_REF (char[9], A, offsetof (struct MemArrays, A[0].A2[0]) + 1)
as it is in this instance it's difficult to determine the member
that is being accessed and tease out from the MEM_REF the offset
as it appears in the source. As a result, the warning mentions
the offset from the beginning of A instead. This is suboptimal
and should be fixed, either by printing the correct offsets or
by mentioning the base object that the offset is relative to. */
T (a[0].a2[0] + 1, s); /* { dg-warning "accessing 8 bytes at offsets \(1|9\) and \(0|8\) overlaps 7 bytes at offset \(1|9\)." } */
T (a[0].a2[1] + 2, s);
T (a[0].a2[2] + 3, s);
T (a[1].a2[0], s);
T (a[1].a2[1], s);
T (a[1].a2[2], s);
T (a[1].a2[0] + 1, s);
T (a[1].a2[1] + 2, s);
T (a[1].a2[2] + 3, s);
}
void test_obj_nested_2_dim_const (void)
{
const char *s = strcpy (nma[0].ma.a2[0], str);
T (nma[0].ma.a2[1], s);
T (nma[0].ma.a2[2], s);
T (nma[0].ma.a2[0] + 1, s); /* { dg-warning "accessing 8 bytes at offsets 1 and 0 overlaps 7 bytes at offset 1" "bug " { xfail *-*-* } } */
T (nma[0].ma.a2[1] + 2, s);
T (nma[0].ma.a2[2] + 3, s);
T (nma[1].ma.a2[1], s);
T (nma[1].ma.a2[2], s);
T (nma[1].ma.a2[0] + 1, s);
T (nma[1].ma.a2[1] + 2, s);
T (nma[1].ma.a2[2] + 3, s);
T (nma[0].ma1[0].a2[1], s);
T (nma[0].ma1[0].a2[2], s);
T (nma[0].ma1[0].a2[0] + 1, s);
T (nma[0].ma1[0].a2[1] + 2, s);
T (nma[0].ma1[0].a2[2] + 3, s);
T (nma[1].ma1[0].a2[1], s);
T (nma[1].ma1[0].a2[2], s);
T (nma[1].ma1[0].a2[0] + 1, s);
T (nma[1].ma1[0].a2[1] + 2, s);
T (nma[1].ma1[0].a2[2] + 3, s);
}
void test_obj_2_dim_var (int i, int j)
{
const char *s = memcpy (a[0].a2[0], "1234567", 8);
T (a[i].a2[0], s); /* { dg-bogus "\\\[-Wrestrict]" } */
T (a[i].a2[1], s);
T (a[i].a2[2], s);
T (a[i].a2[0] + 1, s);
T (a[i].a2[1] + 1, s);
T (a[i].a2[2] + 1, s);
T (a[0].a2[i], s); /* { dg-bogus "\\\[-Wrestrict]" } */
T (a[1].a2[i], s);
T (a[i].a2[0] + j, s);
T (a[i].a2[1] + j, s);
T (a[i].a2[2] + j, s);
T (a[0].a2[i] + 1, s);
T (a[1].a2[i] + 1, s);
T (a[0].a2[i] + j, s);
T (a[1].a2[i] + j, s);
if (i < 0 || 1 < i)
i = 1;
T (a[i].a2[0], s);
T (a[i].a2[1], s);
T (a[i].a2[2], s);
T (a[i].a2[0] + 1, s);
T (a[i].a2[1] + 1, s);
T (a[i].a2[2] + 1, s);
T (a[0].a2[i], s);
T (a[1].a2[i], s);
T (a[i].a2[0] + j, s);
T (a[i].a2[1] + j, s);
T (a[i].a2[2] + j, s);
T (a[0].a2[i] + 1, s);
T (a[1].a2[i] + 1, s);
T (a[0].a2[i] + j, s);
T (a[1].a2[i] + j, s);
}
void test_obj_nested_2_dim_var (int i, int j)
{
const char *s = strcpy (nma[0].ma.a2[0], "1234567");
T (nma[i].ma.a2[0], s); /* { dg-bogus "\\\[-Wrestrict]" } */
T (nma[i].ma.a2[1], s);
T (nma[i].ma.a2[2], s);
T (nma[i].ma.a2[0] + 1, s);
T (nma[i].ma.a2[1] + 1, s);
T (nma[i].ma.a2[2] + 1, s);
T (nma[0].ma.a2[i], s); /* { dg-bogus "\\\[-Wrestrict]" } */
T (nma[1].ma.a2[i], s);
T (nma[i].ma.a2[0] + j, s);
T (nma[i].ma.a2[1] + j, s);
T (nma[i].ma.a2[2] + j, s);
T (nma[0].ma.a2[i] + 1, s);
T (nma[1].ma.a2[i] + 1, s);
T (nma[0].ma.a2[i] + j, s);
T (nma[1].ma.a2[i] + j, s);
}
void test_ref_2_dim_const (struct MemArrays *p)
{
strcpy (p[0].a2[0], "1234567");
const char *s = p[0].a2[0];
T (p[0].a2[1], s);
T (p[0].a2[2], s);
T (p[1].a2[0], s);
T (p[1].a2[1], s);
T (p[1].a2[2], s);
}
void test_ref_2_dim_var (struct MemArrays *p, int i, int j)
{
strcpy (p[0].a2[0], "1234567");
const char *s = p[0].a2[0];
T (p[i].a2[0], s); /* { dg-bogus "\\\[-Wrestrict]" } */
T (p[i].a2[1], s);
T (p[i].a2[2], s);
T (p[0].a2[i], s);
T (p[1].a2[i], s);
T (p[i].a2[0] + j, s);
T (p[i].a2[1] + j, s);
T (p[i].a2[2] + j, s);
T (p[0].a2[i] + j, s);
T (p[1].a2[i] + j, s);
}
void test_obj_3_dim_var (int i, int j)
{
strcpy (a[0].a3[0][0], "1234567");
const char *s = a[0].a3[0][0];
T (a[0].a3[0][i], s);
T (a[0].a3[1][i], s);
T (a[0].a3[2][i], s);
T (a[1].a3[0][i], s);
T (a[1].a3[1][i], s);
T (a[1].a3[2][i], s);
T (a[0].a3[i][0], s); /* { dg-bogus "\\\[-Wrestrict\]" } */
T (a[0].a3[i][1], s);
T (a[0].a3[i][2], s);
T (a[1].a3[i][0], s);
T (a[1].a3[i][1], s);
T (a[1].a3[i][2], s);
T (a[i].a3[0][0], s); /* { dg-bogus "\\\[-Wrestrict\]" } */
T (a[i].a3[0][1], s);
T (a[i].a3[0][2], s);
T (a[i].a3[1][0], s);
T (a[i].a3[1][1], s);
T (a[i].a3[1][2], s);
T (a[i].a3[2][0], s);
T (a[i].a3[2][1], s);
T (a[i].a3[2][2], s);
T (a[0].a3[0][i] + 1, s);
T (a[0].a3[1][i] + 1, s);
T (a[0].a3[2][i] + 1, s);
T (a[1].a3[0][i] + 1, s);
T (a[1].a3[1][i] + 1, s);
T (a[1].a3[2][i] + 1, s);
T (a[0].a3[0][i] + j, s);
T (a[0].a3[1][i] + j, s);
T (a[0].a3[2][i] + j, s);
T (a[1].a3[0][i] + j, s);
T (a[1].a3[1][i] + j, s);
T (a[1].a3[2][i] + j, s);
T (a[0].a3[i][0] + j, s);
T (a[0].a3[i][1] + j, s);
T (a[0].a3[i][2] + j, s);
T (a[1].a3[i][0] + j, s);
T (a[1].a3[i][1] + j, s);
T (a[1].a3[i][2] + j, s);
T (a[i].a3[0][0] + j, s);
T (a[i].a3[0][1] + j, s);
T (a[i].a3[0][2] + j, s);
T (a[i].a3[1][0] + j, s);
T (a[i].a3[1][1] + j, s);
T (a[i].a3[1][2] + j, s);
T (a[i].a3[2][0] + j, s);
T (a[i].a3[2][1] + j, s);
T (a[i].a3[2][2] + j, s);
}
void test_obj_3_dim_const (struct MemArrays *p)
{
strcpy (p[0].a3[0][0], "1234567");
const char *s = p[0].a3[0][0];
T (p[0].a3[0][1], s);
T (p[0].a3[0][2], s);
T (p[0].a3[0][3], s);
T (p[0].a3[0][1] + 1, s);
T (p[0].a3[0][2] + 1, s);
T (p[0].a3[0][3] + 1, s);
T (p[0].a3[1][0], s);
T (p[0].a3[1][1], s);
T (p[0].a3[1][2], s);
T (p[0].a3[1][3], s);
T (p[0].a3[1][0] + 1, s);
T (p[0].a3[1][1] + 1, s);
T (p[0].a3[1][2] + 1, s);
T (p[0].a3[1][3] + 1, s);
T (p[0].a3[2][0], s);
T (p[0].a3[2][1], s);
T (p[0].a3[2][2], s);
T (p[0].a3[2][3], s);
T (p[1].a3[0][0], s);
T (p[1].a3[0][1], s);
T (p[1].a3[0][2], s);
T (p[1].a3[0][3], s);
T (p[1].a3[1][0], s);
T (p[1].a3[1][1], s);
T (p[1].a3[1][2], s);
T (p[1].a3[1][3], s);
T (p[1].a3[2][0], s);
T (p[1].a3[2][1], s);
T (p[1].a3[2][2], s);
T (p[1].a3[2][3], s);
}
/* PR tree-optimization/84095 - false-positive -Wrestrict warnings for
memcpy within array
{ dg-do compile }
{ dg-options "-O2 -Wrestrict" } */
struct { int i; } a[8];
void f (void)
{
int i;
for (i = 1; i < 8; i++)
__builtin_memcpy (&a[i], &a[0], sizeof(a[0])); /* { dg-bogus "\\\[-Wrestrict]" } */
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment