Comment 2 for bug 308951

Revision history for this message
Roman Marynchak (roman-marynchak) wrote :

The problem is connected with incorrect inlining of the FOO's body into BAR. To verify that, check out this code, where FOO is declared notinline:

     (declaim (notinline foo))
     (let ((x 1))
      (dotimes (y 10)
        (let ((y y))
          (when (funcall (eval #'(lambda (x) (eql x 2))) y)
            (defun foo (z)
              (incf x (incf y z))))))
      (defun bar (z)
        (foo z)
        (values x)))

(BAR 1) returns 4 in this case. You can see the problem better with this code:

(let ((x 1))
     (dotimes (y 10)
        (let ((y y))
          (when (= 2 y)
            (defun foo ()
              (print y)))))
      (defun bar () (foo)))

Try to call FOO and BAR. FOO prints 2, while BAR prints 9. The bug is that BAR has the access to Y value when inlining the FOO's body, but lexically this is wrong, since Y should not be normally visible from BAR. As a simple workaround, use 'notinline' declaration until somebody (maybe me, but I do not promise this) fixes this (probably src/compiler/locall.lisp is the right place to look into).

Roman