summaryrefslogtreecommitdiff
path: root/test/ruby/test_super.rb
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2020-04-14 23:24:50 -0700
committerTakashi Kokubun <takashikkbn@gmail.com>2020-04-14 23:32:13 -0700
commit8355a998839f17ff214a89062821a0a4287f6a54 (patch)
tree987e49edc61b9ae3a4793e200bdb99a745cd52e7 /test/ruby/test_super.rb
parent2c12d111cb6efb110caa72b0e5314d3affbefb6e (diff)
Invalidate fastpath when calling attr_writer by super
We started to use fastpath on invokesuper when a method is not refinements since 5c27681813, but we shouldn't have used fastpath for attr_writer either. `cc->aux_.attr_index` is for an actual receiver class, while we store its superclass in `cc->klass` and therefore there's no way to properly invalidate attr_writer's inline cache when it's called by super. [Bug #16785] I suspect the same bug also exists in attr_reader. I'll address that in another commit.
Diffstat (limited to 'test/ruby/test_super.rb')
-rw-r--r--test/ruby/test_super.rb30
1 files changed, 30 insertions, 0 deletions
diff --git a/test/ruby/test_super.rb b/test/ruby/test_super.rb
index 3d5af3d485..7cbe851fdf 100644
--- a/test/ruby/test_super.rb
+++ b/test/ruby/test_super.rb
@@ -603,4 +603,34 @@ class TestSuper < Test::Unit::TestCase
assert_equal :boo, subklass.new.baz
assert_equal :boo2, subklass.new.boo
end
+
+ def test_super_attr_writer # Bug #16785
+ writer_class = Class.new do
+ attr_writer :test
+ end
+ superwriter_class = Class.new(writer_class) do
+ def initialize
+ @test = 1 # index: 1
+ end
+
+ def test=(test)
+ super(test)
+ end
+ end
+ inherited_class = Class.new(superwriter_class) do
+ def initialize
+ @a = nil
+ @test = 2 # index: 2
+ end
+ end
+
+ superwriter = superwriter_class.new
+ superwriter.test = 3 # set ic->index of superwriter_class#test= to 1
+
+ inherited = inherited_class.new
+ inherited.test = 4 # it may set 4 to index=1 while it should be index=2
+
+ assert_equal 3, superwriter.instance_variable_get(:@test)
+ assert_equal 4, inherited.instance_variable_get(:@test)
+ end
end