summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-10-02 01:01:20 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2019-10-02 08:39:15 +0200
commit4c8814a341aace34f9a6011e9ec16048dc0f18b6 (patch)
tree3f3193c51c0883ae70de3ae3a3b225b3c7b9b8cc /src/corelib
parent009d86da2d5a928865819fe44b4d1c78d455bbb9 (diff)
parent8791a8398ac232a8daab98601f1bef88bdf7638f (diff)
Merge remote-tracking branch 'origin/5.15' into dev
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp2
-rw-r--r--src/corelib/global/qconfig-bootstrapped.h1
-rw-r--r--src/corelib/global/qfloat16.cpp47
-rw-r--r--src/corelib/global/qglobal.cpp70
-rw-r--r--src/corelib/global/qnumeric.cpp2
-rw-r--r--src/corelib/global/qnumeric.h7
-rw-r--r--src/corelib/global/qnumeric_p.h3
-rw-r--r--src/corelib/global/qrandom.cpp45
-rw-r--r--src/corelib/global/qrandom_p.h8
-rw-r--r--src/corelib/io/qfileinfo.cpp85
-rw-r--r--src/corelib/io/qfilesystemiterator_unix.cpp4
-rw-r--r--src/corelib/kernel/qeventdispatcher_cf.mm2
-rw-r--r--src/corelib/thread/qwaitcondition_p.h153
-rw-r--r--src/corelib/thread/thread.pri1
-rw-r--r--src/corelib/time/qcalendar.cpp11
-rw-r--r--src/corelib/time/qcalendar.h2
-rw-r--r--src/corelib/time/qdatetime.cpp1
-rw-r--r--src/corelib/tools/qsimd.cpp68
-rw-r--r--src/corelib/tools/qsimd_p.h18
-rw-r--r--src/corelib/tools/qvarlengtharray.h2
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;