diff mbox series

[C++] Fix deleted fn handling (PR c++/92447)

Message ID 20191111201450.GA4650@tucnak
State New
Headers show
Series [C++] Fix deleted fn handling (PR c++/92447) | expand

Commit Message

Jakub Jelinek Nov. 11, 2019, 8:14 p.m. UTC
Hi!

The finish_function change to goto cleanup; on DECL_DELETED_FN added
in the spaceship commit broke the following testcase.
The problem is that during start_preparsed_function push_nested_class
pushes a scope, but as ctype is kept NULL when goto cleanup; crosses
the setting of ctype to something else, pop_nested_class isn't called
anymore and callers get upset they are in current_binding_level
of sk_class instead of what they expected.

Fixed thusly, bootstrapped/regtested on powerpc64le-linux, ok for trunk?

2019-11-11  Jakub Jelinek  <jakub@redhat.com>

	PR c++/92447
	* decl.c (finish_function): Move ctype initialization before
	DECL_DELETED_FN handling.

	* g++.dg/cpp0x/pr92447.C: New test.


	Jakub

Comments

Jason Merrill Nov. 11, 2019, 9:29 p.m. UTC | #1
OK, thanks.

On Mon, Nov 11, 2019 at 3:14 PM Jakub Jelinek <jakub@redhat.com> wrote:

> Hi!
>
> The finish_function change to goto cleanup; on DECL_DELETED_FN added
> in the spaceship commit broke the following testcase.
> The problem is that during start_preparsed_function push_nested_class
> pushes a scope, but as ctype is kept NULL when goto cleanup; crosses
> the setting of ctype to something else, pop_nested_class isn't called
> anymore and callers get upset they are in current_binding_level
> of sk_class instead of what they expected.
>
> Fixed thusly, bootstrapped/regtested on powerpc64le-linux, ok for trunk?
>
> 2019-11-11  Jakub Jelinek  <jakub@redhat.com>
>
>         PR c++/92447
>         * decl.c (finish_function): Move ctype initialization before
>         DECL_DELETED_FN handling.
>
>         * g++.dg/cpp0x/pr92447.C: New test.
>
> --- gcc/cp/decl.c.jj    2019-11-07 09:50:51.000000000 +0100
> +++ gcc/cp/decl.c       2019-11-11 15:29:17.610112820 +0100
> @@ -16803,6 +16803,10 @@ finish_function (bool inline_p)
>         }
>      }
>
> +  /* Remember that we were in class scope.  */
> +  if (current_class_name)
> +    ctype = current_class_type;
> +
>    if (DECL_DELETED_FN (fndecl))
>      {
>        DECL_INITIAL (fndecl) = error_mark_node;
> @@ -16861,10 +16865,6 @@ finish_function (bool inline_p)
>        current_function_return_value = NULL_TREE;
>      }
>
> -  /* Remember that we were in class scope.  */
> -  if (current_class_name)
> -    ctype = current_class_type;
> -
>    /* Must mark the RESULT_DECL as being in this function.  */
>    DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
>
> --- gcc/testsuite/g++.dg/cpp0x/pr92447.C.jj     2019-11-11
> 15:31:28.208138229 +0100
> +++ gcc/testsuite/g++.dg/cpp0x/pr92447.C        2019-11-11
> 15:30:29.314028624 +0100
> @@ -0,0 +1,14 @@
> +// PR c++/92447
> +// { dg-do compile { target c++11 } }
> +
> +template <typename T>
> +void
> +foo ()
> +{
> +  struct S { S &operator=(S &&x) = default; const T s{}; };
> +}
> +
> +void bar ()
> +{
> +  foo<int>();
> +}
>
>         Jakub
>
>
diff mbox series

Patch

--- gcc/cp/decl.c.jj	2019-11-07 09:50:51.000000000 +0100
+++ gcc/cp/decl.c	2019-11-11 15:29:17.610112820 +0100
@@ -16803,6 +16803,10 @@  finish_function (bool inline_p)
 	}
     }
 
+  /* Remember that we were in class scope.  */
+  if (current_class_name)
+    ctype = current_class_type;
+
   if (DECL_DELETED_FN (fndecl))
     {
       DECL_INITIAL (fndecl) = error_mark_node;
@@ -16861,10 +16865,6 @@  finish_function (bool inline_p)
       current_function_return_value = NULL_TREE;
     }
 
-  /* Remember that we were in class scope.  */
-  if (current_class_name)
-    ctype = current_class_type;
-
   /* Must mark the RESULT_DECL as being in this function.  */
   DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
 
--- gcc/testsuite/g++.dg/cpp0x/pr92447.C.jj	2019-11-11 15:31:28.208138229 +0100
+++ gcc/testsuite/g++.dg/cpp0x/pr92447.C	2019-11-11 15:30:29.314028624 +0100
@@ -0,0 +1,14 @@ 
+// PR c++/92447
+// { dg-do compile { target c++11 } }
+
+template <typename T>
+void
+foo ()
+{
+  struct S { S &operator=(S &&x) = default; const T s{}; };
+}
+
+void bar ()
+{
+  foo<int>();
+}