summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-04-20 21:10:55 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-04-20 21:10:55 -0700
commitbda1272fb52f645d13c5b07eb85577b72e93d531 (patch)
tree33afe887014553c32676612bec3dfca89a93a5c3
parentf325a231ae4c618c5e03351f712043e6c2350799 (diff)
downloadtxr-bda1272fb52f645d13c5b07eb85577b72e93d531.tar.gz
txr-bda1272fb52f645d13c5b07eb85577b72e93d531.tar.bz2
txr-bda1272fb52f645d13c5b07eb85577b72e93d531.zip
Bugfix: ash: right shifts of fixnums broken.
* arith.c (ash): The bn <= num_bits comparison here is always true because bn < 0, leading to undefined behavior when bn is sufficiently negative, due to the shift being as wide or wider than the number of bits in a cnum.
-rw-r--r--arith.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/arith.c b/arith.c
index d22adb9b..e9ecdf54 100644
--- a/arith.c
+++ b/arith.c
@@ -2432,9 +2432,10 @@ val ash(val a, val bits)
} else {
switch (type(a)) {
case NUM:
+ bn = -bn;
an = c_num(a);
if (bn <= num_bits)
- return num_fast(an >> -bn);
+ return num_fast(an >> bn);
return num_fast(an >> num_bits);
case BGNUM:
b = make_bignum();