On Tue, 23 Jul 2024, Jason Merrill wrote: > On 7/5/24 12:18 PM, Patrick Palka wrote: > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK > > for trunk/14 and perhaps 13? > > > > Alternatively we can set current_template_parms from weakly_subsumes > > instead, who has only one caller anyway. > > Would it also work to pass tmpl instead of NULL_TREE to > get_normalized_constraints_from_info in weakly_subsumes?
That seems to work nicely too since ci has been rewritten in terms of tmpl's constraints by the caller. I briefly considered that earlier but confused myself into thinking that wouldn't do the right thing. (I might've been looking instead at strictly_subsumes where when called from process_partial_specialization we have two sets of parameters involved: tmpl's parms for the primary template and current_template_parms for the partial specialization, so we can't pass in_decl=tmpl there. Luckily current_template_parms is always properly set there though.) Like so? Bootstrap and regtest in progress. -- >8 -- Subject: [PATCH] c++: normalizing ttp constraints [PR115656] Here we normalize the constraint same_as<T, bool> for the first time during constraint subsumption checking of B / UU as part of ttp coercion. During this normalization the set of in-scope template parameters i.e. current_template_parms is empty, which tricks the satisfaction cache into thinking that the satisfaction value of the constraint is independent of its template parameters, and we incorrectly conflate the satisfaction value with T = bool vs T = long and accept the specialization A<long, B>. Since is_compatible_template_arg is the only caller of weakly_subsumes which rewrote the ttp's constraints ('ci') in terms of those of the argument template ('tmpl'), we can in turn normalize the ttp's constraints relative to tmpl's parameters rather than relying on current_template_parms by passing in_decl=tmpl from weakly_subsumes. PR c++/115656 gcc/cp/ChangeLog: * constraint.cc (weakly_subsumes): Pass in_decl=tmpl to get_normalized_constraints_from_info. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-ttp7.C: New test. --- gcc/cp/constraint.cc | 2 +- gcc/testsuite/g++.dg/cpp2a/concepts-ttp7.C | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-ttp7.C diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 5472cc51b8a..d84094762f7 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -3334,7 +3334,7 @@ strictly_subsumes (tree ci, tree tmpl) bool weakly_subsumes (tree ci, tree tmpl) { - tree n1 = get_normalized_constraints_from_info (ci, NULL_TREE); + tree n1 = get_normalized_constraints_from_info (ci, tmpl); tree n2 = get_normalized_constraints_from_decl (tmpl); return subsumes (n1, n2); diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ttp7.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ttp7.C new file mode 100644 index 00000000000..2ce884b995c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ttp7.C @@ -0,0 +1,12 @@ +// PR c++/115656 +// { dg-do compile { target c++20 } } + +template<class T, class U> concept same_as = __is_same(T, U); + +template<same_as<bool> T, template<same_as<bool>> class UU> +struct A { }; + +template<same_as<bool>> class B; + +A<bool, B> a1; +A<long, B> a2; // { dg-error "constraint failure" } -- 2.46.0.rc0.106.g1c4a234a1c > > > -- >8 -- > > > > Here we normalize the constraint same_as<auto, bool> for the first > > time during constraint subsumption checking of B / TT as part of ttp > > coercion. During this normalization the set of in-scope template > > parameters i.e. current_template_parms is empty, which tricks the > > satisfaction cache into thinking that the satisfaction value of the > > constraint is independent of its template parameters, and we incorrectly > > conflate the satisfaction value with auto = bool vs auto = long and > > accept the specialization A<long, B>. > > > > This patch fixes this by setting current_template_parms appropirately > > during subsumption checking. > > > > PR c++/115656 > > > > gcc/cp/ChangeLog: > > > > * pt.cc (is_compatible_template_arg): Set current_template_parms > > around the call to weakly_subsumes. > > > > gcc/testsuite/ChangeLog: > > > > * g++.dg/cpp2a/concepts-ttp7.C: New test. > > --- > > gcc/cp/pt.cc | 4 ++++ > > gcc/testsuite/g++.dg/cpp2a/concepts-ttp7.C | 12 ++++++++++++ > > 2 files changed, 16 insertions(+) > > create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-ttp7.C > > > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > > index 017cc7fd0ab..1f6553790a5 100644 > > --- a/gcc/cp/pt.cc > > +++ b/gcc/cp/pt.cc > > @@ -8493,6 +8493,10 @@ is_compatible_template_arg (tree parm, tree arg, tree > > args) > > return false; > > } > > + /* Normalization needs to know the effective set of in-scope > > + template parameters. */ > > + auto ctp = make_temp_override (current_template_parms, > > + DECL_TEMPLATE_PARMS (arg)); > > return weakly_subsumes (parm_cons, arg); > > } > > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ttp7.C > > b/gcc/testsuite/g++.dg/cpp2a/concepts-ttp7.C > > new file mode 100644 > > index 00000000000..bc123ecf75e > > --- /dev/null > > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ttp7.C > > @@ -0,0 +1,12 @@ > > +// PR c++/115656 > > +// { dg-do compile { target c++20 } } > > + > > +template<class T, class U> concept same_as = __is_same(T, U); > > + > > +template<same_as<bool> U, template<same_as<bool>> class TT> > > +struct A { }; > > + > > +template<same_as<bool>> class B; > > + > > +A<bool, B> a1; > > +A<long, B> a2; // { dg-error "constraint failure" } > >