c++: partial ordering and dep alias tmpl specs [PR90679]
commit0a37463758dabc9647fa3d675dffdf43a737035d
authorPatrick Palka <ppalka@redhat.com>
Tue, 19 Dec 2023 16:40:15 +0000 (19 11:40 -0500)
committerPatrick Palka <ppalka@redhat.com>
Tue, 19 Dec 2023 16:40:15 +0000 (19 11:40 -0500)
treea81c2f0ae265d8185df258f470bf2df5414b491a
parent6d27ee7fcc3e31c2142124027dc87e5a0288c9ab
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.
gcc/cp/cp-tree.h
gcc/cp/pt.cc
gcc/cp/tree.cc
gcc/testsuite/g++.dg/cpp0x/alias-decl-75a.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/alias-decl-75b.C [new file with mode: 0644]