diff options
author | Joseph Myers <jsm@polyomino.org.uk> | 2004-07-22 21:33:34 +0100 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2004-07-22 21:33:34 +0100 |
commit | 9e629a806df2b10c39b770dfd908b910b3664ace (patch) | |
tree | 5d92e9b1d075e3e456c4f77032271580d8312ecb /gcc | |
parent | d592f1c398da37535d3c528d1a511a32d8b9b3ba (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fold-const.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr7284-1.c | 24 |
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); +} |