Comment 1 for bug 1472785

Revision history for this message
Alastair Bridgewater (alastair-bridgewater) wrote :

Here's another test case, not so dependent on the FILL transform:

(defun bar (x)
  (let ((y (let ((z (cons nil nil)))
             (let ((i 0))
               (tagbody
                b1
                  (when (= x i) (go b2))
                  (incf i)
                  (go b1)
                b2))
             z))
        (w (cons t t)))
    (declare (dynamic-extent y w))
    (eq y w)))

Due to the bug (BAR 0) => NIL, but (BAR 1) => T.

The actual problem is in src/compiler/stack.lisp, BACK-PROPAGATE-ONE-DX-LVAR, where it tries to prevent falling into an infinite loop by refusing to traverse a block twice, which is wrong. Mea culpa. The correct thing to do is to refuse to repeat a transition between two blocks. That way, it can still visit a block multiple times, but because it can't take the same path twice it will still terminate.

Thanks to stassats for narrowing this down to a stack-analysis issue.