https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62077
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jason at gcc dot gnu.org --- Comment #26 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Richard Biener from comment #24) > Or "real" fix for the type_hash_canon issue (untested) > > Index: gcc/tree.c > =================================================================== > --- gcc/tree.c (revision 213814) > +++ gcc/tree.c (working copy) > @@ -6593,7 +6593,9 @@ type_hash_eq (const void *va, const void > || !attribute_list_equal (TYPE_ATTRIBUTES (a->type), > TYPE_ATTRIBUTES (b->type)) > || (TREE_CODE (a->type) != COMPLEX_TYPE > - && TYPE_NAME (a->type) != TYPE_NAME (b->type))) > + && TYPE_NAME (a->type) != TYPE_NAME (b->type)) > + || ((TYPE_MAIN_VARIANT (a->type) == TYPE_MAIN_VARIANT (a->type)) > + != (TYPE_MAIN_VARIANT (b->type) == TYPE_MAIN_VARIANT (b->type)))) > return 0; > > /* Be careful about comparing arrays before and after the element type Hmpf, that doesn't fix it. But the following makes us ICE: Index: tree.c =================================================================== --- tree.c (revision 213814) +++ tree.c (working copy) @@ -6759,6 +6761,7 @@ type_hash_canon (unsigned int hashcode, t1 = type_hash_lookup (hashcode, type); if (t1 != 0) { + gcc_assert (TYPE_MAIN_VARIANT (t1) == t1); if (GATHER_STATISTICS) { tree_code_counts[(int) TREE_CODE (type)]--; which means somebody mangles TYPE_MAIN_VARIANT of a type already in the type hash table. build_cplus_array_type is it: /* We want TYPE_MAIN_VARIANT of an array to strip cv-quals from the element type as well, so fix it up if needed. */ if (elt_type != TYPE_MAIN_VARIANT (elt_type)) { tree m = build_cplus_array_type (TYPE_MAIN_VARIANT (elt_type), index_type); ... TYPE_MAIN_VARIANT (t) = m; Jason? Something like Index: cp/tree.c =================================================================== --- cp/tree.c (revision 213814) +++ cp/tree.c (working copy) @@ -824,7 +824,11 @@ build_cplus_array_type (tree elt_type, t build_cplus_array_type (TYPE_CANONICAL (elt_type), index_type ? TYPE_CANONICAL (index_type) : index_type); - t = build_array_type (elt_type, index_type); + if (elt_type != TYPE_MAIN_VARIANT (elt_type)) + t = build_cplus_array_type (TYPE_MAIN_VARIANT (elt_type), + index_type); + else + t = build_array_type (elt_type, index_type); } /* Push these needs up so that initialization takes place @@ -840,37 +844,19 @@ build_cplus_array_type (tree elt_type, t element type as well, so fix it up if needed. */ if (elt_type != TYPE_MAIN_VARIANT (elt_type)) { - tree m = build_cplus_array_type (TYPE_MAIN_VARIANT (elt_type), - index_type); - - if (TYPE_MAIN_VARIANT (t) != m) + /* ??? We didn't even try to re-use existing types? + ??? Ah, we did via the type_hash_canon that this breaks. */ + tree t1; + for (t1 = TYPE_MAIN_VARIANT (t); t1; t1 = TYPE_NEXT_VARIANT (t1)) + if (TREE_TYPE (t1) == elt_type) + { + t = t1; + break; + } + if (!t1) { - if (COMPLETE_TYPE_P (TREE_TYPE (t)) && !COMPLETE_TYPE_P (m)) - { - /* m was built before the element type was complete, so we - also need to copy the layout info from t. We might - end up doing this multiple times if t is an array of - unknown bound. */ - tree size = TYPE_SIZE (t); - tree size_unit = TYPE_SIZE_UNIT (t); - unsigned int align = TYPE_ALIGN (t); - unsigned int user_align = TYPE_USER_ALIGN (t); - enum machine_mode mode = TYPE_MODE (t); - for (tree var = m; var; var = TYPE_NEXT_VARIANT (var)) - { - TYPE_SIZE (var) = size; - TYPE_SIZE_UNIT (var) = size_unit; - TYPE_ALIGN (var) = align; - TYPE_USER_ALIGN (var) = user_align; - SET_TYPE_MODE (var, mode); - TYPE_NEEDS_CONSTRUCTING (var) = needs_ctor; - TYPE_HAS_NONTRIVIAL_DESTRUCTOR (var) = needs_dtor; - } - } - - TYPE_MAIN_VARIANT (t) = m; - TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); - TYPE_NEXT_VARIANT (m) = t; + t = build_variant_type_copy (t); + TREE_TYPE (t) = elt_type; } } fixes that - but eventually breaks whatever needed that odd type completion, which we also can't allow on types that are recorded in the type_hash_canon hashtable. Not sure how that code can trigger when we build m right before using elt_type which is now either not complete or complete (and so is t). The above fixes the LTO miscompares. Let's see if it survives LTO bootstrap.