https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114931
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jakub at gcc dot gnu.org
--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> ---
I'll note that seeing code like the following which possibly mutates existing
hash entries looks quite broken. But of course type_hash_canon is a fragile
bit of code (well, it shouldn't ...). To me it looks like we should compute
and set the canonical type first and _then_ do the hash lookup (which should
include the canonical type). And I'd make type_hash_canon take a tree * to
modify, making its return value a bool whether we found an existing type so
we can simply do if (type_hash_canon (hash, &t)) { ggc_free (orig_t); return t;
}
tree
build_function_type (tree value_type, tree arg_types,
bool no_named_args_stdarg_p)
{
tree t;
inchash::hash hstate;
bool any_structural_p, any_noncanonical_p;
tree canon_argtypes;
gcc_assert (arg_types != error_mark_node);
if (TREE_CODE (value_type) == FUNCTION_TYPE)
{
error ("function return type cannot be function");
value_type = integer_type_node;
}
/* Make a node of the sort we want. */
t = make_node (FUNCTION_TYPE);
TREE_TYPE (t) = value_type;
TYPE_ARG_TYPES (t) = arg_types;
if (no_named_args_stdarg_p)
{
gcc_assert (arg_types == NULL_TREE);
TYPE_NO_NAMED_ARGS_STDARG_P (t) = 1;
}
/* If we already have such a type, use the old one. */
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 (!COMPLETE_TYPE_P (t))
layout_type (t);
return t;
}