diff --git a/range.c b/range.c index fb3a4cbaff..71d81fa6c4 100644 --- a/range.c +++ b/range.c @@ -402,11 +402,10 @@ range_step(int argc, VALUE *argv, VALUE range) if (FIXNUM_P(b) && NIL_P(e) && FIXNUM_P(step)) { long i = FIX2LONG(b), unit = FIX2LONG(step); - while (1) { + do { rb_yield(LONG2FIX(i)); - if (i + unit < i) break; - i += unit; - } + i += unit; /* FIXABLE+FIXABLE never overflow */ + } while (FIXABLE(i)); b = LONG2NUM(i); for (;; b = rb_funcallv(b, id_succ, 0, 0)) diff --git a/test/ruby/test_range.rb b/test/ruby/test_range.rb index 84319d7d42..dbfe495f29 100644 --- a/test/ruby/test_range.rb +++ b/test/ruby/test_range.rb @@ -3,6 +3,7 @@ require 'test/unit' require 'delegate' require 'timeout' require 'bigdecimal' +require 'rbconfig/sizeof' class TestRange < Test::Unit::TestCase def test_new @@ -244,6 +245,11 @@ class TestRange < Test::Unit::TestCase (2**32-1 .. ).step(2) {|x| a << x; break if a.size == 2 } assert_equal([4294967295, 4294967297], a) + a = [] + max = RbConfig::LIMITS["FIXNUM_MAX"] + (max..).step {|x| a << x; break if a.size == 2 } + assert_equal([max, max+1], a) + o1 = Object.new o2 = Object.new def o1.<=>(x); -1; end