From a9923674030980706940b3ee11145c38674bb35d Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 19 Nov 2018 16:27:03 +0100 Subject: Change documentation of some toDouble()s to reflect reality They actually return infinity if conversion overflows, while still setting ok to false; they were documented to return 0 on failure, with no mention of this special handling of overflow. Documented reality rather than changing the behavior. Gave underflow as an example of failure other than overflow (toDouble()s do indeed fail on it). Added some tests of out-of-range values, infinities and NaNs. [ChangeLog][QtCore][toDouble] QString, QByteArray and QLocale return an infinity on overflow (since 5.7), while setting ok to false; this was at odds with their documented behavior of returning 0 on failure. The documentation now reflects the actual behavior. Fixes: QTBUG-71256 Change-Id: I8d7e80ba1f06091cf0f1480c341553381103703b Reviewed-by: Ulf Hermann --- src/corelib/tools/qbytearray.cpp | 3 ++- src/corelib/tools/qlocale.cpp | 18 ++++++++++++------ src/corelib/tools/qstring.cpp | 6 ++++-- 3 files changed, 18 insertions(+), 9 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 424420204a..1b7a4366c7 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -3871,7 +3871,8 @@ ushort QByteArray::toUShort(bool *ok, int base) const /*! Returns the byte array converted to a \c double value. - Returns 0.0 if the conversion fails. + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for other reasons (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 6361280bc7..8f9fb3de2d 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -1373,8 +1373,10 @@ float QLocale::toFloat(const QString &s, bool *ok) const } /*! - Returns the double represented by the localized string \a s, or - 0.0 if the conversion failed. + Returns the double represented by the localized string \a s. + + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for any other reason (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. @@ -1542,8 +1544,10 @@ float QLocale::toFloat(const QStringRef &s, bool *ok) const } /*! - Returns the double represented by the localized string \a s, or - 0.0 if the conversion failed. + Returns the double represented by the localized string \a s. + + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for any other reason (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. @@ -1711,8 +1715,10 @@ float QLocale::toFloat(QStringView s, bool *ok) const } /*! - Returns the double represented by the localized string \a s, or - 0.0 if the conversion failed. + Returns the double represented by the localized string \a s. + + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for any other reason (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 0a8b2b4238..1381e8c11c 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -7169,7 +7169,8 @@ ushort QString::toUShort(bool *ok, int base) const /*! Returns the string converted to a \c double value. - Returns 0.0 if the conversion fails. + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for other reasons (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. @@ -11794,7 +11795,8 @@ ushort QStringRef::toUShort(bool *ok, int base) const /*! Returns the string converted to a \c double value. - Returns 0.0 if the conversion fails. + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for other reasons (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. -- cgit v1.2.3 From ce159d1a3e48308d54300560f024e8501c1395c9 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 19 Nov 2018 19:53:38 +0100 Subject: Fix toFloat()s between float and double ranges and document Revised some toFloat()s to be consistent with the matching toDouble()s; previously, they would return infinity if toDouble() did but return 0 if toDouble() got a finite value outside float's range. That also applied to values that underflowed float's range, succeeding and returning 0 as long as they were within double's range but failing if toDouble() underflowed. Now float-underflow also fails. Amended their documentation to reflect this more consistent reality. Added some tests of out-of-range values, infinities and NaNs. [ChangeLog][QtCore][toFloat] QString, QByteArray and QLocale returned an infinity on double-overflow (since 5.7) but returned 0 on a finite double outside float's range, while setting ok to false; this was at odds with their documented behavior of returning 0 on any failure. They also succeeded, returning zero, on underflow of float's range, unless double underflowed, where they failed. Changed the handling of values outside float's range to match that of values outside double's range: fail, returning an infinity on overflow or zero on underflow. The documentation now reflects the revised behavior, which matches toDouble(). Change-Id: Ia168bcacf7def0df924840d45d8edc5f850449d6 Reviewed-by: Ulf Hermann --- src/corelib/tools/qbytearray.cpp | 3 ++- src/corelib/tools/qlocale.cpp | 18 ++++++++++++------ src/corelib/tools/qlocale_p.h | 11 ++++++++++- src/corelib/tools/qstring.cpp | 6 ++++-- 4 files changed, 28 insertions(+), 10 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 1b7a4366c7..2a97fa50a9 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -3899,7 +3899,8 @@ double QByteArray::toDouble(bool *ok) const /*! Returns the byte array converted to a \c float value. - Returns 0.0 if the conversion fails. + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for other reasons (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 8f9fb3de2d..417b1e41f6 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -1353,8 +1353,10 @@ qulonglong QLocale::toULongLong(const QString &s, bool *ok) const } /*! - Returns the float represented by the localized string \a s, or 0.0 - if the conversion failed. + Returns the float represented by the localized string \a s. + + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for any other reason (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. @@ -1522,8 +1524,10 @@ qulonglong QLocale::toULongLong(const QStringRef &s, bool *ok) const } /*! - Returns the float represented by the localized string \a s, or 0.0 - if the conversion failed. + Returns the float represented by the localized string \a s. + + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for any other reason (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. @@ -1696,8 +1700,10 @@ qulonglong QLocale::toULongLong(QStringView s, bool *ok) const } /*! - Returns the float represented by the localized string \a s, or 0.0 - if the conversion failed. + Returns the float represented by the localized string \a s. + + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for any other reason (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h index 6669ae7c8b..deca671627 100644 --- a/src/corelib/tools/qlocale_p.h +++ b/src/corelib/tools/qlocale_p.h @@ -249,7 +249,16 @@ public: if (std::fabs(d) > std::numeric_limits::max()) { if (ok != 0) *ok = false; - return 0.0f; + const float huge = std::numeric_limits::infinity(); + return d < 0 ? -huge : huge; + } + if (std::fabs(d) >= std::numeric_limits::min() // i.e. d != 0 + && std::fabs(d) < std::numeric_limits::min()) { + // Values smaller than std::numeric_limits::min() have + // failed already; match them. + if (ok != 0) + *ok = false; + return 0; } return float(d); } diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 1381e8c11c..94b1784202 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -7208,7 +7208,8 @@ double QString::toDouble(bool *ok) const /*! Returns the string converted to a \c float value. - Returns 0.0 if the conversion fails. + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for other reasons (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. @@ -11821,7 +11822,8 @@ double QStringRef::toDouble(bool *ok) const /*! Returns the string converted to a \c float value. - Returns 0.0 if the conversion fails. + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for other reasons (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. -- cgit v1.2.3 From d8b401959f6f58bc80f767684b250dd4589735d6 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 19 Nov 2018 16:26:02 +0100 Subject: Recognize E along with e as exponent character in asciiToDouble Fixed a misguided condition in the check for bogus texts in the sscanf branch of the decoder; it checked for 'e' but neglected 'E', which is just as valid. Change-Id: I9236c76faea000c92df641930e401bce445e06c8 Reviewed-by: Ulf Hermann --- src/corelib/tools/qlocale_tools.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qlocale_tools.cpp b/src/corelib/tools/qlocale_tools.cpp index 4d969a4723..a315356a23 100644 --- a/src/corelib/tools/qlocale_tools.cpp +++ b/src/corelib/tools/qlocale_tools.cpp @@ -350,7 +350,7 @@ double asciiToDouble(const char *num, int numLen, bool &ok, int &processed, ok = false; for (int i = 0; i < processed; ++i) { char c = num[i]; - if ((c < '0' || c > '9') && c != '.' && c != '-' && c != '+' && c != 'e') { + if ((c < '0' || c > '9') && c != '.' && c != '-' && c != '+' && c != 'e' && c != 'E') { // Garbage found processed = 0; return 0.0; -- cgit v1.2.3 From d41879db384905c47c8fca976ae70ad6595de41f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 27 Nov 2018 13:59:53 +0100 Subject: Documention: Use const-ref in the snippets for qOverload() This makes it clearer that const-ref needs to be specified in the template arguments of qOverload() and related. Change-Id: I527c8ca853be159af8665e9759d9549df10573b3 Reviewed-by: Martin Smith Reviewed-by: Olivier Goffart (Woboq GmbH) --- .../doc/snippets/code/src_corelib_global_qglobal.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp index 7fdff974c1..0248640369 100644 --- a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp @@ -647,24 +647,24 @@ template<> class QTypeInfo : public QTypeInfoMerger {}; //! [52] struct Foo { void overloadedFunction(); - void overloadedFunction(int, QString); + void overloadedFunction(int, const QString &); }; ... qOverload<>(&Foo::overloadedFunction) - ... qOverload(&Foo::overloadedFunction) + ... qOverload(&Foo::overloadedFunction) //! [52] //! [53] ... QOverload<>::of(&Foo::overloadedFunction) - ... QOverload::of(&Foo::overloadedFunction) + ... QOverload::of(&Foo::overloadedFunction) //! [53] //! [54] struct Foo { - void overloadedFunction(int, QString); - void overloadedFunction(int, QString) const; + void overloadedFunction(int, const QString &); + void overloadedFunction(int, const QString &) const; }; - ... qConstOverload(&Foo::overloadedFunction) - ... qNonConstOverload(&Foo::overloadedFunction) + ... qConstOverload(&Foo::overloadedFunction) + ... qNonConstOverload(&Foo::overloadedFunction) //! [54] //! [qlikely] -- cgit v1.2.3 From dba606767056986a8c0cc973ec5932f603f14759 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Oct 2018 16:35:58 -0700 Subject: Optimize QSharedPointer::getAndRef with the three-operand testAndSet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Originally QAtomicPointer didn't have the three-operand version, resulting in code like: if (!atomic.testAndSetXxx(expected, newvalue)) expected = atomic.load(); The three-operand version gives us the current value of the atomic in case the test failed and it's free in all architectures, unlike the extra load. I have to use testAndSetOrdered here because I need the failing load to use the Acquire memory order, even though that has an extra Acquire for the successful case we don't need. QAtomicPointer does not have testAndSetReleaseAcquire. Change-Id: I1bd327aeaf73421a8ec5fffd1560fe30d3bfd9b8 Reviewed-by: Romain Pokrzywka Reviewed-by: Jędrzej Nowacki --- src/corelib/tools/qsharedpointer.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 622b03f42d..a1caeeb135 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -1383,15 +1383,18 @@ QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::ge ExternalRefCountData *x = new ExternalRefCountData(Qt::Uninitialized); x->strongref.store(-1); x->weakref.store(2); // the QWeakPointer that called us plus the QObject itself - if (!d->sharedRefcount.testAndSetRelease(0, x)) { + + ExternalRefCountData *ret; + if (d->sharedRefcount.testAndSetOrdered(nullptr, x, ret)) { // ought to be release+acquire; this is acq_rel+acquire + ret = x; + } else { // ~ExternalRefCountData has a Q_ASSERT, so we use this trick to // only execute this if Q_ASSERTs are enabled Q_ASSERT((x->weakref.store(0), true)); delete x; - x = d->sharedRefcount.loadAcquire(); - x->weakref.ref(); + ret->weakref.ref(); } - return x; + return ret; } /** -- cgit v1.2.3 From d8962144b425b9929770b67bcfb8247a9e9b9022 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 26 Oct 2018 23:22:22 -0700 Subject: Fix calculation of the string tab size in QElfParser First of all, we were using the wrong size variable: instead of the size of the section, found in the section header, we were using the size of each section entry in the section table. Since that's usually smaller, we weren't hitting a problem. Second, if the string table is the last thing in the file and there's nothing else after it, not even padding, then offset + section_size can be equal to the file size. In fact, the .shstrtab section is usually the last one, as it contains the section names themselves, so it stands to reason that it's the second to last thing written. For generic linkers, the last data in the file is the section table itself, so usually the file is larger by at least a kilobyte, which is why we haven't hit this bug. It could only manifest as deciding that certain specially-crafted but valid ELF files were invalid. I can't think of a way to trick it into thinking an invalid ELF is valid. That's another reason why this code needs to be rewritten with more modern coding styles and actually using Fixes: QTBUG-71443 Change-Id: I1bd327aeaf73421a8ec5fffd156162f2df5557b8 Reviewed-by: Simon Hausmann --- src/corelib/plugin/qelfparser_p.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/plugin/qelfparser_p.cpp b/src/corelib/plugin/qelfparser_p.cpp index 159a324c6b..13eee3539e 100644 --- a/src/corelib/plugin/qelfparser_p.cpp +++ b/src/corelib/plugin/qelfparser_p.cpp @@ -168,11 +168,11 @@ int QElfParser::parse(const char *dataStart, ulong fdlen, const QString &library parseSectionHeader(dataStart + soff, &strtab); m_stringTableFileOffset = strtab.offset; - if ((quint32)(m_stringTableFileOffset + e_shentsize) >= fdlen || m_stringTableFileOffset == 0) { + if ((quint32)(strtab.offset + strtab.size) > fdlen || strtab.offset == 0) { if (lib) lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)") .arg(library, QLibrary::tr("string table seems to be at %1") - .arg(QString::number(soff, 16))); + .arg(QString::number(strtab.offset, 16))); return Corrupt; } -- cgit v1.2.3 From 49d63057e31427aff84d4fe33d60bacfe2445076 Mon Sep 17 00:00:00 2001 From: Kevin Funk Date: Wed, 28 Nov 2018 10:09:00 +0100 Subject: qobject_p.h: Use nullptr everywhere Change-Id: I605e44607cc09775548c1e6b781d476c1627c9c7 Reviewed-by: Simon Hausmann --- src/corelib/kernel/qobject_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 6aea40cf4a..5dfef786ec 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -341,7 +341,7 @@ inline QMetaObject::Connection QObjectPrivate::connect(const typename QtPrivate: Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible::value), "Return type of the slot is not compatible with the return type of the signal."); - const int *types = 0; + const int *types = nullptr; if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection) types = QtPrivate::ConnectionTypes::types(); -- cgit v1.2.3 From d3ec5a2b09f3c9f5a67e757aa6b7b0dd09bbe97a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 25 Nov 2018 00:41:00 +0100 Subject: CoreText: Use QCFType to track CoreFoundation member variables The operator T() function of QAppleRefCounted should be const so that the underlying type can be accessed from const member functions just like the naked underlying type could. Change-Id: I0819c5795d28442a6ff4db2732e211b183574f9f Reviewed-by: Simon Hausmann --- src/corelib/kernel/qcore_mac_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h index b14a494296..acb87f8a3c 100644 --- a/src/corelib/kernel/qcore_mac_p.h +++ b/src/corelib/kernel/qcore_mac_p.h @@ -89,7 +89,7 @@ public: QAppleRefCounted(QAppleRefCounted &&other) : value(other.value) { other.value = T(); } QAppleRefCounted(const QAppleRefCounted &other) : value(other.value) { if (value) RetainFunction(value); } ~QAppleRefCounted() { if (value) ReleaseFunction(value); } - operator T() { return value; } + operator T() const { return value; } void swap(QAppleRefCounted &other) Q_DECL_NOEXCEPT_EXPR(noexcept(qSwap(value, other.value))) { qSwap(value, other.value); } QAppleRefCounted &operator=(const QAppleRefCounted &other) -- cgit v1.2.3 From 6b875f0625acc6c6a4f8899b829176baaf7d8502 Mon Sep 17 00:00:00 2001 From: Thomas Miller Date: Wed, 14 Nov 2018 16:19:43 -0800 Subject: Implement mul_overflow for MSVC arm64 Change-Id: Ia7c79614e6ef21222fb9683b540ac51b45a77c49 Reviewed-by: Thiago Macieira --- src/corelib/global/qnumeric_p.h | 74 +++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 48 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h index e318c3759b..5326d9485b 100644 --- a/src/corelib/global/qnumeric_p.h +++ b/src/corelib/global/qnumeric_p.h @@ -58,14 +58,21 @@ #if defined(Q_CC_MSVC) # include -#endif - -#if defined(Q_CC_MSVC) -#include +# include +# if defined(Q_PROCESSOR_X86_64) || defined(Q_PROCESSOR_ARM_64) +# define Q_INTRINSIC_MUL_OVERFLOW64 +# define Q_UMULH(v1, v2) __umulh(v1, v2); +# define Q_SMULH(v1, v2) __mulh(v1, v2); +# pragma intrinsic(__umulh) +# pragma intrinsic(__mulh) +# endif #endif # if defined(Q_OS_INTEGRITY) && defined(Q_PROCESSOR_ARM_64) #include +# define Q_INTRINSIC_MUL_OVERFLOW64 +# define Q_UMULH(v1, v2) __MULUH64(v1, v2); +# define Q_SMULH(v1, v2) __MULSH64(v1, v2); #endif #if !defined(Q_CC_MSVC) && (defined(Q_OS_QNX) || defined(Q_CC_INTEL)) @@ -327,26 +334,26 @@ mul_overflow(T v1, T v2, T *r) return lr > std::numeric_limits::max() || lr < std::numeric_limits::min(); } -# if defined(Q_OS_INTEGRITY) && defined(Q_PROCESSOR_ARM_64) +# if defined(Q_INTRINSIC_MUL_OVERFLOW64) template <> inline bool mul_overflow(quint64 v1, quint64 v2, quint64 *r) { *r = v1 * v2; - return __MULUH64(v1, v2); + return Q_UMULH(v1, v2); } template <> inline bool mul_overflow(qint64 v1, qint64 v2, qint64 *r) { - qint64 high = __MULSH64(v1, v2); - if (high == 0) { - *r = v1 * v2; - return *r < 0; - } - if (high == -1) { - *r = v1 * v2; - return *r >= 0; - } - return true; + // This is slightly more complex than the unsigned case above: the sign bit + // of 'low' must be replicated as the entire 'high', so the only valid + // values for 'high' are 0 and -1. Use unsigned multiply since it's the same + // as signed for the low bits and use a signed right shift to verify that + // 'high' is nothing but sign bits that match the sign of 'low'. + + qint64 high = __mulh(v1, v2); + *r = qint64(quint64(v1) * quint64(v2)); + return (*r >> 63) != high; } +# if defined(Q_OS_INTEGRITY) && defined(Q_PROCESSOR_ARM_64) template <> inline bool mul_overflow(uint64_t v1, uint64_t v2, uint64_t *r) { return mul_overflow(v1,v2,reinterpret_cast(r)); @@ -356,8 +363,8 @@ template <> inline bool mul_overflow(int64_t v1, int64_t v2, int64_t *r) { return mul_overflow(v1,v2,reinterpret_cast(r)); } - -#endif +# endif // OS_INTEGRITY ARM64 +# endif // Q_INTRINSIC_MUL_OVERFLOW64 # if defined(Q_CC_MSVC) && defined(Q_PROCESSOR_X86) // We can use intrinsics for the unsigned operations with MSVC @@ -369,37 +376,8 @@ template <> inline bool add_overflow(unsigned v1, unsigned v2, unsigned *r) # if defined(Q_PROCESSOR_X86_64) template <> inline bool add_overflow(quint64 v1, quint64 v2, quint64 *r) { return _addcarry_u64(0, v1, v2, reinterpret_cast(r)); } - -# pragma intrinsic(_umul128) -template <> inline bool mul_overflow(quint64 v1, quint64 v2, quint64 *r) -{ - // use 128-bit multiplication with the _umul128 intrinsic - // https://msdn.microsoft.com/en-us/library/3dayytw9.aspx - quint64 high; - *r = _umul128(v1, v2, &high); - return high; -} - -# pragma intrinsic(_mul128) -template <> inline bool mul_overflow(qint64 v1, qint64 v2, qint64 *r) -{ - // Use 128-bit multiplication with the _mul128 intrinsic - // https://msdn.microsoft.com/en-us/library/82cxdw50.aspx - - // This is slightly more complex than the unsigned case above: the sign bit - // of 'low' must be replicated as the entire 'high', so the only valid - // values for 'high' are 0 and -1. - - qint64 high; - *r = _mul128(v1, v2, &high); - if (high == 0) - return *r < 0; - if (high == -1) - return *r >= 0; - return true; -} # endif // x86-64 -# endif // MSVC x86 +# endif // MSVC X86 #endif // !GCC } #endif // Q_CLANG_QDOC -- cgit v1.2.3 From 1eeebae7e3b5eb8dda37755b32aafe6719b5cf7b Mon Sep 17 00:00:00 2001 From: Ville Voutilainen Date: Wed, 21 Nov 2018 14:07:18 +0200 Subject: Fix compilation of qendian's qswap specializations on gcc 4.8 Task-number: QTBUG-71945 Change-Id: Icf2b75c72946f57ebffc880c9238531dea13ab5b Reviewed-by: Ivan Komissarov Reviewed-by: Simon Hausmann --- src/corelib/global/qendian.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h index 0e67a1ab8e..f2e5833468 100644 --- a/src/corelib/global/qendian.h +++ b/src/corelib/global/qendian.h @@ -162,17 +162,17 @@ Float qbswapFloatHelper(Float source) return qFromUnaligned(&temp); } -template <> inline qfloat16 qbswap(qfloat16 source) +inline qfloat16 qbswap(qfloat16 source) { return qbswapFloatHelper(source); } -template <> inline float qbswap(float source) +inline float qbswap(float source) { return qbswapFloatHelper(source); } -template <> inline double qbswap(double source) +inline double qbswap(double source) { return qbswapFloatHelper(source); } @@ -185,7 +185,7 @@ template <> inline double qbswap(double source) */ template inline void qbswap(const T src, void *dest) { - qToUnaligned(qbswap(src), dest); + qToUnaligned(qbswap(src), dest); } template void *qbswap(const void *source, qsizetype count, void *dest) noexcept; @@ -223,9 +223,9 @@ template inline void qFromLittleEndian(const void *source, qsizetyp #else // Q_LITTLE_ENDIAN template inline Q_DECL_CONSTEXPR T qToBigEndian(T source) -{ return qbswap(source); } +{ return qbswap(source); } template inline Q_DECL_CONSTEXPR T qFromBigEndian(T source) -{ return qbswap(source); } +{ return qbswap(source); } template inline Q_DECL_CONSTEXPR T qToLittleEndian(T source) { return source; } template inline Q_DECL_CONSTEXPR T qFromLittleEndian(T source) -- cgit v1.2.3