diff --git a/gcc/testsuite/g++.dg/torture/pr119778.C b/gcc/testsuite/g++.dg/torture/pr119778.C new file mode 100644 index 00000000000..49480561928 --- /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 05843b8ccf0..3289b4f6d05 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)