ruby-changes:28550
From: nagachika <ko1@a...>
Date: Wed, 8 May 2013 01:49:15 +0900 (JST)
Subject: [ruby-changes:28550] nagachika:r40602 (ruby_2_0_0): merge revision(s) 40208: [Backport #8380]
nagachika 2013-05-08 01:49:01 +0900 (Wed, 08 May 2013) New Revision: 40602 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=40602 Log: merge revision(s) 40208: [Backport #8380] * internal.h (MUL_OVERFLOW_SIGNED_INTEGER_P): New macro. (MUL_OVERFLOW_FIXNUM_P): Ditto. (MUL_OVERFLOW_LONG_P): Ditto. * array.c (rb_ary_product): Don't overflow on signed integer multiplication. * numeric.c (fix_mul): Ditto. (int_pow): Ditto. * rational.c (f_imul): Ditto. * insns.def (opt_mult): Ditto. * thread.c (sleep_timeval): Don't overflow on signed integer addition. * bignum.c (rb_int2big): Don't overflow on signed integer negation. (rb_big2ulong): Ditto. (rb_big2long): Ditto. (rb_big2ull): Ditto. (rb_big2ll): Ditto. Modified directories: branches/ruby_2_0_0/ Modified files: branches/ruby_2_0_0/ChangeLog branches/ruby_2_0_0/array.c branches/ruby_2_0_0/bignum.c branches/ruby_2_0_0/insns.def branches/ruby_2_0_0/internal.h branches/ruby_2_0_0/numeric.c branches/ruby_2_0_0/rational.c branches/ruby_2_0_0/thread.c branches/ruby_2_0_0/version.h Index: ruby_2_0_0/array.c =================================================================== --- ruby_2_0_0/array.c (revision 40601) +++ ruby_2_0_0/array.c (revision 40602) @@ -5035,15 +5035,14 @@ rb_ary_product(int argc, VALUE *argv, VA https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/array.c#L5035 else { /* Compute the length of the result array; return [] if any is empty */ for (i = 0; i < n; i++) { - long k = RARRAY_LEN(arrays[i]), l = resultlen; + long k = RARRAY_LEN(arrays[i]); if (k == 0) { result = rb_ary_new2(0); goto done; } - resultlen *= k; - if (resultlen < k || resultlen < l || resultlen / k != l) { + if (MUL_OVERFLOW_LONG_P(resultlen, k)) rb_raise(rb_eRangeError, "too big to product"); - } + resultlen *= k; } result = rb_ary_new2(resultlen); } Index: ruby_2_0_0/ChangeLog =================================================================== --- ruby_2_0_0/ChangeLog (revision 40601) +++ ruby_2_0_0/ChangeLog (revision 40602) @@ -1,3 +1,27 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/ChangeLog#L1 +Wed May 8 01:18:41 2013 Tanaka Akira <akr@f...> + + * internal.h (MUL_OVERFLOW_SIGNED_INTEGER_P): New macro. + (MUL_OVERFLOW_FIXNUM_P): Ditto. + (MUL_OVERFLOW_LONG_P): Ditto. + + * array.c (rb_ary_product): Don't overflow on signed integer + multiplication. + + * numeric.c (fix_mul): Ditto. + (int_pow): Ditto. + + * rational.c (f_imul): Ditto. + + * insns.def (opt_mult): Ditto. + + * thread.c (sleep_timeval): Don't overflow on signed integer addition. + + * bignum.c (rb_int2big): Don't overflow on signed integer negation. + (rb_big2ulong): Ditto. + (rb_big2long): Ditto. + (rb_big2ull): Ditto. + (rb_big2ll): Ditto. + Tue May 7 20:13:12 2013 CHIKANAGA Tomoyuki <nagachika@r...> * test/ruby/test_thread.rb (invoke_rec): extend timeout 10 -> 50 sec, Index: ruby_2_0_0/insns.def =================================================================== --- ruby_2_0_0/insns.def (revision 40601) +++ ruby_2_0_0/insns.def (revision 40602) @@ -1418,16 +1418,13 @@ opt_mult https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/insns.def#L1418 val = recv; } else { - volatile long c; b = FIX2LONG(obj); - c = a * b; - - if (FIXABLE(c) && c / a == b) { - val = LONG2FIX(c); - } - else { + if (MUL_OVERFLOW_FIXNUM_P(a, b)) { val = rb_big_mul(rb_int2big(a), rb_int2big(b)); - } + } + else { + val = LONG2FIX(a * b); + } } } else if (FLONUM_2_P(recv, obj) && Index: ruby_2_0_0/thread.c =================================================================== --- ruby_2_0_0/thread.c (revision 40601) +++ ruby_2_0_0/thread.c (revision 40602) @@ -981,10 +981,17 @@ sleep_timeval(rb_thread_t *th, struct ti https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/thread.c#L981 enum rb_thread_status prev_status = th->status; getclockofday(&to); - to.tv_sec += tv.tv_sec; + if (TIMET_MAX - tv.tv_sec < to.tv_sec) + to.tv_sec = TIMET_MAX; + else + to.tv_sec += tv.tv_sec; if ((to.tv_usec += tv.tv_usec) >= 1000000) { - to.tv_sec++; - to.tv_usec -= 1000000; + if (to.tv_sec == TIMET_MAX) + to.tv_usec = 999999; + else { + to.tv_sec++; + to.tv_usec -= 1000000; + } } th->status = THREAD_STOPPED; Index: ruby_2_0_0/numeric.c =================================================================== --- ruby_2_0_0/numeric.c (revision 40601) +++ ruby_2_0_0/numeric.c (revision 40602) @@ -2694,7 +2694,6 @@ fix_mul(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/numeric.c#L2694 #if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG LONG_LONG d; #else - volatile long c; VALUE r; #endif @@ -2708,13 +2707,11 @@ fix_mul(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/numeric.c#L2707 #else if (FIT_SQRT_LONG(a) && FIT_SQRT_LONG(b)) return LONG2FIX(a*b); - c = a * b; - r = LONG2FIX(c); - if (a == 0) return x; - if (FIX2LONG(r) != c || c/a != b) { + if (MUL_OVERFLOW_FIXNUM_P(a, b)) r = rb_big_mul(rb_int2big(a), rb_int2big(b)); - } + else + r = LONG2FIX(a * b); return r; #endif } @@ -2936,11 +2933,10 @@ int_pow(long x, unsigned long y) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/numeric.c#L2933 y >>= 1; } { - volatile long xz = x * z; - if (!POSFIXABLE(xz) || xz / x != z) { + if (MUL_OVERFLOW_FIXNUM_P(x, z)) { goto bignum; } - z = xz; + z = x * z; } } while (--y); if (neg) z = -z; Index: ruby_2_0_0/internal.h =================================================================== --- ruby_2_0_0/internal.h (revision 40601) +++ ruby_2_0_0/internal.h (revision 40602) @@ -19,6 +19,15 @@ extern "C" { https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/internal.h#L19 #endif #endif +#define MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \ + (a) == 0 ? 0 : \ + (a) == -1 ? (b) < -(max) : \ + (a) > 0 ? \ + ((b) > 0 ? (max) / (a) < (b) : (min) / (a) > (b)) : \ + ((b) > 0 ? (min) / (a) < (b) : (max) / (a) > (b))) +#define MUL_OVERFLOW_FIXNUM_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, FIXNUM_MIN, FIXNUM_MAX) +#define MUL_OVERFLOW_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LONG_MIN, LONG_MAX) + struct rb_deprecated_classext_struct { char conflict[sizeof(VALUE) * 3]; }; Index: ruby_2_0_0/version.h =================================================================== --- ruby_2_0_0/version.h (revision 40601) +++ ruby_2_0_0/version.h (revision 40602) @@ -1,10 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/version.h#L1 #define RUBY_VERSION "2.0.0" -#define RUBY_RELEASE_DATE "2013-05-07" -#define RUBY_PATCHLEVEL 186 +#define RUBY_RELEASE_DATE "2013-05-08" +#define RUBY_PATCHLEVEL 187 #define RUBY_RELEASE_YEAR 2013 #define RUBY_RELEASE_MONTH 5 -#define RUBY_RELEASE_DAY 7 +#define RUBY_RELEASE_DAY 8 #include "ruby/version.h" Index: ruby_2_0_0/bignum.c =================================================================== --- ruby_2_0_0/bignum.c (revision 40601) +++ ruby_2_0_0/bignum.c (revision 40602) @@ -309,13 +309,17 @@ VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/bignum.c#L309 rb_int2big(SIGNED_VALUE n) { long neg = 0; + VALUE u; VALUE big; if (n < 0) { - n = -n; + u = 1 + (VALUE)(-(n + 1)); /* u = -n avoiding overflow */ neg = 1; } - big = rb_uint2big(n); + else { + u = n; + } + big = rb_uint2big(u); if (neg) { RBIGNUM_SET_SIGN(big, 0); } @@ -1222,12 +1226,15 @@ rb_big2ulong(VALUE x) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/bignum.c#L1226 { VALUE num = big2ulong(x, "unsigned long", TRUE); - if (!RBIGNUM_SIGN(x)) { - unsigned long v = (unsigned long)(-(long)num); - - if (v <= LONG_MAX) - rb_raise(rb_eRangeError, "bignum out of range of unsigned long"); - return (VALUE)v; + if (RBIGNUM_POSITIVE_P(x)) { + return num; + } + else { + if (num <= LONG_MAX) + return -(long)num; + if (num == 1+(unsigned long)(-(LONG_MIN+1))) + return LONG_MIN; + rb_raise(rb_eRangeError, "bignum out of range of unsigned long"); } return num; } @@ -1237,12 +1244,18 @@ rb_big2long(VALUE x) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/bignum.c#L1244 { VALUE num = big2ulong(x, "long", TRUE); - if ((long)num < 0 && - (RBIGNUM_SIGN(x) || (long)num != LONG_MIN)) { - rb_raise(rb_eRangeError, "bignum too big to convert into `long'"); + if (RBIGNUM_POSITIVE_P(x)) { + if (LONG_MAX < num) + rb_raise(rb_eRangeError, "bignum too big to convert into `long'"); + return num; + } + else { + if (num <= LONG_MAX) + return -(long)num; + if (num == 1+(unsigned long)(-(LONG_MIN+1))) + return LONG_MIN; + rb_raise(rb_eRangeError, "bignum too big to convert into `long'"); } - if (!RBIGNUM_SIGN(x)) return -(SIGNED_VALUE)num; - return num; } #if HAVE_LONG_LONG @@ -1270,13 +1283,15 @@ rb_big2ull(VALUE x) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/bignum.c#L1283 { unsigned LONG_LONG num = big2ull(x, "unsigned long long"); - if (!RBIGNUM_SIGN(x)) { - LONG_LONG v = -(LONG_LONG)num; - - /* FIXNUM_MIN-1 .. LLONG_MIN mapped into 0xbfffffffffffffff .. LONG_MAX+1 */ - if ((unsigned LONG_LONG)v <= LLONG_MAX) - rb_raise(rb_eRangeError, "bignum out of range of unsigned long long"); - return v; + if (RBIGNUM_POSITIVE_P(x)) { + return num; + } + else { + if (num <= LLONG_MAX) + return -(LONG_LONG)num; + if (num == 1+(unsigned LONG_LONG)(-(LLONG_MIN+1))) + return LLONG_MIN; + rb_raise(rb_eRangeError, "bignum out of range of unsigned long long"); } return num; } @@ -1286,12 +1301,18 @@ rb_big2ll(VALUE x) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/bignum.c#L1301 { unsigned LONG_LONG num = big2ull(x, "long long"); - if ((LONG_LONG)num < 0 && (RBIGNUM_SIGN(x) - || (LONG_LONG)num != LLONG_MIN)) { - rb_raise(rb_eRangeError, "bignum too big to convert into `long long'"); + if (RBIGNUM_POSITIVE_P(x)) { + if (LLONG_MAX < num) + rb_raise(rb_eRangeError, "bignum too big to convert into `long long'"); + return num; + } + else { + if (num <= LLONG_MAX) + return -(LONG_LONG)num; + if (num == 1+(unsigned LONG_LONG)(-(LLONG_MIN+1))) + return LLONG_MIN; + rb_raise(rb_eRangeError, "bignum too big to convert into `long long'"); } - if (!RBIGNUM_SIGN(x)) return -(LONG_LONG)num; - return num; } #endif /* HAVE_LONG_LONG */ Index: ruby_2_0_0/rational.c =================================================================== --- ruby_2_0_0/rational.c (revision 40601) +++ ruby_2_0_0/rational.c (revision 40602) @@ -639,7 +639,6 @@ inline static VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/rational.c#L639 f_imul(long a, long b) { VALUE r; - volatile long c; if (a == 0 || b == 0) return ZERO; @@ -648,10 +647,10 @@ f_imul(long a, long b) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/rational.c#L647 else if (b == 1) return LONG2NUM(a); - c = a * b; - r = LONG2NUM(c); - if (NUM2LONG(r) != c || (c / a) != b) + if (MUL_OVERFLOW_LONG_P(a, b)) r = rb_big_mul(rb_int2big(a), rb_int2big(b)); + else + r = LONG2NUM(a * b); return r; } Property changes on: ruby_2_0_0 ___________________________________________________________________ Modified: svn:mergeinfo Merged /trunk:r40208 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/