summaryrefslogtreecommitdiff
path: root/test/ruby
diff options
context:
space:
mode:
authoreileencodes <eileencodes@gmail.com>2023-02-07 15:46:50 -0500
committernagachika <nagachika@ruby-lang.org>2023-07-01 14:17:30 +0900
commit8a3d57971c99680d4baec84553247b9c6ee41080 (patch)
tree46800a87d7f72c09087deaa37c504c005a187fd6 /test/ruby
parent06dae46036316e6e9926c4613ac8058b78eb7f2e (diff)
Fix cvar caching when class is cloned
The class variable cache that was added in https://github.com/ruby/ruby/pull/4544 changed the behavior of class variables on cloned classes. As reported when a class is cloned AND a class variable was set, and the class variable was read from the original class, reading a class variable from the cloned class would return the value from the original class. This was happening because the IC (inline cache) is stored on the ISEQ which is shared between the original and cloned class, therefore they share the cache too. To fix this we are now storing the `cref` in the cache so that we can check if it's equal to the current `cref`. If it's different we don't want to read from the cache. If it's the same we do. Cloned classes don't share the same cref with their original class. This will need to be backported to 3.1 in addition to 3.2 since the bug exists in both versions. We also added a marking function which was missing. Fixes [Bug #19379] Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
Diffstat (limited to 'test/ruby')
-rw-r--r--test/ruby/test_variable.rb13
1 files changed, 13 insertions, 0 deletions
diff --git a/test/ruby/test_variable.rb b/test/ruby/test_variable.rb
index 4fe80a86c8..5e8abb0734 100644
--- a/test/ruby/test_variable.rb
+++ b/test/ruby/test_variable.rb
@@ -49,6 +49,19 @@ class TestVariable < Test::Unit::TestCase
assert_equal(1, c.class_variable_get(:@@foo))
end
+ Zeus = Gods.clone
+
+ def test_cloned_allows_setting_cvar
+ Zeus.class_variable_set(:@@rule, "Athena")
+
+ god = Gods.new.ruler0
+ zeus = Zeus.new.ruler0
+
+ assert_equal "Cronus", god
+ assert_equal "Athena", zeus
+ assert_not_equal god.object_id, zeus.object_id
+ end
+
def test_singleton_class_included_class_variable
c = Class.new
c.extend(Olympians)