Commit ef95dcd3 authored by murase_syuka's avatar murase_syuka

Bugfix nagative-number lshift() bit overflow

parent 557ab347
......@@ -821,15 +821,28 @@ static mrb_value
lshift(mrb_state *mrb, mrb_int val, mrb_int width)
{
mrb_assert(width > 0);
if ((width > NUMERIC_SHIFT_WIDTH_MAX) ||
(val > (MRB_INT_MAX >> width))) {
if (val > 0) {
if ((width > NUMERIC_SHIFT_WIDTH_MAX) ||
(val > (MRB_INT_MAX >> width))) {
goto bit_overflow;
}
} else {
if ((width > NUMERIC_SHIFT_WIDTH_MAX) ||
(val < (MRB_INT_MIN >> width))) {
goto bit_overflow;
}
}
return mrb_fixnum_value(val << width);
bit_overflow:
{
mrb_float f = (mrb_float)val;
while (width--) {
f *= 2;
}
return mrb_float_value(mrb, f);
}
return mrb_fixnum_value(val << width);
}
static mrb_value
......
......@@ -150,6 +150,9 @@ assert('Integer#<<', '15.2.8.3.12') do
# Left Shift by 31 is bitShift overflow to SignedInt
assert_equal 2147483648, 1 << 31
# -3 Left Shift by 30 is bitShift overflow to SignedInt
assert_equal -3221225472, -3 << 30
end
assert('Integer#>>', '15.2.8.3.13') do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment