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

ruby-changes:35812

From: nobu <ko1@a...>
Date: Mon, 13 Oct 2014 02:39:40 +0900 (JST)
Subject: [ruby-changes:35812] nobu:r47894 (trunk): parse.y: should not eliminate value nodes

nobu	2014-10-13 02:39:29 +0900 (Mon, 13 Oct 2014)

  New Revision: 47894

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

  Log:
    parse.y: should not eliminate value nodes
    
    * parse.y (remove_duplicate_keys): should not simply eliminate all
      value nodes, which may have side effects.
      [ruby-core:65625] [Bug #10315]

  Modified files:
    trunk/ChangeLog
    trunk/parse.y
    trunk/test/ruby/test_syntax.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 47893)
+++ ChangeLog	(revision 47894)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Mon Oct 13 02:39:26 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* parse.y (remove_duplicate_keys): should not simply eliminate all
+	  value nodes, which may have side effects.
+	  [ruby-core:65625] [Bug #10315]
+
 Sun Oct 12 10:39:16 2014  Zachary Scott  <e@z...>
 
 	* vm.c: [DOC] fix typo by @yui-knk [Fixes GH-738]
Index: parse.y
===================================================================
--- parse.y	(revision 47893)
+++ parse.y	(revision 47894)
@@ -9601,9 +9601,6 @@ append_literal_keys(st_data_t k, st_data https://github.com/ruby/ruby/blob/trunk/parse.y#L9601
 {
     NODE *node = (NODE *)v;
     NODE **result = (NODE **)h;
-    node->nd_alen = 2;
-    node->nd_next->nd_end = node->nd_next;
-    node->nd_next->nd_next = 0;
     if (*result)
 	list_concat(*result, node);
     else
@@ -9618,21 +9615,25 @@ remove_duplicate_keys(struct parser_para https://github.com/ruby/ruby/blob/trunk/parse.y#L9615
     NODE *result = 0;
     while (hash && hash->nd_head && hash->nd_next) {
 	NODE *head = hash->nd_head;
-	VALUE key = 0;
+	NODE *value = hash->nd_next;
+	NODE *next = value->nd_next;
+	VALUE key = (VALUE)head;
 	st_data_t data;
-	if (nd_type(head) == NODE_LIT) {
-	    key = head->nd_lit;
-	    if (st_lookup(literal_keys, key, &data)) {
-		rb_compile_warn(ruby_sourcefile, nd_line((NODE *)data),
-				"duplicated key at line %d ignored: %+"PRIsVALUE,
-				nd_line(head), head->nd_lit);
-	    }
+	hash->nd_alen = 2;
+	value->nd_end = value;
+	value->nd_next = 0;
+	if (nd_type(head) == NODE_LIT &&
+	    st_lookup(literal_keys, (key = head->nd_lit), &data)) {
+	    rb_compile_warn(ruby_sourcefile, nd_line((NODE *)data),
+			    "duplicated key at line %d ignored: %+"PRIsVALUE,
+			    nd_line(head), head->nd_lit);
+	    head = ((NODE *)data)->nd_next;
+	    head->nd_head = block_append(head->nd_head, value->nd_head);
 	}
 	else {
-	    key = (VALUE)head;
+	    st_insert(literal_keys, (st_data_t)key, (st_data_t)hash);
 	}
-	st_insert(literal_keys, (st_data_t)key, (st_data_t)hash);
-	hash = hash->nd_next->nd_next;
+	hash = next;
     }
     st_foreach(literal_keys, append_literal_keys, (st_data_t)&result);
     st_free_table(literal_keys);
Index: test/ruby/test_syntax.rb
===================================================================
--- test/ruby/test_syntax.rb	(revision 47893)
+++ test/ruby/test_syntax.rb	(revision 47894)
@@ -120,6 +120,21 @@ class TestSyntax < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_syntax.rb#L120
     assert_raise(ArgumentError) {o.kw(**h)}
     h = {"k1"=>11, k2: 12}
     assert_raise(TypeError) {o.kw(**h)}
+
+    bug10315 = '[ruby-core:65625] [Bug #10315]'
+    a = []
+    def a.add(x) push(x); x; end
+    def a.f(k:) k; end
+    a.clear
+    r = nil
+    assert_warn(/duplicated/) {r = eval("a.f(k: a.add(1), k: a.add(2))")}
+    assert_equal(2, r)
+    assert_equal([1, 2], a, bug10315)
+    a.clear
+    r = nil
+    assert_warn(/duplicated/) {r = eval("a.f({k: a.add(1), k: a.add(2)})")}
+    assert_equal(2, r)
+    assert_equal([1, 2], a, bug10315)
   end
 
   def test_keyword_self_reference

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

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