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" }
> 
> 

Reply via email to