summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2005-02-16 13:54:30 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2005-02-16 13:54:30 +0000
commitc831d6fb28bc16f59d6676007fe0ee2bf9ab639e (patch)
treea0e729b4caa91a35b874138ae8a236e49b023751
parent6d3d2e2a1129555735bbbea993a852b24ad02785 (diff)
downloadgcc-c831d6fb28bc16f59d6676007fe0ee2bf9ab639e.tar.gz
PR middle-end/19857
* fold-const.c (fold): Don't optimize (T)(x & cst) to (T)x & (T)cst if (T)cst overflows. * convert.c (convert_to_integer) <case POINTER_TYPE>: Pass TYPE_UNSIGNED (type) as type_for_size's UNSIGNEDP argument. * gcc.dg/tree-ssa/20050215-1.c: New test. * gcc.c-torture/execute/20050215-1.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@95106 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/convert.c3
-rw-r--r--gcc/fold-const.c11
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20050215-1.c25
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20050215-1.c13
6 files changed, 62 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fbbe2b51878..1dbbf273a04 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2005-02-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/19857
+ * fold-const.c (fold): Don't optimize (T)(x & cst) to
+ (T)x & (T)cst if (T)cst overflows.
+ * convert.c (convert_to_integer) <case POINTER_TYPE>: Pass
+ TYPE_UNSIGNED (type) as type_for_size's UNSIGNEDP argument.
+
2005-02-15 Jeff Law <law@redhat.com>
* gcse.c (blocks_with_calls): New bitmap.
diff --git a/gcc/convert.c b/gcc/convert.c
index 005d3e2089b..f1a38c2d240 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -387,7 +387,8 @@ convert_to_integer (tree type, tree expr)
expr = integer_zero_node;
else
expr = fold (build1 (CONVERT_EXPR,
- lang_hooks.types.type_for_size (POINTER_SIZE, 0),
+ lang_hooks.types.type_for_size
+ (POINTER_SIZE, TYPE_UNSIGNED (type)),
expr));
return convert_to_integer (type, expr);
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index ef31a32f54e..5e2a8682c09 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -6874,9 +6874,14 @@ fold (tree expr)
#endif
}
if (change)
- return fold (build2 (BIT_AND_EXPR, type,
- fold_convert (type, and0),
- fold_convert (type, and1)));
+ {
+ tem = build_int_cst_wide (type, TREE_INT_CST_LOW (and1),
+ TREE_INT_CST_HIGH (and1));
+ tem = force_fit_type (tem, 0, TREE_OVERFLOW (and1),
+ TREE_CONSTANT_OVERFLOW (and1));
+ return fold (build2 (BIT_AND_EXPR, type,
+ fold_convert (type, and0), tem));
+ }
}
/* Convert (T1)((T2)X op Y) into (T1)X op Y, for pointer types T1 and
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 34b9f12ddcd..950407318ab 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2005-02-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/19857
+ * gcc.dg/tree-ssa/20050215-1.c: New test.
+ * gcc.c-torture/execute/20050215-1.c: New test.
+
2005-02-15 Eric Christopher <echristo@redhat.com>
* gcc.dg/cpp/20050215-1.c: New file.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20050215-1.c b/gcc/testsuite/gcc.c-torture/execute/20050215-1.c
new file mode 100644
index 00000000000..f4920ce5fd9
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20050215-1.c
@@ -0,0 +1,25 @@
+/* PR middle-end/19857 */
+
+typedef struct { char c[8]; } V
+#ifdef __ELF__
+ __attribute__ ((aligned (8)))
+#endif
+ ;
+typedef __SIZE_TYPE__ size_t;
+V v;
+void abort (void);
+
+int
+main (void)
+{
+ V *w = &v;
+ if (((size_t) ((float *) ((size_t) w & ~(size_t) 3)) % 8) != 0
+ || ((size_t) w & 1))
+ {
+#ifndef __ELF__
+ if (((size_t) &v & 7) == 0)
+#endif
+ abort ();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20050215-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20050215-1.c
new file mode 100644
index 00000000000..6ce588038aa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20050215-1.c
@@ -0,0 +1,13 @@
+/* PR middle-end/19857 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int i;
+int foo (void)
+{
+ return i & ~(unsigned int) 3;
+}
+
+/* Make sure the optimizers don't introduce overflow where one
+ did not exist in the original. */
+/* { dg-final { scan-tree-dump-times "-0+4" 0 "optimized"} } */