From 094f6ab3d5aa9753f5fc0c36a8cdfef4c2938140 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Mon, 23 May 2011 12:08:41 +0000 Subject: [PATCH] re PR tree-optimization/49115 (invalid return value optimization (?) when exception is thrown and caught) 2011-05-23 Richard Guenther 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. * g++.dg/torture/pr49115.C: New testcase. From-SVN: r174066 --- gcc/ChangeLog | 7 +++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/torture/pr49115.C | 25 +++++++++++++++++++++++++ gcc/tree-ssa-alias.c | 9 ++++++++- gcc/tree-ssa-dce.c | 9 ++++++++- 5 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr49115.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 25b569eefa4..62990819dbf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2011-05-23 Richard Guenther + + 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-05-23 Richard Guenther PR middle-end/15419 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c41d32448bb..e647cb57145 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-05-23 Richard Guenther + + PR tree-optimization/49115 + * g++.dg/torture/pr49115.C: New testcase. + 2011-05-23 Richard Guenther PR middle-end/15419 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 315a252fadc..ba76ae10ab1 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -1633,7 +1633,14 @@ stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref) return false; 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 6dc8a57f5c8..b13ef59af49 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -521,7 +521,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; -- 2.30.2