[PATCH] Fix ICE caused by nothrow pass (PR c++/70641)
Jakub Jelinek
jakub@redhat.com
Wed Apr 13 17:34:00 GMT 2016
Hi!
If the nothrow pass (which is GIMPLE, not IPA pass) determines that the
current function can't throw externally, it marks it nothrow.
But it fails to adjust self-recursive calls, which might change because of
that from possibly throwing to not being able to throw, so we need to
cleanup the EH region, purge dead eh edges and adjust CFG if needed.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2016-04-13 Jakub Jelinek <jakub@redhat.com>
PR c++/70641
* ipa-pure-const.c (pass_nothrow::execute): Call maybe_clean_eh_stmt
on all recursive call stmts. Return TODO_cleanup_cfg if any dead
eh edges have been purged.
* g++.dg/opt/pr70641.C: New test.
--- gcc/ipa-pure-const.c.jj 2016-04-13 15:53:01.051799840 +0200
+++ gcc/ipa-pure-const.c 2016-04-13 16:03:10.715556547 +0200
@@ -1956,10 +1956,28 @@ pass_nothrow::execute (function *)
}
node->set_nothrow_flag (true);
+
+ bool cfg_changed = false;
+ if (self_recursive_p (node))
+ FOR_EACH_BB_FN (this_block, cfun)
+ for (gimple_stmt_iterator gsi = gsi_start_bb (this_block);
+ !gsi_end_p (gsi);
+ gsi_next (&gsi))
+ if (is_gimple_call (gsi_stmt (gsi)))
+ {
+ gimple *g = gsi_stmt (gsi);
+ tree callee_t = gimple_call_fndecl (g);
+ if (callee_t
+ && recursive_call_p (current_function_decl, callee_t)
+ && maybe_clean_eh_stmt (g)
+ && gimple_purge_dead_eh_edges (gimple_bb (g)))
+ cfg_changed = true;
+ }
+
if (dump_file)
fprintf (dump_file, "Function found to be nothrow: %s\n",
current_function_name ());
- return 0;
+ return cfg_changed ? TODO_cleanup_cfg : 0;
}
} // anon namespace
--- gcc/testsuite/g++.dg/opt/pr70641.C.jj 2016-04-13 16:01:16.381102468 +0200
+++ gcc/testsuite/g++.dg/opt/pr70641.C 2016-04-13 16:01:16.381102468 +0200
@@ -0,0 +1,10 @@
+// PR c++/70641
+// { dg-do compile }
+// { dg-options "-O2" }
+
+void
+foo ()
+{
+ try { foo (); }
+ catch (...) { __builtin_abort (); }
+}
Jakub
More information about the Gcc-patches
mailing list