mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Properly resolve refinements in defined? on private call [Bug #16932]
This commit is contained in:
parent
8340c773e5
commit
184f78314e
Notes:
git
2020-06-04 02:13:23 +09:00
4 changed files with 34 additions and 4 deletions
|
@ -95,6 +95,12 @@ MJIT_SYMBOL_EXPORT_BEGIN
|
|||
void rb_vm_search_method_slowpath(VALUE cd_owner, struct rb_call_data *cd, VALUE klass);
|
||||
MJIT_SYMBOL_EXPORT_END
|
||||
|
||||
/* vm_method.c */
|
||||
struct rb_execution_context_struct;
|
||||
MJIT_SYMBOL_EXPORT_BEGIN
|
||||
int rb_ec_obj_respond_to(struct rb_execution_context_struct *ec, VALUE obj, ID id, int priv);
|
||||
MJIT_SYMBOL_EXPORT_END
|
||||
|
||||
/* vm_dump.c */
|
||||
void rb_print_backtrace(void);
|
||||
|
||||
|
|
|
@ -309,24 +309,45 @@ class TestDefined < Test::Unit::TestCase
|
|||
refine RefinedClass do
|
||||
def pub
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def priv
|
||||
end
|
||||
end
|
||||
|
||||
def self.call_without_using(x = RefinedClass.new)
|
||||
defined?(x.pub)
|
||||
end
|
||||
|
||||
def self.vcall_without_using(x = RefinedClass.new)
|
||||
x.instance_eval {defined?(priv)}
|
||||
end
|
||||
|
||||
using self
|
||||
|
||||
def self.call_with_using(x = RefinedClass.new)
|
||||
defined?(x.pub)
|
||||
end
|
||||
|
||||
def self.vcall_with_using(x = RefinedClass.new)
|
||||
x.instance_eval {defined?(priv)}
|
||||
end
|
||||
end
|
||||
|
||||
def test_defined_refined_call_without_using
|
||||
assert(!RefiningModule.call_without_using, "refined public method without using")
|
||||
end
|
||||
|
||||
def test_defined_refined_vcall_without_using
|
||||
assert(!RefiningModule.vcall_without_using, "refined private method without using")
|
||||
end
|
||||
|
||||
def test_defined_refined_call_with_using
|
||||
assert(RefiningModule.call_with_using, "refined public method with using")
|
||||
end
|
||||
|
||||
def test_defined_refined_vcall_with_using
|
||||
assert(RefiningModule.vcall_with_using, "refined private method with using")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3651,12 +3651,9 @@ vm_defined(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, rb_num_t op_
|
|||
}
|
||||
case DEFINED_FUNC:
|
||||
klass = CLASS_OF(v);
|
||||
if (rb_method_boundp(klass, SYM2ID(obj), 0)) {
|
||||
if (rb_ec_obj_respond_to(ec, v, SYM2ID(obj), TRUE)) {
|
||||
expr_type = DEFINED_METHOD;
|
||||
}
|
||||
else {
|
||||
expr_type = check_respond_to_missing(obj, v);
|
||||
}
|
||||
break;
|
||||
case DEFINED_METHOD:{
|
||||
VALUE klass = CLASS_OF(v);
|
||||
|
|
|
@ -2358,6 +2358,12 @@ int
|
|||
rb_obj_respond_to(VALUE obj, ID id, int priv)
|
||||
{
|
||||
rb_execution_context_t *ec = GET_EC();
|
||||
return rb_ec_obj_respond_to(ec, obj, id, priv);
|
||||
}
|
||||
|
||||
int
|
||||
rb_ec_obj_respond_to(rb_execution_context_t *ec, VALUE obj, ID id, int priv)
|
||||
{
|
||||
VALUE klass = CLASS_OF(obj);
|
||||
int ret = vm_respond_to(ec, klass, obj, id, priv);
|
||||
if (ret == -1) ret = basic_obj_respond_to(ec, obj, id, !priv);
|
||||
|
|
Loading…
Add table
Reference in a new issue