https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114931
--- Comment #12 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Anyway, such changes are a partial shift towards the model to update derived
types which you said you don't want; it doesn't actually update them, but
basically forces new types after the base type(s) is/are finalized.
Another possibility might be simply in all the spots where we set
TYPE_CANONICAL (t) = something; to add if (TYPE_STRUCTURAL_EQUALITY_P
(TYPE_CANONICAL (t))) SET_TYPE_STRUCTURAL_EQUALITY (t);
On the build_function_type it could be
--- gcc/tree.cc.jj 2024-04-16 09:56:16.463008446 +0200
+++ gcc/tree.cc 2024-05-03 10:21:04.119086667 +0200
@@ -7511,17 +7511,25 @@ build_function_type (tree value_type, tr
hashval_t hash = type_hash_canon_hash (t);
t = type_hash_canon (hash, t);
- /* Set up the canonical type. */
- any_structural_p = TYPE_STRUCTURAL_EQUALITY_P (value_type);
- any_noncanonical_p = TYPE_CANONICAL (value_type) != value_type;
- canon_argtypes = maybe_canonicalize_argtypes (arg_types,
- &any_structural_p,
- &any_noncanonical_p);
- if (any_structural_p)
- SET_TYPE_STRUCTURAL_EQUALITY (t);
- else if (any_noncanonical_p)
- TYPE_CANONICAL (t) = build_function_type (TYPE_CANONICAL (value_type),
- canon_argtypes);
+ if (TYPE_CANONICAL (t) == t)
+ {
+ /* Set up the canonical type. */
+ any_structural_p = TYPE_STRUCTURAL_EQUALITY_P (value_type);
+ any_noncanonical_p = TYPE_CANONICAL (value_type) != value_type;
+ canon_argtypes = maybe_canonicalize_argtypes (arg_types,
+ &any_structural_p,
+ &any_noncanonical_p);
+ if (any_structural_p)
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
+ else if (any_noncanonical_p)
+ {
+ TYPE_CANONICAL (t)
+ = build_function_type (TYPE_CANONICAL (value_type),
+ canon_argtypes);
+ if (TYPE_STRUCTURAL_EQUALITY_P (TYPE_CANONICAL (t)))
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
+ }
+ }
if (!COMPLETE_TYPE_P (t))
layout_type (t);