diff options
author | Mark Mitchell <mark@codesourcery.com> | 2004-12-23 08:14:33 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2004-12-23 08:14:33 +0000 |
commit | f98625f6a5077fa1554d7ea94016f452b79a00e2 (patch) | |
tree | 53f2733f9b2d5981233b4f403e52b59105601acd /gcc/gimplify.c | |
parent | ad78a663e81b3d549a7e407d10e5755afc50d7c5 (diff) | |
download | gcc-f98625f6a5077fa1554d7ea94016f452b79a00e2.zip gcc-f98625f6a5077fa1554d7ea94016f452b79a00e2.tar.gz gcc-f98625f6a5077fa1554d7ea94016f452b79a00e2.tar.bz2 |
re PR c++/16405 (Temporary aggregate copy not elided)
PR c++/16405
* gimplify.c (gimplify_modify_expr_rhs): Handle
INDIRECT_REF/ADDR_EXPR combinations.
PR c++/16405
* g++.dg/opt/temp1.C: New test.
From-SVN: r92539
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r-- | gcc/gimplify.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 2434a81..0f610e4 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -2801,6 +2801,33 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p, while (ret != GS_UNHANDLED) switch (TREE_CODE (*from_p)) { + case INDIRECT_REF: + { + /* If we have code like + + *(const A*)(A*)&x + + where the type of "x" is a (possibly cv-qualified variant + of "A"), treat the entire expression as identical to "x". + This kind of code arises in C++ when an object is bound + to a const reference, and if "x" is a TARGET_EXPR we want + to take advantage of the optimization below. */ + tree pointer; + + pointer = TREE_OPERAND (*from_p, 0); + STRIP_NOPS (pointer); + if (TREE_CODE (pointer) == ADDR_EXPR + && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (pointer, 0))) + == TYPE_MAIN_VARIANT (TREE_TYPE (*from_p)))) + { + *from_p = TREE_OPERAND (pointer, 0); + ret = GS_OK; + } + else + ret = GS_UNHANDLED; + break; + } + case TARGET_EXPR: { /* If we are initializing something from a TARGET_EXPR, strip the |