public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c++: explicit spec of constrained member tmpl [PR107522]
@ 2022-12-01 16:37 Patrick Palka
  2022-12-01 19:15 ` Jason Merrill
  0 siblings, 1 reply; 6+ messages in thread
From: Patrick Palka @ 2022-12-01 16:37 UTC (permalink / raw)
  To: gcc-patches; +Cc: jason, Patrick Palka

When defining a explicit specialization of a constrained member template
(of a class template) such as f and g in the below testcase, the
DECL_TEMPLATE_PARMS of the corresponding TEMPLATE_DECL are partially
instantiated, whereas its associated constraints are carried over
from the original template and thus are in terms of the original
DECL_TEMPLATE_PARMS.  So during normalization for such an explicit
specialization we need to consider the (parameters of) the most general
template, since that's what the constraints are in terms of and since we
always use the full set of template arguments during satisfaction.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk and perhaps 12?

	PR c++/107522

gcc/cp/ChangeLog:

	* constraint.cc (get_normalized_constraints_from_decl): Use the
	most general template for an explicit specialization of a
	member template.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp2a/concepts-explicit-spec7.C: New test.
---
 gcc/cp/constraint.cc                          | 18 ++++++++---
 .../g++.dg/cpp2a/concepts-explicit-spec7.C    | 31 +++++++++++++++++++
 2 files changed, 44 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-explicit-spec7.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index ab0f66b3d7e..f1df84c2a1c 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -973,11 +973,19 @@ get_normalized_constraints_from_decl (tree d, bool diag = false)
      accepting the latter causes the template parameter level of U
      to be reduced in a way that makes it overly difficult substitute
      concrete arguments (i.e., eventually {int, int} during satisfaction.  */
-  if (tmpl)
-  {
-    if (DECL_LANG_SPECIFIC(tmpl) && !DECL_TEMPLATE_SPECIALIZATION (tmpl))
-      tmpl = most_general_template (tmpl);
-  }
+  if (tmpl && DECL_LANG_SPECIFIC (tmpl)
+      && (!DECL_TEMPLATE_SPECIALIZATION (tmpl)
+	  /* DECL_TEMPLATE_SPECIALIZATION means we're dealing with either a
+	     partial specialization or an explicit specialization of a member
+	     template.  In the former case all is well: the constraints are in
+	     terms in TMPL's parameters.  But in the latter case TMPL's
+	     parameters are partially instantiated whereas its constraints
+	     aren't, so we need to consider (the parameters of) the most
+	     general template.  The following test distinguishes between a
+	     partial specialization and such an explicit specialization.  */
+	  || (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl))
+	      < TMPL_ARGS_DEPTH (DECL_TI_ARGS (tmpl)))))
+    tmpl = most_general_template (tmpl);
 
   d = tmpl ? tmpl : decl;
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-explicit-spec7.C b/gcc/testsuite/g++.dg/cpp2a/concepts-explicit-spec7.C
new file mode 100644
index 00000000000..5b5a6df20ff
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-explicit-spec7.C
@@ -0,0 +1,31 @@
+// PR c++/107522
+// { dg-do compile { target c++20 } }
+
+template<class T>
+struct A
+{
+  template<int N>
+  static void f() requires (N == 42);
+
+  template<class U>
+  struct B {
+    template<int N>
+    static void g() requires (T(N) == 42);
+  };
+};
+
+template<>
+template<int N>
+void A<int>::f() requires (N == 42) { }
+
+template<>
+template<>
+template<int N>
+void A<int>::B<int>::g() requires (int(N) == 42) { }
+
+int main() {
+  A<int>::f<42>();
+  A<int>::f<43>(); // { dg-error "no match" }
+  A<int>::B<int>::g<42>();
+  A<int>::B<int>::g<43>(); // { dg-error "no match" }
+}
-- 
2.39.0.rc0.49.g083e01275b


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-12-02 16:16 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-01 16:37 [PATCH] c++: explicit spec of constrained member tmpl [PR107522] Patrick Palka
2022-12-01 19:15 ` Jason Merrill
2022-12-01 19:51   ` Patrick Palka
2022-12-01 21:17     ` Jason Merrill
2022-12-02 14:30       ` Patrick Palka
2022-12-02 16:16         ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).