From: Stefan Kangas <stefan@marxist.se>
To: Kevin Ryde <user42@zip.com.au>
Cc: 6376@debbugs.gnu.org, Stefan Monnier <monnier@iro.umontreal.ca>
Subject: bug#6376: 23.2; byte compile add-to-list report free variable
Date: Wed, 18 Nov 2020 20:05:10 -0800 [thread overview]
Message-ID: <CADwFkm=yxm93+TQARoGkp87zQxk5wU0K61q7qg92CmJ8=uZr0Q@mail.gmail.com> (raw)
In-Reply-To: <87zkwzs3tk.fsf@blah.blah> (Kevin Ryde's message of "Sat, 07 Aug 2010 09:45:43 +1000")
Kevin Ryde <user42@zip.com.au> writes:
> I got a bit further to these few lines. Not quite ready yet, but
> getting closer. The byte-compile-check-var is more or less a break-out
> of the checks in byte-compile-variable-ref.
>
> add-hook and remove-hook end up with checks against non-variables, but
> they don't demand a bound variable. I suppose they could helpfully also
> notice undefined functions in their second arg too. You'd be tempted to
> have some sort of general arg-type description for the builtin funcs
> rather than doing checks plus "normal-call" for each.
(That was 10 years ago.)
This change looks useful to me. Any chance you could fix it up and send
it as a patch?
> (require 'bytecomp)
>
> (defun byte-compile-check-var (symbol base-op)
> ;; SYMBOL is the name of a variable. BASE-OP is one of the following
> ;; according to what's being done to the variable.
> ;; 'byte-varref
> ;; 'byte-varset
> ;; 'byte-varbind
> ;; 'varset-def -- set, defining if not already (eg. add-hook)
> ;; Emit a warning if SYMBOL is unbound, or if it's a constant being set or
> ;; bound.
> ;;
> (cond ((and (not (symbolp symbol))
> ;; `constants' warning includes all non-variables
> (byte-compile-warning-enabled-p 'constants))
> (byte-compile-warn "%s non-variable `%S'"
> (assoc-default base-op
> '((byte-varref . "reference to")
> (byte-varset . "assignment to")
> (varset-def . "assignment to")
> (byte-varbind . "let-bind of"))
> nil base-op)
> symbol))
>
> ((and (not (eq base-op 'byte-varref))
> (byte-compile-warning-enabled-p 'constants)
> (byte-compile-const-symbol-p symbol t))
> (byte-compile-warn "%s constant `%S'"
> (assoc-default
> base-op
> '((byte-varset . "variable assignment to")
> (varset-def . "variable assignment to")
> (byte-varbind . "let-bind of"))
> nil base-op)
> symbol))
>
> ((and (not (memq base-op '(varset-def byte-varbind)))
> (byte-compile-warning-enabled-p 'free-vars)
> (not (memq symbol byte-compile-bound-variables))
> (not (memq symbol byte-compile-free-assignments)))
> (byte-compile-warn "%s to free variable `%S'"
> (assoc-default base-op
> '((byte-varref . "reference to")
> (byte-varset . "assignment to"))
> nil base-op)
> symbol)
> (push symbol byte-compile-free-assignments))))
>
> (defun byte-compile-check-argvar (arg base-op)
> ;; ARG is a function argument form which is supposed to evaluate to a
> ;; symbol naming a variable. If ARG is (quote FOO) or :foo then check
> ;; that it's a bound variable per bytecomp-check-var. If ARG is
> ;; self-evaluating like nil, t, strings, etc then pass to the check too,
> ;; to possibly report assignment to a constant. Code like (quote nil) or
> ;; (quote "foo") reaches this point as plain nil or t.
> ;;
> (cond ((eq 'quote (car-safe arg))
> (byte-compile-check-var (car-safe (cdr arg)) base-op))
> ((or (memq arg '(nil t))
> ;; anything except a symbol or list is self-evaluating
> (not (or (symbolp arg)
> (consp arg))))
> (byte-compile-check-var arg base-op))))
>
> (defun byte-compile-addtolist (form)
> ;; first arg is the name of a variable being changed, eg. (foo 'var ...)
> (if (>= (safe-length form) 2)
> (byte-compile-check-argvar (cadr form) 'byte-varset))
> (byte-compile-normal-call form))
> (byte-defop-compiler-1 add-to-list byte-compile-addtolist)
> (byte-defop-compiler-1 add-to-ordered-list byte-compile-addtolist)
>
> (defun byte-compile-addremhook (form)
> ;; first arg is the name of a variable being changed, eg. (foo 'var ...)
> ;; only
> (if (>= (safe-length form) 2)
> (byte-compile-check-argvar (cadr form) 'varset-def))
> (byte-compile-normal-call form))
> (byte-defop-compiler-1 add-hook byte-compile-addremhook)
> (byte-defop-compiler-1 remove-hook byte-compile-addremhook)
next prev parent reply other threads:[~2020-11-19 4:05 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-08 1:30 bug#6376: 23.2; byte compile add-to-list report free variable Kevin Ryde
2010-06-09 1:29 ` Stefan Monnier
2010-06-12 23:11 ` Kevin Ryde
2010-08-06 23:45 ` Kevin Ryde
2010-08-10 9:12 ` Stefan Monnier
2010-09-21 1:34 ` Kevin Ryde
2020-11-19 4:05 ` Stefan Kangas [this message]
2020-11-20 5:06 ` Stefan Kangas
2022-01-31 16:58 ` Lars Ingebrigtsen
2022-02-01 23:31 ` Michael Heerdegen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CADwFkm=yxm93+TQARoGkp87zQxk5wU0K61q7qg92CmJ8=uZr0Q@mail.gmail.com' \
--to=stefan@marxist.se \
--cc=6376@debbugs.gnu.org \
--cc=monnier@iro.umontreal.ca \
--cc=user42@zip.com.au \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.