diff options
Diffstat (limited to 'src/corelib/global/qnumeric_p.h')
-rw-r--r-- | src/corelib/global/qnumeric_p.h | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h index 86e7997680..7a03e32699 100644 --- a/src/corelib/global/qnumeric_p.h +++ b/src/corelib/global/qnumeric_p.h @@ -202,7 +202,7 @@ namespace { This function works for v containing infinities, but not NaN. It's the caller's responsibility to exclude that possibility before calling it. */ -template <typename T> static inline bool convertDoubleTo(double v, T *value) +template <typename T> static inline bool convertDoubleTo(double v, T *value, bool allow_precision_upgrade = true) { Q_STATIC_ASSERT(std::numeric_limits<T>::is_integer); @@ -227,6 +227,10 @@ template <typename T> static inline bool convertDoubleTo(double v, T *value) supremum = -2.0 * std::numeric_limits<ST>::min(); // -2 * (-2^63) = 2^64, exact (for T = quint64) v = fabs(v); } + if (std::is_integral<T>::value && sizeof(T) > 4 && !allow_precision_upgrade) { + if (v > double(Q_INT64_C(1)<<53) || v < double(-((Q_INT64_C(1)<<53) + 1))) + return false; + } *value = std::numeric_limits<T>::max(); if (v >= supremum) @@ -249,7 +253,8 @@ QT_WARNING_POP // size_t. Implementations for 8- and 16-bit types will work but may not be as // efficient. Implementations for 64-bit may be missing on 32-bit platforms. -#if (defined(Q_CC_GNU) && (Q_CC_GNU >= 500) || (defined(Q_CC_INTEL) && !defined(Q_OS_WIN))) || QT_HAS_BUILTIN(__builtin_add_overflow) +#if ((defined(Q_CC_INTEL) ? (Q_CC_INTEL >= 1800 && !defined(Q_OS_WIN)) : defined(Q_CC_GNU)) \ + && Q_CC_GNU >= 500) || __has_builtin(__builtin_add_overflow) // GCC 5, ICC 18, and Clang 3.8 have builtins to detect overflows template <typename T> inline |