+
+297:
+ LOOP with non-constant arithmetic step clauses suffers from overzealous
+ type constraint: code of the form
+ (loop for d of-type double-float from 0d0 to 10d0 by x collect d)
+ compiles to a type restriction on X of (AND DOUBLE-FLOAT (REAL
+ (0))). However, an integral value of X should be legal, because
+ successive adds of integers to double-floats produces double-floats,
+ so none of the type restrictions in the code is violated.
+
+300: (reported by Peter Graves) Function PEEK-CHAR checks PEEK-TYPE
+ argument type only after having read a character. This is caused
+ with EXPLICIT-CHECK attribute in DEFKNOWN. The similar problem
+ exists with =, /=, <, >, <=, >=. They were fixed, but it is probably
+ less error prone to have EXPLICIT-CHECK be a local declaration,
+ being put into the definition, instead of an attribute being kept in
+ a separate file; maybe also put it into SB-EXT?
+
+301: ARRAY-SIMPLE-=-TYPE-METHOD breaks on corner cases which can arise
+ in NOTE-ASSUMED-TYPES
+ In sbcl-0.8.7.32, compiling the file
+ (defun foo (x y)
+ (declare (type integer x))
+ (declare (type (vector (or hash-table bit)) y))
+ (bletch 2 y))
+ (defun bar (x y)
+ (declare (type integer x))
+ (declare (type (simple-array base (2)) y))
+ (bletch 1 y))
+ gives the error
+ failed AVER: "(NOT (AND (NOT EQUALP) CERTAINP))"
+
+302: Undefined type messes up DATA-VECTOR-REF expansion.
+ Compiling this file
+ (defun dis (s ei x y)
+ (declare (type (simple-array function (2)) s) (type ei ei))
+ (funcall (aref s ei) x y))
+ on sbcl-0.8.7.36/X86/Linux causes a BUG to be signalled:
+ full call to SB-KERNEL:DATA-VECTOR-REF
+
+303: "nonlinear LVARs" (aka MISC.293)
+ (defun buu (x)
+ (multiple-value-call #'list
+ (block foo
+ (multiple-value-prog1
+ (eval '(values :a :b :c))
+ (catch 'bar
+ (if (> x 0)
+ (return-from foo
+ (eval `(if (> ,x 1)
+ 1
+ (throw 'bar (values 3 4)))))))))))
+
+ (BUU 1) returns garbage.
+
+ The problem is that both EVALs sequentially write to the same LVAR.
+
+305:
+ (Reported by Dave Roberts.)
+ Local INLINE/NOTINLINE declaration removes local FTYPE declaration:
+
+ (defun quux (x)
+ (declare (ftype (function () (integer 0 10)) fee)
+ (inline fee))
+ (1+ (fee)))
+
+ uses generic arithmetic with INLINE and fixnum without.
+
+306: "Imprecise unions of array types"
+ a.(defun foo (x)
+ (declare (optimize speed)
+ (type (or (array cons) (array vector)) x))
+ (elt (aref x 0) 0))
+ (foo #((0))) => TYPE-ERROR
+
+ relatedly,
+
+ b.(subtypep
+ 'array
+ `(or
+ ,@(loop for x across sb-vm:*specialized-array-element-type-properties*
+ collect `(array ,(sb-vm:saetp-specifier x)))))
+ => NIL, T (when it should be T, T)
+
+308: "Characters without names"
+ (reported by Bruno Haible sbcl-devel "character names are missing"
+ 2004-04-19)
+ (graphic-char-p (code-char 255))
+ => NIL
+ (char-name (code-char 255))
+ => NIL
+
+ SBCL is unsure of what to do about characters with codes in the
+ range 128-255. Currently they are treated as non-graphic, but don't
+ have names, which is not compliant with the standard. Various fixes
+ are possible, such as
+ * giving them names such as NON-ASCII-128;
+ * reducing CHAR-CODE-LIMIT to 127 (almost certainly unpopular);
+ * making the characters graphic (makes a certain amount of sense);
+ * biting the bullet and implementing Unicode (probably quite hard).
+
+309: "Dubious values for implementation limits"
+ (reported by Bruno Haible sbcl-devel "Incorrect value of
+ multiple-values-limit" 2004-04-19)
+ (values-list (make-list 1000000)), on x86/linux, signals a stack
+ exhaustion condition, despite MULTIPLE-VALUES-LIMIT being
+ significantly larger than 1000000. There are probably similar
+ dubious values for CALL-ARGUMENTS-LIMIT (see cmucl-help/cmucl-imp
+ around the same time regarding a call to LIST on sparc with 1000
+ arguments) and other implementation limit constants.
+
+311: "Tokeniser not thread-safe"
+ (see also Robert Marlow sbcl-help "Multi threaded read chucking a
+ spak" 2004-04-19)
+ The tokenizer's use of *read-buffer* and *read-buffer-length* causes
+ spurious errors should two threads attempt to tokenise at the same
+ time.
+
+314: "LOOP :INITIALLY clauses and scope of initializers"
+ reported by Bruno Haible sbcl-devel "various SBCL bugs" from CLISP
+ test suite, originally by Thomas F. Burdick.
+ ;; <http://www.lisp.org/HyperSpec/Body/sec_6-1-7-2.html>
+ ;; According to the HyperSpec 6.1.2.1.4, in for-as-equals-then, var is
+ ;; initialized to the result of evaluating form1. 6.1.7.2 says that
+ ;; initially clauses are evaluated in the loop prologue, which precedes all
+ ;; loop code except for the initial settings provided by with, for, or as.
+ (loop :for x = 0 :then (1+ x)
+ :for y = (1+ x) :then (ash y 1)
+ :for z :across #(1 3 9 27 81 243)
+ :for w = (+ x y z)
+ :initially (assert (zerop x)) :initially (assert (= 2 w))
+ :until (>= w 100) :collect w)
+ Expected: (2 6 15 38)
+ Got: ERROR
+
+317: "FORMAT of floating point numbers"
+ reported by Bruno Haible sbcl-devel "various SBCL bugs" from CLISP
+ test suite.
+ (format nil "~1F" 10) => "0." ; "10." expected
+ (format nil "~0F" 10) => "0." ; "10." expected
+ (format nil "~2F" 1234567.1) => "1000000." ; "1234567." expected
+ it would be nice if whatever fixed this also untangled the two
+ competing implementations of floating point printing (Steele and
+ White, and Burger and Dybvig) present in src/code/print.lisp
+
+318: "stack overflow in compiler warning with redefined class"
+ reported by Bruno Haible sbcl-devel "various SBCL bugs" from CLISP
+ test suite.
+ (setq *print-pretty* nil)
+ (defstruct foo a)
+ (setf (find-class 'foo) nil)
+ (defstruct foo slot-1)
+ gives
+ ...#<SB-KERNEL:STRUCTURE-CLASSOID #<SB-KERNEL:STRUCTURE-CLASSOID #<SB-KERNEL:STRUCTURE-CLASSOID #<SB-KERNEL:STRUCTUREControl stack guard page temporarily disabled: proceed with caution
+ (it's not really clear what it should give: is (SETF FIND-CLASS)
+ meant to be enough to delete structure classes from the system?
+ Giving a stack overflow is definitely suboptimal, though.)
+
+319: "backquote with comma inside array"
+ reported by Bruno Haible sbcl-devel "various SBCL bugs" from CLISP
+ test suite.
+ (read-from-string "`#1A(1 2 ,(+ 2 2) 4)")
+ gives
+ #(1 2 ((SB-IMPL::|,|) + 2 2) 4)
+ which probably isn't intentional.
+
+323: "REPLACE, BIT-BASH and large strings"
+ The transform for REPLACE on simple-base-strings uses BIT-BASH, which
+ at present has an upper limit in size. Consequently, in sbcl-0.8.10
+ (defun foo ()
+ (declare (optimize speed (safety 1)))
+ (let ((x (make-string 140000000))
+ (y (make-string 140000000)))
+ (length (replace x y))))
+ (foo)
+ gives
+ debugger invoked on a TYPE-ERROR in thread 2412:
+ The value 1120000000 is not of type (MOD 536870911).
+ (see also "more and better sequence transforms" sbcl-devel 2004-05-10)
+
+324: "STREAMs and :ELEMENT-TYPE with large bytesize"
+ In theory, (open foo :element-type '(unsigned-byte <x>)) should work
+ for all positive integral <x>. At present, it only works for <x> up
+ to about 1024 (and similarly for signed-byte), so
+ (open "/dev/zero" :element-type '(unsigned-byte 1025))
+ gives an error in sbcl-0.8.10.
+
+325: "CLOSE :ABORT T on supeseding streams"
+ Closing a stream opened with :IF-EXISTS :SUPERSEDE with :ABORT T leaves no
+ file on disk, even if one existed before opening.
+
+ The illegality of this is not crystal clear, as the ANSI dictionary
+ entry for CLOSE says that when :ABORT is T superseded files are not
+ superseded (ie. the original should be restored), whereas the OPEN
+ entry says about :IF-EXISTS :SUPERSEDE "If possible, the
+ implementation should not destroy the old file until the new stream
+ is closed." -- implying that even though undesirable, early deletion
+ is legal. Restoring the original would none the less be the polite
+ thing to do.
+
+326: "*PRINT-CIRCLE* crosstalk between streams"
+ In sbcl-0.8.10.48 it's possible for *PRINT-CIRCLE* references to be
+ mixed between streams when output operations are intermingled closely
+ enough (as by doing output on S2 from within (PRINT-OBJECT X S1) in the
+ test case below), so that e.g. the references #2# appears on a stream
+ with no preceding #2= on that stream to define it (because the #2= was
+ sent to another stream).
+ (cl:in-package :cl-user)
+ (defstruct foo index)
+ (defparameter *foo* (make-foo :index 4))
+ (defstruct bar)
+ (defparameter *bar* (make-bar))
+ (defparameter *tangle* (list *foo* *bar* *foo*))
+ (defmethod print-object ((foo foo) stream)
+ (let ((index (foo-index foo)))
+ (format *trace-output*
+ "~&-$- emitting FOO ~D, ambient *BAR*=~S~%"
+ index *bar*)
+ (format stream "[FOO ~D]" index))
+ foo)
+ (let ((tsos (make-string-output-stream))
+ (ssos (make-string-output-stream)))
+ (let ((*print-circle* t)
+ (*trace-output* tsos)
+ (*standard-output* ssos))
+ (prin1 *tangle* *standard-output*))
+ (let ((string (get-output-stream-string ssos)))
+ (unless (string= string "(#1=[FOO 4] #S(BAR) #1#)")
+ ;; In sbcl-0.8.10.48 STRING was "(#1=[FOO 4] #2# #1#)".:-(
+ (error "oops: ~S" string)))))
+ It might be straightforward to fix this by turning the
+ *CIRCULARITY-HASH-TABLE* and *CIRCULARITY-COUNTER* variables into
+ per-stream slots, but (1) it would probably be sort of messy faking
+ up the special variable binding semantics using UNWIND-PROTECT and
+ (2) it might be sort of a pain to test that no other bugs had been
+ introduced.
+
+328: "Profiling generic functions", transplanted from #241
+ (from tonyms on #lisp IRC 2003-02-25)
+ In sbcl-0.7.12.55, typing
+ (defclass foo () ((bar :accessor foo-bar)))
+ (profile foo-bar)
+ (unintern 'foo-bar)
+ (defclass foo () ((bar :accessor foo-bar)))
+ gives the error message
+ "#:FOO-BAR already names an ordinary function or a macro."
+
+ Problem: when a generic function is profiled, it appears as an ordinary
+ function to PCL. (Remembering the uninterned accessor is OK, as the
+ redefinition must be able to remove old accessors from their generic
+ functions.)
+
+329: "Sequential class redefinition"
+ reported by Bruno Haible:
+ (defclass reactor () ((max-temp :initform 10000000)))
+ (defvar *r1* (make-instance 'reactor))
+ (defvar *r2* (make-instance 'reactor))
+ (slot-value *r1* 'max-temp)
+ (slot-value *r2* 'max-temp)
+ (defclass reactor () ((uptime :initform 0)))
+ (slot-value *r1* 'uptime)
+ (defclass reactor () ((uptime :initform 0) (max-temp :initform 10000)))
+ (slot-value *r1* 'max-temp) ; => 10000
+ (slot-value *r2* 'max-temp) ; => 10000000 oops...
+
+ Possible solution:
+ The method effective when the wrapper is obsoleted can be saved
+ in the wrapper, and then to update the instance just run through
+ all the old wrappers in order from oldest to newest.
+
+331: "lazy creation of CLOS classes for user-defined conditions"
+ (defstruct foo)
+ (defstruct (bar (:include foo)))
+ (sb-mop:class-direct-subclasses (find-class 'foo))
+ returns NIL, rather than a singleton list containing the BAR class.
+
+332: "fasl stack inconsistency in structure redefinition"
+ (reported by Tim Daly Jr sbcl-devel 2004-05-06)
+ Even though structure redefinition is undefined by the standard, the
+ following behaviour is suboptimal: running
+ (defun stimulate-sbcl ()
+ (let ((filename (format nil "/tmp/~A.lisp" (gensym))))
+ ;;create a file which redefines a structure incompatibly
+ (with-open-file (f filename :direction :output :if-exists :supersede)
+ (print '(defstruct astruct foo) f)
+ (print '(defstruct astruct foo bar) f))
+ ;;compile and load the file, then invoke the continue restart on
+ ;;the structure redefinition error
+ (handler-bind ((error (lambda (c) (continue c))))
+ (load (compile-file filename)))))
+ (stimulate-sbcl)
+ and choosing the CONTINUE restart yields the message
+ debugger invoked on a SB-INT:BUG in thread 27726:
+ fasl stack not empty when it should be
+
+336: "slot-definitions must retain the generic functions of accessors"
+ reported by Tony Martinez:
+ (defclass foo () ((bar :reader foo-bar)))
+ (defun foo-bar (x) x)
+ (defclass foo () ((bar :reader get-bar))) ; => error, should work
+
+ Note: just punting the accessor removal if the fdefinition
+ is not a generic function is not enough:
+
+ (defclass foo () ((bar :reader foo-bar)))
+ (defvar *reader* #'foo-bar)
+ (defun foo-bar (x) x)
+ (defclass foo () ((bar :initform 'ok :reader get-bar)))
+ (funcall *reader* (make-instance 'foo)) ; should be an error, since
+ ; the method must be removed
+ ; by the class redefinition
+
+ Fixing this should also fix a subset of #328 -- update the
+ description with a new test-case then.
+
+337: MAKE-METHOD and user-defined method classes
+ (reported by Bruno Haible sbcl-devel 2004-06-11)
+
+ In the presence of
+
+(defclass user-method (standard-method) (myslot))
+(defmacro def-user-method (name &rest rest)
+ (let* ((lambdalist-position (position-if #'listp rest))
+ (qualifiers (subseq rest 0 lambdalist-position))
+ (lambdalist (elt rest lambdalist-position))
+ (body (subseq rest (+ lambdalist-position 1)))
+ (required-part
+ (subseq lambdalist 0 (or
+ (position-if
+ (lambda (x) (member x lambda-list-keywords))
+ lambdalist)
+ (length lambdalist))))
+ (specializers (mapcar #'find-class
+ (mapcar (lambda (x) (if (consp x) (second x) t))
+ required-part)))
+ (unspecialized-required-part
+ (mapcar (lambda (x) (if (consp x) (first x) x)) required-part))
+ (unspecialized-lambdalist
+ (append unspecialized-required-part
+ (subseq lambdalist (length required-part)))))
+ `(PROGN
+ (ADD-METHOD #',name
+ (MAKE-INSTANCE 'USER-METHOD
+ :QUALIFIERS ',qualifiers
+ :LAMBDA-LIST ',unspecialized-lambdalist
+ :SPECIALIZERS ',specializers
+ :FUNCTION
+ (LAMBDA (ARGUMENTS NEXT-METHODS-LIST)
+ (FLET ((NEXT-METHOD-P () NEXT-METHODS-LIST)
+ (CALL-NEXT-METHOD (&REST NEW-ARGUMENTS)
+ (UNLESS NEW-ARGUMENTS (SETQ NEW-ARGUMENTS ARGUMENTS))
+ (IF (NULL NEXT-METHODS-LIST)
+ (ERROR "no next method for arguments ~:S" ARGUMENTS)
+ (FUNCALL (SB-PCL:METHOD-FUNCTION
+ (FIRST NEXT-METHODS-LIST))
+ NEW-ARGUMENTS (REST NEXT-METHODS-LIST)))))
+ (APPLY #'(LAMBDA ,unspecialized-lambdalist ,@body) ARGUMENTS)))))
+ ',name)))
+
+ (progn
+ (defgeneric test-um03 (x))
+ (defmethod test-um03 ((x integer))
+ (list* 'integer x (not (null (next-method-p))) (call-next-method)))
+ (def-user-method test-um03 ((x rational))
+ (list* 'rational x (not (null (next-method-p))) (call-next-method)))
+ (defmethod test-um03 ((x real))
+ (list 'real x (not (null (next-method-p)))))
+ (test-um03 17))
+ works, but
+
+ a.(progn
+ (defgeneric test-um10 (x))
+ (defmethod test-um10 ((x integer))
+ (list* 'integer x (not (null (next-method-p))) (call-next-method)))
+ (defmethod test-um10 ((x rational))
+ (list* 'rational x (not (null (next-method-p))) (call-next-method)))
+ (defmethod test-um10 ((x real))
+ (list 'real x (not (null (next-method-p)))))
+ (defmethod test-um10 :after ((x real)))
+ (def-user-method test-um10 :around ((x integer))
+ (list* 'around-integer x
+ (not (null (next-method-p))) (call-next-method)))
+ (defmethod test-um10 :around ((x rational))
+ (list* 'around-rational x
+ (not (null (next-method-p))) (call-next-method)))
+ (defmethod test-um10 :around ((x real))
+ (list* 'around-real x (not (null (next-method-p))) (call-next-method)))
+ (test-um10 17))
+ fails with a type error, and
+
+ b.(progn
+ (defgeneric test-um12 (x))
+ (defmethod test-um12 ((x integer))
+ (list* 'integer x (not (null (next-method-p))) (call-next-method)))
+ (defmethod test-um12 ((x rational))
+ (list* 'rational x (not (null (next-method-p))) (call-next-method)))
+ (defmethod test-um12 ((x real))
+ (list 'real x (not (null (next-method-p)))))
+ (defmethod test-um12 :after ((x real)))
+ (defmethod test-um12 :around ((x integer))
+ (list* 'around-integer x
+ (not (null (next-method-p))) (call-next-method)))
+ (defmethod test-um12 :around ((x rational))
+ (list* 'around-rational x
+ (not (null (next-method-p))) (call-next-method)))
+ (def-user-method test-um12 :around ((x real))
+ (list* 'around-real x (not (null (next-method-p))) (call-next-method)))
+ (test-um12 17))
+ fails with NO-APPLICABLE-METHOD.
+
+339: "DEFINE-METHOD-COMBINATION bugs"
+ (reported by Bruno Haible via the clisp test suite)
+
+ a. Syntax checking laxity (should produce errors):
+ i. (define-method-combination foo :documentation :operator)
+ ii. (define-method-combination foo :documentation nil)
+ iii. (define-method-combination foo nil)
+ iv. (define-method-combination foo nil nil
+ (:arguments order &aux &key))
+ v. (define-method-combination foo nil nil (:arguments &whole))
+ vi. (define-method-combination foo nil nil (:generic-function))
+ vii. (define-method-combination foo nil nil (:generic-function bar baz))
+ viii. (define-method-combination foo nil nil (:generic-function (bar)))
+ ix. (define-method-combination foo nil ((3)))
+ x. (define-method-combination foo nil ((a)))
+
+ b. define-method-combination arguments lambda list badness
+ i. &aux args are currently unsupported;
+ ii. default values of &optional and &key arguments are ignored;
+ iii. supplied-p variables for &optional and &key arguments are not
+ bound.
+
+ c. qualifier matching incorrect
+ (progn
+ (define-method-combination mc27 ()
+ ((normal ())
+ (ignored (:ignore :unused)))
+ `(list 'result
+ ,@(mapcar #'(lambda (method) `(call-method ,method)) normal)))
+ (defgeneric test-mc27 (x)
+ (:method-combination mc27)
+ (:method :ignore ((x number)) (/ 0)))
+ (test-mc27 7))
+
+ should signal an invalid-method-error, as the :IGNORE (NUMBER)
+ method is applicable, and yet matches neither of the method group
+ qualifier patterns.
+
+340: SETF of VALUES using too many values
+ (fixed in sbcl-0.8.12.10)