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

--- Comment #60 from Andrew Haley <aph at gcc dot gnu.org> ---
(In reply to James Kuyper Jr. from comment #51)
> (In reply to Andrew Haley from comment #49)
> > (In reply to James Kuyper Jr. from comment #46)
> > 
> > The principle of type-based alias analysis is that all you know about
> > two types is their types, not the location of any code that uses them.
> > There are no scopes.  The oracle, given only the types, has to say
> > whether they alias or not, regardless of where those types are used in
> > a program.  The location isn't an input to the oracle.
> > 
> > Bear in mind that inlining and other kinds of code motion happen, and
> > code is often evaluated "outside" the scopes in which it was written
> > and in a completely different order.  That's all perfectly normal
> > optimization.
> > 
> > Besides, when the alias oracle is consulted, all that scope stuff has
> > gone.  It's only relevant to the front end.
> 
> I was only pointing out that implementing this special guarantee where it
> applies, and only where it applies, requires keeping information that must
> already have been collected. If the current design discards that information
> before performing the relevant optimizations, I can understand that this
> would require a significant re-design - but the re-design takes the form of
> saving information already collected, not of collecting additional
> information.

Well, yes, but this is all stuff we already know.  A total redesign of
alias analysis is not going to happen just for this rule.

> > > > So, if any union types with a common initial sequence are declared
> > > > anywhere in a program, then their member types alias.
> > > 
> > > As I understand it, the visibility rule was added specifically for
> > > the purpose of NOT requiring that the entire program be covered by
> > > this exception.
> > 
> > I don't think so.  As I read it, it was a way of declaring to the
> > compiler that they types are intended to alias.
>
> By "the visibility rule", I mean, very specifically, the phrase
> "anywhere that a declaration of the completed type of the union is
> visible". If the intent had been to disable aliasing throughout the
> entire program, that intent could have been expressed by simply
> removing those words entirely; if there was any doubt that people
> would understand the absence of those words correctly, then they
> could have been replaced with the phrase "anywhere, regardless of
> whether or not the completed type of the union was visible". I don't
> see any plausible reason for the committee to write "anywhere that a
> declaration of the completed type of the union is visible", unless
> that phrase was intended to restrict applicability of the special
> guarantee.

And in 1990s compiler technology it might well have been possible to
restrict the effect of this to a single function.  Back then it was
commonplace to parse a function, generate code, and then throw
everything except the code away.  But compiler technology has moved a
long way since then and it is inevitable that if we are to honour N685
we must coarsen the effect of the visibility of the union.

> > > Knowledgeable people writing code intended to take advantage of this
> > > feature of C are likely to carefully place completed declarations of
> > > the union's type so they disable those optimizations only where they
> > > need to be disabled, and to minimize the amount of code where this
> > > exception would unnecessarily disable useful optimizations.
> > 
> > Perhaps so, yes, but in practice it'd be pretty hard to do that.
> > Functions can only be defined in the other scope, and there's no way
> > to undefine a union type. 
> 
> True, but failing to define the union type is quite trivial. If I were
> writing code that used both struct types, but not the union type, and did
> nothing that relied upon the fact that they can alias each other, I would
> simply not #include the header that defines the completed union type,
> #including only the header that defines the struct types.

That'll be fine if you're only compiling a single translation unit at
a time.  If you're using link-time optimization, however, then the
effect of declaring structs in a union will inevitably result in those
structs being treated as aliases for the entire program being linked,
for the simple reason that the alias oracle always returns the same
answer when asked if two types are are aliases.  Therefore, if they're
aliases anywhere they must be aliases everywhere.

Reply via email to