0.8.13.12:
authorChristophe Rhodes <csr21@cam.ac.uk>
Fri, 30 Jul 2004 10:45:30 +0000 (10:45 +0000)
committerChristophe Rhodes <csr21@cam.ac.uk>
Fri, 30 Jul 2004 10:45:30 +0000 (10:45 +0000)
Fix for division-of-integer-by-constant-zero bug
... don't perform the 2^k transform for k = -1 (which when
rounded to an integer gives zero...)
... tests.

NEWS
src/compiler/aliencomp.lisp
src/compiler/srctran.lisp
tests/arith.pure.lisp
version.lisp-expr

diff --git a/NEWS b/NEWS
index 4f52e72..0e37ace 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,9 @@ changes in sbcl-0.8.14 relative to sbcl-0.8.13:
     (reported by Rick Taube)
   * bug fix: structures defined by WITH-ALIEN can be referred to
     within other definitions in the same WITH-ALIEN.
+  * bug fix: division operators (MOD, TRUNCATE and the like) with
+    constant zero divisors and integer dividends no longer generate
+    left shifts.
 
 changes in sbcl-0.8.13 relative to sbcl-0.8.12:
   * new feature: SB-PACKAGE-LOCKS. See the "Package Locks" section of
index 56ff0f3..5ff9427 100644 (file)
     (give-up-ir1-transform))
   (let* ((denominator (lvar-value denominator))
         (bits (1- (integer-length denominator))))
-    (unless (= (ash 1 bits) denominator)
+    (unless (and (> denominator 0) (= (ash 1 bits) denominator))
       (give-up-ir1-transform))
     (let ((alignment (count-low-order-zeros numerator)))
       (unless (>= alignment bits)
index cbc59ca..e4084c3 100644 (file)
   (let* ((y (lvar-value y))
         (y-abs (abs y))
         (len (1- (integer-length y-abs))))
-    (unless (= y-abs (ash 1 len))
+    (unless (and (> y-abs 0) (= y-abs (ash 1 len)))
       (give-up-ir1-transform))
     (if (minusp y)
        `(- (ash x ,len))
         (let* ((y (lvar-value y))
                (y-abs (abs y))
                (len (1- (integer-length y-abs))))
-          (unless (= y-abs (ash 1 len))
+          (unless (and (> y-abs 0) (= y-abs (ash 1 len)))
             (give-up-ir1-transform))
           (let ((shift (- len))
                 (mask (1- y-abs))
   (let* ((y (lvar-value y))
         (y-abs (abs y))
         (len (1- (integer-length y-abs))))
-    (unless (= y-abs (ash 1 len))
+    (unless (and (> y-abs 0) (= y-abs (ash 1 len)))
       (give-up-ir1-transform))
     (let ((mask (1- y-abs)))
       (if (minusp y)
   (let* ((y (lvar-value y))
         (y-abs (abs y))
         (len (1- (integer-length y-abs))))
-    (unless (= y-abs (ash 1 len))
+    (unless (and (> y-abs 0) (= y-abs (ash 1 len)))
       (give-up-ir1-transform))
     (let* ((shift (- len))
           (mask (1- y-abs)))
   (let* ((y (lvar-value y))
         (y-abs (abs y))
         (len (1- (integer-length y-abs))))
-    (unless (= y-abs (ash 1 len))
+    (unless (and (> y-abs 0) (= y-abs (ash 1 len)))
       (give-up-ir1-transform))
     (let ((mask (1- y-abs)))
       `(if (minusp x)
index 8c47082..8d1d12b 100644 (file)
 ;;; ASH of a negative bignum by a bignum count would erroneously
 ;;; return 0 prior to sbcl-0.8.4.4
 (assert (= (ash (1- most-negative-fixnum) (1- most-negative-fixnum)) -1))
+
+;;; Whoops.  Too much optimization in division operators for 0
+;;; divisor.
+(macrolet ((frob (name)
+            `(let ((fn (compile nil '(lambda (x)
+                                      (declare (optimize speed) (fixnum x))
+                                      (,name x 0)))))
+              (assert (raises-error? (funcall fn 1) division-by-zero)))))
+  (frob mod)
+  (frob truncate)
+  (frob rem)
+  (frob /)
+  (frob floor)
+  (frob ceiling))
index 1836c0c..59b49f0 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"0.8.13.11"
+"0.8.13.12"