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.
This commit is contained in:
Richard Biener 2025-04-14 11:42:18 +02:00 committed by Richard Biener
parent 9e0a98a47c
commit a48f934211
2 changed files with 25 additions and 2 deletions

View file

@ -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 ();
}

View 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)