aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJoseph Myers <jsm@polyomino.org.uk>2004-07-22 21:33:34 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2004-07-22 21:33:34 +0100
commit9e629a806df2b10c39b770dfd908b910b3664ace (patch)
tree5d92e9b1d075e3e456c4f77032271580d8312ecb /gcc
parentd592f1c398da37535d3c528d1a511a32d8b9b3ba (diff)
downloadgcc-9e629a806df2b10c39b770dfd908b910b3664ace.zip
gcc-9e629a806df2b10c39b770dfd908b910b3664ace.tar.gz
gcc-9e629a806df2b10c39b770dfd908b910b3664ace.tar.bz2
re PR c/7284 (incorrectly simplifies leftshift followed by signed power-of-2 division)
PR c/7284 * fold-const.c (extract_muldiv_1): Do not treat signed left shift as multiplication. testsuite: * gcc.c-torture/execute/pr7284-1.c: New test. From-SVN: r85059
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/fold-const.c6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr7284-1.c24
4 files changed, 40 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5041b3f..43770e9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2004-07-22 Joseph S. Myers <jsm@polyomino.org.uk>
+ PR c/7284
+ * fold-const.c (extract_muldiv_1): Do not treat signed left shift
+ as multiplication.
+
+2004-07-22 Joseph S. Myers <jsm@polyomino.org.uk>
+
* doc/implement-c.texi: New file.
* doc/extend.texi (C Implementation): Move to there.
* doc/gcc.texi: Include implement-c.texi.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index e976117..a0d6323 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -5139,8 +5139,12 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type)
case LSHIFT_EXPR: case RSHIFT_EXPR:
/* If the second operand is constant, this is a multiplication
or floor division, by a power of two, so we can treat it that
- way unless the multiplier or divisor overflows. */
+ way unless the multiplier or divisor overflows. Signed
+ left-shift overflow is implementation-defined rather than
+ undefined in C90, so do not convert signed left shift into
+ multiplication. */
if (TREE_CODE (op1) == INTEGER_CST
+ && (tcode == RSHIFT_EXPR || TYPE_UNSIGNED (TREE_TYPE (op0)))
/* const_binop may not detect overflow correctly,
so check for it explicitly here. */
&& TYPE_PRECISION (TREE_TYPE (size_one_node)) > TREE_INT_CST_LOW (op1)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9003d13..c28a819 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2004-07-22 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c/7284
+ * gcc.c-torture/execute/pr7284-1.c: New test.
+
2004-07-22 Brian Booth <bbooth@redhat.com>
* gcc.dg/tree-ssa/20040721-1.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr7284-1.c b/gcc/testsuite/gcc.c-torture/execute/pr7284-1.c
new file mode 100644
index 0000000..de0057c
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr7284-1.c
@@ -0,0 +1,24 @@
+/* Signed left-shift is implementation-defined in C89 (and see
+ DR#081), not undefined. Bug 7284 from Al Grant (AlGrant at
+ myrealbox.com). */
+
+/* { dg-options "-std=c89" } */
+
+extern void abort (void);
+extern void exit (int);
+
+int
+f (int n)
+{
+ return (n << 24) / (1 << 23);
+}
+
+volatile int x = 128;
+
+int
+main (void)
+{
+ if (f(x) != -256)
+ abort ();
+ exit (0);
+}