blob: b2321495afcebf41dfa3e753a6299953b3d0b8fc [file] [log] [blame]
/* Test to verify that -Wzero-length-bounds and not -Warray-bounds is
issued for accesses to interior zero-length array members that are
within the bounds of the enclosing struct.
{ dg-do compile }
{ dg-options "-O2 -Wall" } */
void sink (void*);
struct A { int i; };
struct B { int j; struct A a[0]; };
struct C
{
struct B b1;
struct B b2;
};
void test_B_ref (struct B *p)
{
// References with negative indices are always diagnosed by -Warray-bounds
// even though they could be considered the same as past the end accesses
// to trailing zero-length arrays.
p->a[-1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
p->a[ 0].i = 0;
p->a[ 1].i = 0;
sink (p);
p[1].a[-1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
p[1].a[ 0].i = 0;
p[1].a[ 1].i = 0;
}
void test_C_ref (struct C *p)
{
p->b1.a[-1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
p->b1.a[ 0].i = 0; // { dg-warning "\\\[-Wzero-length-bounds" }
p->b1.a[ 1].i = 0; // { dg-warning "\\\[-Wzero-length-bounds" }
// Accesses to trailing zero-length arrays are not diagnosed (should
// they be?)
p->b2.a[ 0].i = 0;
p->b2.a[ 9].i = 0;
}
void test_C_decl (void)
{
struct C c, *p = &c;
p->b1.a[-1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
// c.b1.a[0].i overlaps c.b2.j.
p->b1.a[ 0].i = 0; // { dg-warning "\\\[-Wzero-length-bounds" }
// c.b1.a[1].i is past the end of c...
p->b1.a[ 1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
sink (p);
// ...and so are references to all elements of c.b2.a
p->b2.a[ 0].i = 0; // { dg-warning "\\\[-Warray-bounds" }
p->b2.a[ 1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
sink (p);
}
char cbuf1[1 * sizeof (struct C)];
char cbuf2[2 * sizeof (struct C)] = { };
void test_C_global_buf (void)
{
struct C *p = (struct C*)&cbuf1;
p->b1.a[-1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
p->b1.a[ 0].i = 0; // { dg-warning "\\\[-Wzero-length-bounds" }
p->b1.a[ 1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
sink (p);
p->b2.a[ 0].i = 0; // { dg-warning "\\\[-Warray-bounds" }
p->b2.a[ 1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
sink (p);
p = (struct C*)&cbuf2;
p->b1.a[-1].i = 0; // { dg-warning "\\\[-Warray-bounds" }
p->b1.a[ 0].i = 0; // { dg-warning "\\\[-Wzero-length-bounds" }
p->b1.a[ 1].i = 0; // { dg-warning "\\\[-Wzero-length-bounds" }
sink (p);
p->b2.a[ 0].i = 0; // { dg-warning "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v2si_store && { ! vect_slp_v4si_store } } } }
p->b2.a[ 1].i = 0;
p->b2.a[ 2].i = 0; // { dg-warning "\\\[-Warray-bounds" }
p->b2.a[ 3].i = 0; // { dg-warning "\\\[-Warray-bounds" }
sink (p);
}
void test_C_local_buf (void)
{
char cbuf1[1 * sizeof (struct C)] = "";
char cbuf2[2 * sizeof (struct C)] = { };
struct C *p = (struct C*)&cbuf1;
p->b1.a[-1].i = 1; // { dg-warning "\\\[-Warray-bounds" }
p->b1.a[ 0].i = 2; // { dg-warning "\\\[-Wzero-length-bounds" }
p->b1.a[ 1].i = 3; // { dg-warning "\\\[-Warray-bounds" }
sink (p);
p->b2.a[ 0].i = 4; // { dg-warning "\\\[-Warray-bounds" }
p->b2.a[ 1].i = 5; // { dg-warning "\\\[-Warray-bounds" }
sink (p);
p = (struct C*)&cbuf2;
p->b1.a[-1].i = 6; // { dg-warning "\\\[-Warray-bounds" }
p->b1.a[ 0].i = 7; // { dg-warning "\\\[-Wzero-length-bounds" }
p->b1.a[ 1].i = 8; // { dg-warning "\\\[-Wzero-length-bounds" }
sink (p);
p->b2.a[ 0].i = 9;
p->b2.a[ 1].i = 10;
p->b2.a[ 2].i = 11; // { dg-warning "\\\[-Warray-bounds" }
p->b2.a[ 3].i = 12; // { dg-warning "\\\[-Warray-bounds" }
sink (p);
}