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

ruby-changes:47468

From: nobu <ko1@a...>
Date: Sun, 13 Aug 2017 22:34:33 +0900 (JST)
Subject: [ruby-changes:47468] nobu:r59585 (trunk): parse.y: set used flag in gettable

nobu	2017-08-13 22:34:26 +0900 (Sun, 13 Aug 2017)

  New Revision: 59585

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=59585

  Log:
    parse.y: set used flag in gettable
    
    * parse.y (dvar_defined_ref, dvar_defined): rename macros.  only
      gettable uses the former.  assignable should not set LVAR_USED
      flag.
    
    * parse.y (gettable_gen): set used flag on local/dynamic variables
      instead of setting in lexer.  [ruby-core:82368] [Bug #13809]

  Modified files:
    trunk/parse.y
    trunk/test/ruby/test_parse.rb
Index: parse.y
===================================================================
--- parse.y	(revision 59584)
+++ parse.y	(revision 59585)
@@ -586,8 +586,9 @@ static void local_var_gen(struct parser_ https://github.com/ruby/ruby/blob/trunk/parse.y#L586
 #define local_var(id) local_var_gen(parser, (id))
 static void arg_var_gen(struct parser_params*, ID);
 #define arg_var(id) arg_var_gen(parser, (id))
-static int  local_id_gen(struct parser_params*, ID);
-#define local_id(id) local_id_gen(parser, (id))
+static int  local_id_gen(struct parser_params*, ID, ID **);
+#define local_id_ref(id, vidp) local_id_gen(parser, (id), &(vidp))
+#define local_id(id) local_id_gen(parser, (id), NULL)
 static ID   internal_id_gen(struct parser_params*);
 #define internal_id() internal_id_gen(parser)
 
@@ -598,9 +599,9 @@ static void dyna_pop_gen(struct parser_p https://github.com/ruby/ruby/blob/trunk/parse.y#L599
 static int dyna_in_block_gen(struct parser_params*);
 #define dyna_in_block() dyna_in_block_gen(parser)
 #define dyna_var(id) local_var(id)
-static int dvar_defined_gen(struct parser_params*,ID,int);
-#define dvar_defined(id) dvar_defined_gen(parser, (id), 0)
-#define dvar_defined_get(id) dvar_defined_gen(parser, (id), 1)
+static int dvar_defined_gen(struct parser_params*, ID, ID**);
+#define dvar_defined_ref(id, vidp) dvar_defined_gen(parser, (id), &(vidp))
+#define dvar_defined(id) dvar_defined_gen(parser, (id), NULL)
 static int dvar_curr_gen(struct parser_params*,ID);
 #define dvar_curr(id) dvar_curr_gen(parser, (id))
 
@@ -6791,7 +6792,7 @@ formal_argument_gen(struct parser_params https://github.com/ruby/ruby/blob/trunk/parse.y#L6792
 static int
 lvar_defined_gen(struct parser_params *parser, ID id)
 {
-    return (dyna_in_block() && dvar_defined_get(id)) || local_id(id);
+    return (dyna_in_block() && dvar_defined(id)) || local_id(id);
 }
 
 /* emacsen -*- hack */
@@ -8578,6 +8579,8 @@ yylex(YYSTYPE *lval, struct parser_param https://github.com/ruby/ruby/blob/trunk/parse.y#L8579
     return t;
 }
 
+#define LVAR_USED ((ID)1 << (sizeof(ID) * CHAR_BIT - 1))
+
 #ifndef RIPPER
 static NODE*
 node_newnode(struct parser_params *parser, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
@@ -8932,6 +8935,7 @@ past_dvar_p(struct parser_params *parser https://github.com/ruby/ruby/blob/trunk/parse.y#L8935
 static NODE*
 gettable_gen(struct parser_params *parser, ID id)
 {
+    ID *vidp = NULL;
     switch (id) {
       case keyword_self:
 	return NEW_SELF();
@@ -8950,16 +8954,18 @@ gettable_gen(struct parser_params *parse https://github.com/ruby/ruby/blob/trunk/parse.y#L8954
     }
     switch (id_type(id)) {
       case ID_LOCAL:
-	if (dyna_in_block() && dvar_defined(id)) {
+	if (dyna_in_block() && dvar_defined_ref(id, vidp)) {
 	    if (id == current_arg) {
 		rb_warn1("circular argument reference - %"PRIsWARN, rb_id2str(id));
 	    }
+	    if (vidp) *vidp |= LVAR_USED;
 	    return NEW_DVAR(id);
 	}
-	if (local_id(id)) {
+	if (local_id_ref(id, vidp)) {
 	    if (id == current_arg) {
 		rb_warn1("circular argument reference - %"PRIsWARN, rb_id2str(id));
 	    }
+	    if (vidp) *vidp |= LVAR_USED;
 	    return NEW_LVAR(id);
 	}
 # if WARN_PAST_SCOPE
@@ -9325,8 +9331,6 @@ is_private_local_id(ID name) https://github.com/ruby/ruby/blob/trunk/parse.y#L9331
     return RSTRING_PTR(s)[0] == '_';
 }
 
-#define LVAR_USED ((ID)1 << (sizeof(ID) * CHAR_BIT - 1))
-
 static int
 shadowing_lvar_0(struct parser_params *parser, ID name)
 {
@@ -9335,7 +9339,7 @@ shadowing_lvar_0(struct parser_params *p https://github.com/ruby/ruby/blob/trunk/parse.y#L9339
 	if (dvar_curr(name)) {
 	    yyerror("duplicated argument name");
 	}
-	else if (dvar_defined_get(name) || local_id(name)) {
+	else if (dvar_defined(name) || local_id(name)) {
 	    rb_warning1("shadowing outer local variable - %"PRIsWARN, rb_id2str(name));
 	    vtable_add(lvtbl->vars, name);
 	    if (lvtbl->used) {
@@ -10389,7 +10393,7 @@ local_var_gen(struct parser_params *pars https://github.com/ruby/ruby/blob/trunk/parse.y#L10393
 }
 
 static int
-local_id_gen(struct parser_params *parser, ID id)
+local_id_gen(struct parser_params *parser, ID id, ID **vidrefp)
 {
     struct vtable *vars, *args, *used;
 
@@ -10411,7 +10415,7 @@ local_id_gen(struct parser_params *parse https://github.com/ruby/ruby/blob/trunk/parse.y#L10415
     }
     else {
 	int i = vtable_included(vars, id);
-	if (i && used) used->tbl[i-1] |= LVAR_USED;
+	if (i && used && vidrefp) *vidrefp = &used->tbl[i-1];
 	return i != 0;
     }
 }
@@ -10477,7 +10481,7 @@ dyna_in_block_gen(struct parser_params * https://github.com/ruby/ruby/blob/trunk/parse.y#L10481
 }
 
 static int
-dvar_defined_gen(struct parser_params *parser, ID id, int get)
+dvar_defined_gen(struct parser_params *parser, ID id, ID **vidrefp)
 {
     struct vtable *vars, *args, *used;
     int i;
@@ -10491,12 +10495,12 @@ dvar_defined_gen(struct parser_params *p https://github.com/ruby/ruby/blob/trunk/parse.y#L10495
 	    return 1;
 	}
 	if ((i = vtable_included(vars, id)) != 0) {
-	    if (used) used->tbl[i-1] |= LVAR_USED;
+	    if (used && vidrefp) *vidrefp = &used->tbl[i-1];
 	    return 1;
 	}
 	args = args->prev;
 	vars = vars->prev;
-	if (get) used = 0;
+	if (!vidrefp) used = 0;
 	if (used) used = used->prev;
     }
 
Index: test/ruby/test_parse.rb
===================================================================
--- test/ruby/test_parse.rb	(revision 59584)
+++ test/ruby/test_parse.rb	(revision 59585)
@@ -881,8 +881,11 @@ x = __ENCODING__ https://github.com/ruby/ruby/blob/trunk/test/ruby/test_parse.rb#L881
   def test_unused_variable
     o = Object.new
     assert_warning(/assigned but unused variable/) {o.instance_eval("def foo; a=1; nil; end")}
+    assert_warning(/assigned but unused variable/) {o.instance_eval("def bar; a=1; a(); end")}
     a = "\u{3042}"
     assert_warning(/#{a}/) {o.instance_eval("def foo; #{a}=1; nil; end")}
+    o = Object.new
+    assert_warning(/assigned but unused variable/) {o.instance_eval("def foo; tap {a=1; a()}; end")}
   end
 
   def test_named_capture_conflict

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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