}
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. */
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);
{}
/* 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
--- /dev/null
+/* { 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 <int a> struct b
+{
+ static constexpr int c = a;
+};
+template <bool a> using d = b<a>;
+struct e
+{
+ int f;
+ int
+ g ()
+ {
+ return __builtin_ceil (f / (long double) h);
+ }
+ float h;
+};
+template <typename, typename> using k = d<!bool ()>;
+template <typename> class n
+{
+public:
+ e ae;
+ void af ();
+};
+template <typename l>
+void
+n<l>::af ()
+{
+ ae.g ();
+}
+template <bool> using m = int;
+template <typename ag, typename ah, typename ai = m<k<ag, ah>::c>>
+using aj = n<ai>;
+struct o
+{
+ void
+ af ()
+ {
+ al.af ();
+ }
+ aj<int, int> al;
+};
+template <typename> class am;
+template <typename i> class ao
+{
+protected:
+ static i *ap (int);
+};
+template <typename, typename> class p;
+template <typename ar, typename i, typename... j> class p<ar (j...), i> : ao<i>
+{
+public:
+ static ar
+ as (const int &p1, j...)
+ {
+ (*ao<i>::ap (p1)) (j ()...);
+ }
+};
+template <typename ar, typename... j> class am<ar (j...)>
+{
+ template <typename, typename> using av = int;
+
+public:
+ template <typename i, typename = av<d<!bool ()>, void>,
+ typename = av<i, void>>
+ am (i);
+ using aw = ar (*) (const int &, j...);
+ aw ax;
+};
+template <typename ar, typename... j>
+template <typename i, typename, typename>
+am<ar (j...)>::am (i)
+{
+ ax = p<ar (j...), i>::as;
+}
+struct G
+{
+ void ba (am<void (o)>);
+};
+struct q
+{
+ q ()
+ {
+ G a;
+ a.ba (r ());
+ }
+ struct r
+ {
+ void
+ operator() (o p1)
+ try
+ {
+ p1.af ();
+ }
+ catch (int)
+ {
+ }
+ };
+} s;