c++: more constrained nested partial specialization
authorPatrick Palka <ppalka@redhat.com>
Wed, 3 Jun 2020 20:37:24 +0000 (16:37 -0400)
committerPatrick Palka <ppalka@redhat.com>
Wed, 3 Jun 2020 20:40:34 +0000 (16:40 -0400)
When checking that a constrained partial specialization is more
constrained than the primary template, we pass only the innermost level
of generic template arguments to strictly_subsumes.  This leads to us
doing a nonsensical substitution from normalize_concept_check if the
full set of template arguments has multiple levels, and it ultimately
causes strictly_subsumes to sometimes erroneously return false as in the
testcase below.

gcc/cp/ChangeLog:

* pt.c (process_partial_specialization): Pass the full set of
generic template arguments to strictly_subsumes.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/concepts-partial-spec8.C: New test.

gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec8.C [new file with mode: 0644]

index f5d1442a4004d9c00839dadd298a5a4650139350..c07a48f1261b60c8c21960cb305358560f262846 100644 (file)
@@ -5062,7 +5062,7 @@ process_partial_specialization (tree decl)
   if (comp_template_args (inner_args, INNERMOST_TEMPLATE_ARGS (main_args))
       && (!flag_concepts
          || !strictly_subsumes (current_template_constraints (),
-                                inner_args, maintmpl)))
+                                main_args, maintmpl)))
     {
       if (!flag_concepts)
         error ("partial specialization %q+D does not specialize "
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec8.C b/gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec8.C
new file mode 100644 (file)
index 0000000..873cf44
--- /dev/null
@@ -0,0 +1,14 @@
+// { dg-do compile { target c++20 } }
+
+template<int M, int N>
+concept equal = M == N;
+
+template<int M>
+struct traits
+{
+  template<int N> requires equal<M, N>
+    struct foo {};
+
+  template<int N> requires equal<M, N> && (M >= 0) // { dg-bogus "not more constrained" }
+    struct foo<N> {};
+};