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
This commit is contained in:
Jason Merrill 2014-08-15 13:27:58 -04:00
parent 9de8e7afa4
commit 33cb682bce
4 changed files with 92 additions and 69 deletions

View File

@ -1,3 +1,7 @@
2014-08-15 Jason Merrill <jason@redhat.com>
* tree.c (type_hash_canon): Uncomment assert.
2014-08-15 Manuel López-Ibáñez <manu@gcc.gnu.org>
* input.h (in_system_header_at): Add comment.

View File

@ -1,3 +1,11 @@
2014-08-15 Richard Biener <rguenther@suse.de>
Jason Merrill <jason@redhat.com>
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 <paolo.carlini@oracle.com>
PR c++/62072

View File

@ -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;
}

View File

@ -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)]--;