summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-10-26 07:33:03 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-10-26 07:33:03 -0700
commite15727cf2ad6ebe2503f9ea0e16dccf118bc93ff (patch)
tree66f2a97bd0d786f8b5eb95e86bc1ce3ab1d68912 /eval.c
parent9733bb6dad3b0c430a82b2592d5519383479cb86 (diff)
downloadtxr-e15727cf2ad6ebe2503f9ea0e16dccf118bc93ff.tar.gz
txr-e15727cf2ad6ebe2503f9ea0e16dccf118bc93ff.tar.bz2
txr-e15727cf2ad6ebe2503f9ea0e16dccf118bc93ff.zip
defvar: warn about prior lexical uses.
Now that the compiler has a more efficient treatment of global lexical variables, code which accesses global variables that have not yet been defined will misbehave if the intent is to for those variables to be dynamically scoped. There is such a bug in the op expander, in fact. * eval.c (me_def_variable): When defvar/defparm are expanding, they now check whether there is an outstanding unbound warning against the variable. If so, then a warning is issued that the variable was previously used lexically and is now being marked special. * unwind.c (uw_warning_exists): New function. * unwind.h (uw_warning_exists): Declared.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/eval.c b/eval.c
index 50c6fbc7..e28e1164 100644
--- a/eval.c
+++ b/eval.c
@@ -2929,8 +2929,12 @@ static val me_def_variable(val form, val menv)
if (!bindable(sym))
not_bindable_error(form, sym);
- if (op == defparm_s || op == defvar_s)
+ if (op == defparm_s || op == defvar_s) {
mark_special(sym);
+ if (uw_warning_exists(cons(var_s, sym)))
+ eval_warn(form, lit("~s: global ~s marked special after lexical uses"),
+ op, sym, nao);
+ }
return apply_frob_args(list(prog1_s,
cons(defvarl_s,