aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2025-04-14 11:42:18 +0200
committerRichard Biener <rguenth@gcc.gnu.org>2025-04-14 13:00:40 +0200
commita48f934211434cac1be951c207ee76e4b4340fac (patch)
treea08571412075cd57fcf87302e0fd76dbac4bb660 /gcc
parent9e0a98a47c98fd159a26de4433a3ed1d85afb8c3 (diff)
downloadgcc-a48f934211434cac1be951c207ee76e4b4340fac.zip
gcc-a48f934211434cac1be951c207ee76e4b4340fac.tar.gz
gcc-a48f934211434cac1be951c207ee76e4b4340fac.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/g++.dg/torture/pr119778.C20
-rw-r--r--gcc/tree-inline.cc7
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 0000000..4948056
--- /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 05843b8..3289b4f 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)