Message ID | 20240707002242.2511253-1-ppalka@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: xobj fn call without obj [PR115783] | expand |
On Sat, Jul 6, 2024 at 8:22 PM Patrick Palka <ppalka@redhat.com> wrote: > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this > look OK for trunk/14? Ping. > > -- >8 -- > > The code path for rejecting an object-less call to a non-static > member function should also consider xobj member functions so > that we properly reject the below calls with a "cannot call > member function without object" diagnostic. > > PR c++/115783 > > gcc/cp/ChangeLog: > > * call.cc (build_new_method_call): Generalize METHOD_TYPE > check to DECL_OBJECT_MEMBER_FUNCTION_P. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp23/explicit-obj-diagnostics11.C: New test. > --- > gcc/cp/call.cc | 2 +- > .../g++.dg/cpp23/explicit-obj-diagnostics11.C | 48 +++++++++++++++++++ > 2 files changed, 49 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics11.C > > diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc > index 83070b2f633..41ef7562f27 100644 > --- a/gcc/cp/call.cc > +++ b/gcc/cp/call.cc > @@ -11822,7 +11822,7 @@ build_new_method_call (tree instance, tree fns, vec<tree, va_gc> **args, > fn); > } > > - if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE > + if (DECL_OBJECT_MEMBER_FUNCTION_P (fn) > && !DECL_CONSTRUCTOR_P (fn) > && is_dummy_object (instance)) > { > diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics11.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics11.C > new file mode 100644 > index 00000000000..cc2571f62a2 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics11.C > @@ -0,0 +1,48 @@ > +// PR c++/115783 > +// { dg-do compile { target c++23 } } > + > +struct A { > + int f(this auto); > + > + static void s() { > + f(); // { dg-error "without object" } > + } > +}; > + > +int n = A::f(); // { dg-error "without object" } > + > +struct B { > + void ns() { > + A::f(); // { dg-error "without object" } > + } > + > + static void s() { > + A::f(); // { dg-error "without object" } > + } > +}; > + > +template<class T> > +struct C { > + void ns() { > + A::f(); // { dg-error "without object" } > + T::f(); // { dg-error "without object" } > + } > + > + static void s() { > + A::f(); // { dg-error "without object" } > + T::f(); // { dg-error "without object" } > + }; > +}; > + > +template struct C<A>; > + > +template<class T> > +struct D : T { > + void ns() { > + A::f(); // { dg-error "without object" } > + T::f(); // { dg-error "not a member of 'B'" } > + } > +}; > + > +template struct D<B>; // { dg-message "required from here" } > +template struct D<A>; // { dg-bogus "required from here" } > -- > 2.45.2.746.g06e570c0df >
On 7/6/24 8:22 PM, Patrick Palka wrote: > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this > look OK for trunk/14? OK. > -- >8 -- > > The code path for rejecting an object-less call to a non-static > member function should also consider xobj member functions so > that we properly reject the below calls with a "cannot call > member function without object" diagnostic. > > PR c++/115783 > > gcc/cp/ChangeLog: > > * call.cc (build_new_method_call): Generalize METHOD_TYPE > check to DECL_OBJECT_MEMBER_FUNCTION_P. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp23/explicit-obj-diagnostics11.C: New test. > --- > gcc/cp/call.cc | 2 +- > .../g++.dg/cpp23/explicit-obj-diagnostics11.C | 48 +++++++++++++++++++ > 2 files changed, 49 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics11.C > > diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc > index 83070b2f633..41ef7562f27 100644 > --- a/gcc/cp/call.cc > +++ b/gcc/cp/call.cc > @@ -11822,7 +11822,7 @@ build_new_method_call (tree instance, tree fns, vec<tree, va_gc> **args, > fn); > } > > - if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE > + if (DECL_OBJECT_MEMBER_FUNCTION_P (fn) > && !DECL_CONSTRUCTOR_P (fn) > && is_dummy_object (instance)) > { > diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics11.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics11.C > new file mode 100644 > index 00000000000..cc2571f62a2 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics11.C > @@ -0,0 +1,48 @@ > +// PR c++/115783 > +// { dg-do compile { target c++23 } } > + > +struct A { > + int f(this auto); > + > + static void s() { > + f(); // { dg-error "without object" } > + } > +}; > + > +int n = A::f(); // { dg-error "without object" } > + > +struct B { > + void ns() { > + A::f(); // { dg-error "without object" } > + } > + > + static void s() { > + A::f(); // { dg-error "without object" } > + } > +}; > + > +template<class T> > +struct C { > + void ns() { > + A::f(); // { dg-error "without object" } > + T::f(); // { dg-error "without object" } > + } > + > + static void s() { > + A::f(); // { dg-error "without object" } > + T::f(); // { dg-error "without object" } > + }; > +}; > + > +template struct C<A>; > + > +template<class T> > +struct D : T { > + void ns() { > + A::f(); // { dg-error "without object" } > + T::f(); // { dg-error "not a member of 'B'" } > + } > +}; > + > +template struct D<B>; // { dg-message "required from here" } > +template struct D<A>; // { dg-bogus "required from here" }
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 83070b2f633..41ef7562f27 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -11822,7 +11822,7 @@ build_new_method_call (tree instance, tree fns, vec<tree, va_gc> **args, fn); } - if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE + if (DECL_OBJECT_MEMBER_FUNCTION_P (fn) && !DECL_CONSTRUCTOR_P (fn) && is_dummy_object (instance)) { diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics11.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics11.C new file mode 100644 index 00000000000..cc2571f62a2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics11.C @@ -0,0 +1,48 @@ +// PR c++/115783 +// { dg-do compile { target c++23 } } + +struct A { + int f(this auto); + + static void s() { + f(); // { dg-error "without object" } + } +}; + +int n = A::f(); // { dg-error "without object" } + +struct B { + void ns() { + A::f(); // { dg-error "without object" } + } + + static void s() { + A::f(); // { dg-error "without object" } + } +}; + +template<class T> +struct C { + void ns() { + A::f(); // { dg-error "without object" } + T::f(); // { dg-error "without object" } + } + + static void s() { + A::f(); // { dg-error "without object" } + T::f(); // { dg-error "without object" } + }; +}; + +template struct C<A>; + +template<class T> +struct D : T { + void ns() { + A::f(); // { dg-error "without object" } + T::f(); // { dg-error "not a member of 'B'" } + } +}; + +template struct D<B>; // { dg-message "required from here" } +template struct D<A>; // { dg-bogus "required from here" }