diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | parse.y | 29 | ||||
-rw-r--r-- | test/ruby/test_syntax.rb | 15 |
3 files changed, 36 insertions, 14 deletions
@@ -1,3 +1,9 @@ +Mon Oct 13 02:39:26 2014 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * 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@zzak.io> * vm.c: [DOC] fix typo by @yui-knk [Fixes GH-738] @@ -9601,9 +9601,6 @@ append_literal_keys(st_data_t k, st_data_t v, st_data_t h) { 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_params *parser, NODE *hash) 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); diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb index 5a7d2f8a62..797d559b02 100644 --- a/test/ruby/test_syntax.rb +++ b/test/ruby/test_syntax.rb @@ -120,6 +120,21 @@ class TestSyntax < Test::Unit::TestCase 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 |