Commit 5befa0b4 authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[ubsan] Fix overflowing numeric conversions

Numeric conversions are defined behavior iff the value is in the
range of what the target type can represent.

Bug: v8:3770
Change-Id: Ic6f2276c64cb39345a45d8e37e604c28ecca34c2
Reviewed-on: https://chromium-review.googlesource.com/c/1436216
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59144}
parent a8aa4b4e
......@@ -22,7 +22,7 @@ namespace internal {
// See builtins-arraybuffer.cc for implementations of
// SharedArrayBuffer.prototye.byteLength and SharedArrayBuffer.prototype.slice
inline bool AtomicIsLockFree(uint32_t size) {
inline bool AtomicIsLockFree(double size) {
return size == 1 || size == 2 || size == 4;
}
......
......@@ -1395,8 +1395,7 @@ namespace {
bool IsFloat64RepresentableAsFloat32(const Float64Matcher& m) {
if (m.HasValue()) {
double v = m.Value();
float fv = static_cast<float>(v);
return static_cast<double>(fv) == v;
return DoubleToFloat32(v) == v;
}
return false;
}
......
......@@ -59,10 +59,10 @@ inline unsigned int FastD2UI(double x) {
inline float DoubleToFloat32(double x) {
// TODO(yangguo): This static_cast is implementation-defined behaviour in C++,
// so we may need to do the conversion manually instead to match the spec.
volatile float f = static_cast<float>(x);
return f;
typedef std::numeric_limits<float> limits;
if (x > limits::max()) return limits::infinity();
if (x < limits::lowest()) return -limits::infinity();
return static_cast<float>(x);
}
......
......@@ -56,11 +56,15 @@ Response toProtocolValue(v8::Local<v8::Context> context,
}
if (value->IsNumber()) {
double doubleValue = value.As<v8::Number>()->Value();
if (doubleValue >= std::numeric_limits<int>::min() &&
doubleValue <= std::numeric_limits<int>::max() &&
bit_cast<int64_t>(doubleValue) != bit_cast<int64_t>(-0.0)) {
int intValue = static_cast<int>(doubleValue);
if (intValue == doubleValue) {
*result = protocol::FundamentalValue::create(intValue);
return Response::OK();
}
}
*result = protocol::FundamentalValue::create(doubleValue);
return Response::OK();
}
......
......@@ -197,10 +197,7 @@ bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x,
return true;
}
case Token::EXP: {
double value = Pow(x_val, y_val);
int int_value = static_cast<int>(value);
*x = factory()->NewNumberLiteral(
int_value == value && value != -0.0 ? int_value : value, pos);
*x = factory()->NewNumberLiteral(Pow(x_val, y_val), pos);
return true;
}
default:
......
......@@ -3713,7 +3713,7 @@ TEST(RunFloat64Sub) {
TEST(RunFloat64Neg) {
BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
m.Return(m.AddNode(m.machine()->Float64Neg(), m.Parameter(0)));
FOR_FLOAT64_INPUTS(i) { CHECK_FLOAT_EQ(-0.0 - *i, m.Call(*i)); }
FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(-0.0 - *i, m.Call(*i)); }
}
TEST(RunFloat64Mul) {
......@@ -3918,7 +3918,7 @@ TEST(RunFloat64SubImm1) {
BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
m.Return(m.Float64Sub(m.Float64Constant(*i), m.Parameter(0)));
FOR_FLOAT64_INPUTS(j) { CHECK_FLOAT_EQ(*i - *j, m.Call(*j)); }
FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(*i - *j, m.Call(*j)); }
}
}
......@@ -3928,7 +3928,7 @@ TEST(RunFloat64SubImm2) {
BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
m.Return(m.Float64Sub(m.Parameter(0), m.Float64Constant(*i)));
FOR_FLOAT64_INPUTS(j) { CHECK_FLOAT_EQ(*j - *i, m.Call(*j)); }
FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(*j - *i, m.Call(*j)); }
}
}
......@@ -4044,7 +4044,7 @@ TEST(RunFloat64MulImm1) {
BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
m.Return(m.Float64Mul(m.Float64Constant(*i), m.Parameter(0)));
FOR_FLOAT64_INPUTS(j) { CHECK_FLOAT_EQ(*i * *j, m.Call(*j)); }
FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(*i * *j, m.Call(*j)); }
}
}
......@@ -4054,7 +4054,7 @@ TEST(RunFloat64MulImm2) {
BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
m.Return(m.Float64Mul(m.Parameter(0), m.Float64Constant(*i)));
FOR_FLOAT64_INPUTS(j) { CHECK_FLOAT_EQ(*j * *i, m.Call(*j)); }
FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(*j * *i, m.Call(*j)); }
}
}
......
......@@ -1218,7 +1218,7 @@ WASM_EXEC_TEST(Block_f) {
WASM_EXEC_TEST(Block_d) {
WasmRunner<double, double> r(execution_tier);
BUILD(r, WASM_BLOCK_D(WASM_GET_LOCAL(0)));
FOR_FLOAT64_INPUTS(i) { CHECK_FLOAT_EQ(*i, r.Call(*i)); }
FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(Block_br2) {
......@@ -1261,7 +1261,7 @@ WASM_EXEC_TEST(Loop_f) {
WASM_EXEC_TEST(Loop_d) {
WasmRunner<double, double> r(execution_tier);
BUILD(r, WASM_LOOP_D(WASM_GET_LOCAL(0)));
FOR_FLOAT64_INPUTS(i) { CHECK_FLOAT_EQ(*i, r.Call(*i)); }
FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(Loop_empty_br1) {
......
......@@ -511,7 +511,7 @@ class WasmRunner : public WasmRunnerBase {
CHECK_EQ(expected, Smi::ToInt(*result));
} else {
CHECK(result->IsHeapNumber());
CHECK_FLOAT_EQ(expected, HeapNumber::cast(*result)->value());
CHECK_DOUBLE_EQ(expected, HeapNumber::cast(*result)->value());
}
}
......
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