-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
c++: don't substitute TEMPLATE_PARM_CONSTRAINTS [PR100374]
This patch makes us avoid substituting into the TEMPLATE_PARM_CONSTRAINTS of each template parameter except as necessary for declaration matching, like we already do for the other constituent constraints of a declaration. This patch also improves the CA104 implementation of explicit specialization matching of a constrained function template inside a class template, by considering the function's combined constraints instead of just its trailing constraints. This allows us to correctly handle the first three explicit specializations in concepts-spec2.C below, but because we compare the constraints as a whole, it means we incorrectly accept the fourth explicit specialization which writes #3's constraints in a different way. For complete correctness here, determine_specialization should use tsubst_each_template_parm_constraints and template_parameter_heads_equivalent_p. PR c++/100374 gcc/cp/ChangeLog: * pt.cc (determine_specialization): Compare overall constraints not just the trailing constraints. (tsubst_each_template_parm_constraints): Define. (tsubst_friend_function): Use it. (tsubst_friend_class): Use it. (tsubst_template_parm): Don't substitute TEMPLATE_PARM_CONSTRAINTS. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-spec2.C: New test. * g++.dg/cpp2a/concepts-template-parm11.C: New test.
- Loading branch information
Patrick Palka
committed
Jun 3, 2022
1 parent
df4f95d
commit 43c013d
Showing
3 changed files
with
71 additions
and
7 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// { dg-do compile { target c++20 } } | ||
|
||
template<class T, int> concept C = true; | ||
|
||
template<class T> struct A { | ||
template<C<sizeof(T)> U> void f(); // #1 | ||
template<C<0> U> void f(); // #2 | ||
template<C<-1> U> void f(); // #3 | ||
}; | ||
|
||
constexpr int n = sizeof(int); | ||
template<> template<C<n> U> void A<int>::f() { } // matches #1 | ||
template<> template<C<0> U> void A<int>::f() { } // matches #2 | ||
template<> template<C<-2> U> void A<int>::f() { } // no match { dg-error "match" } | ||
template<> template<class U> void A<int>::f() requires C<U, -1> { } // shouldn't match #3 | ||
// { dg-error "match" "" { xfail *-*-* } .-1 } |
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,20 @@ | ||
// PR c++/100374 | ||
// { dg-do compile { target c++20 } } | ||
|
||
template<class T, class U> | ||
concept C = requires { typename T; }; | ||
|
||
template<class T> | ||
struct A { | ||
template<C<typename T::value_type> U> | ||
void f(); | ||
|
||
template<C<typename T::value_type> U> | ||
struct B; | ||
}; | ||
|
||
int main() { | ||
A<int> a; | ||
a.f<void>(); | ||
using type = A<int>::B<void>; | ||
} |