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
(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))
}
}
- /* 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) {
(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*))
;;; 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"