diff --git a/gcc/function.cc b/gcc/function.cc index d3da20ede7f..361aa5f7ed1 100644 --- a/gcc/function.cc +++ b/gcc/function.cc @@ -6546,7 +6546,7 @@ make_pass_leaf_regs (gcc::context *ctxt) } static unsigned int -rest_of_handle_thread_prologue_and_epilogue (void) +rest_of_handle_thread_prologue_and_epilogue (function *fun) { /* prepare_shrink_wrap is sensitive to the block structure of the control flow graph, so clean it up first. */ @@ -6563,6 +6563,13 @@ rest_of_handle_thread_prologue_and_epilogue (void) Fix that up. */ fixup_partitions (); + /* After prologue and epilogue generation, the judgement on whether + one memory access onto stack frame may trap or not could change, + since we get more exact stack information by now. So try to + remove any EH edges here, see PR90259. */ + if (fun->can_throw_non_call_exceptions) + purge_all_dead_edges (); + /* Shrink-wrapping can result in unreachable edges in the epilogue, see PR57320. */ cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0); @@ -6631,9 +6638,9 @@ public: {} /* opt_pass methods: */ - unsigned int execute (function *) final override + unsigned int execute (function * fun) final override { - return rest_of_handle_thread_prologue_and_epilogue (); + return rest_of_handle_thread_prologue_and_epilogue (fun); } }; // class pass_thread_prologue_and_epilogue diff --git a/gcc/testsuite/g++.target/powerpc/pr90259.C b/gcc/testsuite/g++.target/powerpc/pr90259.C new file mode 100644 index 00000000000..db75ac7fe02 --- /dev/null +++ b/gcc/testsuite/g++.target/powerpc/pr90259.C @@ -0,0 +1,103 @@ +/* { dg-require-effective-target long_double_ibm128 } */ +/* { dg-options "-O2 -ffloat-store -fgcse -fnon-call-exceptions -fno-forward-propagate -fno-omit-frame-pointer -fstack-protector-all" } */ +/* { dg-add-options long_double_ibm128 } */ + +/* Verify there is no ICE. */ + +template struct b +{ + static constexpr int c = a; +}; +template using d = b; +struct e +{ + int f; + int + g () + { + return __builtin_ceil (f / (long double) h); + } + float h; +}; +template using k = d; +template class n +{ +public: + e ae; + void af (); +}; +template +void +n::af () +{ + ae.g (); +} +template using m = int; +template ::c>> +using aj = n; +struct o +{ + void + af () + { + al.af (); + } + aj al; +}; +template class am; +template class ao +{ +protected: + static i *ap (int); +}; +template class p; +template class p : ao +{ +public: + static ar + as (const int &p1, j...) + { + (*ao::ap (p1)) (j ()...); + } +}; +template class am +{ + template using av = int; + +public: + template , void>, + typename = av> + am (i); + using aw = ar (*) (const int &, j...); + aw ax; +}; +template +template +am::am (i) +{ + ax = p::as; +} +struct G +{ + void ba (am); +}; +struct q +{ + q () + { + G a; + a.ba (r ()); + } + struct r + { + void + operator() (o p1) + try + { + p1.af (); + } + catch (int) + { + } + }; +} s;