Message ID | 20200602214550.981432-1-ppalka@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: more constrained nested partial specialization | expand |
On 6/2/20 5:45 PM, Patrick Palka wrote: > 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 causes > strictly_subsumes to sometimes erroneously return false as in the > testcase below. > > Passes 'make check-c++' and also tested by building the testsuites of > cmcstl2 and range-v3. Does this look OK to commit to mainline and to > the 10 branch after a full bootstrap and regtest? OK. > (We shouldn't need to do any substitution from strictly_subsumes here, > since processing_template_decl would always be non-zero and so > substituting in the complete set of generic template arguments should > always be a no-op I think. I can propose this as a subsequent patch for > mainline.) Sounds good. > 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 | 2 +- > .../g++.dg/cpp2a/concepts-partial-spec8.C | 14 ++++++++++++++ > 2 files changed, 15 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec8.C > > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c > index df92f5584cf..d7f61289621 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 00000000000..873cf44e407 > --- /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> {}; > +}; >
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index df92f5584cf..d7f61289621 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 00000000000..873cf44e407 --- /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> {}; +};