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

--- Comment #16 from uecker at gcc dot gnu.org ---
(In reply to Richard Biener from comment #15)
> (In reply to uecker from comment #14)
> > (In reply to Richard Biener from comment #13)
> > > (In reply to uecker from comment #11)


> > > 
> > > But yes, when there are new C standards like C23 changing interoperability
> > > rules a GCC extension needs to be amended to say how it behaves here.  I
> > > would simply say the types covered by the GCC extension are exempt from 
> > > the
> > > C23 tag compatibility rules.
> > 
> > The new C23 tag compatibility rules apply inside one TU only and cross-TU
> > nothing has changed. Across TUs, structurally equivalent types which also
> > have the same tag are already required to be compatible in all previous
> > versions of C and this works correctly in GCC for all structure/union types
> > without GNU extensions. It also works in GCC for structures with GNU
> > extensions and across TUs but only without LTO. 
> > 
> > So the bug here is that LTO - unrelated to C23 - behaves inconsistently for
> > structs with GNU extension relative to  1) non-LTO GCC and 2) to what could
> > be expected from general C rules. Note that we have a similar LTO bug for
> > flexible array members with [] and [0].
> > (for non-LTO it works, of course, because there is no cross-TU TBAA in this
> > case).
> > 
> > So I think the rule how LTO decides to do structural comparison should be
> > changed. 
> 
> LTO only has "rules" for globally visible types.  For local types it simply
> assumes the frontends took care of everything.  LTO doesn't even get to see
> those at unification time.

Can you explain what "globally visible types" are in the context of C? All
types in C have cross-TU structural equivalency (when considering the tag as
part of the strucutre). There is no concept of local of global for types in C.

If "local type" is a type where some size expression depends on a variable, I
do not see where those are treated differently in GCC. The C FE does not
distinguish them and neither does the C standard.

> 
> How does the C frontend handle two such "local" tag equivalent types?  That
> is, how does it "find" them and how does it ensure they are either unified
> or at least have the same TYPE_CANONICAL?

It collects them in a hash table, forms equivalency classes compatible with the
type compatibility rules (which are not transitive), and then assigns the same
TYPE_CANONICAL to all types in the same class. We discussed this previously. 

> 
> Note that LTO ignores TAG differences of global types and unifies solely

Does "unifies" mean "assigns a new TYPE_CANONICAL" ? 

> based on a very weak form of structural equality (I'd have to check the
> exact behavior for VLAs).  See gimple_canonical_types_compatible_p.

Yes, I will look at this. Probably a tweak to this function might be enough.
> 
> > > 
> > > That said - if C23 tag compatibility is something like the C++ ODR then
> > > the frontend could produce a "mangling" (simply the tag name) and direct
> > > the middle-end to handle compatibility that way.  Note that C++ 
> > > specifically
> > > exempts "local" types from the ODR.  I think C is wrong here to not allow
> > > this - it will basically force all structs with that T to be "compatible"
> > > whether or not the types are even structurally related?
> > 
> > The struct have to have the same tag (or both no tag) and must be
> > structurally equivalent. Structs with different tag or which are not
> > structurally equivalent are not compatible. But nothing has changed here
> > with C23 for the cross-TU case, the only question is how the GNU extensions
> > fit in her.
> > 
> > IMHO at least the cases where the arrays are at the end of the struct
> > 
> > struct foo { ...; int x[]; }
> > struct foo { ...; int x[0]; };
> > struct foo { ...; int x[n]; };
> > 
> > should all be treated as compatible for TBAA purposes. 
> > 
> > The case where there is a VLA in the middle of a struct
> > 
> > struct foo { int x[n]; ... };
> > 
> > it also would be good if this worked. But those are very obscure.
> 
> So a pragmatic "solution" would be to get all affected types alias set zero.

I think the problem with alias set zero might be that this is not enough
to allow derived types to alias, e.g. pointers to such structs, or functions
returning them. Or?

> 
> I'll note that in case a type is defined locally and is not VLA LTO
> treats it as local as well (or at least it would be free to do so).
> 
> I'll also note there are some existing LTO issues around VLA types
> when they are refered to by function argument or return types.

I think I filed some bugs.  For function types the solution is probably to set
TYPE_CANONICAL in the FE similar to what we do for structs.

Martin

Reply via email to