https://gcc.gnu.org/g:a48f934211434cac1be951c207ee76e4b4340fac

commit r15-9422-ga48f934211434cac1be951c207ee76e4b4340fac
Author: Richard Biener <rguent...@suse.de>
Date:   Mon Apr 14 11:42:18 2025 +0200

    tree-optimization/119778 - properly mark abnormal edge sources during 
inlining
    
    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.

Diff:
---
 gcc/testsuite/g++.dg/torture/pr119778.C | 20 ++++++++++++++++++++
 gcc/tree-inline.cc                      |  7 +++++--
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/g++.dg/torture/pr119778.C 
b/gcc/testsuite/g++.dg/torture/pr119778.C
new file mode 100644
index 000000000000..494805619282
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr119778.C
@@ -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 ();
+}
diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc
index 05843b8ccf09..3289b4f6d050 100644
--- a/gcc/tree-inline.cc
+++ b/gcc/tree-inline.cc
@@ -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)

Reply via email to