bogus type-error from array access optimization using negative index and positive offset
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Fix Released
|
Medium
|
Unassigned |
Bug Description
x86 and x86-64 only, I think.
Test case:
(defun oops ()
#+nil
(declare (optimize (safety 0)))
(let ((table (make-array 7 :element-type 'fixnum :initial-contents '(0 1 2 3 4 5 6))))
(loop for n from -3 upto 3
do (print (aref table (+ 3 n))))))
signals an error unless SAFETY 0:
The value -3 is not of type (MOD 115292150460684
With SAFETY 0 prints out numbers 0-6, demonstrating that the computed offsets are correct.
The deftransform for data-vector-
However, somewhere we end up generating a type-check for the other offset, asserting that it is a regular array index -- whereas due to the +3 the lower end of the range has been extended to -3. I suspect that that typecheck is wholly pointless, actually.
Changed in sbcl: | |
status: | New → Confirmed |
importance: | Undecided → High |
importance: | High → Medium |
This is what the fix looks like:
diff --git a/src/compiler/ fndb.lisp b/src/compiler/ fndb.lisp fndb.lisp fndb.lisp translatable) ) ref-with- offset (simple-array index fixnum) t ref-with- offset (simple-array fixnum fixnum) t translatable) ) translatable) )
index dfb0dcd..5991492 100644
--- a/src/compiler/
+++ b/src/compiler/
@@ -1448,7 +1448,7 @@
(defknown %check-bound (array index fixnum) index (movable foldable flushable))
(defknown data-vector-ref (simple-array index) t
(foldable explicit-check always-
-(defknown data-vector-
+(defknown data-vector-
(foldable explicit-check always-
(defknown data-vector-set (array index t) t
(unsafe explicit-check always-
Merging after freeze -- though I have good confidence in this fix, the problem has been there for a long time and no-one has yet to report it.