From f8b30fad490086472cb088f76b968ca8ad769eff Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sat, 15 Apr 2017 18:28:36 -0700 Subject: Bugfix expansion: return-from, sys:abscond-from, block*. These three forms are not being traversed properly by the macro expander. * eval.c (do_expand): Do not treat return-from, sys:abscond-from and block* in the same case as block. block* evaluates all of its forms and so can just be walked as a function call in the fallback case. The other two must be in their own case because we must not use expand_progn on them; they do not evaluate a progn-like list of forms. This leads to inappropriate optimizations like (return-from x (progn a b c)) -> (return-from x a b c). --- eval.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/eval.c b/eval.c index 815689f0..60766b4b 100644 --- a/eval.c +++ b/eval.c @@ -4050,15 +4050,20 @@ static val do_expand(val form, val menv) } else { return rlcp(cons(sym, cons(funcs_ex, body_ex)), form); } - } else if (sym == block_s || sym == return_from_s || - sym == sys_abscond_from_s || sym == block_star_s) - { + } else if (sym == block_s) { val name = second(form); val body = rest(rest(form)); val body_ex = expand_progn(body, menv); if (body == body_ex) return form; return rlcp(cons(sym, cons(name, body_ex)), form); + } else if (sym == return_from_s || sym == sys_abscond_from_s) { + val name = second(form); + val ret = third(form); + val ret_ex = expand(ret, menv); + if (ret == ret_ex) + return form; + return rlcp(list(sym, name, ret_ex, nao), form); } else if (sym == cond_s) { val pairs = rest(form); val pairs_ex = expand_cond_pairs(pairs, menv); -- cgit v1.2.3