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(); } }