aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ingebrigtsen2019-06-12 15:59:19 +0200
committerLars Ingebrigtsen2019-06-12 15:59:19 +0200
commitf2071b6de417ea079ab55298e8ca8f7bb2ad8d14 (patch)
treebbdc2892ff80632a5ffbfda98eb2ff7f20f8131e
parentb8350e52ef6201103b12db5ad8b9268452feb8b6 (diff)
downloademacs-f2071b6de417ea079ab55298e8ca8f7bb2ad8d14.tar.gz
emacs-f2071b6de417ea079ab55298e8ca8f7bb2ad8d14.zip
Add the new macro with-suppressed-warnings
* lisp/emacs-lisp/byte-run.el (with-suppressed-warnings): New macro. * doc/lispref/compile.texi (Compiler Errors): Document with-suppressed-warnings and deemphasise with-no-warnings slightly. * lisp/emacs-lisp/bytecomp.el (byte-compile--suppressed-warnings): New internal variable. (byte-compile-warning-enabled-p): Heed byte-compile--suppressed-warnings, bound via with-suppressed-warnings. (byte-compile-initial-macro-environment): Provide a macro expansion of with-suppressed-warnings. (byte-compile-file-form-with-suppressed-warnings): New byte hunk handler for the suppressed symbol machinery. (byte-compile-suppressed-warnings): Ditto for the byteop. (byte-compile-file-form-defmumble): Ditto. (byte-compile-form, byte-compile-normal-call) (byte-compile-normal-call, byte-compile-variable-ref) (byte-compile-set-default, byte-compile-variable-set) (byte-compile-function-form, byte-compile-set-default) (byte-compile-warn-obsolete, byte-compile--declare-var): Pass the symbol being warned in to byte-compile-warning-enabled-p. * test/lisp/emacs-lisp/bytecomp-tests.el (test-suppression): New function. (bytecomp-test--with-suppressed-warnings): Tests.
-rw-r--r--doc/lispref/compile.texi26
-rw-r--r--etc/NEWS4
-rw-r--r--lisp/emacs-lisp/byte-run.el28
-rw-r--r--lisp/emacs-lisp/bytecomp.el82
-rw-r--r--test/lisp/emacs-lisp/bytecomp-tests.el90
5 files changed, 203 insertions, 27 deletions
diff --git a/doc/lispref/compile.texi b/doc/lispref/compile.texi
index d9db55e22cd..4ff0e1c91e4 100644
--- a/doc/lispref/compile.texi
+++ b/doc/lispref/compile.texi
@@ -505,8 +505,25 @@ current lexical scope, or file if at top-level.) @xref{Defining
505Variables}. 505Variables}.
506@end itemize 506@end itemize
507 507
508 You can also suppress any and all compiler warnings within a certain 508 You can also suppress compiler warnings within a certain expression
509expression using the construct @code{with-no-warnings}: 509using the @code{with-suppressed-warnings} macro:
510
511@defspec with-suppressed-warnings warnings body@dots{}
512In execution, this is equivalent to @code{(progn @var{body}...)}, but
513the compiler does not issue warnings for the specified conditions in
514@var{body}. @var{warnings} is an associative list of warning symbols
515and function/variable symbols they apply to. For instance, if you
516wish to call an obsolete function called @code{foo}, but want to
517suppress the compilation warning, say:
518
519@lisp
520(with-suppressed-warnings ((obsolete foo))
521 (foo ...))
522@end lisp
523@end defspec
524
525For more coarse-grained suppression of compiler warnings, you can use
526the @code{with-no-warnings} construct:
510 527
511@c This is implemented with a defun, but conceptually it is 528@c This is implemented with a defun, but conceptually it is
512@c a special form. 529@c a special form.
@@ -516,8 +533,9 @@ In execution, this is equivalent to @code{(progn @var{body}...)},
516but the compiler does not issue warnings for anything that occurs 533but the compiler does not issue warnings for anything that occurs
517inside @var{body}. 534inside @var{body}.
518 535
519We recommend that you use this construct around the smallest 536We recommend that you use @code{with-suppressed-warnings} instead, but
520possible piece of code, to avoid missing possible warnings other than 537if you do use this construct, that you use it around the smallest
538possible piece of code to avoid missing possible warnings other than
521one you intend to suppress. 539one you intend to suppress.
522@end defspec 540@end defspec
523 541
diff --git a/etc/NEWS b/etc/NEWS
index 6efa7642f85..5632ccc6d75 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1693,6 +1693,10 @@ valid event type.
1693* Lisp Changes in Emacs 27.1 1693* Lisp Changes in Emacs 27.1
1694 1694
1695+++ 1695+++
1696** The new macro `with-suppressed-warnings' can be used to suppress
1697specific byte-compile warnings.
1698
1699+++
1696** The 'append' arg of 'add-hook' is generalized to a finer notion of 'depth' 1700** The 'append' arg of 'add-hook' is generalized to a finer notion of 'depth'
1697This makes it possible to control the ordering of functions more precisely, 1701This makes it possible to control the ordering of functions more precisely,
1698as was already possible in 'add-function' and `advice-add`. 1702as was already possible in 'add-function' and `advice-add`.
diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el
index 842d1d48b45..6a21a0c909d 100644
--- a/lisp/emacs-lisp/byte-run.el
+++ b/lisp/emacs-lisp/byte-run.el
@@ -494,6 +494,34 @@ is enabled."
494 ;; The implementation for the interpreter is basically trivial. 494 ;; The implementation for the interpreter is basically trivial.
495 (car (last body))) 495 (car (last body)))
496 496
497(defmacro with-suppressed-warnings (_warnings &rest body)
498 "Like `progn', but prevents compiler WARNINGS in BODY.
499
500WARNINGS is an associative list where the first element of each
501item is a warning type, and the rest of the elements in each item
502are symbols they apply to. For instance, if you want to suppress
503byte compilation warnings about the two obsolete functions `foo'
504and `bar', as well as the function `zot' being called with the
505wrong number of parameters, say
506
507\(with-suppressed-warnings ((obsolete foo bar)
508 (callargs zot))
509 (foo (bar))
510 (zot 1 2))
511
512The warnings that can be suppressed are a subset of the warnings
513in `byte-compile-warning-types'; see this variable for a fuller
514explanation of the warning types. The types that can be
515suppressed with this macro are `free-vars', `callargs',
516`redefine', `obsolete', `interactive-only', `lexical', `mapcar',
517`constants' and `suspicious'.
518
519For the `mapcar' case, only the `mapcar' function can be used in
520the symbol list. For `suspicious', only `set-buffer' can be used."
521 (declare (debug (sexp &optional body)) (indent 1))
522 ;; The implementation for the interpreter is basically trivial.
523 `(progn ,@body))
524
497 525
498(defun byte-run--unescaped-character-literals-warning () 526(defun byte-run--unescaped-character-literals-warning ()
499 "Return a warning about unescaped character literals. 527 "Return a warning about unescaped character literals.
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index f2a38a9c6c3..13d563bde91 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -331,18 +331,27 @@ suppress. For example, (not mapcar) will suppress warnings about mapcar."
331 ,@(mapcar (lambda (x) `(const ,x)) 331 ,@(mapcar (lambda (x) `(const ,x))
332 byte-compile-warning-types)))) 332 byte-compile-warning-types))))
333 333
334(defvar byte-compile--suppressed-warnings nil
335 "Dynamically bound by `with-suppressed-warnings' to suppress warnings.")
336
334;;;###autoload 337;;;###autoload
335(put 'byte-compile-warnings 'safe-local-variable 338(put 'byte-compile-warnings 'safe-local-variable
336 (lambda (v) 339 (lambda (v)
337 (or (symbolp v) 340 (or (symbolp v)
338 (null (delq nil (mapcar (lambda (x) (not (symbolp x))) v)))))) 341 (null (delq nil (mapcar (lambda (x) (not (symbolp x))) v))))))
339 342
340(defun byte-compile-warning-enabled-p (warning) 343(defun byte-compile-warning-enabled-p (warning &optional symbol)
341 "Return non-nil if WARNING is enabled, according to `byte-compile-warnings'." 344 "Return non-nil if WARNING is enabled, according to `byte-compile-warnings'."
342 (or (eq byte-compile-warnings t) 345 (let ((suppress nil))
343 (if (eq (car byte-compile-warnings) 'not) 346 (dolist (elem byte-compile--suppressed-warnings)
344 (not (memq warning byte-compile-warnings)) 347 (when (and (eq (car elem) warning)
345 (memq warning byte-compile-warnings)))) 348 (memq symbol (cdr elem)))
349 (setq suppress t)))
350 (and (not suppress)
351 (or (eq byte-compile-warnings t)
352 (if (eq (car byte-compile-warnings) 'not)
353 (not (memq warning byte-compile-warnings))
354 (memq warning byte-compile-warnings))))))
346 355
347;;;###autoload 356;;;###autoload
348(defun byte-compile-disable-warning (warning) 357(defun byte-compile-disable-warning (warning)
@@ -502,7 +511,16 @@ Return the compile-time value of FORM."
502 form 511 form
503 macroexpand-all-environment))) 512 macroexpand-all-environment)))
504 (eval expanded lexical-binding) 513 (eval expanded lexical-binding)
505 expanded)))))) 514 expanded)))))
515 (with-suppressed-warnings
516 . ,(lambda (warnings &rest body)
517 ;; This function doesn't exist, but is just a placeholder
518 ;; symbol to hook up with the
519 ;; `byte-hunk-handler'/`byte-defop-compiler-1' machinery.
520 `(internal--with-suppressed-warnings
521 ',warnings
522 ,(macroexpand-all `(progn ,@body)
523 macroexpand-all-environment)))))
506 "The default macro-environment passed to macroexpand by the compiler. 524 "The default macro-environment passed to macroexpand by the compiler.
507Placing a macro here will cause a macro to have different semantics when 525Placing a macro here will cause a macro to have different semantics when
508expanded by the compiler as when expanded by the interpreter.") 526expanded by the compiler as when expanded by the interpreter.")
@@ -1268,7 +1286,7 @@ function directly; use `byte-compile-warn' or
1268 1286
1269(defun byte-compile-warn-obsolete (symbol) 1287(defun byte-compile-warn-obsolete (symbol)
1270 "Warn that SYMBOL (a variable or function) is obsolete." 1288 "Warn that SYMBOL (a variable or function) is obsolete."
1271 (when (byte-compile-warning-enabled-p 'obsolete) 1289 (when (byte-compile-warning-enabled-p 'obsolete symbol)
1272 (let* ((funcp (get symbol 'byte-obsolete-info)) 1290 (let* ((funcp (get symbol 'byte-obsolete-info))
1273 (msg (macroexp--obsolete-warning 1291 (msg (macroexp--obsolete-warning
1274 symbol 1292 symbol
@@ -2423,7 +2441,7 @@ list that represents a doc string reference.
2423(defun byte-compile--declare-var (sym) 2441(defun byte-compile--declare-var (sym)
2424 (when (and (symbolp sym) 2442 (when (and (symbolp sym)
2425 (not (string-match "[-*/:$]" (symbol-name sym))) 2443 (not (string-match "[-*/:$]" (symbol-name sym)))
2426 (byte-compile-warning-enabled-p 'lexical)) 2444 (byte-compile-warning-enabled-p 'lexical sym))
2427 (byte-compile-warn "global/dynamic var `%s' lacks a prefix" 2445 (byte-compile-warn "global/dynamic var `%s' lacks a prefix"
2428 sym)) 2446 sym))
2429 (when (memq sym byte-compile-lexical-variables) 2447 (when (memq sym byte-compile-lexical-variables)
@@ -2521,6 +2539,15 @@ list that represents a doc string reference.
2521 (mapc 'byte-compile-file-form (cdr form)) 2539 (mapc 'byte-compile-file-form (cdr form))
2522 nil)) 2540 nil))
2523 2541
2542(put 'internal--with-suppressed-warnings 'byte-hunk-handler
2543 'byte-compile-file-form-with-suppressed-warnings)
2544(defun byte-compile-file-form-with-suppressed-warnings (form)
2545 ;; cf byte-compile-file-form-progn.
2546 (let ((byte-compile--suppressed-warnings
2547 (append (cadadr form) byte-compile--suppressed-warnings)))
2548 (mapc 'byte-compile-file-form (cddr form))
2549 nil))
2550
2524;; Automatically evaluate define-obsolete-function-alias etc at top-level. 2551;; Automatically evaluate define-obsolete-function-alias etc at top-level.
2525(put 'make-obsolete 'byte-hunk-handler 'byte-compile-file-form-make-obsolete) 2552(put 'make-obsolete 'byte-hunk-handler 'byte-compile-file-form-make-obsolete)
2526(defun byte-compile-file-form-make-obsolete (form) 2553(defun byte-compile-file-form-make-obsolete (form)
@@ -2559,7 +2586,7 @@ not to take responsibility for the actual compilation of the code."
2559 (setq byte-compile-call-tree 2586 (setq byte-compile-call-tree
2560 (cons (list name nil nil) byte-compile-call-tree)))) 2587 (cons (list name nil nil) byte-compile-call-tree))))
2561 2588
2562 (if (byte-compile-warning-enabled-p 'redefine) 2589 (if (byte-compile-warning-enabled-p 'redefine name)
2563 (byte-compile-arglist-warn name arglist macro)) 2590 (byte-compile-arglist-warn name arglist macro))
2564 2591
2565 (if byte-compile-verbose 2592 (if byte-compile-verbose
@@ -2571,7 +2598,7 @@ not to take responsibility for the actual compilation of the code."
2571 ;; This also silences "multiple definition" warnings for defmethods. 2598 ;; This also silences "multiple definition" warnings for defmethods.
2572 nil) 2599 nil)
2573 (that-one 2600 (that-one
2574 (if (and (byte-compile-warning-enabled-p 'redefine) 2601 (if (and (byte-compile-warning-enabled-p 'redefine name)
2575 ;; Don't warn when compiling the stubs in byte-run... 2602 ;; Don't warn when compiling the stubs in byte-run...
2576 (not (assq name byte-compile-initial-macro-environment))) 2603 (not (assq name byte-compile-initial-macro-environment)))
2577 (byte-compile-warn 2604 (byte-compile-warn
@@ -2579,7 +2606,7 @@ not to take responsibility for the actual compilation of the code."
2579 name)) 2606 name))
2580 (setcdr that-one nil)) 2607 (setcdr that-one nil))
2581 (this-one 2608 (this-one
2582 (when (and (byte-compile-warning-enabled-p 'redefine) 2609 (when (and (byte-compile-warning-enabled-p 'redefine name)
2583 ;; Hack: Don't warn when compiling the magic internal 2610 ;; Hack: Don't warn when compiling the magic internal
2584 ;; byte-compiler macros in byte-run.el... 2611 ;; byte-compiler macros in byte-run.el...
2585 (not (assq name byte-compile-initial-macro-environment))) 2612 (not (assq name byte-compile-initial-macro-environment)))
@@ -2588,7 +2615,7 @@ not to take responsibility for the actual compilation of the code."
2588 name))) 2615 name)))
2589 ((eq (car-safe (symbol-function name)) 2616 ((eq (car-safe (symbol-function name))
2590 (if macro 'lambda 'macro)) 2617 (if macro 'lambda 'macro))
2591 (when (byte-compile-warning-enabled-p 'redefine) 2618 (when (byte-compile-warning-enabled-p 'redefine name)
2592 (byte-compile-warn "%s `%s' being redefined as a %s" 2619 (byte-compile-warn "%s `%s' being redefined as a %s"
2593 (if macro "function" "macro") 2620 (if macro "function" "macro")
2594 name 2621 name
@@ -3153,7 +3180,7 @@ for symbols generated by the byte compiler itself."
3153 (when (and (byte-compile-warning-enabled-p 'suspicious) 3180 (when (and (byte-compile-warning-enabled-p 'suspicious)
3154 (macroexp--const-symbol-p fn)) 3181 (macroexp--const-symbol-p fn))
3155 (byte-compile-warn "`%s' called as a function" fn)) 3182 (byte-compile-warn "`%s' called as a function" fn))
3156 (when (and (byte-compile-warning-enabled-p 'interactive-only) 3183 (when (and (byte-compile-warning-enabled-p 'interactive-only fn)
3157 interactive-only) 3184 interactive-only)
3158 (byte-compile-warn "`%s' is for interactive use only%s" 3185 (byte-compile-warn "`%s' is for interactive use only%s"
3159 fn 3186 fn
@@ -3194,8 +3221,8 @@ for symbols generated by the byte compiler itself."
3194 (byte-compile-discard)))) 3221 (byte-compile-discard))))
3195 3222
3196(defun byte-compile-normal-call (form) 3223(defun byte-compile-normal-call (form)
3197 (when (and (byte-compile-warning-enabled-p 'callargs) 3224 (when (and (symbolp (car form))
3198 (symbolp (car form))) 3225 (byte-compile-warning-enabled-p 'callargs (car form)))
3199 (if (memq (car form) 3226 (if (memq (car form)
3200 '(custom-declare-group custom-declare-variable 3227 '(custom-declare-group custom-declare-variable
3201 custom-declare-face)) 3228 custom-declare-face))
@@ -3204,7 +3231,7 @@ for symbols generated by the byte compiler itself."
3204 (if byte-compile-generate-call-tree 3231 (if byte-compile-generate-call-tree
3205 (byte-compile-annotate-call-tree form)) 3232 (byte-compile-annotate-call-tree form))
3206 (when (and byte-compile--for-effect (eq (car form) 'mapcar) 3233 (when (and byte-compile--for-effect (eq (car form) 'mapcar)
3207 (byte-compile-warning-enabled-p 'mapcar)) 3234 (byte-compile-warning-enabled-p 'mapcar 'mapcar))
3208 (byte-compile-set-symbol-position 'mapcar) 3235 (byte-compile-set-symbol-position 'mapcar)
3209 (byte-compile-warn 3236 (byte-compile-warn
3210 "`mapcar' called for effect; use `mapc' or `dolist' instead")) 3237 "`mapcar' called for effect; use `mapc' or `dolist' instead"))
@@ -3340,7 +3367,8 @@ for symbols generated by the byte compiler itself."
3340 (when (symbolp var) 3367 (when (symbolp var)
3341 (byte-compile-set-symbol-position var)) 3368 (byte-compile-set-symbol-position var))
3342 (cond ((or (not (symbolp var)) (macroexp--const-symbol-p var)) 3369 (cond ((or (not (symbolp var)) (macroexp--const-symbol-p var))
3343 (when (byte-compile-warning-enabled-p 'constants) 3370 (when (byte-compile-warning-enabled-p 'constants
3371 (and (symbolp var) var))
3344 (byte-compile-warn (if (eq access-type 'let-bind) 3372 (byte-compile-warn (if (eq access-type 'let-bind)
3345 "attempt to let-bind %s `%s'" 3373 "attempt to let-bind %s `%s'"
3346 "variable reference to %s `%s'") 3374 "variable reference to %s `%s'")
@@ -3377,7 +3405,7 @@ for symbols generated by the byte compiler itself."
3377 ;; VAR is lexically bound 3405 ;; VAR is lexically bound
3378 (byte-compile-stack-ref (cdr lex-binding)) 3406 (byte-compile-stack-ref (cdr lex-binding))
3379 ;; VAR is dynamically bound 3407 ;; VAR is dynamically bound
3380 (unless (or (not (byte-compile-warning-enabled-p 'free-vars)) 3408 (unless (or (not (byte-compile-warning-enabled-p 'free-vars var))
3381 (boundp var) 3409 (boundp var)
3382 (memq var byte-compile-bound-variables) 3410 (memq var byte-compile-bound-variables)
3383 (memq var byte-compile-free-references)) 3411 (memq var byte-compile-free-references))
@@ -3393,7 +3421,7 @@ for symbols generated by the byte compiler itself."
3393 ;; VAR is lexically bound. 3421 ;; VAR is lexically bound.
3394 (byte-compile-stack-set (cdr lex-binding)) 3422 (byte-compile-stack-set (cdr lex-binding))
3395 ;; VAR is dynamically bound. 3423 ;; VAR is dynamically bound.
3396 (unless (or (not (byte-compile-warning-enabled-p 'free-vars)) 3424 (unless (or (not (byte-compile-warning-enabled-p 'free-vars var))
3397 (boundp var) 3425 (boundp var)
3398 (memq var byte-compile-bound-variables) 3426 (memq var byte-compile-bound-variables)
3399 (memq var byte-compile-free-assignments)) 3427 (memq var byte-compile-free-assignments))
@@ -3878,7 +3906,7 @@ discarding."
3878(defun byte-compile-function-form (form) 3906(defun byte-compile-function-form (form)
3879 (let ((f (nth 1 form))) 3907 (let ((f (nth 1 form)))
3880 (when (and (symbolp f) 3908 (when (and (symbolp f)
3881 (byte-compile-warning-enabled-p 'callargs)) 3909 (byte-compile-warning-enabled-p 'callargs f))
3882 (byte-compile-function-warn f t (byte-compile-fdefinition f nil))) 3910 (byte-compile-function-warn f t (byte-compile-fdefinition f nil)))
3883 3911
3884 (byte-compile-constant (if (eq 'lambda (car-safe f)) 3912 (byte-compile-constant (if (eq 'lambda (car-safe f))
@@ -3948,7 +3976,8 @@ discarding."
3948 (let ((var (car-safe (cdr varexp)))) 3976 (let ((var (car-safe (cdr varexp))))
3949 (and (or (not (symbolp var)) 3977 (and (or (not (symbolp var))
3950 (macroexp--const-symbol-p var t)) 3978 (macroexp--const-symbol-p var t))
3951 (byte-compile-warning-enabled-p 'constants) 3979 (byte-compile-warning-enabled-p 'constants
3980 (and (symbolp var) var))
3952 (byte-compile-warn 3981 (byte-compile-warn
3953 "variable assignment to %s `%s'" 3982 "variable assignment to %s `%s'"
3954 (if (symbolp var) "constant" "nonvariable") 3983 (if (symbolp var) "constant" "nonvariable")
@@ -4609,7 +4638,7 @@ binding slots have been popped."
4609 4638
4610(defun byte-compile-save-excursion (form) 4639(defun byte-compile-save-excursion (form)
4611 (if (and (eq 'set-buffer (car-safe (car-safe (cdr form)))) 4640 (if (and (eq 'set-buffer (car-safe (car-safe (cdr form))))
4612 (byte-compile-warning-enabled-p 'suspicious)) 4641 (byte-compile-warning-enabled-p 'suspicious 'set-buffer))
4613 (byte-compile-warn 4642 (byte-compile-warn
4614 "Use `with-current-buffer' rather than save-excursion+set-buffer")) 4643 "Use `with-current-buffer' rather than save-excursion+set-buffer"))
4615 (byte-compile-out 'byte-save-excursion 0) 4644 (byte-compile-out 'byte-save-excursion 0)
@@ -4650,7 +4679,7 @@ binding slots have been popped."
4650 ;; This is not used for file-level defvar/consts. 4679 ;; This is not used for file-level defvar/consts.
4651 (when (and (symbolp (nth 1 form)) 4680 (when (and (symbolp (nth 1 form))
4652 (not (string-match "[-*/:$]" (symbol-name (nth 1 form)))) 4681 (not (string-match "[-*/:$]" (symbol-name (nth 1 form))))
4653 (byte-compile-warning-enabled-p 'lexical)) 4682 (byte-compile-warning-enabled-p 'lexical (nth 1 form)))
4654 (byte-compile-warn "global/dynamic var `%s' lacks a prefix" 4683 (byte-compile-warn "global/dynamic var `%s' lacks a prefix"
4655 (nth 1 form))) 4684 (nth 1 form)))
4656 (let ((fun (nth 0 form)) 4685 (let ((fun (nth 0 form))
@@ -4767,6 +4796,13 @@ binding slots have been popped."
4767 (let (byte-compile-warnings) 4796 (let (byte-compile-warnings)
4768 (byte-compile-form (cons 'progn (cdr form))))) 4797 (byte-compile-form (cons 'progn (cdr form)))))
4769 4798
4799(byte-defop-compiler-1 internal--with-suppressed-warnings
4800 byte-compile-suppressed-warnings)
4801(defun byte-compile-suppressed-warnings (form)
4802 (let ((byte-compile--suppressed-warnings
4803 (append (cadadr form) byte-compile--suppressed-warnings)))
4804 (byte-compile-form (macroexp-progn (cddr form)))))
4805
4770;; Warn about misuses of make-variable-buffer-local. 4806;; Warn about misuses of make-variable-buffer-local.
4771(byte-defop-compiler-1 make-variable-buffer-local 4807(byte-defop-compiler-1 make-variable-buffer-local
4772 byte-compile-make-variable-buffer-local) 4808 byte-compile-make-variable-buffer-local)
diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el
index 83162d250fc..6fe7f5b571d 100644
--- a/test/lisp/emacs-lisp/bytecomp-tests.el
+++ b/test/lisp/emacs-lisp/bytecomp-tests.el
@@ -686,6 +686,96 @@ literals (Bug#20852)."
686 (should-not (member '(byte-constant 333) lap)) 686 (should-not (member '(byte-constant 333) lap))
687 (should (member '(byte-constant 444) lap))))) 687 (should (member '(byte-constant 444) lap)))))
688 688
689(defun test-suppression (form suppress match)
690 (let ((lexical-binding t)
691 (byte-compile-log-buffer (generate-new-buffer " *Compile-Log*")))
692 ;; Check that we get a warning without suppression.
693 (with-current-buffer byte-compile-log-buffer
694 (let ((inhibit-read-only t))
695 (erase-buffer)))
696 (test-byte-comp-compile-and-load t form)
697 (with-current-buffer byte-compile-log-buffer
698 (unless match
699 (error "%s" (buffer-string)))
700 (goto-char (point-min))
701 (should (re-search-forward match nil t)))
702 ;; And that it's gone now.
703 (with-current-buffer byte-compile-log-buffer
704 (let ((inhibit-read-only t))
705 (erase-buffer)))
706 (test-byte-comp-compile-and-load t
707 `(with-suppressed-warnings ,suppress
708 ,form))
709 (with-current-buffer byte-compile-log-buffer
710 (goto-char (point-min))
711 (should-not (re-search-forward match nil t)))
712 ;; Also check that byte compiled forms are identical.
713 (should (equal (byte-compile form)
714 (byte-compile
715 `(with-suppressed-warnings ,suppress ,form))))))
716
717(ert-deftest bytecomp-test--with-suppressed-warnings ()
718 (test-suppression
719 '(defvar prefixless)
720 '((lexical prefixless))
721 "global/dynamic var .prefixless. lacks")
722
723 (test-suppression
724 '(defun foo()
725 (let ((nil t))
726 (message-mail)))
727 '((constants nil))
728 "Warning: attempt to let-bind constant .nil.")
729
730 (test-suppression
731 '(progn
732 (defun obsolete ()
733 (declare (obsolete foo "22.1")))
734 (defun zot ()
735 (obsolete)))
736 '((obsolete obsolete))
737 "Warning: .obsolete. is an obsolete function")
738
739 (test-suppression
740 '(progn
741 (defun wrong-params (foo &optional unused)
742 (ignore unused)
743 foo)
744 (defun zot ()
745 (wrong-params 1 2 3)))
746 '((callargs wrong-params))
747 "Warning: wrong-params called with")
748
749 (test-byte-comp-compile-and-load nil
750 (defvar obsolete-variable nil)
751 (make-obsolete-variable 'obsolete-variable nil "24.1"))
752 (test-suppression
753 '(defun zot ()
754 obsolete-variable)
755 '((obsolete obsolete-variable))
756 "obsolete")
757
758 (test-suppression
759 '(defun zot ()
760 (mapcar #'list '(1 2 3))
761 nil)
762 '((mapcar mapcar))
763 "Warning: .mapcar. called for effect")
764
765 (test-suppression
766 '(defun zot ()
767 free-variable)
768 '((free-vars free-variable))
769 "Warning: reference to free variable")
770
771 (test-suppression
772 '(defun zot ()
773 (save-excursion
774 (set-buffer (get-buffer-create "foo"))
775 nil))
776 '((suspicious set-buffer))
777 "Warning: Use .with-current-buffer. rather than"))
778
689;; Local Variables: 779;; Local Variables:
690;; no-byte-compile: t 780;; no-byte-compile: t
691;; End: 781;; End: