Commit b9fa0575 by Jason Merrill Committed by Jason Merrill

re PR c++/64359 (alias_template_specialization_p & template_args_equal show up high in profile)

	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.

From-SVN: r218995
parent d01cc136
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> 2014-12-19 Kai Tietz <ktietz@redhat.com>
PR c++/61198 PR c++/61198
......
...@@ -1674,6 +1674,18 @@ iterative_hash_template_arg (tree arg, hashval_t val) ...@@ -1674,6 +1674,18 @@ iterative_hash_template_arg (tree arg, hashval_t val)
switch (tclass) switch (tclass)
{ {
case tcc_type: 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)) if (TYPE_CANONICAL (arg))
return iterative_hash_object (TYPE_HASH (TYPE_CANONICAL (arg)), return iterative_hash_object (TYPE_HASH (TYPE_CANONICAL (arg)),
val); val);
...@@ -5314,13 +5326,19 @@ alias_type_or_template_p (tree t) ...@@ -5314,13 +5326,19 @@ alias_type_or_template_p (tree t)
bool bool
alias_template_specialization_p (const_tree t) alias_template_specialization_p (const_tree t)
{ {
if (t == NULL_TREE) /* It's an alias template specialization if it's an alias and its
return false; TYPE_NAME is a specialization of a primary template. */
if (TYPE_ALIAS_P (t))
return (TYPE_P (t) {
&& TYPE_TEMPLATE_INFO (t) tree name = TYPE_NAME (t);
&& PRIMARY_TEMPLATE_P (TYPE_TI_TEMPLATE (t)) if (DECL_LANG_SPECIFIC (name))
&& DECL_ALIAS_TEMPLATE_P (TYPE_TI_TEMPLATE (t))); 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 /* Return TRUE iff T is a specialization of an alias template with
...@@ -5330,7 +5348,8 @@ bool ...@@ -5330,7 +5348,8 @@ bool
dependent_alias_template_spec_p (const_tree t) dependent_alias_template_spec_p (const_tree t)
{ {
return (alias_template_specialization_p (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. */ /* Return the number of innermost template parameters in TMPL. */
...@@ -7283,16 +7302,12 @@ template_args_equal (tree ot, tree nt) ...@@ -7283,16 +7302,12 @@ template_args_equal (tree ot, tree nt)
return false; return false;
/* Don't treat an alias template specialization with dependent /* Don't treat an alias template specialization with dependent
arguments as equivalent to its underlying type when used as a arguments as equivalent to its underlying type when used as a
template argument; we need them to hash differently. */ template argument; we need them to be distinct so that we
bool ndep = dependent_alias_template_spec_p (nt); substitute into the specialization arguments at instantiation
++processing_template_decl; time. And aliases can't be equivalent without being ==, so
bool odep = dependent_alias_template_spec_p (ot); we don't need to look any deeper. */
--processing_template_decl; if (TYPE_ALIAS_P (nt) || TYPE_ALIAS_P (ot))
if (ndep != odep)
return false; 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 else
return same_type_p (ot, nt); return same_type_p (ot, nt);
} }
......
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