]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/119778 - properly mark abnormal edge sources during inlining
authorRichard Biener <rguenther@suse.de>
Mon, 14 Apr 2025 09:42:18 +0000 (11:42 +0200)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 14 Apr 2025 11:00:40 +0000 (13:00 +0200)
When inlining a call that abnormally transfers control-flow we make
all inlined calls that can possibly transfer abnormal control-flow
do so as well.  But we failed to mark the calls as altering
control-flow.  This results in inconsistent behavior later and
possibly wrong-code (we'd eventually prune those edges).

PR tree-optimization/119778
* tree-inline.cc (copy_edges_for_bb): Mark calls that are
source of abnormal edges as altering control-flow.

* g++.dg/torture/pr119778.C: New testcase.

gcc/testsuite/g++.dg/torture/pr119778.C [new file with mode: 0644]
gcc/tree-inline.cc

diff --git a/gcc/testsuite/g++.dg/torture/pr119778.C b/gcc/testsuite/g++.dg/torture/pr119778.C
new file mode 100644 (file)
index 0000000..4948056
--- /dev/null
@@ -0,0 +1,20 @@
+// { dg-do compile }
+// { dg-additional-options "-Wall" }
+
+struct jmp_buf { long l[16]; };
+extern "C" int setjmp (jmp_buf *);
+struct S {
+  void foo () { bar (); }
+  virtual char bar () { return 0; }
+};
+void baz ();
+jmp_buf *a;
+
+void
+qux (bool x, S *y)
+{
+  if (x)
+    setjmp (a);
+  y->foo ();
+  baz ();
+}
index 05843b8ccf09d3b00378119f80835d162aea65b6..3289b4f6d0509416c5f383a095f2213f4bf4a25b 100644 (file)
@@ -2729,8 +2729,11 @@ copy_edges_for_bb (basic_block bb, profile_count num, profile_count den,
                   && gimple_call_arg (copy_stmt, 0) == boolean_true_node)
            nonlocal_goto = false;
          else
-           make_single_succ_edge (copy_stmt_bb, abnormal_goto_dest,
-                                  EDGE_ABNORMAL);
+           {
+             make_single_succ_edge (copy_stmt_bb, abnormal_goto_dest,
+                                    EDGE_ABNORMAL);
+             gimple_call_set_ctrl_altering (copy_stmt, true);
+           }
        }
 
       if ((can_throw || nonlocal_goto)