diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d37a4411fb6575e7e8f27b51dd1494ef1175a9cf..a2b33deac3fa12b2d4aa0f9b1a8ba58ea4abd9b7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2011-11-28 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. + 2011-11-28 Georg-Johann Lay <avr@gjlay.de> * doc/extend.texi (AVR Built-in Functions): Add documentation for diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a6a077c9b88a2ef6b8db341b5c63e42747508ff3..72c3fac85e71eb32cfda34252e7c75e53eac45c4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-11-28 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/50682 + * g++.dg/opt/pr50682.C: New test. + 2011-11-28 Tobias Burnus <burnus@net-b.de> PR fortran/51308 diff --git a/gcc/testsuite/g++.dg/opt/pr50682.C b/gcc/testsuite/g++.dg/opt/pr50682.C new file mode 100644 index 0000000000000000000000000000000000000000..b7e91f45d73dff5edfffad6bdde44370b44c01c0 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr50682.C @@ -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 (); +} diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 440ac0f4082d42804db1c2fd3ed9c59549d5f6ea..5faeefed55fa8d0344971479687c65a9278e1c17 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -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. */ diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 211c1079f3c410dc836855485314a351e5b9dd3e..ded7a3f9fac6ac1269f856fe84ef97dd45f66062 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -789,6 +789,7 @@ extern bool maybe_duplicate_eh_stmt_fn (struct function *, gimple, 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; diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c index 5479d9026a6eac69032e41c158493173e3394a83..2f6b394111dc8e190b50607d5bbb1ee5da366046 100644 --- a/gcc/tree-optimize.c +++ b/gcc/tree-optimize.c @@ -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)