circumstances could go off-by-one.
* improved MACHINE-VERSION, especially on Linux (thanks to Lars
Brinkhoff)
+ * type declarations for array element types now obey the description
+ on the CLHS page "Declaration TYPE", as per discussions on
+ sbcl-help around 2003-05-08. This means that a declaration
+ (TYPE (ARRAY FOO) BAR) means that, within the scope of the
+ declaration, all references to BAR will be asserted or assumed
+ (with THE, so dependent on compiler policy) to involve objects of
+ type FOO. Note that no such declaration is implied in
+ (MAKE-ARRAY .. :ELEMENT-TYPE 'FOO).
planned incompatible changes in 0.8.x:
* (not done yet, but planned:) When the profiling interface settles
(bug "called FAILED-%WITH-ARRAY-DATA with valid array parameters?"))
\f
;;;; MAKE-ARRAY
-(defun upgraded-array-element-type (spec &optional environment)
- #!+sb-doc
- "Return the element type that will actually be used to implement an array
- with the specifier :ELEMENT-TYPE Spec."
- (declare (ignore environment))
- (if (unknown-type-p (specifier-type spec))
- (error "undefined type: ~S" spec)
- (type-specifier (array-type-specialized-element-type
- (specifier-type `(array ,spec))))))
(eval-when (:compile-toplevel :execute)
(sb!xc:defmacro pick-vector-type (type &rest specs)
`(cond ,@(mapcar (lambda (spec)
(mapcar (lambda (x y) (if (eq x '*) y x))
dims1 dims2)))
:complexp (if (eq complexp1 :maybe) complexp2 complexp1)
- :element-type (if (eq eltype1 *wild-type*) eltype2 eltype1))))
+ :element-type (cond
+ ((eq eltype1 *wild-type*) eltype2)
+ ((eq eltype2 *wild-type*) eltype1)
+ (t (type-intersection eltype1 eltype2))))))
*empty-type*))
;;; Check a supplied dimension list to determine whether it is legal,
"STRUCTURE-CLASS"
"SUBTYPEP"
"TYPE-OF" "TYPEP"
+ "UPGRADED-ARRAY-ELEMENT-TYPE"
"WITH-COMPILATION-UNIT"))
(export (intern name package-name) package-name)))
;; don't watch:
;; 2002-08-21
*wild-type*)))
+(defun extract-declared-element-type (array)
+ (let ((type (continuation-type array)))
+ (if (array-type-p type)
+ (array-type-element-type type)
+ *wild-type*)))
+
;;; The ``new-value'' for array setters must fit in the array, and the
;;; return type is going to be the same as the new-value for SETF
;;; functions.
`(,(if simple 'simple-array 'array)
,(cond ((not element-type) t)
((constant-continuation-p element-type)
- (continuation-value element-type))
+ (let ((ctype (careful-specifier-type
+ (continuation-value element-type))))
+ (cond
+ ((or (null ctype) (unknown-type-p ctype)) '*)
+ (t (sb!xc:upgraded-array-element-type
+ (continuation-value element-type))))))
(t
'*))
,(cond ((constant-continuation-p dims)
(len (if (constant-continuation-p length)
(continuation-value length)
'*))
- (result-type-spec `(simple-array ,eltype (,len)))
(eltype-type (ir1-transform-specifier-type eltype))
+ (result-type-spec
+ `(simple-array
+ ,(if (unknown-type-p eltype-type)
+ (give-up-ir1-transform
+ "ELEMENT-TYPE is an unknown type: ~S" eltype)
+ (sb!xc:upgraded-array-element-type eltype))
+ (,len)))
(saetp (find-if (lambda (saetp)
(csubtypep eltype-type (saetp-ctype saetp)))
*specialized-array-element-type-properties*)))
(rank (length dims))
(spec `(simple-array
,(cond ((null element-type) t)
- ((constant-continuation-p element-type)
- (continuation-value element-type))
+ ((and (constant-continuation-p element-type)
+ (ir1-transform-specifier-type
+ (continuation-value element-type)))
+ (sb!xc:upgraded-array-element-type
+ (continuation-value element-type)))
(t '*))
,(make-list rank :initial-element '*))))
`(let ((header (make-array-header sb!vm:simple-array-widetag ,rank)))
;; SIGNED-BYTE arrays, so better make it break now if it ever
;; will:
#+sb-xc-host
+ ;; not SB!XC:UPGRADED-ARRAY-ELEMENT-TYPE, because we are
+ ;; worried about whether the host's implementation of arrays.
(aver (subtypep (upgraded-array-element-type specializer)
'unsigned-byte))
(coerce seq `(simple-array ,specializer (*)))))))
(defknown type-of (t) t (foldable flushable))
;;; These can be affected by type definitions, so they're not FOLDABLE.
-(defknown (upgraded-complex-part-type upgraded-array-element-type)
+(defknown (upgraded-complex-part-type sb!xc:upgraded-array-element-type)
(type-specifier &optional lexenv-designator) type-specifier
(unsafely-flushable))
\f
(deftransform hairy-data-vector-ref ((array index) (array t) * :important t)
"avoid runtime dispatch on array element type"
- (let ((element-ctype (extract-upgraded-element-type array)))
+ (let ((element-ctype (extract-upgraded-element-type array))
+ (declared-element-ctype (extract-declared-element-type array)))
(declare (type ctype element-ctype))
(when (eq *wild-type* element-ctype)
(give-up-ir1-transform
`(multiple-value-bind (array index)
(%data-vector-and-index array index)
(declare (type (simple-array ,element-type-specifier 1) array))
- (data-vector-ref array index)))))
+ ,(let ((bare-form '(data-vector-ref array index)))
+ (if (type= element-ctype declared-element-ctype)
+ bare-form
+ `(the ,(type-specifier declared-element-ctype)
+ ,bare-form)))))))
(deftransform data-vector-ref ((array index)
(simple-array t))
*
:important t)
"avoid runtime dispatch on array element type"
- (let ((element-ctype (extract-upgraded-element-type array)))
+ (let ((element-ctype (extract-upgraded-element-type array))
+ (declared-element-ctype (extract-declared-element-type array)))
(declare (type ctype element-ctype))
(when (eq *wild-type* element-ctype)
(give-up-ir1-transform
(%data-vector-and-index array index)
(declare (type (simple-array ,element-type-specifier 1) array)
(type ,element-type-specifier new-value))
- (data-vector-set array
- index
- new-value)))))
+ ,(if (type= element-ctype declared-element-ctype)
+ '(data-vector-set array index new-value)
+ `(truly-the ,(type-specifier declared-element-ctype)
+ (data-vector-set array index
+ (the ,(type-specifier declared-element-ctype)
+ new-value))))))))
(deftransform data-vector-set ((array index new-value)
(simple-array t t))
(return stype))))))
type))
+(defun sb!xc:upgraded-array-element-type (spec &optional environment)
+ #!+sb-doc
+ "Return the element type that will actually be used to implement an array
+ with the specifier :ELEMENT-TYPE Spec."
+ (declare (ignore environment))
+ (if (unknown-type-p (specifier-type spec))
+ (error "undefined type: ~S" spec)
+ (type-specifier (array-type-specialized-element-type
+ (specifier-type `(array ,spec))))))
+
;;; Return the most specific integer type that can be quickly checked that
;;; includes the given type.
(defun containing-integer-type (subtype)
(assert fail)
(assert (raises-error? (funcall fun) type-error)))
+(multiple-value-bind (fun warn fail)
+ (compile nil '(lambda () (make-array 5 :element-type 'undefined-type)))
+ (assert warn))
;;; bug 31 turned out to be a manifestation of non-ANSI array type
;;; handling, fixed by CSR in sbcl-0.7.3.8.
(defun array-element-type-handling (x)
+ (declare (optimize safety))
(declare (type (vector cons) x))
(when (consp (aref x 0))
(aref x 0)))
-(assert (eq (array-element-type-handling
- (make-array 3 :element-type t :initial-element 0))
- nil))
+(assert (raises-error?
+ (array-element-type-handling
+ (make-array 3 :element-type t :initial-element 0))
+ type-error))
;;; bug 220: type check inserted after all arguments in MV-CALL caused
;;; failure of stack analysis
(assert (equal y #*00))
(funcall f y 1)
(assert (equal y #*10))))
+
+(handler-bind ((sb-ext:compiler-note #'error))
+ (compile nil '(lambda (x)
+ (declare (type (simple-array (simple-string 3) (5)) x))
+ (aref (aref x 0) 0))))
;;; 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.1.8"
+"0.8.1.9"