summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/codecs/qwindowscodec.cpp8
-rw-r--r--src/corelib/global/qcompilerdetection.h27
-rw-r--r--src/corelib/global/qglobal.cpp4
-rw-r--r--src/corelib/global/qglobal.h6
-rw-r--r--src/corelib/global/qglobalstatic.h2
-rw-r--r--src/corelib/global/qlogging.cpp9
-rw-r--r--src/corelib/global/qnamespace.h1
-rw-r--r--src/corelib/global/qnamespace.qdoc3
-rw-r--r--src/corelib/global/qprocessordetection.h2
-rw-r--r--src/corelib/global/qversiontagging.h4
-rw-r--r--src/corelib/io/qfilesystemengine.cpp14
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp5
-rw-r--r--src/corelib/io/qlockfile.cpp4
-rw-r--r--src/corelib/io/qlockfile_unix.cpp12
-rw-r--r--src/corelib/io/qloggingregistry.cpp3
-rw-r--r--src/corelib/io/qprocess.cpp31
-rw-r--r--src/corelib/io/qprocess_p.h2
-rw-r--r--src/corelib/io/qprocess_unix.cpp35
-rw-r--r--src/corelib/io/qprocess_win.cpp50
-rw-r--r--src/corelib/io/qresource.cpp27
-rw-r--r--src/corelib/io/qtldurl.cpp13
-rw-r--r--src/corelib/io/qtldurl_p.h6
-rw-r--r--src/corelib/io/qurl.cpp78
-rw-r--r--src/corelib/io/qurlquery.cpp16
-rw-r--r--src/corelib/io/qurlrecode.cpp24
-rw-r--r--src/corelib/io/qwindowspipewriter.cpp41
-rw-r--r--src/corelib/io/qwindowspipewriter_p.h4
-rw-r--r--src/corelib/itemmodels/qidentityproxymodel.h1
-rw-r--r--src/corelib/json/qjson.cpp32
-rw-r--r--src/corelib/json/qjson_p.h20
-rw-r--r--src/corelib/json/qjsonobject.cpp81
-rw-r--r--src/corelib/json/qjsonobject.h7
-rw-r--r--src/corelib/json/qjsonvalue.cpp16
-rw-r--r--src/corelib/json/qjsonvalue.h3
-rw-r--r--src/corelib/kernel/qcore_mac_objc.mm2
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp2
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp25
-rw-r--r--src/corelib/kernel/qeventdispatcher_win_p.h4
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt.cpp31
-rw-r--r--src/corelib/kernel/qmetaobject_p.h1
-rw-r--r--src/corelib/kernel/qmetatype.h2
-rw-r--r--src/corelib/kernel/qmetatype_p.h7
-rw-r--r--src/corelib/kernel/qobject.cpp31
-rw-r--r--src/corelib/kernel/qobject_p.h14
-rw-r--r--src/corelib/kernel/qobjectdefs_impl.h2
-rw-r--r--src/corelib/kernel/qwineventnotifier.h4
-rw-r--r--src/corelib/mimetypes/qmimedatabase.cpp4
-rw-r--r--src/corelib/mimetypes/qmimetype.cpp2
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp38
-rw-r--r--src/corelib/plugin/qlibrary.cpp2
-rw-r--r--src/corelib/plugin/qlibrary_win.cpp11
-rw-r--r--src/corelib/plugin/qplugin.qdoc6
-rw-r--r--src/corelib/thread/qatomic.cpp2
-rw-r--r--src/corelib/thread/qmutex.cpp13
-rw-r--r--src/corelib/thread/qmutex.h11
-rw-r--r--src/corelib/thread/qmutexpool.cpp11
-rw-r--r--src/corelib/thread/qmutexpool_p.h5
-rw-r--r--src/corelib/thread/qthread.cpp6
-rw-r--r--src/corelib/thread/qthread.h2
-rw-r--r--src/corelib/thread/qthread_p.h1
-rw-r--r--src/corelib/thread/qthread_unix.cpp33
-rw-r--r--src/corelib/tools/qarraydata.cpp13
-rw-r--r--src/corelib/tools/qdatetime.cpp2
-rw-r--r--src/corelib/tools/qdatetimeparser.cpp33
-rw-r--r--src/corelib/tools/qelapsedtimer_unix.cpp6
-rw-r--r--src/corelib/tools/qharfbuzz_p.h1
-rw-r--r--src/corelib/tools/qhash.h14
-rw-r--r--src/corelib/tools/qlist.h2
-rw-r--r--src/corelib/tools/qlocale.cpp1
-rw-r--r--src/corelib/tools/qmap.h4
-rw-r--r--src/corelib/tools/qscopedpointer.h20
-rw-r--r--src/corelib/tools/qstring.cpp17
-rw-r--r--src/corelib/tools/qtimezone.cpp2
-rw-r--r--src/corelib/tools/qtimezone.h2
-rw-r--r--src/corelib/tools/qunicodetools.cpp71
-rw-r--r--src/corelib/tools/qunicodetools_p.h4
-rw-r--r--src/corelib/tools/qvarlengtharray.h7
-rw-r--r--src/corelib/tools/qvector.h38
78 files changed, 732 insertions, 368 deletions
diff --git a/src/corelib/codecs/qwindowscodec.cpp b/src/corelib/codecs/qwindowscodec.cpp
index e8f7e6f156..813d3c8153 100644
--- a/src/corelib/codecs/qwindowscodec.cpp
+++ b/src/corelib/codecs/qwindowscodec.cpp
@@ -214,10 +214,12 @@ QByteArray QWindowsLocalCodec::convertFromUnicode(const QChar *ch, int uclen, Co
0, 0, 0, &used_def));
// and try again...
} else {
+ // Fail. Probably can't happen in fact (dwFlags is 0).
#ifndef QT_NO_DEBUG
- // Fail.
- qWarning("WideCharToMultiByte: Cannot convert multibyte text (error %d): %s (UTF-8)",
- r, QString(ch, uclen).toLocal8Bit().data());
+ // Can't use qWarning(), as it'll recurse to handle %ls
+ fprintf(stderr,
+ "WideCharToMultiByte: Cannot convert multibyte text (error %d): %ls\n",
+ r, reinterpret_cast<const wchar_t*>(QString(ch, uclen).utf16()));
#endif
break;
}
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index 9a61efd1b2..04f2084591 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -105,6 +105,12 @@
# endif
# define Q_DECL_EXPORT __declspec(dllexport)
# define Q_DECL_IMPORT __declspec(dllimport)
+# if _MSC_VER >= 1800
+# define QT_MAKE_UNCHECKED_ARRAY_ITERATOR(x) stdext::make_unchecked_array_iterator(x)
+# endif
+# if _MSC_VER >= 1500
+# define QT_MAKE_CHECKED_ARRAY_ITERATOR(x, N) stdext::make_checked_array_iterator(x, size_t(N))
+# endif
/* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */
# if defined(__INTEL_COMPILER)
# define Q_DECL_VARIABLE_DEPRECATED
@@ -1017,9 +1023,15 @@
// Also disable <atomic>, since it's clearly not there
# undef Q_COMPILER_ATOMICS
# endif
-# if defined(_LIBCPP_VERSION)
+# if defined(Q_CC_CLANG) && defined(Q_CC_INTEL) && Q_CC_INTEL >= 1500
+// ICC 15.x and 16.0 have their own implementation of std::atomic, which is activated when in Clang mode
+// (probably because libc++'s <atomic> on OS X failed to compile), but they're missing some
+// critical definitions. (Reported as Intel Issue ID 6000117277)
+# define __USE_CONSTEXPR 1
+# define __USE_NOEXCEPT 1
+# elif defined(_LIBCPP_VERSION)
// libc++ uses __has_feature(cxx_atomic), so disable the feature if the compiler
-// doesn't support it. That's required for the Intel compiler on OS X, for example.
+// doesn't support it. That's required for the Intel compiler 14.x or earlier on OS X, for example.
# if !__has_feature(cxx_atomic)
# undef Q_COMPILER_ATOMICS
# endif
@@ -1108,6 +1120,11 @@
# define Q_ALIGNOF(x) alignof(x)
#endif
+#if defined(Q_COMPILER_ALIGNAS)
+# undef Q_DECL_ALIGN
+# define Q_DECL_ALIGN(n) alignas(n)
+#endif
+
/*
* Fallback macros to certain compiler features
*/
@@ -1176,6 +1193,12 @@
#ifndef Q_DECL_CONST_FUNCTION
# define Q_DECL_CONST_FUNCTION Q_DECL_PURE_FUNCTION
#endif
+#ifndef QT_MAKE_UNCHECKED_ARRAY_ITERATOR
+# define QT_MAKE_UNCHECKED_ARRAY_ITERATOR(x) (x)
+#endif
+#ifndef QT_MAKE_CHECKED_ARRAY_ITERATOR
+# define QT_MAKE_CHECKED_ARRAY_ITERATOR(x, N) (x)
+#endif
/*
* SG10's SD-6 feature detection and some useful extensions from Clang and GCC
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 7e4e09c6c7..dd357e4b15 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -1998,6 +1998,7 @@ static inline OSVERSIONINFOEX determineWinOsVersion()
#define pGetModuleHandle GetModuleHandleW
#endif
+#ifndef Q_OS_WINCE
HMODULE ntdll = pGetModuleHandle(L"ntdll.dll");
if (Q_UNLIKELY(!ntdll))
return result;
@@ -2017,6 +2018,9 @@ static inline OSVERSIONINFOEX determineWinOsVersion()
// GetVersionEx() has been deprecated in Windows 8.1 and will return
// only Windows 8 from that version on, so use the kernel API function.
pRtlGetVersion((LPOSVERSIONINFO) &result); // always returns STATUS_SUCCESS
+#else // !Q_OS_WINCE
+ GetVersionEx(&result);
+#endif
return result;
}
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 0d83bc04fe..808f433278 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -573,10 +573,6 @@ Q_DECL_CONSTEXPR inline const T &qBound(const T &min, const T &val, const T &max
# define QT_OSX_DEPLOYMENT_TARGET_BELOW(osx) \
QT_MAC_DEPLOYMENT_TARGET_BELOW(osx, __IPHONE_NA)
-QT_END_NAMESPACE
-Q_FORWARD_DECLARE_OBJC_CLASS(NSAutoreleasePool);
-QT_BEGIN_NAMESPACE
-
// Implemented in qcore_mac_objc.mm
class Q_CORE_EXPORT QMacAutoReleasePool
{
@@ -585,7 +581,7 @@ public:
~QMacAutoReleasePool();
private:
Q_DISABLE_COPY(QMacAutoReleasePool)
- NSAutoreleasePool *pool;
+ void *pool;
};
#endif // Q_OS_MAC
diff --git a/src/corelib/global/qglobalstatic.h b/src/corelib/global/qglobalstatic.h
index 4fb3c4f91f..7a6dea9b92 100644
--- a/src/corelib/global/qglobalstatic.h
+++ b/src/corelib/global/qglobalstatic.h
@@ -116,7 +116,7 @@ QT_BEGIN_NAMESPACE
guard.store(QtGlobalStatic::Destroyed); \
} \
} cleanup; \
- guard.store(QtGlobalStatic::Initialized); \
+ guard.storeRelease(QtGlobalStatic::Initialized); \
} \
} \
return d; \
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 295de9485a..6dc453009b 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -988,15 +988,18 @@ struct QMessagePattern {
#endif
#ifdef QLOGGING_HAVE_BACKTRACE
struct BacktraceParams {
- QString backtraceSeparator;
- int backtraceDepth;
+ QString backtraceSeparator;
+ int backtraceDepth;
};
- QList<BacktraceParams> backtraceArgs; // backtrace argumens in sequence of %{backtrace
+ QVector<BacktraceParams> backtraceArgs; // backtrace argumens in sequence of %{backtrace
#endif
bool fromEnvironment;
static QBasicMutex mutex;
};
+#ifdef QLOGGING_HAVE_BACKTRACE
+Q_DECLARE_TYPEINFO(QMessagePattern::BacktraceParams, Q_MOVABLE_TYPE);
+#endif
QBasicMutex QMessagePattern::mutex;
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index c8699c15fe..06b0f824f6 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -1336,6 +1336,7 @@ public:
ImTextAfterCursor = 0x1000,
ImEnterKeyType = 0x2000,
ImAnchorRectangle = 0x4000,
+ ImInputItemClipRectangle = 0x8000,
ImPlatformData = 0x80000000,
ImQueryInput = ImCursorRectangle | ImCursorPosition | ImSurroundingText |
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 13e2b55e2a..9878ce046a 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -2582,6 +2582,9 @@
\value ImEnterKeyType The Enter key type.
\value ImAnchorRectangle The bounding rectangle of the selection anchor.
This value has been added in Qt 5.7.
+ \value ImInputItemClipRectangle The actual exposed input item rectangle. Parts of the input item might be
+ clipped. This value will take clipping into consideration and return the actual painted
+ item rectangle. The rectangle is in widget coordinates.
Masks:
diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h
index 8c1e041a17..ee94720e7a 100644
--- a/src/corelib/global/qprocessordetection.h
+++ b/src/corelib/global/qprocessordetection.h
@@ -141,6 +141,8 @@
# endif
# if Q_PROCESSOR_ARM >= 5
# define Q_PROCESSOR_ARM_V5
+# else
+# error "ARM architecture too old"
# endif
# if defined(__ARMEL__)
# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
diff --git a/src/corelib/global/qversiontagging.h b/src/corelib/global/qversiontagging.h
index ef3da7c658..1e276dc3e0 100644
--- a/src/corelib/global/qversiontagging.h
+++ b/src/corelib/global/qversiontagging.h
@@ -64,9 +64,9 @@ QT_BEGIN_NAMESPACE
// don't make tags in QtCore, bootstrapped systems or if the user asked not to
#elif defined(Q_CC_GNU) && !defined(Q_OS_ANDROID)
# if defined(Q_PROCESSOR_X86) && (defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD_KERNEL))
-# if defined(Q_PROCESSOR_X86_64) // x86-64 or x32
+# if defined(Q_PROCESSOR_X86_64) && QT_POINTER_SIZE == 8 // x86-64 64-bit
# define QT_VERSION_TAG_RELOC(sym) ".quad " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n"
-# else // x86
+# else // x86 or x86-64 32-bit (x32)
# define QT_VERSION_TAG_RELOC(sym) ".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n"
# endif
# define QT_VERSION_TAG(sym) \
diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp
index 2dad56befd..fd8f251ccb 100644
--- a/src/corelib/io/qfilesystemengine.cpp
+++ b/src/corelib/io/qfilesystemengine.cpp
@@ -264,7 +264,7 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer)
entryFlags |= QFileSystemMetaData::FileType;
else if ((statBuffer.st_mode & S_IFMT) == S_IFDIR)
entryFlags |= QFileSystemMetaData::DirectoryType;
- else
+ else if ((statBuffer.st_mode & S_IFMT) != S_IFBLK)
entryFlags |= QFileSystemMetaData::SequentialType;
// Attributes
@@ -347,6 +347,18 @@ void QFileSystemMetaData::fillFromDirEnt(const QT_DIRENT &entry)
break;
case DT_BLK:
+ knownFlagsMask = QFileSystemMetaData::LinkType
+ | QFileSystemMetaData::FileType
+ | QFileSystemMetaData::DirectoryType
+ | QFileSystemMetaData::BundleType
+ | QFileSystemMetaData::AliasType
+ | QFileSystemMetaData::SequentialType
+ | QFileSystemMetaData::ExistsAttribute;
+
+ entryFlags = QFileSystemMetaData::ExistsAttribute;
+
+ break;
+
case DT_CHR:
case DT_FIFO:
case DT_SOCK:
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 329dfa9fdd..dd71c68edc 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -1308,8 +1308,9 @@ bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSyst
COPYFILE2_EXTENDED_PARAMETERS copyParams = {
sizeof(copyParams), COPY_FILE_FAIL_IF_EXISTS, NULL, NULL, NULL
};
- bool ret = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(),
- (const wchar_t*)target.nativeFilePath().utf16(), &copyParams) != 0;
+ HRESULT hres = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(),
+ (const wchar_t*)target.nativeFilePath().utf16(), &copyParams);
+ bool ret = SUCCEEDED(hres);
#endif // Q_OS_WINRT
if(!ret)
error = QSystemError(::GetLastError(), QSystemError::NativeError);
diff --git a/src/corelib/io/qlockfile.cpp b/src/corelib/io/qlockfile.cpp
index 7e39dc56fb..cb61a52c04 100644
--- a/src/corelib/io/qlockfile.cpp
+++ b/src/corelib/io/qlockfile.cpp
@@ -293,12 +293,12 @@ bool QLockFilePrivate::getLockInfo(qint64 *pid, QString *hostname, QString *appn
QByteArray pidLine = reader.readLine();
pidLine.chop(1);
+ if (pidLine.isEmpty())
+ return false;
QByteArray appNameLine = reader.readLine();
appNameLine.chop(1);
QByteArray hostNameLine = reader.readLine();
hostNameLine.chop(1);
- if (pidLine.isEmpty())
- return false;
qint64 thePid = pidLine.toLongLong();
if (pid)
diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp
index 7255414bdc..03dc5fc660 100644
--- a/src/corelib/io/qlockfile_unix.cpp
+++ b/src/corelib/io/qlockfile_unix.cpp
@@ -151,12 +151,14 @@ static bool fcntlWorksAfterFlock(const QString &fn)
if (fcntlOK.isDestroyed())
return QLockFilePrivate::checkFcntlWorksAfterFlock(fn);
bool *worksPtr = fcntlOK->object(fn);
- if (!worksPtr) {
- worksPtr = new bool(QLockFilePrivate::checkFcntlWorksAfterFlock(fn));
- fcntlOK->insert(fn, worksPtr);
- }
+ if (worksPtr)
+ return *worksPtr;
+
+ const bool val = QLockFilePrivate::checkFcntlWorksAfterFlock(fn);
+ worksPtr = new bool(val);
+ fcntlOK->insert(fn, worksPtr);
- return *worksPtr;
+ return val;
}
static bool setNativeLocks(const QString &fileName, int fd)
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index 818772a399..eaebbc1ffc 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -365,9 +365,6 @@ void QLoggingRegistry::setApiRules(const QString &content)
*/
void QLoggingRegistry::updateRules()
{
- if (categoryFilter != defaultCategoryFilter)
- return;
-
rules = qtConfigRules + configRules + apiRules + envRules;
for (auto it = categories.keyBegin(), end = categories.keyEnd(); it != end; ++it)
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 439f9fce5a..fea5a4c967 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -109,11 +109,13 @@ QT_BEGIN_NAMESPACE
\macro QT_NO_PROCESS_COMBINED_ARGUMENT_START
\relates QProcess
- Disables the QProcess::start() overload taking a single string.
+ Disables the
+ \l {QProcess::start(const QString &, OpenMode)}{QProcess::start()}
+ overload taking a single string.
In most cases where it is used, the user intends for the first argument
to be treated atomically as per the other overload.
- \sa QProcess::start()
+ \sa QProcess::start(const QString &command, OpenMode mode)
*/
/*!
@@ -1098,7 +1100,6 @@ bool QProcessPrivate::_q_canReadStandardError()
*/
bool QProcessPrivate::_q_canWrite()
{
- Q_Q(QProcess);
if (stdinChannel.notifier)
stdinChannel.notifier->setEnabled(false);
@@ -1109,31 +1110,13 @@ bool QProcessPrivate::_q_canWrite()
return false;
}
- qint64 written = writeToStdin(writeBuffer.readPointer(), writeBuffer.nextDataBlockSize());
- if (written < 0) {
- closeChannel(&stdinChannel);
- setErrorAndEmit(QProcess::WriteError);
- return false;
- }
-
-#if defined QPROCESS_DEBUG
- qDebug("QProcessPrivate::canWrite(), wrote %d bytes to the process input", int(written));
-#endif
+ const bool writeSucceeded = writeToStdin();
- if (written != 0) {
- writeBuffer.free(written);
- if (!emittedBytesWritten) {
- emittedBytesWritten = true;
- emit q->bytesWritten(written);
- emittedBytesWritten = false;
- }
- emit q->channelBytesWritten(0, written);
- }
if (stdinChannel.notifier && !writeBuffer.isEmpty())
stdinChannel.notifier->setEnabled(true);
if (writeBuffer.isEmpty() && stdinChannel.closed)
closeWriteChannel();
- return true;
+ return writeSucceeded;
}
/*!
@@ -2531,7 +2514,7 @@ bool QProcess::startDetached(const QString &program,
After the \a command string has been split and unquoted, this function
behaves like the overload which takes the arguments as a string list.
- \sa start()
+ \sa start(const QString &command, OpenMode mode)
*/
bool QProcess::startDetached(const QString &command)
{
diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h
index 1f88c3a043..ae236c8c60 100644
--- a/src/corelib/io/qprocess_p.h
+++ b/src/corelib/io/qprocess_p.h
@@ -379,7 +379,7 @@ public:
qint64 bytesAvailableInChannel(const Channel *channel) const;
qint64 readFromChannel(const Channel *channel, char *data, qint64 maxlen);
- qint64 writeToStdin(const char *data, qint64 maxlen);
+ bool writeToStdin();
void cleanup();
void setError(QProcess::ProcessError error, const QString &description = QString());
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index a5b7692fc9..8c5589538d 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -681,21 +681,36 @@ qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint
return bytesRead;
}
-qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen)
+bool QProcessPrivate::writeToStdin()
{
- qint64 written = qt_safe_write_nosignal(stdinChannel.pipe[1], data, maxlen);
+ const char *data = writeBuffer.readPointer();
+ const qint64 bytesToWrite = writeBuffer.nextDataBlockSize();
+
+ qint64 written = qt_safe_write_nosignal(stdinChannel.pipe[1], data, bytesToWrite);
#if defined QPROCESS_DEBUG
- qDebug("QProcessPrivate::writeToStdin(%p \"%s\", %lld) == %lld",
- data, qt_prettyDebug(data, maxlen, 16).constData(), maxlen, written);
+ qDebug("QProcessPrivate::writeToStdin(), write(%p \"%s\", %lld) == %lld",
+ data, qt_prettyDebug(data, bytesToWrite, 16).constData(), bytesToWrite, written);
if (written == -1)
qDebug("QProcessPrivate::writeToStdin(), failed to write (%s)", qPrintable(qt_error_string(errno)));
#endif
- // If the O_NONBLOCK flag is set and If some data can be written without blocking
- // the process, write() will transfer what it can and return the number of bytes written.
- // Otherwise, it will return -1 and set errno to EAGAIN
- if (written == -1 && errno == EAGAIN)
- written = 0;
- return written;
+ if (written == -1) {
+ // If the O_NONBLOCK flag is set and If some data can be written without blocking
+ // the process, write() will transfer what it can and return the number of bytes written.
+ // Otherwise, it will return -1 and set errno to EAGAIN
+ if (errno == EAGAIN)
+ return true;
+
+ closeChannel(&stdinChannel);
+ setErrorAndEmit(QProcess::WriteError);
+ return false;
+ }
+ writeBuffer.free(written);
+ if (!emittedBytesWritten && written != 0) {
+ emittedBytesWritten = true;
+ emit q_func()->bytesWritten(written);
+ emittedBytesWritten = false;
+ }
+ return true;
}
void QProcessPrivate::terminateProcess()
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index 5d8b567c8c..96b39efe3a 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -49,6 +49,7 @@
#include <qfileinfo.h>
#include <qregexp.h>
#include <qwineventnotifier.h>
+#include <private/qsystemlibrary_p.h>
#include <private/qthread_p.h>
#include <qdebug.h>
@@ -804,21 +805,64 @@ qint64 QProcessPrivate::pipeWriterBytesToWrite() const
return stdinChannel.writer ? stdinChannel.writer->bytesToWrite() : qint64(0);
}
-qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen)
+bool QProcessPrivate::writeToStdin()
{
Q_Q(QProcess);
if (!stdinChannel.writer) {
stdinChannel.writer = new QWindowsPipeWriter(stdinChannel.pipe[1], q);
+ QObject::connect(stdinChannel.writer, &QWindowsPipeWriter::bytesWritten,
+ q, &QProcess::bytesWritten);
QObjectPrivate::connect(stdinChannel.writer, &QWindowsPipeWriter::canWrite,
this, &QProcessPrivate::_q_canWrite);
+ } else {
+ if (stdinChannel.writer->isWriteOperationActive())
+ return true;
}
- return stdinChannel.writer->write(data, maxlen);
+ stdinChannel.writer->write(writeBuffer.read());
+ return true;
+}
+
+// Use ShellExecuteEx() to trigger an UAC prompt when CreateProcess()fails
+// with ERROR_ELEVATION_REQUIRED.
+static bool startDetachedUacPrompt(const QString &programIn, const QStringList &arguments,
+ const QString &workingDir, qint64 *pid)
+{
+ typedef BOOL (WINAPI *ShellExecuteExType)(SHELLEXECUTEINFOW *);
+
+ static const ShellExecuteExType shellExecuteEx = // XP ServicePack 1 onwards.
+ reinterpret_cast<ShellExecuteExType>(QSystemLibrary::resolve(QLatin1String("shell32"),
+ "ShellExecuteExW"));
+ if (!shellExecuteEx)
+ return false;
+
+ const QString args = qt_create_commandline(QString(), arguments); // needs arguments only
+ SHELLEXECUTEINFOW shellExecuteExInfo;
+ memset(&shellExecuteExInfo, 0, sizeof(SHELLEXECUTEINFOW));
+ shellExecuteExInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
+ shellExecuteExInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_UNICODE | SEE_MASK_FLAG_NO_UI;
+ shellExecuteExInfo.lpVerb = L"runas";
+ const QString program = QDir::toNativeSeparators(programIn);
+ shellExecuteExInfo.lpFile = reinterpret_cast<LPCWSTR>(program.utf16());
+ if (!args.isEmpty())
+ shellExecuteExInfo.lpParameters = reinterpret_cast<LPCWSTR>(args.utf16());
+ if (!workingDir.isEmpty())
+ shellExecuteExInfo.lpDirectory = reinterpret_cast<LPCWSTR>(workingDir.utf16());
+ shellExecuteExInfo.nShow = SW_SHOWNORMAL;
+
+ if (!shellExecuteEx(&shellExecuteExInfo))
+ return false;
+ if (pid)
+ *pid = qint64(GetProcessId(shellExecuteExInfo.hProcess));
+ CloseHandle(shellExecuteExInfo.hProcess);
+ return true;
}
bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDir, qint64 *pid)
{
+ static const DWORD errorElevationRequired = 740;
+
QString args = qt_create_commandline(program, arguments);
bool success = false;
PROCESS_INFORMATION pinfo;
@@ -838,6 +882,8 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a
CloseHandle(pinfo.hProcess);
if (pid)
*pid = pinfo.dwProcessId;
+ } else if (GetLastError() == errorElevationRequired) {
+ success = startDetachedUacPrompt(program, arguments, workingDir, pid);
}
return success;
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index 1ead114235..96957ac11d 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -1194,9 +1194,10 @@ protected:
private:
uchar *map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags);
bool unmap(uchar *ptr);
+ void uncompress() const;
qint64 offset;
QResource resource;
- QByteArray uncompressed;
+ mutable QByteArray uncompressed;
protected:
QResourceFileEnginePrivate() : offset(0) { }
};
@@ -1231,13 +1232,6 @@ QResourceFileEngine::QResourceFileEngine(const QString &file) :
{
Q_D(QResourceFileEngine);
d->resource.setFileName(file);
- if(d->resource.isCompressed() && d->resource.size()) {
-#ifndef QT_NO_COMPRESS
- d->uncompressed = qUncompress(d->resource.data(), d->resource.size());
-#else
- Q_ASSERT(!"QResourceFileEngine::open: Qt built without support for compression");
-#endif
- }
}
QResourceFileEngine::~QResourceFileEngine()
@@ -1259,6 +1253,7 @@ bool QResourceFileEngine::open(QIODevice::OpenMode flags)
}
if(flags & QIODevice::WriteOnly)
return false;
+ d->uncompress();
if (!d->resource.isValid()) {
d->errorString = qt_error_string(ENOENT);
return false;
@@ -1324,8 +1319,10 @@ qint64 QResourceFileEngine::size() const
Q_D(const QResourceFileEngine);
if(!d->resource.isValid())
return 0;
- if(d->resource.isCompressed())
+ if (d->resource.isCompressed()) {
+ d->uncompress();
return d->uncompressed.size();
+ }
return d->resource.size();
}
@@ -1493,6 +1490,18 @@ bool QResourceFileEnginePrivate::unmap(uchar *ptr)
Q_UNUSED(ptr);
return true;
}
+
+void QResourceFileEnginePrivate::uncompress() const
+{
+ if (resource.isCompressed() && uncompressed.isEmpty() && resource.size()) {
+#ifndef QT_NO_COMPRESS
+ uncompressed = qUncompress(resource.data(), resource.size());
+#else
+ Q_ASSERT(!"QResourceFileEngine::open: Qt built without support for compression");
+#endif
+ }
+}
+
#endif // !defined(QT_BOOTSTRAPPED)
QT_END_NAMESPACE
diff --git a/src/corelib/io/qtldurl.cpp b/src/corelib/io/qtldurl.cpp
index 3971d55750..dd0ee6068d 100644
--- a/src/corelib/io/qtldurl.cpp
+++ b/src/corelib/io/qtldurl.cpp
@@ -46,7 +46,7 @@
QT_BEGIN_NAMESPACE
-static bool containsTLDEntry(const QString &entry)
+static bool containsTLDEntry(const QStringRef &entry)
{
int index = qt_hash(entry) % tldCount;
@@ -69,6 +69,11 @@ static bool containsTLDEntry(const QString &entry)
return false;
}
+static inline bool containsTLDEntry(const QString &entry)
+{
+ return containsTLDEntry(QStringRef(&entry));
+}
+
/*!
\internal
@@ -86,7 +91,7 @@ Q_CORE_EXPORT QString qTopLevelDomain(const QString &domain)
QString level, tld;
for (int j = sections.count() - 1; j >= 0; --j) {
level.prepend(QLatin1Char('.') + sections.at(j));
- if (qIsEffectiveTLD(level.right(level.size() - 1)))
+ if (qIsEffectiveTLD(level.rightRef(level.size() - 1)))
tld = level;
}
return tld;
@@ -98,7 +103,7 @@ Q_CORE_EXPORT QString qTopLevelDomain(const QString &domain)
Return true if \a domain is a top-level-domain per Qt's copy of the Mozilla public suffix list.
*/
-Q_CORE_EXPORT bool qIsEffectiveTLD(const QString &domain)
+Q_CORE_EXPORT bool qIsEffectiveTLD(const QStringRef &domain)
{
// for domain 'foo.bar.com':
// 1. return if TLD table contains 'foo.bar.com'
@@ -108,7 +113,7 @@ Q_CORE_EXPORT bool qIsEffectiveTLD(const QString &domain)
const int dot = domain.indexOf(QLatin1Char('.'));
if (dot >= 0) {
int count = domain.size() - dot;
- QString wildCardDomain = QLatin1Char('*') + domain.rightRef(count);
+ QString wildCardDomain = QLatin1Char('*') + domain.right(count);
// 2. if table contains '*.bar.com',
// test if table contains '!foo.bar.com'
if (containsTLDEntry(wildCardDomain)) {
diff --git a/src/corelib/io/qtldurl_p.h b/src/corelib/io/qtldurl_p.h
index 35a61797cf..b1fde0c700 100644
--- a/src/corelib/io/qtldurl_p.h
+++ b/src/corelib/io/qtldurl_p.h
@@ -57,7 +57,11 @@
QT_BEGIN_NAMESPACE
Q_CORE_EXPORT QString qTopLevelDomain(const QString &domain);
-Q_CORE_EXPORT bool qIsEffectiveTLD(const QString &domain);
+Q_CORE_EXPORT bool qIsEffectiveTLD(const QStringRef &domain);
+inline bool qIsEffectiveTLD(const QString &domain)
+{
+ return qIsEffectiveTLD(QStringRef(&domain));
+}
QT_END_NAMESPACE
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 3c1d314d20..40fc492d91 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -1049,7 +1049,7 @@ inline void QUrlPrivate::setAuthority(const QString &auth, int from, int end, QU
if (colonIndex == end - 1) {
// found a colon but no digits after it
- setError(PortEmptyError, auth, colonIndex + 1);
+ port = -1;
} else if (uint(colonIndex) < uint(end)) {
unsigned long x = 0;
for (int i = colonIndex + 1; i < end; ++i) {
@@ -1179,7 +1179,7 @@ inline void QUrlPrivate::appendHost(QString &appendTo, QUrl::FormattingOptions o
} else {
// this is either an IPv4Address or a reg-name
// if it is a reg-name, it is already stored in Unicode form
- if (options == QUrl::EncodeUnicode)
+ if (options & QUrl::EncodeUnicode && !(options & 0x4000000))
appendTo += qt_ACE_do(host, ToAceOnly, AllowLeadingDot);
else
appendTo += host;
@@ -2043,14 +2043,15 @@ void QUrl::setAuthority(const QString &authority, ParsingMode mode)
*/
QString QUrl::authority(ComponentFormattingOptions options) const
{
- if (!d) return QString();
+ QString result;
+ if (!d)
+ return result;
if (options == QUrl::FullyDecoded) {
qWarning("QUrl::authority(): QUrl::FullyDecoded is not permitted in this function");
- return QString();
+ return result;
}
- QString result;
d->appendAuthority(result, options, QUrlPrivate::Authority);
return result;
}
@@ -2116,14 +2117,15 @@ void QUrl::setUserInfo(const QString &userInfo, ParsingMode mode)
*/
QString QUrl::userInfo(ComponentFormattingOptions options) const
{
- if (!d) return QString();
+ QString result;
+ if (!d)
+ return result;
if (options == QUrl::FullyDecoded) {
qWarning("QUrl::userInfo(): QUrl::FullyDecoded is not permitted in this function");
- return QString();
+ return result;
}
- QString result;
d->appendUserInfo(result, options, QUrlPrivate::UserInfo);
return result;
}
@@ -2185,10 +2187,9 @@ void QUrl::setUserName(const QString &userName, ParsingMode mode)
*/
QString QUrl::userName(ComponentFormattingOptions options) const
{
- if (!d) return QString();
-
QString result;
- d->appendUserName(result, options);
+ if (d)
+ d->appendUserName(result, options);
return result;
}
@@ -2278,10 +2279,9 @@ void QUrl::setPassword(const QString &password, ParsingMode mode)
*/
QString QUrl::password(ComponentFormattingOptions options) const
{
- if (!d) return QString();
-
QString result;
- d->appendPassword(result, options);
+ if (d)
+ d->appendPassword(result, options);
return result;
}
@@ -2386,12 +2386,12 @@ void QUrl::setHost(const QString &host, ParsingMode mode)
*/
QString QUrl::host(ComponentFormattingOptions options) const
{
- if (!d) return QString();
-
QString result;
- d->appendHost(result, options);
- if (result.startsWith(QLatin1Char('[')))
- return result.mid(1, result.length() - 2);
+ if (d) {
+ d->appendHost(result, options);
+ if (result.startsWith(QLatin1Char('[')))
+ result = result.mid(1, result.length() - 2);
+ }
return result;
}
@@ -2531,10 +2531,9 @@ void QUrl::setPath(const QString &path, ParsingMode mode)
*/
QString QUrl::path(ComponentFormattingOptions options) const
{
- if (!d) return QString();
-
QString result;
- d->appendPath(result, options, QUrlPrivate::Path);
+ if (d)
+ d->appendPath(result, options, QUrlPrivate::Path);
return result;
}
@@ -2974,12 +2973,12 @@ void QUrl::setQuery(const QUrlQuery &query)
*/
QString QUrl::query(ComponentFormattingOptions options) const
{
- if (!d) return QString();
-
QString result;
- d->appendQuery(result, options, QUrlPrivate::Query);
- if (d->hasQuery() && result.isNull())
- result.detach();
+ if (d) {
+ d->appendQuery(result, options, QUrlPrivate::Query);
+ if (d->hasQuery() && result.isNull())
+ result.detach();
+ }
return result;
}
@@ -3047,12 +3046,12 @@ void QUrl::setFragment(const QString &fragment, ParsingMode mode)
*/
QString QUrl::fragment(ComponentFormattingOptions options) const
{
- if (!d) return QString();
-
QString result;
- d->appendFragment(result, options, QUrlPrivate::Fragment);
- if (d->hasFragment() && result.isNull())
- result.detach();
+ if (d) {
+ d->appendFragment(result, options, QUrlPrivate::Fragment);
+ if (d->hasFragment() && result.isNull())
+ result.detach();
+ }
return result;
}
@@ -3269,9 +3268,10 @@ QString QUrl::url(FormattingOptions options) const
*/
QString QUrl::toString(FormattingOptions options) const
{
+ QString url;
if (!isValid()) {
// also catches isEmpty()
- return QString();
+ return url;
}
if (options == QUrl::FullyDecoded) {
qWarning("QUrl: QUrl::FullyDecoded is not permitted when reconstructing the full URL");
@@ -3288,11 +3288,10 @@ QString QUrl::toString(FormattingOptions options) const
&& (!d->hasQuery() || options.testFlag(QUrl::RemoveQuery))
&& (!d->hasFragment() || options.testFlag(QUrl::RemoveFragment))
&& isLocalFile()) {
- return d->toLocalFile(options);
+ url = d->toLocalFile(options);
+ return url;
}
- QString url;
-
// for the full URL, we consider that the reserved characters are prettier if encoded
if (options & DecodeReserved)
options &= ~EncodeReserved;
@@ -4006,16 +4005,17 @@ static inline void appendComponentIfPresent(QString &msg, bool present, const ch
*/
QString QUrl::errorString() const
{
+ QString msg;
if (!d)
- return QString();
+ return msg;
QString errorSource;
int errorPosition = 0;
QUrlPrivate::ErrorCode errorCode = d->validityError(&errorSource, &errorPosition);
if (errorCode == QUrlPrivate::NoError)
- return QString();
+ return msg;
- QString msg = errorMessage(errorCode, errorSource, errorPosition);
+ msg += errorMessage(errorCode, errorSource, errorPosition);
msg += QLatin1String("; source was \"");
msg += errorSource;
msg += QLatin1String("\";");
diff --git a/src/corelib/io/qurlquery.cpp b/src/corelib/io/qurlquery.cpp
index a6351d3a21..231a26c211 100644
--- a/src/corelib/io/qurlquery.cpp
+++ b/src/corelib/io/qurlquery.cpp
@@ -43,6 +43,8 @@
#include <QtCore/qhashfunctions.h>
#include <QtCore/qstringlist.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
/*!
@@ -754,14 +756,12 @@ void QUrlQuery::removeQueryItem(const QString &key)
void QUrlQuery::removeAllQueryItems(const QString &key)
{
if (d.constData()) {
- QString encodedKey = d->recodeFromUser(key);
- Map::iterator it = d->itemList.begin();
- while (it != d->itemList.end()) {
- if (it->first == encodedKey)
- it = d->itemList.erase(it);
- else
- ++it;
- }
+ const QString encodedKey = d->recodeFromUser(key);
+ auto firstEqualsEncodedKey = [&encodedKey](const QPair<QString, QString> &item) {
+ return item.first == encodedKey;
+ };
+ const auto end = d->itemList.end();
+ d->itemList.erase(std::remove_if(d->itemList.begin(), end, firstEqualsEncodedKey), end);
}
}
diff --git a/src/corelib/io/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp
index de6476de84..ce90ab49d3 100644
--- a/src/corelib/io/qurlrecode.cpp
+++ b/src/corelib/io/qurlrecode.cpp
@@ -234,6 +234,30 @@ static void ensureDetached(QString &result, ushort *&output, const ushort *begin
namespace {
struct QUrlUtf8Traits : public QUtf8BaseTraitsNoAscii
{
+ // From RFC 3987:
+ // iunreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" / ucschar
+ //
+ // ucschar = %xA0-D7FF / %xF900-FDCF / %xFDF0-FFEF
+ // / %x10000-1FFFD / %x20000-2FFFD / %x30000-3FFFD
+ // / %x40000-4FFFD / %x50000-5FFFD / %x60000-6FFFD
+ // / %x70000-7FFFD / %x80000-8FFFD / %x90000-9FFFD
+ // / %xA0000-AFFFD / %xB0000-BFFFD / %xC0000-CFFFD
+ // / %xD0000-DFFFD / %xE1000-EFFFD
+ //
+ // iprivate = %xE000-F8FF / %xF0000-FFFFD / %x100000-10FFFD
+ //
+ // That RFC allows iprivate only as part of iquery, but we don't know here
+ // whether we're looking at a query or another part of an URI, so we accept
+ // them too. The definition above excludes U+FFF0 to U+FFFD from appearing
+ // unencoded, but we see no reason for its exclusion, so we allow them to
+ // be decoded (and we need U+FFFD the replacement character to indicate
+ // failure to decode).
+ //
+ // That means we must disallow:
+ // * unpaired surrogates (QUtf8Functions takes care of that for us)
+ // * non-characters
+ static const bool allowNonCharacters = false;
+
// override: our "bytes" are three percent-encoded UTF-16 characters
static void appendByte(ushort *&ptr, uchar b)
{
diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp
index 79e7d13eb5..ab179641f8 100644
--- a/src/corelib/io/qwindowspipewriter.cpp
+++ b/src/corelib/io/qwindowspipewriter.cpp
@@ -79,21 +79,19 @@ QWindowsPipeWriter::~QWindowsPipeWriter()
bool QWindowsPipeWriter::waitForWrite(int msecs)
{
- if (!writeSequenceStarted)
- return false;
-
if (bytesWrittenPending) {
- if (!inBytesWritten)
- emitPendingBytesWrittenValue();
+ emitPendingBytesWrittenValue();
return true;
}
+ if (!writeSequenceStarted)
+ return false;
+
if (!waitForNotification(msecs))
return false;
if (bytesWrittenPending) {
- if (!inBytesWritten)
- emitPendingBytesWrittenValue();
+ emitPendingBytesWrittenValue();
return true;
}
@@ -102,20 +100,24 @@ bool QWindowsPipeWriter::waitForWrite(int msecs)
qint64 QWindowsPipeWriter::bytesToWrite() const
{
- return numberOfBytesToWrite;
+ return numberOfBytesToWrite + pendingBytesWrittenValue;
}
void QWindowsPipeWriter::emitPendingBytesWrittenValue()
{
if (bytesWrittenPending) {
+ // Reset the state even if we don't emit bytesWritten().
+ // It's a defined behavior to not re-emit this signal recursively.
bytesWrittenPending = false;
const qint64 bytes = pendingBytesWrittenValue;
pendingBytesWrittenValue = 0;
- inBytesWritten = true;
- emit bytesWritten(bytes);
- inBytesWritten = false;
emit canWrite();
+ if (!inBytesWritten) {
+ inBytesWritten = true;
+ emit bytesWritten(bytes);
+ inBytesWritten = false;
+ }
}
}
@@ -135,6 +137,8 @@ void QWindowsPipeWriter::notified(DWORD errorCode, DWORD numberOfBytesWritten)
notifiedCalled = true;
writeSequenceStarted = false;
numberOfBytesToWrite = 0;
+ Q_ASSERT(errorCode != ERROR_SUCCESS || numberOfBytesWritten == DWORD(buffer.size()));
+ buffer.clear();
switch (errorCode) {
case ERROR_SUCCESS:
@@ -179,21 +183,26 @@ bool QWindowsPipeWriter::waitForNotification(int timeout)
return notifiedCalled;
}
-qint64 QWindowsPipeWriter::write(const char *ptr, qint64 maxlen)
+bool QWindowsPipeWriter::write(const QByteArray &ba)
{
if (writeSequenceStarted)
- return 0;
+ return false;
overlapped.clear();
- numberOfBytesToWrite = maxlen;
+ buffer = ba;
+ numberOfBytesToWrite = buffer.size();
stopped = false;
writeSequenceStarted = true;
- if (!WriteFileEx(handle, ptr, maxlen, &overlapped, &writeFileCompleted)) {
+ if (!WriteFileEx(handle, buffer.constData(), numberOfBytesToWrite,
+ &overlapped, &writeFileCompleted)) {
writeSequenceStarted = false;
+ numberOfBytesToWrite = 0;
+ buffer.clear();
qErrnoWarning("QWindowsPipeWriter::write failed.");
+ return false;
}
- return maxlen;
+ return true;
}
void QWindowsPipeWriter::stop()
diff --git a/src/corelib/io/qwindowspipewriter_p.h b/src/corelib/io/qwindowspipewriter_p.h
index 59f20edae0..3c641670b6 100644
--- a/src/corelib/io/qwindowspipewriter_p.h
+++ b/src/corelib/io/qwindowspipewriter_p.h
@@ -53,6 +53,7 @@
#include <qelapsedtimer.h>
#include <qobject.h>
+#include <qbytearray.h>
#include <qt_windows.h>
QT_BEGIN_NAMESPACE
@@ -112,7 +113,7 @@ public:
explicit QWindowsPipeWriter(HANDLE pipeWriteEnd, QObject *parent = 0);
~QWindowsPipeWriter();
- qint64 write(const char *data, qint64 maxlen);
+ bool write(const QByteArray &ba);
void stop();
bool waitForWrite(int msecs);
bool isWriteOperationActive() const { return writeSequenceStarted; }
@@ -142,6 +143,7 @@ private:
HANDLE handle;
Overlapped overlapped;
+ QByteArray buffer;
qint64 numberOfBytesToWrite;
qint64 pendingBytesWrittenValue;
bool stopped;
diff --git a/src/corelib/itemmodels/qidentityproxymodel.h b/src/corelib/itemmodels/qidentityproxymodel.h
index 7a75f42d81..e93740c1a2 100644
--- a/src/corelib/itemmodels/qidentityproxymodel.h
+++ b/src/corelib/itemmodels/qidentityproxymodel.h
@@ -62,6 +62,7 @@ public:
QModelIndex mapFromSource(const QModelIndex& sourceIndex) const Q_DECL_OVERRIDE;
QModelIndex mapToSource(const QModelIndex& proxyIndex) const Q_DECL_OVERRIDE;
QModelIndex parent(const QModelIndex& child) const Q_DECL_OVERRIDE;
+ using QObject::parent;
int rowCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) Q_DECL_OVERRIDE;
diff --git a/src/corelib/json/qjson.cpp b/src/corelib/json/qjson.cpp
index 24fcaf0937..bb98e25fa5 100644
--- a/src/corelib/json/qjson.cpp
+++ b/src/corelib/json/qjson.cpp
@@ -179,7 +179,29 @@ void Base::removeItems(int pos, int numItems)
length -= numItems;
}
-int Object::indexOf(const QString &key, bool *exists)
+int Object::indexOf(const QString &key, bool *exists) const
+{
+ int min = 0;
+ int n = length;
+ while (n > 0) {
+ int half = n >> 1;
+ int middle = min + half;
+ if (*entryAt(middle) >= key) {
+ n = half;
+ } else {
+ min = middle + 1;
+ n -= half + 1;
+ }
+ }
+ if (min < (int)length && *entryAt(min) == key) {
+ *exists = true;
+ return min;
+ }
+ *exists = false;
+ return min;
+}
+
+int Object::indexOf(QLatin1String key, bool *exists) const
{
int min = 0;
int n = length;
@@ -248,6 +270,14 @@ bool Entry::operator ==(const QString &key) const
return (shallowKey() == key);
}
+bool Entry::operator==(QLatin1String key) const
+{
+ if (value.latinKey)
+ return shallowLatin1Key() == key;
+ else
+ return shallowKey() == key;
+}
+
bool Entry::operator ==(const Entry &other) const
{
if (value.latinKey) {
diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h
index e5010c2da7..5e34845fe3 100644
--- a/src/corelib/json/qjson_p.h
+++ b/src/corelib/json/qjson_p.h
@@ -122,6 +122,7 @@ QT_BEGIN_NAMESPACE
Other measurements have shown a slightly bigger binary size than a compact text
representation where all possible whitespace was stripped out.
*/
+#define Q_DECLARE_JSONPRIVATE_TYPEINFO(Class, Flags) } Q_DECLARE_TYPEINFO(QJsonPrivate::Class, Flags); namespace QJsonPrivate {
namespace QJsonPrivate {
class Array;
@@ -572,7 +573,8 @@ public:
Entry *entryAt(int i) const {
return reinterpret_cast<Entry *>(((char *)this) + table()[i]);
}
- int indexOf(const QString &key, bool *exists);
+ int indexOf(const QString &key, bool *exists) const;
+ int indexOf(QLatin1String key, bool *exists) const;
bool isValid() const;
};
@@ -619,6 +621,7 @@ public:
static uint valueToStore(const QJsonValue &v, uint offset);
static void copyData(const QJsonValue &v, char *dest, bool compressed);
};
+Q_DECLARE_JSONPRIVATE_TYPEINFO(Value, Q_PRIMITIVE_TYPE)
inline Value Array::at(int i) const
{
@@ -673,6 +676,10 @@ public:
inline bool operator !=(const QString &key) const { return !operator ==(key); }
inline bool operator >=(const QString &key) const;
+ bool operator==(QLatin1String key) const;
+ inline bool operator!=(QLatin1String key) const { return !operator ==(key); }
+ inline bool operator>=(QLatin1String key) const;
+
bool operator ==(const Entry &other) const;
bool operator >=(const Entry &other) const;
};
@@ -685,9 +692,20 @@ inline bool Entry::operator >=(const QString &key) const
return (shallowKey() >= key);
}
+inline bool Entry::operator >=(QLatin1String key) const
+{
+ if (value.latinKey)
+ return shallowLatin1Key() >= key;
+ else
+ return shallowKey() >= key;
+}
+
inline bool operator <(const QString &key, const Entry &e)
{ return e >= key; }
+inline bool operator<(QLatin1String key, const Entry &e)
+{ return e >= key; }
+
class Header {
public:
diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp
index 4ee20ef168..b5b6f36bc6 100644
--- a/src/corelib/json/qjsonobject.cpp
+++ b/src/corelib/json/qjsonobject.cpp
@@ -304,6 +304,7 @@ QVariantHash QJsonObject::toVariantHash() const
{
QVariantHash hash;
if (o) {
+ hash.reserve(o->length);
for (uint i = 0; i < o->length; ++i) {
QJsonPrivate::Entry *e = o->entryAt(i);
hash.insert(e->key(), QJsonValue(d, o, e->value).toVariant());
@@ -374,6 +375,22 @@ QJsonValue QJsonObject::value(const QString &key) const
}
/*!
+ \overload
+ \since 5.7
+*/
+QJsonValue QJsonObject::value(QLatin1String key) const
+{
+ if (!d)
+ return QJsonValue(QJsonValue::Undefined);
+
+ bool keyExists;
+ int i = o->indexOf(key, &keyExists);
+ if (!keyExists)
+ return QJsonValue(QJsonValue::Undefined);
+ return QJsonValue(d, o, o->entryAt(i)->value);
+}
+
+/*!
Returns a QJsonValue representing the value for the key \a key.
This does the same as value().
@@ -388,6 +405,13 @@ QJsonValue QJsonObject::operator [](const QString &key) const
}
/*!
+ \fn QJsonValue QJsonObject::operator [](QLatin1String key) const
+
+ \overload
+ \since 5.7
+*/
+
+/*!
Returns a reference to the value for \a key.
The return value is of type QJsonValueRef, a helper class for QJsonArray
@@ -411,6 +435,16 @@ QJsonValueRef QJsonObject::operator [](const QString &key)
}
/*!
+ \overload
+ \since 5.7
+*/
+QJsonValueRef QJsonObject::operator [](QLatin1String key)
+{
+ // ### optimize me
+ return operator[](QString(key));
+}
+
+/*!
Inserts a new item with the key \a key and a value of \a value.
If there is already an item with the key \a key, then that item's value
@@ -535,6 +569,20 @@ bool QJsonObject::contains(const QString &key) const
}
/*!
+ \overload
+ \since 5.7
+*/
+bool QJsonObject::contains(QLatin1String key) const
+{
+ if (!o)
+ return false;
+
+ bool keyExists;
+ o->indexOf(key, &keyExists);
+ return keyExists;
+}
+
+/*!
Returns \c true if \a other is equal to this object.
*/
bool QJsonObject::operator==(const QJsonObject &other) const
@@ -608,11 +656,31 @@ QJsonObject::iterator QJsonObject::find(const QString &key)
return iterator(this, index);
}
+/*!
+ \overload
+ \since 5.7
+*/
+QJsonObject::iterator QJsonObject::find(QLatin1String key)
+{
+ bool keyExists = false;
+ int index = o ? o->indexOf(key, &keyExists) : 0;
+ if (!keyExists)
+ return end();
+ detach2();
+ return iterator(this, index);
+}
+
/*! \fn QJsonObject::const_iterator QJsonObject::find(const QString &key) const
\overload
*/
+/*! \fn QJsonObject::const_iterator QJsonObject::find(QLatin1String key) const
+
+ \overload
+ \since 5.7
+*/
+
/*!
Returns a const iterator pointing to the item with key \a key in the
map.
@@ -629,6 +697,19 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const
return const_iterator(this, index);
}
+/*!
+ \overload
+ \since 5.7
+*/
+QJsonObject::const_iterator QJsonObject::constFind(QLatin1String key) const
+{
+ bool keyExists = false;
+ int index = o ? o->indexOf(key, &keyExists) : 0;
+ if (!keyExists)
+ return end();
+ return const_iterator(this, index);
+}
+
/*! \fn int QJsonObject::count() const
\overload
diff --git a/src/corelib/json/qjsonobject.h b/src/corelib/json/qjsonobject.h
index 6cffbce83a..e238c84d98 100644
--- a/src/corelib/json/qjsonobject.h
+++ b/src/corelib/json/qjsonobject.h
@@ -86,12 +86,16 @@ public:
bool isEmpty() const;
QJsonValue value(const QString &key) const;
+ QJsonValue value(QLatin1String key) const;
QJsonValue operator[] (const QString &key) const;
+ QJsonValue operator[] (QLatin1String key) const { return value(key); }
QJsonValueRef operator[] (const QString &key);
+ QJsonValueRef operator[] (QLatin1String key);
void remove(const QString &key);
QJsonValue take(const QString &key);
bool contains(const QString &key) const;
+ bool contains(QLatin1String key) const;
bool operator==(const QJsonObject &other) const;
bool operator!=(const QJsonObject &other) const;
@@ -200,8 +204,11 @@ public:
typedef iterator Iterator;
typedef const_iterator ConstIterator;
iterator find(const QString &key);
+ iterator find(QLatin1String key);
const_iterator find(const QString &key) const { return constFind(key); }
+ const_iterator find(QLatin1String key) const { return constFind(key); }
const_iterator constFind(const QString &key) const;
+ const_iterator constFind(QLatin1String key) const;
iterator insert(const QString &key, const QJsonValue &value);
// STL compatibility
diff --git a/src/corelib/json/qjsonvalue.cpp b/src/corelib/json/qjsonvalue.cpp
index 36df146332..b21f59ae35 100644
--- a/src/corelib/json/qjsonvalue.cpp
+++ b/src/corelib/json/qjsonvalue.cpp
@@ -564,6 +564,22 @@ QString QJsonValue::toString(const QString &defaultValue) const
}
/*!
+ Converts the value to a QString and returns it.
+
+ If type() is not String, a null QString will be returned.
+
+ \sa QString::isNull()
+ */
+QString QJsonValue::toString() const
+{
+ if (t != String)
+ return QString();
+ stringData->ref.ref(); // the constructor below doesn't add a ref.
+ QStringDataPtr holder = { stringData };
+ return QString(holder);
+}
+
+/*!
Converts the value to an array and returns it.
If type() is not Array, the \a defaultValue will be returned.
diff --git a/src/corelib/json/qjsonvalue.h b/src/corelib/json/qjsonvalue.h
index 8b6221ea4c..1ce7f745e0 100644
--- a/src/corelib/json/qjsonvalue.h
+++ b/src/corelib/json/qjsonvalue.h
@@ -107,7 +107,8 @@ public:
bool toBool(bool defaultValue = false) const;
int toInt(int defaultValue = 0) const;
double toDouble(double defaultValue = 0) const;
- QString toString(const QString &defaultValue = QString()) const;
+ QString toString() const;
+ QString toString(const QString &defaultValue) const;
QJsonArray toArray() const;
QJsonArray toArray(const QJsonArray &defaultValue) const;
QJsonObject toObject() const;
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm
index a923d83bcf..de491dd43d 100644
--- a/src/corelib/kernel/qcore_mac_objc.mm
+++ b/src/corelib/kernel/qcore_mac_objc.mm
@@ -156,7 +156,7 @@ QMacAutoReleasePool::~QMacAutoReleasePool()
// Drain behaves the same as release, with the advantage that
// if we're ever used in a garbage-collected environment, the
// drain acts as a hint to the garbage collector to collect.
- [pool drain];
+ [static_cast<NSAutoreleasePool*>(pool) drain];
}
// -------------------------------------------------------------------------
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index e319008292..8df384ab09 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -419,7 +419,7 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
if (!isArgvModified(argc, argv)) {
origArgc = argc;
origArgv = new char *[argc];
- std::copy(argv, argv + argc, origArgv);
+ std::copy(argv, argv + argc, QT_MAKE_CHECKED_ARRAY_ITERATOR(origArgv, argc));
}
#endif // Q_OS_WIN && !Q_OS_WINRT
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index b222cf491d..e05de4f085 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -96,7 +96,10 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
QEventDispatcherWin32Private::QEventDispatcherWin32Private()
: threadId(GetCurrentThreadId()), interrupt(false), closingDown(false), internalHwnd(0),
getMessageHook(0), serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0),
- wakeUps(0), activateNotifiersPosted(false)
+ wakeUps(0)
+#ifndef Q_OS_WINCE
+ , activateNotifiersPosted(false)
+#endif
{
}
@@ -177,9 +180,11 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
QSockNot *sn = dict ? dict->value(wp) : 0;
if (sn) {
+#ifndef Q_OS_WINCE
d->doWsaAsyncSelect(sn->fd, 0);
d->active_fd[sn->fd].selected = false;
d->postActivateSocketNotifiers();
+#endif
if (type < 3) {
QEvent event(QEvent::SockAct);
QCoreApplication::sendEvent(sn->obj, &event);
@@ -190,6 +195,7 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
}
}
return 0;
+#ifndef Q_OS_WINCE
} else if (message == WM_QT_ACTIVATENOTIFIERS) {
Q_ASSERT(d != 0);
@@ -204,6 +210,7 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
}
d->activateNotifiersPosted = false;
return 0;
+#endif // !Q_OS_WINCE
} else if (message == WM_QT_SENDPOSTEDEVENTS
// we also use a Windows timer to send posted events when the message queue is full
|| (message == WM_TIMER
@@ -438,11 +445,13 @@ void QEventDispatcherWin32Private::doWsaAsyncSelect(int socket, long event)
WSAAsyncSelect(socket, internalHwnd, event ? int(WM_QT_SOCKETNOTIFIER) : 0, event);
}
+#ifndef Q_OS_WINCE
void QEventDispatcherWin32Private::postActivateSocketNotifiers()
{
if (!activateNotifiersPosted)
activateNotifiersPosted = PostMessage(internalHwnd, WM_QT_ACTIVATENOTIFIERS, 0, 0);
}
+#endif // !Q_OS_WINCE
void QEventDispatcherWin32::createInternalHwnd()
{
@@ -696,16 +705,22 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier)
QSFDict::iterator it = d->active_fd.find(sockfd);
if (it != d->active_fd.end()) {
QSockFd &sd = it.value();
+#ifndef Q_OS_WINCE
if (sd.selected) {
d->doWsaAsyncSelect(sockfd, 0);
sd.selected = false;
}
+#endif // !Q_OS_WINCE
sd.event |= event;
} else {
d->active_fd.insert(sockfd, QSockFd(event));
}
+#ifndef Q_OS_WINCE
d->postActivateSocketNotifiers();
+#else
+ d->doWsaAsyncSelect(sockfd, event);
+#endif
}
void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier)
@@ -734,6 +749,7 @@ void QEventDispatcherWin32::doUnregisterSocketNotifier(QSocketNotifier *notifier
QSFDict::iterator it = d->active_fd.find(sockfd);
if (it != d->active_fd.end()) {
QSockFd &sd = it.value();
+#ifndef Q_OS_WINCE
if (sd.selected)
d->doWsaAsyncSelect(sockfd, 0);
const long event[3] = { FD_READ | FD_CLOSE | FD_ACCEPT, FD_WRITE | FD_CONNECT, FD_OOB };
@@ -744,6 +760,13 @@ void QEventDispatcherWin32::doUnregisterSocketNotifier(QSocketNotifier *notifier
sd.selected = false;
d->postActivateSocketNotifiers();
}
+#else
+ const long event[3] = { FD_READ | FD_CLOSE | FD_ACCEPT, FD_WRITE | FD_CONNECT, FD_OOB };
+ sd.event ^= event[type];
+ d->doWsaAsyncSelect(sockfd, sd.event);
+ if (sd.event == 0)
+ d->active_fd.erase(it);
+#endif // !Q_OS_WINCE
}
QSNDict *sn_vec[3] = { &d->sn_read, &d->sn_write, &d->sn_except };
diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h
index 16a74432df..773315c04f 100644
--- a/src/corelib/kernel/qeventdispatcher_win_p.h
+++ b/src/corelib/kernel/qeventdispatcher_win_p.h
@@ -185,9 +185,11 @@ public:
QSNDict sn_write;
QSNDict sn_except;
QSFDict active_fd;
+#ifndef Q_OS_WINCE
bool activateNotifiersPosted;
- void doWsaAsyncSelect(int socket, long event);
void postActivateSocketNotifiers();
+#endif
+ void doWsaAsyncSelect(int socket, long event);
QList<QWinEventNotifier *> winEventNotifierList;
void activateEventNotifier(QWinEventNotifier * wen);
diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp
index a6f61afc90..2ffcf03eb2 100644
--- a/src/corelib/kernel/qeventdispatcher_winrt.cpp
+++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp
@@ -56,6 +56,7 @@ using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::System::Threading;
using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
using namespace ABI::Windows::UI::Core;
using namespace ABI::Windows::ApplicationModel::Core;
@@ -185,8 +186,34 @@ HRESULT QEventDispatcherWinRT::runOnXamlThread(const std::function<HRESULT ()> &
ComPtr<ICoreWindow> window;
hr = view->get_CoreWindow(&window);
Q_ASSERT_SUCCEEDED(hr);
- hr = window->get_Dispatcher(&dispatcher);
- Q_ASSERT_SUCCEEDED(hr);
+ if (!window) {
+ // In case the application is launched via activation
+ // there might not be a main view (eg ShareTarget).
+ // Hence iterate through the available views and try to find
+ // a dispatcher in there
+ ComPtr<IVectorView<CoreApplicationView*>> appViews;
+ hr = application->get_Views(&appViews);
+ Q_ASSERT_SUCCEEDED(hr);
+ quint32 count;
+ hr = appViews->get_Size(&count);
+ Q_ASSERT_SUCCEEDED(hr);
+ for (quint32 i = 0; i < count; ++i) {
+ hr = appViews->GetAt(i, &view);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = view->get_CoreWindow(&window);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (window) {
+ hr = window->get_Dispatcher(&dispatcher);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (dispatcher)
+ break;
+ }
+ }
+ Q_ASSERT(dispatcher);
+ } else {
+ hr = window->get_Dispatcher(&dispatcher);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
}
HRESULT hr;
diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h
index 54cc9d33c3..9b67d63524 100644
--- a/src/corelib/kernel/qmetaobject_p.h
+++ b/src/corelib/kernel/qmetaobject_p.h
@@ -159,6 +159,7 @@ private:
int _type;
QByteArray _name;
};
+Q_DECLARE_TYPEINFO(QArgumentType, Q_MOVABLE_TYPE);
typedef QVarLengthArray<QArgumentType, 10> QArgumentTypeArray;
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index f4989975ee..a36d247c3c 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -1189,6 +1189,7 @@ public:
public:
template<class T> QAssociativeIterableImpl(const T*p)
: _iterable(p)
+ , _iterator(Q_NULLPTR)
, _metaType_id_key(qMetaTypeId<typename T::key_type>())
, _metaType_flags_key(QTypeInfo<typename T::key_type>::isPointer)
, _metaType_id_value(qMetaTypeId<typename T::mapped_type>())
@@ -1208,6 +1209,7 @@ public:
QAssociativeIterableImpl()
: _iterable(Q_NULLPTR)
+ , _iterator(Q_NULLPTR)
, _metaType_id_key(QMetaType::UnknownType)
, _metaType_flags_key(0)
, _metaType_id_value(QMetaType::UnknownType)
diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h
index 642d1c5d9e..445e912cf7 100644
--- a/src/corelib/kernel/qmetatype_p.h
+++ b/src/corelib/kernel/qmetatype_p.h
@@ -74,10 +74,10 @@ class QTypeModuleInfo
{
public:
enum Module {
- IsCore = !QTypeInfo<T>::isComplex, // Primitive types are in Core
+ IsCore = false,
IsWidget = false,
IsGui = false,
- IsUnknown = !IsCore
+ IsUnknown = true
};
};
@@ -107,7 +107,10 @@ public: \
#define QT_DECLARE_WIDGETS_MODULE_TYPES_ITER(TypeName, TypeId, Name) \
QT_ASSIGN_TYPE_TO_MODULE(Name, QModulesPrivate::Widgets);
+QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(QT_DECLARE_CORE_MODULE_TYPES_ITER)
+QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(QT_DECLARE_CORE_MODULE_TYPES_ITER)
QT_FOR_EACH_STATIC_CORE_CLASS(QT_DECLARE_CORE_MODULE_TYPES_ITER)
+QT_FOR_EACH_STATIC_CORE_POINTER(QT_DECLARE_CORE_MODULE_TYPES_ITER)
QT_FOR_EACH_STATIC_CORE_TEMPLATE(QT_DECLARE_CORE_MODULE_TYPES_ITER)
QT_FOR_EACH_STATIC_GUI_CLASS(QT_DECLARE_GUI_MODULE_TYPES_ITER)
QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_DECLARE_WIDGETS_MODULE_TYPES_ITER)
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index fc5e6abf00..9b421d6a78 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -1130,7 +1130,7 @@ QObjectPrivate::Connection::~Connection()
RTTI support and it works across dynamic library boundaries.
qobject_cast() can also be used in conjunction with interfaces;
- see the \l{tools/plugandpaint}{Plug & Paint} example for details.
+ see the \l{tools/plugandpaint/app}{Plug & Paint} example for details.
\warning If T isn't declared with the Q_OBJECT macro, this
function's return value is undefined.
@@ -2151,8 +2151,8 @@ void QObject::deleteLater()
Returns a translated version of \a sourceText, optionally based on a
\a disambiguation string and value of \a n for strings containing plurals;
- otherwise returns \a sourceText itself if no appropriate translated string
- is available.
+ otherwise returns QString::fromUtf8(\a sourceText) if no appropriate
+ translated string is available.
Example:
\snippet ../widgets/mainwindows/sdi/mainwindow.cpp implicit tr context
@@ -2178,7 +2178,7 @@ void QObject::deleteLater()
translators while performing translations is not supported. Doing
so will probably result in crashes or other undesirable behavior.
- \sa trUtf8(), QCoreApplication::translate(), {Internationalization with Qt}
+ \sa QCoreApplication::translate(), {Internationalization with Qt}
*/
/*!
@@ -3609,18 +3609,21 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
{
int signal_index = signalOffset + local_signal_index;
- if (!sender->d_func()->isSignalConnected(signal_index)
- && !qt_signal_spy_callback_set.signal_begin_callback
- && !qt_signal_spy_callback_set.signal_end_callback) {
- return; // nothing connected to these signals, and no spy
- }
-
if (sender->d_func()->blockSig)
return;
- if (sender->d_func()->declarativeData && QAbstractDeclarativeData::signalEmitted)
+ if (sender->d_func()->isDeclarativeSignalConnected(signal_index)
+ && QAbstractDeclarativeData::signalEmitted) {
QAbstractDeclarativeData::signalEmitted(sender->d_func()->declarativeData, sender,
signal_index, argv);
+ }
+
+ if (!sender->d_func()->isSignalConnected(signal_index, /*checkDeclarative =*/ false)
+ && !qt_signal_spy_callback_set.signal_begin_callback
+ && !qt_signal_spy_callback_set.signal_end_callback) {
+ // The possible declarative connection is done, and nothing else is connected, so:
+ return;
+ }
void *empty_argv[] = { 0 };
if (qt_signal_spy_callback_set.signal_begin_callback != 0) {
@@ -4157,11 +4160,11 @@ QDebug operator<<(QDebug dbg, const QObject *o)
Example:
- \snippet ../widgets/tools/plugandpaintplugins/basictools/basictoolsplugin.h 1
+ \snippet ../widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.h 1
\dots
- \snippet ../widgets/tools/plugandpaintplugins/basictools/basictoolsplugin.h 3
+ \snippet ../widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.h 3
- See the \l{tools/plugandpaintplugins/basictools}{Plug & Paint
+ See the \l{tools/plugandpaint/plugins/basictools}{Plug & Paint
Basic Tools} example for details.
\sa Q_DECLARE_INTERFACE(), Q_PLUGIN_METADATA(), {How to Create Qt Plugins}
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index e6ab75f104..4383ece245 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -199,7 +199,8 @@ public:
}
int signalIndex(const char *signalName, const QMetaObject **meta = 0) const;
- inline bool isSignalConnected(uint signalIdx) const;
+ inline bool isSignalConnected(uint signalIdx, bool checkDeclarative = true) const;
+ inline bool isDeclarativeSignalConnected(uint signalIdx) const;
// To allow abitrary objects to call connectNotify()/disconnectNotify() without making
// the API public in QObject. This is used by QQmlNotifierEndpoint.
@@ -250,12 +251,17 @@ public:
\a signal_index must be the index returned by QObjectPrivate::signalIndex;
*/
-inline bool QObjectPrivate::isSignalConnected(uint signal_index) const
+inline bool QObjectPrivate::isSignalConnected(uint signal_index, bool checkDeclarative) const
{
return signal_index >= sizeof(connectedSignals) * 8
|| (connectedSignals[signal_index >> 5] & (1 << (signal_index & 0x1f))
- || (declarativeData && QAbstractDeclarativeData::isSignalConnected
- && QAbstractDeclarativeData::isSignalConnected(declarativeData, q_func(), signal_index)));
+ || (checkDeclarative && isDeclarativeSignalConnected(signal_index)));
+}
+
+inline bool QObjectPrivate::isDeclarativeSignalConnected(uint signal_index) const
+{
+ return declarativeData && QAbstractDeclarativeData::isSignalConnected
+ && QAbstractDeclarativeData::isSignalConnected(declarativeData, q_func(), signal_index);
}
inline QObjectPrivate::Sender *QObjectPrivate::setCurrentSender(QObject *receiver,
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h
index 2da76e1a4e..6ef83a6eb5 100644
--- a/src/corelib/kernel/qobjectdefs_impl.h
+++ b/src/corelib/kernel/qobjectdefs_impl.h
@@ -497,7 +497,7 @@ namespace QtPrivate {
template <typename, typename, typename, typename> struct FunctorCall;
template <int... II, typename... SignalArgs, typename R, typename Function>
struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, Function> {
- static void call(Function f, void **arg) {
+ static void call(Function &f, void **arg) {
f((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
}
};
diff --git a/src/corelib/kernel/qwineventnotifier.h b/src/corelib/kernel/qwineventnotifier.h
index ad712b20a4..f17fa059a1 100644
--- a/src/corelib/kernel/qwineventnotifier.h
+++ b/src/corelib/kernel/qwineventnotifier.h
@@ -54,8 +54,8 @@ class Q_CORE_EXPORT QWinEventNotifier : public QObject
typedef Qt::HANDLE HANDLE;
public:
- explicit QWinEventNotifier(QObject *parent = 0);
- explicit QWinEventNotifier(HANDLE hEvent, QObject *parent = 0);
+ explicit QWinEventNotifier(QObject *parent = Q_NULLPTR);
+ explicit QWinEventNotifier(HANDLE hEvent, QObject *parent = Q_NULLPTR);
~QWinEventNotifier();
void setHandle(HANDLE hEvent);
diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp
index a32031a788..d866d3bcf7 100644
--- a/src/corelib/mimetypes/qmimedatabase.cpp
+++ b/src/corelib/mimetypes/qmimedatabase.cpp
@@ -285,7 +285,7 @@ bool QMimeDatabasePrivate::inherits(const QString &mime, const QString &parent)
\snippet code/src_corelib_mimetype_qmimedatabase.cpp 0
- \sa QMimeType
+ \sa QMimeType, {MIME Type Browser Example}
*/
/*!
@@ -520,7 +520,7 @@ QMimeType QMimeDatabase::mimeTypeForUrl(const QUrl &url) const
return mimeTypeForFile(url.toLocalFile());
const QString scheme = url.scheme();
- if (scheme.startsWith(QLatin1String("http")))
+ if (scheme.startsWith(QLatin1String("http")) || scheme == QLatin1String("mailto"))
return mimeTypeForName(d->defaultMimeType());
return mimeTypeForFile(url.path());
diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp
index 3bdac2109b..80b6a76ecc 100644
--- a/src/corelib/mimetypes/qmimetype.cpp
+++ b/src/corelib/mimetypes/qmimetype.cpp
@@ -107,7 +107,7 @@ void QMimeTypePrivate::addGlobPattern(const QString &pattern)
MIME types can inherit from each other: for instance a C source file is
a specific type of plain text file, so text/x-csrc inherits text/plain.
- \sa QMimeDatabase
+ \sa QMimeDatabase, {MIME Type Browser Example}
*/
/*!
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index c820d53f91..c09dc6c22b 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -56,18 +56,6 @@
QT_BEGIN_NAMESPACE
-namespace {
-
-// avoid duplicate QStringLiteral data:
-inline QString iidKeyLiteral() { return QStringLiteral("IID"); }
-#ifdef QT_SHARED
-inline QString versionKeyLiteral() { return QStringLiteral("version"); }
-#endif
-inline QString metaDataKeyLiteral() { return QStringLiteral("MetaData"); }
-inline QString keysKeyLiteral() { return QStringLiteral("Keys"); }
-
-}
-
class QFactoryLoaderPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QFactoryLoader)
@@ -167,12 +155,12 @@ void QFactoryLoader::update()
QStringList keys;
bool metaDataOk = false;
- QString iid = library->metaData.value(iidKeyLiteral()).toString();
+ QString iid = library->metaData.value(QLatin1String("IID")).toString();
if (iid == QLatin1String(d->iid.constData(), d->iid.size())) {
- QJsonObject object = library->metaData.value(metaDataKeyLiteral()).toObject();
+ QJsonObject object = library->metaData.value(QLatin1String("MetaData")).toObject();
metaDataOk = true;
- QJsonArray k = object.value(keysKeyLiteral()).toArray();
+ QJsonArray k = object.value(QLatin1String("Keys")).toArray();
for (int i = 0; i < k.size(); ++i)
keys += d->cs ? k.at(i).toString() : k.at(i).toString().toLower();
}
@@ -195,9 +183,9 @@ void QFactoryLoader::update()
QLibraryPrivate *previous = d->keyMap.value(key);
int prev_qt_version = 0;
if (previous) {
- prev_qt_version = (int)previous->metaData.value(versionKeyLiteral()).toDouble();
+ prev_qt_version = (int)previous->metaData.value(QLatin1String("version")).toDouble();
}
- int qt_version = (int)library->metaData.value(versionKeyLiteral()).toDouble();
+ int qt_version = (int)library->metaData.value(QLatin1String("version")).toDouble();
if (!previous || (prev_qt_version > QT_VERSION && qt_version <= QT_VERSION)) {
d->keyMap[key] = library;
++keyUsageCount;
@@ -280,7 +268,7 @@ QList<QJsonObject> QFactoryLoader::metaData() const
const auto staticPlugins = QPluginLoader::staticPlugins();
for (const QStaticPlugin &plugin : staticPlugins) {
const QJsonObject object = plugin.metaData();
- if (object.value(iidKeyLiteral()) != QLatin1String(d->iid.constData(), d->iid.size()))
+ if (object.value(QLatin1String("IID")) != QLatin1String(d->iid.constData(), d->iid.size()))
continue;
metaData.append(object);
}
@@ -314,7 +302,7 @@ QObject *QFactoryLoader::instance(int index) const
QVector<QStaticPlugin> staticPlugins = QPluginLoader::staticPlugins();
for (int i = 0; i < staticPlugins.count(); ++i) {
const QJsonObject object = staticPlugins.at(i).metaData();
- if (object.value(iidKeyLiteral()) != QLatin1String(d->iid.constData(), d->iid.size()))
+ if (object.value(QLatin1String("IID")) != QLatin1String(d->iid.constData(), d->iid.size()))
continue;
if (index == 0)
@@ -328,12 +316,10 @@ QObject *QFactoryLoader::instance(int index) const
QMultiMap<int, QString> QFactoryLoader::keyMap() const
{
QMultiMap<int, QString> result;
- const QString metaDataKey = metaDataKeyLiteral();
- const QString keysKey = keysKeyLiteral();
const QList<QJsonObject> metaDataList = metaData();
for (int i = 0; i < metaDataList.size(); ++i) {
- const QJsonObject metaData = metaDataList.at(i).value(metaDataKey).toObject();
- const QJsonArray keys = metaData.value(keysKey).toArray();
+ const QJsonObject metaData = metaDataList.at(i).value(QLatin1String("MetaData")).toObject();
+ const QJsonArray keys = metaData.value(QLatin1String("Keys")).toArray();
const int keyCount = keys.size();
for (int k = 0; k < keyCount; ++k)
result.insert(i, keys.at(k).toString());
@@ -343,12 +329,10 @@ QMultiMap<int, QString> QFactoryLoader::keyMap() const
int QFactoryLoader::indexOf(const QString &needle) const
{
- const QString metaDataKey = metaDataKeyLiteral();
- const QString keysKey = keysKeyLiteral();
const QList<QJsonObject> metaDataList = metaData();
for (int i = 0; i < metaDataList.size(); ++i) {
- const QJsonObject metaData = metaDataList.at(i).value(metaDataKey).toObject();
- const QJsonArray keys = metaData.value(keysKey).toArray();
+ const QJsonObject metaData = metaDataList.at(i).value(QLatin1String("MetaData")).toObject();
+ const QJsonArray keys = metaData.value(QLatin1String("Keys")).toArray();
const int keyCount = keys.size();
for (int k = 0; k < keyCount; ++k) {
if (!keys.at(k).toString().compare(needle, Qt::CaseInsensitive))
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 9babfa4d91..ff04116705 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -1096,8 +1096,6 @@ QString QLibrary::errorString() const
to the library \c shr_64.o in the archive file named \c libGL.a. This
is only supported on the AIX platform.
- Setting PreventUnloadHint will only apply on Unix platforms.
-
The interpretation of the load hints is platform dependent, and if
you use it you are probably making some assumptions on which platform
you are compiling for, so use them only if you understand the consequences
diff --git a/src/corelib/plugin/qlibrary_win.cpp b/src/corelib/plugin/qlibrary_win.cpp
index 982035b49b..48aa0cdbb6 100644
--- a/src/corelib/plugin/qlibrary_win.cpp
+++ b/src/corelib/plugin/qlibrary_win.cpp
@@ -134,6 +134,17 @@ bool QLibraryPrivate::load_sys()
qualifiedFileName = moduleFileName;
else
qualifiedFileName = dir.filePath(moduleFileName);
+
+ if (loadHints() & QLibrary::PreventUnloadHint) {
+ // prevent the unloading of this component
+ HMODULE hmod;
+ bool ok = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_PIN |
+ GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+ reinterpret_cast<const wchar_t *>(pHnd),
+ &hmod);
+ Q_ASSERT(!ok || hmod == pHnd);
+ Q_UNUSED(ok);
+ }
#endif // !Q_OS_WINRT
}
return (pHnd != 0);
diff --git a/src/corelib/plugin/qplugin.qdoc b/src/corelib/plugin/qplugin.qdoc
index 5dcc14b64b..968fb4820a 100644
--- a/src/corelib/plugin/qplugin.qdoc
+++ b/src/corelib/plugin/qplugin.qdoc
@@ -44,11 +44,11 @@
to the interface class called \a ClassName. The \a Identifier must
be unique. For example:
- \snippet plugandpaint/interfaces.h 3
+ \snippet plugandpaint/app/interfaces.h 3
This macro is normally used right after the class definition for
\a ClassName, in a header file. See the
- \l{tools/plugandpaint}{Plug & Paint} example for details.
+ \l{tools/plugandpaint/app}{Plug & Paint} example for details.
If you want to use Q_DECLARE_INTERFACE with interface classes
declared in a namespace then you have to make sure the Q_DECLARE_INTERFACE
@@ -76,7 +76,7 @@
\snippet code/doc_src_qplugin.cpp 1
- See the \l{tools/plugandpaint}{Plug & Paint} example for details.
+ See the \l{tools/plugandpaint/app}{Plug & Paint} example for details.
Note that the class this macro appears on must be default-constructible.
diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp
index 23e816af64..ccb0ee6923 100644
--- a/src/corelib/thread/qatomic.cpp
+++ b/src/corelib/thread/qatomic.cpp
@@ -1289,7 +1289,7 @@
/*!
\fn T *QAtomicPointer::loadAcquire() const
- Atomically loads the value of this QAtomicPointerusing the "Acquire" memory
+ Atomically loads the value of this QAtomicPointer using the "Acquire" memory
ordering. The value is not modified in any way, but note that there's no
guarantee that it remains so.
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index 8d9fa82a7a..0b14ec31c2 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -282,19 +282,22 @@ void QMutex::unlock() Q_DECL_NOTHROW
unlockInternal();
}
+bool QBasicMutex::isRecursive() Q_DECL_NOTHROW
+{
+ return QT_PREPEND_NAMESPACE(isRecursive)(d_ptr.loadAcquire());
+}
+
/*!
- \fn void QMutex::isRecursive()
- \since 5.0
+ \overload
+ \since 5.7
Returns \c true if the mutex is recursive
-
*/
-bool QBasicMutex::isRecursive()
+bool QBasicMutex::isRecursive() const Q_DECL_NOTHROW
{
return QT_PREPEND_NAMESPACE(isRecursive)(d_ptr.loadAcquire());
}
-
/*!
\class QMutexLocker
\inmodule QtCore
diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h
index 57f89aa439..a06bcd99ac 100644
--- a/src/corelib/thread/qmutex.h
+++ b/src/corelib/thread/qmutex.h
@@ -75,7 +75,8 @@ public:
return fastTryLock();
}
- bool isRecursive(); //### Qt6: mark const
+ bool isRecursive() Q_DECL_NOTHROW; //### Qt6: remove me
+ bool isRecursive() const Q_DECL_NOTHROW;
private:
inline bool fastTryLock() Q_DECL_NOTHROW {
@@ -104,7 +105,8 @@ private:
friend class QMutexData;
};
-class Q_CORE_EXPORT QMutex : public QBasicMutex {
+class Q_CORE_EXPORT QMutex : public QBasicMutex
+{
public:
enum RecursionMode { NonRecursive, Recursive };
explicit QMutex(RecursionMode mode = NonRecursive);
@@ -114,7 +116,8 @@ public:
bool tryLock(int timeout = 0) QT_MUTEX_LOCK_NOEXCEPT;
void unlock() Q_DECL_NOTHROW;
- using QBasicMutex::isRecursive;
+ bool isRecursive() const Q_DECL_NOTHROW
+ { return QBasicMutex::isRecursive(); }
private:
Q_DISABLE_COPY(QMutex)
@@ -187,7 +190,7 @@ public:
inline void lock() Q_DECL_NOTHROW {}
inline bool tryLock(int timeout = 0) Q_DECL_NOTHROW { Q_UNUSED(timeout); return true; }
inline void unlock() Q_DECL_NOTHROW {}
- inline bool isRecursive() Q_DECL_NOTHROW { return true; }
+ inline bool isRecursive() const Q_DECL_NOTHROW { return true; }
private:
Q_DISABLE_COPY(QMutex)
diff --git a/src/corelib/thread/qmutexpool.cpp b/src/corelib/thread/qmutexpool.cpp
index 90b6989467..522fd5eac2 100644
--- a/src/corelib/thread/qmutexpool.cpp
+++ b/src/corelib/thread/qmutexpool.cpp
@@ -92,11 +92,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(QMutexPool, globalMutexPool, (QMutex::Recursive))
QMutexPool is destructed.
*/
QMutexPool::QMutexPool(QMutex::RecursionMode recursionMode, int size)
- : mutexes(size), recursionMode(recursionMode)
+ : count(size),
+ mutexes(new QAtomicPointer<QMutex>[size]()), // (): zero-initialize
+ recursionMode(recursionMode)
{
- for (int index = 0; index < mutexes.count(); ++index) {
- mutexes[index].store(0);
- }
}
/*!
@@ -105,8 +104,8 @@ QMutexPool::QMutexPool(QMutex::RecursionMode recursionMode, int size)
*/
QMutexPool::~QMutexPool()
{
- for (int index = 0; index < mutexes.count(); ++index)
- delete mutexes[index].load();
+ qDeleteAll(mutexes, mutexes + count);
+ delete[] mutexes;
}
/*!
diff --git a/src/corelib/thread/qmutexpool_p.h b/src/corelib/thread/qmutexpool_p.h
index 796e65d960..33e9a52cb7 100644
--- a/src/corelib/thread/qmutexpool_p.h
+++ b/src/corelib/thread/qmutexpool_p.h
@@ -66,7 +66,7 @@ public:
~QMutexPool();
inline QMutex *get(const void *address) {
- int index = uint(quintptr(address)) % mutexes.count();
+ int index = uint(quintptr(address)) % count;
QMutex *m = mutexes[index].load();
if (m)
return m;
@@ -78,7 +78,8 @@ public:
private:
QMutex *createMutex(int index);
- QVarLengthArray<QAtomicPointer<QMutex>, 131> mutexes;
+ int count;
+ QAtomicPointer<QMutex> *mutexes;
QMutex::RecursionMode recursionMode;
};
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index 8a797772fc..4aac24f454 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -149,16 +149,12 @@ QThreadPrivate::QThreadPrivate(QThreadData *d)
exited(false), returnCode(-1),
stackSize(0), priority(QThread::InheritPriority), data(d)
{
-#if defined (Q_OS_UNIX)
- thread_id = 0;
-#elif defined (Q_OS_WIN)
+#if defined (Q_OS_WIN)
handle = 0;
# ifndef Q_OS_WINRT
id = 0;
# endif
waiters = 0;
-#endif
-#if defined (Q_OS_WIN)
terminationEnabled = true;
terminatePending = false;
#endif
diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h
index 68ee366277..410f642ca7 100644
--- a/src/corelib/thread/qthread.h
+++ b/src/corelib/thread/qthread.h
@@ -56,7 +56,7 @@ class Q_CORE_EXPORT QThread : public QObject
{
Q_OBJECT
public:
- static Qt::HANDLE currentThreadId() Q_DECL_NOTHROW;
+ static Qt::HANDLE currentThreadId() Q_DECL_NOTHROW Q_DECL_PURE_FUNCTION;
static QThread *currentThread();
static int idealThreadCount() Q_DECL_NOTHROW;
static void yieldCurrentThread();
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index adcd98b609..37eca9c612 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -176,7 +176,6 @@ public:
static QThread *threadForId(int id);
#ifdef Q_OS_UNIX
- pthread_t thread_id;
QWaitCondition thread_done;
static void *start(void *arg);
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index f456e56a9c..e7a31e0b70 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -110,6 +110,8 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_THREAD
+Q_STATIC_ASSERT(sizeof(pthread_t) == sizeof(Qt::HANDLE));
+
enum { ThreadPriorityResetFlag = 0x80000000 };
#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (defined(Q_CC_GNU) || defined(Q_CC_INTEL)) && !defined(QT_LINUXBASE)
@@ -239,8 +241,6 @@ QThreadData *QThreadData::current(bool createIfNecessary)
void QAdoptedThread::init()
{
- Q_D(QThread);
- d->thread_id = pthread_self();
}
/*
@@ -328,10 +328,11 @@ void *QThreadPrivate::start(void *arg)
// sets the name of the current thread.
QString objectName = thr->objectName();
+ pthread_t thread_id = reinterpret_cast<pthread_t>(data->threadId);
if (Q_LIKELY(objectName.isEmpty()))
- setCurrentThreadName(thr->d_func()->thread_id, thr->metaObject()->className());
+ setCurrentThreadName(thread_id, thr->metaObject()->className());
else
- setCurrentThreadName(thr->d_func()->thread_id, objectName.toLocal8Bit());
+ setCurrentThreadName(thread_id, objectName.toLocal8Bit());
}
#endif
@@ -372,7 +373,6 @@ void QThreadPrivate::finish(void *arg)
locker.relock();
}
- d->thread_id = 0;
d->running = false;
d->finished = true;
d->interruptionRequested = false;
@@ -618,15 +618,16 @@ void QThread::start(Priority priority)
}
int code =
- pthread_create(&d->thread_id, &attr, QThreadPrivate::start, this);
+ pthread_create(reinterpret_cast<pthread_t *>(&d->data->threadId), &attr,
+ QThreadPrivate::start, this);
if (code == EPERM) {
// caller does not have permission to set the scheduling
// parameters/policy
#if defined(QT_HAS_THREAD_PRIORITY_SCHEDULING)
pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
#endif
- code =
- pthread_create(&d->thread_id, &attr, QThreadPrivate::start, this);
+ code = pthread_create(reinterpret_cast<pthread_t *>(&d->data->threadId), &attr,
+ QThreadPrivate::start, this);
}
pthread_attr_destroy(&attr);
@@ -636,7 +637,7 @@ void QThread::start(Priority priority)
d->running = false;
d->finished = false;
- d->thread_id = 0;
+ d->data->threadId = 0;
}
}
@@ -646,10 +647,10 @@ void QThread::terminate()
Q_D(QThread);
QMutexLocker locker(&d->mutex);
- if (!d->thread_id)
+ if (!d->data->threadId)
return;
- int code = pthread_cancel(d->thread_id);
+ int code = pthread_cancel(reinterpret_cast<pthread_t>(d->data->threadId));
if (code) {
qWarning("QThread::start: Thread termination error: %s",
qPrintable(qt_error_string((code))));
@@ -662,7 +663,7 @@ bool QThread::wait(unsigned long time)
Q_D(QThread);
QMutexLocker locker(&d->mutex);
- if (d->thread_id == pthread_self()) {
+ if (reinterpret_cast<pthread_t>(d->data->threadId) == pthread_self()) {
qWarning("QThread::wait: Thread tried to wait on itself");
return false;
}
@@ -704,7 +705,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
int sched_policy;
sched_param param;
- if (pthread_getschedparam(thread_id, &sched_policy, &param) != 0) {
+ if (pthread_getschedparam(reinterpret_cast<pthread_t>(data->threadId), &sched_policy, &param) != 0) {
// failed to get the scheduling policy, don't bother setting
// the priority
qWarning("QThread::setPriority: Cannot get scheduler parameters");
@@ -720,15 +721,15 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
}
param.sched_priority = prio;
- int status = pthread_setschedparam(thread_id, sched_policy, &param);
+ int status = pthread_setschedparam(reinterpret_cast<pthread_t>(data->threadId), sched_policy, &param);
# ifdef SCHED_IDLE
// were we trying to set to idle priority and failed?
if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) {
// reset to lowest priority possible
- pthread_getschedparam(thread_id, &sched_policy, &param);
+ pthread_getschedparam(reinterpret_cast<pthread_t>(data->threadId), &sched_policy, &param);
param.sched_priority = sched_get_priority_min(sched_policy);
- pthread_setschedparam(thread_id, sched_policy, &param);
+ pthread_setschedparam(reinterpret_cast<pthread_t>(data->threadId), sched_policy, &param);
}
# else
Q_UNUSED(status);
diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp
index 21ad799e25..bf336a8f31 100644
--- a/src/corelib/tools/qarraydata.cpp
+++ b/src/corelib/tools/qarraydata.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include <QtCore/qarraydata.h>
+#include <QtCore/private/qnumeric_p.h>
#include <QtCore/private/qtools_p.h>
#include <stdlib.h>
@@ -93,16 +94,22 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
if (capacity > std::numeric_limits<size_t>::max() / objectSize)
return 0;
- size_t alloc = objectSize * capacity;
+ size_t alloc;
+ if (mul_overflow(objectSize, capacity, &alloc))
+ return 0;
- // Make sure qAllocMore won't overflow.
+ // Make sure qAllocMore won't overflow qAllocMore.
if (headerSize > size_t(MaxAllocSize) || alloc > size_t(MaxAllocSize) - headerSize)
return 0;
capacity = qAllocMore(int(alloc), int(headerSize)) / int(objectSize);
}
- size_t allocSize = headerSize + objectSize * capacity;
+ size_t allocSize;
+ if (mul_overflow(objectSize, capacity, &allocSize))
+ return 0;
+ if (add_overflow(allocSize, headerSize, &allocSize))
+ return 0;
QArrayData *header = static_cast<QArrayData *>(::malloc(allocSize));
if (header) {
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index 6aae979835..a223aa1490 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -4565,7 +4565,7 @@ QDateTime QDateTime::fromString(const QString &string, const QString &format)
Q_UNUSED(string);
Q_UNUSED(format);
#endif
- return QDateTime(QDate(), QTime(-1, -1, -1));
+ return QDateTime();
}
#endif // QT_NO_DATESTRING
diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp
index c1abdf11a7..8ddf1d9e41 100644
--- a/src/corelib/tools/qdatetimeparser.cpp
+++ b/src/corelib/tools/qdatetimeparser.cpp
@@ -313,7 +313,7 @@ int QDateTimeParser::sectionPos(const SectionNode &sn) const
*/
-static QString unquote(const QString &str)
+static QString unquote(const QStringRef &str)
{
const QChar quote(QLatin1Char('\''));
const QChar slash(QLatin1Char('\\'));
@@ -357,10 +357,8 @@ static inline int countRepeat(const QString &str, int index, int maxCount)
static inline void appendSeparator(QStringList *list, const QString &string, int from, int size, int lastQuote)
{
- QString str(string.mid(from, size));
- if (lastQuote >= from)
- str = unquote(str);
- list->append(str);
+ const QStringRef separator = string.midRef(from, size);
+ list->append(lastQuote >= from ? unquote(separator) : separator.toString());
}
@@ -471,7 +469,7 @@ bool QDateTimeParser::parseFormat(const QString &newFormat)
if (parserType != QVariant::Time) {
const SectionNode sn = { MonthSection, i - add, countRepeat(newFormat, i, 4), 0 };
newSectionNodes.append(sn);
- newSeparators.append(unquote(newFormat.mid(index, i - index)));
+ newSeparators.append(unquote(newFormat.midRef(index, i - index)));
i += sn.count - 1;
index = i + 1;
newDisplay |= MonthSection;
@@ -553,19 +551,20 @@ int QDateTimeParser::sectionSize(int sectionIndex) const
// is the previous value and displayText() is the new value.
// The size difference is always due to leading zeroes.
int sizeAdjustment = 0;
- if (displayText().size() != text.size()) {
+ const int displayTextSize = displayText().size();
+ if (displayTextSize != text.size()) {
// Any zeroes added before this section will affect our size.
int preceedingZeroesAdded = 0;
if (sectionNodes.size() > 1 && context == DateTimeEdit) {
- for (QVector<SectionNode>::ConstIterator sectionIt = sectionNodes.constBegin();
- sectionIt != sectionNodes.constBegin() + sectionIndex; ++sectionIt) {
+ const auto begin = sectionNodes.cbegin();
+ const auto end = begin + sectionIndex;
+ for (auto sectionIt = begin; sectionIt != end; ++sectionIt)
preceedingZeroesAdded += sectionIt->zeroesAdded;
- }
}
sizeAdjustment = preceedingZeroesAdded;
}
- return displayText().size() + sizeAdjustment - sectionPos(sectionIndex) - separators.last().size();
+ return displayTextSize + sizeAdjustment - sectionPos(sectionIndex) - separators.last().size();
} else {
return sectionPos(sectionIndex + 1) - sectionPos(sectionIndex)
- separators.at(sectionIndex + 1).size();
@@ -847,7 +846,7 @@ int QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionInde
if (skipToNextSection(sectionIndex, currentValue, digitsStr)) {
state = Acceptable;
const int missingZeroes = sectionmaxsize - digitsStr.size();
- text.insert(index, QString().fill(QLatin1Char('0'), missingZeroes));
+ text.insert(index, QString(missingZeroes, QLatin1Char('0')));
used = sectionmaxsize;
cursorPosition += missingZeroes;
++(const_cast<QDateTimeParser*>(this)->sectionNodes[sectionIndex].zeroesAdded);
@@ -1164,11 +1163,12 @@ end:
if (newCurrentValue.daysTo(minimum) != 0) {
break;
}
- toMin = newCurrentValue.time().msecsTo(minimum.time());
+ const QTime time = newCurrentValue.time();
+ toMin = time.msecsTo(minimum.time());
if (newCurrentValue.daysTo(maximum) > 0) {
toMax = -1; // can't get to max
} else {
- toMax = newCurrentValue.time().msecsTo(maximum.time());
+ toMax = time.msecsTo(maximum.time());
}
} else {
toMin = newCurrentValue.daysTo(minimum);
@@ -1555,10 +1555,7 @@ QString QDateTimeParser::SectionNode::format() const
qWarning("QDateTimeParser::sectionFormat Internal error 2");
return QString();
}
-
- QString str;
- str.fill(fillChar, count);
- return str;
+ return QString(count, fillChar);
}
diff --git a/src/corelib/tools/qelapsedtimer_unix.cpp b/src/corelib/tools/qelapsedtimer_unix.cpp
index 1e672531c8..e1fc77fb4c 100644
--- a/src/corelib/tools/qelapsedtimer_unix.cpp
+++ b/src/corelib/tools/qelapsedtimer_unix.cpp
@@ -115,7 +115,11 @@ static inline void qt_clock_gettime(clockid_t clock, struct timespec *ts)
static int unixCheckClockType()
{
-#if (_POSIX_MONOTONIC_CLOCK-0 == 0) && defined(_SC_MONOTONIC_CLOCK)
+#ifdef Q_OS_LINUX
+ // Despite glibc claiming that we should check at runtime, the Linux kernel
+ // always supports the monotonic clock
+ return CLOCK_MONOTONIC;
+#elif (_POSIX_MONOTONIC_CLOCK-0 == 0) && defined(_SC_MONOTONIC_CLOCK)
// we need a value we can store in a clockid_t that isn't a valid clock
// check if the valid ones are both non-negative or both non-positive
# if CLOCK_MONOTONIC >= 0 && CLOCK_REALTIME >= 0
diff --git a/src/corelib/tools/qharfbuzz_p.h b/src/corelib/tools/qharfbuzz_p.h
index 3b69a2e4f6..cc4d9bbd85 100644
--- a/src/corelib/tools/qharfbuzz_p.h
+++ b/src/corelib/tools/qharfbuzz_p.h
@@ -348,6 +348,7 @@ Q_CORE_EXPORT HB_Face qHBLoadFace(HB_Face face);
Q_DECLARE_TYPEINFO(HB_GlyphAttributes, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(HB_FixedPoint, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(HB_ScriptItem, Q_PRIMITIVE_TYPE);
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index 5e3016d313..b15dc7b07b 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -554,11 +554,15 @@ QHash<Key, T>::createNode(uint ah, const Key &akey, const T &avalue, Node **anex
template <class Key, class T>
Q_INLINE_TEMPLATE QHash<Key, T> &QHash<Key, T>::unite(const QHash &other)
{
- QHash copy(other);
- const_iterator it = copy.constEnd();
- while (it != copy.constBegin()) {
- --it;
- insertMulti(it.key(), it.value());
+ if (d == &QHashData::shared_null) {
+ *this = other;
+ } else {
+ QHash copy(other);
+ const_iterator it = copy.constEnd();
+ while (it != copy.constBegin()) {
+ --it;
+ insertMulti(it.key(), it.value());
+ }
}
return *this;
}
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 8149238a50..81f8f8ec05 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -855,7 +855,7 @@ inline bool QList<T>::op_eq_impl(const QList &l, QListData::ArrayCompatibleLayou
const T *lb = reinterpret_cast<const T*>(l.p.begin());
const T *b = reinterpret_cast<const T*>(p.begin());
const T *e = reinterpret_cast<const T*>(p.end());
- return std::equal(b, e, lb);
+ return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(lb, l.p.size()));
}
template <typename T>
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 52f82827f2..7809c513d6 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -54,7 +54,6 @@
#include "qlocale.h"
#include "qlocale_p.h"
#include "qlocale_tools_p.h"
-#include "qdatetime_p.h"
#include "qdatetimeparser_p.h"
#include "qnamespace.h"
#include "qdatetime.h"
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index 9801878bdc..f84d733db0 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -640,6 +640,8 @@ Q_INLINE_TEMPLATE void QMap<Key, T>::clear()
*this = QMap<Key, T>();
}
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_CLANG("-Wreturn-stack-address")
template <class Key, class T>
Q_INLINE_TEMPLATE const T QMap<Key, T>::value(const Key &akey, const T &adefaultValue) const
@@ -648,6 +650,8 @@ Q_INLINE_TEMPLATE const T QMap<Key, T>::value(const Key &akey, const T &adefault
return n ? n->value : adefaultValue;
}
+QT_WARNING_POP
+
template <class Key, class T>
Q_INLINE_TEMPLATE const T QMap<Key, T>::operator[](const Key &akey) const
{
diff --git a/src/corelib/tools/qscopedpointer.h b/src/corelib/tools/qscopedpointer.h
index d98b914757..3e6af97a33 100644
--- a/src/corelib/tools/qscopedpointer.h
+++ b/src/corelib/tools/qscopedpointer.h
@@ -162,7 +162,7 @@ public:
return oldD;
}
- inline void swap(QScopedPointer<T, Cleanup> &other)
+ void swap(QScopedPointer<T, Cleanup> &other) Q_DECL_NOTHROW
{
qSwap(d, other.d);
}
@@ -189,18 +189,9 @@ inline bool operator!=(const QScopedPointer<T, Cleanup> &lhs, const QScopedPoint
}
template <class T, class Cleanup>
-Q_INLINE_TEMPLATE void qSwap(QScopedPointer<T, Cleanup> &p1, QScopedPointer<T, Cleanup> &p2)
+inline void swap(QScopedPointer<T, Cleanup> &p1, QScopedPointer<T, Cleanup> &p2) Q_DECL_NOTHROW
{ p1.swap(p2); }
-QT_END_NAMESPACE
-namespace std {
- template <class T, class Cleanup>
- Q_INLINE_TEMPLATE void swap(QT_PREPEND_NAMESPACE(QScopedPointer)<T, Cleanup> &p1, QT_PREPEND_NAMESPACE(QScopedPointer)<T, Cleanup> &p2)
- { p1.swap(p2); }
-}
-QT_BEGIN_NAMESPACE
-
-
namespace QtPrivate {
template <typename X, typename Y> struct QScopedArrayEnsureSameType;
@@ -230,6 +221,9 @@ public:
return this->d[i];
}
+ void swap(QScopedArrayPointer &other) Q_DECL_NOTHROW // prevent QScopedPointer <->QScopedArrayPointer swaps
+ { QScopedPointer<T, Cleanup>::swap(other); }
+
private:
explicit inline QScopedArrayPointer(void *) {
// Enforce the same type.
@@ -245,6 +239,10 @@ private:
Q_DISABLE_COPY(QScopedArrayPointer)
};
+template <typename T, typename Cleanup>
+inline void swap(QScopedArrayPointer<T, Cleanup> &lhs, QScopedArrayPointer<T, Cleanup> &rhs) Q_DECL_NOTHROW
+{ lhs.swap(rhs); }
+
QT_END_NAMESPACE
#endif // QSCOPEDPOINTER_H
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 27d85c6460..21f3e34c6f 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -709,8 +709,8 @@ static int findChar(const QChar *str, int len, QChar ch, int from,
}
#define REHASH(a) \
- if (sl_minus_1 < (int)sizeof(int) * CHAR_BIT) \
- hashHaystack -= (a) << sl_minus_1; \
+ if (sl_minus_1 < sizeof(uint) * CHAR_BIT) \
+ hashHaystack -= uint(a) << sl_minus_1; \
hashHaystack <<= 1
inline bool qIsUpper(char ch)
@@ -3093,8 +3093,9 @@ int qFindString(
const ushort *needle = (const ushort *)needle0;
const ushort *haystack = (const ushort *)haystack0 + from;
const ushort *end = (const ushort *)haystack0 + (l-sl);
- const int sl_minus_1 = sl-1;
- int hashNeedle = 0, hashHaystack = 0, idx;
+ const uint sl_minus_1 = sl - 1;
+ uint hashNeedle = 0, hashHaystack = 0;
+ int idx;
if (cs == Qt::CaseSensitive) {
for (idx = 0; idx < sl; ++idx) {
@@ -3169,10 +3170,11 @@ static int lastIndexOfHelper(const ushort *haystack, int from, const ushort *nee
const ushort *end = haystack;
haystack += from;
- const int sl_minus_1 = sl-1;
+ const uint sl_minus_1 = sl - 1;
const ushort *n = needle+sl_minus_1;
const ushort *h = haystack+sl_minus_1;
- int hashNeedle = 0, hashHaystack = 0, idx;
+ uint hashNeedle = 0, hashHaystack = 0;
+ int idx;
if (cs == Qt::CaseSensitive) {
for (idx = 0; idx < sl; ++idx) {
@@ -10127,6 +10129,9 @@ static inline int qt_find_latin1_string(const QChar *haystack, int size,
QLatin1String needle,
int from, Qt::CaseSensitivity cs)
{
+ if (size < needle.size())
+ return -1;
+
const char *latin1 = needle.latin1();
int len = needle.size();
QVarLengthArray<ushort> s(len);
diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp
index 3c7417d64e..63a21ec75c 100644
--- a/src/corelib/tools/qtimezone.cpp
+++ b/src/corelib/tools/qtimezone.cpp
@@ -325,7 +325,7 @@ Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz);
Create a null/invalid time zone instance.
*/
-QTimeZone::QTimeZone()
+QTimeZone::QTimeZone() Q_DECL_NOTHROW
: d(0)
{
}
diff --git a/src/corelib/tools/qtimezone.h b/src/corelib/tools/qtimezone.h
index b5957150f9..db99f07f44 100644
--- a/src/corelib/tools/qtimezone.h
+++ b/src/corelib/tools/qtimezone.h
@@ -74,7 +74,7 @@ public:
};
typedef QVector<OffsetData> OffsetDataList;
- QTimeZone();
+ QTimeZone() Q_DECL_NOTHROW;
explicit QTimeZone(const QByteArray &ianaId);
explicit QTimeZone(int offsetSeconds);
/*implicit*/ QTimeZone(const QByteArray &zoneId, int offsetSeconds, const QString &name,
diff --git a/src/corelib/tools/qunicodetools.cpp b/src/corelib/tools/qunicodetools.cpp
index 52e7b5a53f..fad4267edc 100644
--- a/src/corelib/tools/qunicodetools.cpp
+++ b/src/corelib/tools/qunicodetools.cpp
@@ -685,10 +685,10 @@ Q_CORE_EXPORT void initCharAttributes(const ushort *string, int length,
Q_CORE_EXPORT void initScripts(const ushort *string, int length, uchar *scripts)
{
int sor = 0;
- int eor = -1;
+ int eor = 0;
uchar script = QChar::Script_Common;
- for (int i = 0; i < length; ++i) {
- eor = i;
+
+ for (int i = 0; i < length; ++i, eor = i) {
uint ucs4 = string[i];
if (QChar::isHighSurrogate(ucs4) && i + 1 < length) {
ushort low = string[i + 1];
@@ -700,60 +700,37 @@ Q_CORE_EXPORT void initScripts(const ushort *string, int length, uchar *scripts)
const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ucs4);
- if (Q_LIKELY(prop->script == script || prop->script <= QChar::Script_Inherited))
+ uchar nscript = prop->script;
+
+ if (Q_LIKELY(nscript == script || nscript <= QChar::Script_Common))
continue;
+ // inherit preceding Common-s
+ if (Q_UNLIKELY(script <= QChar::Script_Common)) {
+ // also covers a case where the base character of Common script followed
+ // by one or more combining marks of non-Inherited, non-Common script
+ script = nscript;
+ continue;
+ }
+
// Never break between a combining mark (gc= Mc, Mn or Me) and its base character.
// Thus, a combining mark — whatever its script property value is — should inherit
// the script property value of its base character.
static const int test = (FLAG(QChar::Mark_NonSpacing) | FLAG(QChar::Mark_SpacingCombining) | FLAG(QChar::Mark_Enclosing));
- if (Q_UNLIKELY(FLAG(prop->category) & test)) {
- // In cases where the base character itself has the Common script property value,
- // and it is followed by one or more combining marks with a specific script property value,
- // it may be even better for processing to let the base acquire the script property value
- // from the first mark. This approach can be generalized by treating all the characters
- // of a combining character sequence as having the script property value
- // of the first non-Inherited, non-Common character in the sequence if there is one,
- // and otherwise treating all the characters as having the Common script property value.
- if (Q_LIKELY(script > QChar::Script_Common || prop->script <= QChar::Script_Common))
- continue;
-
- script = QChar::Script(prop->script);
- }
-
-#if 0 // ### Disabled due to regressions. The font selection algorithm is not prepared for this change.
- if (Q_LIKELY(script != QChar::Script_Common)) {
- // override preceding Common-s
- while (sor > 0 && scripts[sor - 1] == QChar::Script_Common)
- --sor;
- } else {
- // see if we are inheriting preceding run
- if (sor > 0)
- script = scripts[sor - 1];
- }
-#endif
+ if (Q_UNLIKELY(FLAG(prop->category) & test))
+ continue;
- while (sor < eor)
- scripts[sor++] = script;
+ Q_ASSERT(script > QChar::Script_Common);
+ Q_ASSERT(sor < eor);
+ ::memset(scripts + sor, script, (eor - sor) * sizeof(uchar));
+ sor = eor;
- script = prop->script;
- }
- eor = length;
-
-#if 0 // ### Disabled due to regressions. The font selection algorithm is not prepared for this change.
- if (Q_LIKELY(script != QChar::Script_Common)) {
- // override preceding Common-s
- while (sor > 0 && scripts[sor - 1] == QChar::Script_Common)
- --sor;
- } else {
- // see if we are inheriting preceding run
- if (sor > 0)
- script = scripts[sor - 1];
+ script = nscript;
}
-#endif
- while (sor < eor)
- scripts[sor++] = script;
+ Q_ASSERT(script >= QChar::Script_Common);
+ Q_ASSERT(eor == length);
+ ::memset(scripts + sor, script, (eor - sor) * sizeof(uchar));
}
} // namespace QUnicodeTools
diff --git a/src/corelib/tools/qunicodetools_p.h b/src/corelib/tools/qunicodetools_p.h
index 1103f28452..5cde188656 100644
--- a/src/corelib/tools/qunicodetools_p.h
+++ b/src/corelib/tools/qunicodetools_p.h
@@ -77,6 +77,10 @@ struct ScriptItem
int script;
};
+} // namespace QUnicodeTools
+Q_DECLARE_TYPEINFO(QUnicodeTools::ScriptItem, Q_PRIMITIVE_TYPE);
+namespace QUnicodeTools {
+
enum CharAttributeOption {
GraphemeBreaks = 0x01,
WordBreaks = 0x02,
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index 24574dc90b..c3ac104399 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -102,7 +102,8 @@ public:
QVarLengthArray<T, Prealloc> &operator=(std::initializer_list<T> list)
{
resize(list.size());
- std::copy(list.begin(), list.end(), this->begin());
+ std::copy(list.begin(), list.end(),
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(this->begin(), this->size()));
return *this;
}
#endif
@@ -473,7 +474,7 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
int l = int(aend - ptr);
int n = l - f;
if (QTypeInfo<T>::isComplex) {
- std::copy(ptr + l, ptr + s, ptr + f);
+ std::copy(ptr + l, ptr + s, QT_MAKE_CHECKED_ARRAY_ITERATOR(ptr + f, s - f));
T *i = ptr + s;
T *b = ptr + s - n;
while (i != b) {
@@ -495,7 +496,7 @@ bool operator==(const QVarLengthArray<T, Prealloc1> &l, const QVarLengthArray<T,
const T *rb = r.begin();
const T *b = l.begin();
const T *e = l.end();
- return std::equal(b, e, rb);
+ return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(rb, r.size()));
}
template <typename T, int Prealloc1, int Prealloc2>
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 13ae121450..557bec9676 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -773,7 +773,7 @@ bool QVector<T>::operator==(const QVector<T> &v) const
const T *vb = v.d->begin();
const T *b = d->begin();
const T *e = d->end();
- return std::equal(b, e, vb);
+ return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(vb, v.d->size));
}
template <typename T>
@@ -793,24 +793,28 @@ QVector<T> &QVector<T>::fill(const T &from, int asize)
template <typename T>
QVector<T> &QVector<T>::operator+=(const QVector &l)
{
- uint newSize = d->size + l.d->size;
- const bool isTooSmall = newSize > d->alloc;
- if (!isDetached() || isTooSmall) {
- QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow : QArrayData::Default);
- reallocData(d->size, isTooSmall ? newSize : d->alloc, opt);
- }
+ if (d == Data::sharedNull()) {
+ *this = l;
+ } else {
+ uint newSize = d->size + l.d->size;
+ const bool isTooSmall = newSize > d->alloc;
+ if (!isDetached() || isTooSmall) {
+ QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow : QArrayData::Default);
+ reallocData(d->size, isTooSmall ? newSize : d->alloc, opt);
+ }
- if (d->alloc) {
- T *w = d->begin() + newSize;
- T *i = l.d->end();
- T *b = l.d->begin();
- while (i != b) {
- if (QTypeInfo<T>::isComplex)
- new (--w) T(*--i);
- else
- *--w = *--i;
+ if (d->alloc) {
+ T *w = d->begin() + newSize;
+ T *i = l.d->end();
+ T *b = l.d->begin();
+ while (i != b) {
+ if (QTypeInfo<T>::isComplex)
+ new (--w) T(*--i);
+ else
+ *--w = *--i;
+ }
+ d->size = newSize;
}
- d->size = newSize;
}
return *this;
}