Make UBSan happy.

This involves avoiding signed multiplication overflow, shifting too
far and overflow during negation.

R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/382153003

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22351 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 0a5a0cc3
...@@ -1922,15 +1922,18 @@ Range* HMathFloorOfDiv::InferRange(Zone* zone) { ...@@ -1922,15 +1922,18 @@ Range* HMathFloorOfDiv::InferRange(Zone* zone) {
} }
// Returns the absolute value of its argument minus one, avoiding undefined
// behavior at kMinInt.
static int32_t AbsMinus1(int32_t a) { return a < 0 ? -(a + 1) : (a - 1); }
Range* HMod::InferRange(Zone* zone) { Range* HMod::InferRange(Zone* zone) {
if (representation().IsInteger32()) { if (representation().IsInteger32()) {
Range* a = left()->range(); Range* a = left()->range();
Range* b = right()->range(); Range* b = right()->range();
// The magnitude of the modulus is bounded by the right operand. Note that // The magnitude of the modulus is bounded by the right operand.
// apart for the cases involving kMinInt, the calculation below is the same int32_t positive_bound = Max(AbsMinus1(b->lower()), AbsMinus1(b->upper()));
// as Max(Abs(b->lower()), Abs(b->upper())) - 1.
int32_t positive_bound = -(Min(NegAbs(b->lower()), NegAbs(b->upper())) + 1);
// The result of the modulo operation has the sign of its left operand. // The result of the modulo operation has the sign of its left operand.
bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative(); bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative();
......
...@@ -7009,9 +7009,12 @@ RUNTIME_FUNCTION(Runtime_NumberImul) { ...@@ -7009,9 +7009,12 @@ RUNTIME_FUNCTION(Runtime_NumberImul) {
HandleScope scope(isolate); HandleScope scope(isolate);
ASSERT(args.length() == 2); ASSERT(args.length() == 2);
CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); // We rely on implementation-defined behavior below, but at least not on
CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); // undefined behavior.
return *isolate->factory()->NewNumberFromInt(x * y); CONVERT_NUMBER_CHECKED(uint32_t, x, Int32, args[0]);
CONVERT_NUMBER_CHECKED(uint32_t, y, Int32, args[1]);
int32_t product = static_cast<int32_t>(x * y);
return *isolate->factory()->NewNumberFromInt(product);
} }
......
...@@ -247,7 +247,7 @@ static bool DiyFpStrtod(Vector<const char> buffer, ...@@ -247,7 +247,7 @@ static bool DiyFpStrtod(Vector<const char> buffer,
const int kDenominator = 1 << kDenominatorLog; const int kDenominator = 1 << kDenominatorLog;
// Move the remaining decimals into the exponent. // Move the remaining decimals into the exponent.
exponent += remaining_decimals; exponent += remaining_decimals;
int error = (remaining_decimals == 0 ? 0 : kDenominator / 2); int64_t error = (remaining_decimals == 0 ? 0 : kDenominator / 2);
int old_e = input.e(); int old_e = input.e();
input.Normalize(); input.Normalize();
......
...@@ -140,13 +140,6 @@ T Abs(T a) { ...@@ -140,13 +140,6 @@ T Abs(T a) {
} }
// Returns the negative absolute value of its argument.
template <typename T>
T NegAbs(T a) {
return a < 0 ? a : -a;
}
// TODO(svenpanne) Clean up the whole power-of-2 mess. // TODO(svenpanne) Clean up the whole power-of-2 mess.
inline int32_t WhichPowerOf2Abs(int32_t x) { inline int32_t WhichPowerOf2Abs(int32_t x) {
return (x == kMinInt) ? 31 : WhichPowerOf2(Abs(x)); return (x == kMinInt) ? 31 : WhichPowerOf2(Abs(x));
......
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