Avoid undefined behaviour with large right shifts.
authorTaylor R Campbell <campbell@mumble.net>
Fri, 14 Dec 2018 16:48:00 +0000 (16:48 +0000)
committerTaylor R Campbell <campbell@mumble.net>
Sat, 15 Dec 2018 22:33:21 +0000 (22:33 +0000)
src/microcode/artutl.c
tests/runtime/test-integer-bits.scm

index d3d666a32d28edc47715b92b40dad9b6723d5dde..114bd05428565075134e46418ce75b989b38a2b7 100644 (file)
@@ -696,6 +696,8 @@ integer_shift_right (SCHEME_OBJECT n, unsigned long m)
   if (FIXNUM_P (n))
     {
       long n1 = (FIXNUM_TO_LONG (n));
+      if (m >= (CHAR_BIT * (sizeof (n1))))
+       return (LONG_TO_FIXNUM ((n1 < 0) ? (-1) : 0));
       return (LONG_TO_FIXNUM ((n1 < 0) ? (~ ((~n1) >> m)) : (n1 >> m)));
     }
   else
index 531d08d9e5ae6800357c56929cf27619b79754eb..8f1991521362a59d58f96cc48d04a613637e4d46 100644 (file)
@@ -466,6 +466,4 @@ USA.
 \f
 (define-test 'SHIFT-RIGHT/TOO-MANY
   (lambda ()
-    (expect-failure
-     (lambda ()
-       (assert-= (shift-right (identity-procedure 1234567) 100) 0)))))
\ No newline at end of file
+    (assert-= (shift-right (identity-procedure 1234567) 100) 0)))
\ No newline at end of file