diff options
| author | Lars Ingebrigtsen | 2019-06-12 15:59:19 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2019-06-12 15:59:19 +0200 |
| commit | f2071b6de417ea079ab55298e8ca8f7bb2ad8d14 (patch) | |
| tree | bbdc2892ff80632a5ffbfda98eb2ff7f20f8131e | |
| parent | b8350e52ef6201103b12db5ad8b9268452feb8b6 (diff) | |
| download | emacs-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.texi | 26 | ||||
| -rw-r--r-- | etc/NEWS | 4 | ||||
| -rw-r--r-- | lisp/emacs-lisp/byte-run.el | 28 | ||||
| -rw-r--r-- | lisp/emacs-lisp/bytecomp.el | 82 | ||||
| -rw-r--r-- | test/lisp/emacs-lisp/bytecomp-tests.el | 90 |
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 | |||
| 505 | Variables}. | 505 | Variables}. |
| 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 |
| 509 | expression using the construct @code{with-no-warnings}: | 509 | using the @code{with-suppressed-warnings} macro: |
| 510 | |||
| 511 | @defspec with-suppressed-warnings warnings body@dots{} | ||
| 512 | In execution, this is equivalent to @code{(progn @var{body}...)}, but | ||
| 513 | the compiler does not issue warnings for the specified conditions in | ||
| 514 | @var{body}. @var{warnings} is an associative list of warning symbols | ||
| 515 | and function/variable symbols they apply to. For instance, if you | ||
| 516 | wish to call an obsolete function called @code{foo}, but want to | ||
| 517 | suppress the compilation warning, say: | ||
| 518 | |||
| 519 | @lisp | ||
| 520 | (with-suppressed-warnings ((obsolete foo)) | ||
| 521 | (foo ...)) | ||
| 522 | @end lisp | ||
| 523 | @end defspec | ||
| 524 | |||
| 525 | For more coarse-grained suppression of compiler warnings, you can use | ||
| 526 | the @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}...)}, | |||
| 516 | but the compiler does not issue warnings for anything that occurs | 533 | but the compiler does not issue warnings for anything that occurs |
| 517 | inside @var{body}. | 534 | inside @var{body}. |
| 518 | 535 | ||
| 519 | We recommend that you use this construct around the smallest | 536 | We recommend that you use @code{with-suppressed-warnings} instead, but |
| 520 | possible piece of code, to avoid missing possible warnings other than | 537 | if you do use this construct, that you use it around the smallest |
| 538 | possible piece of code to avoid missing possible warnings other than | ||
| 521 | one you intend to suppress. | 539 | one you intend to suppress. |
| 522 | @end defspec | 540 | @end defspec |
| 523 | 541 | ||
| @@ -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 | ||
| 1697 | specific 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' |
| 1697 | This makes it possible to control the ordering of functions more precisely, | 1701 | This makes it possible to control the ordering of functions more precisely, |
| 1698 | as was already possible in 'add-function' and `advice-add`. | 1702 | as 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 | |||
| 500 | WARNINGS is an associative list where the first element of each | ||
| 501 | item is a warning type, and the rest of the elements in each item | ||
| 502 | are symbols they apply to. For instance, if you want to suppress | ||
| 503 | byte compilation warnings about the two obsolete functions `foo' | ||
| 504 | and `bar', as well as the function `zot' being called with the | ||
| 505 | wrong number of parameters, say | ||
| 506 | |||
| 507 | \(with-suppressed-warnings ((obsolete foo bar) | ||
| 508 | (callargs zot)) | ||
| 509 | (foo (bar)) | ||
| 510 | (zot 1 2)) | ||
| 511 | |||
| 512 | The warnings that can be suppressed are a subset of the warnings | ||
| 513 | in `byte-compile-warning-types'; see this variable for a fuller | ||
| 514 | explanation of the warning types. The types that can be | ||
| 515 | suppressed with this macro are `free-vars', `callargs', | ||
| 516 | `redefine', `obsolete', `interactive-only', `lexical', `mapcar', | ||
| 517 | `constants' and `suspicious'. | ||
| 518 | |||
| 519 | For the `mapcar' case, only the `mapcar' function can be used in | ||
| 520 | the 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. |
| 507 | Placing a macro here will cause a macro to have different semantics when | 525 | Placing a macro here will cause a macro to have different semantics when |
| 508 | expanded by the compiler as when expanded by the interpreter.") | 526 | expanded 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: |