From b41909f603dce3c8f48d49514c50d6813a1ca491 Mon Sep 17 00:00:00 2001 From: nobu Date: Fri, 12 Sep 2014 08:13:28 +0000 Subject: vm_method.c: should not modify frozen objects * vm_method.c (rb_method_entry_make, remove_method): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47551 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 4 ++++ eval.c | 4 ++++ test/ruby/test_class.rb | 9 +++++++++ vm_method.c | 4 ++-- 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0994dc379d..e1cafee06b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Fri Sep 12 17:13:29 2014 Nobuyoshi Nakada + + * vm_method.c (rb_method_entry_make, remove_method): ditto. + Fri Sep 12 14:39:55 2014 SHIBATA Hiroshi * gems/bundled_gems: Upgraded to test-unit-3.0.1 and minitest-5.4.1 diff --git a/eval.c b/eval.c index 90da22503e..cd91a1a735 100644 --- a/eval.c +++ b/eval.c @@ -409,6 +409,10 @@ rb_frozen_class_p(VALUE klass) noclass: Check_Type(klass, T_CLASS); } + if (FL_TEST(klass, FL_SINGLETON)) { + VALUE obj = rb_ivar_get(klass, id__attached__); + if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass); + } if (OBJ_FROZEN(klass)) { const char *desc; diff --git a/test/ruby/test_class.rb b/test/ruby/test_class.rb index 963c497d2f..9a4cdb0f58 100644 --- a/test/ruby/test_class.rb +++ b/test/ruby/test_class.rb @@ -384,4 +384,13 @@ class TestClass < Test::Unit::TestCase Class.new.freeze.clone.to_s } end + + def test_singleton_class_of_frozen_object + obj = Object.new + c = obj.singleton_class + obj.freeze + assert_raise(RuntimeError, /frozen object/) { + c.class_eval {def f; end} + } + end end diff --git a/vm_method.c b/vm_method.c index 74dafab3f6..60b7dc0e8f 100644 --- a/vm_method.c +++ b/vm_method.c @@ -271,7 +271,7 @@ rb_method_entry_make(VALUE klass, ID mid, rb_method_type_t type, } } - rb_check_frozen(klass); + rb_frozen_class_p(klass); #if NOEX_NOREDEF rklass = klass; #endif @@ -746,7 +746,7 @@ remove_method(VALUE klass, ID mid) VALUE self = klass; klass = RCLASS_ORIGIN(klass); - rb_check_frozen(klass); + rb_frozen_class_p(klass); if (mid == object_id || mid == id__send__ || mid == idInitialize) { rb_warn("removing `%s' may cause serious problems", rb_id2name(mid)); } -- cgit v1.2.3