summaryrefslogtreecommitdiff
path: root/test-suite
diff options
context:
space:
mode:
authorMark H Weaver <mhw@netris.org>2018-10-14 05:29:52 -0400
committerMark H Weaver <mhw@netris.org>2018-10-14 05:37:18 -0400
commit1990aa916382d0afcebd5315a6d6f555949ff654 (patch)
treedbbf60e3713333ab39d5b795f1f0c04d05869404 /test-suite
parent9448a078b5a35fc49a16d32c0398d5789a863f09 (diff)
In 'ash' and 'round-ash', handle right shift count of LONG_MIN.
Fixes <https://bugs.gnu.org/21901>. Reported by Zefram <zefram@fysh.org>. * libguile/numbers.c: Add another top-level 'verify' to ensure that LONG_MIN is not a fixnum. (scm_ash, scm_round_ash): Ensure that when the shift count is LONG_MIN, it is not handled via the normal code path, to avoid signed overflow when the shift count is negated. * test-suite/tests/numbers.test: Add tests.
Diffstat (limited to 'test-suite')
-rw-r--r--test-suite/tests/numbers.test24
1 files changed, 24 insertions, 0 deletions
diff --git a/test-suite/tests/numbers.test b/test-suite/tests/numbers.test
index 8cecb06ad..59e370ec9 100644
--- a/test-suite/tests/numbers.test
+++ b/test-suite/tests/numbers.test
@@ -5390,11 +5390,19 @@
(for-each (lambda (n)
(for-each (lambda (count) (test n count))
`(-1000
+ ,(* 2 (- fixnum-bit))
+ ,(- -3 fixnum-bit)
+ ,(- -2 fixnum-bit)
+ ,(- -1 fixnum-bit)
,(- fixnum-bit)
,(- (- fixnum-bit 1))
-3 -2 -1 0 1 2 3
,(- fixnum-bit 1)
,fixnum-bit
+ ,(+ fixnum-bit 1)
+ ,(+ fixnum-bit 2)
+ ,(+ fixnum-bit 3)
+ ,(* 2 fixnum-bit)
1000)))
(list 0 1 3 23 -1 -3 -23
fixnum-max
@@ -5423,6 +5431,22 @@
'(#b11001 #b11100 #b11101 #b10001 #b10100 #b10101)))
(list 0 64 -64 (* 64 fixnum-max) (* 64 fixnum-min)))
+ ;; Right shift by LONG_MIN, typically (ash -1 63) and (ash -1 31)
+ ;; depending on the word size, where negating the shift count
+ ;; overflows. See <https://bugs.gnu.org/21901>.
+ (pass-if-equal "Right shift of positive integer by (ash -1 63) bits"
+ 0
+ (ash-variant 123 (ash -1 63)))
+ (pass-if-equal "Right shift of negative integer by (ash -1 63) bits"
+ (if rounded? 0 -1)
+ (ash-variant -123 (ash -1 63)))
+ (pass-if-equal "Right shift of positive integer by (ash -1 31) bits"
+ 0
+ (ash-variant 123 (ash -1 31)))
+ (pass-if-equal "Right shift of negative integer by (ash -1 31) bits"
+ (if rounded? 0 -1)
+ (ash-variant -123 (ash -1 31)))
+
;; Huge shift counts
(pass-if-equal "Huge left shift of 0"
0