diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8854cd7a2b6..567c09a6ff0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2014-06-24 Chung-Lin Tang + + PR tree-optimization/61554 + * tree-ssa-propagate.c: Include "bitmap.h". + (substitute_and_fold_dom_walker): Add 'bitmap need_eh_cleanup' member, + properly update constructor/destructor. + (substitute_and_fold_dom_walker::before_dom_children): + Remove call to gimple_purge_dead_eh_edges, add bb->index to + need_eh_cleaup instead. + (substitute_and_fold): Call gimple_purge_all_dead_eh_edges on + need_eh_cleanup. + 2014-06-23 Jan Hubicka * varpool.c (dump_varpool_node): Dump used_by_single_function. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 86ad4fc3dc1..e797c79ed54 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-06-24 Markus Trippelsdorf + + PR tree-optimization/61554 + * g++.dg/torture/pr61554.C: New testcase. + 2014-06-23 Max Ostapenko * c-c++-common/asan/strlen-overflow-1.c: Change match patterns. diff --git a/gcc/testsuite/g++.dg/torture/pr61554.C b/gcc/testsuite/g++.dg/torture/pr61554.C new file mode 100644 index 00000000000..6f609c8be09 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr61554.C @@ -0,0 +1,46 @@ +// { dg-do compile } + +struct A +{ + A (); +}; +const unsigned long &min (const unsigned long &, const unsigned long &) {} + +template +void transform (_InputIterator1 p1, _InputIterator2, _OutputIterator, + _BinaryOperation p4) +{ + for (; p1;) + p4 (0, 0); +} + +class multi_array +{ +public: + multi_array (int &, int &); + int &resize_ranges; + int resize___trans_tmp_1; + void m_fn1 () + { + multi_array a (resize_ranges, this->m_fn2 ()); + const unsigned long &(*b)(const unsigned long &, const unsigned long &) + = min; + transform (&resize___trans_tmp_1, 0, 0, b); + A c; + } + ~multi_array () + { + for (int i; &base_;) + ; + } + int base_; + int &m_fn2 (); +}; + +class B +{ + void m_fn3 (const int &, const int &); + multi_array _bookingSnapshotBlock; +}; +void B::m_fn3 (const int &, const int &) { _bookingSnapshotBlock.m_fn1 (); } diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index eb65b18ce85..2e337e428c6 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -29,6 +29,7 @@ #include "function.h" #include "gimple-pretty-print.h" #include "dumpfile.h" +#include "bitmap.h" #include "sbitmap.h" #include "tree-ssa-alias.h" #include "internal-fn.h" @@ -1031,8 +1032,13 @@ public: fold_fn (fold_fn_), do_dce (do_dce_), something_changed (false) { stmts_to_remove.create (0); + need_eh_cleanup = BITMAP_ALLOC (NULL); + } + ~substitute_and_fold_dom_walker () + { + stmts_to_remove.release (); + BITMAP_FREE (need_eh_cleanup); } - ~substitute_and_fold_dom_walker () { stmts_to_remove.release (); } virtual void before_dom_children (basic_block); virtual void after_dom_children (basic_block) {} @@ -1042,6 +1048,7 @@ public: bool do_dce; bool something_changed; vec stmts_to_remove; + bitmap need_eh_cleanup; }; void @@ -1144,7 +1151,7 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb) /* If we cleaned up EH information from the statement, remove EH edges. */ if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt)) - gimple_purge_dead_eh_edges (bb); + bitmap_set_bit (need_eh_cleanup, bb->index); if (is_gimple_assign (stmt) && (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)) @@ -1235,6 +1242,9 @@ substitute_and_fold (ssa_prop_get_value_fn get_value_fn, } } + if (!bitmap_empty_p (walker.need_eh_cleanup)) + gimple_purge_all_dead_eh_edges (walker.need_eh_cleanup); + statistics_counter_event (cfun, "Constants propagated", prop_stats.num_const_prop); statistics_counter_event (cfun, "Copies propagated",