aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--numeric.c8
-rw-r--r--test/ruby/test_numeric.rb27
3 files changed, 36 insertions, 4 deletions
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 <nobu@ruby-lang.org>
+
+ * 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 <nobu@ruby-lang.org>
* 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