* Fixes lp#454681.
* Patch by Alexey. In his words, in reference to the test-case:
(multiple-value-bind (iterator+977 getter+978)
(does-not-exist-but-does-not-matter)
(flet ((iterator+976 ()
(funcall iterator+977)))
(declare (inline iterator+976))
(let ((iterator+976 #'iterator+976))
(funcall iterator+976)))))
Inline expansion of ITERATOR+976 tries to refer to a dead
LAMBDA-VAR ITERATOR+977 of varargs entry, which was substituted
with ITERATOR+977 of &OPTIONAL processor. Thus the referenced
variable is dead and is not bound anywhere.
The attached patch fixes the problem by giving up on inline
expansion if it tries to make a reference to a dead LAMBDA-VAR,
similar to the way dead BLOCK tags are treated.
(lp#544421)
* bug fix: legally dynamic-extent lists and vectors used as
initialization arguments to MAKE-ARRAY can be stack allocated. (lp#586105)
+ * bug fix: inline-expansion creating references to dead lambda-variables
+ (lp#454681, thanks to Alexey Dejneka)
changes in sbcl-1.0.42 relative to sbcl-1.0.41
* build changes
;;; functional instead.
(defun reference-leaf (start next result leaf &optional (name '.anonymous.))
(declare (type ctran start next) (type (or lvar null) result) (type leaf leaf))
- (when (functional-p leaf)
- (assure-functional-live-p leaf))
+ (assure-leaf-live-p leaf)
(let* ((type (lexenv-find leaf type-restrictions))
(leaf (or (and (defined-fun-p leaf)
(not (eq (defined-fun-inlinep leaf)
(defun delete-lambda-var (leaf)
(declare (type lambda-var leaf))
+ (setf (lambda-var-deleted leaf) t)
;; Iterate over all local calls flushing the corresponding argument,
;; allowing the computation of the argument to be deleted. We also
;; mark the LET for reoptimization, since it may be that we have
(memq (functional-kind functional) '(:deleted :zombie))))
(throw 'locall-already-let-converted functional)))
+(defun assure-leaf-live-p (leaf)
+ (typecase leaf
+ (lambda-var
+ (when (lambda-var-deleted leaf)
+ (throw 'locall-already-let-converted leaf)))
+ (functional
+ (assure-functional-live-p leaf))))
+
+
(defun call-full-like-p (call)
(declare (type combination call))
(let ((kind (basic-combination-kind call)))
;; This is set by physical environment analysis if it chooses an
;; indirect (value cell) representation for this variable because it
;; is both set and closed over.
- indirect)
+ indirect
+ ;; true if the last reference has been deleted (and new references
+ ;; should not be made)
+ deleted
+ )
(def!struct (lambda-var (:include basic-var))
(flags (lambda-var-attributes)
`(lambda-var-attributep (lambda-var-flags ,var) ignore))
(defmacro lambda-var-indirect (var)
`(lambda-var-attributep (lambda-var-flags ,var) indirect))
+(defmacro lambda-var-deleted (var)
+ `(lambda-var-attributep (lambda-var-flags ,var) deleted))
\f
;;;; basic node types
(with-test (:name :dotimes-non-integer-counter-value)
(assert (raises-error? (dotimes (i 8.6)) type-error)))
+
+(with-test (:name :bug-454681)
+ ;; This used to break due to reference to a dead lambda-var during
+ ;; inline expansion.
+ (assert (compile nil
+ `(lambda ()
+ (multiple-value-bind (iterator+977 getter+978)
+ (does-not-exist-but-does-not-matter)
+ (flet ((iterator+976 ()
+ (funcall iterator+977)))
+ (declare (inline iterator+976))
+ (let ((iterator+976 #'iterator+976))
+ (funcall iterator+976))))))))
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.42.14"
+"1.0.42.15"