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