X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=tests%2Fclos.impure.lisp;h=e5cc14046c91e46398bd169339a95da3e9636a25;hb=68ea71d0f020f2726e3c56c1ec491d0af734b3a4;hp=a1e22b137b450e70568fb8cad066d971eaf791ae;hpb=fb03344c5e8388e0b16512f1cb662d8cf5d13972;p=sbcl.git diff --git a/tests/clos.impure.lisp b/tests/clos.impure.lisp index a1e22b1..e5cc140 100644 --- a/tests/clos.impure.lisp +++ b/tests/clos.impure.lisp @@ -1320,4 +1320,85 @@ (defclass class-with-odd-class-name-method () ((a :accessor class-name))) +;;; another case where precomputing (this time on PRINT-OBJET) and +;;; lazily-finalized classes caused problems. (report from James Y +;;; Knight sbcl-devel 20-07-2006) + +(defclass base-print-object () ()) +;;; this has the side-effect of finalizing BASE-PRINT-OBJECT, and +;;; additionally the second specializer (STREAM) changes the cache +;;; structure to require two keys, not just one. +(defmethod print-object ((o base-print-object) (s stream)) + nil) + +;;; unfinalized as yet +(defclass sub-print-object (base-print-object) ()) +;;; the accessor causes an eager finalization +(defclass subsub-print-object (sub-print-object) + ((a :accessor a))) + +;;; triggers a discriminating function (and so cache) recomputation. +;;; The method on BASE-PRINT-OBJECT will cause the system to attempt +;;; to fill the cache for all subclasses of BASE-PRINT-OBJECT which +;;; have valid wrappers; however, in the course of doing so, the +;;; SUB-PRINT-OBJECT class gets finalized, which invalidates the +;;; SUBSUB-PRINT-OBJECT wrapper; if an invalid wrapper gets into a +;;; cache with more than one key, then failure ensues. +(reinitialize-instance #'print-object) + +;;; bug in long-form method combination: if there's an applicable +;;; method not part of any method group, we need to call +;;; INVALID-METHOD-ERROR. (MC27 test case from Bruno Haible) +(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))) +(assert (raises-error? (test-mc27 7))) + +(define-method-combination mc27prime () + ((normal ()) + (ignored (:ignore))) + `(list 'result ,@(mapcar (lambda (m) `(call-method ,m)) normal))) +(defgeneric test-mc27prime (x) + (:method-combination mc27prime) + (:method :ignore ((x number)) (/ 0))) +(assert (equal '(result) (test-mc27prime 3))) +(assert (raises-error? (test-mc27 t))) ; still no-applicable-method + +;;; more invalid wrappers. This time for a long-standing bug in the +;;; compiler's expansion for TYPEP on various class-like things, with +;;; user-visible consequences. +(defclass obsolete-again () ()) +(defvar *obsolete-again* (make-instance 'obsolete-again)) +(defvar *obsolete-again-hash* (sxhash *obsolete-again*)) +(make-instances-obsolete (find-class 'obsolete-again)) +(assert (not (streamp *obsolete-again*))) +(make-instances-obsolete (find-class 'obsolete-again)) +(assert (= (sxhash *obsolete-again*) *obsolete-again-hash*)) +(compile (defun is-a-structure-object-p (x) (typep x 'structure-object))) +(make-instances-obsolete (find-class 'obsolete-again)) +(assert (not (is-a-structure-object-p *obsolete-again*))) + +;;; overeager optimization of slot-valuish things +(defclass listoid () + ((caroid :initarg :caroid) + (cdroid :initarg :cdroid :initform nil))) +(defmethod lengthoid ((x listoid)) + (let ((result 0)) + (loop until (null x) + do (incf result) (setq x (slot-value x 'cdroid))) + result)) +(with-test (:name ((:setq :method-parameter) slot-value) :fails-on :sbcl) + (assert (= (lengthoid (make-instance 'listoid)) 1)) + (error "the failure mode is an infinite loop") + (assert (= (lengthoid + (make-instance 'listoid :cdroid + (make-instance 'listoid :cdroid + (make-instance 'listoid)))) + 3))) + ;;;; success