diff --git a/ChangeLog b/ChangeLog index 8f9ac7ded0..050f1415d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Sat Oct 22 22:33:32 2016 Nobuyoshi Nakada + + * numeric.c (num_funcall1): check recursion by inverse pair, to + fix fake infinite recursion. [ruby-core:77713] [Bug #12864] + Sat Oct 22 18:52:32 2016 Nobuyoshi Nakada * hash.c (rb_hash_compact_bang): should return nil if no elements diff --git a/numeric.c b/numeric.c index e288119318..7d4d9225e9 100644 --- a/numeric.c +++ b/numeric.c @@ -294,10 +294,10 @@ num_funcall0(VALUE x, ID func) } static VALUE -num_funcall_op_1(VALUE x, VALUE arg, int recursive) +num_funcall_op_1(VALUE y, VALUE arg, int recursive) { ID func = (ID)((VALUE *)arg)[0]; - VALUE y = ((VALUE *)arg)[1]; + VALUE x = ((VALUE *)arg)[1]; if (recursive) { const char *name = rb_id2name(func); if (ISALNUM(name[0])) { @@ -317,8 +317,8 @@ num_funcall1(VALUE x, ID func, VALUE y) { VALUE args[2]; args[0] = (VALUE)func; - args[1] = y; - return rb_exec_recursive_paired(num_funcall_op_1, x, y, (VALUE)args); + args[1] = x; + return rb_exec_recursive_paired(num_funcall_op_1, y, x, (VALUE)args); } /* diff --git a/test/ruby/test_numeric.rb b/test/ruby/test_numeric.rb index c5817c5efe..eb056f61c3 100644 --- a/test/ruby/test_numeric.rb +++ b/test/ruby/test_numeric.rb @@ -353,4 +353,31 @@ class TestNumeric < Test::Unit::TestCase assert_raise(ArgumentError) {1.remainder(x)} end; end + + def test_comparison_comparable + bug12864 = '[ruby-core:77713] [Bug #12864]' + + myinteger = Class.new do + include Comparable + + def initialize(i) + @i = i.to_i + end + attr_reader :i + + def <=>(other) + @i <=> (other.is_a?(self.class) ? other.i : other) + end + end + + all_assertions(bug12864) do |a| + [5, 2**62, 2**61].each do |i| + a.for("%#x"%i) do + m = myinteger.new(i) + assert_equal(i, m) + assert_equal(m, i) + end + end + end + end end