-
Notifications
You must be signed in to change notification settings - Fork 162
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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.
- Loading branch information
Patrick Palka
committed
Dec 19, 2023
1 parent
6d27ee7
commit 0a37463
Showing
5 changed files
with
88 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// PR c++/90679 | ||
// A version of alias-decl-75.C where the specializations of the | ||
// complex alias template first_t are dependent. | ||
// { dg-do compile { target c++11 } } | ||
|
||
template<class T, class...> | ||
using first_t = T; | ||
|
||
template<class T> | ||
struct A; | ||
|
||
template<class T> | ||
struct traits; | ||
|
||
template<class T> | ||
struct traits<A<first_t<T, T&>>> { | ||
static constexpr int value = 1; | ||
}; | ||
|
||
template<class T> | ||
struct traits<A<first_t<const T, T&>>> { | ||
static constexpr int value = 2; | ||
}; | ||
|
||
static_assert(traits<A<int>>::value == 1, ""); | ||
static_assert(traits<A<const int>>::value == 2, ""); // { dg-bogus "ambiguous" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// PR c++/90679 | ||
// A version of alias-decl-75a.C where the alias template specialization | ||
// appears as a more deeply nested template argument. | ||
// { dg-do compile { target c++11 } } | ||
|
||
template<class T, class...> | ||
using first_t = T; | ||
|
||
template<class T> | ||
struct A; | ||
|
||
template<class T> | ||
struct traits; | ||
|
||
template<class T> | ||
struct traits<A<A<first_t<T, T&>>>> { | ||
static constexpr int value = 1; | ||
}; | ||
|
||
template<class T> | ||
struct traits<A<A<first_t<const T, T&>>>> { | ||
static constexpr int value = 2; | ||
}; | ||
|
||
static_assert(traits<A<A<int>>>::value == 1, ""); | ||
static_assert(traits<A<A<const int>>>::value == 2, ""); // { dg-bogus "ambiguous" } |