ruby-changes:36107
From: nobu <ko1@a...>
Date: Wed, 29 Oct 2014 21:13:38 +0900 (JST)
Subject: [ruby-changes:36107] nobu:r48188 (trunk): parse.y: warn circular argument reference
nobu 2014-10-29 21:13:26 +0900 (Wed, 29 Oct 2014) New Revision: 48188 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=48188 Log: parse.y: warn circular argument reference * parse.y (gettable_gen): warn circular argument reference, for transition from 2.1 and earlier. [ruby-core:65990] [Bug #10314] Modified files: trunk/ChangeLog trunk/parse.y trunk/test/ruby/test_syntax.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 48187) +++ ChangeLog (revision 48188) @@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Oct 29 21:13:23 2014 Nobuyoshi Nakada <nobu@r...> + + * parse.y (gettable_gen): warn circular argument reference, for + transition from 2.1 and earlier. [ruby-core:65990] [Bug #10314] + Wed Oct 29 20:41:01 2014 Nobuyoshi Nakada <nobu@r...> * parse.y (parser_params): remove unused member `cur_mid`. Index: parse.y =================================================================== --- parse.y (revision 48187) +++ parse.y (revision 48188) @@ -256,6 +256,8 @@ struct parser_params { https://github.com/ruby/ruby/blob/trunk/parse.y#L256 int last_cr_line; + ID cur_arg; + #ifndef RIPPER /* Ruby core only */ NODE *parser_eval_tree_begin; @@ -328,6 +330,7 @@ static int parser_yyerror(struct parser_ https://github.com/ruby/ruby/blob/trunk/parse.y#L330 #define ruby_sourcefile (parser->parser_ruby_sourcefile) #define ruby_sourcefile_string (parser->parser_ruby_sourcefile_string) #define current_enc (parser->enc) +#define current_arg (parser->cur_arg) #define yydebug (parser->parser_yydebug) #ifdef RIPPER #else @@ -634,6 +637,7 @@ new_args_tail_gen(struct parser_params * https://github.com/ruby/ruby/blob/trunk/parse.y#L637 # define rb_warn0(fmt) rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt)) # define rb_warnI(fmt,a) rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt), (a)) # define rb_warnS(fmt,a) rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt), (a)) +# define rb_warnV(fmt,a) rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt), (a)) # define rb_warn4S(file,line,fmt,a) rb_compile_warn((file), (line), (fmt), (a)) # define rb_warn4V(file,line,fmt,a) rb_compile_warn((file), (line), (fmt), (a)) # define rb_warning0(fmt) rb_compile_warning(ruby_sourcefile, ruby_sourceline, (fmt)) @@ -2979,6 +2983,8 @@ primary : literal https://github.com/ruby/ruby/blob/trunk/parse.y#L2983 { in_def++; local_push(0); + $<id>$ = current_arg; + current_arg = 0; } f_arglist bodystmt @@ -4591,13 +4597,16 @@ f_norm_arg : f_bad_arg https://github.com/ruby/ruby/blob/trunk/parse.y#L4597 f_arg_asgn : f_norm_arg { - arg_var(get_id($1)); + ID id = get_id($1); + arg_var(id); + current_arg = id; $$ = $1; } ; f_arg_item : f_arg_asgn { + current_arg = 0; /*%%%*/ $$ = NEW_ARGS_AUX($1, 1); /*% @@ -4646,13 +4655,16 @@ f_arg : f_arg_item https://github.com/ruby/ruby/blob/trunk/parse.y#L4655 f_label : tLABEL { - arg_var(formal_argument(get_id($1))); + ID id = get_id($1); + arg_var(formal_argument(id)); + current_arg = id; $$ = $1; } ; f_kw : f_label arg_value { + current_arg = 0; $$ = assignable($1, $2); /*%%%*/ $$ = NEW_KW_ARG(0, $$); @@ -4662,6 +4674,7 @@ f_kw : f_label arg_value https://github.com/ruby/ruby/blob/trunk/parse.y#L4674 } | f_label { + current_arg = 0; $$ = assignable($1, (NODE *)-1); /*%%%*/ $$ = NEW_KW_ARG(0, $$); @@ -4757,6 +4770,7 @@ f_kwrest : kwrest_mark tIDENTIFIER https://github.com/ruby/ruby/blob/trunk/parse.y#L4770 f_opt : f_arg_asgn '=' arg_value { + current_arg = 0; $$ = assignable($1, $3); /*%%%*/ $$ = NEW_OPT_ARG(0, $$); @@ -4768,6 +4782,7 @@ f_opt : f_arg_asgn '=' arg_value https://github.com/ruby/ruby/blob/trunk/parse.y#L4782 f_block_opt : f_arg_asgn '=' primary_value { + current_arg = 0; $$ = assignable($1, $3); /*%%%*/ $$ = NEW_OPT_ARG(0, $$); @@ -8719,7 +8734,12 @@ gettable_gen(struct parser_params *parse https://github.com/ruby/ruby/blob/trunk/parse.y#L8734 switch (id_type(id)) { case ID_LOCAL: if (dyna_in_block() && dvar_defined(id)) return NEW_DVAR(id); - if (local_id(id)) return NEW_LVAR(id); + if (local_id(id)) { + if (id == current_arg) { + rb_warnV("circular argument reference - %"PRIsVALUE, rb_id2str(id)); + } + return NEW_LVAR(id); + } /* method call without arguments */ return NEW_VCALL(id); case ID_GLOBAL: @@ -10257,6 +10277,7 @@ parser_initialize(struct parser_params * https://github.com/ruby/ruby/blob/trunk/parse.y#L10277 parser->parser_ruby__end__seen = 0; parser->parser_ruby_sourcefile = 0; parser->parser_ruby_sourcefile_string = Qnil; + parser->cur_arg = 0; #ifndef RIPPER parser->is_ripper = 0; parser->parser_eval_tree_begin = 0; Index: test/ruby/test_syntax.rb =================================================================== --- test/ruby/test_syntax.rb (revision 48187) +++ test/ruby/test_syntax.rb (revision 48188) @@ -140,24 +140,32 @@ class TestSyntax < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_syntax.rb#L140 def test_keyword_self_reference bug9593 = '[ruby-core:61299] [Bug #9593]' o = Object.new - def o.foo(var: defined?(var)) var end + assert_warn(/circular argument reference - var/) do + o.instance_eval("def foo(var: defined?(var)) var end") + end assert_equal(42, o.foo(var: 42)) assert_equal("local-variable", o.foo, bug9593) o = Object.new - def o.foo(var: var) var end + assert_warn(/circular argument reference - var/) do + o.instance_eval("def foo(var: var) var end") + end assert_nil(o.foo, bug9593) end def test_optional_self_reference bug9593 = '[ruby-core:61299] [Bug #9593]' o = Object.new - def o.foo(var = defined?(var)) var end + assert_warn(/circular argument reference - var/) do + o.instance_eval("def foo(var = defined?(var)) var end") + end assert_equal(42, o.foo(42)) assert_equal("local-variable", o.foo, bug9593) o = Object.new - def o.foo(var = var) var end + assert_warn(/circular argument reference - var/) do + o.instance_eval("def foo(var = var) var end") + end assert_nil(o.foo, bug9593) end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/