Commit 4bd1215c authored by Bruce Dawson's avatar Bruce Dawson Committed by Commit Bot

Workaround VS/UCRT fmod bug

Recent versions of the Windows Universal CRT changed the behavior of
fmod for when the first parameter is negative. In particular, a result
of negative zero became positive zero. This is rarely critical but it
causes test failures and may effect some JS test suites or web pages.

The fix is to modify Modulo to check for a result of 0 when the first
parameter is negative and change the result to -0. That fixes four of
the five test failures and the fifth one is fixed by comparing the
results against Modulo instead of std::fmod.

Bug: chromium:915045
Change-Id: Ia4490ec98361a37006d6c338acd33f959fa3ccea
Reviewed-on: https://chromium-review.googlesource.com/c/1383091
Commit-Queue: Bruce Dawson <brucedawson@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58377}
parent 886713e7
......@@ -228,7 +228,11 @@ inline double Modulo(double x, double y) {
// dividend is a zero and divisor is nonzero finite => result equals dividend
if (!(std::isfinite(x) && (!std::isfinite(y) && !std::isnan(y))) &&
!(x == 0 && (y != 0 && std::isfinite(y)))) {
x = fmod(x, y);
double result = fmod(x, y);
// Workaround MS bug in VS CRT in some OS versions, https://crbug.com/915045
// fmod(-17, +/-1) should equal -0.0 but now returns 0.0.
if (x < 0 && result == 0) result = -0.0;
x = result;
}
return x;
#elif defined(V8_OS_AIX)
......
......@@ -241,7 +241,7 @@ static double BinaryOpC(Token::Value op, double lhs, double rhs) {
case Token::Value::DIV:
return lhs / rhs;
case Token::Value::MOD:
return std::fmod(lhs, rhs);
return Modulo(lhs, rhs);
case Token::Value::BIT_OR:
return (v8::internal::DoubleToInt32(lhs) |
v8::internal::DoubleToInt32(rhs));
......
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