summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2014-12-21 05:00:43 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2014-12-21 05:00:43 +0000
commit0b808489a2d152ccb85824e7bfd836a21342c021 (patch)
tree85ffa26ec5a0fbc5e4e768b3e229b898960bb08f
parentdc99511941fa5ee41aa4f8c309cff052738e5993 (diff)
downloadgcc-0b808489a2d152ccb85824e7bfd836a21342c021.tar.gz
PR c++/64359
* pt.c (iterative_hash_template_arg): Hash alias specializations differently from their TYPE_CANONICAL. (alias_template_specialization_p): Optimize. (template_args_equal): Optimize alias handling. (dependent_alias_template_spec_p): Only check innermost args. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@218995 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/pt.c49
2 files changed, 41 insertions, 17 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7fcad878af7..8802e59b87d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2014-12-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/64359
+ * pt.c (iterative_hash_template_arg): Hash alias specializations
+ differently from their TYPE_CANONICAL.
+ (alias_template_specialization_p): Optimize.
+ (template_args_equal): Optimize alias handling.
+ (dependent_alias_template_spec_p): Only check innermost args.
+
2014-12-19 Kai Tietz <ktietz@redhat.com>
PR c++/61198
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 15d304af635..f5bd842df0e 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1674,6 +1674,18 @@ iterative_hash_template_arg (tree arg, hashval_t val)
switch (tclass)
{
case tcc_type:
+ if (alias_template_specialization_p (arg))
+ {
+ // We want an alias specialization that survived strip_typedefs
+ // to hash differently from its TYPE_CANONICAL, to avoid hash
+ // collisions that compare as different in template_args_equal.
+ // These could be dependent specializations that strip_typedefs
+ // left alone, or untouched specializations because
+ // coerce_template_parms returns the unconverted template
+ // arguments if it sees incomplete argument packs.
+ tree ti = TYPE_TEMPLATE_INFO (arg);
+ return hash_tmpl_and_args (TI_TEMPLATE (ti), TI_ARGS (ti));
+ }
if (TYPE_CANONICAL (arg))
return iterative_hash_object (TYPE_HASH (TYPE_CANONICAL (arg)),
val);
@@ -5314,13 +5326,19 @@ alias_type_or_template_p (tree t)
bool
alias_template_specialization_p (const_tree t)
{
- if (t == NULL_TREE)
- return false;
-
- return (TYPE_P (t)
- && TYPE_TEMPLATE_INFO (t)
- && PRIMARY_TEMPLATE_P (TYPE_TI_TEMPLATE (t))
- && DECL_ALIAS_TEMPLATE_P (TYPE_TI_TEMPLATE (t)));
+ /* It's an alias template specialization if it's an alias and its
+ TYPE_NAME is a specialization of a primary template. */
+ if (TYPE_ALIAS_P (t))
+ {
+ tree name = TYPE_NAME (t);
+ if (DECL_LANG_SPECIFIC (name))
+ if (tree ti = DECL_TEMPLATE_INFO (name))
+ {
+ tree tmpl = TI_TEMPLATE (ti);
+ return PRIMARY_TEMPLATE_P (tmpl);
+ }
+ }
+ return false;
}
/* Return TRUE iff T is a specialization of an alias template with
@@ -5330,7 +5348,8 @@ bool
dependent_alias_template_spec_p (const_tree t)
{
return (alias_template_specialization_p (t)
- && any_dependent_template_arguments_p (TYPE_TI_ARGS (t)));
+ && (any_dependent_template_arguments_p
+ (INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (t)))));
}
/* Return the number of innermost template parameters in TMPL. */
@@ -7283,16 +7302,12 @@ template_args_equal (tree ot, tree nt)
return false;
/* Don't treat an alias template specialization with dependent
arguments as equivalent to its underlying type when used as a
- template argument; we need them to hash differently. */
- bool ndep = dependent_alias_template_spec_p (nt);
- ++processing_template_decl;
- bool odep = dependent_alias_template_spec_p (ot);
- --processing_template_decl;
- if (ndep != odep)
+ template argument; we need them to be distinct so that we
+ substitute into the specialization arguments at instantiation
+ time. And aliases can't be equivalent without being ==, so
+ we don't need to look any deeper. */
+ if (TYPE_ALIAS_P (nt) || TYPE_ALIAS_P (ot))
return false;
- else if (ndep)
- return (TYPE_TI_TEMPLATE (nt) == TYPE_TI_TEMPLATE (ot)
- && template_args_equal (TYPE_TI_ARGS (nt), TYPE_TI_ARGS (ot)));
else
return same_type_p (ot, nt);
}