Update double-conversion library to 3.1.5

Part of the 5.14.0 third-party component update.

[ChangeLog][Third-Party Code] Updated double-conversion code to
upstream version 3.1.5.

Task-number: QTBUG-79418
Change-Id: I70c3890fcfa0606c462cc0fe702d0f62fd9c7279
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
Edward Welbourne 2019-10-23 15:20:10 +02:00
parent a9ac6c89be
commit 425df43d7f
6 changed files with 35 additions and 30 deletions

View File

@ -1,8 +0,0 @@
This is a copy of the library for binary-decimal and decimal-binary
conversion routines for IEEE doubles, available from
https://github.com/google/double-conversion
commit 2fb03de56faa32bbba5e02222528e7b760f71d77
See the LICENSE file for license information.

View File

@ -38,11 +38,6 @@
#include <double-conversion/strtod.h> #include <double-conversion/strtod.h>
#include <double-conversion/utils.h> #include <double-conversion/utils.h>
// Fix warning C4244: 'argument': conversion from 'const uc16' to 'char', possible loss of data
#ifdef _MSC_VER
__pragma(warning(disable: 4244))
#endif
namespace double_conversion { namespace double_conversion {
const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() { const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() {
@ -255,6 +250,12 @@ bool DoubleToStringConverter::ToExponential(
const int kDecimalRepCapacity = kMaxExponentialDigits + 2; const int kDecimalRepCapacity = kMaxExponentialDigits + 2;
ASSERT(kDecimalRepCapacity > kBase10MaximalLength); ASSERT(kDecimalRepCapacity > kBase10MaximalLength);
char decimal_rep[kDecimalRepCapacity]; char decimal_rep[kDecimalRepCapacity];
#ifndef NDEBUG
// Problem: there is an assert in StringBuilder::AddSubstring() that
// will pass this buffer to strlen(), and this buffer is not generally
// null-terminated.
memset(decimal_rep, 0, sizeof(decimal_rep));
#endif
int decimal_rep_length; int decimal_rep_length;
if (requested_digits == -1) { if (requested_digits == -1) {
@ -534,7 +535,7 @@ static double SignedZero(bool sign) {
// because it constant-propagated the radix and concluded that the last // because it constant-propagated the radix and concluded that the last
// condition was always true. By moving it into a separate function the // condition was always true. By moving it into a separate function the
// compiler wouldn't warn anymore. // compiler wouldn't warn anymore.
#if _MSC_VER #ifdef _MSC_VER
#pragma optimize("",off) #pragma optimize("",off)
static bool IsDecimalDigitForRadix(int c, int radix) { static bool IsDecimalDigitForRadix(int c, int radix) {
return '0' <= c && c <= '9' && (c - '0') < radix; return '0' <= c && c <= '9' && (c - '0') < radix;
@ -558,7 +559,7 @@ static bool IsCharacterDigitForRadix(int c, int radix, char a_character) {
// Returns true, when the iterator is equal to end. // Returns true, when the iterator is equal to end.
template<class Iterator> template<class Iterator>
static bool Advance (Iterator* it, char separator, int base, Iterator& end) { static bool Advance (Iterator* it, uc16 separator, int base, Iterator& end) {
if (separator == StringToDoubleConverter::kNoSeparator) { if (separator == StringToDoubleConverter::kNoSeparator) {
++(*it); ++(*it);
return *it == end; return *it == end;
@ -586,7 +587,7 @@ static bool Advance (Iterator* it, char separator, int base, Iterator& end) {
template<class Iterator> template<class Iterator>
static bool IsHexFloatString(Iterator start, static bool IsHexFloatString(Iterator start,
Iterator end, Iterator end,
char separator, uc16 separator,
bool allow_trailing_junk) { bool allow_trailing_junk) {
ASSERT(start != end); ASSERT(start != end);
@ -603,8 +604,8 @@ static bool IsHexFloatString(Iterator start,
saw_digit = true; saw_digit = true;
if (Advance(&current, separator, 16, end)) return false; if (Advance(&current, separator, 16, end)) return false;
} }
if (!saw_digit) return false; // Only the '.', but no digits.
} }
if (!saw_digit) return false;
if (*current != 'p' && *current != 'P') return false; if (*current != 'p' && *current != 'P') return false;
if (Advance(&current, separator, 16, end)) return false; if (Advance(&current, separator, 16, end)) return false;
if (*current == '+' || *current == '-') { if (*current == '+' || *current == '-') {
@ -627,7 +628,7 @@ template <int radix_log_2, class Iterator>
static double RadixStringToIeee(Iterator* current, static double RadixStringToIeee(Iterator* current,
Iterator end, Iterator end,
bool sign, bool sign,
char separator, uc16 separator,
bool parse_as_hex_float, bool parse_as_hex_float,
bool allow_trailing_junk, bool allow_trailing_junk,
double junk_string_value, double junk_string_value,
@ -762,7 +763,11 @@ static double RadixStringToIeee(Iterator* current,
} }
int written_exponent = 0; int written_exponent = 0;
while (IsDecimalDigitForRadix(**current, 10)) { while (IsDecimalDigitForRadix(**current, 10)) {
// No need to read exponents if they are too big. That could potentially overflow
// the `written_exponent` variable.
if (abs(written_exponent) <= 100 * Double::kMaxExponent) {
written_exponent = 10 * written_exponent + **current - '0'; written_exponent = 10 * written_exponent + **current - '0';
}
if (Advance(current, separator, radix, end)) break; if (Advance(current, separator, radix, end)) break;
} }
if (is_negative) written_exponent = -written_exponent; if (is_negative) written_exponent = -written_exponent;
@ -898,10 +903,11 @@ double StringToDoubleConverter::StringToIeee(
(*current == 'x' || *current == 'X')) { (*current == 'x' || *current == 'X')) {
++current; ++current;
if (current == end) return junk_string_value_; // "0x"
bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) && bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) &&
IsHexFloatString(current, end, separator_, allow_trailing_junk); IsHexFloatString(current, end, separator_, allow_trailing_junk);
if (current == end) return junk_string_value_; // "0x"
if (!parse_as_hex_float && !isDigit(*current, 16)) { if (!parse_as_hex_float && !isDigit(*current, 16)) {
return junk_string_value_; return junk_string_value_;
} }

View File

@ -1,4 +1,4 @@
INCLUDEPATH += $$PWD/.. $$PWD/include $$PWD/include/double-conversion INCLUDEPATH += $$PWD/.. $$PWD/include
SOURCES += \ SOURCES += \
$$PWD/bignum.cc \ $$PWD/bignum.cc \
$$PWD/bignum-dtoa.cc \ $$PWD/bignum-dtoa.cc \
@ -20,5 +20,3 @@ HEADERS += \
$$PWD/ieee.h \ $$PWD/ieee.h \
$$PWD/strtod.h \ $$PWD/strtod.h \
$$PWD/include/double-conversion/utils.h $$PWD/include/double-conversion/utils.h
OTHER_FILES += README

View File

@ -47,6 +47,8 @@ class Double {
static const uint64_t kHiddenBit = UINT64_2PART_C(0x00100000, 00000000); static const uint64_t kHiddenBit = UINT64_2PART_C(0x00100000, 00000000);
static const int kPhysicalSignificandSize = 52; // Excludes the hidden bit. static const int kPhysicalSignificandSize = 52; // Excludes the hidden bit.
static const int kSignificandSize = 53; static const int kSignificandSize = 53;
static const int kExponentBias = 0x3FF + kPhysicalSignificandSize;
static const int kMaxExponent = 0x7FF - kExponentBias;
Double() : d64_(0) {} Double() : d64_(0) {}
explicit Double(double d) : d64_(double_to_uint64(d)) {} explicit Double(double d) : d64_(double_to_uint64(d)) {}
@ -222,9 +224,7 @@ class Double {
} }
private: private:
static const int kExponentBias = 0x3FF + kPhysicalSignificandSize;
static const int kDenormalExponent = -kExponentBias + 1; static const int kDenormalExponent = -kExponentBias + 1;
static const int kMaxExponent = 0x7FF - kExponentBias;
static const uint64_t kInfinity = UINT64_2PART_C(0x7FF00000, 00000000); static const uint64_t kInfinity = UINT64_2PART_C(0x7FF00000, 00000000);
static const uint64_t kNaN = UINT64_2PART_C(0x7FF80000, 00000000); static const uint64_t kNaN = UINT64_2PART_C(0x7FF80000, 00000000);

View File

@ -56,6 +56,13 @@ inline void abort_noreturn() { abort(); }
#endif #endif
#endif #endif
#ifndef DOUBLE_CONVERSION_UNUSED
#ifdef __GNUC__
#define DOUBLE_CONVERSION_UNUSED __attribute__((unused))
#else
#define DOUBLE_CONVERSION_UNUSED
#endif
#endif
// Double operations detection based on target architecture. // Double operations detection based on target architecture.
// Linux uses a 80bit wide floating point stack on x86. This induces double // Linux uses a 80bit wide floating point stack on x86. This induces double
@ -91,10 +98,11 @@ int main(int argc, char** argv) {
defined(_POWER) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \ defined(_POWER) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
defined(__sparc__) || defined(__sparc) || defined(__s390__) || \ defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
defined(__SH4__) || defined(__alpha__) || \ defined(__SH4__) || defined(__alpha__) || \
defined(_MIPS_ARCH_MIPS32R2) || \ defined(_MIPS_ARCH_MIPS32R2) || defined(__ARMEB__) ||\
defined(__AARCH64EL__) || defined(__aarch64__) || defined(__AARCH64EB__) || \ defined(__AARCH64EL__) || defined(__aarch64__) || defined(__AARCH64EB__) || \
defined(__riscv) || defined(__EMSCRIPTEN__) || \ defined(__riscv) || \
defined(__or1k__) defined(__or1k__) || defined(__arc__) || \
defined(__EMSCRIPTEN__)
#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
#elif defined(__mc68000__) || \ #elif defined(__mc68000__) || \
defined(__pnacl__) || defined(__native_client__) defined(__pnacl__) || defined(__native_client__)
@ -343,6 +351,7 @@ inline Dest BitCast(const Source& source) {
static_assert(sizeof(Dest) == sizeof(Source), static_assert(sizeof(Dest) == sizeof(Source),
"source and destination size mismatch"); "source and destination size mismatch");
#else #else
DOUBLE_CONVERSION_UNUSED
typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1]; typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
#endif #endif

View File

@ -5,8 +5,8 @@
"QtUsage": "Used in Qt Core. Configure with -system-doubleconversion or -no-doubleconversion to avoid.", "QtUsage": "Used in Qt Core. Configure with -system-doubleconversion or -no-doubleconversion to avoid.",
"Homepage": "https://github.com/google/double-conversion", "Homepage": "https://github.com/google/double-conversion",
"Version": "3.1.1", "Version": "3.1.5",
"DownloadLocation": "https://github.com/google/double-conversion/commit/4199ef3d456ed0549e5665cf4186f0ee6210db3b", "DownloadLocation": "https://github.com/google/double-conversion/commit/5fa81e88ef24e735b4283b8f7454dc59693ac1fc",
"License": "BSD 3-clause \"New\" or \"Revised\" License", "License": "BSD 3-clause \"New\" or \"Revised\" License",
"LicenseId": "BSD-3-Clause", "LicenseId": "BSD-3-Clause",
"LicenseFile": "LICENSE", "LicenseFile": "LICENSE",