Message ID | 20111123204239.GF27242@tyan-ft48-01.lab.bos.redhat.com |
---|---|
State | New |
Headers | show |
-----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-----
--- 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 (); +}