3rdparty: Update double-conversion

The old patch is removed but another was needed to fix a warning from
MSVC about truncation which is taken from
e634f265db5d296bd7a780f9813d6b8573f5bd90 in the master branch.

Since there is no other changes to the double-conversion directory
between 3.2.0 and that change we are essentially using that commit
directly.

Pick-to: 6.3
Fixes: QTBUG-100988
Change-Id: Ia69f39f61ef989907fdf097f897bece0b3af7194
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Kai Koehne <kai.koehne@qt.io>
bb10
Mårten Nordheim 2022-02-17 18:01:52 +01:00
parent 04f49e6881
commit b1d8fb3279
14 changed files with 162 additions and 72 deletions

View File

@ -276,7 +276,7 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
// Let v = numerator / denominator < 10.
// Then we generate 'count' digits of d = x.xxxxx... (without the decimal point)
// from left to right. Once 'count' digits have been produced we decide wether
// from left to right. Once 'count' digits have been produced we decide whether
// to round up or down. Remainders of exactly .5 round upwards. Numbers such
// as 9.999999 propagate a carry all the way, and change the
// exponent (decimal_point), when rounding upwards.

View File

@ -136,7 +136,7 @@ void Bignum::AssignHexString(Vector<const char> value) {
DOUBLE_CONVERSION_ASSERT(sizeof(uint64_t) * 8 >= kBigitSize + 4); // TODO: static_assert
// Accumulates converted hex digits until at least kBigitSize bits.
// Works with non-factor-of-four kBigitSizes.
uint64_t tmp = 0; // Accumulates converted hex digits until at least
uint64_t tmp = 0;
for (int cnt = 0; !value.is_empty(); value.pop_back()) {
tmp |= (HexCharValue(value.last()) << cnt);
if ((cnt += 4) >= kBigitSize) {
@ -146,7 +146,8 @@ void Bignum::AssignHexString(Vector<const char> value) {
}
}
if (tmp > 0) {
RawBigit(used_bigits_++) = tmp;
DOUBLE_CONVERSION_ASSERT(tmp <= kBigitMask);
RawBigit(used_bigits_++) = (tmp & kBigitMask);
}
Clamp();
}

View File

@ -38,7 +38,7 @@ class DoubleToStringConverter {
// or a requested_digits parameter > kMaxFixedDigitsAfterPoint then the
// function returns false.
static const int kMaxFixedDigitsBeforePoint = 60;
static const int kMaxFixedDigitsAfterPoint = 60;
static const int kMaxFixedDigitsAfterPoint = 100;
// When calling ToExponential with a requested_digits
// parameter > kMaxExponentialDigits then the function returns false.
@ -123,7 +123,7 @@ class DoubleToStringConverter {
// Example with max_leading_padding_zeroes_in_precision_mode = 6.
// ToPrecision(0.0000012345, 2) -> "0.0000012"
// ToPrecision(0.00000012345, 2) -> "1.2e-7"
// Similarily the converter may add up to
// Similarly the converter may add up to
// max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid
// returning an exponential representation. A zero added by the
// EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit.
@ -181,7 +181,7 @@ class DoubleToStringConverter {
// Example with decimal_in_shortest_low = -6,
// decimal_in_shortest_high = 21,
// EMIT_POSITIVE_EXPONENT_SIGN activated, and
// EMIT_TRAILING_DECIMAL_POINT deactived:
// EMIT_TRAILING_DECIMAL_POINT deactivated:
// ToShortest(0.000001) -> "0.000001"
// ToShortest(0.0000001) -> "1e-7"
// ToShortest(111111111111111111111.0) -> "111111111111111110000"
@ -305,7 +305,7 @@ class DoubleToStringConverter {
// Example with max_leading_padding_zeroes_in_precision_mode = 6.
// ToPrecision(0.0000012345, 2) -> "0.0000012"
// ToPrecision(0.00000012345, 2) -> "1.2e-7"
// Similarily the converter may add up to
// Similarly the converter may add up to
// max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid
// returning an exponential representation. A zero added by the
// EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit.

View File

@ -565,7 +565,7 @@ static bool Grisu3(double v,
// the difference between w and boundary_minus/plus (a power of 2) and to
// compute scaled_boundary_minus/plus by subtracting/adding from
// scaled_w. However the code becomes much less readable and the speed
// enhancements are not terriffic.
// enhancements are not terrific.
DiyFp scaled_boundary_minus = DiyFp::Times(boundary_minus, ten_mk);
DiyFp scaled_boundary_plus = DiyFp::Times(boundary_plus, ten_mk);
@ -573,7 +573,7 @@ static bool Grisu3(double v,
// v == (double) (scaled_w * 10^-mk).
// Set decimal_exponent == -mk and pass it to DigitGen. If scaled_w is not an
// integer than it will be updated. For instance if scaled_w == 1.23 then
// the buffer will be filled with "123" und the decimal_exponent will be
// the buffer will be filled with "123" and the decimal_exponent will be
// decreased by 2.
int kappa;
bool result = DigitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus,

View File

@ -395,8 +395,8 @@ bool FastFixedDtoa(double v,
TrimZeros(buffer, length, decimal_point);
buffer[*length] = '\0';
if ((*length) == 0) {
// The string is empty and the decimal_point thus has no importance. Mimick
// Gay's dtoa and and set it to -fractional_count.
// The string is empty and the decimal_point thus has no importance. Mimic
// Gay's dtoa and set it to -fractional_count.
*decimal_point = -fractional_count;
}
return true;

View File

@ -150,11 +150,19 @@ class Double {
}
bool IsQuietNan() const {
#if (defined(__mips__) && !defined(__mips_nan2008)) || defined(__hppa__)
return IsNan() && ((AsUint64() & kQuietNanBit) == 0);
#else
return IsNan() && ((AsUint64() & kQuietNanBit) != 0);
#endif
}
bool IsSignalingNan() const {
#if (defined(__mips__) && !defined(__mips_nan2008)) || defined(__hppa__)
return IsNan() && ((AsUint64() & kQuietNanBit) != 0);
#else
return IsNan() && ((AsUint64() & kQuietNanBit) == 0);
#endif
}
@ -236,7 +244,12 @@ class Double {
private:
static const int kDenormalExponent = -kExponentBias + 1;
static const uint64_t kInfinity = DOUBLE_CONVERSION_UINT64_2PART_C(0x7FF00000, 00000000);
#if (defined(__mips__) && !defined(__mips_nan2008)) || defined(__hppa__)
static const uint64_t kNaN = DOUBLE_CONVERSION_UINT64_2PART_C(0x7FF7FFFF, FFFFFFFF);
#else
static const uint64_t kNaN = DOUBLE_CONVERSION_UINT64_2PART_C(0x7FF80000, 00000000);
#endif
const uint64_t d64_;
@ -336,11 +349,19 @@ class Single {
}
bool IsQuietNan() const {
#if (defined(__mips__) && !defined(__mips_nan2008)) || defined(__hppa__)
return IsNan() && ((AsUint32() & kQuietNanBit) == 0);
#else
return IsNan() && ((AsUint32() & kQuietNanBit) != 0);
#endif
}
bool IsSignalingNan() const {
#if (defined(__mips__) && !defined(__mips_nan2008)) || defined(__hppa__)
return IsNan() && ((AsUint32() & kQuietNanBit) != 0);
#else
return IsNan() && ((AsUint32() & kQuietNanBit) == 0);
#endif
}
@ -410,7 +431,11 @@ class Single {
static const int kDenormalExponent = -kExponentBias + 1;
static const int kMaxExponent = 0xFF - kExponentBias;
static const uint32_t kInfinity = 0x7F800000;
#if (defined(__mips__) && !defined(__mips_nan2008)) || defined(__hppa__)
static const uint32_t kNaN = 0x7FBFFFFF;
#else
static const uint32_t kNaN = 0x7FC00000;
#endif
const uint32_t d32_;

View File

@ -729,11 +729,17 @@ double StringToDoubleConverter::StringToIeee(
DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize);
buffer[buffer_pos] = '\0';
// Code above ensures there are no leading zeros and the buffer has fewer than
// kMaxSignificantDecimalDigits characters. Trim trailing zeros.
Vector<const char> chars(buffer, buffer_pos);
chars = TrimTrailingZeros(chars);
exponent += buffer_pos - chars.length();
double converted;
if (read_as_double) {
converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
converted = StrtodTrimmed(chars, exponent);
} else {
converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent);
converted = StrtofTrimmed(chars, exponent);
}
*processed_characters_count = static_cast<int>(current - input);
return sign? -converted: converted;
@ -773,4 +779,40 @@ float StringToDoubleConverter::StringToFloat(
processed_characters_count));
}
template<>
double StringToDoubleConverter::StringTo<double>(
const char* buffer,
int length,
int* processed_characters_count) const {
return StringToDouble(buffer, length, processed_characters_count);
}
template<>
float StringToDoubleConverter::StringTo<float>(
const char* buffer,
int length,
int* processed_characters_count) const {
return StringToFloat(buffer, length, processed_characters_count);
}
template<>
double StringToDoubleConverter::StringTo<double>(
const uc16* buffer,
int length,
int* processed_characters_count) const {
return StringToDouble(buffer, length, processed_characters_count);
}
template<>
float StringToDoubleConverter::StringTo<float>(
const uc16* buffer,
int length,
int* processed_characters_count) const {
return StringToFloat(buffer, length, processed_characters_count);
}
} // namespace double_conversion

View File

@ -86,7 +86,7 @@ class StringToDoubleConverter {
// This *must* start with "0x" and separate the exponent with "p".
// Examples: 0x1.2p3 == 9.0
// 0x10.1p0 == 16.0625
// ALLOW_HEX and ALLOW_HEX_FLOATS are indendent.
// ALLOW_HEX and ALLOW_HEX_FLOATS are indented.
//
// empty_string_value is returned when an empty string is given as input.
// If ALLOW_LEADING_SPACES or ALLOW_TRAILING_SPACES are set, then a string
@ -204,6 +204,18 @@ class StringToDoubleConverter {
int length,
int* processed_characters_count) const;
// Same as StringToDouble for T = double, and StringToFloat for T = float.
template <typename T>
T StringTo(const char* buffer,
int length,
int* processed_characters_count) const;
// Same as StringTo above but for 16 bit characters.
template <typename T>
T StringTo(const uc16* buffer,
int length,
int* processed_characters_count) const;
private:
const int flags_;
const double empty_string_value_;

View File

@ -101,17 +101,6 @@ static Vector<const char> TrimLeadingZeros(Vector<const char> buffer) {
return Vector<const char>(buffer.start(), 0);
}
static Vector<const char> TrimTrailingZeros(Vector<const char> buffer) {
for (int i = buffer.length() - 1; i >= 0; --i) {
if (buffer[i] != '0') {
return buffer.SubVector(0, i + 1);
}
}
return Vector<const char>(buffer.start(), 0);
}
static void CutToMaxSignificantDigits(Vector<const char> buffer,
int exponent,
char* significant_buffer,
@ -536,6 +525,12 @@ float Strtof(Vector<const char> buffer, int exponent) {
TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits,
&trimmed, &updated_exponent);
exponent = updated_exponent;
return StrtofTrimmed(trimmed, exponent);
}
float StrtofTrimmed(Vector<const char> trimmed, int exponent) {
DOUBLE_CONVERSION_ASSERT(trimmed.length() <= kMaxSignificantDecimalDigits);
DOUBLE_CONVERSION_ASSERT(AssertTrimmedDigits(trimmed));
double double_guess;
bool is_correct = ComputeGuess(trimmed, exponent, &double_guess);
@ -555,7 +550,7 @@ float Strtof(Vector<const char> buffer, int exponent) {
// low-precision (3 digits):
// when read from input: 123
// when rounded from high precision: 124.
// To do this we simply look at the neigbors of the correct result and see
// To do this we simply look at the neighbors of the correct result and see
// if they would round to the same float. If the guess is not correct we have
// to look at four values (since two different doubles could be the correct
// double).

View File

@ -40,11 +40,25 @@ double Strtod(Vector<const char> buffer, int exponent);
// contain a dot or a sign. It must not start with '0', and must not be empty.
float Strtof(Vector<const char> buffer, int exponent);
// For special use cases, the heart of the Strtod() function is also available
// separately, it assumes that 'trimmed' is as produced by TrimAndCut(), i.e.
// no leading or trailing zeros, also no lone zero, and not 'too many' digits.
// Same as Strtod, but assumes that 'trimmed' is already trimmed, as if run
// through TrimAndCut. That is, 'trimmed' must have no leading or trailing
// zeros, must not be a lone zero, and must not have 'too many' digits.
double StrtodTrimmed(Vector<const char> trimmed, int exponent);
// Same as Strtof, but assumes that 'trimmed' is already trimmed, as if run
// through TrimAndCut. That is, 'trimmed' must have no leading or trailing
// zeros, must not be a lone zero, and must not have 'too many' digits.
float StrtofTrimmed(Vector<const char> trimmed, int exponent);
inline Vector<const char> TrimTrailingZeros(Vector<const char> buffer) {
for (int i = buffer.length() - 1; i >= 0; --i) {
if (buffer[i] != '0') {
return buffer.SubVector(0, i + 1);
}
}
return Vector<const char>(buffer.start(), 0);
}
} // namespace double_conversion
#endif // DOUBLE_CONVERSION_STRTOD_H_

View File

@ -28,17 +28,28 @@
#ifndef DOUBLE_CONVERSION_UTILS_H_
#define DOUBLE_CONVERSION_UTILS_H_
// Use DOUBLE_CONVERSION_NON_PREFIXED_MACROS to get unprefixed macros as was
// the case in double-conversion releases prior to 3.1.6
#include <cstdlib>
#include <cstring>
#include <cassert>
#ifndef DOUBLE_CONVERSION_ASSERT
#define DOUBLE_CONVERSION_ASSERT(condition) \
assert(condition);
assert(condition)
#endif
#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(ASSERT)
#define ASSERT DOUBLE_CONVERSION_ASSERT
#endif
#ifndef DOUBLE_CONVERSION_UNIMPLEMENTED
#define DOUBLE_CONVERSION_UNIMPLEMENTED() (abort())
#endif
#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(UNIMPLEMENTED)
#define UNIMPLEMENTED DOUBLE_CONVERSION_UNIMPLEMENTED
#endif
#ifndef DOUBLE_CONVERSION_NO_RETURN
#ifdef _MSC_VER
#define DOUBLE_CONVERSION_NO_RETURN __declspec(noreturn)
@ -46,6 +57,10 @@
#define DOUBLE_CONVERSION_NO_RETURN __attribute__((noreturn))
#endif
#endif
#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(NO_RETURN)
#define NO_RETURN DOUBLE_CONVERSION_NO_RETURN
#endif
#ifndef DOUBLE_CONVERSION_UNREACHABLE
#ifdef _MSC_VER
void DOUBLE_CONVERSION_NO_RETURN abort_noreturn();
@ -55,6 +70,9 @@ inline void abort_noreturn() { abort(); }
#define DOUBLE_CONVERSION_UNREACHABLE() (abort())
#endif
#endif
#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(UNREACHABLE)
#define UNREACHABLE DOUBLE_CONVERSION_UNREACHABLE
#endif
// Not all compilers support __has_attribute and combining a check for both
// ifdef and __has_attribute on the same preprocessor line isn't portable.
@ -71,12 +89,18 @@ inline void abort_noreturn() { abort(); }
#define DOUBLE_CONVERSION_UNUSED
#endif
#endif
#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(UNUSED)
#define UNUSED DOUBLE_CONVERSION_UNUSED
#endif
#if DOUBLE_CONVERSION_HAS_ATTRIBUTE(uninitialized)
#define DOUBLE_CONVERSION_STACK_UNINITIALIZED __attribute__((uninitialized))
#else
#define DOUBLE_CONVERSION_STACK_UNINITIALIZED
#endif
#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(STACK_UNINITIALIZED)
#define STACK_UNINITIALIZED DOUBLE_CONVERSION_STACK_UNINITIALIZED
#endif
// Double operations detection based on target architecture.
// Linux uses a 80bit wide floating point stack on x86. This induces double
@ -108,6 +132,7 @@ int main(int argc, char** argv) {
defined(__ARMEL__) || defined(__avr32__) || defined(_M_ARM) || defined(_M_ARM64) || \
defined(__hppa__) || defined(__ia64__) || \
defined(__mips__) || \
defined(__loongarch__) || \
defined(__nios2__) || defined(__ghs) || \
defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
defined(_POWER) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
@ -116,7 +141,7 @@ int main(int argc, char** argv) {
defined(_MIPS_ARCH_MIPS32R2) || defined(__ARMEB__) ||\
defined(__AARCH64EL__) || defined(__aarch64__) || defined(__AARCH64EB__) || \
defined(__riscv) || defined(__e2k__) || \
defined(__or1k__) || defined(__arc__) || \
defined(__or1k__) || defined(__arc__) || defined(__ARC64__) || \
defined(__microblaze__) || defined(__XTENSA__) || \
defined(__EMSCRIPTEN__) || defined(__wasm32__)
#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
@ -133,6 +158,9 @@ int main(int argc, char** argv) {
#else
#error Target architecture was not detected as supported by Double-Conversion.
#endif
#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(CORRECT_DOUBLE_OPERATIONS)
#define CORRECT_DOUBLE_OPERATIONS DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
#endif
#if defined(_WIN32) && !defined(__MINGW32__)
@ -158,7 +186,9 @@ typedef uint16_t uc16;
// Usage: instead of writing 0x1234567890123456
// write DOUBLE_CONVERSION_UINT64_2PART_C(0x12345678,90123456);
#define DOUBLE_CONVERSION_UINT64_2PART_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(UINT64_2PART_C)
#define UINT64_2PART_C DOUBLE_CONVERSION_UINT64_2PART_C
#endif
// The expression DOUBLE_CONVERSION_ARRAY_SIZE(a) is a compile-time constant of type
// size_t which represents the number of elements of the given
@ -169,6 +199,9 @@ typedef uint16_t uc16;
((sizeof(a) / sizeof(*(a))) / \
static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
#endif
#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(ARRAY_SIZE)
#define ARRAY_SIZE DOUBLE_CONVERSION_ARRAY_SIZE
#endif
// A macro to disallow the evil copy constructor and operator= functions
// This should be used in the private: declarations for a class
@ -177,6 +210,9 @@ typedef uint16_t uc16;
TypeName(const TypeName&); \
void operator=(const TypeName&)
#endif
#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(DC_DISALLOW_COPY_AND_ASSIGN)
#define DC_DISALLOW_COPY_AND_ASSIGN DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN
#endif
// A macro to disallow all the implicit constructors, namely the
// default constructor, copy constructor and operator= functions.
@ -189,6 +225,9 @@ typedef uint16_t uc16;
TypeName(); \
DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(TypeName)
#endif
#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(DC_DISALLOW_IMPLICIT_CONSTRUCTORS)
#define DC_DISALLOW_IMPLICIT_CONSTRUCTORS DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS
#endif
namespace double_conversion {

View File

@ -1,29 +0,0 @@
From 56a9da33eccb6ed0b6d9f99301a271ca5cd6edfa Mon Sep 17 00:00:00 2001
From: Edward Welbourne <edward.welbourne@qt.io>
Date: Wed, 27 Jan 2021 15:27:05 +0100
Subject: [PATCH] Avoid unused function warning for AssertTrimmedDigits()
It's only used in an assertion, hence it's unused when assertions are off.
---
double-conversion/strtod.cc | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/double-conversion/strtod.cc b/double-conversion/strtod.cc
index 850bcda..24fd859 100644
--- a/double-conversion/strtod.cc
+++ b/double-conversion/strtod.cc
@@ -460,6 +460,11 @@ static bool IsNonZeroDigit(const char d) {
return ('1' <= d) && (d <= '9');
}
+#ifdef __has_cpp_attribute
+#if __has_cpp_attribute(maybe_unused)
+[[maybe_unused]]
+#endif
+#endif
static bool AssertTrimmedDigits(const Vector<const char>& buffer) {
for(int i = 0; i < buffer.length(); ++i) {
if(!IsDigit(buffer[i])) {
--
2.29.2

View File

@ -1,9 +0,0 @@
Files generated, by git format-patch, from a branch off the
double-conversion upstream's master branch, reflecting the changes to
files there before copying to this directory and its include/. This
ensures that the upstream can take the changes most easily.
Although they have a CLA, our changes have never risen to the level of
having any standing at copyright or patent law; on that basis, they
accepted our patches up to 2020 in early 2021 and we may hope they
will do so again in future.

View File

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