aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mmitchel@gcc.gnu.org>2003-03-23 22:57:26 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-03-23 22:57:26 +0000
commit068d2c9db6aa8553b34925ea0c0957e8ce671e30 (patch)
treee1c8674477700f6ed2edd93d67199d024ef407d1
parentc967e28c2fc6e87601f1ef89f44baff7f53083ea (diff)
downloadgcc-068d2c9db6aa8553b34925ea0c0957e8ce671e30.zip
gcc-068d2c9db6aa8553b34925ea0c0957e8ce671e30.tar.gz
gcc-068d2c9db6aa8553b34925ea0c0957e8ce671e30.tar.bz2
re PR c/8224 (Incorrect joining of signed and unsigned division)
PR c/8224 * fold-const.c (extract_muldiv_1): Don't pass through type conversions when signedness changes for division or modulus. PR c/8224 * gcc.dg/20030323-1.c: New test. From-SVN: r64760
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/fold-const.c7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/20030323-1.c24
4 files changed, 41 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fc8f418..596e91e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2003-03-23 Glen Nakamura <glen@imodulo.com>
+
+ PR c/8224
+ * fold-const.c (extract_muldiv_1): Don't pass through type conversions
+ when signedness changes for division or modulus.
+
2003-03-24 Alan Modra <amodra@bigpond.net.au>
* config/rs6000/sysv4.h (ASM_OUTPUT_ALIGNED_BSS): Remove unnecessary
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 7b051fa..0f9f3d4 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -4170,7 +4170,12 @@ extract_muldiv_1 (t, c, code, wide_type)
/* ... or its type is larger than ctype,
then we cannot pass through this truncation. */
|| (GET_MODE_SIZE (TYPE_MODE (ctype))
- < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0))))))
+ < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0))))
+ /* ... or signedness changes for division or modulus,
+ then we cannot pass through this conversion. */
+ || (code != MULT_EXPR
+ && (TREE_UNSIGNED (ctype)
+ != TREE_UNSIGNED (TREE_TYPE (op0))))))
break;
/* Pass the constant down and see if we can make a simplification. If
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 05b170c..9db8535 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2003-03-23 Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
+
+ PR c/8224
+ * gcc.dg/20030323-1.c: New test.
+
2003-03-23 Roger Sayle <roger@eyesopen.com>
* gcc.c-torture/compile/20030323-1.c: New test case.
diff --git a/gcc/testsuite/gcc.dg/20030323-1.c b/gcc/testsuite/gcc.dg/20030323-1.c
new file mode 100644
index 0000000..8a563ec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20030323-1.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+
+/* PR c/8224 */
+/* Contributed by Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz> */
+
+extern void abort (void);
+
+unsigned f (int x)
+{
+ return (unsigned) (x / 2) / 2;
+}
+
+unsigned f1 (int x)
+{
+ unsigned xx = x / 2;
+ return xx / 2;
+}
+
+int main ()
+{
+ if (f1 (-5) != f (-5))
+ abort ();
+ return 0;
+}