summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--range.c7
-rw-r--r--test/ruby/test_range.rb6
2 files changed, 9 insertions, 4 deletions
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