]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix byte-compiler crash for legal dynamic-binding code
authorMattias Engdegård <mattiase@acm.org>
Sat, 25 Sep 2021 10:15:21 +0000 (12:15 +0200)
committerMattias Engdegård <mattiase@acm.org>
Sat, 25 Sep 2021 18:25:02 +0000 (20:25 +0200)
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
test/lisp/emacs-lisp/bytecomp-tests.el

index c8a96fa22a94b27c2e7f859575fab7b5d7d93f99..c8990f23531788be4af355888d9b2436d3254a19 100644 (file)
@@ -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)))
 
index ded6351c5ee708733fcdb0b90cc81bd3d38cd0e5..d56c60b1f1d71451c3467b41fe3849d7a010dc98 100644 (file)
@@ -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))