emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 40d2970 1/2: Don't propagate lexical variables into inlined funct


From: Mattias Engdegård
Subject: master 40d2970 1/2: Don't propagate lexical variables into inlined functions
Date: Thu, 27 May 2021 08:20:14 -0400 (EDT)

branch: master
commit 40d2970f4360bd942ffc3f86db9ff1499a5a5393
Author: Mattias Engdegård <mattiase@acm.org>
Commit: Mattias Engdegård <mattiase@acm.org>

    Don't propagate lexical variables into inlined functions
    
    Functions compiled when inlined (thus from inside the optimiser)
    mustn't retain the lexical environment of the caller or there will be
    tears.  See discussion at
    https://lists.gnu.org/archive/html/emacs-devel/2021-05/msg01227.html .
    
    Bug found by Stefan Monnier.
    
    * lisp/emacs-lisp/byte-opt.el (byte-compile-inline-expand):
    Bind byte-optimize--lexvars to nil when re-entering the compiler
    recursively.
    * test/lisp/emacs-lisp/bytecomp-resources/bc-test-alpha.el:
    * test/lisp/emacs-lisp/bytecomp-resources/bc-test-beta.el: New files.
    * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-defsubst): New test.
---
 lisp/emacs-lisp/byte-opt.el                            |  5 ++++-
 .../emacs-lisp/bytecomp-resources/bc-test-alpha.el     |  9 +++++++++
 .../lisp/emacs-lisp/bytecomp-resources/bc-test-beta.el |  6 ++++++
 test/lisp/emacs-lisp/bytecomp-tests.el                 | 18 ++++++++++++++++++
 4 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index 99b5319..842697c 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -278,7 +278,10 @@
          ;; first, and then inline its byte-code.  This also has the advantage
          ;; that the final code does not depend on the order of compilation
          ;; of ELisp files, making the build more reproducible.
-         (byte-compile name)
+         ;; Since we are called from inside the optimiser, we need to make
+         ;; sure not to propagate lexvar values.
+         (dlet ((byte-optimize--lexvars nil))
+           (byte-compile name))
          `(,(symbol-function name) ,@(cdr form))))
 
       (_ ;; Give up on inlining.
diff --git a/test/lisp/emacs-lisp/bytecomp-resources/bc-test-alpha.el 
b/test/lisp/emacs-lisp/bytecomp-resources/bc-test-alpha.el
new file mode 100644
index 0000000..6997d91
--- /dev/null
+++ b/test/lisp/emacs-lisp/bytecomp-resources/bc-test-alpha.el
@@ -0,0 +1,9 @@
+;;; -*- lexical-binding: t -*-
+
+(require 'bc-test-beta)
+
+(defun bc-test-alpha-f (x)
+  (let ((y nil))
+    (list y (bc-test-beta-f x))))
+
+(provide 'bc-test-alpha)
diff --git a/test/lisp/emacs-lisp/bytecomp-resources/bc-test-beta.el 
b/test/lisp/emacs-lisp/bytecomp-resources/bc-test-beta.el
new file mode 100644
index 0000000..9205a13
--- /dev/null
+++ b/test/lisp/emacs-lisp/bytecomp-resources/bc-test-beta.el
@@ -0,0 +1,6 @@
+;;; -*- lexical-binding: t -*-
+
+(defsubst bc-test-beta-f (y)
+  y)
+
+(provide 'bc-test-beta)
diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el 
b/test/lisp/emacs-lisp/bytecomp-tests.el
index c9ab3ec..33413f5 100644
--- a/test/lisp/emacs-lisp/bytecomp-tests.el
+++ b/test/lisp/emacs-lisp/bytecomp-tests.el
@@ -1312,6 +1312,24 @@ compiled correctly."
                    (funcall f 3))
                  4)))
 
+(declare-function bc-test-alpha-f (ert-resource-file "bc-test-alpha.el"))
+
+(ert-deftest bytecomp-defsubst ()
+  ;; Check that lexical variables don't leak into inlined code.  See
+  ;; https://lists.gnu.org/archive/html/emacs-devel/2021-05/msg01227.html
+
+  ;; First, remove any trace of the functions and package defined:
+  (fmakunbound 'bc-test-alpha-f)
+  (fmakunbound 'bc-test-beta-f)
+  (setq features (delq 'bc-test-beta features))
+  ;; Byte-compile one file that uses a function from another file that isn't
+  ;; compiled.
+  (let ((file (ert-resource-file "bc-test-alpha.el"))
+        (load-path (cons (ert-resource-directory) load-path)))
+    (byte-compile-file file)
+    (load-file (concat file "c"))
+    (should (equal (bc-test-alpha-f 'a) '(nil a)))))
+
 ;; Local Variables:
 ;; no-byte-compile: t
 ;; End:



reply via email to

[Prev in Thread] Current Thread [Next in Thread]