summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compile.c1
-rw-r--r--test/ruby/test_literal.rb16
2 files changed, 17 insertions, 0 deletions
diff --git a/compile.c b/compile.c
index 731b05323b..cb168438d8 100644
--- a/compile.c
+++ b/compile.c
@@ -4026,6 +4026,7 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node_ro
hash = rb_hash_new_with_size(RARRAY_LEN(ary) / 2);
rb_hash_bulk_insert(RARRAY_LEN(ary), RARRAY_CONST_PTR_TRANSIENT(ary), hash);
+ rb_hash_freeze(hash);
iseq_add_mark_object_compile_time(iseq, hash);
ADD_INSN1(ret, line, duphash, hash);
}
diff --git a/test/ruby/test_literal.rb b/test/ruby/test_literal.rb
index ef2467e177..37755422a1 100644
--- a/test/ruby/test_literal.rb
+++ b/test/ruby/test_literal.rb
@@ -283,6 +283,22 @@ class TestRubyLiteral < Test::Unit::TestCase
assert_equal "literal", h["string"]
end
+ def frozen_hash_literal_arg
+ {0=>1,1=>4,2=>17}
+ end
+
+ def test_hash_literal_frozen
+ assert_not_include frozen_hash_literal_arg, 3
+ assert_raise(FrozenError) do
+ ObjectSpace.each_object(Hash) do |a|
+ if a.class == Hash and !a.default_proc and a.size == 3
+ a[3] = 8 if a[0] == 1 and a[1] == 4 and a[2] == 17
+ end
+ end
+ end
+ assert_not_include frozen_hash_literal_arg, 3
+ end
+
def test_big_array_and_hash_literal
assert_normal_exit %q{GC.disable=true; x = nil; raise if eval("[#{(1..1_000_000).map{'x'}.join(", ")}]").size != 1_000_000}, "", timeout: 300, child_env: %[--disable-gems]
assert_normal_exit %q{GC.disable=true; x = nil; raise if eval("[#{(1..1_000_000).to_a.join(", ")}]").size != 1_000_000}, "", timeout: 300, child_env: %[--disable-gems]