summaryrefslogtreecommitdiff
path: root/internal.h
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-02-03 06:11:32 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-02-03 06:11:32 +0000
commitc2a6adc5fbd5953c0490eb9a53cd9ec15b7dec95 (patch)
treeffb6688ef3d4f0bdcb0296c9286b6aabc5b7a081 /internal.h
parent0db6b623a63003aad342739e66d81f957deff60c (diff)
internal.h: fix r57507
* internal.h (rb_overflowed_fix_to_int): invert sign bit. should not set LSB of fixnum value, which is always set, to MSB. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57509 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'internal.h')
-rw-r--r--internal.h10
1 files changed, 5 insertions, 5 deletions
diff --git a/internal.h b/internal.h
index 4ed1e41440..7d9250c886 100644
--- a/internal.h
+++ b/internal.h
@@ -348,10 +348,10 @@ VALUE rb_int128t2big(int128_t n);
#define ST2FIX(h) LONG2FIX((long)(h))
-static inline unsigned long
-rb_ulong_rotate_right(unsigned long x)
+static inline long
+rb_overflowed_fix_to_int(long x)
{
- return (x >> 1) | (x << (SIZEOF_LONG * CHAR_BIT - 1));
+ return (long)((unsigned long)(x >> 1) ^ (1LU << (SIZEOF_LONG * CHAR_BIT - 1)));
}
static inline VALUE
@@ -368,7 +368,7 @@ rb_fix_plus_fix(VALUE x, VALUE y)
* and it equals to `(z<<63)|(z>>1)` == `ror(z)`.
*/
if (__builtin_add_overflow((long)x, (long)y-1, &lz)) {
- return rb_int2big(rb_ulong_rotate_right((unsigned long)lz));
+ return rb_int2big(rb_overflowed_fix_to_int(lz));
}
else {
return (VALUE)lz;
@@ -385,7 +385,7 @@ rb_fix_minus_fix(VALUE x, VALUE y)
#ifdef HAVE_BUILTIN___BUILTIN_SUB_OVERFLOW
long lz;
if (__builtin_sub_overflow((long)x, (long)y-1, &lz)) {
- return rb_int2big(rb_ulong_rotate_right((unsigned long)lz));
+ return rb_int2big(rb_overflowed_fix_to_int(lz));
}
else {
return (VALUE)lz;