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]

Re: Alias analysis and zero-sized arrays vs. flexible arrays


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


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