From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25846 invoked by alias); 4 Apr 2005 13:32:40 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 25703 invoked by alias); 4 Apr 2005 13:32:28 -0000 Date: Mon, 04 Apr 2005 13:32:00 -0000 Message-ID: <20050404133228.25702.qmail@sourceware.org> From: "aoliva at redhat dot com" To: gcc-bugs@gcc.gnu.org In-Reply-To: <20041230105911.19199.lars@trolltech.com> References: <20041230105911.19199.lars@trolltech.com> Reply-To: gcc-bugzilla@gcc.gnu.org Subject: [Bug c++/19199] [3.3/3.4/4.0/4.1 Regression] Wrong warning about returning a reference to a temporary X-Bugzilla-Reason: CC X-SW-Source: 2005-04/txt/msg00296.txt.bz2 List-Id: ------- Additional Comments From aoliva at gcc dot gnu dot org 2005-04-04 13:32 ------- Subject: Re: [Committed] PR c++/19199: Preserve COND_EXPR lvalueness in fold On Apr 4, 2005, Roger Sayle wrote: > (fold_cond_expr_with_comparison): Preserve lvalue-ness for the > C++ front-end prior to lowering into gimple form. > * expr2.C: Fixed. Err... Why did you choose to drop the portion of the patch below, that would have avoided the ugliness of comparing langhooks.name, but still retained it in the ChangeLog entry? Index: fold-const.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v retrieving revision 1.554 diff -u -p -d -u -p -d -u -p -r1.554 fold-const.c --- fold-const.c 4 Apr 2005 08:50:25 -0000 1.554 +++ fold-const.c 4 Apr 2005 13:25:47 -0000 @@ -4173,7 +4173,15 @@ fold_cond_expr_with_comparison (tree typ tree arg00 = TREE_OPERAND (arg0, 0); tree arg01 = TREE_OPERAND (arg0, 1); tree arg1_type = TREE_TYPE (arg1); - tree tem; + tree tem = NULL; + /* If the COND_EXPR can possibly be an lvalue, we don't want to + perform transformations that return a simplified result that will + be recognized as lvalue, but that will not match the expected + result. We may still return other expressions that would be + incorrect, but those are going to be rvalues, and the caller is + supposed to discard them. */ + bool lvalue = !pedantic_lvalues + && maybe_lvalue_p (arg1) && maybe_lvalue_p (arg2); STRIP_NOPS (arg1); STRIP_NOPS (arg2); @@ -4215,10 +4223,12 @@ fold_cond_expr_with_comparison (tree typ case EQ_EXPR: case UNEQ_EXPR: tem = fold_convert (arg1_type, arg1); - return pedantic_non_lvalue (fold_convert (type, negate_expr (tem))); + tem = pedantic_non_lvalue (fold_convert (type, negate_expr (tem))); + break; case NE_EXPR: case LTGT_EXPR: - return pedantic_non_lvalue (fold_convert (type, arg1)); + tem = pedantic_non_lvalue (fold_convert (type, arg1)); + break; case UNGE_EXPR: case UNGT_EXPR: if (flag_trapping_math) @@ -4230,7 +4240,8 @@ fold_cond_expr_with_comparison (tree typ arg1 = fold_convert (lang_hooks.types.signed_type (TREE_TYPE (arg1)), arg1); tem = fold_build1 (ABS_EXPR, TREE_TYPE (arg1), arg1); - return pedantic_non_lvalue (fold_convert (type, tem)); + tem = pedantic_non_lvalue (fold_convert (type, tem)); + break; case UNLE_EXPR: case UNLT_EXPR: if (flag_trapping_math) @@ -4241,12 +4252,18 @@ fold_cond_expr_with_comparison (tree typ arg1 = fold_convert (lang_hooks.types.signed_type (TREE_TYPE (arg1)), arg1); tem = fold_build1 (ABS_EXPR, TREE_TYPE (arg1), arg1); - return negate_expr (fold_convert (type, tem)); + tem = negate_expr (fold_convert (type, tem)); + break; default: gcc_assert (TREE_CODE_CLASS (comp_code) == tcc_comparison); break; } + if (tem && (! lvalue || maybe_lvalue_p (tem))) + return tem; + else + tem = NULL; + /* A != 0 ? A : 0 is simply A, unless A is -0. Likewise A == 0 ? A : 0 is always 0 unless A is -0. Note that both transformations are correct when A is NaN: A != 0 @@ -4255,11 +4272,16 @@ fold_cond_expr_with_comparison (tree typ if (integer_zerop (arg01) && integer_zerop (arg2)) { if (comp_code == NE_EXPR) - return pedantic_non_lvalue (fold_convert (type, arg1)); + tem = pedantic_non_lvalue (fold_convert (type, arg1)); else if (comp_code == EQ_EXPR) - return fold_convert (type, integer_zero_node); + tem = fold_convert (type, integer_zero_node); } + if (tem && (! lvalue || maybe_lvalue_p (tem))) + return tem; + else + tem = NULL; + /* Try some transformations of A op B ? A : B. A == B? A : B same as B @@ -4309,9 +4331,15 @@ fold_cond_expr_with_comparison (tree typ switch (comp_code) { case EQ_EXPR: - return pedantic_non_lvalue (fold_convert (type, arg2)); + if (lvalue) + break; + tem = pedantic_non_lvalue (fold_convert (type, arg2)); + break; case NE_EXPR: - return pedantic_non_lvalue (fold_convert (type, arg1)); + if (lvalue) + break; + tem = pedantic_non_lvalue (fold_convert (type, arg1)); + break; case LE_EXPR: case LT_EXPR: case UNLE_EXPR: @@ -4327,7 +4355,7 @@ fold_cond_expr_with_comparison (tree typ tem = (comp_code == LE_EXPR || comp_code == UNLE_EXPR) ? fold_build2 (MIN_EXPR, comp_type, comp_op0, comp_op1) : fold_build2 (MIN_EXPR, comp_type, comp_op1, comp_op0); - return pedantic_non_lvalue (fold_convert (type, tem)); + tem = pedantic_non_lvalue (fold_convert (type, tem)); } break; case GE_EXPR: @@ -4341,16 +4369,16 @@ fold_cond_expr_with_comparison (tree typ tem = (comp_code == GE_EXPR || comp_code == UNGE_EXPR) ? fold_build2 (MAX_EXPR, comp_type, comp_op0, comp_op1) : fold_build2 (MAX_EXPR, comp_type, comp_op1, comp_op0); - return pedantic_non_lvalue (fold_convert (type, tem)); + tem = pedantic_non_lvalue (fold_convert (type, tem)); } break; case UNEQ_EXPR: - if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1)))) - return pedantic_non_lvalue (fold_convert (type, arg2)); + if (! lvalue && !HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1)))) + tem = pedantic_non_lvalue (fold_convert (type, arg2)); break; case LTGT_EXPR: - if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1)))) - return pedantic_non_lvalue (fold_convert (type, arg1)); + if (! lvalue && !HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1)))) + tem = pedantic_non_lvalue (fold_convert (type, arg1)); break; default: gcc_assert (TREE_CODE_CLASS (comp_code) == tcc_comparison); @@ -4358,6 +4386,11 @@ fold_cond_expr_with_comparison (tree typ } } + if (tem && (! lvalue || maybe_lvalue_p (tem))) + return tem; + else + tem = NULL; + /* If this is A op C1 ? A : C2 with C1 and C2 constant integers, we might still be able to simplify this. For example, if C1 is one less or one more than C2, this might have started @@ -4372,7 +4405,7 @@ fold_cond_expr_with_comparison (tree typ case EQ_EXPR: /* We can replace A with C1 in this case. */ arg1 = fold_convert (type, arg01); - return fold_build3 (COND_EXPR, type, arg0, arg1, arg2); + tem = fold_build3 (COND_EXPR, type, arg0, arg1, arg2); case LT_EXPR: /* If C1 is C2 + 1, this is min(A, C2). */ @@ -4382,8 +4415,8 @@ fold_cond_expr_with_comparison (tree typ const_binop (PLUS_EXPR, arg2, integer_one_node, 0), OEP_ONLY_CONST)) - return pedantic_non_lvalue (fold_build2 (MIN_EXPR, - type, arg1, arg2)); + tem = pedantic_non_lvalue (fold_build2 (MIN_EXPR, + type, arg1, arg2)); break; case LE_EXPR: @@ -4394,8 +4427,8 @@ fold_cond_expr_with_comparison (tree typ const_binop (MINUS_EXPR, arg2, integer_one_node, 0), OEP_ONLY_CONST)) - return pedantic_non_lvalue (fold_build2 (MIN_EXPR, - type, arg1, arg2)); + tem = pedantic_non_lvalue (fold_build2 (MIN_EXPR, + type, arg1, arg2)); break; case GT_EXPR: @@ -4406,8 +4439,8 @@ fold_cond_expr_with_comparison (tree typ const_binop (MINUS_EXPR, arg2, integer_one_node, 0), OEP_ONLY_CONST)) - return pedantic_non_lvalue (fold_build2 (MAX_EXPR, - type, arg1, arg2)); + tem = pedantic_non_lvalue (fold_build2 (MAX_EXPR, + type, arg1, arg2)); break; case GE_EXPR: @@ -4418,8 +4451,8 @@ fold_cond_expr_with_comparison (tree typ const_binop (PLUS_EXPR, arg2, integer_one_node, 0), OEP_ONLY_CONST)) - return pedantic_non_lvalue (fold_build2 (MAX_EXPR, - type, arg1, arg2)); + tem = pedantic_non_lvalue (fold_build2 (MAX_EXPR, + type, arg1, arg2)); break; case NE_EXPR: break; @@ -4427,6 +4460,11 @@ fold_cond_expr_with_comparison (tree typ gcc_unreachable (); } + if (tem && (! lvalue || maybe_lvalue_p (tem))) + return tem; + else + tem = NULL; + return NULL_TREE; } -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19199