summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-12-25 03:47:46 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-12-25 03:47:46 +0000
commitf5f6218a23fdbe45d1a80c202a131f02c3eef0ce (patch)
tree97c75e272f700fa4df8691b571d7e0db15df8100 /parse.y
parentce59e249a562c8dded6482bc986d72fe34119bff (diff)
parse.y: warn past scope variable
* parse.y (gettable_gen): warn possible reference to a local variable defined in a past scope. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48986 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y27
1 files changed, 25 insertions, 2 deletions
diff --git a/parse.y b/parse.y
index 20345085b5..bfc685a05f 100644
--- a/parse.y
+++ b/parse.y
@@ -113,6 +113,7 @@ struct local_vars {
struct vtable *args;
struct vtable *vars;
struct vtable *used;
+ struct vtable *past;
struct local_vars *prev;
stack_type cmdargs;
};
@@ -8827,6 +8828,17 @@ match_op_gen(struct parser_params *parser, NODE *node1, NODE *node2)
return NEW_CALL(node1, tMATCH, NEW_LIST(node2));
}
+static int
+past_dvar_p(struct parser_params *parser, ID id)
+{
+ struct vtable *past = lvtbl->past;
+ while (past) {
+ if (vtable_included(past, id)) return 1;
+ past = past->prev;
+ }
+ return 0;
+}
+
static NODE*
gettable_gen(struct parser_params *parser, ID id)
{
@@ -8860,6 +8872,9 @@ gettable_gen(struct parser_params *parser, ID id)
}
return NEW_LVAR(id);
}
+ if (!in_defined && RTEST(ruby_verbose) && past_dvar_p(parser, id)) {
+ rb_warningV("possible reference to past scope - %"PRIsVALUE, rb_id2str(id));
+ }
/* method call without arguments */
return NEW_VCALL(id);
case ID_GLOBAL:
@@ -9978,6 +9993,7 @@ local_push_gen(struct parser_params *parser, int inherit_dvars)
local->used = !(inherit_dvars &&
(ifndef_ripper(compile_for_eval || e_option_supplied(parser))+0)) &&
RTEST(ruby_verbose) ? vtable_alloc(0) : 0;
+ local->past = 0;
local->cmdargs = cmdarg_stack;
cmdarg_stack = 0;
lvtbl = local;
@@ -9991,6 +10007,11 @@ local_pop_gen(struct parser_params *parser)
warn_unused_var(parser, lvtbl);
vtable_free(lvtbl->used);
}
+ while (lvtbl->past) {
+ struct vtable *past = lvtbl->past;
+ lvtbl->past = past->prev;
+ vtable_free(past);
+ }
vtable_free(lvtbl->args);
vtable_free(lvtbl->vars);
cmdarg_stack = lvtbl->cmdargs;
@@ -10090,10 +10111,12 @@ dyna_pop_1(struct parser_params *parser)
}
tmp = lvtbl->args;
lvtbl->args = lvtbl->args->prev;
- vtable_free(tmp);
+ tmp->prev = lvtbl->past;
+ lvtbl->past = tmp;
tmp = lvtbl->vars;
lvtbl->vars = lvtbl->vars->prev;
- vtable_free(tmp);
+ tmp->prev = lvtbl->past;
+ lvtbl->past = tmp;
}
static void