From: Jason Merrill Date: Sun, 21 Dec 2014 05:00:43 +0000 (-0500) Subject: re PR c++/64359 (alias_template_specialization_p & template_args_equal show up high... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b9fa057537445e7ecfb2bbbfcf7ecacdc4e3ad05;p=gcc.git 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 --- 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 + + 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 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); }