]> git.eshelyaron.com Git - emacs.git/commit
cl-loop: Add missing guard condition
authorTino Calancha <tino.calancha@gmail.com>
Mon, 8 Jan 2018 10:11:20 +0000 (19:11 +0900)
committerTino Calancha <tino.calancha@gmail.com>
Mon, 8 Jan 2018 10:15:28 +0000 (19:15 +0900)
commita0365437c9ee308ad7978e436631020f513b25e7
treec6164968de607fd2bfd37c32983fe9a4be0eceba
parent1daac66a6eedbcbfa32ab920b5c579872d989517
cl-loop: Add missing guard condition

Consider the expansion of `cl-loop' with a `for' clause and more
than one internal variables, X, Y, processed in parallel.
Each step updates X and Y right after update the loop variable, K; if
either X or Y depend on K, then some forms of the body are
evaluated with the wrong K (Bug#29799).

For instance, consider the following code:
(cl-loop for k below 2
         for x = (progn (message "k = %d" k) 1)
         and y = 1)

This code should show in *Messages*:
k = 0
k = 1

Instead, the code shows:
k = 0
k = 1
k = 2

To prevent this we must ensure that the loop condition is still
satisfied right after update the loop variable.
In the macro expansion of the example above, right after:
(setq k (+ k 1))

evaluate the rest of the body forms iif the condition
(< k 2)
is still valid.

* lisp/emacs-lisp/cl-macs.el (cl--loop-guard-cond): New variable.
(cl--parse-loop-clause): Set it non-nil if the loop contains
a for/as clause.
(cl-loop): After update the loop variable, evaluate the remaining of
the body forms just if the loop condition is still valid (Bug#29799).

* test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs-loop-for-as-equals-and):
New test.
lisp/emacs-lisp/cl-macs.el
test/lisp/emacs-lisp/cl-macs-tests.el