aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2007-10-08 14:44:14 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2007-10-08 14:44:14 +0000
commit8174836f1ebff55e127300c942adf3e689d3d3d4 (patch)
treefed6dbf121ef1138a33f97ed54004b0db8ff84e0 /gcc
parent7b6cb84335d934861a6058e2751435fbad61191d (diff)
downloadgcc-8174836f1ebff55e127300c942adf3e689d3d3d4.zip
gcc-8174836f1ebff55e127300c942adf3e689d3d3d4.tar.gz
gcc-8174836f1ebff55e127300c942adf3e689d3d3d4.tar.bz2
re PR middle-end/33691 (Type checking error with bitwise and/or)
2007-10-08 Richard Guenther <rguenther@suse.de> 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/fold-const.c31
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/gcc.dg/pr33691.c8
-rw-r--r--gcc/testsuite/gcc.dg/pr33694.c8
-rw-r--r--gcc/testsuite/gcc.dg/pr33696.c13
6 files changed, 69 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5fed689..a54a60c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2007-10-08 Richard Guenther <rguenther@suse.de>
+
+ 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 <manu@gcc.gnu.org>
* doc/invoke.texi (Wall): fix formatting issues.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 46e0e33..0313c0c 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 3997ac3..9af8f71 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2007-10-08 Richard Guenther <rguenther@suse.de>
+
+ 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 <tkoenig@gcc.gnu.org>
PR libfortran/33683
diff --git a/gcc/testsuite/gcc.dg/pr33691.c b/gcc/testsuite/gcc.dg/pr33691.c
new file mode 100644
index 0000000..9321361
--- /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 0000000..eb7655e
--- /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 0000000..97bbfe8
--- /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));
+}
+