This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix fold_unary (PR middle-end/38771)


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]