When a dead EH or abnormal edge makes a call queued for noreturn fixup unreachable, just skip processing it.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. PR tree-optimization/121870 * tree-ssa-propagate.cc (substitute_and_fold_engine::substitute_and_fold): Skip removed stmts from noreturn fixup. * g++.dg/torture/pr121870.C: New testcase. --- gcc/testsuite/g++.dg/torture/pr121870.C | 20 ++++++++++++++++++++ gcc/tree-ssa-propagate.cc | 2 ++ 2 files changed, 22 insertions(+) create mode 100644 gcc/testsuite/g++.dg/torture/pr121870.C diff --git a/gcc/testsuite/g++.dg/torture/pr121870.C b/gcc/testsuite/g++.dg/torture/pr121870.C new file mode 100644 index 00000000000..8f4e7ab5069 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr121870.C @@ -0,0 +1,20 @@ +__attribute__((noreturn)) void f1(void) +{ + while(true) {} +} +static void (*fptr)(void) = f1; +struct s1 +{ + ~s1() { + fptr(); + } + void DoInner() { + fptr(); + } +}; + +void f() +{ + s1 xxx; + xxx.DoInner(); +} diff --git a/gcc/tree-ssa-propagate.cc b/gcc/tree-ssa-propagate.cc index ec206894821..872f881b644 100644 --- a/gcc/tree-ssa-propagate.cc +++ b/gcc/tree-ssa-propagate.cc @@ -1019,6 +1019,8 @@ substitute_and_fold_engine::substitute_and_fold (basic_block block) while (!walker.stmts_to_fixup.is_empty ()) { gimple *stmt = walker.stmts_to_fixup.pop (); + if (!gimple_bb (stmt)) + continue; if (dump_file && dump_flags & TDF_DETAILS) { fprintf (dump_file, "Fixing up noreturn call "); -- 2.51.0