154 lines
5.5 KiB
C
154 lines
5.5 KiB
C
/* PR middle-end/103215 - bogus -Wstringop-overflow with two pointers with
|
|
different offsets each
|
|
Test for accesses into distinct arrays through pointers with different
|
|
offsets each.
|
|
|
|
If/when -Wstringop-overflow is enhanced to issue "maybe" kinds of
|
|
warnings some of the accesses here will trigger those and will need
|
|
updating.
|
|
|
|
{ dg-do compile }
|
|
{ dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
|
|
|
|
#define NOIPA __attribute__ ((noipa))
|
|
|
|
void sink (int[1]);
|
|
#define A(p, off) sink (p + off)
|
|
|
|
extern int a4[4], a8[8];
|
|
|
|
|
|
|
|
|
|
NOIPA void a4_p1_a8_p3 (int i)
|
|
{
|
|
int *a4_p1 = a4 + 1;
|
|
int *a8_p3 = a8 + 3;
|
|
int *q = i ? a4_p1 : a8_p3;
|
|
A (q, -4); // { dg-warning "-Wstringop-overflow" }
|
|
/* Because -3 is a valid offset into a8 but not a4, q must point
|
|
to the former and so subscripts between -3 and +4 refer to its
|
|
elements. */
|
|
A (q, -3); A (q, -2); A (q, -1); A (q, 0);
|
|
A (q, 1); A (q, 2); A (q, 3); A (q, 4);
|
|
A (q, 5); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
/* Both of the following are definitely out of bounds but the first isn't
|
|
diagnosed because the code conservatively merges the offsets into A4
|
|
and A8. */
|
|
A (q, 7); // { dg-warning "-Wstringop-overflow" }
|
|
}
|
|
|
|
|
|
NOIPA void a4_p1_a8_p5 (int i)
|
|
{
|
|
int *a4_p1 = a4 + 1;
|
|
int *a8_p5 = a8 + 5;
|
|
int *q = i ? a4_p1 : a8_p5;
|
|
A (q, -6); // { dg-warning "-Wstringop-overflow" }
|
|
/* Similarly to the above, because -5 is a valid offset into a8 but
|
|
not a4, q must point to the former and so subscripts between -5
|
|
and +2 refer to its elements. */
|
|
A (q, -5); A (q, -4); A (q, -3); A (q, -2);
|
|
A (q, -1); A (q, 0); A (q, 1); A (q, 2);
|
|
A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 7); // { dg-warning "-Wstringop-overflow" }
|
|
}
|
|
|
|
|
|
NOIPA void a4_p1_a8_p7 (int i)
|
|
{
|
|
int *a4_p1 = a4 + 1;
|
|
int *a8_p7 = a8 + 7;
|
|
int *q = i ? a4_p1 : a8_p7;
|
|
A (q, -8); // { dg-warning "-Wstringop-overflow" }
|
|
A (q, -7); A (q, -6); A (q, -5); A (q, -4);
|
|
A (q, -3); A (q, -2); A (q, -1); A (q, 0);
|
|
/* Since -7 is valid, q must point to a8 and the last valid subscript
|
|
must be 0. */
|
|
A (q, 1); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 7); // { dg-warning "-Wstringop-overflow" }
|
|
}
|
|
|
|
|
|
NOIPA void mp_1_a4_p1_a8_p7 (int i, int j)
|
|
{
|
|
int *a4_p1 = a4 + 1;
|
|
int *a8_p7 = a8 + 7;
|
|
int *p = i ? a4_p1 : a8_p7;
|
|
int *q = j ? p + 1 : p - 1;
|
|
|
|
A (q, -9); // { dg-warning "-Wstringop-overflow" }
|
|
|
|
/* q points either to a8 + [6, 8] or a4 + [0, 2]. */
|
|
A (q, -8); A (q, -7); A (q, -6); A (q, -5);
|
|
A (q, -4); A (q, -3); A (q, -2); A (q, -1);
|
|
|
|
/* Since all the above are valid, q must point to a8 + 8. But as
|
|
mentioned above, the warning for each subscript is independent
|
|
of prior subscripts into the same object so the access below
|
|
aren't diagnosed. */
|
|
A (q, 0); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 1); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 4); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 8); // { dg-warning "-Wstringop-overflow" }
|
|
}
|
|
|
|
|
|
NOIPA void mp1_a4_p1_a8_p5 (int i, int j)
|
|
{
|
|
int *a4_p1 = a4 + 1;
|
|
int *a8_p5 = a8 + 5;
|
|
int *p = i ? a4_p1 : a8_p5;
|
|
|
|
int *q = j ? p + 1 : p - 1;
|
|
|
|
// q is assumed to point to a8 + 6
|
|
A (q, -7); // { dg-warning "-Wstringop-overflow" }
|
|
A (q, -6); A (q, -5); A (q, -4); A (q, -3);
|
|
A (q, -2); A (q, -1); A (q, 0); A (q, 1);
|
|
/* Even though the above accesses rule it out, q is now assumed
|
|
to point to either a4 + [0, 2] or a8 + [4, 5]. */
|
|
A (q, 2);
|
|
/* q is now assumed to point tp a4. Given that, only the first store
|
|
is valid. */
|
|
A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 4); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 5); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 6); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 7); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 8); // { dg-warning "-Wstringop-overflow" }
|
|
}
|
|
|
|
|
|
NOIPA void mp1_a4_p1_a8_p4 (int i, int j)
|
|
{
|
|
int *a4_p1 = a4 + 1;
|
|
int *a8_p4 = a8 + 4;
|
|
int *p = i ? a4_p1 : a8_p4;
|
|
|
|
int *q = j ? p + 1 : p - 1;
|
|
|
|
// q is assumed to point to a8 + 5
|
|
A (q, -6); // { dg-warning "-Wstringop-overflow" }
|
|
A (q, -5);
|
|
A (q, -4);
|
|
A (q, -3);
|
|
A (q, -2);
|
|
A (q, -1);
|
|
A (q, 0);
|
|
A (q, 1);
|
|
A (q, 2);
|
|
/* Even though the above accesses rule it out, q is now assumed
|
|
to point tp a4. Given that, only the first store is valid. */
|
|
A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 4); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 5); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 6); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 7); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
|
|
A (q, 8); // { dg-warning "-Wstringop-overflow" }
|
|
}
|