From 45c32d7f00e225a78e6c8b2251de335e93e556e0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mattias=20Engdeg=C3=A5rd?= Date: Sat, 25 Sep 2021 12:15:21 +0200 Subject: [PATCH] Fix byte-compiler crash for legal dynamic-binding code This should really be taken care of by a syntax normalisation step in the frontend, but there is no such step for non-lexbind code yet. * lisp/emacs-lisp/byte-opt.el (byte-optimize-letX): Tolerate bindingsa without initialising expressions. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases): Add test cases. --- lisp/emacs-lisp/byte-opt.el | 17 ++++++++++++----- test/lisp/emacs-lisp/bytecomp-tests.el | 8 ++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index c8a96fa22a9..c8990f23531 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -1367,17 +1367,24 @@ See Info node `(elisp) Integer Basics'." (and (consp binding) (cadr binding))) bindings) ,const) - `(let* ,(butlast bindings) ,(cadar (last bindings)) ,const))) + `(let* ,(butlast bindings) + ,@(and (consp (car (last bindings))) + (cdar (last bindings))) + ,const))) ;; Body is last variable. - (`(,head ,bindings ,(and var (pred symbolp) (pred (not keywordp)) - (pred (not booleanp)) - (guard (eq var (caar (last bindings)))))) + (`(,head ,(and bindings + (let last-var (let ((last (car (last bindings)))) + (if (consp last) (car last) last)))) + ,(and last-var ; non-linear pattern + (pred symbolp) (pred (not keywordp)) (pred (not booleanp)))) (if (eq head 'let) `(progn ,@(mapcar (lambda (binding) (and (consp binding) (cadr binding))) bindings)) - `(let* ,(butlast bindings) ,(cadar (last bindings))))) + `(let* ,(butlast bindings) + ,@(and (consp (car (last bindings))) + (cdar (last bindings)))))) (_ form))) diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el index ded6351c5ee..d56c60b1f1d 100644 --- a/test/lisp/emacs-lisp/bytecomp-tests.el +++ b/test/lisp/emacs-lisp/bytecomp-tests.el @@ -573,6 +573,14 @@ inner loops respectively." (let ((_a 1) (_b 2)) 'z) + (let (x y) + y) + (let* (x y) + y) + (let (x y) + 'a) + (let* (x y) + 'a) ;; Check empty-list optimisations. (mapcar (lambda (x) (member x nil)) '("a" 2 nil)) -- 2.39.2