summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/bytecomp.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/emacs-lisp/bytecomp.el')
-rw-r--r--lisp/emacs-lisp/bytecomp.el93
1 files changed, 69 insertions, 24 deletions
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index db200f3c504..b5b618e87d7 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -265,8 +265,8 @@ This option is enabled by default because it reduces Emacs memory usage."
(defcustom byte-optimize-log nil
"If non-nil, the byte-compiler will log its optimizations.
-If this is 'source, then only source-level optimizations will be logged.
-If it is 'byte, then only byte-level optimizations will be logged.
+If this is `source', then only source-level optimizations will be logged.
+If it is `byte', then only byte-level optimizations will be logged.
The information is logged to `byte-compile-log-buffer'."
:group 'bytecomp
:type '(choice (const :tag "none" nil)
@@ -456,10 +456,20 @@ Return the compile-time value of FORM."
(byte-compile-recurse-toplevel
(macroexp-progn body)
(lambda (form)
- (setf result
- (byte-compile-eval
- (byte-compile-top-level
- (byte-compile-preprocess form))))))
+ ;; Insulate the following variables
+ ;; against changes made in the
+ ;; subsidiary compilation. This
+ ;; prevents spurious warning
+ ;; messages: "not defined at runtime"
+ ;; etc.
+ (let ((byte-compile-unresolved-functions
+ byte-compile-unresolved-functions)
+ (byte-compile-new-defuns
+ byte-compile-new-defuns))
+ (setf result
+ (byte-compile-eval
+ (byte-compile-top-level
+ (byte-compile-preprocess form)))))))
(list 'quote result))))
(eval-and-compile . ,(lambda (&rest body)
(byte-compile-recurse-toplevel
@@ -503,6 +513,11 @@ defined with incorrect args.")
Used for warnings about calling a function that is defined during compilation
but won't necessarily be defined when the compiled file is loaded.")
+(defvar byte-compile-new-defuns nil
+ "List of (runtime) functions defined in this compilation run.
+This variable is used to qualify `byte-compile-noruntime-functions' when
+outputting warnings about functions not being defined at runtime.")
+
;; Variables for lexical binding
(defvar byte-compile--lexical-environment nil
"The current lexical environment.")
@@ -1503,8 +1518,9 @@ extra args."
;; Separate the functions that will not be available at runtime
;; from the truly unresolved ones.
(dolist (f byte-compile-unresolved-functions)
- (setq f (car f))
- (if (fboundp f) (push f noruntime) (push f unresolved)))
+ (setq f (car f))
+ (when (not (memq f byte-compile-new-defuns))
+ (if (fboundp f) (push f noruntime) (push f unresolved))))
;; Complain about the no-run-time functions
(byte-compile-print-syms
"the function `%s' might not be defined at runtime."
@@ -1691,7 +1707,7 @@ Any other non-nil value of ARG means to ask the user.
If optional argument LOAD is non-nil, loads the file after compiling.
If compilation is needed, this functions returns the result of
-`byte-compile-file'; otherwise it returns 'no-byte-compile."
+`byte-compile-file'; otherwise it returns `no-byte-compile'."
(interactive
(let ((file buffer-file-name)
(file-name nil)
@@ -1961,6 +1977,8 @@ With argument ARG, insert value in current buffer after the form."
;; compiled. A: Yes! b-c-u-f might contain dross from a
;; previous byte-compile.
(setq byte-compile-unresolved-functions nil)
+ (setq byte-compile-noruntime-functions nil)
+ (setq byte-compile-new-defuns nil)
;; Compile the forms from the input buffer.
(while (progn
@@ -2287,8 +2305,7 @@ list that represents a doc string reference.
;; byte-compile-warn-about-unresolved-functions.
(if (memq funsym byte-compile-noruntime-functions)
(setq byte-compile-noruntime-functions
- (delq funsym byte-compile-noruntime-functions)
- byte-compile-noruntime-functions)
+ (delq funsym byte-compile-noruntime-functions))
(setq byte-compile-unresolved-functions
(delq (assq funsym byte-compile-unresolved-functions)
byte-compile-unresolved-functions)))))
@@ -2346,8 +2363,21 @@ list that represents a doc string reference.
(defun byte-compile-file-form-require (form)
(let ((args (mapcar 'eval (cdr form)))
(hist-orig load-history)
- hist-new)
+ hist-new prov-cons)
(apply 'require args)
+
+ ;; Record the functions defined by the require in `byte-compile-new-defuns'.
+ (setq hist-new load-history)
+ (setq prov-cons (cons 'provide (car args)))
+ (while (and hist-new
+ (not (member prov-cons (car hist-new))))
+ (setq hist-new (cdr hist-new)))
+ (when hist-new
+ (dolist (x (car hist-new))
+ (when (and (consp x)
+ (memq (car x) '(defun t)))
+ (push (cdr x) byte-compile-new-defuns))))
+
(when (byte-compile-warning-enabled-p 'cl-functions)
;; Detect (require 'cl) in a way that works even if cl is already loaded.
(if (member (car args) '("cl" cl))
@@ -2403,6 +2433,7 @@ not to take responsibility for the actual compilation of the code."
(byte-compile-current-form name)) ; For warnings.
(byte-compile-set-symbol-position name)
+ (push name byte-compile-new-defuns)
;; When a function or macro is defined, add it to the call tree so that
;; we can tell when functions are not used.
(if byte-compile-generate-call-tree
@@ -3710,16 +3741,25 @@ discarding."
(byte-defop-compiler-1 quote)
(defun byte-compile-setq (form)
- (let ((args (cdr form)))
- (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))
+ (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))
+ byte-compile--for-effect))
+ (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)
@@ -3973,8 +4013,13 @@ that suppresses all warnings during execution of BODY."
(setq byte-compile--for-effect nil)))
(defun byte-compile-funcall (form)
- (mapc 'byte-compile-form (cdr form))
- (byte-compile-out 'byte-call (length (cdr (cdr form)))))
+ (if (cdr form)
+ (progn
+ (mapc 'byte-compile-form (cdr form))
+ (byte-compile-out 'byte-call (length (cdr (cdr form)))))
+ (byte-compile-log-warning "`funcall' called with no arguments" nil :error)
+ (byte-compile-form '(signal 'wrong-number-of-arguments '(funcall 0))
+ byte-compile--for-effect)))
;; let binding