Subject: Re: bug#29520: peval leaves behind dangling lexical reference

From: Mark H Weaver <[email-masked]>
Date: Mon, 04 Dec 2017 21:55:21 -0500

Mark H Weaver <[email-masked]> writes:

> It occurs to me that there's another problem with this optimization:
>
>   scheme@(guile-user)> ,optimize (lambda (x y . z) (apply (lambda x x) x y z))
>   $1 = (lambda x x)
>
> This optimization changes the arity of the procedure.  The original
> version checks that at least 2 arguments are provided, and ensures that
> at least 2 arguments are passed to the inner procedure, which the code
> might depend on.  The optimization effectively removes this check.

Here's an updated patch that fixes both issues.

      Mark

diff --git a/module/language/tree-il/peval.scm b/module/language/tree-il/peval.scm
index 993fa0ad6..13b7d9bc4 100644
--- a/module/language/tree-il/peval.scm
+++ b/module/language/tree-il/peval.scm
@@ -1585,11 +1585,15 @@ top-level bindings from ENV and return the resulting expression."
          (and (not opt) rest (not kw)
               (match body
                 (($ <primcall> _ 'apply
-                    (($ <lambda> _ _ (and lcase ($ <lambda-case>)))
+                    (($ <lambda> _ _ (and lcase ($ <lambda-case> _ req1)))
                      ($ <lexical-ref> _ _ sym)
                      ...))
                  (and (equal? sym gensyms)
                       (not (lambda-case-alternate lcase))
+                      (<= (length req) (length req1))
+                      (every (lambda (s)
+                               (= (lexical-refcount s) 1))
+                             sym)
                       lcase))
                 (_ #f))))
        (let* ((vars (map lookup-var gensyms))