summaryrefslogtreecommitdiffstats
path: root/gcc/cp
diff options
context:
space:
mode:
authordgregor <dgregor@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-02 14:23:26 +0000
committerdgregor <dgregor@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-02 14:23:26 +0000
commit6753bca010ec145c663288e8ffb30f5abb77547d (patch)
treec7764f44cdfd0ac83984115b7e6b9f215d169dc5 /gcc/cp
parent7c69b636e86fa2d36a731fd25aafc6fa797686d3 (diff)
downloadppe42-gcc-6753bca010ec145c663288e8ffb30f5abb77547d.tar.gz
ppe42-gcc-6753bca010ec145c663288e8ffb30f5abb77547d.zip
2007-01-02 Douglas Gregor <doug.gregor@gmail.com>
* c-common.c(c_common_nodes_and_builtins): Since variants of void_type_node get built before it is given a name, we need to give those variants the name, too. (complete_array_type): We need to work with the canonical main type of the array, from which we will build the qualified version. * params.def (PARAM_VERIFY_CANONICAL_TYPES): New. * print-tree.c (print_node): Display canonical type information for each type. * stor-layout.c (layout_type): When we don't know the alignment of a type for which we're building an array, we end up guessing wrong, so make the type require structural equality. * tree.c (make_node_stat): When we build a new type, it is its own canonical type. (build_type_attribute_qual_variant): When building an attribute variant, its canonical type is the non-attribute variant. However, if the attributes are target-dependent and they differ, we need to use structural equality checks for this type. (build_qualified_type): A qualified type is not equivalent to its unqualified variant; set the canonical type appropriately. (build_distinct_type_copy): When building a distinct type from another type, the new type is its own canonical type. (build_variant_type_copy): When building a new type variant, we assume that it is equivalent to the original type. (build_pointer_type_for_mode): When building a pointer type, also build a canonical type pointer. (build_reference_type_for_mode): When building a reference type, also build a canonical type reference. (build_index_type): When we can't hash an index type (e.g., because its maximum value is negative), the index type requires structural equality tests. (build_array_type): Build the canonical form of an array type. (build_function_type): Function types require structural equality, because they contain default arguments, attributes, etc. (build_method_type_directly): Ditto for method types. (build_offset_type): Build the canonical offset type. (build_complex_type): Build the canonical vector type. (make_vector_type): Build the canonical vector type. * tree.h (TYPE_CANONICAL): New. (TYPE_STRUCTURAL_EQUALITY_P): New. (SET_TYPE_STRUCTURAL_EQUALITY): New. (struct tree_type): Added "canonical" field. * params.h (VERIFY_CANONICAL_TYPES): New. * doc/c-tree.texi (TYPE_CANONICAL): Document. (TYPE_STRUCTURAL_EQUALITY_P): Document. (SET_TYPE_STRUCTURAL_EQUALITY): Document. * doc/invoke.texi (verify-canonical-types): Document --param parameter for verifying canonical types. 2007-01-02 Douglas Gregor <doug.gregor@gmail.com> * typeck.c (structural_comptypes): Renamed from "comptypes". (comptypes): Use canonical type information to perform fast type comparison. When VERIFY_CANONICAL_TYPES, verify that the canonical type comparison returns the same results as we would see from the current, structural check. Support COMPARE_STRUCTURAL when we need structural checks. * decl.c (typename_compare): Fix comment. (build_typename_type): TYPENAME_TYPE nodes require structural equality checks, because they resolve different based on the current class type. (make_unbound_class_template): UNBOUND_CLASS_TEMPLATE nodes require structural equality checks (for now). (build_ptrmemfunc_type): Build the canonical pointer to member function type. (compute_array_index_type): Whenever we build a new index type to represent the size of an array in a template, we need to mark this index type as requiring structural equality. This goes for arrays with value-dependent sizes with the current ABI, or all arrays with ABI-1. * tree.c (cplus_array_hash): New. (struct cplus_array_info): New. (cplus_array_compare): New. (cplus_array_htab): New. (build_cplus_array_type_1): Use a hash table to cache the array types we build. Build the canonical array type for each array type. (cp_build_qualified_type_real): When building a cv-qualified array type, use the hash table of array types and build canonical array types as necessary. (bind_template_template_parm): BOUND_TEMPLATE_TEMPLATE_PARM nodes use structural equality (for now). * cp-tree.h (COMPARE_STRUCTURAL): New. * pt.c (canonical_template_parms): New. (canonical_type_parameter): New. (process_template_parm): Find the canonical type parameter. (lookup_template_class): When we have named the primary template type, set the canonical type for our template class to the primary template type. If any of the template arguments need structural equality checks, the template class needs structural equality checks. (tsubst): When reducing the level of a template template parameter, we require structural equality tests for the resulting parameter because its template parameters have not had their types canonicalized. When reducing a template type parameter, find the canonical reduced type parameter. (any_template_arguments_need_structural_equality_p): New. 2007-01-02 Douglas Gregor <doug.gregor@gmail.com> * objc-act.c (objc_build_volatilized_type): Keep track of canonical types. (objc_get_protocol_qualified_type): Ditto. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120341 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog49
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/decl.c52
-rw-r--r--gcc/cp/pt.c94
-rw-r--r--gcc/cp/tree.c137
-rw-r--r--gcc/cp/typeck.c67
6 files changed, 386 insertions, 17 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ae5beb2a624..dc291d054a1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,52 @@
+2007-01-02 Douglas Gregor <doug.gregor@gmail.com>
+
+ * typeck.c (structural_comptypes): Renamed from "comptypes".
+ (comptypes): Use canonical type information to perform fast type
+ comparison. When VERIFY_CANONICAL_TYPES, verify that the
+ canonical type comparison returns the same results as we would see
+ from the current, structural check. Support COMPARE_STRUCTURAL
+ when we need structural checks.
+ * decl.c (typename_compare): Fix comment.
+ (build_typename_type): TYPENAME_TYPE nodes require structural
+ equality checks, because they resolve different based on the
+ current class type.
+ (make_unbound_class_template): UNBOUND_CLASS_TEMPLATE nodes
+ require structural equality checks (for now).
+ (build_ptrmemfunc_type): Build the canonical pointer to member
+ function type.
+ (compute_array_index_type): Whenever we build a new index type
+ to represent the size of an array in a template, we need to mark
+ this index type as requiring structural equality. This goes for
+ arrays with value-dependent sizes with the current ABI, or all
+ arrays with ABI-1.
+ * tree.c (cplus_array_hash): New.
+ (struct cplus_array_info): New.
+ (cplus_array_compare): New.
+ (cplus_array_htab): New.
+ (build_cplus_array_type_1): Use a hash table to cache the array
+ types we build. Build the canonical array type for each array
+ type.
+ (cp_build_qualified_type_real): When building a cv-qualified array
+ type, use the hash table of array types and build canonical array
+ types as necessary.
+ (bind_template_template_parm): BOUND_TEMPLATE_TEMPLATE_PARM nodes
+ use structural equality (for now).
+ * cp-tree.h (COMPARE_STRUCTURAL): New.
+ * pt.c (canonical_template_parms): New.
+ (canonical_type_parameter): New.
+ (process_template_parm): Find the canonical type parameter.
+ (lookup_template_class): When we have named the primary template
+ type, set the canonical type for our template class to the primary
+ template type. If any of the template arguments need structural
+ equality checks, the template class needs structural equality
+ checks.
+ (tsubst): When reducing the level of a template template
+ parameter, we require structural equality tests for the resulting
+ parameter because its template parameters have not had their types
+ canonicalized. When reducing a template type parameter, find the
+ canonical reduced type parameter.
+ (any_template_arguments_need_structural_equality_p): New.
+
2006-12-31 Simon Martin <simartin@users.sourceforge.net>
PR c++/29731
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6707a20de66..1ec96655ab5 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3508,6 +3508,10 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
#define COMPARE_REDECLARATION 4 /* The comparison is being done when
another declaration of an existing
entity is seen. */
+#define COMPARE_STRUCTURAL 8 /* The comparison is intended to be
+ structural. The actual comparison
+ will be identical to
+ COMPARE_STRICT. */
/* Used with push_overloaded_decl. */
#define PUSH_GLOBAL 0 /* Push the DECL into namespace scope,
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 6a46636ea10..1ed8afc7708 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -2695,7 +2695,8 @@ typedef struct typename_info {
bool class_p;
} typename_info;
-/* Compare two TYPENAME_TYPEs. K1 and K2 are really of type `tree'. */
+/* Compare two TYPENAME_TYPEs. K1 is really of type `tree', K2 is
+ really of type `typename_info*' */
static int
typename_compare (const void * k1, const void * k2)
@@ -2766,6 +2767,11 @@ build_typename_type (tree context, tree name, tree fullname,
/* Store it in the hash table. */
*e = t;
+
+ /* TYPENAME_TYPEs must always be compared structurally, because
+ they may or may not resolve down to another type depending on
+ the currently open classes. */
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
}
return t;
@@ -2937,6 +2943,7 @@ make_unbound_class_template (tree context, tree name, tree parm_list,
t = make_aggr_type (UNBOUND_CLASS_TEMPLATE);
TYPE_CONTEXT (t) = FROB_CONTEXT (context);
TREE_TYPE (t) = NULL_TREE;
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
/* Build the corresponding TEMPLATE_DECL. */
d = build_decl (TEMPLATE_DECL, name, t);
@@ -6461,6 +6468,11 @@ build_ptrmemfunc_type (tree type)
later. */
TYPE_SET_PTRMEMFUNC_TYPE (type, t);
+ if (TYPE_STRUCTURAL_EQUALITY_P (type))
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
+ else if (TYPE_CANONICAL (type) != type)
+ TYPE_CANONICAL (t) = build_ptrmemfunc_type (TYPE_CANONICAL (type));
+
return t;
}
@@ -6535,6 +6547,7 @@ compute_array_index_type (tree name, tree size)
{
tree type;
tree itype;
+ tree abi_1_itype = NULL_TREE;
if (error_operand_p (size))
return error_mark_node;
@@ -6551,14 +6564,26 @@ compute_array_index_type (tree name, tree size)
type = TREE_TYPE (size);
}
- if (abi_version_at_least (2)
- /* We should only handle value dependent expressions specially. */
- ? value_dependent_expression_p (size)
- /* But for abi-1, we handled all instances in templates. This
- effects the manglings produced. */
- : processing_template_decl)
- return build_index_type (build_min (MINUS_EXPR, sizetype,
- size, integer_one_node));
+ if (value_dependent_expression_p (size))
+ {
+ /* We cannot do any checking for a value-dependent SIZE. Just
+ build the index type and mark that it requires structural
+ equality checks. */
+ itype = build_index_type (build_min (MINUS_EXPR, sizetype,
+ size, integer_one_node));
+ SET_TYPE_STRUCTURAL_EQUALITY (itype);
+ return itype;
+ }
+
+ if (!abi_version_at_least (2) && processing_template_decl)
+ /* For abi-1, we handled all instances in templates the same way,
+ even when they were non-dependent. This effects the manglings
+ produced. So, we do the normal checking for non-dependent
+ sizes, but at the end we'll return the same type that abi-1
+ would have, but with TYPE_CANONICAL set to the "right"
+ value that the current ABI would provide. */
+ abi_1_itype = build_index_type (build_min (MINUS_EXPR, sizetype,
+ size, integer_one_node));
/* The size might be the result of a cast. */
STRIP_TYPE_NOPS (size);
@@ -6649,7 +6674,14 @@ compute_array_index_type (tree name, tree size)
}
/* Create and return the appropriate index type. */
- return build_index_type (itype);
+ if (abi_1_itype)
+ {
+ tree t = build_index_type (itype);
+ TYPE_CANONICAL (abi_1_itype) = TYPE_CANONICAL (t);
+ return abi_1_itype;
+ }
+ else
+ return build_index_type (itype);
}
/* Returns the scope (if any) in which the entity declared by
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f9a728fa4b5..1e90751287c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -80,6 +80,12 @@ static tree cur_stmt_expr;
local variables. */
static htab_t local_specializations;
+/* Contains canonical template parameter types. The vector is index by
+ the TEMPLATE_TYPE_IDX of the template parameter. Each element is a
+ TREE_LIST, whose TREE_VALUEs contain the canonical template
+ parameters of various types and levels. */
+static GTY(()) VEC(tree,gc) *canonical_template_parms;
+
#define UNIFY_ALLOW_NONE 0
#define UNIFY_ALLOW_MORE_CV_QUAL 1
#define UNIFY_ALLOW_LESS_CV_QUAL 2
@@ -157,6 +163,7 @@ static tree copy_default_args_to_explicit_spec_1 (tree, tree);
static void copy_default_args_to_explicit_spec (tree);
static int invalid_nontype_parm_type_p (tree, tsubst_flags_t);
static int eq_local_specializations (const void *, const void *);
+static bool any_template_arguments_need_structural_equality_p (tree);
static bool dependent_type_p_r (tree);
static tree tsubst (tree, tree, tsubst_flags_t, tree);
static tree tsubst_expr (tree, tree, tsubst_flags_t, tree, bool);
@@ -2335,6 +2342,35 @@ build_template_parm_index (int index,
return t;
}
+/* Find the canonical type parameter for the given template type
+ parmaeter. Returns the canonical type parameter, which may be TYPE
+ if no such parameter existed. */
+static tree
+canonical_type_parameter (tree type)
+{
+ tree list;
+ int idx = TEMPLATE_TYPE_IDX (type);
+ if (!canonical_template_parms)
+ canonical_template_parms = VEC_alloc (tree, gc, idx+1);
+
+ while (VEC_length (tree, canonical_template_parms) <= (unsigned)idx)
+ VEC_safe_push (tree, gc, canonical_template_parms, NULL_TREE);
+
+ list = VEC_index (tree, canonical_template_parms, idx);
+ while (list && !comptypes (type, TREE_VALUE (list), COMPARE_STRUCTURAL))
+ list = TREE_CHAIN (list);
+
+ if (list)
+ return TREE_VALUE (list);
+ else
+ {
+ VEC_replace(tree, canonical_template_parms, idx,
+ tree_cons (NULL_TREE, type,
+ VEC_index (tree, canonical_template_parms, idx)));
+ return type;
+ }
+}
+
/* Return a TEMPLATE_PARM_INDEX, similar to INDEX, but whose
TEMPLATE_PARM_LEVEL has been decreased by LEVELS. If such a
TEMPLATE_PARM_INDEX already exists, it is returned; otherwise, a
@@ -2473,6 +2509,7 @@ process_template_parm (tree list, tree parm, bool is_non_type)
= build_template_parm_index (idx, processing_template_decl,
processing_template_decl,
decl, TREE_TYPE (parm));
+ TYPE_CANONICAL (t) = canonical_type_parameter (t);
}
DECL_ARTIFICIAL (decl) = 1;
SET_DECL_TEMPLATE_PARM_P (decl);
@@ -4807,6 +4844,17 @@ lookup_template_class (tree d1,
/* A local class. Make sure the decl gets registered properly. */
if (context == current_function_decl)
pushtag (DECL_NAME (template), t, /*tag_scope=*/ts_current);
+
+ if (comp_template_args (CLASSTYPE_TI_ARGS (template_type), arglist))
+ /* This instantiation is another name for the primary
+ template type. Set the TYPE_CANONICAL field
+ appropriately. */
+ TYPE_CANONICAL (t) = template_type;
+ else if (any_template_arguments_need_structural_equality_p (arglist))
+ /* Some of the template arguments require structural
+ equality testing, so this template class requires
+ structural equality testing. */
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
}
/* If we called start_enum or pushtag above, this information
@@ -7473,6 +7521,18 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
TYPE_POINTER_TO (r) = NULL_TREE;
TYPE_REFERENCE_TO (r) = NULL_TREE;
+ if (TREE_CODE (r) == TEMPLATE_TEMPLATE_PARM)
+ /* We have reduced the level of the template
+ template parameter, but not the levels of its
+ template parameters, so canonical_type_parameter
+ will not be able to find the canonical template
+ template parameter for this level. Thus, we
+ require structural equality checking to compare
+ TEMPLATE_TEMPLATE_PARMs. */
+ SET_TYPE_STRUCTURAL_EQUALITY (r);
+ else
+ TYPE_CANONICAL (r) = canonical_type_parameter (r);
+
if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
{
tree argvec = tsubst (TYPE_TI_ARGS (t), args,
@@ -13168,6 +13228,40 @@ dependent_template_arg_p (tree arg)
}
/* Returns true if ARGS (a collection of template arguments) contains
+ any types that require structural equality testing. */
+
+bool
+any_template_arguments_need_structural_equality_p (tree args)
+{
+ int i;
+ int j;
+
+ if (!args)
+ return false;
+ if (args == error_mark_node)
+ return true;
+
+ for (i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
+ {
+ tree level = TMPL_ARGS_LEVEL (args, i + 1);
+ for (j = 0; j < TREE_VEC_LENGTH (level); ++j)
+ {
+ tree arg = TREE_VEC_ELT (level, j);
+ if (TREE_CODE (arg) == TEMPLATE_DECL
+ || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
+ continue;
+ else if (TYPE_P (arg) && TYPE_STRUCTURAL_EQUALITY_P (arg))
+ return true;
+ else if (!TYPE_P (arg) && TREE_TYPE (arg)
+ && TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (arg)))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* Returns true if ARGS (a collection of template arguments) contains
any dependent arguments. */
bool
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 526077a43e9..ae3dc4c2786 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -407,6 +407,49 @@ rvalue (tree expr)
}
+/* Hash an ARRAY_TYPE. K is really of type `tree'. */
+
+static hashval_t
+cplus_array_hash (const void* k)
+{
+ hashval_t hash;
+ tree t = (tree) k;
+
+ hash = (htab_hash_pointer (TREE_TYPE (t))
+ ^ htab_hash_pointer (TYPE_DOMAIN (t)));
+
+ return hash;
+}
+
+typedef struct cplus_array_info {
+ tree type;
+ tree domain;
+} cplus_array_info;
+
+/* Compare two ARRAY_TYPEs. K1 is really of type `tree', K2 is really
+ of type `cplus_array_info*'. */
+
+static int
+cplus_array_compare (const void * k1, const void * k2)
+{
+ tree t1 = (tree) k1;
+ const cplus_array_info *t2 = (const cplus_array_info*) k2;
+
+ if (!comptypes (TREE_TYPE (t1), t2->type, COMPARE_STRUCTURAL))
+ return 0;
+
+ if (!TYPE_DOMAIN (t1))
+ return !t2->domain;
+
+ if (!t2->domain)
+ return 0;
+
+ return comptypes (TYPE_DOMAIN (t1), t2->domain, COMPARE_STRUCTURAL);
+}
+
+static GTY ((param_is (union tree_node))) htab_t cplus_array_htab;
+
+
static tree
build_cplus_array_type_1 (tree elt_type, tree index_type)
{
@@ -419,9 +462,47 @@ build_cplus_array_type_1 (tree elt_type, tree index_type)
|| (index_type
&& value_dependent_expression_p (TYPE_MAX_VALUE (index_type))))
{
- t = make_node (ARRAY_TYPE);
- TREE_TYPE (t) = elt_type;
- TYPE_DOMAIN (t) = index_type;
+ void **e;
+ cplus_array_info cai;
+ hashval_t hash;
+
+ if (cplus_array_htab == NULL)
+ cplus_array_htab = htab_create_ggc (61, &cplus_array_hash,
+ &cplus_array_compare, NULL);
+
+ hash = (htab_hash_pointer (elt_type)
+ ^ htab_hash_pointer (index_type));
+ cai.type = elt_type;
+ cai.domain = index_type;
+
+ e = htab_find_slot_with_hash (cplus_array_htab, &cai, hash, INSERT);
+ if (*e)
+ /* We have found the type: we're done. */
+ return (tree) *e;
+ else
+ {
+ /* Build a new array type. */
+ t = make_node (ARRAY_TYPE);
+ TREE_TYPE (t) = elt_type;
+ TYPE_DOMAIN (t) = index_type;
+
+ /* Complete building the array type. */
+ 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)
+ = TYPE_CANONICAL
+ (build_cplus_array_type_1 (TYPE_CANONICAL (elt_type),
+ index_type?
+ TYPE_CANONICAL (index_type)
+ : index_type));
+
+ /* Store it in the hash table. */
+ *e = t;
+ }
}
else
t = build_array_type (elt_type, index_type);
@@ -508,10 +589,59 @@ cp_build_qualified_type_real (tree type,
if (!t)
{
+ tree domain = TYPE_DOMAIN (type);
+
/* Make a new array type, just like the old one, but with the
appropriately qualified element type. */
t = build_variant_type_copy (type);
TREE_TYPE (t) = element_type;
+
+ /* This is a new type. */
+ TYPE_CANONICAL (t) = t;
+
+ if (dependent_type_p (element_type)
+ || (domain
+ && value_dependent_expression_p (TYPE_MAX_VALUE (domain))))
+ {
+ /* The new dependent array type we just created might be
+ equivalent to an existing dependent array type, so we
+ need to keep track of this new array type with a
+ lookup into CPLUS_ARRAY_HTAB. Note that we cannot
+ directly call build_cplus_array_type (that would
+ recurse) or build_cplus_array_type_1 (that would lose
+ attributes). */
+ void **e;
+ cplus_array_info cai;
+ hashval_t hash;
+
+ if (cplus_array_htab == NULL)
+ cplus_array_htab = htab_create_ggc (61, &cplus_array_hash,
+ &cplus_array_compare,
+ NULL);
+
+ hash = (htab_hash_pointer (element_type)
+ ^ htab_hash_pointer (domain));
+ cai.type = element_type;
+ cai.domain = domain;
+
+ e = htab_find_slot_with_hash (cplus_array_htab, &cai, hash,
+ INSERT);
+ if (! *e)
+ /* Save this new type. */
+ *e = t;
+ }
+
+ if (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (t))
+ || (TYPE_DOMAIN (t)
+ && TYPE_STRUCTURAL_EQUALITY_P (TYPE_DOMAIN (t))))
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
+ else
+ TYPE_CANONICAL (t)
+ = TYPE_CANONICAL
+ (build_array_type (TYPE_CANONICAL (TREE_TYPE (t)),
+ TYPE_DOMAIN (t)?
+ TYPE_CANONICAL (TYPE_DOMAIN(t))
+ : TYPE_DOMAIN (t)));
}
/* Even if we already had this variant, we update
@@ -1003,6 +1133,7 @@ bind_template_template_parm (tree t, tree newargs)
TYPE_NAME (t2) = decl;
TYPE_STUB_DECL (t2) = decl;
TYPE_SIZE (t2) = 0;
+ SET_TYPE_STRUCTURAL_EQUALITY (t2);
return t2;
}
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index cb09d4c987c..7e8b785b3eb 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -43,6 +43,7 @@ Boston, MA 02110-1301, USA. */
#include "target.h"
#include "convert.h"
#include "c-common.h"
+#include "params.h"
static tree pfn_from_ptrmemfunc (tree);
static tree convert_for_assignment (tree, tree, const char *, tree, int);
@@ -927,11 +928,10 @@ comp_array_types (tree t1, tree t2, bool allow_redeclaration)
return true;
}
-/* Return true if T1 and T2 are related as allowed by STRICT. STRICT
- is a bitwise-or of the COMPARE_* flags. */
+/* Subroutine in comptypes. */
-bool
-comptypes (tree t1, tree t2, int strict)
+static bool
+structural_comptypes (tree t1, tree t2, int strict)
{
if (t1 == t2)
return true;
@@ -1090,6 +1090,65 @@ comptypes (tree t1, tree t2, int strict)
return targetm.comp_type_attributes (t1, t2);
}
+/* Return true if T1 and T2 are related as allowed by STRICT. STRICT
+ is a bitwise-or of the COMPARE_* flags. */
+
+bool
+comptypes (tree t1, tree t2, int strict)
+{
+ if (strict == COMPARE_STRICT)
+ {
+ bool result;
+
+ if (t1 == t2)
+ return true;
+
+ if (t1 == error_mark_node || t2 == error_mark_node)
+ return false;
+
+ if (TYPE_STRUCTURAL_EQUALITY_P (t1) || TYPE_STRUCTURAL_EQUALITY_P (t2))
+ /* At least one of the types requires structural equality, so
+ perform a deep check. */
+ return structural_comptypes (t1, t2, strict);
+
+ if (VERIFY_CANONICAL_TYPES)
+ {
+ result = structural_comptypes (t1, t2, strict);
+
+ if (result && TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2))
+ {
+ /* The two types are structurally equivalent, but their
+ canonical types were different. This is a failure of the
+ canonical type propagation code.*/
+ warning(0,
+ "canonical types differ for identical types %T and %T",
+ t1, t2);
+ debug_tree (t1);
+ debug_tree (t2);
+ }
+ else if (!result && TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2))
+ {
+ /* Two types are structurally different, but the canonical
+ types are the same. This means we were over-eager in
+ assigning canonical types. */
+ warning (0,
+ "same canonical type node for different types %T and %T",
+ t1, t2);
+ debug_tree (t1);
+ debug_tree (t2);
+ }
+
+ return result;
+ }
+ else
+ return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2);
+ }
+ else if (strict == COMPARE_STRUCTURAL)
+ return structural_comptypes (t1, t2, COMPARE_STRICT);
+ else
+ return structural_comptypes (t1, t2, strict);
+}
+
/* Returns 1 if TYPE1 is at least as qualified as TYPE2. */
bool
OpenPOWER on IntegriCloud