* Report the type of the array instead, and encapsulate the array object in the
condition object so that it can still be inspected manually.
* Suggested by Stas Boukarev.
"COMPILED-PROGRAM-ERROR"
"ENCAPSULATED-CONDITION"
"INTERPRETED-PROGRAM-ERROR"
+ "INVALID-ARRAY-INDEX-ERROR"
"SIMPLE-CONTROL-ERROR" "SIMPLE-FILE-ERROR"
"SIMPLE-PARSE-ERROR" "SIMPLE-PROGRAM-ERROR"
"SIMPLE-READER-ERROR"
#!+win32 "HANDLE-WIN32-EXCEPTION"
"INTERNAL-TIME" "INTERSECTION-TYPE" "INTERSECTION-TYPE-P"
"INTERSECTION-TYPE-TYPES" "INVALID-ARG-COUNT-ERROR"
- "INVALID-ARRAY-INDEX-ERROR" "INVALID-UNWIND-ERROR"
+ "INVALID-UNWIND-ERROR"
"IRRATIONAL" "JUST-DUMP-IT-NORMALLY" "KEY-INFO"
"KEY-INFO-NAME" "KEY-INFO-P" "KEY-INFO-TYPE"
"LAYOUT-DEPTHOID" "LAYOUT-INVALID-ERROR"
(defun data-vector-ref-with-offset (array index offset)
(hairy-data-vector-ref array (+ index offset)))
+(declaim (ftype (function (array integer integer &optional t) nil) signal-invalid-array-index-error))
+(defun invalid-array-index-error (array index bound &optional axis)
+ (error 'invalid-array-index-error
+ :array array
+ :axis axis
+ :datum index
+ :type `(integer 0 (,bound))))
+
;;; SUBSCRIPTS has a dynamic-extent list structure and is destroyed
(defun %array-row-major-index (array subscripts
&optional (invalid-index-error-p t))
(declare (fixnum dim))
(unless (and (fixnump index) (< -1 index dim))
(if invalid-index-error-p
- (error 'simple-type-error
- :format-control "invalid index ~W~[~;~:; on axis ~:*~W~] in ~S"
- :format-arguments (list index axis array)
- :datum index
- :expected-type `(integer 0 (,dim)))
+ (invalid-array-index-error array index dim axis)
(return-from %array-row-major-index nil)))
(incf result (* chunk-size (the fixnum index)))
(setf chunk-size (* chunk-size dim))))
(length (length (the (simple-array * (*)) array))))
(unless (and (fixnump index) (< -1 index length))
(if invalid-index-error-p
- ;; FIXME: perhaps this should share a format-string
- ;; with INVALID-ARRAY-INDEX-ERROR or
- ;; INDEX-TOO-LARGE-ERROR?
- (error 'simple-type-error
- :format-control "invalid index ~W in ~S"
- :format-arguments (list index array)
- :datum index
- :expected-type `(integer 0 (,length)))
+ (invalid-array-index-error array index length)
(return-from %array-row-major-index nil)))
index))))
"No traps are enabled? How can this be?"
stream))))))
+(define-condition invalid-array-index-error (type-error)
+ ((array :initarg :array :reader invalid-array-index-error-array)
+ (axis :initarg :axis :reader invalid-array-index-error-axis))
+ (:report
+ (lambda (condition stream)
+ (let ((array (invalid-array-index-error-array condition)))
+ (format stream "Index ~W out of bounds for ~@[axis ~W of ~]~S, ~
+ should be nonnegative and <~W."
+ (type-error-datum condition)
+ (when (> (array-rank array) 1)
+ (invalid-array-index-error-axis condition))
+ (type-of array)
+ ;; Extract the bound from (INTEGER 0 (BOUND))
+ (caaddr (type-error-expected-type condition)))))))
+
(define-condition index-too-large-error (type-error)
()
(:report
:format-arguments (list key-name)))
(deferr invalid-array-index-error (array bound index)
- (error 'simple-type-error
- :format-control
- "invalid array index ~W for ~S (should be nonnegative and <~W)"
- :format-arguments (list index array bound)
- :datum index
- :expected-type `(integer 0 (,bound))))
+ (invalid-array-index-error array bound index))
(deferr object-not-simple-array-error (object)
(error 'type-error
(assert (not (array-has-fill-pointer-p
(sb-ext::array-storage-vector
(make-array 5 :fill-pointer 4)))))))
+
+(with-test (:name invalid-array-index-error)
+ (let ((array (make-array '(3 3 3))))
+ (assert
+ (eq :right
+ (handler-case
+ (eval `(aref ,array 0 1 3))
+ (sb-int:invalid-array-index-error (e)
+ (when (and (eq array (sb-kernel::invalid-array-index-error-array e))
+ (= 3 (type-error-datum e)))
+ :right)))))))
;;; 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".)
-"1.0.24.35"
+"1.0.24.36"