diff options
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr49115.C | 25 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.c | 9 | ||||
-rw-r--r-- | gcc/tree-ssa-dce.c | 9 |
5 files changed, 59 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7e1e03070f7..c039f72a7e8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2011-06-17 Richard Guenther <rguenther@suse.de> + + Backport from mainline + 2011-05-23 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/49115 + * tree-ssa-alias.c (stmt_kills_ref_p_1): If the assignment + is not necessarily carried out, do not claim it kills the ref. + * tree-ssa-dce.c (mark_aliased_reaching_defs_necessary_1): Likewise. + 2011-06-17 Hans-Peter Nilsson <hp@axis.com> Backport from mainline diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c25386f15a8..cd5e76559d7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2011-06-17 Richard Guenther <rguenther@suse.de> + + Backport from mainline + 2011-05-23 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/49115 + * g++.dg/torture/pr49115.C: New testcase. + 2011-06-17 Hans-Peter Nilsson <hp@axis.com> Backport from mainline diff --git a/gcc/testsuite/g++.dg/torture/pr49115.C b/gcc/testsuite/g++.dg/torture/pr49115.C new file mode 100644 index 00000000000..c4cce21ba5d --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr49115.C @@ -0,0 +1,25 @@ +// { dg-do run } + +extern "C" void abort (void); +struct MyException {}; +struct Data { + int nr; + Data() : nr(66) {} +}; +Data __attribute__((noinline,noclone)) getData(int i) +{ + if (i) throw MyException(); + Data data; + data.nr = i; + return data; +} +int main(int, char **) +{ + Data data; + try { + data = getData(1); + } catch (MyException& e) { + if (data.nr != 66) + abort (); + } +} diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 1d213dfa31f..90aebc68dd0 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -1652,7 +1652,14 @@ static bool stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref) { if (gimple_has_lhs (stmt) - && TREE_CODE (gimple_get_lhs (stmt)) != SSA_NAME) + && TREE_CODE (gimple_get_lhs (stmt)) != SSA_NAME + /* The assignment is not necessarily carried out if it can throw + and we can catch it in the current function where we could inspect + the previous value. + ??? We only need to care about the RHS throwing. For aggregate + assignments or similar calls and non-call exceptions the LHS + might throw as well. */ + && !stmt_can_throw_internal (stmt)) { tree base, lhs = gimple_get_lhs (stmt); HOST_WIDE_INT size, offset, max_size; diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index a9c886f0a8f..b34c7cf7fcd 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -529,7 +529,14 @@ mark_aliased_reaching_defs_necessary_1 (ao_ref *ref, tree vdef, void *data) /* If the stmt lhs kills ref, then we can stop walking. */ if (gimple_has_lhs (def_stmt) - && TREE_CODE (gimple_get_lhs (def_stmt)) != SSA_NAME) + && TREE_CODE (gimple_get_lhs (def_stmt)) != SSA_NAME + /* The assignment is not necessarily carried out if it can throw + and we can catch it in the current function where we could inspect + the previous value. + ??? We only need to care about the RHS throwing. For aggregate + assignments or similar calls and non-call exceptions the LHS + might throw as well. */ + && !stmt_can_throw_internal (def_stmt)) { tree base, lhs = gimple_get_lhs (def_stmt); HOST_WIDE_INT size, offset, max_size; |