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
commit0ba765092f20424828a520d6ccda1c313dab08f0 (patch)
tree33afe887014553c32676612bec3dfca89a93a5c3
parent2a93dcfebf39ce77d3cfd3a180cacae8e8a5aacc (diff)
downloadtxr-0ba765092f20424828a520d6ccda1c313dab08f0.tar.gz
txr-0ba765092f20424828a520d6ccda1c313dab08f0.tar.bz2
txr-0ba765092f20424828a520d6ccda1c313dab08f0.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();