diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e0772c1fe82..9aba03d6861 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2011-01-21 Jeff Law + + PR tree-optimization/47053 + * tree-ssa-dse.c (need_eh_cleanup): New bitmap. + (dse_optimize_stmt): Set the appropriate bit in NEED_EH_CLEANUP when + statements are deleted. + (tree_ssa_dse): Allocate & free NEED_EH_CLEANUP. If NEED_EH_CLEANUP + is nonempty, then purge dead edges and cleanup the CFG. + 2011-01-21 Alexandre Oliva PR debug/47402 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 95d0a778c46..1c980ac7399 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-01-21 Jeff Law + + PR tree-optimization/47053 + * g++.dg/pr47053.C: New test. + 2011-01-21 Jason Merrill PR c++/47041 diff --git a/gcc/testsuite/g++.dg/pr47053.C b/gcc/testsuite/g++.dg/pr47053.C new file mode 100644 index 00000000000..186e3a7ad10 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr47053.C @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fnon-call-exceptions" } */ +struct A +{ + int i; + virtual ~A () + {} +}; + +struct B : virtual A +{}; + +struct C : public B +{ + C (); + ~C (){} +}; + +void foo () +{ + C c; +} diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c index 80c2622c9dc..26a438d12b2 100644 --- a/gcc/tree-ssa-dse.c +++ b/gcc/tree-ssa-dse.c @@ -83,6 +83,10 @@ struct dse_block_local_data bitmap stores; }; +/* Bitmap of blocks that have had EH statements cleaned. We should + remove their dead edges eventually. */ +static bitmap need_eh_cleanup; + static bool gate_dse (void); static unsigned int tree_ssa_dse (void); static void dse_initialize_block_local_data (struct dom_walk_data *, @@ -335,6 +339,8 @@ dse_optimize_stmt (struct dse_global_data *dse_gd, /* Then we need to fix the operand of the consuming stmt. */ unlink_stmt_vdef (stmt); + bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index); + /* Remove the dead store. */ gsi_remove (&gsi, true); @@ -401,6 +407,8 @@ tree_ssa_dse (void) struct dom_walk_data walk_data; struct dse_global_data dse_gd; + need_eh_cleanup = BITMAP_ALLOC (NULL); + renumber_gimple_stmt_uids (); /* We might consider making this a property of each pass so that it @@ -435,6 +443,16 @@ tree_ssa_dse (void) /* Release the main bitmap. */ BITMAP_FREE (dse_gd.stores); + /* Removal of stores may make some EH edges dead. Purge such edges from + the CFG as needed. */ + if (!bitmap_empty_p (need_eh_cleanup)) + { + gimple_purge_all_dead_eh_edges (need_eh_cleanup); + cleanup_tree_cfg (); + } + + BITMAP_FREE (need_eh_cleanup); + /* For now, just wipe the post-dominator information. */ free_dominance_info (CDI_POST_DOMINATORS); return 0;