Bug #7290

Overriding method_added on a refinement's anonymous module can cause the opt_* opcodes to behave incorrectly

Added by Charlie Somerville over 1 year ago. Updated over 1 year ago.

[ruby-core:48970]
Status:Closed
Priority:Normal
Assignee:Shugo Maeda
Category:core
Target version:2.0.0
ruby -v:2.0.0-preview1 Backport:

Description

Ruby stores flags in (({rubyvmredefined_flag})) to track whether certain methods have been redefined on particular classes. If the redefined flag for a certain class and operator is not set, Ruby will skip method lookup and directly call the method implementing that operator.

The current implementation of refinements uses the (({method_added})) callback to set these flags. If this method is overridden, the flags are not set properly.

This code should raise a RuntimeError with the message "addition is not allowed". Instead it outputs "3". If line 3 is removed, it behaves correctly.

module Test
refine Fixnum do
def self.method_added(id); end

  def +(other)
    raise "addition is not allowed"
  end
end

end

using Test

puts 1 + 2

Associated revisions

Revision 37534
Added by Shugo Maeda over 1 year ago

  • eval.c (rbmodrefine): set RMODULEISREFINEMENT to a created
    refinement module, and don't override method_added.

  • vmmethod.c (rbmethodentrymake): check redefinition of
    optimized methods when a method is added to a refinement module.
    [Bug #7290]

  • test/ruby/test_refinement.rb: related test.

History

#1 Updated by Koichi Sasada over 1 year ago

  • Category set to core
  • Assignee set to Shugo Maeda
  • Target version set to 2.0.0

#2 Updated by Shugo Maeda over 1 year ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r37534.
Charlie, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • eval.c (rbmodrefine): set RMODULEISREFINEMENT to a created
    refinement module, and don't override method_added.

  • vmmethod.c (rbmethodentrymake): check redefinition of
    optimized methods when a method is added to a refinement module.
    [Bug #7290]

  • test/ruby/test_refinement.rb: related test.

Also available in: Atom PDF