diff options
author | Liang Qi <liang.qi@qt.io> | 2018-12-04 09:58:43 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2018-12-04 09:58:43 +0100 |
commit | 5d5c00c67682bce105197b659687fd1fee8f60cf (patch) | |
tree | 686e41dc3ea121235fb73afb9157ed603f1bfeff /src/corelib | |
parent | f213e818f03d35cb82e3daf187415197fd156f8e (diff) | |
parent | b82559244e2dc03f1ceff66bb67630df4300dc7c (diff) |
Merge remote-tracking branch 'origin/5.12' into dev
Conflicts:
src/gui/painting/qdrawhelper.cpp
Change-Id: I4916e07b635e1d3830e9b46ef7914f99bec3098e
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp | 14 | ||||
-rw-r--r-- | src/corelib/global/qendian.h | 12 | ||||
-rw-r--r-- | src/corelib/global/qnumeric_p.h | 74 | ||||
-rw-r--r-- | src/corelib/kernel/qcore_mac_p.h | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qobject_p.h | 2 | ||||
-rw-r--r-- | src/corelib/plugin/qelfparser_p.cpp | 4 | ||||
-rw-r--r-- | src/corelib/tools/qbytearray.cpp | 6 | ||||
-rw-r--r-- | src/corelib/tools/qlocale.cpp | 36 | ||||
-rw-r--r-- | src/corelib/tools/qlocale_p.h | 11 | ||||
-rw-r--r-- | src/corelib/tools/qlocale_tools.cpp | 2 | ||||
-rw-r--r-- | src/corelib/tools/qsharedpointer.cpp | 11 | ||||
-rw-r--r-- | src/corelib/tools/qstring.cpp | 12 |
12 files changed, 97 insertions, 89 deletions
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<A> : public QTypeInfoMerger<A, B, C, D> {}; //! [52] struct Foo { void overloadedFunction(); - void overloadedFunction(int, QString); + void overloadedFunction(int, const QString &); }; ... qOverload<>(&Foo::overloadedFunction) - ... qOverload<int, QString>(&Foo::overloadedFunction) + ... qOverload<int, const QString &>(&Foo::overloadedFunction) //! [52] //! [53] ... QOverload<>::of(&Foo::overloadedFunction) - ... QOverload<int, QString>::of(&Foo::overloadedFunction) + ... QOverload<int, const QString &>::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<int, QString>(&Foo::overloadedFunction) - ... qNonConstOverload<int, QString>(&Foo::overloadedFunction) + ... qConstOverload<int, const QString &>(&Foo::overloadedFunction) + ... qNonConstOverload<int, const QString &>(&Foo::overloadedFunction) //! [54] //! [qlikely] 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<Float>(&temp); } -template <> inline qfloat16 qbswap<qfloat16>(qfloat16 source) +inline qfloat16 qbswap(qfloat16 source) { return qbswapFloatHelper(source); } -template <> inline float qbswap<float>(float source) +inline float qbswap(float source) { return qbswapFloatHelper(source); } -template <> inline double qbswap<double>(double source) +inline double qbswap(double source) { return qbswapFloatHelper(source); } @@ -185,7 +185,7 @@ template <> inline double qbswap<double>(double source) */ template <typename T> inline void qbswap(const T src, void *dest) { - qToUnaligned<T>(qbswap<T>(src), dest); + qToUnaligned<T>(qbswap(src), dest); } template <int Size> void *qbswap(const void *source, qsizetype count, void *dest) noexcept; @@ -223,9 +223,9 @@ template <typename T> inline void qFromLittleEndian(const void *source, qsizetyp #else // Q_LITTLE_ENDIAN template <typename T> inline Q_DECL_CONSTEXPR T qToBigEndian(T source) -{ return qbswap<T>(source); } +{ return qbswap(source); } template <typename T> inline Q_DECL_CONSTEXPR T qFromBigEndian(T source) -{ return qbswap<T>(source); } +{ return qbswap(source); } template <typename T> inline Q_DECL_CONSTEXPR T qToLittleEndian(T source) { return source; } template <typename T> inline Q_DECL_CONSTEXPR T qFromLittleEndian(T source) 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 <intrin.h> -#endif - -#if defined(Q_CC_MSVC) -#include <float.h> +# include <float.h> +# 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 <arm64_ghs.h> +# 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<T>::max() || lr < std::numeric_limits<T>::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<quint64>(v1,v2,reinterpret_cast<quint64*>(r)); @@ -356,8 +363,8 @@ template <> inline bool mul_overflow(int64_t v1, int64_t v2, int64_t *r) { return mul_overflow<qint64>(v1,v2,reinterpret_cast<qint64*>(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<unsigned __int64 *>(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 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) diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index c4e1c69883..9c6724d8ab 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<typename SlotType::ReturnType, typename SignalType::ReturnType>::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<typename SignalType::Arguments>::types(); 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; } diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 1d8621ad5a..70eae9e463 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -4112,7 +4112,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. @@ -4147,7 +4148,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 4d5924a03e..51b886b0e0 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -1371,8 +1371,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. @@ -1391,8 +1393,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. @@ -1538,8 +1542,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. @@ -1560,8 +1566,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. @@ -1710,8 +1718,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. @@ -1729,8 +1739,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/qlocale_p.h b/src/corelib/tools/qlocale_p.h index 9f5811990b..98b6a31a46 100644 --- a/src/corelib/tools/qlocale_p.h +++ b/src/corelib/tools/qlocale_p.h @@ -251,7 +251,16 @@ public: if (std::fabs(d) > std::numeric_limits<float>::max()) { if (ok != 0) *ok = false; - return 0.0f; + const float huge = std::numeric_limits<float>::infinity(); + return d < 0 ? -huge : huge; + } + if (std::fabs(d) >= std::numeric_limits<double>::min() // i.e. d != 0 + && std::fabs(d) < std::numeric_limits<float>::min()) { + // Values smaller than std::numeric_limits<double>::min() have + // failed already; match them. + if (ok != 0) + *ok = false; + return 0; } return float(d); } diff --git a/src/corelib/tools/qlocale_tools.cpp b/src/corelib/tools/qlocale_tools.cpp index bde52a20b9..53258bec3e 100644 --- a/src/corelib/tools/qlocale_tools.cpp +++ b/src/corelib/tools/qlocale_tools.cpp @@ -354,7 +354,7 @@ double qt_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; 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; } /** diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 90713bab10..5ea5aeca12 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -7401,7 +7401,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. @@ -7439,7 +7440,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. @@ -12008,7 +12010,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. @@ -12033,7 +12036,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. |