]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Avoid registering __builtin_setjmp_receiver label twice [PR101347]
authorAlexander Monakov <amonakov@ispras.ru>
Tue, 19 Jul 2022 15:04:30 +0000 (18:04 +0300)
committerAlexander Monakov <amonakov@ispras.ru>
Wed, 20 Jul 2022 13:12:34 +0000 (16:12 +0300)
The testcase in the PR demonstrates how it is possible for one
__builtin_setjmp_receiver label to appear in
nonlocal_goto_handler_labels list twice (after the block with
__builtin_setjmp_setup referring to it was duplicated).

remove_node_from_insn_list did not account for this possibility and
removed only the first copy from the list. Add an assert verifying that
duplicates are not present.

To avoid adding a label to the list twice, move registration of the
label from __builtin_setjmp_setup handling to __builtin_setjmp_receiver.

gcc/ChangeLog:

PR rtl-optimization/101347
* builtins.cc (expand_builtin) [BUILT_IN_SETJMP_SETUP]: Move
population of nonlocal_goto_handler_labels from here ...
(expand_builtin) [BUILT_IN_SETJMP_RECEIVER]: ... to here.
* rtlanal.cc (remove_node_from_insn_list): Verify that a
duplicate is not present in the remainder of the list.

gcc/builtins.cc
gcc/rtlanal.cc

index 0d13197703d9388e87a64b9620663f3e26881dfc..b08b4365da36ba34fbceca2b94d99b2bb58c9e32 100644 (file)
@@ -7472,15 +7472,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode,
          tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 1), 0);
          rtx_insn *label_r = label_rtx (label);
 
-         /* This is copied from the handling of non-local gotos.  */
          expand_builtin_setjmp_setup (buf_addr, label_r);
-         nonlocal_goto_handler_labels
-           = gen_rtx_INSN_LIST (VOIDmode, label_r,
-                                nonlocal_goto_handler_labels);
-         /* ??? Do not let expand_label treat us as such since we would
-            not want to be both on the list of non-local labels and on
-            the list of forced labels.  */
-         FORCED_LABEL (label) = 0;
          return const0_rtx;
        }
       break;
@@ -7493,6 +7485,13 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode,
          rtx_insn *label_r = label_rtx (label);
 
          expand_builtin_setjmp_receiver (label_r);
+         nonlocal_goto_handler_labels
+           = gen_rtx_INSN_LIST (VOIDmode, label_r,
+                                nonlocal_goto_handler_labels);
+         /* ??? Do not let expand_label treat us as such since we would
+            not want to be both on the list of non-local labels and on
+            the list of forced labels.  */
+         FORCED_LABEL (label) = 0;
          return const0_rtx;
        }
       break;
index ec95ecd6cf955b6e5d74c4b36fd0ab00bcc45804..56da7435a283682359580a4d822183937a0205d7 100644 (file)
@@ -2899,6 +2899,7 @@ remove_node_from_insn_list (const rtx_insn *node, rtx_insn_list **listp)
          else
            *listp = temp->next ();
 
+         gcc_checking_assert (!in_insn_list_p (temp->next (), node));
          return;
        }