diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-10-02 01:01:20 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2019-10-02 08:39:15 +0200 |
commit | 4c8814a341aace34f9a6011e9ec16048dc0f18b6 (patch) | |
tree | 3f3193c51c0883ae70de3ae3a3b225b3c7b9b8cc /src/corelib | |
parent | 009d86da2d5a928865819fe44b4d1c78d455bbb9 (diff) | |
parent | 8791a8398ac232a8daab98601f1bef88bdf7638f (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Change-Id: Ideaa64d583746f1ce8265997131fb1ce3a9acbcf
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp | 2 | ||||
-rw-r--r-- | src/corelib/global/qconfig-bootstrapped.h | 1 | ||||
-rw-r--r-- | src/corelib/global/qfloat16.cpp | 47 | ||||
-rw-r--r-- | src/corelib/global/qglobal.cpp | 70 | ||||
-rw-r--r-- | src/corelib/global/qnumeric.cpp | 2 | ||||
-rw-r--r-- | src/corelib/global/qnumeric.h | 7 | ||||
-rw-r--r-- | src/corelib/global/qnumeric_p.h | 3 | ||||
-rw-r--r-- | src/corelib/global/qrandom.cpp | 45 | ||||
-rw-r--r-- | src/corelib/global/qrandom_p.h | 8 | ||||
-rw-r--r-- | src/corelib/io/qfileinfo.cpp | 85 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemiterator_unix.cpp | 4 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_cf.mm | 2 | ||||
-rw-r--r-- | src/corelib/thread/qwaitcondition_p.h | 153 | ||||
-rw-r--r-- | src/corelib/thread/thread.pri | 1 | ||||
-rw-r--r-- | src/corelib/time/qcalendar.cpp | 11 | ||||
-rw-r--r-- | src/corelib/time/qcalendar.h | 2 | ||||
-rw-r--r-- | src/corelib/time/qdatetime.cpp | 1 | ||||
-rw-r--r-- | src/corelib/tools/qsimd.cpp | 68 | ||||
-rw-r--r-- | src/corelib/tools/qsimd_p.h | 18 | ||||
-rw-r--r-- | src/corelib/tools/qvarlengtharray.h | 2 |
20 files changed, 446 insertions, 86 deletions
diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp index 1e31a5292f..1966f8195a 100644 --- a/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp @@ -416,7 +416,7 @@ public: LoadArchiveMemberHint = 0x04 }; Q_DECLARE_FLAGS(LoadHints, LoadHint) - Q_FLAG(LoadHints) + Q_FLAG(LoadHint) ... } //! [39] diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h index 2e58dabf5f..e6ad80525a 100644 --- a/src/corelib/global/qconfig-bootstrapped.h +++ b/src/corelib/global/qconfig-bootstrapped.h @@ -109,6 +109,7 @@ # define QT_FEATURE_renameat2 -1 #endif #define QT_FEATURE_sharedmemory -1 +#define QT_FEATURE_signaling_nan -1 #define QT_FEATURE_slog2 -1 #ifdef __GLIBC_PREREQ # define QT_FEATURE_statx (__GLIBC_PREREQ(2, 28) ? 1 : -1) diff --git a/src/corelib/global/qfloat16.cpp b/src/corelib/global/qfloat16.cpp index ff2997b73a..2ba4c79374 100644 --- a/src/corelib/global/qfloat16.cpp +++ b/src/corelib/global/qfloat16.cpp @@ -107,10 +107,51 @@ QT_BEGIN_NAMESPACE */ /*! - \internal - Implements qFpClassify() for qfloat16. - */ + \internal + \since 5.14 + bool qfloat16::isInf() const noexcept + + Tests whether this \c qfloat16 value is an infinity. + + \sa qIsInf() +*/ + +/*! + \internal + \since 5.14 + bool qfloat16::isNaN() const noexcept + + Tests whether this \c qfloat16 value is "not a number". + + \sa qIsNaN() +*/ + +/*! + \since 5.14 + bool qfloat16::isNormal() const noexcept + Tests whether this \c qfloat16 value is finite and in normal form. + + \sa qFpClassify() +*/ + +/*! + \internal + \since 5.14 + bool qfloat16::isFinite() const noexcept + + Tests whether this \c qfloat16 value is finite. + + \sa qIsFinite() +*/ + +/*! + \internal + \since 5.14 + Implements qFpClassify() for qfloat16. + + \sa qFpClassify() +*/ int qfloat16::fpClassify() const noexcept { return isInf() ? FP_INFINITE : isNaN() ? FP_NAN diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 2b1a40cf4c..63ad44f79a 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -48,6 +48,10 @@ #include "qoperatingsystemversion_p.h" #if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN) || defined(Q_OS_WINRT) #include "qoperatingsystemversion_win_p.h" +# if QT_CONFIG(settings) +# include "qsettings.h" +# include "qvariant.h" +# endif #endif #include <private/qlocale_tools_p.h> @@ -2202,12 +2206,36 @@ const QSysInfo::WinVersion QSysInfo::WindowsVersion = QSysInfo::windowsVersion() QT_WARNING_POP #endif +static QString readRegistryString(const QString &key, const QString &subKey) +{ +#if QT_CONFIG(settings) + QSettings settings(key, QSettings::NativeFormat); + return settings.value(subKey).toString(); +#else + Q_UNUSED(key); + Q_UNUSED(subKey); + return QString(); +#endif +} + +static inline QString windowsVersionKey() { return QStringLiteral(R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion)"); } + +static inline QString windows10ReleaseId() +{ + return readRegistryString(windowsVersionKey(), QStringLiteral("ReleaseId")); +} + +static inline QString windows7Build() +{ + return readRegistryString(windowsVersionKey(), QStringLiteral("CurrentBuild")); +} + static QString winSp_helper() { const auto osv = qWindowsVersionInfo(); const qint16 major = osv.wServicePackMajor; if (major) { - QString sp = QStringLiteral(" SP ") + QString::number(major); + QString sp = QStringLiteral("SP ") + QString::number(major); const qint16 minor = osv.wServicePackMinor; if (minor) sp += QLatin1Char('.') + QString::number(minor); @@ -2920,19 +2948,35 @@ QString QSysInfo::prettyProductName() { #if (defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)) || defined(Q_OS_DARWIN) || defined(Q_OS_WIN) const auto version = QOperatingSystemVersion::current(); + const int majorVersion = version.majorVersion(); + const QString versionString = QString::number(majorVersion) + QLatin1Char('.') + + QString::number(version.minorVersion()); + QString result = version.name() + QLatin1Char(' '); const char *name = osVer_helper(version); - if (name) - return version.name() + QLatin1Char(' ') + QLatin1String(name) -# if defined(Q_OS_WIN) - + winSp_helper() -# endif - + QLatin1String(" (") + QString::number(version.majorVersion()) - + QLatin1Char('.') + QString::number(version.minorVersion()) - + QLatin1Char(')'); - else - return version.name() + QLatin1Char(' ') - + QString::number(version.majorVersion()) + QLatin1Char('.') - + QString::number(version.minorVersion()); + if (!name) + return result + versionString; + result += QLatin1String(name); +# if !defined(Q_OS_WIN) + return result + QLatin1String(" (") + versionString + QLatin1Char(')'); +# else + // (resembling winver.exe): Windows 10 "Windows 10 Version 1809" + result += QLatin1String(" Version "); + if (majorVersion >= 10) { + const auto releaseId = windows10ReleaseId(); + if (!releaseId.isEmpty()) + result += QLatin1String(" Version ") + releaseId; + return result; + } + // Windows 7: "Windows 7 Version 6.1 (Build 7601: Service Pack 1)" + result += versionString + QLatin1String(" ("); + const auto build = windows7Build(); + if (!build.isEmpty()) + result += QLatin1String("Build ") + build; + const auto servicePack = winSp_helper(); + if (!servicePack.isEmpty()) + result += QLatin1String(": ") + servicePack; + return result + QLatin1Char(')'); +# endif // Windows #elif defined(Q_OS_HAIKU) return QLatin1String("Haiku ") + productVersion(); #elif defined(Q_OS_UNIX) diff --git a/src/corelib/global/qnumeric.cpp b/src/corelib/global/qnumeric.cpp index 11440f40a4..9cb9c1283a 100644 --- a/src/corelib/global/qnumeric.cpp +++ b/src/corelib/global/qnumeric.cpp @@ -81,11 +81,13 @@ Q_CORE_EXPORT bool qIsNaN(float f) { return qt_is_nan(f); } */ Q_CORE_EXPORT bool qIsFinite(float f) { return qt_is_finite(f); } +#if QT_CONFIG(signaling_nan) /*! Returns the bit pattern of a signalling NaN as a double. \relates <QtGlobal> */ Q_CORE_EXPORT double qSNaN() { return qt_snan(); } +#endif /*! Returns the bit pattern of a quiet NaN as a double. diff --git a/src/corelib/global/qnumeric.h b/src/corelib/global/qnumeric.h index 6a0c64712f..2771eea64f 100644 --- a/src/corelib/global/qnumeric.h +++ b/src/corelib/global/qnumeric.h @@ -44,7 +44,6 @@ QT_BEGIN_NAMESPACE - Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsInf(double d); Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsNaN(double d); Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsFinite(double d); @@ -53,7 +52,9 @@ Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsInf(float f); Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsNaN(float f); Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsFinite(float f); Q_CORE_EXPORT Q_DECL_CONST_FUNCTION int qFpClassify(float val); +#if QT_CONFIG(signaling_nan) Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qSNaN(); +#endif Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qQNaN(); Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qInf(); @@ -61,7 +62,9 @@ Q_CORE_EXPORT quint32 qFloatDistance(float a, float b); Q_CORE_EXPORT quint64 qFloatDistance(double a, double b); #define Q_INFINITY (QT_PREPEND_NAMESPACE(qInf)()) -#define Q_SNAN (QT_PREPEND_NAMESPACE(qSNaN)()) +#if QT_CONFIG(signaling_nan) +# define Q_SNAN (QT_PREPEND_NAMESPACE(qSNaN)()) +#endif #define Q_QNAN (QT_PREPEND_NAMESPACE(qQNaN)()) QT_END_NAMESPACE diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h index 21f9cfbef0..86e7997680 100644 --- a/src/corelib/global/qnumeric_p.h +++ b/src/corelib/global/qnumeric_p.h @@ -133,13 +133,14 @@ Q_DECL_CONSTEXPR Q_DECL_CONST_FUNCTION static inline double qt_inf() noexcept return std::numeric_limits<double>::infinity(); } -// Signaling NaN +#if QT_CONFIG(signaling_nan) Q_DECL_CONSTEXPR Q_DECL_CONST_FUNCTION static inline double qt_snan() noexcept { Q_STATIC_ASSERT_X(std::numeric_limits<double>::has_signaling_NaN, "platform has no definition for signaling NaN for type double"); return std::numeric_limits<double>::signaling_NaN(); } +#endif // Quiet NaN Q_DECL_CONSTEXPR Q_DECL_CONST_FUNCTION static inline double qt_qnan() noexcept diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index e5b2399566..3cbd40b772 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -90,47 +90,6 @@ DECLSPEC_IMPORT BOOLEAN WINAPI SystemFunction036(PVOID RandomBuffer, ULONG Rando QT_BEGIN_NAMESPACE -#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND) -static qsizetype qt_random_cpu(void *buffer, qsizetype count) noexcept; - -# ifdef Q_PROCESSOR_X86_64 -# define _rdrandXX_step _rdrand64_step -# else -# define _rdrandXX_step _rdrand32_step -# endif - -static QT_FUNCTION_TARGET(RDRND) qsizetype qt_random_cpu(void *buffer, qsizetype count) noexcept -{ - unsigned *ptr = reinterpret_cast<unsigned *>(buffer); - unsigned *end = ptr + count; - int retries = 10; - - while (ptr + sizeof(qregisteruint)/sizeof(*ptr) <= end) { - if (_rdrandXX_step(reinterpret_cast<qregisteruint *>(ptr))) - ptr += sizeof(qregisteruint)/sizeof(*ptr); - else if (--retries == 0) - goto out; - } - - while (sizeof(*ptr) != sizeof(qregisteruint) && ptr != end) { - bool ok = _rdrand32_step(ptr); - if (!ok && --retries) - continue; - if (ok) - ++ptr; - break; - } - -out: - return ptr - reinterpret_cast<unsigned *>(buffer); -} -#else -static qsizetype qt_random_cpu(void *, qsizetype) -{ - return 0; -} -#endif - enum { // may be "overridden" by a member enum FillBufferNoexcept = true @@ -371,8 +330,8 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin, } qsizetype filled = 0; - if (qt_has_hwrng() && (uint(qt_randomdevice_control.loadAcquire()) & SkipHWRNG) == 0) - filled += qt_random_cpu(buffer, count); + if (qHasHwrng() && (uint(qt_randomdevice_control.loadAcquire()) & SkipHWRNG) == 0) + filled += qRandomCpu(buffer, count); if (filled != count && (uint(qt_randomdevice_control.loadAcquire()) & SkipSystemRNG) == 0) { qsizetype bytesFilled = diff --git a/src/corelib/global/qrandom_p.h b/src/corelib/global/qrandom_p.h index 167f4cc57d..934a9282b8 100644 --- a/src/corelib/global/qrandom_p.h +++ b/src/corelib/global/qrandom_p.h @@ -81,14 +81,6 @@ static const struct { } qt_randomdevice_control; #endif -inline bool qt_has_hwrng() -{ -#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND) - return qCpuHasFeature(RDRND); -#else - return false; -#endif -} QT_END_NAMESPACE diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index a6f8b45ea3..89834de29f 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -249,16 +249,18 @@ QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request) isSymLink(). The symLinkTarget() function provides the name of the file the symlink points to. - On Unix (including \macos and iOS), the symlink has the same size() has - the file it points to, because Unix handles symlinks - transparently; similarly, opening a symlink using QFile - effectively opens the link's target. For example: + On Unix (including \macos and iOS), the property getter functions in this + class return the properties such as times and size of the target file, not + the symlink, because Unix handles symlinks transparently. Opening a symlink + using QFile effectively opens the link's target. For example: \snippet code/src_corelib_io_qfileinfo.cpp 0 - On Windows, shortcuts are \c .lnk files. The reported size() is that of - the shortcut (not the link's target), and opening a shortcut using QFile - opens the \c .lnk file. For example: + On Windows, shortcuts (\c .lnk files) are currently treated as symlinks. As + on Unix systems, the property getters return the size of the targeted file, + not the \c .lnk file itself. This behavior is deprecated and will likely be + removed in a future version of Qt, after which \c .lnk files will be treated + as regular files. \snippet code/src_corelib_io_qfileinfo.cpp 1 @@ -903,6 +905,9 @@ QDir QFileInfo::absoluteDir() const /*! Returns \c true if the user can read the file; otherwise returns \c false. + If the file is a symlink, this function returns true if the target is + readable (not the symlink). + \note If the \l{NTFS permissions} check has not been enabled, the result on Windows will merely reflect whether the file exists. @@ -920,6 +925,9 @@ bool QFileInfo::isReadable() const /*! Returns \c true if the user can write to the file; otherwise returns \c false. + If the file is a symlink, this function returns true if the target is + writeable (not the symlink). + \note If the \l{NTFS permissions} check has not been enabled, the result on Windows will merely reflect whether the file is marked as Read Only. @@ -937,6 +945,9 @@ bool QFileInfo::isWritable() const /*! Returns \c true if the file is executable; otherwise returns \c false. + If the file is a symlink, this function returns true if the target is + executable (not the symlink). + \sa isReadable(), isWritable(), permission() */ bool QFileInfo::isExecutable() const @@ -951,8 +962,13 @@ bool QFileInfo::isExecutable() const /*! Returns \c true if this is a `hidden' file; otherwise returns \c false. - \b{Note:} This function returns \c true for the special entries - "." and ".." on Unix, even though QDir::entryList threats them as shown. + \b{Note:} This function returns \c true for the special entries "." and + ".." on Unix, even though QDir::entryList threats them as shown. And note + that, since this function inspects the file name, on Unix it will inspect + the name of the symlink, if this file is a symlink, not the target's name. + + On Windows, this function returns \c true if the target file is hidden (not + the symlink). */ bool QFileInfo::isHidden() const { @@ -991,6 +1007,9 @@ bool QFileInfo::isNativePath() const link to a file. Returns \c false if the object points to something which isn't a file, such as a directory. + If the file is a symlink, this function returns true if the target is a + regular file (not the symlink). + \sa isDir(), isSymLink(), isBundle() */ bool QFileInfo::isFile() const @@ -1006,6 +1025,9 @@ bool QFileInfo::isFile() const Returns \c true if this object points to a directory or to a symbolic link to a directory; otherwise returns \c false. + If the file is a symlink, this function returns true if the target is a + directory (not the symlink). + \sa isFile(), isSymLink(), isBundle() */ bool QFileInfo::isDir() const @@ -1023,6 +1045,9 @@ bool QFileInfo::isDir() const Returns \c true if this object points to a bundle or to a symbolic link to a bundle on \macos and iOS; otherwise returns \c false. + If the file is a symlink, this function returns true if the target is a + bundle (not the symlink). + \sa isDir(), isSymLink(), isFile() */ bool QFileInfo::isBundle() const @@ -1044,7 +1069,8 @@ bool QFileInfo::isBundle() const the \l{symLinkTarget()}{link's target}. In addition, true will be returned for shortcuts (\c *.lnk files) on - Windows. Opening those will open the \c .lnk file itself. + Windows. This behavior is deprecated and will likely change in a future + version of Qt. Opening those will open the \c .lnk file itself. Example: @@ -1190,6 +1216,9 @@ QString QFileInfo::symLinkTarget() const milliseconds). On Windows, it will return an empty string unless the \l{NTFS permissions} check has been enabled. + If the file is a symlink, this function returns the owner of the target + (not the symlink). + \sa ownerId(), group(), groupId() */ QString QFileInfo::owner() const @@ -1206,6 +1235,9 @@ QString QFileInfo::owner() const On Windows and on systems where files do not have owners this function returns ((uint) -2). + If the file is a symlink, this function returns the id of the owner of the target + (not the symlink). + \sa owner(), group(), groupId() */ uint QFileInfo::ownerId() const @@ -1225,6 +1257,9 @@ uint QFileInfo::ownerId() const This function can be time consuming under Unix (in the order of milliseconds). + If the file is a symlink, this function returns the owning group of the + target (not the symlink). + \sa groupId(), owner(), ownerId() */ QString QFileInfo::group() const @@ -1241,6 +1276,9 @@ QString QFileInfo::group() const On Windows and on systems where files do not have groups this function always returns (uint) -2. + If the file is a symlink, this function returns the id of the group owning the + target (not the symlink). + \sa group(), owner(), ownerId() */ uint QFileInfo::groupId() const @@ -1266,6 +1304,9 @@ uint QFileInfo::groupId() const Example: \snippet code/src_corelib_io_qfileinfo.cpp 10 + If the file is a symlink, this function checks the permissions of the + target (not the symlink). + \sa isReadable(), isWritable(), isExecutable() */ bool QFileInfo::permission(QFile::Permissions permissions) const @@ -1288,6 +1329,9 @@ bool QFileInfo::permission(QFile::Permissions permissions) const \note The result might be inaccurate on Windows if the \l{NTFS permissions} check has not been enabled. + + If the file is a symlink, this function returns the permissions of the + target (not the symlink). */ QFile::Permissions QFileInfo::permissions() const { @@ -1305,6 +1349,9 @@ QFile::Permissions QFileInfo::permissions() const Returns the file size in bytes. If the file does not exist or cannot be fetched, 0 is returned. + If the file is a symlink, the size of the target file is returned + (not the symlink). + \sa exists() */ qint64 QFileInfo::size() const @@ -1334,6 +1381,9 @@ qint64 QFileInfo::size() const the time the file was created, metadataChangeTime() to get the time its metadata was last changed, or lastModified() to get the time it was last modified. + If the file is a symlink, the time of the target file is returned + (not the symlink). + \sa birthTime(), metadataChangeTime(), lastModified(), lastRead() */ QDateTime QFileInfo::created() const @@ -1352,6 +1402,9 @@ QDateTime QFileInfo::created() const If the file birth time is not available, this function returns an invalid QDateTime. + If the file is a symlink, the time of the target file is returned + (not the symlink). + \sa lastModified(), lastRead(), metadataChangeTime() */ QDateTime QFileInfo::birthTime() const @@ -1366,6 +1419,9 @@ QDateTime QFileInfo::birthTime() const user writes or sets inode information (for example, changing the file permissions). + If the file is a symlink, the time of the target file is returned + (not the symlink). + \sa lastModified(), lastRead() */ QDateTime QFileInfo::metadataChangeTime() const @@ -1376,6 +1432,9 @@ QDateTime QFileInfo::metadataChangeTime() const /*! Returns the date and local time when the file was last modified. + If the file is a symlink, the time of the target file is returned + (not the symlink). + \sa birthTime(), lastRead(), metadataChangeTime(), fileTime() */ QDateTime QFileInfo::lastModified() const @@ -1389,6 +1448,9 @@ QDateTime QFileInfo::lastModified() const On platforms where this information is not available, returns the same as lastModified(). + If the file is a symlink, the time of the target file is returned + (not the symlink). + \sa birthTime(), lastModified(), metadataChangeTime(), fileTime() */ QDateTime QFileInfo::lastRead() const @@ -1402,6 +1464,9 @@ QDateTime QFileInfo::lastRead() const Returns the file time specified by \a time. If the time cannot be determined, an invalid date time is returned. + If the file is a symlink, the time of the target file is returned + (not the symlink). + \sa QFile::FileTime, QDateTime::isValid() */ QDateTime QFileInfo::fileTime(QFile::FileTime time) const diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp index 2d09c277eb..74b7e820d9 100644 --- a/src/corelib/io/qfilesystemiterator_unix.cpp +++ b/src/corelib/io/qfilesystemiterator_unix.cpp @@ -69,7 +69,9 @@ static bool checkNameDecodable(const char *d_name, qsizetype len) # ifdef QT_LOCALE_IS_UTF8 int mibEnum = 106; # else - int mibEnum = codec->mibEnum(); + int mibEnum = 4; // Latin 1 + if (codec) + mibEnum = codec->mibEnum(); # endif if (Q_LIKELY(mibEnum == 106)) // UTF-8 return QUtf8::isValidUtf8(d_name, len).isValidUtf8; diff --git a/src/corelib/kernel/qeventdispatcher_cf.mm b/src/corelib/kernel/qeventdispatcher_cf.mm index 33c231987f..b9e334f1f4 100644 --- a/src/corelib/kernel/qeventdispatcher_cf.mm +++ b/src/corelib/kernel/qeventdispatcher_cf.mm @@ -423,7 +423,7 @@ bool QEventDispatcherCoreFoundation::processPostedEvents() m_processEvents.processedPostedEvents = true; qCDebug(lcEventDispatcher) << "Sending posted events for" - << QEventLoop::ProcessEventsFlags(m_processEvents.flags.load()); + << QEventLoop::ProcessEventsFlags(m_processEvents.flags.loadRelaxed()); QCoreApplication::sendPostedEvents(); return true; diff --git a/src/corelib/thread/qwaitcondition_p.h b/src/corelib/thread/qwaitcondition_p.h new file mode 100644 index 0000000000..5133e52e92 --- /dev/null +++ b/src/corelib/thread/qwaitcondition_p.h @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com> +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QWAITCONDITION_P_H +#define QWAITCONDITION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qmutex.cpp, qmutex_unix.cpp, and qmutex_win.cpp. This header +// file may change from version to version without notice, or even be +// removed. +// +// We mean it. +// + +#include <QtCore/QWaitCondition> +#include <QtCore/QMutex> +#include <QtCore/QDeadlineTimer> + +#include <condition_variable> +#include <mutex> + +QT_BEGIN_NAMESPACE + +namespace QtPrivate +{ + +#if defined(Q_OS_INTEGRITY) + +class condition_variable; + +class mutex : private QMutex +{ + friend class QtPrivate::condition_variable; +public: + // all special member functions are ok! + // do not expose the (QMutex::Recursive) ctor + // don't use 'using QMutex::lock;' etc as those have the wrong noexcept + + void lock() { return QMutex::lock(); } + void unlock() { return QMutex::unlock(); } + bool try_lock() { return QMutex::tryLock(); } +}; + +class condition_variable : private QWaitCondition +{ +public: + // all special member functions are ok! + + void notify_one() { QWaitCondition::wakeOne(); } + void notify_all() { QWaitCondition::wakeAll(); } + + void wait(std::unique_lock<QtPrivate::mutex> &lock) { QWaitCondition::wait(lock.mutex()); } + template <class Predicate> + void wait(std::unique_lock<QtPrivate::mutex> &lock, Predicate p) + { + while (!p()) + wait(lock); + } + + template <typename Rep, typename Period> + std::cv_status wait_for(std::unique_lock<QtPrivate::mutex> &lock, + const std::chrono::duration<Rep, Period> &d) + { + return QWaitCondition::wait(lock.mutex(), QDeadlineTimer{d}) + ? std::cv_status::no_timeout + : std::cv_status::timeout; + } + template <typename Rep, typename Period, typename Predicate> + bool wait_for(std::unique_lock<QtPrivate::mutex> &lock, + const std::chrono::duration<Rep, Period> &d, Predicate p) + { + const auto timer = QDeadlineTimer{d}; + while (!p()) { + if (!QWaitCondition::wait(lock.mutex(), timer)) + return p(); + } + return true; + } + + template <typename Clock, typename Duration> + std::cv_status wait_until(std::unique_lock<QtPrivate::mutex> &lock, + const std::chrono::time_point<Clock, Duration> &t) + { + return QWaitCondition::wait(lock.mutex(), QDeadlineTimer{t}) + ? std::cv_status::no_timeout + : std::cv_status::timeout; + } + + template <typename Clock, typename Duration, typename Predicate> + bool wait_until(std::unique_lock<QtPrivate::mutex> &lock, + const std::chrono::time_point<Clock, Duration> &t, Predicate p) + { + const auto timer = QDeadlineTimer{t}; + while (!p()) { + if (!QWaitCondition::wait(lock.mutex(), timer)) + return p(); + } + return true; + } + +}; + +#else // Integrity + +using mutex = std::mutex; +using condition_variable = std::condition_variable; + +#endif // Integrity + +} // namespace QtPrivate + +QT_END_NAMESPACE + +#endif /* QWAITCONDITION_P_H */ diff --git a/src/corelib/thread/thread.pri b/src/corelib/thread/thread.pri index 9fc9af0e65..25cf68a324 100644 --- a/src/corelib/thread/thread.pri +++ b/src/corelib/thread/thread.pri @@ -6,6 +6,7 @@ HEADERS += \ thread/qrunnable.h \ thread/qthread.h \ thread/qthreadstorage.h \ + thread/qwaitcondition_p.h \ thread/qwaitcondition.h SOURCES += \ diff --git a/src/corelib/time/qcalendar.cpp b/src/corelib/time/qcalendar.cpp index d706f1d5ab..d308aeba2b 100644 --- a/src/corelib/time/qcalendar.cpp +++ b/src/corelib/time/qcalendar.cpp @@ -701,7 +701,7 @@ const QCalendarBackend *QCalendarBackend::fromEnum(QCalendar::System system) calendar being constructed by other means first. With no argument, the default constructor returns the Gregorian calendar. - \sa QCalendar, System + \sa QCalendar, System, isValid() */ QCalendar::QCalendar() @@ -723,6 +723,15 @@ QCalendar::QCalendar(QLatin1String name) QCalendar::QCalendar(QStringView name) : d(QCalendarBackend::fromName(name)) {} +/* + \fn bool QCalendar::isValid() const + + Returns true if this is a valid calendar object. + + Constructing a calendar with an unrecognised calendar name may result in an + invalid object. Use this method to check after creating a calendar by name. +*/ + // Date queries: /*! diff --git a/src/corelib/time/qcalendar.h b/src/corelib/time/qcalendar.h index dd3df76e17..42c8e150c5 100644 --- a/src/corelib/time/qcalendar.h +++ b/src/corelib/time/qcalendar.h @@ -137,7 +137,7 @@ public: explicit QCalendar(QStringView name); // QCalendar is a trivially copyable value type. - bool isValid() { return d != nullptr; } + bool isValid() const { return d != nullptr; } // Date queries: int daysInMonth(int month, int year = Unspecified) const; diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index 13a54c1210..6ed0efe77d 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -3548,6 +3548,7 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT */ /*! + \since 5.14 \enum QDateTime::YearRange This enumerated type describes the range of years (in the Gregorian diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index ecf1822e42..fb9b5996f6 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -376,6 +376,38 @@ static quint64 detectProcessorFeatures() features &= ~AllAVX512; } +#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND) + /** + * Some AMD CPUs (e.g. AMD A4-6250J and AMD Ryzen 3000-series) have a + * failing random generation instruction, which always returns + * 0xffffffff, even when generation was "successful". + * + * This code checks if hardware random generator generates four consecutive + * equal numbers. If it does, then we probably have a failing one and + * should disable it completely. + * + * https://bugreports.qt.io/browse/QTBUG-69423 + */ + if (features & CpuFeatureRDRND) { + const qsizetype testBufferSize = 4; + unsigned testBuffer[4] = {}; + + const qsizetype generated = qRandomCpu(testBuffer, testBufferSize); + + if (Q_UNLIKELY(generated == testBufferSize && + testBuffer[0] == testBuffer[1] && + testBuffer[1] == testBuffer[2] && + testBuffer[2] == testBuffer[3])) { + + fprintf(stderr, "WARNING: CPU random generator seem to be failing, disable hardware random number generation\n"); + fprintf(stderr, "WARNING: RDRND generated: 0x%x 0x%x 0x%x 0x%x\n", + testBuffer[0], testBuffer[1], testBuffer[2], testBuffer[3]); + + features &= ~CpuFeatureRDRND; + } + } +#endif + return features; } @@ -590,4 +622,40 @@ void qDumpCPUFeatures() puts(""); } +#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND) + +# ifdef Q_PROCESSOR_X86_64 +# define _rdrandXX_step _rdrand64_step +# else +# define _rdrandXX_step _rdrand32_step +# endif + +QT_FUNCTION_TARGET(RDRND) qsizetype qRandomCpu(void *buffer, qsizetype count) noexcept +{ + unsigned *ptr = reinterpret_cast<unsigned *>(buffer); + unsigned *end = ptr + count; + int retries = 10; + + while (ptr + sizeof(qregisteruint)/sizeof(*ptr) <= end) { + if (_rdrandXX_step(reinterpret_cast<qregisteruint *>(ptr))) + ptr += sizeof(qregisteruint)/sizeof(*ptr); + else if (--retries == 0) + goto out; + } + + while (sizeof(*ptr) != sizeof(qregisteruint) && ptr != end) { + bool ok = _rdrand32_step(ptr); + if (!ok && --retries) + continue; + if (ok) + ++ptr; + break; + } + +out: + return ptr - reinterpret_cast<unsigned *>(buffer); +} +#endif + + QT_END_NAMESPACE diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index db2f546651..c28624a25e 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -346,6 +346,15 @@ extern Q_CORE_EXPORT QBasicAtomicInteger<unsigned> qt_cpu_features[2]; #endif Q_CORE_EXPORT quint64 qDetectCpuFeatures(); +#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND) +Q_CORE_EXPORT qsizetype qRandomCpu(void *, qsizetype) noexcept; +#else +static inline qsizetype qRandomCpu(void *, qsizetype) noexcept +{ + return 0; +} +#endif + static inline quint64 qCpuFeatures() { quint64 features = qt_cpu_features[0].loadRelaxed(); @@ -362,6 +371,15 @@ static inline quint64 qCpuFeatures() #define qCpuHasFeature(feature) (((qCompilerCpuFeatures & CpuFeature ## feature) == CpuFeature ## feature) \ || ((qCpuFeatures() & CpuFeature ## feature) == CpuFeature ## feature)) +inline bool qHasHwrng() +{ +#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND) + return qCpuHasFeature(RDRND); +#else + return false; +#endif +} + #define ALIGNMENT_PROLOGUE_16BYTES(ptr, i, length) \ for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((4 - ((reinterpret_cast<quintptr>(ptr) >> 2) & 0x3)) & 0x3))); ++i) diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index 253d05ba2b..6be695e317 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -104,7 +104,7 @@ public: QVarLengthArray<T, Prealloc> &operator=(std::initializer_list<T> list) { - resize(list.size()); + resize(int(list.size())); // ### q6sizetype std::copy(list.begin(), list.end(), QT_MAKE_CHECKED_ARRAY_ITERATOR(this->begin(), this->size())); return *this; |