summaryrefslogtreecommitdiff
path: root/test/lisp/emacs-lisp
diff options
context:
space:
mode:
authorMattias EngdegÄrd <mattiase@acm.org>2021-05-27 14:03:14 +0200
committerMattias EngdegÄrd <mattiase@acm.org>2021-05-27 14:16:17 +0200
commit40d2970f4360bd942ffc3f86db9ff1499a5a5393 (patch)
treead709ac8bb438e17b724b30b97161776386039d4 /test/lisp/emacs-lisp
parent501296f994ba8b578d8a546eddfd2cdc365305f3 (diff)
downloademacs-40d2970f4360bd942ffc3f86db9ff1499a5a5393.tar.gz
emacs-40d2970f4360bd942ffc3f86db9ff1499a5a5393.tar.bz2
emacs-40d2970f4360bd942ffc3f86db9ff1499a5a5393.zip
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.
Diffstat (limited to 'test/lisp/emacs-lisp')
-rw-r--r--test/lisp/emacs-lisp/bytecomp-resources/bc-test-alpha.el9
-rw-r--r--test/lisp/emacs-lisp/bytecomp-resources/bc-test-beta.el6
-rw-r--r--test/lisp/emacs-lisp/bytecomp-tests.el18
3 files changed, 33 insertions, 0 deletions
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 00000000000..6997d91b26a
--- /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 00000000000..9205a13d7d5
--- /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 c9ab3ec1f1b..33413f5a002 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: