re PR tree-optimization/49115 (invalid return value optimization (?) when exception is thrown and caught)

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.

	* g++.dg/torture/pr49115.C: New testcase.

From-SVN: r174066
This commit is contained in:
Richard Guenther 2011-05-23 12:08:41 +00:00 committed by Richard Biener
parent 9a9822e13e
commit 094f6ab3d5
5 changed files with 53 additions and 2 deletions

View File

@ -1,3 +1,10 @@
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-05-23 Richard Guenther <rguenther@suse.de>
PR middle-end/15419

View File

@ -1,3 +1,8 @@
2011-05-23 Richard Guenther <rguenther@suse.de>
PR tree-optimization/49115
* g++.dg/torture/pr49115.C: New testcase.
2011-05-23 Richard Guenther <rguenther@suse.de>
PR middle-end/15419

View File

@ -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 ();
}
}

View File

@ -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;

View File

@ -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;