[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]