diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-11-06 19:22:11 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-11-06 19:22:11 -0800 |
commit | c9a91f89404386552c174fee057b68b3d20c42a8 (patch) | |
tree | 5366d44f6d2007ef6072c512eb1bf20297d5b6a7 /share | |
parent | 548f5dd94aa4cabd725d8eb37e558cee480567c2 (diff) | |
download | txr-c9a91f89404386552c174fee057b68b3d20c42a8.tar.gz txr-c9a91f89404386552c174fee057b68b3d20c42a8.tar.bz2 txr-c9a91f89404386552c174fee057b68b3d20c42a8.zip |
Fix regression: infinite loop in place expansion.
This shows up when the anaphoric ifa is used.
Test case:
| (ifa (f a)
| (set it (g it)))
* share/txr/stdlib/place.tl (sys:pl-expand): In the
origin chasing loop, use a stack to more thoroughly
detect a cycle.
Diffstat (limited to 'share')
-rw-r--r-- | share/txr/stdlib/place.tl | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/share/txr/stdlib/place.tl b/share/txr/stdlib/place.tl index 48e0182e..12ad1b71 100644 --- a/share/txr/stdlib/place.tl +++ b/share/txr/stdlib/place.tl @@ -165,12 +165,14 @@ (defun sys:cp-origin (to-tree from-form : circ-check) (unless (memq to-tree circ-check) (tree-case to-tree - ((a . d) (whenlet (next-orig - (orig (macro-ancestor to-tree))) - (while (and (neq orig from-form) + ((a . d) (whenlet ((next-orig nil) + (visited-stack (list from-form)) + (orig (macro-ancestor to-tree))) + (while (and (not (memq orig visited-stack)) (sys:setq next-orig (macro-ancestor orig))) + (sys:setq visited-stack (cons next-orig visited-stack)) (sys:setq orig next-orig)) - (unless (eq orig from-form) + (unless (memq orig visited-stack) (sys:set-macro-ancestor orig from-form))) (sys:cp-origin a from-form (cons to-tree circ-check)) (sys:cp-origin d from-form (cons to-tree circ-check))))) |