From: Christophe R. <cs...@ca...> - 2004-05-05 10:10:10
|
Hi, Bruno sent me this list of bugs a few days ago. Since our private discussion seems to have died down, I thought I'd forward them to the list with a summary of our discussion (Bruno, feel free to leap back in if I mischaracterise your position -- and thank you for the complete and detailed reports and the useful discussions :-). Bruno Haible <br...@cl...> writes: > Platform: Linux/x86. SBCL version: 0.8.9 compiled by CMUCL 18e. > ============================================================================= > Subject: LOOP :INITIALLY clauses > > ;; reported by "Thomas F. Burdick" <tfb@OCF.Berkeley.EDU> > ;; <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 > > [Taken from clisp's loop.tst] [Bug also present in CMUCL 18e] No discussion. I presume this is a bug, but my loop-fu is weak. > ============================================================================= > Subject: keyword argument determination > > CLHS 3.4.1.4 says that "If more than one such argument pair matches, the > leftmost argument pair is used". > > (defparameter x 1) > x > > (defun test-key () (find 1 #(0 1 2 3) :test #'= :test (incf x))) > test-key > > (list (test-key) x) > Expected: (1 2) > Got: ERROR > > [Taken from clisp's macro8.tst] I don't think this is a bug: I think callers are allowed to add assertions to arguments of built-in operators even if the argument is then subsequently not used. Bruno disagrees. > ============================================================================= > Subject: no bounds check for access to displaced array > > (locally (declare (optimize (safety 3) (speed 0))) > (let* ((x (make-array 10 :fill-pointer 4 :element-type 'character > :initial-element #\space :adjustable t)) > (y (make-array 10 :fill-pointer 4 :element-type 'character > :displaced-to x))) > (adjust-array x '(5)) > (char y 5))) > Expected: ERROR > Got: #\Nul > > [Taken from clisp's strings.tst] [Bug also present in CMUCL 18e] Oh, this one's definitely a bug. > ============================================================================= > Subject: the (COMPLEX type) type > > The type specifier (COMPLEX type) should, according to ANSI CL's description > (HyperSpec/Body/syscla_complex.html), only depend on > (upgraded-complex-element-type type). > > * (upgraded-complex-part-type '(eql 0)) > > RATIONAL > * (upgraded-complex-part-type 'rational) > > RATIONAL > > Therefore the types (COMPLEX (EQL 0)) and (COMPLEX RATIONAL) should be the > same. But TYPEP doesn't work this way: > > * (typep #c(0 1) '(complex rational)) > > T > * (typep #c(0 1) '(complex (eql 0))) > > NIL > > And SUBTYPEP doesn't work this way either: > > * (subtypep '(complex rational) '(complex (eql 0))) > > NIL > T > > [Taken from clisp's type.tst] Fixed in sbcl-0.8.10.9 > ============================================================================= > Subject: SHIFTF and multiple values > > SHIFTF does not support forms that produce multiple values. But parts of the > explanation of SHIFTF in ANSI CL talk about multiple store variables, and > the X3J13 vote SETF-MULTIPLE-STORE-VARIABLES:ALLOW also says that SHIFTF > should support multiple value places. > > * (shiftf (values x y) (values y x)) > > debugger invoked on a SIMPLE-ERROR in thread 2522: > GET-SETF-METHOD used for a form with multiple store variables: > (VALUES X Y) > > [Taken from clisp's setf.tst] Dunno. Probably an arguable bug. > ============================================================================= > Subject: FORMAT of floating-point numbers > > * (FORMAT NIL "~1f" 10) > > "0." > * (FORMAT NIL "~0f" 10) > > "0." > > Expected "10." for both, according to ANSI CL 22.3.3.1. > > Similarly > * (FORMAT NIL "~2f" 1234567.1) > > "1000000." > > Expected "1234567." here. > > [Taken from clisp's format.tst] [Bug also present in CMUCL 18e] Well, sbcl's results here certainly need some explaining. Presumably a bug. > ============================================================================= > Subject: set-pprint-dispatch bug > > (progn > (defun my-pprint-reverse (out list) > (write-char #\( out) > (when (setq list (reverse list)) > (loop (write (pop list) :stream out) > (when (endp list) (return)) > (write-char #\Space out))) > (write-char #\) out)) > (let ((*print-pprint-dispatch* (copy-pprint-dispatch))) > (set-pprint-dispatch '(cons (member foo)) 'my-pprint-reverse 0) > (write-to-string '(foo bar :boo 1) :pretty t :escape t))) > Expected: "(1 :BOO BAR FOO)" > Got: "(FOO BAR :BOO 1)" > > [Taken from clisp's iofkts.tst] > ============================================================================= > Subject: set-pprint-dispatch bug > > (progn > (defun my-pprint-logical (out list) > (pprint-logical-block (out list :prefix "(" :suffix ")") > (when list > (loop (write-char #\? out) > (write (pprint-pop) :stream out) > (write-char #\? out) > (pprint-exit-if-list-exhausted) > (write-char #\Space out))))) > (let ((*print-pprint-dispatch* (copy-pprint-dispatch))) > (set-pprint-dispatch '(cons (member bar)) 'my-pprint-logical 0) > (write-to-string '(bar foo :boo 1) :pretty t :escape t))) > Expected: "(?BAR? ?FOO? ?:BOO? ?1?)" > Got: "(BAR FOO :BOO 1)" > > [Taken from clisp's iofkts.tst] These two were fixed in sbcl-0.8.10.8 by making WRITE-TO-STRING not FOLDABLE. > ============================================================================= > Subject: double-float-epsilon and rounding > > The values of {double,long}-float-{,negative-}epsilon look wrong: > > * (+ 1.0d0 double-float-epsilon) > > 1.0d0 > * (- 1.0d0 double-float-negative-epsilon) > > 1.0d0 > > The values are those that are expected for an IEEE double-float > arithmetic. The problem appears to be that the rounding is not IEEE on x86 > compliant: namely, values are first rounded to 64 bits mantissa precision, > then only to 53 bits mantissa precision. This gives different results than > rounding to 53 bits mantissa precision in a single step. > > The quick "fix", to permanently change the FPU control word from 0x037f to > 0x027f, will give problems with the fdlibm code that is used for computing > transcendental functions like sinh() etc. > > [Taken from clisp's floeps.tst] [Bug also present in CMUCL 18e] > [Looks like the same as bug #118 in sbcl/BUGS] This is indeed the same as bug #118 and also (possibly) #45d. Presumably what we have to do is to alter the control word while executing lisp code, and then restore it in call_into_c? > ============================================================================= > Subject: backquote-comma expression is printed differently > > * (write-to-string '``,,`,3) > > Expected: "``,,`,3" > Got: "3" > > [Taken from clisp's backquot.tst] [Bug also present in CMUCL 18e] I claim this is not a bug: implementations are allowed to optimize backquoted expressions at read-time. I haven't heard to the contrary from Bruno on this one, so I assume he agrees. > ============================================================================= > Subject: deadly stack overflow in compiler warning > > (setq *print-pretty* nil) > (defstruct foo a) > (setf (find-class 'foo) nil) > (defstruct foo slot-1) > > Here SBCL gives a warning/error message from which I can only see the tail: > #<SB-KERNEL:STRUCTURE-CLASSOID #<SB-KERNEL:STRUCTURE-CLASSOID > #<SB-KERNEL:STRUCTURE-CLASSOID #<SB-KERNEL:STRUCTUREControl stack guard page temporarily disabled: proceed with caution > > There are several problems here: > 1) When SBCL decides to show me one of its internal data structures, and > it is a circular structure, it should turn on *print-circle* by itself, > instead of expecting that I have done it. > 2) After this error, the Lisp session is vowed for death: > If I type 0 and then (quit) to exit SBCL, I get > > 0] 0 > > * (quit) > > debugger invoked on a SIMPLE-ERROR in thread 2175: segmentation violation at #X8 > > You can type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL. > > (no restarts: If you didn't do this on purpose, please report it as a bug.) > > debugger invoked on a TYPE-ERROR in thread 2175: > The value NIL is not of type SB-DI:FRAME. > > You can type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL. > > (no restarts: If you didn't do this on purpose, please report it as a bug.) > > debugger invoked on a TYPE-ERROR in thread 2175: > The value NIL is not of type SB-DI:FRAME. > > You can type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL. > > (no restarts: If you didn't do this on purpose, please report it as a bug.) > > debugger invoked on a TYPE-ERROR in thread 2175: > The value NIL is not of type SB-DI:FRAME. > > You can type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL. > > (no restarts: If you didn't do this on purpose, please report it as a bug.) > > debugger invoked on a TYPE-ERROR in thread 2175: > The value NIL is not of type SB-DI:FRAME. > > You can type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL. > > (no restarts: If you didn't do this on purpose, please report it as a bug.) > Help! 11 nested errors. SB-KERNEL:*MAXIMUM-ERROR-DEPTH* exceeded. > > ... and SBCL busy-loops eating CPU time, and doesn't react on Ctrl-C, > Ctrl-Z and Ctrl-\. I can only kill it. > > Similarly if I type Ctrl-D instead of (quit), of if I do (quit) immediately > from within the debugger. > > [Taken from clisp's clos.tst] Er, yeah. :-/ > ============================================================================= > Subject: backquote - comma inside array > > * (READ-FROM-STRING "`#1A(1 2 ,(+ 2 2) 4)") > > #(1 2 ((SB-IMPL::|,|) + 2 2) 4) > 20 > > One would expect either an error, or (as an extension of ANSI CL) > #(1 2 4 4) > > [Taken from clisp's backquot.tst] [Bug also present in CMUCL 18e] Looks like a bug. > ============================================================================= > Subject: handling of shared -> local slot conversion in subclass of redefined class > > ;; Shared slot becomes local. > ;; 4.3.6.1.: "The value of a slot that is specified as shared in the old class > ;; and as local in the new class is retained." > (multiple-value-bind (value condition) > (ignore-errors > (defclass foo85a () ((size :initarg :size :initform 1 :allocation :class))) > (defclass foo85b (foo85a) ()) > (setq i (make-instance 'foo85b)) > (defclass foo85a () ((size :initarg :size :initform 2) (other))) > (slot-value i 'size)) > (list value (type-of condition))) > Expected: (1 NULL) > Got: (2 NULL) > > [Taken from clisp's clos.tst] [Bug also present in CMUCL 18e] A bug. What's happening here is that the class slot is vanishing in shared-initialize standard-class, while the machinery for copying over slot values runs later. Probably we need to keep the old class slot values around for a while. > ============================================================================= > Subject: handling of method qualifiers with user-defined method-combination > > (progn > (defun positive-integer-qualifier-p (method-qualifiers) > (and (= (length method-qualifiers) 1) > (typep (first method-qualifiers) '(integer 0 *)))) > (define-method-combination example-method-combination () > ((method-list positive-integer-qualifier-p)) > `(progn ,@(mapcar #'(lambda (method) `(call-method ,method)) > (stable-sort method-list #'< > :key #'(lambda (method) > (first (method-qualifiers > method))))))) > (defgeneric mc-test-piq (p1 p2 s) > (:method-combination example-method-combination) > (:method 1 ((p1 t) (p2 t) s) (vector-push-extend (list 1 p1 p2) s)) > (:method 2 ((p1 t) (p2 t) s) (vector-push-extend (list 2 p1 p2) s)) > (:method 3 ((p1 t) (p2 t) s) (vector-push-extend (list 3 p1 p2) s))) > (let ((s (make-array 10 :adjustable t :fill-pointer 0))) > (mc-test-piq 1 2 s) > s)) > Expected: #((1 1 2) (2 1 2) (3 1 2)) > Got: ERROR: More than one method of type METHOD-LIST with the same specializers. > > [Taken from clisp's clos.tst] [Bug also present in CMUCL 18e] This was in fact a bug in clisp; the DEFINE-METHOD-COMBINATION page prohibits methods with the same specializers in the same method group, even if they have different qualifiers. > ============================================================================= > Subject: define-method-combination arguments lambda lists parsing > > ;; 3.4.10 Define-method-combination Arguments Lambda Lists > (progn > (define-method-combination w-args () > ((method-list *)) > (:arguments arg1 arg2 &aux (extra :extra)) > `(progn ,@(mapcar #'(lambda (method) `(call-method ,method)) method-list))) > (defgeneric mc-test-w-args (p1 p2 s) > (:method-combination w-args) > (:method ((p1 number) (p2 t) s) > (vector-push-extend (list 'number p1 p2) s)) > (:method ((p1 string) (p2 t) s) > (vector-push-extend (list 'string p1 p2) s)) > (:method ((p1 t) (p2 t) s) (vector-push-extend (list t p1 p2) s))) > (let ((s (make-array 10 :adjustable t :fill-pointer 0))) > (mc-test-w-args 1 2 s) > s)) > Expected: #((NUMBER 1 2) (T 1 2)) > Got: ERROR: The lambda variable (EXTRA :EXTRA) is not a symbol. > > [Taken from clisp's clos.tst] [Bug also present in CMUCL 18e] Yep, this looks like a bug in sbcl. > ============================================================================= > Subject: binary I/O with element type (SIGNED-BYTE 33) > > I/O with element type (SIGNED-BYTE n) where n > 32 doesn't work. > > (defun bin-stream-test (&key (size (integer-length most-positive-fixnum)) > (type 'unsigned-byte) (file-name "./foocl") > (num-bytes 10) > (bytes (if (eq type 'signed-byte) > (loop :repeat num-bytes :collect > (- (random (ash 1 size)) > (ash 1 (1- size)))) > (loop :repeat num-bytes :collect > (random (ash 1 size)))))) > (with-open-file (foo file-name :direction :output #+SBCL :if-exists #+SBCL :supersede > :element-type (list type size)) > (dolist (byte bytes) > (write-byte byte foo))) > (unwind-protect > (with-open-file (foo file-name :direction :input > :element-type (list type size)) > (list (stream-element-type foo) (file-length foo) bytes > (loop :for byte :in bytes :for nb = (read-byte foo) :collect nb > :unless (= nb byte) :do > (flet ((by-out (sz by) > (format nil "~v,'0,' ,4:b" > (+ sz (floor sz 4)) by))) > (error "~& * [(~s ~s)] ~a != ~a~%" type size > (by-out size byte) (by-out size nb)))))) > (delete-file file-name))) > (loop for size from 2 to 40 do (bin-stream-test :size size :type 'signed-byte)) > Expected: NIL > Got: ERROR > > [Taken from clisp's streamslong.tst] Fixed in sbcl-0.8.9.36, I believe. > ============================================================================= > Subject: the COMPLEX type > > * (subtypep 'complex '(complex real)) > > NIL > T > > So there can be instances of COMPLEX whose real and imaginary part are not > REAL? Strange... > > [Taken from clisp's type.tst] [Bug also present in CMUCL 18e] > ============================================================================= > Subject: the empty COMPLEX type > > * (subtypep '(complex nil) 'nil) > > Expected: T T > Got: ERROR: (known bug #145): The type NIL is too hairy to be > used for a COMPLEX component. > > What's too hairy about it? (COMPLEX NIL) is the empty type. > > [Taken from clisp's type.tst] These two were fixed in sbcl-0.8.10.9 > ============================================================================= > Subject: DEFSTRUCT type test predicate > > (defstruct (foo73 (:type list) (:initial-offset 5) :named)) > (defstruct (foo74 (:type list) (:initial-offset 2) :named (:include foo73))) > (foo74-p (list* nil nil nil nil nil 'foo73 nil 'tail)) > Expected: NIL > Got: ERROR: The value TAIL is not of type LIST. > > [Taken from clisp's type.tst] [Bug also present in CMUCL 18e] Strange... I thought we had fixed that ages ago. Oh well. > ============================================================================= > Subject: HANDLER-BIND without effect > > HANDLER-BIND appears to have no effect here: > > * (handler-bind ((type-error (lambda (c) (princ c) (terpri) (use-value '#\1)))) > (eql (char-code #\1) (char-code 12))) > ... > The value 12 is not of type BASE-CHAR. > > debugger invoked on a TYPE-ERROR in thread 2986: > The value 12 is not of type BASE-CHAR. > > [Taken from clisp's conditions.tst] [Bug also present in CMUCL 18e] Not a bug. > ============================================================================= > Subject: attributes of a BROADCAST-STREAM > > http://www.lisp.org/HyperSpec/Body/syscla_broadcast-stream.html > > (stream-external-format (make-broadcast-stream)) > Expected: :DEFAULT > Got: ERROR > > (file-length (make-broadcast-stream)) > Expected: 0 > Got: ERROR > > (file-position (make-broadcast-stream)) > Expected: 0 > Got: NIL > > (file-string-length (make-broadcast-stream) "foo") > Expected: 1 > Got: ERROR > > [Taken from clisp's streams.tst] Disputed: STREAM-EXTERNAL-FORMAT, FILE-LENGTH and FILE-STRING-LENGTH are specified to accept FILE-STREAMs, while MAKE-BROADCAST-STREAM gives results on broadcast streams. Should probably be logged as a bug either way, but fixing it is low priority until we understand why the apparent contradiction. > ============================================================================= > Subject: error when redefining a class with new superclass > > * (defclass foo95b () ((s :initarg :s :accessor foo95b-s))) > > #<STANDARD-CLASS FOO95B> > * (defclass foo95b (foo95a) ((s :accessor foo95b-s))) > > debugger invoked on a SIMPLE-ERROR in thread 2902: > While computing the class precedence list of the class named FOO95B. > The class named FOO95A is a forward referenced class. > The class named FOO95A is a direct superclass of the class named FOO95B. > > Why this error? http://www.lisp.org/HyperSpec/Body/mac_defclass.html says > "It is not required that the superclasses of a class be defined before > the defclass form for that class is evaluated." > And the explanations in CLHS section 4.3.6. which talk about instances > don't apply since there are no instances of the class FOO95B. > > [Taken from clisp's clos.tst] I claim this is not a bug, because the implementation creates an instance when the class is finalized, and therefore the redefinition to an incomplete class is illegal. Bruno I think disagrees, but I think his argument is from programmer convenience rather than specificational authority. -- http://www-jcsu.jesus.cam.ac.uk/~csr21/ +44 1223 510 299/+44 7729 383 757 (set-pprint-dispatch 'number (lambda (s o) (declare (special b)) (format s b))) (defvar b "~&Just another Lisp hacker~%") (pprint #36rJesusCollegeCambridge) |