diff options
author | Hannes Domani <ssbssa@yahoo.de> | 2024-06-11 20:32:59 +0200 |
---|---|---|
committer | Hannes Domani <ssbssa@yahoo.de> | 2024-07-05 21:42:58 +0200 |
commit | cec2e207d08127bf5458a220f741020aff4148da (patch) | |
tree | 27aa7b05bf3fd2a0fcfa8ed32cbb29273fbf1c81 | |
parent | edd3f7be255e2e51ff7928cabb744af5d3d20018 (diff) | |
download | gdb-cec2e207d08127bf5458a220f741020aff4148da.zip gdb-cec2e207d08127bf5458a220f741020aff4148da.tar.gz gdb-cec2e207d08127bf5458a220f741020aff4148da.tar.bz2 |
Fix too-large or negative right shift of negative numbers
As seen in these test failures:
print -1 >> -1
warning: right shift count is negative
$N = 0
(gdb) FAIL: gdb.base/bitshift.exp: lang=c: neg lhs/rhs: print -1 >> -1
print -4 >> -2
warning: right shift count is negative
$N = 0
(gdb) FAIL: gdb.base/bitshift.exp: lang=c: neg lhs/rhs: print -4 >> -2
Fixed by restoring the logic from before the switch to gmp.
Approved-By: Tom Tromey <tom@tromey.com>
-rw-r--r-- | gdb/testsuite/gdb.base/bitshift.exp | 1 | ||||
-rw-r--r-- | gdb/valarith.c | 16 |
2 files changed, 16 insertions, 1 deletions
diff --git a/gdb/testsuite/gdb.base/bitshift.exp b/gdb/testsuite/gdb.base/bitshift.exp index 17f6b78..d6e2521 100644 --- a/gdb/testsuite/gdb.base/bitshift.exp +++ b/gdb/testsuite/gdb.base/bitshift.exp @@ -348,6 +348,7 @@ proc test_shifts {} { test_shift $lang "print -3 >> 1" " = -2" test_shift $lang "print -8 >> 1" " = -4" test_shift $lang "print [make_int64 $lang -8] >> 1" " = -4" + test_rshift_tl $lang "print -8 >> 100" " = -1" } # Make sure an unsigned 64-bit value with high bit set isn't diff --git a/gdb/valarith.c b/gdb/valarith.c index 7034fa6..6160b0e 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -1303,7 +1303,21 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) { unsigned long nbits; if (!check_valid_shift_count (op, result_type, type2, v2, nbits)) - v = 0; + { + /* Pretend the too-large shift was decomposed in a + number of smaller shifts. An arithmetic signed + right shift of a negative number always yields -1 + with such semantics. This is the right thing to + do for Go, and we might as well do it for + languages where it is undefined. Also, pretend a + shift by a negative number was a shift by the + negative number cast to unsigned, which is the + same as shifting by a too-large number. */ + if (v1 < 0 && !result_type->is_unsigned ()) + v = -1; + else + v = 0; + } else v = v1 >> nbits; } |