diff options
author | Patrick Palka <ppalka@redhat.com> | 2020-06-03 16:37:24 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2020-06-03 16:40:34 -0400 |
commit | c06280ac4c34b0aff8cfa2e74ae8c7afd759d52f (patch) | |
tree | 23209ade8805880d036eb64aed9ecc4f95270a42 | |
parent | aee69073cdb8086d393f12474c6177e75467ceaa (diff) | |
download | gcc-c06280ac4c34b0aff8cfa2e74ae8c7afd759d52f.zip gcc-c06280ac4c34b0aff8cfa2e74ae8c7afd759d52f.tar.gz gcc-c06280ac4c34b0aff8cfa2e74ae8c7afd759d52f.tar.bz2 |
c++: more constrained nested partial specialization
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.
-rw-r--r-- | gcc/cp/pt.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec8.C | 14 |
2 files changed, 15 insertions, 1 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f5d1442..c07a48f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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 index 0000000..873cf44 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec8.C @@ -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> {}; +}; |