This is the mail archive of the gcc-bugs@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]

[Bug c/70166] Wrong optimization of type punning in unions with 2d array


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70166

--- Comment #2 from Alexander Cherepanov <ch3root at openwall dot com> ---
On 03/11/2016 12:16 PM, rguenth at gcc dot gnu.org wrote:
> You are not accessing through the union type but through a pointer to double
> and int because u.a and p->d decay to a pointer:
>
>    *(int *) &u.a = 1;
>    *(double *) &p->d = 0.0;
>    if (*(int *) &u.a != 0)
>      {
>        abort ();

This is true but I'm afraid it doesn't explain anything.

First of all, some data points:
- the example works fine with 1d array;
- the example works fine with **u.a replaced by u.a[0][0], *u.a[0] or 
(*u.a)[0];
- the example fails in the same way with u.a and p->d wrapped in structs.

In all these cases u.a and p->d decay to a pointer too but gcc does the 
right thing anyway. Furthermore, saying that the problem is in 
array-to-pointer decay means that arrays inside unions (including 
recursively) cannot be accessed directly at all (they would work only 
wrapped in structs and copied in and out inside these structs). I guess 
this is not intended and arrays inside unions are supposed to work somehow.

Ok, let's change if to "if (**u.a != (*u.a)[0])" and do -fdump-tree-all. 
In 003t.original we have this:

   *(int *) &u.a = 1;
   *(double *) &p->d = 0.0;
   if (*(int *) &u.a != (*(int[1] *) &u.a)[0])
     {
       abort ();

and in 004t.gimple we have this:

         D.1636 = &u.a;
         D.1639 = MEM[(int *)D.1636];
         D.1640 = u.a[0][0];
         if (D.1639 != D.1640) goto <D.1641>; else goto <D.1642>;
         <D.1641>:
         abort ();

It seems the general direction is to convert * to [] but gcc fails to 
convert **. Different treatment of **x and x[0][0] is not limited to 
unions in any way. In other cases I guess it will just prevent some 
optimizations but with unions it has a user-visible effect.

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