From 3b98467ebe0e447d8343457310827e18706e9550 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Fri, 8 Apr 2016 07:39:41 +0200 Subject: winrt: Try to acquire CoreDispatcher from multiple sources When the system launches the application via different activation mode (eg. app registered for sharing) no main window will be created. Hence accessing the core window will return null and event dispatcher initialization will fail. In that case iterate through all available views and try to get access to their dispatcher to be able to invoke code on the xaml thread. Task-number: QTBUG-49276 Change-Id: I8c78baa27747a0465ff7a1b2ead6c9e03f0e05a8 Reviewed-by: Oliver Wolff --- src/corelib/kernel/qeventdispatcher_winrt.cpp | 31 +++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp index ca4ba72b66..d115a3db2a 100644 --- a/src/corelib/kernel/qeventdispatcher_winrt.cpp +++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp @@ -50,6 +50,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; @@ -179,8 +180,34 @@ HRESULT QEventDispatcherWinRT::runOnXamlThread(const std::function & ComPtr 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> 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; -- cgit v1.2.3 From dbe9a8c9696428529cacb9dd4e004db99914b56e Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 12 Apr 2016 16:05:10 +0200 Subject: Don't copy the functor object for each signal emission The behavior was different in the variadic template code and in the C++98 code. The code without variadic template support was not copying the functor object (e.g. a lambda) before calling it. However, in the variadic template section, QtPrivate::FunctorCall::call took the functor by value instead of by reference resulting in a copy. QtPrivate::FunctorCall::call is a helper function for QtPrivate::FunctionPointer::call which is only needed for variadic template expension. [ChangeLog][QtCore][QObject] If the compiler supports variadic templates, no longer copy functor connected to a signal each time the signal is emitted. Restoring the C++98 behavior. Task-number: QTBUG-52542 Change-Id: I3ca20ef6910893b8a288e70af7de4c7b69502173 Reviewed-by: Thiago Macieira --- src/corelib/kernel/qobjectdefs_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h index d5574a4dd1..922b6bbb42 100644 --- a/src/corelib/kernel/qobjectdefs_impl.h +++ b/src/corelib/kernel/qobjectdefs_impl.h @@ -491,7 +491,7 @@ namespace QtPrivate { template struct FunctorCall; template struct FunctorCall, List, R, Function> { - static void call(Function f, void **arg) { + static void call(Function &f, void **arg) { f((*reinterpret_cast::Type *>(arg[II+1]))...), ApplyReturnValue(arg[0]); } }; -- cgit v1.2.3 From 17ad6e2a93f93aaa948c1286b3cad785e7f38808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 13 Apr 2016 14:09:35 +0200 Subject: Fix build when Qt is used in an automatic reference-counted environment When automatic reference-counting (ARC) is enabled on Darwin platforms the NSAutoReleasePool class should not be used directly, which caused a build error if qglobal.h was included after the Foundation.h in client code. The preferred alternative for ARC is the scoped @autoreleasepool construct, which allows the compiler to reason about needing to insert _objc_autoreleasePoolPush and _objc_autoreleasePoolPop calls. Note that ARC translation units can be combined with non-ARC translation units, so Qt and the QMacAutoReleasePool class can still be used in ARC client code even if Qt is not built with ARC. Task-number: QTBUG-51332 Change-Id: I7ef1c3146aa416a9d6a1dc299ce7b17f22f889e5 Reviewed-by: Simon Hausmann Reviewed-by: Richard Moe Gustavsen --- src/corelib/global/qglobal.h | 6 +----- src/corelib/kernel/qcore_mac_objc.mm | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 98c9902674..5bb1ce77bd 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -579,10 +579,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 { @@ -591,7 +587,7 @@ public: ~QMacAutoReleasePool(); private: Q_DISABLE_COPY(QMacAutoReleasePool) - NSAutoreleasePool *pool; + void *pool; }; #endif // Q_OS_MAC diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index 1a2b047041..e1480a36d5 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -150,7 +150,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(pool) drain]; } // ------------------------------------------------------------------------- -- cgit v1.2.3 From 5b37c9f7d3153a756af8fa89b2467c87a3021a8b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 12 Apr 2016 13:35:30 -0700 Subject: Work around Clang false-positive warning on returning default parameters Clang 3.8 and Apple Clang 7.x seem to think that the parameter is a temporary. See https://llvm.org/bugs/show_bug.cgi?id=26396 Task-number: QTBUG-52134 Change-Id: Id75834dab9ed466e94c7ffff1444b6f2424d7fb7 Reviewed-by: Jake Petroules --- src/corelib/tools/qmap.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index fe9ddaaa32..ed49e70f4e 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -634,6 +634,8 @@ Q_INLINE_TEMPLATE void QMap::clear() *this = QMap(); } +QT_WARNING_PUSH +QT_WARNING_DISABLE_CLANG("-Wreturn-stack-address") template Q_INLINE_TEMPLATE const T QMap::value(const Key &akey, const T &adefaultValue) const @@ -642,6 +644,8 @@ Q_INLINE_TEMPLATE const T QMap::value(const Key &akey, const T &adefault return n ? n->value : adefaultValue; } +QT_WARNING_POP + template Q_INLINE_TEMPLATE const T QMap::operator[](const Key &akey) const { -- cgit v1.2.3 From 7ab0829823024dd07d15ff6786e3648388d4f28d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 12 Apr 2016 13:38:18 -0700 Subject: Fix parsing of empty port sections in URLs The RFC does allow it. It even has examples showing them as valid. In section 6.2.3, it shows: http://example.com http://example.com/ http://example.com:/ http://example.com:80/ Change-Id: Id75834dab9ed466e94c7ffff1444b7195ad21cab Reviewed-by: Frederik Gladhorn Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov --- src/corelib/io/qurl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index b51119c7ad..b27321b2a6 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -1046,7 +1046,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) { -- cgit v1.2.3 From 77fb9ca271e515f6a147d3dc7025bf3501c70fa0 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 12 Apr 2016 14:46:04 -0700 Subject: Fix encoding of IDN hostnames with QUrl::host When the formatting parameter wasn't exactly QUrl::EncodeUnicode, it wouldn't encode, despite having to. Change-Id: Id75834dab9ed466e94c7ffff1444bacc08dd109b Reviewed-by: Frederik Gladhorn Reviewed-by: Edward Welbourne --- src/corelib/io/qurl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index b27321b2a6..fb2f4ba918 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -1176,7 +1176,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; -- cgit v1.2.3 From 479a791ab2696d5c5571c99d1313681dd12d40d0 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Wed, 13 Apr 2016 13:03:12 +0200 Subject: Fix QSysInfo::windowsVersion() on WinCE Use the GetVersionEx method on WinCE. The ntdll.dll does not exist on that platform, therefor a wrong version number was returned. Change-Id: I7b51757d0fb612dcd8832e0903a93b9d1c6746c0 Reviewed-by: Friedemann Kleint Reviewed-by: Andreas Holzammer --- src/corelib/global/qglobal.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 461b0f383d..77724d2a0d 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1940,6 +1940,7 @@ static inline OSVERSIONINFO winOsVersion() #define pGetModuleHandle GetModuleHandleW #endif +#ifndef Q_OS_WINCE HMODULE ntdll = pGetModuleHandle(L"ntdll.dll"); if (Q_UNLIKELY(!ntdll)) return result; @@ -1959,6 +1960,10 @@ static inline OSVERSIONINFO winOsVersion() // 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(&result); // always returns STATUS_SUCCESS +#else // !Q_OS_WINCE + GetVersionEx(&result); +#endif + return result; } -- cgit v1.2.3 From 62ad5abe0637abc742f10cc31a3faf0a2353ab2f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 14 Apr 2016 10:00:24 +0200 Subject: QWinEventNotifier: compile with -Wzero-as-null-pointer-constant Seems to be the last 5.6 QtBase public header that didn't, paving the way to add the warning to the headersclean check. Change-Id: Ib2655782e34ec58e5d9b1b9c0ec31a965a38f9b7 Reviewed-by: Friedemann Kleint --- src/corelib/kernel/qwineventnotifier.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qwineventnotifier.h b/src/corelib/kernel/qwineventnotifier.h index 95fdff07ce..f59754de6f 100644 --- a/src/corelib/kernel/qwineventnotifier.h +++ b/src/corelib/kernel/qwineventnotifier.h @@ -48,8 +48,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); -- cgit v1.2.3 From 8d169943eb4421b6bf3165ff42d9444f282fb03c Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 12 Apr 2016 13:39:18 +0200 Subject: QWindowsLocalCodec::convertFromUnicode(): preclude stack overflow. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This method is called by QString::toLocal8Bit_helper(), so using QString::toLocal8Bit() on the input in an error message on failure to decode would be apt to recurse on the same data (if such an error ever arises). Furthermore, the qWarning()'s format string even claimed what it was displaying was in UTF-8. Fix by using native fprintf and UTF-16. Thanks to Frédéric Marchal for spotting this and checking that such errors aren't (at present) possible. Change-Id: I1ad441f2e3700bc01256d6c1718d404e27bce488 Reviewed-by: Thiago Macieira --- src/corelib/codecs/qwindowscodec.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/codecs/qwindowscodec.cpp b/src/corelib/codecs/qwindowscodec.cpp index dded93ccb5..a7c6f72422 100644 --- a/src/corelib/codecs/qwindowscodec.cpp +++ b/src/corelib/codecs/qwindowscodec.cpp @@ -208,10 +208,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(QString(ch, uclen).utf16())); #endif break; } -- cgit v1.2.3 From efb829d44b7a63cbdd0681763bf4aa9fd38d4fe4 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 5 Apr 2016 18:19:47 +0200 Subject: Mime type browser example: Add documentation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ic5f2103b0771799bc9e5e5efceeadf153f8a2159 Reviewed-by: Topi Reiniö --- src/corelib/mimetypes/qmimedatabase.cpp | 2 +- src/corelib/mimetypes/qmimetype.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp index a32031a788..bff6a9ac15 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} */ /*! 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} */ /*! -- cgit v1.2.3 From 1721d56d2895f3b1f5b09022dc558bf40cd8194c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 18 Apr 2016 13:08:24 -0700 Subject: Fix build on Linux/x32 systems (x86-64 ILP32) When I tested this, it compiled, but either I wasn't using the same compiler or the problem happens during linking: we can't use .quad (64-bit) with a relocation on x32. So instead, let's use .long (32-bit). Task-number: QTBUG-52658 Change-Id: Ifea6e497f11a461db432ffff14468d1a16f49c67 Reviewed-by: Shawn Rutledge --- src/corelib/global/qversiontagging.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qversiontagging.h b/src/corelib/global/qversiontagging.h index 953f669501..fa824d1c89 100644 --- a/src/corelib/global/qversiontagging.h +++ b/src/corelib/global/qversiontagging.h @@ -58,9 +58,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) \ -- cgit v1.2.3 From cc7cd61909ad0931ea702178274b7138dd5bdf52 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Sat, 9 Apr 2016 18:17:52 +0300 Subject: Improve performance of socket notifications on WinCE QEventDispatcherWin32 on WinCE uses a separate low-priority thread to monitor sockets activity, so changing the state of notifiers occurs asynchronously to the main thread. This makes a message-based socket activation mechanism ineffective. To avoid timeouts in the helper thread, update the thread's pool directly from the (un)registerSocketNotifier() functions. Change-Id: I702c32d69dce09323ca5f65dc2ee1407842e41ef Reviewed-by: Tobias Koenig Reviewed-by: Friedemann Kleint --- src/corelib/kernel/qeventdispatcher_win.cpp | 25 ++++++++++++++++++++++++- src/corelib/kernel/qeventdispatcher_win_p.h | 4 +++- 2 files changed, 27 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index b3df139743..31c6530e80 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -309,7 +309,10 @@ static void resolveTimerAPI() 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 { resolveTimerAPI(); } @@ -391,9 +394,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); @@ -404,6 +409,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); @@ -418,6 +424,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 @@ -658,11 +665,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() { @@ -920,16 +929,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) @@ -958,6 +973,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 }; @@ -968,6 +984,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 222562dfce..989bac3904 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -179,9 +179,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 winEventNotifierList; void activateEventNotifier(QWinEventNotifier * wen); -- cgit v1.2.3 From a24ac8950fd53c70928cf00a86c566201a3a7786 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 19 Apr 2016 13:38:56 +0200 Subject: Doc: Fix typo in QAtomicPointer::loadAcquire documentation Change-Id: I1b0e6b0f230b2f17595a9cc91234a011ad0260b5 Reviewed-by: Leena Miettinen --- src/corelib/thread/qatomic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp index fceeef02b0..fd02489998 100644 --- a/src/corelib/thread/qatomic.cpp +++ b/src/corelib/thread/qatomic.cpp @@ -1282,7 +1282,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. -- cgit v1.2.3 From 64b54819d8b03e369693ae7dfc0e2908166305c3 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 6 Apr 2016 13:11:07 +0200 Subject: Doc: Fix links to QProcess::start(const QString &, OpenMode) The startDetached(const QString &, OpenMode) overload and the QT_NO_PROCESS_COMBINED_ARGUMENT_START macro must point to the start(const QString &, OpenMode) overload. Change-Id: I7607fcb92b9f1ef3547a4a1aadc950532024225a Reviewed-by: Leena Miettinen --- src/corelib/io/qprocess.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index a86e3cb438..68f7157ad2 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -106,11 +106,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) */ /*! @@ -2538,7 +2540,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) { -- cgit v1.2.3 From 9def501433e80e1a45c0d7888b9ceba4e32ca1fa Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 18 Apr 2016 23:27:12 +0200 Subject: QString: Avoid searching for a needle which is longer than the hay Avoid incurring the cost of converting the latin1 data in that case. Several existing QString unit tests excercise the new code path. Task-number: QTBUG-52617 Change-Id: I27256d9e7db34f09543e244a79d754ff7932f0d0 Reviewed-by: Thiago Macieira --- src/corelib/tools/qstring.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 10d3441d2c..983d1213d9 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -10005,6 +10005,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 s(len); -- cgit v1.2.3 From ea64dc9a113a850334fbf47ca2cdc3b447945c25 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 15 Apr 2016 13:49:25 +0200 Subject: qlockfile_unix - code cleanup Coverity's CID 157687: QCache::insert, indeed, can delete (immediately) the object we're trying to insert. While this never happens actually in qlockfile_unix since we have max cost 10 and insert with cost 1, the code does not look good and Coverity is not happy. Change-Id: I16a428017bf86e151afe5256906e4cab1ef4044a Reviewed-by: Joerg Bornemann --- src/corelib/io/qlockfile_unix.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index bcef84206e..f23a232fb8 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -139,12 +139,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) -- cgit v1.2.3 From ab83912c7900805987f7efe38cee2c60baf5f315 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 5 Apr 2016 11:26:20 +0200 Subject: Windows/QProcess::startDetached(): Fall back to ShellExecuteEx() for UAC prompt. When running a process that requires elevated privileges (such as regedt32 or an installer), the Win32 API CreateProcess fails with error ERROR_ELEVATION_REQUIRED. Fall back to ShellExecuteEx() using the verb "runas" in that case, bringing up the UAC prompt. Task-number: QTBUG-7645 Change-Id: Iee82a86a30f78c5a49246d2c0d4566306f3afc71 Reviewed-by: Oliver Wolff Reviewed-by: Joerg Bornemann --- src/corelib/io/qprocess_win.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index e7cd9d9a17..7e9cffe129 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -808,8 +809,45 @@ bool QProcessPrivate::waitForWrite(int msecs) return false; } +// 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(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(program.utf16()); + if (!args.isEmpty()) + shellExecuteExInfo.lpParameters = reinterpret_cast(args.utf16()); + if (!workingDir.isEmpty()) + shellExecuteExInfo.lpDirectory = reinterpret_cast(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; @@ -829,6 +867,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; -- cgit v1.2.3 From 16fa29352b7402c82624d6367231f67de836d17e Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 22 Apr 2016 13:51:31 +0200 Subject: QMimeDatabase: fix mimeTypeForUrl for mailto URLs The "path" of a mailto URL isn't a file, so we shouldn't try to do glob-based matching. I was getting application/x-ms-dos-executable for a .com domain and application/x-perl for a .pl domain... Change-Id: Ifc346c3bba83ba1a8476db3202492f4c2e4d52bb Reviewed-by: Friedemann Kleint Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/corelib/mimetypes/qmimedatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp index fd11dbc787..cf6abbd5cb 100644 --- a/src/corelib/mimetypes/qmimedatabase.cpp +++ b/src/corelib/mimetypes/qmimedatabase.cpp @@ -515,7 +515,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()); -- cgit v1.2.3 From 721d7d383df512bc4dea79b85601d01df576117f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 14 Apr 2016 22:57:11 -0700 Subject: QMessagePattern: Fix indentation and use QVector for a large struct struct BacktraceParams is too big (more than one pointer), so using it with QList is inefficient. Let's use QVector instead. Change-Id: Id75834dab9ed466e94c7ffff144572c1eb3fb0e5 Reviewed-by: Marc Mutz Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/global/qlogging.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 86b9597609..6cd2d7914b 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -986,15 +986,18 @@ struct QMessagePattern { #endif #ifdef QLOGGING_HAVE_BACKTRACE struct BacktraceParams { - QString backtraceSeparator; - int backtraceDepth; + QString backtraceSeparator; + int backtraceDepth; }; - QList backtraceArgs; // backtrace argumens in sequence of %{backtrace + QVector 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; -- cgit v1.2.3 From 072f5b513e486e884ea7fa4a1cac9aedf3846374 Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Fri, 22 Apr 2016 11:34:07 +0200 Subject: Also update filter rules if there is a custom filter installed. This is relevant if the custom filter passes through some categories to the previous one (which might be the default one). In this case changes to the filter rules never took effect. Change-Id: I1a3ab569857d43621ce5df4e690c6e64e6bc7a66 Reviewed-by: Kai Koehne --- src/corelib/io/qloggingregistry.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp index b53e251102..a9ac38c6a6 100644 --- a/src/corelib/io/qloggingregistry.cpp +++ b/src/corelib/io/qloggingregistry.cpp @@ -359,9 +359,6 @@ void QLoggingRegistry::setApiRules(const QString &content) */ void QLoggingRegistry::updateRules() { - if (categoryFilter != defaultCategoryFilter) - return; - rules = qtConfigRules + configRules + apiRules + envRules; foreach (QLoggingCategory *cat, categories.keys()) -- cgit v1.2.3 From 4579d966af2e5d4ba229f13312eeb2f921406038 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 24 Apr 2016 12:00:25 +0200 Subject: QMutexPool: avoid QVarLengthArray of QAtomicPointers QAtomicPointer is CopyConstructible, but std::atomic is not, for a reason. So avoid putting them in a QVarLengthArray, using a dynamic heap allocation instead. This sounds wasteful until you realize that virtually all users of QMutexPool (and we know them all) use the global instance(), and that each QMutex (131, by default) is heap-allocated, too. Change-Id: Ie9c95671ec42a1f51919c18631b623aad2c0d6ba Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Thiago Macieira --- src/corelib/thread/qmutexpool.cpp | 11 +++++------ src/corelib/thread/qmutexpool_p.h | 5 +++-- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/corelib') 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[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, 131> mutexes; + int count; + QAtomicPointer *mutexes; QMutex::RecursionMode recursionMode; }; -- cgit v1.2.3 From 0909a94af2d274840697e4ae25cc14b3f5eb6197 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 24 Apr 2016 00:07:28 +0200 Subject: QtCore: mark more types as primitive/movable These types are held in QVarLengthArrays, so benefit from being trivially relocatable. They are also part of the private API, so there's no BC issues with potential uses of these types in QList. Change-Id: I8adc0c801885f8fffa05eb1f173d7e4bb085ba7b Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/json/qjson_p.h | 2 ++ src/corelib/kernel/qmetaobject_p.h | 1 + src/corelib/tools/qharfbuzz_p.h | 1 + src/corelib/tools/qunicodetools_p.h | 4 ++++ 4 files changed, 8 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h index e5010c2da7..3580e0b61c 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; @@ -619,6 +620,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 { diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h index 69f884f4ed..0790af2bb5 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 QArgumentTypeArray; 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/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, -- cgit v1.2.3 From be6c14211e93da4b59c4c25aa8e85b860ccb8666 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Thu, 21 Apr 2016 22:35:32 +0300 Subject: qTopLevelDomain: use QStringRef more qIsEffectiveTLD() and containsTLDEntry() now have overloaded versions with QStringRef arg. Change-Id: Ic2b7fd56c8ea1579d3e4bdf4ed0e10405515d417 Reviewed-by: Marc Mutz --- src/corelib/io/qtldurl.cpp | 13 +++++++++---- src/corelib/io/qtldurl_p.h | 6 +++++- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'src/corelib') 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 -- cgit v1.2.3 From 84330007e12122bf1b690a4e68b5ef8e973c7882 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Thu, 21 Apr 2016 21:58:58 +0300 Subject: QLockFile: move early out earlier to avoid allocations. Saves reading two lines and allocating storage for them. Change-Id: I71f6c7019f4c097897945eea52851e4623b75dc2 Reviewed-by: David Faure Reviewed-by: Edward Welbourne --- src/corelib/io/qlockfile.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/corelib') 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) -- cgit v1.2.3 From e2f7d04a6143d2d0dfa0d0ec588e87f32c6f2e23 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 25 Apr 2016 08:54:48 +0200 Subject: Add missing initializers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Coverity, CIDs: 10724, 10725. Data member _iterator is not initialized. Change-Id: I0c94f5cef031e208aab1687209282fae0317f0ab Reviewed-by: Jędrzej Nowacki --- src/corelib/kernel/qmetatype.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 899a51173e..b6cfad56b5 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1183,6 +1183,7 @@ public: public: template QAssociativeIterableImpl(const T*p) : _iterable(p) + , _iterator(Q_NULLPTR) , _metaType_id_key(qMetaTypeId()) , _metaType_flags_key(QTypeInfo::isPointer) , _metaType_id_value(qMetaTypeId()) @@ -1202,6 +1203,7 @@ public: QAssociativeIterableImpl() : _iterable(Q_NULLPTR) + , _iterator(Q_NULLPTR) , _metaType_id_key(QMetaType::UnknownType) , _metaType_flags_key(0) , _metaType_id_value(QMetaType::UnknownType) -- cgit v1.2.3 From 943a658c0763b62eff9f1a234bf561645e77b1cf Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Mon, 25 Apr 2016 12:20:08 +0300 Subject: QJsonObject: use reserve() to reduce memory allocations Change-Id: I97821ffa0c485815c781dc4f98012b0b490da90a Reviewed-by: Edward Welbourne Reviewed-by: Marc Mutz --- src/corelib/json/qjsonobject.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/corelib') diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp index 4ee20ef168..7badc9d929 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()); -- cgit v1.2.3 From 31c7b24aa5f57fbe8258c9e9845c8d630af4aec1 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 1 Apr 2016 23:55:25 +0200 Subject: Silence MSVC warnings when using certain std algorithms The MSVC STL warns when passing naked pointers as non-bounded iterators to algorithms such as std::equal and std::copy, in an attempt to inform users that the range specified by that iterator has an implicit minimum size that the caller of the algorithm must ensure is met: warning C4996: 'std::_Equal1': Function call with parameters that may be unsafe - \ this call relies on the caller to check that the passed values are correct. To \ disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to \ use Visual C++ 'Checked Iterators' When building Qt, as well as when building user projects with qmake (cf. 0a76b6bc7f98900ea884cd10ccca1a332e5bdba5), we globally disable this warning (with -D_SCL_SECURE_NO_WARNINGS), but since we started using STL algorithms in public headers (e.g. in qvector.h), users get this warning in their own projects now, unless they, too, define said macro. But such a requirement is against the Qt policy to have headers that are warning-free as much as possible. The suggested way of fixing this warning is to wrap the naked pointer in a stdext::unchecked_array_iterator before passing it to the algorithm, cf. examples in https://msdn.microsoft.com/en-us/library/ttcz0bys%28v=vs.120%29.aspx or, together with the capacity-made-explicit, in a stdext::checked_array_iterator. To avoid ifdefs for platforms that don't have these extensions (which, incidentally, for the unchecked case, includes MSVC 2012), wrap the calls in macros. The end game here is to drop -D_SCL_SECURE_NO_WARNINGS, at least for public headers, even though this commit also adds the wrapper to implementation and private header files. An alternative to the wrapper would have been the version of std::equal that takes four iterators. However, that is a C++14 library feature, while this version of Qt still needs to compile with a C++98 compiler, and, more importantly, there isn't, and never will be, a corresponding 4-iterator version of std::copy. Task-number: QTBUG-47948 Done-with: Stephen Kelly Change-Id: I1bbab257fb5f1c5042939c382a412b596112ff26 Reviewed-by: Stephen Kelly --- src/corelib/global/qcompilerdetection.h | 12 ++++++++++++ src/corelib/kernel/qcoreapplication.cpp | 2 +- src/corelib/tools/qlist.h | 2 +- src/corelib/tools/qvarlengtharray.h | 7 ++++--- src/corelib/tools/qvector.h | 2 +- 5 files changed, 19 insertions(+), 6 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index b11237dce5..25043dab75 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -94,6 +94,12 @@ # define Q_DECL_DEPRECATED_X(text) __declspec(deprecated(text)) # 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 @@ -1117,6 +1123,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 /* * Warning/diagnostic handling diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 30a3204d3d..b3b35dc9b6 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -444,7 +444,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/tools/qlist.h b/src/corelib/tools/qlist.h index 9a57a2c6a5..e04a6be1ab 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -846,7 +846,7 @@ inline bool QList::op_eq_impl(const QList &l, QListData::ArrayCompatibleLayou const T *lb = reinterpret_cast(l.p.begin()); const T *b = reinterpret_cast(p.begin()); const T *e = reinterpret_cast(p.end()); - return std::equal(b, e, lb); + return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(lb, l.p.size())); } template diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index bb15d66439..8371352061 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -96,7 +96,8 @@ public: QVarLengthArray &operator=(std::initializer_list 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 @@ -467,7 +468,7 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray::iterator QVarLengthA int l = int(aend - ptr); int n = l - f; if (QTypeInfo::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) { @@ -489,7 +490,7 @@ bool operator==(const QVarLengthArray &l, const QVarLengthArray diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 3ce33fb477..691872cb36 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -767,7 +767,7 @@ bool QVector::operator==(const QVector &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 -- cgit v1.2.3 From a1e3a0daed6c056c3b957151605f0f277fd38d3c Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 25 Mar 2016 10:40:44 +0100 Subject: QString: Fix UBs (signed overflow) in hashed string search Similar change to 390ea21873cf229447c2dcaea85a40e472fab03c, but more extensive because the hash variables were not, yet, of unsigned type. This brings the three hashed string search algorithms in QtBase (in QString, QByteArray and QByteArrayMatcher) in line again. Found by UBSan, fixing the following bunch of errors: tools/qstring.cpp:3080:38: runtime error: left shift of negative value -1291179264 tools/qstring.cpp:3081:42: runtime error: left shift of negative value -1291179264 tools/qstring.cpp:3091:13: runtime error: left shift of 73 by 26 places cannot be represented in type 'int' tools/qstring.cpp:3091:13: runtime error: left shift of negative value -1255957171 tools/qstring.cpp:3091:13: runtime error: signed integer overflow: 1783052986 - -1207959552 cannot be represented in type 'int' tools/qstring.cpp:3097:37: runtime error: left shift of negative value -1298753576 tools/qstring.cpp:3098:41: runtime error: left shift of negative value -1298753576 tools/qstring.cpp:3107:13: runtime error: left shift of negative value -1508912760 tools/qstring.cpp:3158:38: runtime error: left shift of negative value -677037574 tools/qstring.cpp:3159:42: runtime error: left shift of negative value -677037574 tools/qstring.cpp:3169:13: runtime error: left shift of negative value -1657715810 tools/qstring.cpp:3173:38: runtime error: left shift of negative value -677037574 tools/qstring.cpp:3174:42: runtime error: left shift of negative value -677037574 tools/qstring.cpp:3183:13: runtime error: left shift of negative value -1657715810 Change-Id: I1436eb61369919df9fe34251f863dd54fb58af98 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qstring.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 983d1213d9..6bbaf05fef 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -705,8 +705,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) @@ -3072,8 +3072,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) { @@ -3148,10 +3149,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) { -- cgit v1.2.3 From 6e306e8d942464d969c3792e6299aa014a2d2b8f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 20 Apr 2016 22:23:54 -0700 Subject: Disallow non-character Unicode codepoints in QUrl/QUrlQuery Since they are non-characters and should not be used for text interchange, it stands to reason that they should not appear in unencoded for in a URL. To change the behavior, we just need to toggle a simple flag for QUtf8Functions. This behavior also matches the recommendation from RFC 3987. We do not usually follow recommendations from that RFC (as it is generally believed to be a bad RFC), but this one seems like a good idea. Change-Id: Ifea6e497f11a461db432ffff1447486c623c12bd Reviewed-by: David Faure --- src/corelib/io/qurlrecode.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/corelib') 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) { -- cgit v1.2.3 From 3df159ba174c1775a0e77d2305a639eeab1ea71d Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Sat, 30 Jan 2016 10:18:25 +0400 Subject: Improve the script itemization algorithm to match Unicode 8.0 Override preceding Common-s with a subsequent non-Inherited, non-Common script. This produces longer script runs, which automagically improves the shaping quality (as we don't lose the context anymore), the shaping performance (as we're typically shape a fewer runs), and the fallback font selection (when the font supports more than just a single language/script). Task-number: QTBUG-29930 Change-Id: I1c55af30bd397871d7f1f6e062605517f5a7e5a1 Reviewed-by: Lars Knoll Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/tools/qunicodetools.cpp | 71 +++++++++++++------------------------ 1 file changed, 24 insertions(+), 47 deletions(-) (limited to 'src/corelib') 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 -- cgit v1.2.3 From ef7b0df4192b390c70a5e848bbe7c397daaefcce Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 26 Apr 2016 14:56:32 -0700 Subject: Fix QArrayData::allocate() to guard against integer overflows The proper solution with qCalculateBlockSize will come for Qt 5.7. Change-Id: Ifea6e497f11a461db432ffff14490788fc522eb7 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qarraydata.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp index d9519745b0..fa6556f7d9 100644 --- a/src/corelib/tools/qarraydata.cpp +++ b/src/corelib/tools/qarraydata.cpp @@ -32,6 +32,7 @@ ****************************************************************************/ #include +#include #include #include @@ -87,16 +88,22 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment, if (capacity > std::numeric_limits::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(::malloc(allocSize)); if (header) { -- cgit v1.2.3 From 3430552881ccd75b4f00c62014b7fa810c998002 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 24 Apr 2016 12:57:25 -0700 Subject: Use C++11 alignas() for Q_DECL_ALIGN, if possible Change-Id: Ifea6e497f11a461db432ffff144863d4ed69a212 Reviewed-by: Marc Mutz --- src/corelib/global/qcompilerdetection.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 25043dab75..8574059616 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -1055,6 +1055,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 */ -- cgit v1.2.3 From 9366a8be1eb7cfa5a5cb3650ae6230b46bb7e538 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 25 Apr 2016 14:43:43 +0200 Subject: Add an early-out to QVector::operator+= and QHash::unite for empty LHS If the container being added to is default constructed and has never been modified, we don't have to do all the checking and iterating. Instead we can just assign with operator=. If the LHS is merely empty, we could lose reserve()d capacity, so only do this for a shared-null LHS. Change-Id: If1e3342662d10833babc7ab847ada0285073723b Reviewed-by: Marc Mutz Reviewed-by: Milian Wolff --- src/corelib/tools/qhash.h | 14 +++++++++----- src/corelib/tools/qvector.h | 36 ++++++++++++++++++++---------------- 2 files changed, 29 insertions(+), 21 deletions(-) (limited to 'src/corelib') 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::createNode(uint ah, const Key &akey, const T &avalue, Node **anex template Q_INLINE_TEMPLATE QHash &QHash::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/qvector.h b/src/corelib/tools/qvector.h index 13ae121450..806a127cc2 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -793,24 +793,28 @@ QVector &QVector::fill(const T &from, int asize) template QVector &QVector::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::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::isComplex) + new (--w) T(*--i); + else + *--w = *--i; + } + d->size = newSize; } - d->size = newSize; } return *this; } -- cgit v1.2.3 From 9a7e967e99957668f7846763ce592f54d94b9a71 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Mon, 18 Apr 2016 18:46:13 +0300 Subject: Unhide QObject::parent() from QFileSystemModel and QIdentityProxyModel It was hidden by overridden parent(const QModelIndex &) methods. See also 63b5082ea8e3e750af986f815474f7207006cb46 (Unhide QObject::parent() from QAbstract{Table,List}model). Change-Id: I8b6d4d4175e4d43ff269eaeb0b2b1a9fb8f44bab Task-number: QTBUG-45393 Reviewed-by: Milian Wolff Reviewed-by: Marc Mutz --- src/corelib/itemmodels/qidentityproxymodel.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/corelib') diff --git a/src/corelib/itemmodels/qidentityproxymodel.h b/src/corelib/itemmodels/qidentityproxymodel.h index 7578f8d380..395fec11cb 100644 --- a/src/corelib/itemmodels/qidentityproxymodel.h +++ b/src/corelib/itemmodels/qidentityproxymodel.h @@ -56,6 +56,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; -- cgit v1.2.3 From 89d1c7c179aea55bd991b524bdcc9c3e265510fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Tue, 19 Apr 2016 13:33:46 +0100 Subject: Make it clear that QObject::tr() falls back to QString::fromUtf8() The reference to trUtf8() made it even more confusing, so remove it. It's redundant and deprecated anyway. Change-Id: I9921297160db3660bb5099692bbfdaf6e85637aa Reviewed-by: Oswald Buddenhagen --- src/corelib/kernel/qobject.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 5afdd6a4e5..19df24744a 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2144,8 +2144,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 @@ -2171,7 +2171,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} */ /*! -- cgit v1.2.3 From 112e53fdc4e46a5e94cb2d575d132e2015694407 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 28 Apr 2016 17:47:57 -0700 Subject: Don't store the pthread_t thread ID twice in QThread MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was being stored once in QThreadPrivate and once in QThreadData, with the latter being hidden as a Qt::HANDLE. Besides saving a little bit of memory, this also solves a small data race condition that arises from trying to connect a signal to an object moved to that thread and then emit that signal shortly after the thread starts. Before this patch, QThreadData::threadId was initialized only by QThreadPrivate::start(), which meant that we were racing that initialization with this check in QMetaObject::activate: const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId; Task-number: QTBUG-52337 Change-Id: Ifea6e497f11a461db432ffff1449ae01f1099aae Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Jędrzej Nowacki --- src/corelib/thread/qthread.cpp | 6 +----- src/corelib/thread/qthread_p.h | 1 - src/corelib/thread/qthread_unix.cpp | 33 +++++++++++++++++---------------- 3 files changed, 18 insertions(+), 22 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index a0a2e76bda..8ea487e330 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -142,16 +142,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_p.h b/src/corelib/thread/qthread_p.h index a0d354acdc..a56b879462 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -169,7 +169,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 af4ce7c59e..3fc0ebfbb6 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -105,6 +105,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) @@ -234,8 +236,6 @@ QThreadData *QThreadData::current(bool createIfNecessary) void QAdoptedThread::init() { - Q_D(QThread); - d->thread_id = pthread_self(); } /* @@ -325,10 +325,11 @@ void *QThreadPrivate::start(void *arg) // sets the name of the current thread. QString objectName = thr->objectName(); + pthread_t thread_id = reinterpret_cast(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 @@ -369,7 +370,6 @@ void QThreadPrivate::finish(void *arg) locker.relock(); } - d->thread_id = 0; d->running = false; d->finished = true; d->interruptionRequested = false; @@ -615,15 +615,16 @@ void QThread::start(Priority priority) } int code = - pthread_create(&d->thread_id, &attr, QThreadPrivate::start, this); + pthread_create(reinterpret_cast(&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(&d->data->threadId), &attr, + QThreadPrivate::start, this); } pthread_attr_destroy(&attr); @@ -633,7 +634,7 @@ void QThread::start(Priority priority) d->running = false; d->finished = false; - d->thread_id = 0; + d->data->threadId = 0; } } @@ -643,10 +644,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(d->data->threadId)); if (code) { qWarning("QThread::start: Thread termination error: %s", qPrintable(qt_error_string((code)))); @@ -659,7 +660,7 @@ bool QThread::wait(unsigned long time) Q_D(QThread); QMutexLocker locker(&d->mutex); - if (d->thread_id == pthread_self()) { + if (reinterpret_cast(d->data->threadId) == pthread_self()) { qWarning("QThread::wait: Thread tried to wait on itself"); return false; } @@ -701,7 +702,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority) int sched_policy; sched_param param; - if (pthread_getschedparam(thread_id, &sched_policy, ¶m) != 0) { + if (pthread_getschedparam(reinterpret_cast(data->threadId), &sched_policy, ¶m) != 0) { // failed to get the scheduling policy, don't bother setting // the priority qWarning("QThread::setPriority: Cannot get scheduler parameters"); @@ -717,15 +718,15 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority) } param.sched_priority = prio; - int status = pthread_setschedparam(thread_id, sched_policy, ¶m); + int status = pthread_setschedparam(reinterpret_cast(data->threadId), sched_policy, ¶m); # 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, ¶m); + pthread_getschedparam(reinterpret_cast(data->threadId), &sched_policy, ¶m); param.sched_priority = sched_get_priority_min(sched_policy); - pthread_setschedparam(thread_id, sched_policy, ¶m); + pthread_setschedparam(reinterpret_cast(data->threadId), sched_policy, ¶m); } # else Q_UNUSED(status); -- cgit v1.2.3 From 5e059c6047a49568233b2379984ccd55614d43c5 Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Sun, 24 Apr 2016 15:22:49 +0200 Subject: Decompress QResources only when needed. In particular, just creating a QFileInfo (or a QDirIterator, which uses QFileInfo internally) no longer triggers decompression. This doubles the performance when using a QDirIterator/QFile combo for loading a bunch of files. Change-Id: I7f53354e890ad6360693b7848d21a0cd5d595628 Reviewed-by: Thiago Macieira --- src/corelib/io/qresource.cpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'src/corelib') 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 -- cgit v1.2.3 From a4d26cf522b966056e47e47a004b7e4d668e3a2d Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Fri, 8 Apr 2016 16:55:39 +0300 Subject: QWindowsPipeWriter: ensure validity of the write buffer QWindowsPipeWriter uses asynchronous API to perform writing. Once a cycle has been started, the write buffer must remain valid until the write operation is completed. To avoid data corruption and possibly undefined behavior, this patch makes QWindowsPipeWriter::write() take a QByteArray, which it keeps alive for the duration of the write cycle. Autotest-by: Thomas Hartmann Task-number: QTBUG-52401 Change-Id: Ia35faee735c4e684267daa1f6bd689512b670cd2 Reviewed-by: Joerg Bornemann --- src/corelib/io/qprocess.cpp | 23 ++------------------ src/corelib/io/qprocess_p.h | 2 +- src/corelib/io/qprocess_unix.cpp | 35 +++++++++++++++++++++--------- src/corelib/io/qprocess_win.cpp | 10 +++++++-- src/corelib/io/qprocess_wince.cpp | 6 ++--- src/corelib/io/qwindowspipewriter.cpp | 41 +++++++++++++++++++++-------------- src/corelib/io/qwindowspipewriter_p.h | 4 +++- 7 files changed, 66 insertions(+), 55 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 68f7157ad2..502628489d 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -1051,7 +1051,6 @@ bool QProcessPrivate::_q_canReadStandardError() */ bool QProcessPrivate::_q_canWrite() { - Q_Q(QProcess); if (stdinChannel.notifier) stdinChannel.notifier->setEnabled(false); @@ -1062,31 +1061,13 @@ bool QProcessPrivate::_q_canWrite() return false; } - qint64 written = writeToStdin(stdinChannel.buffer.readPointer(), - stdinChannel.buffer.nextDataBlockSize()); - if (written < 0) { - closeChannel(&stdinChannel); - setErrorAndEmit(QProcess::WriteError); - return false; - } + const bool writeSucceeded = writeToStdin(); -#if defined QPROCESS_DEBUG - qDebug("QProcessPrivate::canWrite(), wrote %d bytes to the process input", int(written)); -#endif - - if (written != 0) { - stdinChannel.buffer.free(written); - if (!emittedBytesWritten) { - emittedBytesWritten = true; - emit q->bytesWritten(written); - emittedBytesWritten = false; - } - } if (stdinChannel.notifier && !stdinChannel.buffer.isEmpty()) stdinChannel.notifier->setEnabled(true); if (stdinChannel.buffer.isEmpty() && stdinChannel.closed) closeWriteChannel(); - return true; + return writeSucceeded; } /*! diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index 436869462c..0af1903063 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -375,7 +375,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 df13a2533e..fda91780d0 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -620,21 +620,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 = stdinChannel.buffer.readPointer(); + const qint64 bytesToWrite = stdinChannel.buffer.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; + } + stdinChannel.buffer.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 7e9cffe129..592bee58a5 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -787,17 +787,23 @@ 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(stdinChannel.buffer.read()); + return true; } bool QProcessPrivate::waitForWrite(int msecs) diff --git a/src/corelib/io/qprocess_wince.cpp b/src/corelib/io/qprocess_wince.cpp index 050d6879db..ab37a4c484 100644 --- a/src/corelib/io/qprocess_wince.cpp +++ b/src/corelib/io/qprocess_wince.cpp @@ -265,11 +265,9 @@ qint64 QProcessPrivate::pipeWriterBytesToWrite() const return 0; } -qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) +bool QProcessPrivate::writeToStdin() { - Q_UNUSED(data); - Q_UNUSED(maxlen); - return -1; + return false; } bool QProcessPrivate::waitForWrite(int msecs) diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index ff92ca763e..05a4aa484a 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -73,21 +73,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; } @@ -96,20 +94,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; + } } } @@ -129,6 +131,8 @@ void QWindowsPipeWriter::notified(DWORD errorCode, DWORD numberOfBytesWritten) notifiedCalled = true; writeSequenceStarted = false; numberOfBytesToWrite = 0; + Q_ASSERT(errorCode != ERROR_SUCCESS || numberOfBytesWritten == buffer.size()); + buffer.clear(); switch (errorCode) { case ERROR_SUCCESS: @@ -173,21 +177,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 a78ab61adf..0228867522 100644 --- a/src/corelib/io/qwindowspipewriter_p.h +++ b/src/corelib/io/qwindowspipewriter_p.h @@ -47,6 +47,7 @@ #include #include +#include #include QT_BEGIN_NAMESPACE @@ -106,7 +107,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; } @@ -136,6 +137,7 @@ private: HANDLE handle; Overlapped overlapped; + QByteArray buffer; qint64 numberOfBytesToWrite; qint64 pendingBytesWrittenValue; bool stopped; -- cgit v1.2.3 From 0d0141d746e71f25fd68e1439f8251e4e476e332 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 29 Apr 2016 23:14:01 -0700 Subject: Don't bother asking if Linux supports a monotonic clock: it does Change-Id: Id5480807d25e49e78b79ffff144a0e61bd001dff Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Lars Knoll --- src/corelib/tools/qelapsedtimer_unix.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/corelib') 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 -- cgit v1.2.3 From ac7d14f1aa0c0efd861d9801540aaf4e940bb786 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 29 Apr 2016 14:38:09 +0300 Subject: QDateTimeParser: enable RVO in format() Change-Id: I3d9f84d03519b2b8fb37c7d2e773e68bc4b9a1d3 Reviewed-by: Edward Welbourne Reviewed-by: Marc Mutz --- src/corelib/tools/qdatetimeparser.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index c1abdf11a7..fbf91fe8a4 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -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); } -- cgit v1.2.3 From 6cbcff49716e8632fa5d41f68fc11e9ebaf1d3c6 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 29 Apr 2016 12:02:31 +0300 Subject: QDateTime: use default ctor to create invalid object Don't perform some internal init functions. Change-Id: I9986e7a8adab35499aea804d1019012547aefd5d Reviewed-by: Marc Mutz Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- src/corelib/tools/qdatetime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 7cc86eb3f1..e18c220884 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -4699,7 +4699,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 -- cgit v1.2.3 From 54d95d09887e9f6394dcc440369959994ff5bad9 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 29 Apr 2016 11:27:11 +0200 Subject: Fix UB (data race) in Q_GLOBAL_STATIC The store to guard in the inner function's critical section was not synchronized-with the load at the start of the function: T1 T2 guard.load() mutex.lock() guard.load() d = new Type guard.store() guard.load() // use d mutex.unlock() The use of d in T2 does not synchronize with the write to d in T1 -> data race -> UB. Fix by storing with release memory ordering, so that the guard.load() in T2 synchronizes with the guard.store() in T1. Change-Id: I5c1cd1fa097c6397cb0b48b0d8e8012f95978558 Reviewed-by: Thiago Macieira Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/global/qglobalstatic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qglobalstatic.h b/src/corelib/global/qglobalstatic.h index 41fc151652..22194d8be7 100644 --- a/src/corelib/global/qglobalstatic.h +++ b/src/corelib/global/qglobalstatic.h @@ -110,7 +110,7 @@ QT_BEGIN_NAMESPACE guard.store(QtGlobalStatic::Destroyed); \ } \ } cleanup; \ - guard.store(QtGlobalStatic::Initialized); \ + guard.storeRelease(QtGlobalStatic::Initialized); \ } \ } \ return d; \ -- cgit v1.2.3 From c09008d27ca1456fb53a3fc9c71d5f88b1081221 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 2 May 2016 11:34:44 +0200 Subject: QWindowsPipeWriter: Fix developer build with MinGW. Fix signedness in comparion: io\qwindowspipewriter.cpp: In member function 'void QWindowsPipeWriter::notified(DWORD, DWORD)': io\qwindowspipewriter.cpp:134:65: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare] Q_ASSERT(errorCode != ERROR_SUCCESS || numberOfBytesWritten == buffer.size()); Amends change a4d26cf522b966056e47e47a004b7e4d668e3a2d. Task-number: QTBUG-52401 Change-Id: If0c0e2107342408675fa00b93f28c9de339080f6 Reviewed-by: Joerg Bornemann --- src/corelib/io/qwindowspipewriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index 05a4aa484a..839dc8a19c 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -131,7 +131,7 @@ void QWindowsPipeWriter::notified(DWORD errorCode, DWORD numberOfBytesWritten) notifiedCalled = true; writeSequenceStarted = false; numberOfBytesToWrite = 0; - Q_ASSERT(errorCode != ERROR_SUCCESS || numberOfBytesWritten == buffer.size()); + Q_ASSERT(errorCode != ERROR_SUCCESS || numberOfBytesWritten == DWORD(buffer.size())); buffer.clear(); switch (errorCode) { -- cgit v1.2.3 From eb63c0fa4761fa5a8505a594ea5fd861af474533 Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Tue, 19 Apr 2016 14:00:40 +0200 Subject: Add ImInputItemClipRectangle This rectangle represents the "effective" visual rectangle of the input item, excluding any areas obscured due to clipping. Note: The effective visual rectangle will not be influenced by overlapping items. Change-Id: I234176161dcfb9c236124e33ae510a0b01fe6dc3 Reviewed-by: Richard Moe Gustavsen --- src/corelib/global/qnamespace.h | 1 + src/corelib/global/qnamespace.qdoc | 3 +++ 2 files changed, 4 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 5a4f499a87..c73ceb9503 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1340,6 +1340,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 0cc9467921..60ce1fc916 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -2583,6 +2583,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: -- cgit v1.2.3 From 1c456751b35ded269663d63015b8078bab283b93 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 27 Apr 2016 18:40:56 +0300 Subject: Fix QFile::copy() on WinRT. Implementation of QFileSystemEngine::copyFile() uses CopyFile2() as if it is CopyFile() function, but CopyFile2() returns HRESULT, not BOOL. So the success should be checked by "SUCCEEDED()" instead of "!= 0". Current implementation does exactly the opposite because S_OK == 0. Change-Id: I0677d54447d22366fb2031e0b928a3d10e24c0ed Reviewed-by: Maurice Kalinowski --- src/corelib/io/qfilesystemengine_win.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index f1a6019094..e55ab0b544 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -1416,8 +1416,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(), ©Params) != 0; + HRESULT hres = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(), + (const wchar_t*)target.nativeFilePath().utf16(), ©Params); + bool ret = SUCCEEDED(hres); #endif // Q_OS_WINRT if(!ret) error = QSystemError(::GetLastError(), QSystemError::NativeError); -- cgit v1.2.3 From 2410be7f45b8688c9910336ec9b8a79d3232b9c7 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Tue, 5 Apr 2016 16:44:51 +0200 Subject: Tune fast-exit for signal activation for QML. When using QML, it quite often happens that only the QML engine is connected to a signal, and no C++ handlers. By splitting up the fast-exit case and handling QML separately, we can prevent a call to QThread::currentThreadId, and locking+unlocking the mutex. On x86 this saves ~130 instructions according to valgrind. Change-Id: I947fe42afe351922339ac982a6d498bc2f7b5192 Reviewed-by: Simon Hausmann Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qobject.cpp | 17 ++++++++++------- src/corelib/kernel/qobject_p.h | 14 ++++++++++---- 2 files changed, 20 insertions(+), 11 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 2b0eff3708..04ec713522 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -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) { 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, -- cgit v1.2.3 From 5bbbea4c83149d6920cff2991fc2458c49a1004e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 26 Apr 2016 14:43:01 +0200 Subject: normalize structure of plugandpaint example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit as in other examples which come with plugins, use an additional hierarchy level which contains the app and plugin subdirs. Change-Id: I2487755967aa3474c337c8c8af10be49627b63d0 Reviewed-by: Topi Reiniö --- src/corelib/kernel/qobject.cpp | 8 ++++---- src/corelib/plugin/qplugin.qdoc | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 19df24744a..d97f8d0ef1 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -1123,7 +1123,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. @@ -4150,11 +4150,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/plugin/qplugin.qdoc b/src/corelib/plugin/qplugin.qdoc index 1b394c4174..09eed5a1e6 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. -- cgit v1.2.3 From 5eae0ce8008ec4d8641ffdc5eeb221a3da0abfc9 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 6 Jul 2015 12:27:01 +0200 Subject: QScoped(Array)Pointer: canonicalize swapping This includes: - have nothrow member-swap - have ADL non-member swap - not specialize qSwap or std::swap Also prevent QScopedPointer <-> QScopedArrayPointer swaps by overloading swap (both member and non-member) on QScopedArrayPointer. It's not 100% safe, but it's what we're doing elsewhere (QMulti(Map,Hash), say). That's technically a SiC change if users expected (qualified) std::swap to invoke QScopedPointer::swap(), but those users were doing it wrong to begin with, and they now get a compile-error instead of silent pessimization, because generic std::swap() doesn't work on QScopedPointer, due to lack of copy (and thus move) semantics. Change-Id: I3ab5c1668722a2c8ccafc16f57310ce8d4bffbd6 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qscopedpointer.h | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'src/corelib') 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 &other) + void swap(QScopedPointer &other) Q_DECL_NOTHROW { qSwap(d, other.d); } @@ -189,18 +189,9 @@ inline bool operator!=(const QScopedPointer &lhs, const QScopedPoint } template -Q_INLINE_TEMPLATE void qSwap(QScopedPointer &p1, QScopedPointer &p2) +inline void swap(QScopedPointer &p1, QScopedPointer &p2) Q_DECL_NOTHROW { p1.swap(p2); } -QT_END_NAMESPACE -namespace std { - template - Q_INLINE_TEMPLATE void swap(QT_PREPEND_NAMESPACE(QScopedPointer) &p1, QT_PREPEND_NAMESPACE(QScopedPointer) &p2) - { p1.swap(p2); } -} -QT_BEGIN_NAMESPACE - - namespace QtPrivate { template struct QScopedArrayEnsureSameType; @@ -230,6 +221,9 @@ public: return this->d[i]; } + void swap(QScopedArrayPointer &other) Q_DECL_NOTHROW // prevent QScopedPointer <->QScopedArrayPointer swaps + { QScopedPointer::swap(other); } + private: explicit inline QScopedArrayPointer(void *) { // Enforce the same type. @@ -245,6 +239,10 @@ private: Q_DISABLE_COPY(QScopedArrayPointer) }; +template +inline void swap(QScopedArrayPointer &lhs, QScopedArrayPointer &rhs) Q_DECL_NOTHROW +{ lhs.swap(rhs); } + QT_END_NAMESPACE #endif // QSCOPEDPOINTER_H -- cgit v1.2.3 From 691151a2411da76987f3e9cb2b6e278a3cb93767 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Wed, 4 May 2016 16:25:52 +0300 Subject: QUrlQuery: use erase and std::remove_if with QList ... instead of using erase() in a loop, with quadratic complexity. Change-Id: I277ff2527e0a22b3d754b1d14296b9882f164c23 Reviewed-by: Marc Mutz --- src/corelib/io/qurlquery.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/corelib') 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 #include +#include + 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 &item) { + return item.first == encodedKey; + }; + const auto end = d->itemList.end(); + d->itemList.erase(std::remove_if(d->itemList.begin(), end, firstEqualsEncodedKey), end); } } -- cgit v1.2.3 From f57d8f1341587e6b2aa84b8404aa218432584206 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Sat, 5 Mar 2016 19:32:02 +0200 Subject: QFileSystemMetaData: do not treat block devices as sequential MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch allows handling of special block devices in random-access mode that restores a Qt4 behavior. Can not be tested because requires root privileges in the system. Task-number: QTBUG-51666 Change-Id: Iaa56355f1be343c0d05b292e3c7d2e1c88724529 Reviewed-by: Edward Welbourne Reviewed-by: Andrius Štikonas Reviewed-by: Oswald Buddenhagen Reviewed-by: Allan Sandfeld Jensen --- src/corelib/io/qfilesystemengine.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index a49d69d447..02aa2ff4b7 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -258,7 +258,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 @@ -341,6 +341,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: -- cgit v1.2.3 From 0b2bc18efdd37e0cf00c40017c55a4f26cd4c60a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 1 May 2016 19:22:40 -0700 Subject: Mark QTimeZone constructor nothrow. Change-Id: Id5480807d25e49e78b79ffff144a9eead3fc9597 Reviewed-by: Marc Mutz --- src/corelib/tools/qtimezone.cpp | 2 +- src/corelib/tools/qtimezone.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/corelib') 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 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, -- cgit v1.2.3 From 04ca11e6f9c69ac47cca8a35135718cc67f5019c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 30 Apr 2016 20:11:35 -0700 Subject: Remove includes to qdatetime_p.h that aren't necessary Since I'm changing QDateTime's privates, it's easier to know what may be depending on it or not. Change-Id: Id5480807d25e49e78b79ffff144a53018d057e19 Reviewed-by: Marc Mutz --- src/corelib/tools/qlocale.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index eccedca4c8..ea5d74d9bb 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" -- cgit v1.2.3 From a63ca3fa106f4b0f9776bf2004661ef6dec2c0c6 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 28 Apr 2016 14:09:32 -0700 Subject: Implement QLibrary::PreventUnloadHint for Windows It's interesting that the HMODULE/HINSTANCE pointer points to something in the actual module that got loaded, so we can use its value as "address of something in the module" for GetModuleHandleEx. The "PIN" flag tells the Windows DLL loader to never unload. Change-Id: Ifea6e497f11a461db432ffff1449a2169eb6293e Reviewed-by: Friedemann Kleint Reviewed-by: Kai Koehne Reviewed-by: Joerg Bornemann --- src/corelib/plugin/qlibrary.cpp | 2 -- src/corelib/plugin/qlibrary_win.cpp | 10 ++++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'src/corelib') 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 deec54db0a..95e5afa837 100644 --- a/src/corelib/plugin/qlibrary_win.cpp +++ b/src/corelib/plugin/qlibrary_win.cpp @@ -148,6 +148,16 @@ bool QLibraryPrivate::load_sys() else qualifiedFileName = dir.filePath(moduleFileName); #endif // !Q_OS_WINRT + + 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(pHnd), + &hmod); + Q_ASSERT(!ok || hmod == pHnd); + } } return (pHnd != 0); } -- cgit v1.2.3 From 29efec2d8cc8138f990fedc55a73e48635f999fb Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 25 Apr 2016 17:55:55 -0700 Subject: Mark QThread::currentThreadId() as a pure function It always returns the same information for each thread it is called in. But since it's different per thread, we don't think it's const. pthread_self() on Linux is marked const, though we think it really ought to be pure. On other OSes, the annotation isn't present, but the we can assume function is so. Change-Id: Ifea6e497f11a461db432ffff1448c2b37d94d5f3 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/thread/qthread.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') 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(); -- cgit v1.2.3 From 75d65600f9fd41cb88068c664e3e94bb67eebc93 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 13 Jul 2015 18:09:23 -0700 Subject: Work around ICC's bug in making std::atomic a literal type ICC 15.x and 16.0 (beta, at least) are missing the "constexpr" and "noexcept" keywords in the definition of the std::atomic constructors. The lack of constexpr makes std::atomic a non-literal type, which in turn makes QBasicAtomicInteger's constructor (which is constexpr) fail to compile. Reported as Intel issue 6000117277. Change-Id: I4a88bcca48bf0ce51557d809ef32a4545edcafee Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/global/qcompilerdetection.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index a08fde8bb0..85613283f9 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -1023,9 +1023,15 @@ // Also disable , 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 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 -- cgit v1.2.3 From 0b1b06ffc0a334263c01e32e5bfb50b4d96ba70d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 25 Apr 2016 16:42:11 -0700 Subject: Add a QMutex::isRecursive() const noexcept This is source- and binary-compatible, including the marking of the existing function as noexcept. [ChangeLog][QtCore][QMutex] Made the isRecursive() method be a const function so that it can be called in const QMutex objects too. Change-Id: Ifea6e497f11a461db432ffff1448bead97c08f92 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/thread/qmutex.cpp | 13 ++++++++----- src/corelib/thread/qmutex.h | 11 +++++++---- 2 files changed, 15 insertions(+), 9 deletions(-) (limited to 'src/corelib') 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) -- cgit v1.2.3 From 4a4b377cd0912615477083d0f597907a51d025a9 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 4 May 2016 14:51:37 +0200 Subject: QJsonValue: don't create a temporary QString on every toString() invocation The vast majority of users call toString() without the optional defaultValue. So do it like the toArray() and toObject() methods and split toString() into two overloads, so the common case no longer needs to pass a temporaray QString. Saves ~1.4 and ~1KiB in QtCore and QtGui text size, resp., on optimized GCC 6.0 Linux AMD64 builds, even though we added a new function to QtCore, too. Change-Id: Ibe02397ca49ce11fdb58f5c5fc69e909bf94c1c6 Reviewed-by: Lars Knoll --- src/corelib/json/qjsonvalue.cpp | 16 ++++++++++++++++ src/corelib/json/qjsonvalue.h | 3 ++- 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'src/corelib') 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 @@ -563,6 +563,22 @@ QString QJsonValue::toString(const QString &defaultValue) const return QString(holder); } +/*! + 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. 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; -- cgit v1.2.3 From 45655cbe8d73db13d33d4facbfd2c18db8f38952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Thu, 25 Feb 2016 14:44:12 +0100 Subject: Be more specific what is in Core and what is not !isComplex is quite good heuristic, but we know for sure which types should be included. Change-Id: I609d021b8a668e6c1945ed2b11d69f5a82b5e2bf Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qmetatype_p.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/corelib') 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::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) -- cgit v1.2.3 From 7abb90a70aed97c665430eb1e9f174dce26addd4 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 29 Apr 2016 15:50:11 +0300 Subject: QDateTimeParser: proper construction of QString ... with known size and known char by corresponding ctor. Don't use fill() for this case. Change-Id: I475a0655132ecbb40b1eac919309597b2560e71b Reviewed-by: Edward Welbourne Reviewed-by: Marc Mutz --- src/corelib/tools/qdatetimeparser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index fbf91fe8a4..9b0f293d59 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -847,7 +847,7 @@ int QDateTimeParser::parseSection(const QDateTime ¤tValue, 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(this)->sectionNodes[sectionIndex].zeroesAdded); -- cgit v1.2.3 From 2f595a0178bc5f3c8c0ad5464913c753bbde5e82 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Wed, 4 May 2016 18:08:26 +0300 Subject: QUrl: enable (N)RVO for gcc Change-Id: Ie0fba08ce55a3c60a5b1565986c4280f065c7b2f Reviewed-by: Thiago Macieira --- src/corelib/io/qurl.cpp | 74 ++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index fda7d59619..451e3b2967 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -2046,14 +2046,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; } @@ -2119,14 +2120,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; } @@ -2188,10 +2190,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; } @@ -2281,10 +2282,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; } @@ -2389,12 +2389,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; } @@ -2534,10 +2534,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; } @@ -2977,12 +2976,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; } @@ -3050,12 +3049,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; } @@ -3272,9 +3271,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"); @@ -3291,11 +3291,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; @@ -4036,16 +4035,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("\";"); -- cgit v1.2.3 From 4c06592ad80dc55420c4b9efebae2a39f4ad5542 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 10 May 2016 14:09:59 +0200 Subject: Fix build on WinRT a63ca3fa106f4b0f9776bf2004661ef6dec2c0c6 caused a build breakage for WinRT as GetModuleHandleEx does not exist on that platform. Change-Id: I143d9cad5f32d98a4d86292dfa73f94a4acdf305 Reviewed-by: Simon Hausmann --- src/corelib/plugin/qlibrary_win.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/plugin/qlibrary_win.cpp b/src/corelib/plugin/qlibrary_win.cpp index 95e5afa837..46fbba151c 100644 --- a/src/corelib/plugin/qlibrary_win.cpp +++ b/src/corelib/plugin/qlibrary_win.cpp @@ -147,7 +147,6 @@ bool QLibraryPrivate::load_sys() qualifiedFileName = moduleFileName; else qualifiedFileName = dir.filePath(moduleFileName); -#endif // !Q_OS_WINRT if (loadHints() & QLibrary::PreventUnloadHint) { // prevent the unloading of this component @@ -157,7 +156,9 @@ bool QLibraryPrivate::load_sys() reinterpret_cast(pHnd), &hmod); Q_ASSERT(!ok || hmod == pHnd); + Q_UNUSED(ok); } +#endif // !Q_OS_WINRT } return (pHnd != 0); } -- cgit v1.2.3 From a5159cc50aa0f8a57b6f736621b359a3bcecbf7e Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 28 Apr 2016 09:40:49 +0200 Subject: QJsonObject: add some overloads taking QLatin1String QXmlStreamReader also has QLatin1String overloads, which greatly benefits parsers, since the vast majority of keys in both JSON and XML are US-ASCII. This patch adds such an overload to the JSON parser. The value() function is all typical parsers need, so even though many more QJsonObject functions taking QString could benefit from the same treatment, value() is the single most important one for read-only JSON access. Add some more overloads, too, for functions that don't need more internal scaffolding than value(). Requires adding a dummy op[](QL1S) (forwarding to the QString overload) so as not to make QJsonObject json; json[QLatin1String("key")]; // mutable ambiguous between const op[](QL1S) and mutable op[](QString). [ChangeLog][QtCore][QJsonObject] Added value(), op[] const, find(), constFind(), contains() overloads taking QLatin1String. Change-Id: I00883028956ad949ba5ba2b18dd8a6a25ad5085b Reviewed-by: Lars Knoll --- src/corelib/json/qjson.cpp | 32 +++++++++++++++- src/corelib/json/qjson_p.h | 18 ++++++++- src/corelib/json/qjsonobject.cpp | 80 ++++++++++++++++++++++++++++++++++++++++ src/corelib/json/qjsonobject.h | 7 ++++ 4 files changed, 135 insertions(+), 2 deletions(-) (limited to 'src/corelib') 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 3580e0b61c..5e34845fe3 100644 --- a/src/corelib/json/qjson_p.h +++ b/src/corelib/json/qjson_p.h @@ -573,7 +573,8 @@ public: Entry *entryAt(int i) const { return reinterpret_cast(((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; }; @@ -675,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; }; @@ -687,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 7badc9d929..b5b6f36bc6 100644 --- a/src/corelib/json/qjsonobject.cpp +++ b/src/corelib/json/qjsonobject.cpp @@ -374,6 +374,22 @@ QJsonValue QJsonObject::value(const QString &key) const return QJsonValue(d, o, o->entryAt(i)->value); } +/*! + \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. @@ -388,6 +404,13 @@ QJsonValue QJsonObject::operator [](const QString &key) const return value(key); } +/*! + \fn QJsonValue QJsonObject::operator [](QLatin1String key) const + + \overload + \since 5.7 +*/ + /*! Returns a reference to the value for \a key. @@ -411,6 +434,16 @@ QJsonValueRef QJsonObject::operator [](const QString &key) return QJsonValueRef(this, index); } +/*! + \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. @@ -535,6 +568,20 @@ bool QJsonObject::contains(const QString &key) const return keyExists; } +/*! + \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. */ @@ -609,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. @@ -630,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 -- cgit v1.2.3 From f5aa65349cf567dbbd512cbf8d08f5968e9c462a Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 28 Apr 2016 09:51:24 +0200 Subject: QFactoryLoader: use new QJsonObject::value(QLatin1String) Allows to get rid of some QStringLiterals, reducing QtCore text size by ~800b. Change-Id: I8f7e57927163eaaf628e42020f83f053faea6bf8 Reviewed-by: Lars Knoll --- src/corelib/plugin/qfactoryloader.cpp | 38 ++++++++++------------------------- 1 file changed, 11 insertions(+), 27 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index dce750b5ad..6cd02e3a3f 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) @@ -163,12 +151,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(); } @@ -191,9 +179,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; @@ -274,7 +262,7 @@ QList 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); } @@ -308,7 +296,7 @@ QObject *QFactoryLoader::instance(int index) const QVector 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) @@ -322,12 +310,10 @@ QObject *QFactoryLoader::instance(int index) const QMultiMap QFactoryLoader::keyMap() const { QMultiMap result; - const QString metaDataKey = metaDataKeyLiteral(); - const QString keysKey = keysKeyLiteral(); const QList 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()); @@ -337,12 +323,10 @@ QMultiMap QFactoryLoader::keyMap() const int QFactoryLoader::indexOf(const QString &needle) const { - const QString metaDataKey = metaDataKeyLiteral(); - const QString keysKey = keysKeyLiteral(); const QList 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)) -- cgit v1.2.3 From 967c91e7778f571cd2f9fc9bc5f3e3c63b9c27da Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 7 Dec 2015 18:53:55 -0800 Subject: Make it an #error if we failed to detect the ARM architecture version ... or if it is less than ARMv5. The last ARMv4 Qt supported was Windows CE 7, which was dropped for Qt 5.7 alongside MSVC 2008. Change-Id: Ifc817705441a4aab9469ffff141dcfe491464efa Reviewed-by: Maurice Kalinowski --- src/corelib/global/qprocessordetection.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/corelib') 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 -- cgit v1.2.3 From c6618cb8852cd4572d42004c58c6b9c11affc635 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 29 Apr 2016 14:36:32 +0300 Subject: QDateTimeParser: de-duplicate calls and cache results Change-Id: I0d6065fbdd19acff14072ff626585e8a12a3e073 Reviewed-by: Edward Welbourne Reviewed-by: Marc Mutz --- src/corelib/tools/qdatetimeparser.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index 9b0f293d59..5eaa1252d6 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -553,19 +553,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::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(); @@ -1164,11 +1165,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); -- cgit v1.2.3 From 361564dacf75019f8436ac42fa44c95ceac9e1db Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 29 Apr 2016 13:24:20 +0300 Subject: QDateTimeParser: adapt unquote() to make good use of QStringRef. Avoid unnecessary allocations. Change-Id: I9bed622c0dd7d9fe993b52d9169d1773957da4f2 Reviewed-by: Edward Welbourne Reviewed-by: Marc Mutz --- src/corelib/tools/qdatetimeparser.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index 5eaa1252d6..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; -- cgit v1.2.3