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