Disallow converting negative numbers to int/u64

The wrap-around rule doesn't make sense once subtraction is
properly fixed.
This commit is contained in:
Calvin Rose 2023-07-09 22:25:20 -05:00
parent f3bda1536d
commit 8183cc5a8d
2 changed files with 10 additions and 13 deletions

View File

@ -118,10 +118,9 @@ int64_t janet_unwrap_s64(Janet x) {
default: default:
break; break;
case JANET_NUMBER : { case JANET_NUMBER : {
double dbl = janet_unwrap_number(x); double d = janet_unwrap_number(x);
if (fabs(dbl) <= MAX_INT_IN_DBL) if (!janet_checkint64range(d)) break;
return (int64_t)dbl; return (int64_t) d;
break;
} }
case JANET_STRING: { case JANET_STRING: {
int64_t value; int64_t value;
@ -147,12 +146,9 @@ uint64_t janet_unwrap_u64(Janet x) {
default: default:
break; break;
case JANET_NUMBER : { case JANET_NUMBER : {
double dbl = janet_unwrap_number(x); double d = janet_unwrap_number(x);
/* Allow negative values to be cast to "wrap around". if (!janet_checkuint64range(d)) break;
* This let's addition and subtraction work as expected. */ return (uint64_t) d;
if (fabs(dbl) <= MAX_INT_IN_DBL)
return (uint64_t)dbl;
break;
} }
case JANET_STRING: { case JANET_STRING: {
uint64_t value; uint64_t value;

View File

@ -196,7 +196,8 @@
(assert-error "division by zero" (op (int 7) (int 0))))) (assert-error "division by zero" (op (int 7) (int 0)))))
(each int [int/s64 int/u64] (each int [int/s64 int/u64]
(loop [x :in [-5 -3 0 3 5]] (loop [x :in [-5 -3 0 3 5] :when (or (pos? x) (= int int/s64))]
# skip check when comparing negative values with unsigned integers.
(assert (= (int x) (mod (int x) 0)) (string int " mod 0")) (assert (= (int x) (mod (int x) 0)) (string int " mod 0"))
(assert (= (int x) (mod x (int 0))) (string int " mod 0")) (assert (= (int x) (mod x (int 0))) (string int " mod 0"))
(assert (= (int x) (mod (int x) (int 0))) (string int " mod 0")))) (assert (= (int x) (mod (int x) (int 0))) (string int " mod 0"))))
@ -267,12 +268,12 @@
# compare u64/i64 # compare u64/i64
(assert (= (compare (u64 1) (i64 2)) -1) "compare 7") (assert (= (compare (u64 1) (i64 2)) -1) "compare 7")
(assert (= (compare (u64 1) (i64 -1)) +1) "compare 8") (assert (= (compare (u64 1) (i64 -1)) +1) "compare 8")
(assert (= (compare (u64 -1) (i64 -1)) +1) "compare 9") (assert (= (compare (u64 0) (i64 -1)) +1) "compare 9")
# compare i64/u64 # compare i64/u64
(assert (= (compare (i64 1) (u64 2)) -1) "compare 10") (assert (= (compare (i64 1) (u64 2)) -1) "compare 10")
(assert (= (compare (i64 -1) (u64 1)) -1) "compare 11") (assert (= (compare (i64 -1) (u64 1)) -1) "compare 11")
(assert (= (compare (i64 -1) (u64 -1)) -1) "compare 12") (assert (= (compare (i64 -1) (u64 0)) -1) "compare 12")
# off by 1 error in inttypes # off by 1 error in inttypes
# a3e812b86 # a3e812b86