summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2021-09-24 01:30:00 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2021-09-24 08:29:00 +0900
commitb929af430c39df6597d2f3f53b82c38b1d76217b (patch)
tree7e76a81c8617d265e6cee0d42760fd735c51d9e4
parent65285bf673914424e960671d1d35e357c455985e (diff)
downloadruby-b929af430c39df6597d2f3f53b82c38b1d76217b.tar.gz
Use the flag for uninitialized module [Bug #18185]
Make `Module#ancestors` not to include `BasicObject`.
-rw-r--r--class.c15
-rw-r--r--test/ruby/test_module.rb3
2 files changed, 12 insertions, 6 deletions
diff --git a/class.c b/class.c
index 8e37f8a93e..ca8bdc2e79 100644
--- a/class.c
+++ b/class.c
@@ -351,19 +351,22 @@ copy_tables(VALUE clone, VALUE orig)
static bool ensure_origin(VALUE klass);
+/**
+ * If this flag is set, that module is allocated but not initialized yet.
+ */
+enum {RMODULE_ALLOCATED_BUT_NOT_INITIALIZED = RUBY_FL_USER5};
+
static inline bool
RMODULE_UNINITIALIZED(VALUE module)
{
- return RCLASS_SUPER(module) == rb_cBasicObject;
+ return FL_TEST_RAW(module, RMODULE_ALLOCATED_BUT_NOT_INITIALIZED);
}
void
rb_module_set_initialized(VALUE mod)
{
- if (RMODULE_UNINITIALIZED(mod)) {
- RB_OBJ_WRITE(mod, &RCLASS(mod)->super, 0);
- /* no more re-initialization */
- }
+ FL_UNSET_RAW(mod, RMODULE_ALLOCATED_BUT_NOT_INITIALIZED);
+ /* no more re-initialization */
}
void
@@ -817,7 +820,7 @@ rb_module_s_alloc(VALUE klass)
{
VALUE mod = class_alloc(T_MODULE, klass);
RCLASS_M_TBL_INIT(mod);
- RB_OBJ_WRITE(mod, &RCLASS(mod)->super, rb_cBasicObject);
+ FL_SET(mod, RMODULE_ALLOCATED_BUT_NOT_INITIALIZED);
return mod;
}
diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb
index 429fab897e..be23b84c46 100644
--- a/test/ruby/test_module.rb
+++ b/test/ruby/test_module.rb
@@ -449,7 +449,9 @@ class TestModule < Test::Unit::TestCase
class Bug18185 < Module
module InstanceMethods
end
+ attr_reader :ancestor_list
def initialize
+ @ancestor_list = ancestors
include InstanceMethods
end
class Foo
@@ -470,6 +472,7 @@ class TestModule < Test::Unit::TestCase
assert_equal(1, anc.count(BasicObject), ->{anc.inspect})
b = c.new(key: 1)
assert_equal(1, b.key)
+ assert_not_include(mod.ancestor_list, BasicObject)
end
def test_dup