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/