diff options
author | Richard Guenther <rguenther@suse.de> | 2009-11-28 19:11:22 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2009-11-28 19:11:22 +0000 |
commit | f1c19648079168df5e3bf8ab7cee3a15f9203dc4 (patch) | |
tree | 94b97fb1416e57dbc696388eb5687ca3e1482c24 /gcc/tree-nrv.c | |
parent | c750c208706d56fb9b3b8e2badf44ec4b7f37058 (diff) | |
download | gcc-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.c | 10 |
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. */ |