I'm not positive whether or not this is a duplicate of 25895. I figured I'd better enter it just in case it wasn't. Test case: #include <stdio.h> struct A { A() : data1_(0), data2_(0) {} A(int i, int j) : data1_(i), data2_(j) {} A operator+(int); friend A operator+(int, const A&); ~A() {} //private: int data1_; int data2_; }; extern bool x; void display(const A& x) { printf("%d %d\n", x.data1_, x.data2_); } int main() { A a1(1,2); a1 = (x ? a1 + 3 : 3 + a1); display(a1); } bool x = false; A A::operator+(int i) { A a; a = *this; a.data2_ = i; return a; } A operator+(int i, const A& x) { A a; a = x; a.data1_ = i; return a; } Output: 3 0 Expected output: 3 2 The gimple tree (-fdump-tree-gimple) is showing statements like: operator+ (&a1, 3, &a1) [return slot addr]; which shoud instead be: operator+ (temp, 3, &a1) [return slot addr]; ... a1 = temp; The bad codegen is sensitive to the presence or absence of special member functions. For example if you comment out ~A(), you get the expected output.
This is actually a dup of bug 25977. But I think it was worked around in 4.0.2 (or maybe just 4.0.3, I have to double check that).
It was worked around in 4.0.2 (done on 2005-04-05 23:13:35) by: PR c++/19317 * calls.c (expand_call): Disable return slot optimization. Which just disabled the return slot optimization for 4.0.x Now 4.1.0 never got that patch but a different one which fixed a similar bug (PR 19317) but it did not fix this one or the duplicated one. *** This bug has been marked as a duplicate of 25977 ***
Actually this is not a full dup as this one is also still broken on the 4.0 branch.
Confirmed, very much related to PR 25977. Though I think this and PR 25977 are almost the same bug as we get: TARGET_EXPR <D.3014, <<< Unknown tree: aggr_init_expr operator+ 3, (struct A &) (struct A *) &a1 D.3014 >>> We are losing some piece of information.
Jason, do you have an ETA on this bug?
Subject: Bug 25979 Author: jason Date: Fri Feb 3 21:56:03 2006 New Revision: 110564 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=110564 Log: PR c++/25979 * gimplify.c (gimplify_modify_expr_rhs): Disable *& optimization for now. PR middle-end/25977 * gimplify.c (gimplify_modify_expr_rhs): It's not always safe to do RVO on the return slot if it's an NRV. Added: branches/gcc-4_1-branch/gcc/testsuite/g++.dg/opt/nrv10.C branches/gcc-4_1-branch/gcc/testsuite/g++.dg/opt/nrv11.C Modified: branches/gcc-4_1-branch/gcc/ChangeLog branches/gcc-4_1-branch/gcc/gimplify.c branches/gcc-4_1-branch/gcc/testsuite/g++.dg/opt/temp1.C
Subject: Bug 25979 Author: jason Date: Fri Feb 3 21:57:08 2006 New Revision: 110565 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=110565 Log: PR c++/25979 * gimplify.c (gimplify_modify_expr_rhs): Disable *& optimization for now. PR middle-end/25977 * gimplify.c (gimplify_modify_expr_rhs): It's not always safe to do RVO on the return slot if it's an NRV. Added: trunk/gcc/testsuite/g++.dg/opt/nrv10.C trunk/gcc/testsuite/g++.dg/opt/nrv11.C Modified: trunk/gcc/ChangeLog trunk/gcc/gimplify.c trunk/gcc/testsuite/g++.dg/opt/temp1.C
Fixed in 4.1 and 4.2 by disabling the fix for c++/16405 (a missed optimization regression). Working on a better fix.
No longer a 4.1/4.2 regression.
Subject: Bug 25979 Author: jason Date: Thu Feb 9 09:54:36 2006 New Revision: 110789 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=110789 Log: PR c++/25979 * tree.def: Elaborate on difference from MODIFY_EXPR. * doc/c-tree.texi (INIT_EXPR): Likewise. * gimplify.c (internal_get_tmp_var): Use INIT_EXPR. (gimplify_decl_expr, gimplify_init_ctor_eval): Likewise. (gimplify_target_expr): Likewise. (gimplify_cond_expr): Remove target handling. (gimplify_modify_expr): Don't clobber INIT_EXPR code here. (gimplify_expr): Clobber it here. (gimplify_modify_expr_rhs): Push assignment into COND_EXPR here. Do return slot optimization if we have an INIT_EXPR. PR tree-opt/24365 * tree-inline.c (declare_return_variable): Also clear DECL_COMPLEX_GIMPLE_REG_P as needed in the modify_dest case. PR c++/16405 * gimplify.c (gimplify_modify_expr_rhs): Re-enable *& handling. PR middle-end/22439 * gimplify.c (gimplify_one_sizepos): Fix typo. Modified: trunk/gcc/ChangeLog trunk/gcc/cp/ChangeLog trunk/gcc/cp/cp-gimplify.c trunk/gcc/cp/typeck2.c trunk/gcc/doc/c-tree.texi trunk/gcc/gimplify.c trunk/gcc/testsuite/g++.dg/opt/temp1.C trunk/gcc/tree-inline.c trunk/gcc/tree.def
Subject: Bug 25979 Author: jason Date: Fri Feb 10 17:32:10 2006 New Revision: 110838 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=110838 Log: PR c++/25979 * tree.def: Elaborate on difference from MODIFY_EXPR. * doc/c-tree.texi (INIT_EXPR): Likewise. * gimplify.c (internal_get_tmp_var): Use INIT_EXPR. (gimplify_decl_expr, gimplify_init_ctor_eval): Likewise. (gimplify_target_expr): Likewise. (gimplify_cond_expr): Remove target handling. (gimplify_modify_expr): Don't clobber INIT_EXPR code here. (gimplify_expr): Clobber it here. (gimplify_modify_expr_rhs): Push assignment into COND_EXPR here. Do return slot optimization if we have an INIT_EXPR. PR tree-opt/24365 * tree-inline.c (declare_return_variable): Also clear DECL_COMPLEX_GIMPLE_REG_P as needed in the modify_dest case. PR c++/16405 * gimplify.c (gimplify_modify_expr_rhs): Re-enable *& handling. PR middle-end/22439 * gimplify.c (gimplify_one_sizepos): Fix typo. Modified: branches/gcc-4_1-branch/gcc/ChangeLog branches/gcc-4_1-branch/gcc/cp/ChangeLog branches/gcc-4_1-branch/gcc/cp/cp-gimplify.c branches/gcc-4_1-branch/gcc/cp/typeck2.c branches/gcc-4_1-branch/gcc/doc/c-tree.texi branches/gcc-4_1-branch/gcc/gimplify.c branches/gcc-4_1-branch/gcc/testsuite/g++.dg/opt/temp1.C branches/gcc-4_1-branch/gcc/tree-inline.c branches/gcc-4_1-branch/gcc/tree.def
Subject: Bug 25979 Author: jason Date: Sat Feb 11 00:19:30 2006 New Revision: 110864 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=110864 Log: PR c++/25979 * tree.def: Elaborate on difference from MODIFY_EXPR. * doc/c-tree.texi (INIT_EXPR): Likewise. * cp/cp-gimplify.c (cp_gimplify_expr): Don't call cp_gimplify_init_expr for MODIFY_EXPRs. * cp/typeck2.c (split_nonconstant_init_1): Use INIT_EXPR. * gimplify.c (internal_get_tmp_var): Likewise. (gimplify_decl_expr, gimplify_init_ctor_eval): Likewise. (gimplify_target_expr): Likewise. (gimplify_cond_expr): Remove target handling. (gimplify_modify_expr): Don't clobber INIT_EXPR code here. (gimplify_expr): Clobber it here. (gimplify_modify_expr_rhs): Push assignment into COND_EXPR here. Do return slot optimization if we have an INIT_EXPR. PR middle-end/22439 * gimplify.c (gimplify_one_sizepos): Fix typo. Modified: branches/gcc-4_0-branch/gcc/ChangeLog branches/gcc-4_0-branch/gcc/cp/ChangeLog branches/gcc-4_0-branch/gcc/cp/cp-gimplify.c branches/gcc-4_0-branch/gcc/cp/typeck2.c branches/gcc-4_0-branch/gcc/doc/c-tree.texi branches/gcc-4_0-branch/gcc/gimplify.c branches/gcc-4_0-branch/gcc/tree.def
Fixed.