On Mon, Apr 15, 2024 at 08:55:56AM +0200, Richard Biener wrote: > > diff --git a/gcc/ipa-free-lang-data.cc b/gcc/ipa-free-lang-data.cc > > index 16ed55e2e5a..6f75444e513 100644 > > --- a/gcc/ipa-free-lang-data.cc > > +++ b/gcc/ipa-free-lang-data.cc > > @@ -255,7 +255,9 @@ fld_incomplete_type_of (tree t, class free_lang_data_d > > *fld) > > first = build_reference_type_for_mode (t2, TYPE_MODE (t), > > TYPE_REF_CAN_ALIAS_ALL (t)); > > gcc_assert (TYPE_CANONICAL (t2) != t2 > > - && TYPE_CANONICAL (t2) == TYPE_CANONICAL (TREE_TYPE (t))); > > + && (TYPE_CANONICAL (t2) == TYPE_CANONICAL (TREE_TYPE (t)) > > + || TYPE_STRUCTURAL_EQUALITY_P (t2) > > + || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (t)))); > > I think we want the same canonical types for t2 and TREE_TYPE (t), why > doesn't fld_incomplete_type_of make it so?
I had this spot instrumented to log the different cases (before adding the code to fix up also pointer types in c_update_type_canonical) and the only thing that triggered was that the 2 TYPE_CANONICALs weren't equal if TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (t)), the other was just in case. gcc.c-torture/compile/20021205-1.c gcc.c-torture/compile/20040214-2.c gcc.c-torture/compile/20060109-1.c gcc.c-torture/compile/pr113623.c gcc.c-torture/compile/pr46866.c gcc.c-torture/compile/pta-1.c gcc.c-torture/execute/pr33870-1.c gcc.c-torture/execute/pr33870.c gcc.dg/torture/pr57478.c tests were affected in make check-gcc. I thought it would be a clear consequence of the choice we've discussed on IRC, that build_pointer_type_for_mode and other tree.cc functions which lookup/create derived types don't try to fill in TYPE_CANONICAL for types derived from something which initially had TYPE_STRUCTURAL_EQUALITY_P but later changed to non-TYPE_STRUCTURAL_EQUALITY_P. The patch updates it solely for qualified types/related pointer types, but doesn't do that for array types, pointer to array types, function types, ... So, I think the assertion could still trigger if we have something like -O2 -flto -std=c23 struct S; typedef struct S *T; typedef T U[10]; typedef U *V; V foo (int x) { return 0; } struct S { int s; }; (but doesn't, dunno what I'm missing; though here certainly V and U have TYPE_STRUCTURAL_EQUALITY_P, even T has because it is a typedef, not something actually normally returned by build_pointer_type). Jakub