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.