This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Alias analysis and zero-sized arrays vs. flexible arrays


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]