From 8174836f1ebff55e127300c942adf3e689d3d3d4 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Mon, 8 Oct 2007 14:44:14 +0000 Subject: [PATCH] re PR middle-end/33691 (Type checking error with bitwise and/or) 2007-10-08 Richard Guenther PR middle-end/33691 PR middle-end/33694 PR middle-end/33696 * fold-const.c (fold_binary): Use the correct types when folding (A | CST1) & CST2 to (A & CST2) | (CST1 & CST2). (fold_binary): Use the correct types when folding (-A) - B to (-B) - A. (fold_unary): Use the correct types when folding ~(X). * gcc.dg/pr33691.c: New testcase. * gcc.dg/pr33694.c: Likewise. * gcc.dg/pr33696.c: Likewise. From-SVN: r129128 --- gcc/ChangeLog | 11 +++++++++++ gcc/fold-const.c | 31 ++++++++++++++++++++----------- gcc/testsuite/ChangeLog | 9 +++++++++ gcc/testsuite/gcc.dg/pr33691.c | 8 ++++++++ gcc/testsuite/gcc.dg/pr33694.c | 8 ++++++++ gcc/testsuite/gcc.dg/pr33696.c | 13 +++++++++++++ 6 files changed, 69 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr33691.c create mode 100644 gcc/testsuite/gcc.dg/pr33694.c create mode 100644 gcc/testsuite/gcc.dg/pr33696.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5fed689a7ed..a54a60c868e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2007-10-08 Richard Guenther + + PR middle-end/33691 + PR middle-end/33694 + PR middle-end/33696 + * fold-const.c (fold_binary): Use the correct types when + folding (A | CST1) & CST2 to (A & CST2) | (CST1 & CST2). + (fold_binary): Use the correct types when folding + (-A) - B to (-B) - A. + (fold_unary): Use the correct types when folding ~(X). + 2007-10-08 Manuel Lopez-Ibanez * doc/invoke.texi (Wall): fix formatting issues. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 46e0e3348a5..0313c0ca840 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -8374,10 +8374,11 @@ fold_unary (enum tree_code code, tree type, tree op0) if (TREE_CODE (arg0) == INTEGER_CST) return fold_not_const (arg0, type); else if (TREE_CODE (arg0) == BIT_NOT_EXPR) - return TREE_OPERAND (arg0, 0); + return TREE_OPERAND (op0, 0); /* Convert ~ (-A) to A - 1. */ else if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR) - return fold_build2 (MINUS_EXPR, type, TREE_OPERAND (arg0, 0), + return fold_build2 (MINUS_EXPR, type, + fold_convert (type, TREE_OPERAND (arg0, 0)), build_int_cst (type, 1)); /* Convert ~ (A - 1) or ~ (A + -1) to -A. */ else if (INTEGRAL_TYPE_P (type) @@ -8385,7 +8386,8 @@ fold_unary (enum tree_code code, tree type, tree op0) && integer_onep (TREE_OPERAND (arg0, 1))) || (TREE_CODE (arg0) == PLUS_EXPR && integer_all_onesp (TREE_OPERAND (arg0, 1))))) - return fold_build1 (NEGATE_EXPR, type, TREE_OPERAND (arg0, 0)); + return fold_build1 (NEGATE_EXPR, type, + fold_convert (type, TREE_OPERAND (arg0, 0))); /* Convert ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify. */ else if (TREE_CODE (arg0) == BIT_XOR_EXPR && (tem = fold_unary (BIT_NOT_EXPR, type, @@ -10126,15 +10128,17 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) } /* A - (-B) -> A + B */ if (TREE_CODE (arg1) == NEGATE_EXPR) - return fold_build2 (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)); + return fold_build2 (PLUS_EXPR, type, op0, + fold_convert (type, TREE_OPERAND (arg1, 0))); /* (-A) - B -> (-B) - A where B is easily negated and we can swap. */ if (TREE_CODE (arg0) == NEGATE_EXPR && (FLOAT_TYPE_P (type) || INTEGRAL_TYPE_P (type)) && negate_expr_p (arg1) && reorder_operands_p (arg0, arg1)) - return fold_build2 (MINUS_EXPR, type, negate_expr (arg1), - TREE_OPERAND (arg0, 0)); + return fold_build2 (MINUS_EXPR, type, + fold_convert (type, negate_expr (arg1)), + fold_convert (type, TREE_OPERAND (arg0, 0))); /* Convert -A - 1 to ~A. */ if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR @@ -10889,11 +10893,16 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) if (TREE_CODE (arg0) == BIT_IOR_EXPR && TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST) - return fold_build2 (BIT_IOR_EXPR, type, - fold_build2 (BIT_AND_EXPR, type, - TREE_OPERAND (arg0, 0), arg1), - fold_build2 (BIT_AND_EXPR, type, - TREE_OPERAND (arg0, 1), arg1)); + { + tree tmp1 = fold_convert (TREE_TYPE (arg0), arg1); + tree tmp2 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg0), + TREE_OPERAND (arg0, 0), tmp1); + tree tmp3 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg0), + TREE_OPERAND (arg0, 1), tmp1); + return fold_convert (type, + fold_build2 (BIT_IOR_EXPR, TREE_TYPE (arg0), + tmp2, tmp3)); + } /* (X | Y) & Y is (X, Y). */ if (TREE_CODE (arg0) == BIT_IOR_EXPR diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3997ac380ba..9af8f71c4b5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2007-10-08 Richard Guenther + + PR middle-end/33691 + PR middle-end/33694 + PR middle-end/33696 + * gcc.dg/pr33691.c: New testcase. + * gcc.dg/pr33694.c: Likewise. + * gcc.dg/pr33696.c: Likewise. + 2007-10-07 Thomas Koenig PR libfortran/33683 diff --git a/gcc/testsuite/gcc.dg/pr33691.c b/gcc/testsuite/gcc.dg/pr33691.c new file mode 100644 index 00000000000..93213610d28 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr33691.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ + +/* ICEd with type-checking enabled. */ + +unsigned int mgaSetTexImages(int i) +{ + return ((i | 0x40) & 0xffffffc0); +} diff --git a/gcc/testsuite/gcc.dg/pr33694.c b/gcc/testsuite/gcc.dg/pr33694.c new file mode 100644 index 00000000000..eb7655e8585 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr33694.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ + +/* This used to ICE with type-checking enabled. */ + +__SIZE_TYPE__ cnfs_mapcntl(long pagesize) +{ + return ~(__SIZE_TYPE__)(pagesize - 1); +} diff --git a/gcc/testsuite/gcc.dg/pr33696.c b/gcc/testsuite/gcc.dg/pr33696.c new file mode 100644 index 00000000000..97bbfe8bf43 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr33696.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +/* This used to ICE with type-checking enabled. */ + +typedef unsigned char uint8_t; +typedef unsigned int uint_least32_t; +extern int foo (long int __off); +void write (uint_least32_t chunk_len) +{ + uint8_t tmp[4]; + foo (-(long)chunk_len - sizeof(tmp)); +} + -- 2.30.2