From 33cb682bcea5e450ea4c19f99dd07cda04e0ada7 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 15 Aug 2014 13:27:58 -0400 Subject: [PATCH] re PR bootstrap/62077 (--with-build-config=bootstrap-lto fails) PR bootstrap/62077 gcc/ * tree.c (type_hash_canon): Uncomment assert. gcc/cp/ * tree.c (build_min_array_type, set_array_type_canon): Split out... (build_cplus_array_type): ...from here. Only call build_array_type for main variants. From-SVN: r214030 --- gcc/ChangeLog | 4 ++ gcc/cp/ChangeLog | 8 +++ gcc/cp/tree.c | 144 ++++++++++++++++++++++++++--------------------- gcc/tree.c | 5 +- 4 files changed, 92 insertions(+), 69 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 906231ac02a..1222d30fa4d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2014-08-15 Jason Merrill + + * tree.c (type_hash_canon): Uncomment assert. + 2014-08-15 Manuel López-Ibáñez * input.h (in_system_header_at): Add comment. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6623e96df35..e57131f716e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2014-08-15 Richard Biener + Jason Merrill + + PR bootstrap/62077 + * tree.c (build_min_array_type, set_array_type_canon): Split out... + (build_cplus_array_type): ...from here. Only call build_array_type + for main variants. + 2014-08-15 Paolo Carlini PR c++/62072 diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 3b53039cde3..c9199f2c186 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -757,7 +757,40 @@ cplus_array_compare (const void * k1, const void * k2) the language-independent type hash table. */ static GTY ((param_is (union tree_node))) htab_t cplus_array_htab; -/* Like build_array_type, but handle special C++ semantics. */ +/* Build an ARRAY_TYPE without laying it out. */ + +static tree +build_min_array_type (tree elt_type, tree index_type) +{ + tree t = cxx_make_type (ARRAY_TYPE); + TREE_TYPE (t) = elt_type; + TYPE_DOMAIN (t) = index_type; + return t; +} + +/* Set TYPE_CANONICAL like build_array_type_1, but using + build_cplus_array_type. */ + +static void +set_array_type_canon (tree t, tree elt_type, tree index_type) +{ + /* Set the canonical type for this new node. */ + if (TYPE_STRUCTURAL_EQUALITY_P (elt_type) + || (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type))) + SET_TYPE_STRUCTURAL_EQUALITY (t); + else if (TYPE_CANONICAL (elt_type) != elt_type + || (index_type && TYPE_CANONICAL (index_type) != index_type)) + TYPE_CANONICAL (t) + = build_cplus_array_type (TYPE_CANONICAL (elt_type), + index_type + ? TYPE_CANONICAL (index_type) : index_type); + else + TYPE_CANONICAL (t) = t; +} + +/* Like build_array_type, but handle special C++ semantics: an array of a + variant element type is a variant of the array of the main variant of + the element type. */ tree build_cplus_array_type (tree elt_type, tree index_type) @@ -767,10 +800,19 @@ build_cplus_array_type (tree elt_type, tree index_type) if (elt_type == error_mark_node || index_type == error_mark_node) return error_mark_node; - if (processing_template_decl - && (dependent_type_p (elt_type) - || (index_type && !TREE_CONSTANT (TYPE_MAX_VALUE (index_type))))) + bool dependent + = (processing_template_decl + && (dependent_type_p (elt_type) + || (index_type && !TREE_CONSTANT (TYPE_MAX_VALUE (index_type))))); + + if (elt_type != TYPE_MAIN_VARIANT (elt_type)) + /* Start with an array of the TYPE_MAIN_VARIANT. */ + t = build_cplus_array_type (TYPE_MAIN_VARIANT (elt_type), + index_type); + else if (dependent) { + /* Since type_hash_canon calls layout_type, we need to use our own + hash table. */ void **e; cplus_array_info cai; hashval_t hash; @@ -792,82 +834,33 @@ build_cplus_array_type (tree elt_type, tree index_type) else { /* Build a new array type. */ - t = cxx_make_type (ARRAY_TYPE); - TREE_TYPE (t) = elt_type; - TYPE_DOMAIN (t) = index_type; + t = build_min_array_type (elt_type, index_type); /* Store it in the hash table. */ *e = t; /* Set the canonical type for this new node. */ - if (TYPE_STRUCTURAL_EQUALITY_P (elt_type) - || (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type))) - SET_TYPE_STRUCTURAL_EQUALITY (t); - else if (TYPE_CANONICAL (elt_type) != elt_type - || (index_type - && TYPE_CANONICAL (index_type) != index_type)) - TYPE_CANONICAL (t) - = build_cplus_array_type - (TYPE_CANONICAL (elt_type), - index_type ? TYPE_CANONICAL (index_type) : index_type); - else - TYPE_CANONICAL (t) = t; + set_array_type_canon (t, elt_type, index_type); } } else { - if (!TYPE_STRUCTURAL_EQUALITY_P (elt_type) - && !(index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type)) - && (TYPE_CANONICAL (elt_type) != elt_type - || (index_type && TYPE_CANONICAL (index_type) != index_type))) - /* Make sure that the canonical type is on the appropriate - variants list. */ - build_cplus_array_type - (TYPE_CANONICAL (elt_type), - index_type ? TYPE_CANONICAL (index_type) : index_type); t = build_array_type (elt_type, index_type); } - /* Push these needs up so that initialization takes place - more easily. */ - bool needs_ctor - = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (elt_type)); - TYPE_NEEDS_CONSTRUCTING (t) = needs_ctor; - bool needs_dtor - = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (elt_type)); - TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = needs_dtor; - - /* We want TYPE_MAIN_VARIANT of an array to strip cv-quals from the - element type as well, so fix it up if needed. */ + /* Now check whether we already have this array variant. */ 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) + tree m = t; + for (t = m; t; t = TYPE_NEXT_VARIANT (t)) + if (TREE_TYPE (t) == elt_type) + break; + if (!t) { - 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; - } - } + t = build_min_array_type (elt_type, index_type); + set_array_type_canon (t, elt_type, index_type); + if (!dependent) + layout_type (t); TYPE_MAIN_VARIANT (t) = m; TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); @@ -879,6 +872,27 @@ build_cplus_array_type (tree elt_type, tree index_type) if (TYPE_SIZE (t) && EXPR_P (TYPE_SIZE (t))) TREE_NO_WARNING (TYPE_SIZE (t)) = 1; + /* Push these needs up to the ARRAY_TYPE so that initialization takes + place more easily. */ + bool needs_ctor = (TYPE_NEEDS_CONSTRUCTING (t) + = TYPE_NEEDS_CONSTRUCTING (elt_type)); + bool needs_dtor = (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) + = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (elt_type)); + + if (!dependent && t == TYPE_MAIN_VARIANT (t) + && !COMPLETE_TYPE_P (t) && COMPLETE_TYPE_P (elt_type)) + { + /* The element type has been completed since the last time we saw + this array type; update the layout and 'tor flags for any variants + that need it. */ + layout_type (t); + for (tree v = TYPE_NEXT_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v)) + { + TYPE_NEEDS_CONSTRUCTING (v) = needs_ctor; + TYPE_HAS_NONTRIVIAL_DESTRUCTOR (v) = needs_dtor; + } + } + return t; } diff --git a/gcc/tree.c b/gcc/tree.c index ec65fa8c0b5..2e4ce8d30bc 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -6793,10 +6793,7 @@ type_hash_canon (unsigned int hashcode, tree type) if (*loc) { tree t1 = ((type_hash *) *loc)->type; - /* ??? We'd like to assert here that the hashtable only contains - main variants but the C++ frontend breaks this by modifying - types already in the hashtable in build_cplus_array_type. */ - /* gcc_assert (TYPE_MAIN_VARIANT (t1) == t1); */ + gcc_assert (TYPE_MAIN_VARIANT (t1) == t1); if (GATHER_STATISTICS) { tree_code_counts[(int) TREE_CODE (type)]--;