diff options
author | Richard Biener <rguenther@suse.de> | 2025-04-14 11:42:18 +0200 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2025-04-14 13:00:40 +0200 |
commit | a48f934211434cac1be951c207ee76e4b4340fac (patch) | |
tree | a08571412075cd57fcf87302e0fd76dbac4bb660 /gcc | |
parent | 9e0a98a47c98fd159a26de4433a3ed1d85afb8c3 (diff) | |
download | gcc-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.C | 20 | ||||
-rw-r--r-- | 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 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) |