c++: partial ordering and dep alias tmpl specs [PR90679]
During partial ordering, we want to look through dependent alias
template specializations within template arguments and otherwise
treat them as opaque in other contexts (see e.g.
r7-7116-g0c942f3edab108
and
r11-7011-g6e0a231a4aa240). To that end template_args_equal was
given a partial_order flag that controls this behavior. This flag
does the right thing when a dependent alias template specialization
appears as template argument of the partial specialization, e.g. in
template<class T, class...> using first_t = T;
template<class T> struct traits;
template<class T> struct traits<first_t<T, T&>> { }; // #1
template<class T> struct traits<first_t<const T, T&>> { }; // #2
we correctly consider #2 to be more specialized than #1. But if the
alias specialization appears as a nested template argument of another
class template specialization, e.g. in
template<class T> struct traits<A<first_t<T, T&>>> { }; // #1
template<class T> struct traits<A<first_t<const T, T&>>> { }; // #2
then we incorrectly consider #1 and #2 to be unordered. This is because
1. we don't propagate the flag to recursive template_args_equal calls
2. we don't use structural equality for class template specializations
written in terms of dependent alias template specializations
This patch fixes the first issue by turning the partial_order flag into
a global. This patch fixes the second issue by making us propagate
structural equality appropriately when building a class template
specialization. In passing this patch also improves hashing of
specializations that use structural equality.
PR c++/90679
gcc/cp/ChangeLog:
* cp-tree.h (comp_template_args): Remove partial_order parameter.
(template_args_equal): Likewise.
* pt.cc (comparing_for_partial_ordering): New global flag.
(iterative_hash_template_arg) <case tcc_type>: Hash the template
and arguments for specializations that use structural equality.
(template_args_equal): Remove partial order parameter and
use comparing_for_partial_ordering instead.
(comp_template_args): Likewise.
(comp_template_args_porder): Set comparing_for_partial_ordering
instead. Make static.
(any_template_arguments_need_structural_equality_p): Return true
for an argument that's a dependent alias template specialization
or a class template specialization that itself needs structural
equality.
* tree.cc (cp_tree_equal) <case TREE_VEC>: Adjust call to
comp_template_args.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/alias-decl-75a.C: New test.
* g++.dg/cpp0x/alias-decl-75b.C: New test.