This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Alias analysis and zero-sized arrays vs. flexible arrays
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: sellcey at cavium dot com
- Cc: GCC Development <gcc at gcc dot gnu dot org>
- Date: Tue, 25 Apr 2017 12:53:58 +0200
- Subject: Re: Alias analysis and zero-sized arrays vs. flexible arrays
- Authentication-results: sourceware.org; auth=none
- References: <201704242306.v3ON6iSI022843@sellcey-dt.caveonetworks.com>
On Tue, Apr 25, 2017 at 1:06 AM, Steve Ellcey <sellcey@cavium.com> wrote:
> 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;
in case b->slot[j].b aliases a->o[i] or a->o[a->n]
you invoke undefined behavior becuase you violate
strict aliasing rules. I don't know why there's a
difference between -DFLEX and -UFLEX but your
code is buggy even if it works in one case.
Richard.
> }
> bar();
> }
> }