commit 84e00cbc1702be62eff1f83006603f02b24d93c3 Author: Alastair Bridgewater Date: Thu Oct 21 18:14:40 2010 -0400 constraint: Check leaf visibility prior to changing REF LEAFs. * Define a new predicate, LEAF-VISIBLE-FROM-NODE to check if a NODE is in a lexical environment to be able to "see" a given LEAF. * Use the new predicate to prevent rewriting REFs to point to LEAFs that aren't in the REFs lexical environment (thus preventing problems with attempting to CLOSE-OVER a variable that isn't visible). * This fixes lp#551227 (error: the value NIL is not of type SB-C::NODE), but I'm not entirely convinced of its correctness. diff --git a/src/compiler/constraint.lisp b/src/compiler/constraint.lisp index eb936ba..da8e55e 100644 --- a/src/compiler/constraint.lisp +++ b/src/compiler/constraint.lisp @@ -604,6 +604,25 @@ (modified-numeric-type x :low new-bound) (modified-numeric-type x :high new-bound))))) +;;; Return true if LEAF is "visible" from NODE. +(defun leaf-visible-from-node (leaf node) + (cond + ((lambda-var-p leaf) + ;; A LAMBDA-VAR is visible iif it is homed in a CLAMBDA in the + ;; allocator chain for NODE. + (let ((leaf-lambda (lambda-var-home leaf)) + (node-lambda (node-home-lambda node))) + (loop for lambda = node-lambda then (awhen (functional-allocator lambda) + (node-home-lambda it)) + while lambda + when (eq lambda leaf-lambda) + return t))) + ;; FIXME: Check on FUNCTIONALs (CLAMBDAs and OPTIONAL-DISPATCHes), + ;; not just LAMBDA-VARs. + (t + ;; Assume everything else is globally visible. + t))) + ;;; Given the set of CONSTRAINTS for a variable and the current set of ;;; restrictions from flow analysis IN, set the type for REF ;;; accordingly. @@ -659,7 +678,11 @@ (and (leaf-refs other) ; protect from ; deleted vars (csubtypep other-type leaf-type) - (not (type= other-type leaf-type)))) + (not (type= other-type leaf-type)) + ;; KLUDGE: This "fixes" lp#551227, + ;; but I don't know that it's truly + ;; correct. -- AB, 2010-Oct-21 + (leaf-visible-from-node other ref))) (change-ref-leaf ref other) (when (constant-p other) (return))) (t