This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix fold_unary (PR middle-end/38771)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 9 Jan 2009 14:26:08 +0100
- Subject: [PATCH] Fix fold_unary (PR middle-end/38771)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
On the attached testcase,
fold_unary (NEGATE_EXPR, unsigned long long, (unsigned long long) (x0 ?: x1))
for long long x0 and x1 creates tree with invalid types
(NEGATE_EXPR with ullong type with operand of llong type).
The problem is that fold_unary does:
arg0 = op0;
STRIP_NOPS (arg0);
but doesn't for COND_EXPR or COMPOUND_EXPR arg0 convert back to the
right type. The right type in this case is TREE_TYPE (op0), which might
be different from type, e.g. for code FIX_TRUNC_EXPR, NOP_EXPR, etc.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?
2009-01-09 Jakub Jelinek <jakub@redhat.com>
PR middle-end/38771
* fold-const.c (fold_unary): For COMPOUND_EXPR and COND_EXPR,
fold_convert arg0 operands to TREE_TYPE (op0) first.
* gcc.c-torture/compile/pr38771.c: New test.
--- gcc/fold-const.c.jj 2009-01-02 09:32:55.000000000 +0100
+++ gcc/fold-const.c 2009-01-09 09:51:24.000000000 +0100
@@ -8053,15 +8053,19 @@ fold_unary (enum tree_code code, tree ty
{
if (TREE_CODE (arg0) == COMPOUND_EXPR)
return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
- fold_build1 (code, type, TREE_OPERAND (arg0, 1)));
+ fold_build1 (code, type,
+ fold_convert (TREE_TYPE (op0),
+ TREE_OPERAND (arg0, 1))));
else if (TREE_CODE (arg0) == COND_EXPR)
{
tree arg01 = TREE_OPERAND (arg0, 1);
tree arg02 = TREE_OPERAND (arg0, 2);
if (! VOID_TYPE_P (TREE_TYPE (arg01)))
- arg01 = fold_build1 (code, type, arg01);
+ arg01 = fold_build1 (code, type,
+ fold_convert (TREE_TYPE (op0), arg01));
if (! VOID_TYPE_P (TREE_TYPE (arg02)))
- arg02 = fold_build1 (code, type, arg02);
+ arg02 = fold_build1 (code, type,
+ fold_convert (TREE_TYPE (op0), arg02));
tem = fold_build3 (COND_EXPR, type, TREE_OPERAND (arg0, 0),
arg01, arg02);
--- gcc/testsuite/gcc.c-torture/compile/pr38771.c.jj 2009-01-09 10:00:23.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr38771.c 2009-01-09 09:29:27.000000000 +0100
@@ -0,0 +1,7 @@
+/* PR middle-end/38771 */
+
+unsigned long long
+foo (long long x)
+{
+ return -(unsigned long long) (x ? : x);
+}
Jakub