diff options
author | Mattias EngdegÄrd <mattiase@acm.org> | 2021-09-25 12:15:21 +0200 |
---|---|---|
committer | Mattias EngdegÄrd <mattiase@acm.org> | 2021-09-25 20:25:02 +0200 |
commit | 45c32d7f00e225a78e6c8b2251de335e93e556e0 (patch) | |
tree | cf0058e94deabaf35a76c4d43693dc4c3b56f977 /lisp/emacs-lisp/byte-opt.el | |
parent | e93bdfb6dafd4cb8d660e1330a8527f61e831eab (diff) | |
download | emacs-45c32d7f00e225a78e6c8b2251de335e93e556e0.tar.gz emacs-45c32d7f00e225a78e6c8b2251de335e93e556e0.tar.bz2 emacs-45c32d7f00e225a78e6c8b2251de335e93e556e0.zip |
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.
Diffstat (limited to 'lisp/emacs-lisp/byte-opt.el')
-rw-r--r-- | lisp/emacs-lisp/byte-opt.el | 17 |
1 files changed, 12 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))) |