diff options
author | Takashi Kokubun <takashikkbn@gmail.com> | 2020-04-14 23:49:28 -0700 |
---|---|---|
committer | Takashi Kokubun <takashikkbn@gmail.com> | 2020-04-14 23:49:29 -0700 |
commit | 79f3403be0cdbec814be29308c0583599ca5824f (patch) | |
tree | 3143b34566e4d5e07b153d892bdb03648c2c7459 | |
parent | 8355a998839f17ff214a89062821a0a4287f6a54 (diff) | |
download | ruby-79f3403be0cdbec814be29308c0583599ca5824f.tar.gz |
Invalidate fastpath when calling attr_reader by super
The same bug as 8355a99883 existed in attr_reader too.
-rw-r--r-- | test/ruby/test_super.rb | 29 | ||||
-rw-r--r-- | vm_insnhelper.c | 4 |
2 files changed, 30 insertions, 3 deletions
diff --git a/test/ruby/test_super.rb b/test/ruby/test_super.rb index 7cbe851fdf..78c8ee5dc2 100644 --- a/test/ruby/test_super.rb +++ b/test/ruby/test_super.rb @@ -604,7 +604,7 @@ class TestSuper < Test::Unit::TestCase assert_equal :boo2, subklass.new.boo end - def test_super_attr_writer # Bug #16785 + def test_super_attr_writer # [Bug #16785] writer_class = Class.new do attr_writer :test end @@ -633,4 +633,31 @@ class TestSuper < Test::Unit::TestCase assert_equal 3, superwriter.instance_variable_get(:@test) assert_equal 4, inherited.instance_variable_get(:@test) end + + def test_super_attr_reader + writer_class = Class.new do + attr_reader :test + end + superwriter_class = Class.new(writer_class) do + def initialize + @test = 1 # index: 1 + end + + def test + super + end + end + inherited_class = Class.new(superwriter_class) do + def initialize + @a = nil + @test = 2 # index: 2 + end + end + + superwriter = superwriter_class.new + assert_equal 1, superwriter.test # set ic->index of superwriter_class#test to 1 + + inherited = inherited_class.new + assert_equal 2, inherited.test # it may read index=1 while it should be index=2 + end end diff --git a/vm_insnhelper.c b/vm_insnhelper.c index c4a8dfaf61..70c957cd9a 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -3235,9 +3235,9 @@ vm_search_super_method(const rb_control_frame_t *reg_cfp, struct rb_call_data *c switch (cached_cme->def->type) { // vm_call_refined (search_refined_method) assumes cc->call is vm_call_super_method on invokesuper case VM_METHOD_TYPE_REFINED: - // cc->klass is superclass of a class of receiver. Checking cc->klass is not enough to invalidate IVC for the receiver class. + // cc->klass is superclass of receiver class. Checking cc->klass is not enough to invalidate IVC for the receiver class. case VM_METHOD_TYPE_ATTRSET: - // TODO: case VM_METHOD_TYPE_IVAR: + case VM_METHOD_TYPE_IVAR: vm_cc_call_set(cd->cc, vm_call_super_method); // invalidate fastpath break; default: |