GNU bug report logs - #60974
30.0.50; byte-compile-preprocess mutates self evaluating forms in expanded macro bodies

Previous Next

Package: emacs;

Reported by: Vibhav Pant <vibhavp <at> gmail.com>

Date: Fri, 20 Jan 2023 21:25:01 UTC

Severity: normal

Found in version 30.0.50

Full log


Message #17 received at 60974 <at> debbugs.gnu.org (full text, mbox):

From: Vibhav Pant <vibhavp <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 60974 <at> debbugs.gnu.org, emacs-devel <emacs-devel <at> gnu.org>
Subject: Re: bug#60974: 30.0.50; byte-compile-preprocess mutates self
 evaluating forms in expanded macro bodies
Date: Fri, 27 Jan 2023 18:14:39 +0530
[Message part 1 (text/plain, inline)]
On Sat, 2023-01-21 at 00:43 -0500, Stefan Monnier wrote:
> > The attached patch should fix this, thoughts?
> 
> It's not really an option:
> - it's expensive
> - it breaks code when it doesn't form a tree, e.g.
> 
>       (list '#1=(a b #1#) 'c 'd)
> 
> Instead, we need to find out where in the code we perform the
> side effect and change just that part.
> 
> 
>         Stefan
> 

Ah, right. Theother way I could think of a fix is setq-ing `form` to a
shallow copy of the original form, with only the place(s) changed. This
patch tries to do that by using `pcase-let` to destructure forms.
 

-- 
Vibhav Pant
vibhavp <at> gmail.com
GPG: 7ED1 D48C 513C A024 BE3A  785F E3FB 28CB 6AB5 9598
[60974-2.patch (text/x-patch, inline)]
diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el
index e715bd90a00..f6160a13579 100644
--- a/lisp/emacs-lisp/cconv.el
+++ b/lisp/emacs-lisp/cconv.el
@@ -477,20 +477,37 @@ cconv-convert
                                         branch))
                               cond-forms)))
 
-    (`(function (lambda ,args . ,body) . ,_)
+    (`(function (lambda ,args . ,body) . ,rest)
      (let* ((docstring (if (eq :documentation (car-safe (car body)))
                            (cconv-convert (cadr (pop body)) env extend)))
             (bf (if (stringp (car body)) (cdr body) body))
             (if (when (eq 'interactive (car-safe (car bf)))
                   (gethash form cconv--interactive-form-funs)))
             (cif (when if (cconv-convert if env extend)))
-            (_ (pcase cif
-                 (`#'(lambda () ,form) (setf (cadr (car bf)) form) (setq cif nil))
-                 ('nil nil)
-                 ;; The interactive form needs special treatment, so the form
-                 ;; inside the `interactive' won't be used any further.
-                 (_ (setf (cadr (car bf)) nil))))
-            (cf (cconv--convert-function args body env form docstring)))
+            (cf nil))
+       (pcase cif
+         (`#'(lambda () ,form)
+          (pcase-let ((`((,f1 . (,_ . ,f2)) . ,f3) bf))
+            (setq bf `((,f1 . (,form . ,f2)) . ,f3)))
+          (setq cif nil))
+         ('nil (setq bf nil))
+         ;; The interactive form needs special treatment, so the form
+         ;; inside the `interactive' won't be used any further.
+         (_ (pcase-let ((`((,f1 . (,_ . ,f2)) . ,f3) bf))
+              (setq bf `((,f1 . (nil . ,f2)) . ,f3)))))
+       (when bf
+         ;; If we modified bf, re-build body and form as
+         ;; copies with the modified bits.
+         (setq body (if (stringp (car body))
+                        (cons (car body) bf)
+                      bf)
+               form `(function (lambda ,args . ,body) . ,rest))
+         ;; Also, remove the current old entry on the alist, replacing
+         ;; it with the new one.
+         (let ((entry (pop cconv-freevars-alist)))
+           (push (cons body (cdr entry)) cconv-freevars-alist)))
+       (setq cf (cconv--convert-function args body env form docstring))
+
        (if (not cif)
            ;; Normal case, the interactive form needs no special treatment.
            cf
[signature.asc (application/pgp-signature, inline)]

This bug report was last modified 2 years and 189 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.