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

--- Comment #43 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Andrew Haley from comment #42)
> On 04/29/2018 05:42 PM, rguenther at suse dot de wrote:>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65892
> > 
> > --- Comment #41 from rguenther at suse dot de <rguenther at suse dot de> ---
> > On April 29, 2018 1:51:58 PM GMT+02:00, "aph at gcc dot gnu.org"
> > <gcc-bugzi...@gcc.gnu.org> wrote:
> >> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65892
> >>
> >> --- Comment #40 from Andrew Haley <aph at gcc dot gnu.org> ---
> >> (In reply to rguent...@suse.de from comment #29)
> >>
> >>> Note I repeatedly said this part of the standard is just stupid.  It
> >> makes
> >>> most if not all type-based alias analysis useless.
> >>
> >> I don't think so.  It does mean that we'd have to feed all declared
> >> union types (or, at least the ones containing structs with common
> >> initial sequences) into the alias oracle.  While unpleasant, in that
> >> simply declaring a type without even declaring an object of that type
> >> changes code generation, it doesn't render all type-based alias
> >> analysis useless.
> > 
> > How do you handle this within the LTO framework?
> 
> In order to use type-based alias analysis in any LTO framework it's
> necessary to save type information, and this is just more type
> information.  The question is, I suppose, how to handle the scopes of
> union declarations.  I'd just treat them as being global, which in
> practice isn't unrealistic because such declarations are in header
> files in global scope and shared anyway.
> 
> So, if any union types with a common initial sequence are declared
> anywhere in a program, then their member types alias.  Alternatively,
> a tighter implementation might restrict such declarations to a
> compilation unit, in which case the alias oracle would scan only the
> union types declared in that unit.

So for the middle-end the easiest thing would be if the FE would comply
to its existing semantics and for the initial sequences generate a
transparent struct.  Thus,

union {
 struct A { int i; float f; double z; } a;
 struct B { int i; float f; void *p; } b;
};

would cause the FE to "implement" struct A and B like

 struct __init_seq1 { int i; float f; };
 struct A { struct __init_seq1 _transp_memb1; double z; } a;
 struct B { struct __init_seq1 _transp_memb2; void *p; } b;

then everything would work as expected from an aliasing point of view.
The difficulty is probably that argument passing of A and B might
change depending on how the ABIs are defined and how the backend handles
those wrapping structs.

But as you can clearly see the above would be also a way for the user
to get what the clause permits without the clause being present.  So
I'm not sure why this clause was added.

> >>> Which means I'll refuse any patches implementing it in a way that
> >>> affects default behavior.
> >>
> >> Maybe --pedantic or even --pedantic-aliasing?
> > 
> > Whatever you call it I doubt any working solution will fit nicely
> > into our existing TBAA framework.
> 
> Well, perhaps not, but this is the language specification.

language specifications have defects ...

> > When I read the language text then a union declaration in between
> > two accesses will change the semantic of the second?
> 
> Not necessarily.  It would be correct to collect all union
> declarations at the end of parsing and then use those to feed the
> alias oracle.  There's no actual need to restrict their scope.  Sure,
> it would lead to GCC being somewhat over-cautious, but that's OK.

given the TBAA oracle is filled on-demand it is important that both
outcomes are allowed.  I still don't see how we can make it work easily
in the middle-end.

For anyone wanting to make GCC comply I suggest the above sketched route
and start with looking how backends deal with this kind of wrapping in
their argument passing.

Reply via email to