blob: 5a83397bd6d7454504eef81dcc3e93174ac9570c [file] [log] [blame]
/* { dg-do run }
* { dg-options "-std=gnu23 -O2" }
*/
/* This test checks that different field offsets imply
* that the types can be assumed not to alias
* and that this is exploited during optimization. */
struct bar0 { int x; int f[3]; int y; };
[[gnu::noinline,gnu::noipa]]
int test_bar0(struct bar0* a, void* b)
{
a->x = 1;
struct bar0 { int x; int f[4]; int y; }* p = b;
p->x = 2;
return a->x;
}
/* While these tests check that different structs with different
* sizes in arrays pointed to by field members can alias,
* even though the types are incompatible. */
struct bar1 { int x; int (*f)[3]; };
[[gnu::noinline,gnu::noipa]]
int test_bar1(struct bar1* a, void* b)
{
a->x = 1;
struct bar1 { int x; int (*f)[3]; }* p = b;
p->x = 2;
return a->x;
}
struct bar2 { int x; int (*f)[3]; };
[[gnu::noinline,gnu::noipa]]
int test_bar2(struct bar2* a, void* b)
{
a->x = 1;
struct bar2 { int x; int (*f)[4]; }* p = b;
p->x = 2;
return a->x;
}
/* This test checks that different structs with pointers to
* different compatible arrays types can alias. */
struct bar3 { int x; int (*f)[3]; };
[[gnu::noinline,gnu::noipa]]
int test_bar3(struct bar3* a, void* b)
{
a->x = 1;
struct bar3 { int x; int (*f)[]; }* p = b;
p->x = 2;
return a->x;
}
int main()
{
// control
struct bar0 z0;
if (1 != test_bar0(&z0, &z0))
__builtin_abort();
// this could be different
struct bar1 z1;
if (2 != test_bar1(&z1, &z1))
__builtin_abort();
struct bar2 z2;
if (2 != test_bar2(&z2, &z2))
__builtin_abort();
struct bar3 z3;
if (2 != test_bar3(&z3, &z3))
__builtin_abort();
return 0;
}