emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] emacs-25 5d93a89: Byte compiler: on setq with an odd numbe


From: Alan Mackenzie
Subject: [Emacs-diffs] emacs-25 5d93a89: Byte compiler: on setq with an odd number of arguments, generate a `signal'
Date: Thu, 26 Nov 2015 10:37:16 +0000

branch: emacs-25
commit 5d93a89e805baa2f29941fd801e48235f6c1a6b6
Author: Alan Mackenzie <address@hidden>
Commit: Alan Mackenzie <address@hidden>

    Byte compiler: on setq with an odd number of arguments, generate a `signal'
    
    * lisp/emacs-lisp/cconv.el (cconv-convert): Don't transform `setq' form when
    it has an odd number of arguments, to allow bytecomp to handle the error.
    
    * lisp/emacs-lisp/bytecomp.el (byte-compile-setq): In a `setq' form with an
    odd number of arguments, generate a `signal' instead of the normal code.
---
 lisp/emacs-lisp/bytecomp.el |   32 ++++++++++++++++++--------------
 lisp/emacs-lisp/cconv.el    |   43 ++++++++++++++++++++++---------------------
 2 files changed, 40 insertions(+), 35 deletions(-)

diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 58cce67..ffe73de 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -3741,20 +3741,24 @@ discarding."
 (byte-defop-compiler-1 quote)
 
 (defun byte-compile-setq (form)
-  (let ((args (cdr form)))
-    (if args
-       (while args
-         (if (eq (length args) 1)
-              (byte-compile-log-warning
-               (format "missing value for `%S' at end of setq" (car args))
-               nil :error))
-          (byte-compile-form (car (cdr args)))
-         (or byte-compile--for-effect (cdr (cdr args))
-             (byte-compile-out 'byte-dup 0))
-         (byte-compile-variable-set (car args))
-         (setq args (cdr (cdr args))))
-      ;; (setq), with no arguments.
-      (byte-compile-form nil byte-compile--for-effect))
+  (let* ((args (cdr form))
+         (len (length args)))
+    (if (= (logand len 1) 1)
+        (progn
+          (byte-compile-log-warning
+           (format "missing value for `%S' at end of setq" (car (last args)))
+           nil :error)
+          (byte-compile-form
+           `(signal 'wrong-number-of-arguments '(setq ,len))))
+      (if args
+          (while args
+            (byte-compile-form (car (cdr args)))
+            (or byte-compile--for-effect (cdr (cdr args))
+                (byte-compile-out 'byte-dup 0))
+            (byte-compile-variable-set (car args))
+            (setq args (cdr (cdr args))))
+        ;; (setq), with no arguments.
+        (byte-compile-form nil byte-compile--for-effect)))
     (setq byte-compile--for-effect nil)))
 
 (defun byte-compile-setq-default (form)
diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el
index 4a3c273..355913a 100644
--- a/lisp/emacs-lisp/cconv.el
+++ b/lisp/emacs-lisp/cconv.el
@@ -473,27 +473,28 @@ places where they originally did not directly appear."
         :fun-body ,(cconv--convert-function () body env form)))
 
     (`(setq . ,forms)                   ; setq special form
-     (let ((prognlist ()))
-       (while forms
-         (let* ((sym (pop forms))
-                (sym-new (or (cdr (assq sym env)) sym))
-                (value-in-list
-                 (and forms
-                      (list (cconv-convert (pop forms) env extend)))))
-           (push (pcase sym-new
-                   ((pred symbolp) `(setq ,sym-new ,@value-in-list))
-                   (`(car-safe ,iexp) `(setcar ,iexp ,@value-in-list))
-                   ;; This "should never happen", but for variables which are
-                   ;; mutated+captured+unused, we may end up trying to `setq'
-                   ;; on a closed-over variable, so just drop the setq.
-                   (_ ;; (byte-compile-report-error
-                    ;;  (format "Internal error in cconv of (setq %s ..)"
-                    ;;          sym-new))
-                    (car value-in-list)))
-                 prognlist)))
-       (if (cdr prognlist)
-           `(progn . ,(nreverse prognlist))
-         (car prognlist))))
+     (if (= (logand (length forms) 1) 1)
+         ;; With an odd number of args, let bytecomp.el handle the error.
+         form
+       (let ((prognlist ()))
+         (while forms
+           (let* ((sym (pop forms))
+                  (sym-new (or (cdr (assq sym env)) sym))
+                  (value (cconv-convert (pop forms) env extend)))
+             (push (pcase sym-new
+                     ((pred symbolp) `(setq ,sym-new ,value))
+                     (`(car-safe ,iexp) `(setcar ,iexp ,value))
+                     ;; This "should never happen", but for variables which are
+                     ;; mutated+captured+unused, we may end up trying to `setq'
+                     ;; on a closed-over variable, so just drop the setq.
+                     (_ ;; (byte-compile-report-error
+                      ;;  (format "Internal error in cconv of (setq %s ..)"
+                      ;;          sym-new))
+                      value))
+                   prognlist)))
+         (if (cdr prognlist)
+             `(progn . ,(nreverse prognlist))
+           (car prognlist)))))
 
     (`(,(and (or `funcall `apply) callsym) ,fun . ,args)
      ;; These are not special forms but we treat them separately for the needs



reply via email to

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