diff mbox series

c++: xobj fn call without obj [PR115783]

Message ID 20240707002242.2511253-1-ppalka@redhat.com
State New
Headers show
Series c++: xobj fn call without obj [PR115783] | expand

Commit Message

Patrick Palka July 7, 2024, 12:22 a.m. UTC
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this
look OK for trunk/14?

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

Comments

Patrick Palka July 19, 2024, 2:55 p.m. UTC | #1
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
>
Jason Merrill July 19, 2024, 4:03 p.m. UTC | #2
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 mbox series

Patch

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