From: William Harold Newman Date: Wed, 14 Mar 2001 13:46:52 +0000 (+0000) Subject: 0.6.11.14: X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=4ea1b7a6961e6b2d336603a04e448db052993244;p=sbcl.git 0.6.11.14: response to MNA message sbcl-devel 2001-03-07.. ..merged test case to exercise byte compiler bug ..merged patch to fix the bug also merged Dan Barlow's explanation (sbcl-devel 2001-03-12) into a comment in the source --- diff --git a/src/compiler/byte-comp.lisp b/src/compiler/byte-comp.lisp index ae010f6..db5be90 100644 --- a/src/compiler/byte-comp.lisp +++ b/src/compiler/byte-comp.lisp @@ -1268,26 +1268,26 @@ (values (if info (byte-continuation-info-results info) 0))) + (unless (eql values 0) + ;; Someone wants the value, so copy it. + (output-do-xop segment 'dup)) (etypecase leaf - (global-var + (global-var (ecase (global-var-kind leaf) ((:special :global) (output-push-constant segment (global-var-name leaf)) (output-do-inline-function segment 'setf-symbol-value)))) (lambda-var - ;; Note: It's important to test for whether there are any - ;; references to the variable before we actually try to set it. - ;; (Setting a lexical variable with no refs caused bugs ca. CMU - ;; CL 18c, because the compiler deletes such variables.) - (cond ((leaf-refs leaf) - (unless (eql values 0) - ;; Someone wants the value, so copy it. - (output-do-xop segment 'dup)) - (output-set-lambda-var segment leaf (node-environment set))) - ;; If no one wants the value, then pop it, else leave it - ;; for them. - ((eql values 0) - (output-byte-with-operand segment byte-pop-n 1))))) + ;; Note: It's important to test for whether there are any + ;; references to the variable before we actually try to set it. + ;; (Setting a lexical variable with no refs caused bugs ca. CMU + ;; CL 18c, because the compiler deletes such variables.) + (cond ((leaf-refs leaf) + (output-set-lambda-var segment leaf (node-environment set))) + ;; If no one wants the value, then pop it, else leave it + ;; for them. + ((eql values 0) + (output-byte-with-operand segment byte-pop-n 1))))) (unless (eql values 0) (checked-canonicalize-values segment cont 1))) (values)) diff --git a/src/runtime/interrupt.c b/src/runtime/interrupt.c index 94b2de8..a3fd5a0 100644 --- a/src/runtime/interrupt.c +++ b/src/runtime/interrupt.c @@ -280,9 +280,30 @@ interrupt_handle_pending(os_context_t *context) } } - /* FIXME: How come we unconditionally copy from pending_mask into - * the context, and then test whether pending_signal is set? If - * pending_signal wasn't set, how could pending_mask be valid? */ + /* FIXME: This isn't very clear. It would be good to reverse + * engineer it and rewrite the code more clearly, or write a clear + * explanation of what's going on in the comments, or both. + * + * WHN's question 1a: How come we unconditionally copy from + * pending_mask into the context, and then test whether + * pending_signal is set? + * + * WHN's question 1b: If pending_signal wasn't set, how could + * pending_mask be valid? + * + * Dan Barlow's reply (sbcl-devel 2001-03-13): And the answer is - + * or appears to be - because interrupt_maybe_gc set it that way + * (look in the #ifndef __i386__ bit). We can't GC during a + * pseudo-atomic, so we set maybe_gc_pending=1 and + * arch_set_pseudo_atomic_interrupted(..) When we come out of + * pseudo_atomic we're marked as interrupted, so we call + * interrupt_handle_pending, which does the GC using the pending + * context (it needs a context so that it has registers to use as + * GC roots) then notices there's no actual interrupt handler to + * call, so doesn't. That's the second question [1b] answered, + * anyway. Why we still need to copy the pending_mask into the + * context given that we're now done with the context anyway, I + * couldn't say. */ memcpy(os_context_sigmask_addr(context), &pending_mask, sizeof(sigset_t)); sigemptyset(&pending_mask); if (pending_signal) { diff --git a/tests/compiler.pure-cload.lisp b/tests/compiler.pure-cload.lisp index 8c7dd8e..c1b5ef1 100644 --- a/tests/compiler.pure-cload.lisp +++ b/tests/compiler.pure-cload.lisp @@ -20,3 +20,18 @@ (declare (type (mod 1000) a b)) (let ((tmp (= 10 (+ (incf a) (incf a) (incf b) (incf b))))) (or tmp (error "TMP not true")))) + +;;; Exercise a (byte-)compiler bug by causing a call to ERROR, not +;;; because the symbol isn't defined as a variable, but because +;;; TYPE-ERROR in SB-KERNEL::OBJECT-NOT-TYPE-ERROR-HANDLER: +;;; 0 is not of type (OR FUNCTION SB-KERNEL:FDEFN). +;;; Correct behavior is to warn at compile time because the symbol +;;; isn't declared as a variable, but to set its SYMBOL-VALUE anyway. +;;; +;;; This bug was in sbcl-0.6.11.13. +(print (setq improperly-declared-var '(1 2))) +(assert (equal (symbol-value 'improperly-declared-var) '(1 2))) +(makunbound 'improperly-declared-var) +;;; This is a slightly different way of getting the same symptoms out +;;; of the sbcl-0.6.11.13 byte compiler bug. +(print (setq *print-level* *print-level*)) diff --git a/version.lisp-expr b/version.lisp-expr index e1626ff..fe1a06f 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -15,4 +15,4 @@ ;;; versions, and a string like "0.6.5.12" is used for versions which ;;; aren't released but correspond only to CVS tags or snapshots. -"0.6.11.13" +"0.6.11.14"