On Tue, Dec 28, 2021 at 10:08 AM Patrick Palka <ppa...@redhat.com> wrote: > > Here during satisfaction of B's associated constraints we're failing to > reject the object-less call to the non-static member function A::size > ultimately because satisfaction is performed in the (access) context of > the class template B, which has a dependent bases, and so the > any_dependent_bases_p check within build_new_method_call causes us to > avoid rejecting the call. > > This patch fixes this by refining the any_dependent_bases_p check within > build_new_method_call: dependent bases can't make a difference for > resolving the implicit object parameter if we're in a conext where > 'this' is unavailable, so let's check current_class_ptr too. > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > trunk and perhaps 11? The first testcase exhibits a regression > introduced by r12-1937.
D'oh, never mind about the backport request since this is at worst a 12 regression. > > PR c++/103831 > > gcc/cp/ChangeLog: > > * call.c (build_new_method_call): Consider dependent bases only > if 'this' is available. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp2a/concepts-class3.C: New test. > * g++.dg/template/non-dependent18.C: New test. > --- > gcc/cp/call.c | 2 +- > gcc/testsuite/g++.dg/cpp2a/concepts-class3.C | 12 ++++++++++++ > .../g++.dg/template/non-dependent18.C | 19 +++++++++++++++++++ > 3 files changed, 32 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-class3.C > create mode 100644 gcc/testsuite/g++.dg/template/non-dependent18.C > > diff --git a/gcc/cp/call.c b/gcc/cp/call.c > index bee367f57d7..3da9e7a6284 100644 > --- a/gcc/cp/call.c > +++ b/gcc/cp/call.c > @@ -11098,7 +11098,7 @@ build_new_method_call (tree instance, tree fns, > vec<tree, va_gc> **args, > we know we really need it. */ > cand->first_arg = instance; > } > - else if (any_dependent_bases_p ()) > + else if (current_class_ptr && any_dependent_bases_p ()) > /* We can't tell until instantiation time whether we can use > *this as the implicit object argument. */; > else > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-class3.C > b/gcc/testsuite/g++.dg/cpp2a/concepts-class3.C > new file mode 100644 > index 00000000000..68b50b71278 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-class3.C > @@ -0,0 +1,12 @@ > +// PR c++/103831 > +// { dg-do compile { target c++20 } } > + > +struct A { > + constexpr int size() { return 42; } // non-static > +}; > + > +template<class T> > + requires (T::size() == 42) // { dg-error "without object" } > +struct B : T { }; > + > +template struct B<A>; // { dg-error "constraint" } > diff --git a/gcc/testsuite/g++.dg/template/non-dependent18.C > b/gcc/testsuite/g++.dg/template/non-dependent18.C > new file mode 100644 > index 00000000000..7fe623d497f > --- /dev/null > +++ b/gcc/testsuite/g++.dg/template/non-dependent18.C > @@ -0,0 +1,19 @@ > +// PR c++/103831 > +// { dg-do compile { target c++11 } } > + > +struct A { > + constexpr int size() { return 42; } // non-static > +}; > + > +template<class T> > +struct B : T { > + static_assert(A::size() == 42); // { dg-error "without object" } > + > + static int f() { > + static_assert(A::size() == 42, ""); // { dg-error "without object" } > + return A::size(); // { dg-error "without object" } > + } > + > + int n = A::size(); > + static const int m = A::size(); // { dg-error "without object" } > +}; > -- > 2.34.1.390.g2ae0a9cb82 >