1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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
This commit is contained in:
nobu 2014-12-25 03:47:46 +00:00
parent ce59e249a5
commit f5f6218a23
3 changed files with 34 additions and 2 deletions

View file

@ -1,3 +1,8 @@
Thu Dec 25 12:47:44 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* parse.y (gettable_gen): warn possible reference to a local
variable defined in a past scope.
Thu Dec 25 10:09:14 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* ext/io/console/console.c (console_dev): id_console is not a

27
parse.y
View file

@ -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

View file

@ -873,4 +873,8 @@ x = __ENCODING__
a = "\u{3042}"
assert_warning(/#{a}/) {eval("#{a} = 1; /(?<#{a}>)/ =~ ''")}
end
def test_past_scope_variable
assert_warning(/past scope/) {catch {|tag| eval("BEGIN{throw tag}; tap {a = 1}; a")}}
end
end