mirror of
https://github.com/ruby/ruby.git
synced 2026-01-27 04:24:23 +00:00
Fix bad NameError raised using sendforward instruction through vcall
If you called a VCALL method and the method takes forwarding arguments and then you forward those arguments along using the sendforward instruction, the method_missing class was wrongly chosen as NameError instead of NoMethodError. This is because the VM looked at the CallInfo of the vcall and determined it needed to raise NameError. Now we detect that case and raise NoMethodError. [Backport #21535]
This commit is contained in:
parent
5a42d267bf
commit
0d367ce65f
@ -106,4 +106,32 @@ class TestNoMethodError < Test::Unit::TestCase
|
||||
|
||||
assert_match(/undefined method.+this_method_does_not_exist.+for.+Module/, err.to_s)
|
||||
end
|
||||
|
||||
def test_send_forward_raises
|
||||
t = EnvUtil.labeled_class("Test") do
|
||||
def foo(...)
|
||||
forward(...)
|
||||
end
|
||||
end
|
||||
obj = t.new
|
||||
assert_raise(NoMethodError) do
|
||||
obj.foo
|
||||
end
|
||||
end
|
||||
|
||||
# [Bug #21535]
|
||||
def test_send_forward_raises_when_called_through_vcall
|
||||
t = EnvUtil.labeled_class("Test") do
|
||||
def foo(...)
|
||||
forward(...)
|
||||
end
|
||||
def foo_indirect
|
||||
foo # vcall
|
||||
end
|
||||
end
|
||||
obj = t.new
|
||||
assert_raise(NoMethodError) do
|
||||
obj.foo_indirect
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -4185,7 +4185,7 @@ static enum method_missing_reason
|
||||
ci_missing_reason(const struct rb_callinfo *ci)
|
||||
{
|
||||
enum method_missing_reason stat = MISSING_NOENTRY;
|
||||
if (vm_ci_flag(ci) & VM_CALL_VCALL) stat |= MISSING_VCALL;
|
||||
if (vm_ci_flag(ci) & VM_CALL_VCALL && !(vm_ci_flag(ci) & VM_CALL_FORWARDING)) stat |= MISSING_VCALL;
|
||||
if (vm_ci_flag(ci) & VM_CALL_FCALL) stat |= MISSING_FCALL;
|
||||
if (vm_ci_flag(ci) & VM_CALL_SUPER) stat |= MISSING_SUPER;
|
||||
return stat;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user