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);
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
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. */
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);
}