diff mbox

Run remove_unreachable_handlers before expansion if needed (PR tree-optimization/50682)

Message ID 20111123204239.GF27242@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Nov. 23, 2011, 8:42 p.m. UTC
Hi!

As mentioned in the PR, if gimple_purge_dead_eh_edges is ever called
after ehcleanup2 pass (or in its after todos as in the testcase below),
nothing removes the unreachable EH regions and we crash either in
cleanup_dead_labels_eh or, if we ignore those there, later on during
emitting of exception info.

We could run remove_unreachable_handlers unconditionally again shortly
before expansion, but that needs a walk of all stmts, so this
patch chooses to do it only if it sees some landing pads got removed.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2011-11-23  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/50682
	* tree-eh.c (maybe_remove_unreachable_handlers): New function.
	* tree-flow.h (maybe_remove_unreachable_handlers): New prototype.
	* tree-optimize.c (execute_cleanup_cfg_post_optimizing): Call it.

	* g++.dg/opt/pr50682.C: New test.


	Jakub

Comments

Jeff Law Nov. 28, 2011, 7:47 p.m. UTC | #1
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 11/23/11 13:42, Jakub Jelinek wrote:
> Hi!
> 
> As mentioned in the PR, if gimple_purge_dead_eh_edges is ever
> called after ehcleanup2 pass (or in its after todos as in the
> testcase below), nothing removes the unreachable EH regions and we
> crash either in cleanup_dead_labels_eh or, if we ignore those
> there, later on during emitting of exception info.
> 
> We could run remove_unreachable_handlers unconditionally again
> shortly before expansion, but that needs a walk of all stmts, so
> this patch chooses to do it only if it sees some landing pads got
> removed.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk?
> 
> 2011-11-23  Jakub Jelinek  <jakub@redhat.com>
> 
> PR tree-optimization/50682 * tree-eh.c
> (maybe_remove_unreachable_handlers): New function. * tree-flow.h
> (maybe_remove_unreachable_handlers): New prototype. *
> tree-optimize.c (execute_cleanup_cfg_post_optimizing): Call it.
> 
> * g++.dg/opt/pr50682.C: New test.
OK.
jeff
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJO0+VXAAoJEBRtltQi2kC7KHsH/3lnrTb35gC1Qomuqwjx5bxe
CigQq/U1li55183bUDgNlKVWg3T/EtZO+QFtsdcy+e6lNZD7RebuNfIzz9rO8AT2
ra8Gj9Lz9fmZflhO64qvK+ti6k6n3/3wkM7e7b3z4+hWZWbf0OT9YI5eU/rfy6c7
57ylnZU5xGV6tvA16v7VTPoUQ2u2Pkan9PgRG8E+YZo7xTz0oxHM9o6CZe7VAPf5
rxvAY1KSBS16RNvCxtaZfBxpf8BdgOIF2wW7hWwfoyjtSk8DItFRRuD262AX3Z4R
Ka83fO+ukTnz1UUTPPzxszX0ZDAsqzD0iD3sjzh9PQcEvgiriVJcWrwvavMVLfg=
=Cmlo
-----END PGP SIGNATURE-----
diff mbox

Patch

--- gcc/tree-eh.c.jj	2011-11-08 23:35:12.000000000 +0100
+++ gcc/tree-eh.c	2011-11-23 17:32:10.726659121 +0100
@@ -3473,6 +3473,29 @@  remove_unreachable_handlers (void)
 #endif
 }
 
+/* Remove unreachable handlers if any landing pads have been removed after
+   last ehcleanup pass (due to gimple_purge_dead_eh_edges).  */
+
+void
+maybe_remove_unreachable_handlers (void)
+{
+  eh_landing_pad lp;
+  int i;
+
+  if (cfun->eh == NULL)
+    return;
+              
+  for (i = 1; VEC_iterate (eh_landing_pad, cfun->eh->lp_array, i, lp); ++i)
+    if (lp && lp->post_landing_pad)
+      {
+	if (label_to_block (lp->post_landing_pad) == NULL)
+	  {
+	    remove_unreachable_handlers ();
+	    return;
+	  }
+      }
+}
+
 /* Remove regions that do not have landing pads.  This assumes
    that remove_unreachable_handlers has already been run, and
    that we've just manipulated the landing pads since then.  */
--- gcc/tree-flow.h.jj	2011-11-08 23:35:12.000000000 +0100
+++ gcc/tree-flow.h	2011-11-23 17:33:27.211192957 +0100
@@ -789,6 +789,7 @@  extern bool maybe_duplicate_eh_stmt_fn (
 extern bool maybe_duplicate_eh_stmt (gimple, gimple);
 extern bool verify_eh_edges (gimple);
 extern bool verify_eh_dispatch_edge (gimple);
+extern void maybe_remove_unreachable_handlers (void);
 
 /* In tree-ssa-pre.c  */
 struct pre_expr_d;
--- gcc/tree-optimize.c.jj	2011-08-18 08:36:01.000000000 +0200
+++ gcc/tree-optimize.c	2011-11-23 17:34:12.661916087 +0100
@@ -159,6 +159,7 @@  static unsigned int
 execute_cleanup_cfg_post_optimizing (void)
 {
   cleanup_tree_cfg ();
+  maybe_remove_unreachable_handlers ();
   cleanup_dead_labels ();
   group_case_labels ();
   if ((flag_compare_debug_opt || flag_compare_debug)
--- gcc/testsuite/g++.dg/opt/pr50682.C.jj	2011-11-23 17:40:01.352786764 +0100
+++ gcc/testsuite/g++.dg/opt/pr50682.C	2011-11-23 17:39:20.000000000 +0100
@@ -0,0 +1,39 @@ 
+// PR tree-optimization/50682
+// { dg-do compile }
+// { dg-options "-O2 -fnon-call-exceptions -ftracer -fno-tree-ccp -fno-tree-copy-prop -fno-tree-dce" }
+
+void foo () __attribute__ ((__noreturn__));
+int baz ();
+
+const int &
+bar (const int &x, const int &y)
+{
+  if (x >= y)
+    return y;
+  return x;
+}
+
+int a, b;
+
+struct S
+{
+  ~S ();
+  bool m ()
+  {
+    int l = bar (a, b);
+    int r = baz ();
+    if (r)
+        r = l;
+      return r;
+  }
+};
+
+void
+test ()
+{
+  S s;
+  if (!s.m ())
+    foo ();
+  if (!s.m ())
+    foo ();
+}