summaryrefslogtreecommitdiff
path: root/gcc/tree-nrv.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2009-11-28 19:11:22 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2009-11-28 19:11:22 +0000
commitf1c19648079168df5e3bf8ab7cee3a15f9203dc4 (patch)
tree94b97fb1416e57dbc696388eb5687ca3e1482c24 /gcc/tree-nrv.c
parentc750c208706d56fb9b3b8e2badf44ec4b7f37058 (diff)
downloadgcc-f1c19648079168df5e3bf8ab7cee3a15f9203dc4.tar.gz
re PR middle-end/42183 (internal compiler error: verify_stmts failed)
2009-11-28 Richard Guenther <rguenther@suse.de> PR tree-optimization/42183 * tree-nrv.c (tree_nrv): Bail out if the RESULT_DECL has its address taken. Merge the addressable state of the NRV variable and the result instead of copying it. * g++.dg/torture/pr42183.C: New testcase. From-SVN: r154728
Diffstat (limited to 'gcc/tree-nrv.c')
-rw-r--r--gcc/tree-nrv.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c
index defa8def89c..a825a7a0c3f 100644
--- a/gcc/tree-nrv.c
+++ b/gcc/tree-nrv.c
@@ -129,6 +129,12 @@ tree_nrv (void)
if (DECL_NAME (result))
return 0;
+ /* If the result has its address taken then it might be modified
+ by means not detected in the following loop. Bail out in this
+ case. */
+ if (TREE_ADDRESSABLE (result))
+ return 0;
+
/* Look through each block for assignments to the RESULT_DECL. */
FOR_EACH_BB (bb)
{
@@ -178,7 +184,7 @@ tree_nrv (void)
|| TREE_ADDRESSABLE (found)
|| DECL_ALIGN (found) > DECL_ALIGN (result)
|| !useless_type_conversion_p (result_type,
- TREE_TYPE (found)))
+ TREE_TYPE (found)))
return 0;
}
else if (gimple_has_lhs (stmt))
@@ -218,7 +224,7 @@ tree_nrv (void)
DECL_ABSTRACT_ORIGIN (result) = DECL_ABSTRACT_ORIGIN (found);
}
- TREE_ADDRESSABLE (result) = TREE_ADDRESSABLE (found);
+ TREE_ADDRESSABLE (result) |= TREE_ADDRESSABLE (found);
/* Now walk through the function changing all references to VAR to be
RESULT. */