summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--parse.y5
-rw-r--r--test/ruby/test_syntax.rb4
3 files changed, 16 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index a2acc6b061..f17a1577e2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Thu Jun 21 17:20:44 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * parse.y (new_args_tail_gen): fix GC problem of keyword rest
+ argument. the wrapped struct should be bound to the wrapping node
+ before assignment of child nodes, to get rid of the case the
+ children are referred by only the struct pointer which is not a
+ subject of GC. [ruby-core:45744]
+
Thu Jun 21 07:06:52 2012 Koichi Sasada <ko1@atdot.net>
* error.c (err_append): rename err_append() to compile_err_append()
diff --git a/parse.y b/parse.y
index 9f9093b0bb..c10099126f 100644
--- a/parse.y
+++ b/parse.y
@@ -9289,8 +9289,11 @@ new_args_tail_gen(struct parser_params *parser, NODE *k, ID kr, ID b)
int saved_line = ruby_sourceline;
struct rb_args_info *args;
NODE *kw_rest_arg = 0;
+ NODE *node;
args = ALLOC(struct rb_args_info);
+ MEMZERO(args, struct rb_args_info, 1);
+ node = NEW_NODE(NODE_ARGS, 0, 0, args);
args->block_arg = b;
args->kw_args = k;
@@ -9302,7 +9305,7 @@ new_args_tail_gen(struct parser_params *parser, NODE *k, ID kr, ID b)
args->kw_rest_arg = kw_rest_arg;
ruby_sourceline = saved_line;
- return NEW_NODE(NODE_ARGS, 0, 0, args);
+ return node;
}
#endif /* !RIPPER */
diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb
index 7eef6d6066..51e898f972 100644
--- a/test/ruby/test_syntax.rb
+++ b/test/ruby/test_syntax.rb
@@ -88,6 +88,10 @@ class TestSyntax < Test::Unit::TestCase
assert_equal({}, o.kw, bug5989)
assert_equal({foo: 1}, o.kw(foo: 1), bug5989)
assert_equal({foo: 1, bar: 2}, o.kw(foo: 1, bar: 2), bug5989)
+ EnvUtil.under_gc_stress do
+ eval("def o.m(k: 0) k end")
+ end
+ assert_equal(42, o.m(k: 42), '[ruby-core:45744]')
end
def test_keyword_splat