Commit 9ae165a0 by Douglas Gregor Committed by Doug Gregor

re PR c++/33977 (internal compiler error: canonical types differ for identical…

re PR c++/33977 (internal compiler error: canonical types differ for identical types const char [5] and const sal_Char [5])

2007-11-06  Douglas Gregor  <doug.gregor@gmail.com>

	PR c++/33977
	PR c++/33886
	* tree.c (c_build_qualified_type): Define bridge to
	cp_build_qualified_type.

2007-11-06  Douglas Gregor  <doug.gregor@gmail.com>

	PR c++/33977
	PR c++/33886
	* c-common.c (c_build_qualified_type): Moved to c-typeck.c.
	(complete_array_type): Set canonical type appropriately.
	* c-typeck.c (c_build_qualified_type): Moved from c-common.c. The
	C and C++ front ends now have different versions of this function,
	because the C++ version needs to maintain canonical types here.

2007-11-06  Douglas Gregor  <doug.gregor@gmail.com>

	PR c++/33977
	PR c++/33886
	* g++.dg/other/canon-array.C: New.

From-SVN: r129929
parent 1ad8aeeb
2007-11-06 Douglas Gregor <doug.gregor@gmail.com>
PR c++/33977
PR c++/33886
* c-common.c (c_build_qualified_type): Moved to c-typeck.c.
(complete_array_type): Set canonical type appropriately.
* c-typeck.c (c_build_qualified_type): Moved from c-common.c. The
C and C++ front ends now have different versions of this function,
because the C++ version needs to maintain canonical types here.
2007-11-04 Razya Ladelsky <razya@il.ibm.com>
* tree-parloops.c (reduction_info): Remove reduction_init field.
......@@ -3086,70 +3086,6 @@ static void def_builtin_1 (enum built_in_function fncode,
bool both_p, bool fallback_p, bool nonansi_p,
tree fnattrs, bool implicit_p);
/* Make a variant type in the proper way for C/C++, propagating qualifiers
down to the element type of an array. */
tree
c_build_qualified_type (tree type, int type_quals)
{
if (type == error_mark_node)
return type;
if (TREE_CODE (type) == ARRAY_TYPE)
{
tree t;
tree element_type = c_build_qualified_type (TREE_TYPE (type),
type_quals);
/* See if we already have an identically qualified type. */
for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
{
if (TYPE_QUALS (strip_array_types (t)) == type_quals
&& TYPE_NAME (t) == TYPE_NAME (type)
&& TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
&& attribute_list_equal (TYPE_ATTRIBUTES (t),
TYPE_ATTRIBUTES (type)))
break;
}
if (!t)
{
tree domain = TYPE_DOMAIN (type);
t = build_variant_type_copy (type);
TREE_TYPE (t) = element_type;
if (TYPE_STRUCTURAL_EQUALITY_P (element_type)
|| (domain && TYPE_STRUCTURAL_EQUALITY_P (domain)))
SET_TYPE_STRUCTURAL_EQUALITY (t);
else if (TYPE_CANONICAL (element_type) != element_type
|| (domain && TYPE_CANONICAL (domain) != domain))
{
tree unqualified_canon
= build_array_type (TYPE_CANONICAL (element_type),
domain? TYPE_CANONICAL (domain)
: NULL_TREE);
TYPE_CANONICAL (t)
= c_build_qualified_type (unqualified_canon, type_quals);
}
else
TYPE_CANONICAL (t) = t;
}
return t;
}
/* A restrict-qualified pointer type must be a pointer to object or
incomplete type. Note that the use of POINTER_TYPE_P also allows
REFERENCE_TYPEs, which is appropriate for C++. */
if ((type_quals & TYPE_QUAL_RESTRICT)
&& (!POINTER_TYPE_P (type)
|| !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
{
error ("invalid use of %<restrict%>");
type_quals &= ~TYPE_QUAL_RESTRICT;
}
return build_qualified_type (type, type_quals);
}
/* Apply the TYPE_QUALS to the new DECL. */
......@@ -7044,6 +6980,19 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default)
hashcode);
main_type = type_hash_canon (hashcode, main_type);
/* Fix the canonical type. */
if (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (main_type))
|| TYPE_STRUCTURAL_EQUALITY_P (TYPE_DOMAIN (main_type)))
SET_TYPE_STRUCTURAL_EQUALITY (main_type);
else if (TYPE_CANONICAL (TREE_TYPE (main_type)) != TREE_TYPE (main_type)
|| (TYPE_CANONICAL (TYPE_DOMAIN (main_type))
!= TYPE_DOMAIN (main_type)))
TYPE_CANONICAL (main_type)
= build_array_type (TYPE_CANONICAL (TREE_TYPE (main_type)),
TYPE_CANONICAL (TYPE_DOMAIN (main_type)));
else
TYPE_CANONICAL (main_type) = main_type;
if (quals == 0)
type = main_type;
else
......
......@@ -8896,3 +8896,68 @@ c_finish_omp_clauses (tree clauses)
bitmap_obstack_release (NULL);
return clauses;
}
/* Make a variant type in the proper way for C/C++, propagating qualifiers
down to the element type of an array. */
tree
c_build_qualified_type (tree type, int type_quals)
{
if (type == error_mark_node)
return type;
if (TREE_CODE (type) == ARRAY_TYPE)
{
tree t;
tree element_type = c_build_qualified_type (TREE_TYPE (type),
type_quals);
/* See if we already have an identically qualified type. */
for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
{
if (TYPE_QUALS (strip_array_types (t)) == type_quals
&& TYPE_NAME (t) == TYPE_NAME (type)
&& TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
&& attribute_list_equal (TYPE_ATTRIBUTES (t),
TYPE_ATTRIBUTES (type)))
break;
}
if (!t)
{
tree domain = TYPE_DOMAIN (type);
t = build_variant_type_copy (type);
TREE_TYPE (t) = element_type;
if (TYPE_STRUCTURAL_EQUALITY_P (element_type)
|| (domain && TYPE_STRUCTURAL_EQUALITY_P (domain)))
SET_TYPE_STRUCTURAL_EQUALITY (t);
else if (TYPE_CANONICAL (element_type) != element_type
|| (domain && TYPE_CANONICAL (domain) != domain))
{
tree unqualified_canon
= build_array_type (TYPE_CANONICAL (element_type),
domain? TYPE_CANONICAL (domain)
: NULL_TREE);
TYPE_CANONICAL (t)
= c_build_qualified_type (unqualified_canon, type_quals);
}
else
TYPE_CANONICAL (t) = t;
}
return t;
}
/* A restrict-qualified pointer type must be a pointer to object or
incomplete type. Note that the use of POINTER_TYPE_P also allows
REFERENCE_TYPEs, which is appropriate for C++. */
if ((type_quals & TYPE_QUAL_RESTRICT)
&& (!POINTER_TYPE_P (type)
|| !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
{
error ("invalid use of %<restrict%>");
type_quals &= ~TYPE_QUAL_RESTRICT;
}
return build_qualified_type (type, type_quals);
}
2007-11-06 Douglas Gregor <doug.gregor@gmail.com>
PR c++/33977
PR c++/33886
* tree.c (c_build_qualified_type): Define bridge to
cp_build_qualified_type.
2007-11-06 Douglas Gregor <doug.gregor@gmail.com>
PR c++/31439
PR c++/32114
PR c++/32115
......
......@@ -649,6 +649,14 @@ cp_build_reference_type (tree to_type, bool rval)
}
/* Used by the C++ front end to build qualified array types. However,
the C version of this function does not properly maintain canonical
types (which are not used in C). */
tree
c_build_qualified_type (tree type, int type_quals)
{
return cp_build_qualified_type (type, type_quals);
}
/* Make a variant of TYPE, qualified with the TYPE_QUALS. Handles
......
2007-11-06 Douglas Gregor <doug.gregor@gmail.com>
PR c++/33977
PR c++/33886
* g++.dg/other/canon-array.C: New.
2007-11-06 Douglas Gregor <doug.gregor@gmail.com>
* testsuite/g++.dg/parser/crash36.C: Tweak expected errors.
* testsuite/g++.dg/cpp0x/pr31439.C: New.
* testsuite/g++.dg/cpp0x/pr32114.C: New.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment