I was wondering if someone could help me understand a bug involving
aliasing, this is happening on aarch64 but I don't think it is architecure
specific. The problem involves flexible arrays vs. zero sized arrays at
the end of a structure.
In the original code, a zero size array is used and the program does not
behave correctly, if the zero sized array is changed to a C99 flexible
array it does work. Are there any reasons why a zero-size array and
a flexible array should behave differently?
I was able to cut the test case down into the attached (non-runnable) test
case which when compiled with -O2 for aarch64 generates different code
with -DFLEX and -UFLEX. In the code for the main loop GCC generates a
ldr/str/ldr/str sequence (with other instructions) when using a flexible
array and a ldr/ldr/str/str sequence when using a zero size array. Moving
the second ldr ahead of the first str is what is causing the problem in the
original test case.
I have tracked the change in behaviour to differences in alias analysis
and to the get_ref_base_and_extent routine in tree-dfa.c and it looks
like the 'tree exp' argument is different between the two versions but
I am not sure if it should be different and, if the difference is OK,
should that affect how get_ref_base_and_extent behaves, as it apparently
does.
Steve Ellcey
sell...@cavium.com
Test case, compiling with '-O2 -DFLEX' generates different code than
'-O2 -UFLEX' on aarch64 using ToT GCC. A cross compiler built on x86
can reproduce the problem too.
---
struct q {
int b;
};
struct r {
int n;
struct q slot[0];
};
struct s {
int n;
#ifdef FLEX
long int o[];
#else
long int o[0];
#endif
};
extern int x, y, m;
extern struct s *a;
extern struct r *b;
extern void bar();
int foo() {
int i,j;
for (i = 0; i < m; i++) {
a->o[i] = sizeof(*a);
b = ((struct r *)(((char *)a) + a->o[a->n]));
for (j = 0; j < 10; j++) {
b->slot[j].b = 0;
}
bar();
}
}