diff options
author | Roger Sayle <sayle@gcc.gnu.org> | 2005-04-04 05:02:10 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2005-04-04 05:02:10 +0000 |
commit | 283da5df2d76ce3909d70ea9dd6b77143eb7c04a (patch) | |
tree | 7edc4f9f0dabe9c7e7d4bdddc9d08b31857564fb /gcc/fold-const.c | |
parent | af842ce06249a2b2b9d09867af8e0076486b1acc (diff) | |
download | gcc-283da5df2d76ce3909d70ea9dd6b77143eb7c04a.zip gcc-283da5df2d76ce3909d70ea9dd6b77143eb7c04a.tar.gz gcc-283da5df2d76ce3909d70ea9dd6b77143eb7c04a.tar.bz2 |
re PR c++/19199 (Wrong warning about returning a reference to a temporary)
2005-04-03 Roger Sayle <roger@eyesopen.com>
Alexandre Oliva <aoliva@redhat.com>
PR c++/19199
* fold-const.c (non_lvalue): Split tests into...
(maybe_lvalue_p): New function.
(fold_cond_expr_with_comparison): Preserve lvalue-ness for the
C++ front-end prior to lowering into gimple form.
* g++.dg/expr/lval2.C: New.
* expr2.C: Fixed.
From-SVN: r97522
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index c224257..0b9a71f 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -2003,16 +2003,13 @@ fold_convert (tree type, tree arg) } } +/* Return false if expr can be assumed not to be an value, true + otherwise. */ /* Return an expr equal to X but certainly not valid as an lvalue. */ -tree -non_lvalue (tree x) +static bool +maybe_lvalue_p (tree x) { - /* While we are in GIMPLE, NON_LVALUE_EXPR doesn't mean anything to - us. */ - if (in_gimple_form) - return x; - /* We only need to wrap lvalue tree codes. */ switch (TREE_CODE (x)) { @@ -2052,8 +2049,24 @@ non_lvalue (tree x) /* Assume the worst for front-end tree codes. */ if ((int)TREE_CODE (x) >= NUM_TREE_CODES) break; - return x; + return false; } + + return true; +} + +/* Return an expr equal to X but certainly not valid as an lvalue. */ + +tree +non_lvalue (tree x) +{ + /* While we are in GIMPLE, NON_LVALUE_EXPR doesn't mean anything to + us. */ + if (in_gimple_form) + return x; + + if (! maybe_lvalue_p (x)) + return x; return build1 (NON_LVALUE_EXPR, TREE_TYPE (x), x); } @@ -4273,7 +4286,13 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2) a number and A is not. The conditions in the original expressions will be false, so all four give B. The min() and max() versions would give a NaN instead. */ - if (operand_equal_for_comparison_p (arg01, arg2, arg00)) + if (operand_equal_for_comparison_p (arg01, arg2, arg00) + /* Avoid these transformations if the COND_EXPR may be used + as an lvalue in the C++ front-end. PR c++/19199. */ + && (in_gimple_form + || strcmp (lang_hooks.name, "GNU C++") != 0 + || ! maybe_lvalue_p (arg1) + || ! maybe_lvalue_p (arg2))) { tree comp_op0 = arg00; tree comp_op1 = arg01; |