summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2026-03-24 14:13:50 +0900
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2026-03-24 14:49:12 +0900
commitc675ec66e912b3000e05d65bba473e8bf6e18c96 (patch)
tree1e5ed51e34f3703b1eb6618f190d57c9fb36daa1
parent83637aea6ea726f7fc4c17e56ac60c289e2d98db (diff)
merge revision(s) 1e7cf7b2bc1f9b356b2e980e1e18548618da6363: [Backport #21446]
[PATCH] Fix refinement modification of method visibility in superclass Previously, this didn't work correctly, resulting in a SystemStackError. This fixes the issue by finding the related superclass method entry, and updating the orig_me in the refinement method to point to the superclass method. Fixes [Bug #21446]
-rw-r--r--test/ruby/test_refinement.rb23
-rw-r--r--version.h2
-rw-r--r--vm_method.c6
3 files changed, 30 insertions, 1 deletions
diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb
index b05e651c90..a8d46f4d07 100644
--- a/test/ruby/test_refinement.rb
+++ b/test/ruby/test_refinement.rb
@@ -1939,6 +1939,29 @@ class TestRefinement < Test::Unit::TestCase
end;
end
+ def test_public_in_refine_for_method_in_superclass
+ assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}")
+ begin;
+ bug21446 = '[ruby-core:122558] [Bug #21446]'
+
+ class CowSuper
+ private
+ def moo() "Moo"; end
+ end
+ class Cow < CowSuper
+ end
+
+ module PublicCows
+ refine(Cow) {
+ public :moo
+ }
+ end
+
+ using PublicCows
+ assert_equal("Moo", Cow.new.moo, bug21446)
+ end;
+ end
+
module SuperToModule
class Parent
end
diff --git a/version.h b/version.h
index 26194701aa..31a4f79cb2 100644
--- a/version.h
+++ b/version.h
@@ -11,7 +11,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 10
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 198
+#define RUBY_PATCHLEVEL 199
#include "ruby/version.h"
#include "ruby/internal/abi.h"
diff --git a/vm_method.c b/vm_method.c
index 855ddd14c8..4dc67ad37b 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -941,6 +941,7 @@ check_override_opt_method(VALUE klass, VALUE mid)
}
}
+static inline rb_method_entry_t* search_method0(VALUE klass, ID id, VALUE *defined_class_ptr, bool skip_refined);
/*
* klass->method_table[mid] = method_entry(defined_class, visi, def)
*
@@ -981,7 +982,12 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil
if (RB_TYPE_P(klass, T_MODULE) && FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
VALUE refined_class = rb_refinement_module_get_refined_class(klass);
+ bool search_superclass = type == VM_METHOD_TYPE_ZSUPER && !lookup_method_table(refined_class, mid);
rb_add_refined_method_entry(refined_class, mid);
+ if (search_superclass) {
+ rb_method_entry_t *me = lookup_method_table(refined_class, mid);
+ me->def->body.refined.orig_me = search_method0(refined_class, mid, NULL, true);
+ }
}
if (type == VM_METHOD_TYPE_REFINED) {
rb_method_entry_t *old_me = lookup_method_table(RCLASS_ORIGIN(klass), mid);