[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