From 90655e30130f8f609911335902db3c8354a5e21a Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Fri, 3 Jun 2022 09:29:12 -0400 Subject: 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. (cherry picked from commit 43c013df02fdb07f9b7a5e7e6669e6d69769d451) --- gcc/testsuite/g++.dg/cpp2a/concepts-spec2.C | 16 ++++++++++++++++ .../g++.dg/cpp2a/concepts-template-parm11.C | 20 ++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-spec2.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-template-parm11.C (limited to 'gcc/testsuite') diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-spec2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-spec2.C new file mode 100644 index 00000000000..4de07352c27 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-spec2.C @@ -0,0 +1,16 @@ +// { dg-do compile { target c++20 } } + +template concept C = true; + +template struct A { + template U> void f(); // #1 + template U> void f(); // #2 + template U> void f(); // #3 +}; + +constexpr int n = sizeof(int); +template<> template U> void A::f() { } // matches #1 +template<> template U> void A::f() { } // matches #2 +template<> template U> void A::f() { } // no match { dg-error "match" } +template<> template void A::f() requires C { } // shouldn't match #3 +// { dg-error "match" "" { xfail *-*-* } .-1 } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm11.C b/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm11.C new file mode 100644 index 00000000000..498e3c175cf --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm11.C @@ -0,0 +1,20 @@ +// PR c++/100374 +// { dg-do compile { target c++20 } } + +template +concept C = requires { typename T; }; + +template +struct A { + template U> + void f(); + + template U> + struct B; +}; + +int main() { + A a; + a.f(); + using type = A::B; +} -- cgit v1.2.3