From 4d40f09a45202dff901d4f970a6a7e939797138b Mon Sep 17 00:00:00 2001 From: Thomas Miller Date: Wed, 19 Sep 2018 10:53:16 -0700 Subject: Upgrade double-conversion to v3.1.1 Utils.h now includes defines for _M_ARM and _M_ARM64 to enable compilation on Windows arm and arm64. The locally added __ghs and __EMSCRIPTEN__ clauses are preserved. [ChangeLog][Third-Party Code] double-conversion got updated to upstream version 3.1.1. Task-number: QTBUG-70008 Change-Id: Ie5411ee8d9cb32c39d7dca5a2262e6b3854732a5 Reviewed-by: Ulf Hermann --- src/3rdparty/double-conversion/strtod.cc | 49 ++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 12 deletions(-) (limited to 'src/3rdparty/double-conversion/strtod.cc') diff --git a/src/3rdparty/double-conversion/strtod.cc b/src/3rdparty/double-conversion/strtod.cc index 17abcbb2a5..e8cc13f2de 100644 --- a/src/3rdparty/double-conversion/strtod.cc +++ b/src/3rdparty/double-conversion/strtod.cc @@ -25,13 +25,13 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include -#include +#include +#include -#include "strtod.h" -#include "bignum.h" -#include "cached-powers.h" -#include "ieee.h" +#include +#include +#include +#include namespace double_conversion { @@ -205,7 +205,7 @@ static bool DoubleStrtod(Vector trimmed, // Note that the ARM simulator is compiled for 32bits. It therefore exhibits // the same problem. return false; -#endif +#else if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) { int read_digits; // The trimmed input fits into a double. @@ -243,6 +243,7 @@ static bool DoubleStrtod(Vector trimmed, } } return false; +#endif } @@ -471,6 +472,30 @@ double Strtod(Vector buffer, int exponent) { } } +static float SanitizedDoubletof(double d) { + ASSERT(d >= 0.0); + // ASAN has a sanitize check that disallows casting doubles to floats if + // they are too big. + // https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#available-checks + // The behavior should be covered by IEEE 754, but some projects use this + // flag, so work around it. + float max_finite = 3.4028234663852885981170418348451692544e+38; + // The half-way point between the max-finite and infinity value. + // Since infinity has an even significand everything equal or greater than + // this value should become infinity. + double half_max_finite_infinity = + 3.40282356779733661637539395458142568448e+38; + if (d >= max_finite) { + if (d >= half_max_finite_infinity) { + return Single::Infinity(); + } else { + return max_finite; + } + } else { + return static_cast(d); + } +} + float Strtof(Vector buffer, int exponent) { char copy_buffer[kMaxSignificantDecimalDigits]; Vector trimmed; @@ -482,7 +507,7 @@ float Strtof(Vector buffer, int exponent) { double double_guess; bool is_correct = ComputeGuess(trimmed, exponent, &double_guess); - float float_guess = static_cast(double_guess); + float float_guess = SanitizedDoubletof(double_guess); if (float_guess == double_guess) { // This shortcut triggers for integer values. return float_guess; @@ -505,15 +530,15 @@ float Strtof(Vector buffer, int exponent) { double double_next = Double(double_guess).NextDouble(); double double_previous = Double(double_guess).PreviousDouble(); - float f1 = static_cast(double_previous); + float f1 = SanitizedDoubletof(double_previous); float f2 = float_guess; - float f3 = static_cast(double_next); + float f3 = SanitizedDoubletof(double_next); float f4; if (is_correct) { f4 = f3; } else { double double_next2 = Double(double_next).NextDouble(); - f4 = static_cast(double_next2); + f4 = SanitizedDoubletof(double_next2); } (void) f2; // Mark variable as used. ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4); @@ -528,7 +553,7 @@ float Strtof(Vector buffer, int exponent) { (f1 == f2 && f2 != f3 && f3 == f4) || (f1 == f2 && f2 == f3 && f3 != f4)); - // guess and next are the two possible canditates (in the same way that + // guess and next are the two possible candidates (in the same way that // double_guess was the lower candidate for a double-precision guess). float guess = f1; float next = f4; -- cgit v1.2.3