summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-06-21 08:20:51 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-06-21 08:20:51 +0000
commit64ae33a18ae0e13444b6ab7c043450b2fe68c62b (patch)
tree6c46afb9552a6e2095957c4011c4a86fcd8525db
parentb8b67c0b9d7fc55a37647064f77a898f34abf89b (diff)
parse.y: fix GC problem of keyword rest argument
* 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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36161 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-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