From e8ea1edd89729d4caeffa70dd8cf76a686294987 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Tue, 11 Apr 2017 13:17:21 +0300 Subject: Android: Fix deadlock when calling requestPermission The hang happend when using QtAndroidPrivate::requestPermissions before the QApplication::exec. Android UI calls "sendRequestPermissionsResult" which was blocking until the event is delivered, but the qt main loop is blocked and waits for the main surface to be created by the Android UI thread which is already blocked. With this patch sendRequestPermissionsResult won't block for the result to be delivered. Change-Id: I48ada65fe9ea63471ab46d8a9d839ba1b91d17b3 Reviewed-by: Christian Stromme --- src/corelib/kernel/qjnihelpers.cpp | 15 ++++++++------- src/corelib/kernel/qjnihelpers_p.h | 8 ++++++-- 2 files changed, 14 insertions(+), 9 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp index 93bc477e7d..cb4b93905e 100644 --- a/src/corelib/kernel/qjnihelpers.cpp +++ b/src/corelib/kernel/qjnihelpers.cpp @@ -80,13 +80,13 @@ class PermissionsResultClass : public QObject Q_OBJECT public: PermissionsResultClass(const QtAndroidPrivate::PermissionsResultFunc &func) : m_func(func) {} - Q_INVOKABLE void sendResult(const QtAndroidPrivate::PermissionsHash &result) { m_func(result); } + Q_INVOKABLE void sendResult(const QtAndroidPrivate::PermissionsHash &result) { m_func(result); delete this;} private: QtAndroidPrivate::PermissionsResultFunc m_func; }; -typedef QHash> PendingPermissionRequestsHash; +typedef QHash PendingPermissionRequestsHash; Q_GLOBAL_STATIC(PendingPermissionRequestsHash, g_pendingPermissionRequests); static QBasicMutex g_pendingPermissionRequestsMutex; static int nextRequestCode() @@ -131,11 +131,11 @@ static void sendRequestPermissionsResult(JNIEnv *env, jobject /*obj*/, jint requ // show an error or something ? return; } - auto request = std::move(*it); + auto request = *it; g_pendingPermissionRequests->erase(it); locker.unlock(); - Qt::ConnectionType connection = QThread::currentThread() == request->thread() ? Qt::DirectConnection : Qt::BlockingQueuedConnection; + Qt::ConnectionType connection = QThread::currentThread() == request->thread() ? Qt::DirectConnection : Qt::QueuedConnection; QtAndroidPrivate::PermissionsHash hash; const int size = env->GetArrayLength(permissions); std::unique_ptr results(new jint[size]); @@ -147,7 +147,7 @@ static void sendRequestPermissionsResult(JNIEnv *env, jobject /*obj*/, jint requ QtAndroidPrivate::PermissionsResult::Denied; hash[permission] = value; } - QMetaObject::invokeMethod(request.data(), "sendResult", connection, Q_ARG(QtAndroidPrivate::PermissionsHash, hash)); + QMetaObject::invokeMethod(request, "sendResult", connection, Q_ARG(QtAndroidPrivate::PermissionsHash, hash)); } static jboolean dispatchGenericMotionEvent(JNIEnv *, jclass, jobject event) @@ -410,6 +410,7 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env) g_jNativeClass = static_cast(env->NewGlobalRef(jQtNative)); env->DeleteLocalRef(jQtNative); + qRegisterMetaType(); return JNI_OK; } @@ -491,13 +492,13 @@ void QtAndroidPrivate::requestPermissions(JNIEnv *env, const QStringList &permis const int requestCode = nextRequestCode(); if (!directCall) { QMutexLocker locker(&g_pendingPermissionRequestsMutex); - (*g_pendingPermissionRequests)[requestCode] = QSharedPointer::create(callbackFunc); + (*g_pendingPermissionRequests)[requestCode] = new PermissionsResultClass(callbackFunc); } runOnAndroidThread([permissions, callbackFunc, requestCode, directCall] { if (directCall) { QMutexLocker locker(&g_pendingPermissionRequestsMutex); - (*g_pendingPermissionRequests)[requestCode] = QSharedPointer::create(callbackFunc); + (*g_pendingPermissionRequests)[requestCode] = new PermissionsResultClass(callbackFunc); } QJNIEnvironmentPrivate env; diff --git a/src/corelib/kernel/qjnihelpers_p.h b/src/corelib/kernel/qjnihelpers_p.h index 62f9358513..d88e4fc19e 100644 --- a/src/corelib/kernel/qjnihelpers_p.h +++ b/src/corelib/kernel/qjnihelpers_p.h @@ -52,8 +52,10 @@ // #include -#include #include +#include +#include +#include QT_BEGIN_NAMESPACE @@ -117,7 +119,7 @@ namespace QtAndroidPrivate Q_CORE_EXPORT void runOnAndroidThreadSync(const Runnable &runnable, JNIEnv *env, int timeoutMs = INT_MAX); Q_CORE_EXPORT void runOnUiThread(QRunnable *runnable, JNIEnv *env); Q_CORE_EXPORT void requestPermissions(JNIEnv *env, const QStringList &permissions, const PermissionsResultFunc &callbackFunc, bool directCall = false); - Q_CORE_EXPORT QHash requestPermissionsSync(JNIEnv *env, const QStringList &permissions, int timeoutMs = INT_MAX); + Q_CORE_EXPORT PermissionsHash requestPermissionsSync(JNIEnv *env, const QStringList &permissions, int timeoutMs = INT_MAX); Q_CORE_EXPORT PermissionsResult checkPermission(const QString &permission); Q_CORE_EXPORT bool shouldShowRequestPermissionRationale(const QString &permission); @@ -145,4 +147,6 @@ namespace QtAndroidPrivate QT_END_NAMESPACE +Q_DECLARE_METATYPE(QtAndroidPrivate::PermissionsHash) + #endif // QJNIHELPERS_H -- cgit v1.2.3 From 6ae801875ea3c654f808b7ed519b403807653068 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 5 Jun 2017 10:52:02 -0700 Subject: Re-fix the detection of CPU architecture on an Apple OS Commit d56c6cf7a4fe2b7e5543d58a786efc768b7370c2 was incorrect. It was a nice try, but on a 64-bit Mac machine (x86_64 CPU), it returned hw.cputype = 7, which is CPU_TYPE_X86. CPU_TYPE_X86_64 is only used in Mach-O slices for fat binaries and does not reflect hw.cputype. Task-number: QTBUG-61205 Change-Id: Ia3e896da908f42939148fffd14c54b3050b8e64b Reviewed-by: Jake Petroules --- src/corelib/global/qglobal.cpp | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 2176bd8d4a..583acef377 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -86,12 +86,6 @@ # include #endif -#if defined(Q_OS_DARWIN) -# include -# include -# include -#endif - #ifdef Q_OS_UNIX #include #include @@ -2443,20 +2437,9 @@ QString QSysInfo::currentCpuArchitecture() case PROCESSOR_ARCHITECTURE_IA64: return QStringLiteral("ia64"); } -#elif defined(Q_OS_DARWIN) - cpu_type_t type; - size_t size = sizeof(type); - sysctlbyname("hw.cputype", &type, &size, NULL, 0); - switch (type) { - case CPU_TYPE_X86: - return QStringLiteral("i386"); - case CPU_TYPE_X86_64: - return QStringLiteral("x86_64"); - case CPU_TYPE_ARM: - return QStringLiteral("arm"); - case CPU_TYPE_ARM64: - return QStringLiteral("arm64"); - } +#elif defined(Q_OS_DARWIN) && !defined(Q_OS_MACOS) + // iOS-based OSes do not return the architecture on uname(2)'s result. + return buildCpuArchitecture(); #elif defined(Q_OS_UNIX) long ret = -1; struct utsname u; -- cgit v1.2.3 From d254d8c19714af69a9897bdd67c4e9aa3267c3a3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 18 Apr 2017 16:43:41 -0700 Subject: Use the C++ [[nodiscard]] attribute Change-Id: I7814054a102a407d876ffffd14b6a285c70b21de Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Lars Knoll --- src/corelib/global/qcompilerdetection.h | 67 ++++++++++++++++++--------------- src/corelib/tools/qbytearray.h | 2 +- src/corelib/tools/qstring.h | 2 +- 3 files changed, 38 insertions(+), 33 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index c221115e8f..9ffd164b61 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -1060,6 +1060,37 @@ # endif #endif +/* + * SG10's SD-6 feature detection and some useful extensions from Clang and GCC + * https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations + * http://clang.llvm.org/docs/LanguageExtensions.html#feature-checking-macros + */ +#ifdef __has_builtin +# define QT_HAS_BUILTIN(x) __has_builtin(x) +#else +# define QT_HAS_BUILTIN(x) 0 +#endif +#ifdef __has_attribute +# define QT_HAS_ATTRIBUTE(x) __has_attribute(x) +#else +# define QT_HAS_ATTRIBUTE(x) 0 +#endif +#ifdef __has_cpp_attribute +# define QT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +# define QT_HAS_CPP_ATTRIBUTE(x) 0 +#endif +#ifdef __has_include +# define QT_HAS_INCLUDE(x) __has_include(x) +#else +# define QT_HAS_INCLUDE(x) 0 +#endif +#ifdef __has_include_next +# define QT_HAS_INCLUDE_NEXT(x) __has_include_next(x) +#else +# define QT_HAS_INCLUDE_NEXT(x) 0 +#endif + /* * C++11 keywords and expressions */ @@ -1141,6 +1172,11 @@ # define Q_DECL_ALIGN(n) alignas(n) #endif +#if QT_HAS_CPP_ATTRIBUTE(nodiscard) // P0188R1 +# undef Q_REQUIRED_RESULT +# define Q_REQUIRED_RESULT [[nodiscard]] +#endif + /* * Fallback macros to certain compiler features */ @@ -1215,37 +1251,6 @@ #ifndef QT_MAKE_CHECKED_ARRAY_ITERATOR # define QT_MAKE_CHECKED_ARRAY_ITERATOR(x, N) (x) #endif - -/* - * SG10's SD-6 feature detection and some useful extensions from Clang and GCC - * https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations - * http://clang.llvm.org/docs/LanguageExtensions.html#feature-checking-macros - */ -#ifdef __has_builtin -# define QT_HAS_BUILTIN(x) __has_builtin(x) -#else -# define QT_HAS_BUILTIN(x) 0 -#endif -#ifdef __has_attribute -# define QT_HAS_ATTRIBUTE(x) __has_attribute(x) -#else -# define QT_HAS_ATTRIBUTE(x) 0 -#endif -#ifdef __has_cpp_attribute -# define QT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) -#else -# define QT_HAS_CPP_ATTRIBUTE(x) 0 -#endif -#ifdef __has_include -# define QT_HAS_INCLUDE(x) __has_include(x) -#else -# define QT_HAS_INCLUDE(x) 0 -#endif -#ifdef __has_include_next -# define QT_HAS_INCLUDE_NEXT(x) __has_include_next(x) -#else -# define QT_HAS_INCLUDE_NEXT(x) 0 -#endif #ifdef __has_feature # define QT_HAS_FEATURE(x) __has_feature(x) #else diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index 03bb9b5747..432ef922f6 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -243,7 +243,7 @@ public: void chop(int n); #if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(QT_COMPILING_QSTRING_COMPAT_CPP) && !defined(Q_CLANG_QDOC) -# if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) +# if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) && !QT_HAS_CPP_ATTRIBUTE(nodiscard) // required due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61941 # pragma push_macro("Q_REQUIRED_RESULT") # undef Q_REQUIRED_RESULT diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 109b68c544..88ba4a3fb5 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -383,7 +383,7 @@ public: Q_REQUIRED_RESULT QString rightJustified(int width, QChar fill = QLatin1Char(' '), bool trunc = false) const; #if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(QT_COMPILING_QSTRING_COMPAT_CPP) && !defined(Q_CLANG_QDOC) -# if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) +# if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) && !QT_HAS_CPP_ATTRIBUTE(nodiscard) // required due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61941 # pragma push_macro("Q_REQUIRED_RESULT") # undef Q_REQUIRED_RESULT -- cgit v1.2.3 From 510d18d7aedc1c7853292395dd0e6b470570cc9d Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Mon, 5 Jun 2017 10:32:21 -0700 Subject: Update for the newest Darwin-family operating systems Change-Id: Id6533c8a444854f6215f6e47000875ef9751905b Reviewed-by: Gabriel de Dietrich Reviewed-by: Lars Knoll --- src/corelib/global/qglobal.cpp | 2 ++ src/corelib/global/qoperatingsystemversion.cpp | 8 ++++++++ src/corelib/global/qoperatingsystemversion.h | 1 + 3 files changed, 11 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 583acef377..5b57e1ad61 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2005,6 +2005,8 @@ static const char *osVer_helper(QOperatingSystemVersion version = QOperatingSyst return "El Capitan"; case 12: return "Sierra"; + case 13: + return "High Sierra"; } } // unknown, future version diff --git a/src/corelib/global/qoperatingsystemversion.cpp b/src/corelib/global/qoperatingsystemversion.cpp index bed08f0000..244f294312 100644 --- a/src/corelib/global/qoperatingsystemversion.cpp +++ b/src/corelib/global/qoperatingsystemversion.cpp @@ -412,6 +412,14 @@ const QOperatingSystemVersion QOperatingSystemVersion::OSXElCapitan = const QOperatingSystemVersion QOperatingSystemVersion::MacOSSierra = QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 10, 12); +/*! + \variable QOperatingSystemVersion::MacOSHighSierra + \brief a version corresponding to macOS High Sierra (version 10.13). + \since 5.9.1 + */ +const QOperatingSystemVersion QOperatingSystemVersion::MacOSHighSierra = + QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 10, 13); + /*! \variable QOperatingSystemVersion::AndroidJellyBean \brief a version corresponding to Android Jelly Bean (version 4.1, API level 16). diff --git a/src/corelib/global/qoperatingsystemversion.h b/src/corelib/global/qoperatingsystemversion.h index cc14d701e1..295365aad1 100644 --- a/src/corelib/global/qoperatingsystemversion.h +++ b/src/corelib/global/qoperatingsystemversion.h @@ -69,6 +69,7 @@ public: static const QOperatingSystemVersion OSXYosemite; static const QOperatingSystemVersion OSXElCapitan; static const QOperatingSystemVersion MacOSSierra; + static const QOperatingSystemVersion MacOSHighSierra; static const QOperatingSystemVersion AndroidJellyBean; static const QOperatingSystemVersion AndroidJellyBean_MR1; -- cgit v1.2.3 From 86a948fc0ff124d2ef03956ac507c923cbb262eb Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 3 May 2017 11:42:16 +0200 Subject: Document that QLoggingCategory is thread-safe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-60475 Change-Id: Idced5e1a8ad1d2d28839fd23126a7bf084141eca Reviewed-by: Topi Reiniƶ --- src/corelib/io/qloggingcategory.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp index 967a614a2d..69af936bca 100644 --- a/src/corelib/io/qloggingcategory.cpp +++ b/src/corelib/io/qloggingcategory.cpp @@ -63,6 +63,7 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift) \class QLoggingCategory \inmodule QtCore \since 5.2 + \threadsafe \brief The QLoggingCategory class represents a category, or 'area' in the logging infrastructure. @@ -95,6 +96,9 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift) \li Category names starting with \c{qt} are reserved for Qt modules. \endlist + QLoggingCategory objects implicitly defined by Q_LOGGING_CATEGORY() + are created on first use in a thread-safe manner. + \section1 Checking Category Configuration QLoggingCategory provides \l isDebugEnabled(), \l isInfoEnabled(), @@ -458,6 +462,8 @@ void QLoggingCategory::setFilterRules(const QString &rules) \note Arguments are not processed if debug output for the category is not enabled, so do not rely on any side effects. + \note Using the macro is thread-safe. + \sa qDebug() */ @@ -477,6 +483,8 @@ void QLoggingCategory::setFilterRules(const QString &rules) \note Arguments might not be processed if debug output for the category is not enabled, so do not rely on any side effects. + \note Using the macro is thread-safe. + \sa qDebug() */ @@ -499,6 +507,8 @@ void QLoggingCategory::setFilterRules(const QString &rules) \note Arguments are not processed if debug output for the category is not enabled, so do not rely on any side effects. + \note Using the macro is thread-safe. + \sa qInfo() */ @@ -518,6 +528,8 @@ void QLoggingCategory::setFilterRules(const QString &rules) \note Arguments might not be processed if debug output for the category is not enabled, so do not rely on any side effects. + \note Using the macro is thread-safe. + \sa qInfo() */ @@ -540,6 +552,8 @@ void QLoggingCategory::setFilterRules(const QString &rules) \note Arguments are not processed if warning output for the category is not enabled, so do not rely on any side effects. + \note Using the macro is thread-safe. + \sa qWarning() */ @@ -559,6 +573,8 @@ void QLoggingCategory::setFilterRules(const QString &rules) \note Arguments might not be processed if warning output for the category is not enabled, so do not rely on any side effects. + \note Using the macro is thread-safe. + \sa qWarning() */ @@ -581,6 +597,8 @@ void QLoggingCategory::setFilterRules(const QString &rules) \note Arguments are not processed if critical output for the category is not enabled, so do not rely on any side effects. + \note Using the macro is thread-safe. + \sa qCritical() */ @@ -600,6 +618,8 @@ void QLoggingCategory::setFilterRules(const QString &rules) \note Arguments might not be processed if critical output for the category is not enabled, so do not rely on any side effects. + \note Using the macro is thread-safe. + \sa qCritical() */ /*! @@ -624,7 +644,8 @@ void QLoggingCategory::setFilterRules(const QString &rules) \a string identifier. By default, all message types are enabled. Only one translation unit in a library or executable can define a category - with a specific name. + with a specific name. The implicitly defined QLoggingCategory object is + created on first use, in a thread-safe manner. This macro must be used outside of a class or method. */ @@ -640,7 +661,8 @@ void QLoggingCategory::setFilterRules(const QString &rules) and more severe are enabled, types with a lower severity are disabled. Only one translation unit in a library or executable can define a category - with a specific name. + with a specific name. The implicitly defined QLoggingCategory object is + created on first use, in a thread-safe manner. This macro must be used outside of a class or method. It is only defined if variadic macros are supported. -- cgit v1.2.3 From 147aa291620d9e2533bbea536a748a8f8a7ed14b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 5 May 2017 16:57:56 +0100 Subject: Fix sending UTC-offset QTimeZones through QDataStream QTimeZone("UTC") should be valid, as "UTC" appears in the list of availableTimeZoneIds(), and tst_QTimeZone::dataStreamTest() constructs timezones like this, which are considered valid. The internal representation of a QTimeZone("UTC") as created by QTimeZone::QTimeZone(const QByteArray &ianaId) is a QUtcTimeZonePrivate which isValid(), so the containing QTimeZone isValid() too. When QTimeZone is serialized into a QDataStream, it calls tz.d->serialize(ds) which is QUtcTimeZonePrivate::serialize. This writes QStringLiteral("OffsetFromUtc") followed by the IANA ID and the offset (etc.) to the datastream. When QTimeZone is deserialized it looks for this marker string, and if present, it passed all of the parameters to the QTimeZone constructor (not just the name). However, that constructor does not support standard IANA timezones (only custom ones), and when it detects that the supplied IANA ID is actually listed in availableTimeZoneIds(), it leaves the pointer to the QTimeZonePrivate uninitialized (NULL), which leaves the QTimeZone invalid (isValid() returns false). Thus, a valid timezone which was serialized and then deserialized has become invalid. This also affects serialization of QDateTimes with timezones. Fixed by calling the name-only constructor first, which works (only) for IANA standard timezones and leaves the QTimeZone invalid (isValid() returns false) otherwise. In which case, we can call the many-argument contructor to create a custom timezone with the same offset as the one which was originally serialized. [ChangeLog][QtCore][QTimeZone] Fixed sending IANA standard UTC-offset QTimeZones through QDataStream, which previously came out invalid after deserialization. Task-number: QTBUG-60595 Change-Id: Id9c47e8bda701faae4d800e012afb6db545b2fe9 Reviewed-by: Oswald Buddenhagen Reviewed-by: Edward Welbourne --- src/corelib/tools/qtimezone.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp index ec2f7c4af6..c4cd76c59c 100644 --- a/src/corelib/tools/qtimezone.cpp +++ b/src/corelib/tools/qtimezone.cpp @@ -961,7 +961,13 @@ QDataStream &operator>>(QDataStream &ds, QTimeZone &tz) int country; QString comment; ds >> ianaId >> utcOffset >> name >> abbreviation >> country >> comment; - tz = QTimeZone(ianaId.toUtf8(), utcOffset, name, abbreviation, (QLocale::Country) country, comment); + // Try creating as a system timezone, which succeeds (producing a valid + // zone) iff ianaId is valid; we can then ignore the other data. + tz = QTimeZone(ianaId.toUtf8()); + // If not, then construct a custom timezone using all the saved values: + if (!tz.isValid()) + tz = QTimeZone(ianaId.toUtf8(), utcOffset, name, abbreviation, + QLocale::Country(country), comment); } else { tz = QTimeZone(ianaId.toUtf8()); } -- cgit v1.2.3 From 71090f09509d52451e68b33e3e26807822849721 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 9 Jun 2017 22:20:58 -0700 Subject: JSON doc: update the RFC we link to MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RFC 4627 is obsoleted by RFC 7159. Change-Id: Ia53158e207a94bf49489fffd14c6ab1ae0a19a72 Reviewed-by: Topi Reiniƶ --- src/corelib/doc/src/json.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/doc/src/json.qdoc b/src/corelib/doc/src/json.qdoc index a32772f910..4c7e62a10a 100644 --- a/src/corelib/doc/src/json.qdoc +++ b/src/corelib/doc/src/json.qdoc @@ -45,7 +45,7 @@ access. More details about the JSON data format can be found at \l{http://json.org}{json.org} - and in \l{http://tools.ietf.org/html/rfc4627}{RFC-4627}. + and in \l{https://tools.ietf.org/html/rfc7159}{RFC-7159}. \tableofcontents -- cgit v1.2.3 From 57d16c12ccb8d50e208078c37d13fa752eab98e1 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 9 Jun 2017 11:42:36 -0700 Subject: qsimd_p.h: Don't set the __xxx__ variables with Clang and GCC Commit 418184c2a0ad97cce12717a43f84fa6f12ece189 set some extra defines that Clang and GCC do set so that MSVC and ICC builds would properly get the features detected. But that meant we set them with Clang and GCC (technically, set them again, but to the same value so no warning was printed). Don't do that. This commit allows me to use "-march=native -mno-rdrnd" to disable the unconditional use of RDRAND instruction. That's required to valgrind any applications, as the current version (3.12) does not have support for that instruction. vex amd64->IR: unhandled instruction bytes: 0x48 0xF 0xC7 0xF0 0x48 0x8B 0x55 0xE8 0x48 0x89 vex amd64->IR: REX=1 REX.W=1 REX.R=0 REX.X=0 REX.B=0 vex amd64->IR: VEX=0 VEX.L=0 VEX.nVVVV=0x0 ESC=0F vex amd64->IR: PFX.66=0 PFX.F2=0 PFX.F3=0 ==78321== valgrind: Unrecognised instruction at address 0x4ef159c. ==78321== at 0x4EF159C: _rdrand64_step (immintrin.h:208) ==78321== by 0x4EF159C: qt_random_cpu(void*, long long) (qrandom.cpp:95) Change-Id: Ia3e896da908f42939148fffd14c6884501de4fa4 Reviewed-by: Allan Sandfeld Jensen --- src/corelib/tools/qsimd_p.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index 28253b3ae9..023a4b08d2 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -232,7 +232,7 @@ #if defined(__SSE4_2__) || (defined(QT_COMPILER_SUPPORTS_SSE4_2) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)) #include -# if defined(__SSE4_2__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) +# if defined(__SSE4_2__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) && (defined(Q_CC_INTEL) || defined(Q_CC_MSVC)) // POPCNT instructions: // All processors that support SSE4.2 support POPCNT // (but neither MSVC nor the Intel compiler define this macro) @@ -245,7 +245,7 @@ // immintrin.h is the ultimate header, we don't need anything else after this #include -# if defined(__AVX__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) +# if defined(__AVX__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) && (defined(Q_CC_INTEL) || defined(Q_CC_MSVC)) // AES, PCLMULQDQ instructions: // All processors that support AVX support AES, PCLMULQDQ // (but neither MSVC nor the Intel compiler define these macros) @@ -253,7 +253,7 @@ # define __PCLMUL__ 1 # endif -# if defined(__AVX2__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) +# if defined(__AVX2__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) && (defined(Q_CC_INTEL) || defined(Q_CC_MSVC)) // F16C & RDRAND instructions: // All processors that support AVX2 support F16C & RDRAND: // (but neither MSVC nor the Intel compiler define these macros) -- cgit v1.2.3 From 26fd805f500acfdcf730f2488a66e18c72d0ff9a Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 30 May 2017 21:45:23 +0200 Subject: macOS/iOS: Correctly ignore punctuation in QCollator When punctuation is ignored then the kUCCollatePunctionSignificantMask should not be set. This was originally thought to not be working due to a bug on the Apple platforms, but this is not the case. [ChangeLog][Platform Specific Changes][macOS][iOS] QCollator now respects the ignorePunctuation property on Apple based platforms correctly. Task-number: QTBUG-41978 Change-Id: I62044076387d6e4479f4aaef3c2f48f49dbd160e Reviewed-by: Lars Knoll --- src/corelib/tools/qcollator.cpp | 2 +- src/corelib/tools/qcollator_macx.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qcollator.cpp b/src/corelib/tools/qcollator.cpp index e34d16079f..f1e3d6652d 100644 --- a/src/corelib/tools/qcollator.cpp +++ b/src/corelib/tools/qcollator.cpp @@ -254,7 +254,7 @@ bool QCollator::numericMode() const The default is locale dependent. - \note This method is not currently supported on Apple platforms or if Qt is configured to not use ICU on Linux. + \note This method is not currently supported if Qt is configured to not use ICU on Linux. \sa ignorePunctuation() */ diff --git a/src/corelib/tools/qcollator_macx.cpp b/src/corelib/tools/qcollator_macx.cpp index d468272430..9aa59a81dc 100644 --- a/src/corelib/tools/qcollator_macx.cpp +++ b/src/corelib/tools/qcollator_macx.cpp @@ -66,7 +66,7 @@ void QCollatorPrivate::init() options |= kUCCollateCaseInsensitiveMask; if (numericMode) options |= kUCCollateDigitsAsNumberMask | kUCCollateDigitsOverrideMask; - if (ignorePunctuation) + if (!ignorePunctuation) options |= kUCCollatePunctuationSignificantMask; OSStatus status = UCCreateCollator( -- cgit v1.2.3 From b4381100280adbfa4cb6c4d8c84eed8f1dc126b9 Mon Sep 17 00:00:00 2001 From: Thomas Sondergaard Date: Sun, 11 Jun 2017 18:09:21 +0200 Subject: Rename QProcessEnvironmentPrivate::hash to vars Also use auto for iterators to vars. This is a small refactoring in preparation for changing type of vars to QMap. Task-number: QTBUG-61315 Change-Id: I5731d7916b6f54a0da5be2da378c09a7688bd870 Reviewed-by: Thiago Macieira --- src/corelib/io/qprocess.cpp | 36 ++++++++++++++++++------------------ src/corelib/io/qprocess_darwin.mm | 2 +- src/corelib/io/qprocess_p.h | 6 +++--- src/corelib/io/qprocess_unix.cpp | 8 ++++---- src/corelib/io/qprocess_win.cpp | 8 ++++---- 5 files changed, 30 insertions(+), 30 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index c0ec35ff32..2226b4435b 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -154,8 +154,8 @@ QT_BEGIN_NAMESPACE QStringList QProcessEnvironmentPrivate::toList() const { QStringList result; - result.reserve(hash.size()); - for (Hash::const_iterator it = hash.cbegin(), end = hash.cend(); it != end; ++it) + result.reserve(vars.size()); + for (auto it = vars.cbegin(), end = vars.cend(); it != end; ++it) result << nameToString(it.key()) + QLatin1Char('=') + valueToString(it.value()); return result; } @@ -181,9 +181,9 @@ QProcessEnvironment QProcessEnvironmentPrivate::fromList(const QStringList &list QStringList QProcessEnvironmentPrivate::keys() const { QStringList result; - result.reserve(hash.size()); - Hash::ConstIterator it = hash.constBegin(), - end = hash.constEnd(); + result.reserve(vars.size()); + auto it = vars.constBegin(); + const auto end = vars.constEnd(); for ( ; it != end; ++it) result << nameToString(it.key()); return result; @@ -191,14 +191,14 @@ QStringList QProcessEnvironmentPrivate::keys() const void QProcessEnvironmentPrivate::insert(const QProcessEnvironmentPrivate &other) { - Hash::ConstIterator it = other.hash.constBegin(), - end = other.hash.constEnd(); + auto it = other.vars.constBegin(); + const auto end = other.vars.constEnd(); for ( ; it != end; ++it) - hash.insert(it.key(), it.value()); + vars.insert(it.key(), it.value()); #ifdef Q_OS_UNIX - QHash::ConstIterator nit = other.nameMap.constBegin(), - nend = other.nameMap.constEnd(); + auto nit = other.nameMap.constBegin(); + const auto nend = other.nameMap.constEnd(); for ( ; nit != nend; ++nit) nameMap.insert(nit.key(), nit.value()); #endif @@ -271,7 +271,7 @@ bool QProcessEnvironment::operator==(const QProcessEnvironment &other) const if (d) { if (other.d) { QProcessEnvironmentPrivate::OrderedMutexLocker locker(d, other.d); - return d->hash == other.d->hash; + return d->vars == other.d->vars; } else { return isEmpty(); } @@ -289,7 +289,7 @@ bool QProcessEnvironment::operator==(const QProcessEnvironment &other) const bool QProcessEnvironment::isEmpty() const { // Needs no locking, as no hash nodes are accessed - return d ? d->hash.isEmpty() : true; + return d ? d->vars.isEmpty() : true; } /*! @@ -301,7 +301,7 @@ bool QProcessEnvironment::isEmpty() const void QProcessEnvironment::clear() { if (d) - d->hash.clear(); + d->vars.clear(); // Unix: Don't clear d->nameMap, as the environment is likely to be // re-populated with the same keys again. } @@ -318,7 +318,7 @@ bool QProcessEnvironment::contains(const QString &name) const if (!d) return false; QProcessEnvironmentPrivate::MutexLocker locker(d); - return d->hash.contains(d->prepareName(name)); + return d->vars.contains(d->prepareName(name)); } /*! @@ -337,7 +337,7 @@ void QProcessEnvironment::insert(const QString &name, const QString &value) { // our re-impl of detach() detaches from null d.detach(); // detach before prepareName() - d->hash.insert(d->prepareName(name), d->prepareValue(value)); + d->vars.insert(d->prepareName(name), d->prepareValue(value)); } /*! @@ -352,7 +352,7 @@ void QProcessEnvironment::remove(const QString &name) { if (d) { d.detach(); // detach before prepareName() - d->hash.remove(d->prepareName(name)); + d->vars.remove(d->prepareName(name)); } } @@ -369,8 +369,8 @@ QString QProcessEnvironment::value(const QString &name, const QString &defaultVa return defaultValue; QProcessEnvironmentPrivate::MutexLocker locker(d); - QProcessEnvironmentPrivate::Hash::ConstIterator it = d->hash.constFind(d->prepareName(name)); - if (it == d->hash.constEnd()) + const auto it = d->vars.constFind(d->prepareName(name)); + if (it == d->vars.constEnd()) return defaultValue; return d->valueToString(it.value()); diff --git a/src/corelib/io/qprocess_darwin.mm b/src/corelib/io/qprocess_darwin.mm index dd7a8275b9..2c3c296cb4 100644 --- a/src/corelib/io/qprocess_darwin.mm +++ b/src/corelib/io/qprocess_darwin.mm @@ -48,7 +48,7 @@ QProcessEnvironment QProcessEnvironment::systemEnvironment() __block QProcessEnvironment env; [[[NSProcessInfo processInfo] environment] enumerateKeysAndObjectsUsingBlock:^(NSString *name, NSString *value, BOOL *__unused stop) { - env.d->hash.insert( + env.d->vars.insert( QProcessEnvironmentPrivate::Key(QString::fromNSString(name).toLocal8Bit()), QProcessEnvironmentPrivate::Value(QString::fromNSString(value).toLocal8Bit())); }]; diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index 6e0630eb66..b8820510b3 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -197,17 +197,17 @@ public: // do not need a lock, as they detach objects (however, we need to // ensure that they really detach before using prepareName()). MutexLocker locker(&other); - hash = other.hash; + vars = other.vars; nameMap = other.nameMap; // We need to detach our members, so that our mutex can protect them. // As we are being detached, they likely would be detached a moment later anyway. - hash.detach(); + vars.detach(); nameMap.detach(); } #endif typedef QHash Hash; - Hash hash; + Hash vars; #ifdef Q_OS_UNIX typedef QHash NameHash; diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index b822417ddf..53803e15d6 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -136,7 +136,7 @@ QProcessEnvironment QProcessEnvironment::systemEnvironment() QByteArray name(entry, equal - entry); QByteArray value(equal + 1); - env.d->hash.insert(QProcessEnvironmentPrivate::Key(name), + env.d->vars.insert(QProcessEnvironmentPrivate::Key(name), QProcessEnvironmentPrivate::Value(value)); } return env; @@ -348,8 +348,8 @@ static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Hash &environm envp[environment.count()] = 0; envp[environment.count() + 1] = 0; - QProcessEnvironmentPrivate::Hash::ConstIterator it = environment.constBegin(); - const QProcessEnvironmentPrivate::Hash::ConstIterator end = environment.constEnd(); + auto it = environment.constBegin(); + const auto end = environment.constEnd(); for ( ; it != end; ++it) { QByteArray key = it.key().key; QByteArray value = it.value().bytes(); @@ -436,7 +436,7 @@ void QProcessPrivate::startProcess() char **envp = 0; if (environment.d.constData()) { QProcessEnvironmentPrivate::MutexLocker locker(environment.d); - envp = _q_dupEnvironment(environment.d.constData()->hash, &envc); + envp = _q_dupEnvironment(environment.d.constData()->vars, &envc); } // Encode the working directory if it's non-empty, otherwise just pass 0. diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 329d1842f0..9adb5138b7 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -75,7 +75,7 @@ QProcessEnvironment QProcessEnvironment::systemEnvironment() int nameLen = equal - entry; QString name = QString::fromWCharArray(entry, nameLen); QString value = QString::fromWCharArray(equal + 1, entryLen - nameLen - 1); - env.d->hash.insert(QProcessEnvironmentPrivate::Key(name), value); + env.d->vars.insert(QProcessEnvironmentPrivate::Key(name), value); } entry += entryLen + 1; } @@ -413,8 +413,8 @@ static QByteArray qt_create_environment(const QProcessEnvironmentPrivate::Hash & } int pos = 0; - QProcessEnvironmentPrivate::Hash::ConstIterator it = copy.constBegin(), - end = copy.constEnd(); + auto it = copy.constBegin(); + const auto end = copy.constEnd(); static const wchar_t equal = L'='; static const wchar_t nul = L'\0'; @@ -475,7 +475,7 @@ void QProcessPrivate::startProcess() QString args = qt_create_commandline(program, arguments); QByteArray envlist; if (environment.d.constData()) - envlist = qt_create_environment(environment.d.constData()->hash); + envlist = qt_create_environment(environment.d.constData()->vars); if (!nativeArguments.isEmpty()) { if (!args.isEmpty()) args += QLatin1Char(' '); -- cgit v1.2.3 From 65a317e6745ee267bef7295f4dfe31d5ec62f7aa Mon Sep 17 00:00:00 2001 From: Thomas Sondergaard Date: Sun, 11 Jun 2017 18:41:57 +0200 Subject: Use QMap in QProcessEnvironment so variables are sorted The motivation for this change is to make it simple to pass a correctly sorted environment block to Win32 CreateProcess(). It is also nice in other contexts that the environment variables are sorted. The change is made for all platforms. This keeps it simple and the only ill effect is slightly slower lookups. Concerning the environment block passed to Win32 CreateProcess: The environment block that is passed to CreateProcess() must be sorted case-insensitively and without regard to locale. See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682009(v=vs.85).aspx The need for sorting the environment block is also mentioned in the CreateProcess() documentation, but with less details: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx Task-number: QTBUG-61315 Change-Id: Ie1edd443301de79cf5f699d45beab01b7c0f9de3 Reviewed-by: Thiago Macieira --- src/corelib/io/qprocess_p.h | 35 ++++++++++++++++------------------- src/corelib/io/qprocess_unix.cpp | 4 ++-- src/corelib/io/qprocess_win.cpp | 4 ++-- 3 files changed, 20 insertions(+), 23 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index b8820510b3..c5abf7b762 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -55,6 +55,7 @@ #include "QtCore/qprocess.h" #include "QtCore/qstringlist.h" #include "QtCore/qhash.h" +#include "QtCore/qmap.h" #include "QtCore/qshareddata.h" #include "private/qiodevice_p.h" @@ -90,22 +91,19 @@ public: QProcEnvKey(const QProcEnvKey &other) : QString(other) {} bool operator==(const QProcEnvKey &other) const { return !compare(other, Qt::CaseInsensitive); } }; -inline uint qHash(const QProcEnvKey &key) { return qHash(key.toCaseFolded()); } -typedef QString QProcEnvValue; -#else -class QProcEnvKey +inline bool operator<(const QProcEnvKey &a, const QProcEnvKey &b) { -public: - QProcEnvKey() : hash(0) {} - explicit QProcEnvKey(const QByteArray &other) : key(other), hash(qHash(key)) {} - QProcEnvKey(const QProcEnvKey &other) { *this = other; } - bool operator==(const QProcEnvKey &other) const { return key == other.key; } + // On windows use case-insensitive ordering because that is how Windows needs the environment + // block sorted (https://msdn.microsoft.com/en-us/library/windows/desktop/ms682009(v=vs.85).aspx) + return a.compare(b, Qt::CaseInsensitive) < 0; +} - QByteArray key; - uint hash; -}; -inline uint qHash(const QProcEnvKey &key) Q_DECL_NOTHROW { return key.hash; } +Q_DECLARE_TYPEINFO(QProcEnvKey, Q_MOVABLE_TYPE); + +typedef QString QProcEnvValue; +#else +using QProcEnvKey = QByteArray; class QProcEnvValue { @@ -138,7 +136,6 @@ public: }; Q_DECLARE_TYPEINFO(QProcEnvValue, Q_MOVABLE_TYPE); #endif -Q_DECLARE_TYPEINFO(QProcEnvKey, Q_MOVABLE_TYPE); class QProcessEnvironmentPrivate: public QSharedData { @@ -161,13 +158,13 @@ public: inline Key prepareName(const QString &name) const { Key &ent = nameMap[name]; - if (ent.key.isEmpty()) - ent = Key(name.toLocal8Bit()); + if (ent.isEmpty()) + ent = name.toLocal8Bit(); return ent; } inline QString nameToString(const Key &name) const { - const QString sname = QString::fromLocal8Bit(name.key); + const QString sname = QString::fromLocal8Bit(name); nameMap[sname] = name; return sname; } @@ -206,8 +203,8 @@ public: } #endif - typedef QHash Hash; - Hash vars; + using Map = QMap; + Map vars; #ifdef Q_OS_UNIX typedef QHash NameHash; diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 53803e15d6..98d196ff7b 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -338,7 +338,7 @@ bool QProcessPrivate::openChannel(Channel &channel) } } -static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Hash &environment, int *envc) +static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Map &environment, int *envc) { *envc = 0; if (environment.isEmpty()) @@ -351,7 +351,7 @@ static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Hash &environm auto it = environment.constBegin(); const auto end = environment.constEnd(); for ( ; it != end; ++it) { - QByteArray key = it.key().key; + QByteArray key = it.key(); QByteArray value = it.value().bytes(); key.reserve(key.length() + 1 + value.length()); key.append('='); diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 9adb5138b7..05c9d6594c 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -390,11 +390,11 @@ static QString qt_create_commandline(const QString &program, const QStringList & return args; } -static QByteArray qt_create_environment(const QProcessEnvironmentPrivate::Hash &environment) +static QByteArray qt_create_environment(const QProcessEnvironmentPrivate::Map &environment) { QByteArray envlist; if (!environment.isEmpty()) { - QProcessEnvironmentPrivate::Hash copy = environment; + QProcessEnvironmentPrivate::Map copy = environment; // add PATH if necessary (for DLL loading) QProcessEnvironmentPrivate::Key pathKey(QLatin1String("PATH")); -- cgit v1.2.3 From 9a73b7ac96453963693d69ebd71691636d90a154 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Thu, 8 Jun 2017 11:30:44 +0300 Subject: QLogging: Fix unused static function warning Detected by clang Change-Id: Ia7d1bf085d838d19319ee1060dcb3c0086a510e4 Reviewed-by: Kai Koehne --- src/corelib/global/qlogging.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 6a91b2cfd0..b5ba935194 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -254,7 +254,7 @@ Q_CORE_EXPORT bool qt_logging_to_console() \sa QMessageLogContext, qDebug(), qInfo(), qWarning(), qCritical(), qFatal() */ -#ifdef Q_OS_WIN +#if defined(Q_CC_MSVC) && defined(QT_DEBUG) && defined(_DEBUG) && defined(_CRT_ERROR) static inline void convert_to_wchar_t_elided(wchar_t *d, size_t space, const char *s) Q_DECL_NOEXCEPT { size_t len = qstrlen(s); -- cgit v1.2.3 From efd9016ea1f11dca78fec7b6c5a4221474436a63 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 5 Jun 2017 14:16:16 -0700 Subject: Add warning about missing but required CPU features Useful to debug why you're getting SIGILL, like running under Valgrind: Processor features: sse3[required] sse2[required] ssse3[required] fma cmpxchg16b sse4.1[required] sse4.2[required] movbe popcnt[required] aes[required] avx[required] f16c[required] bmi[required] avx2[required] bmi2[required] !!!!!!!!!!!!!!!!!!!! !!! Missing required features: rdrand rdseed !!! Applications will likely crash with "Invalid Instruction" !!!!!!!!!!!!!!!!!!!! Change-Id: Ia3e896da908f42939148fffd14c556557419b091 Reviewed-by: Allan Sandfeld Jensen --- src/corelib/tools/qsimd.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index d4edf459de..4c6f08c774 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -721,6 +721,14 @@ void qDumpCPUFeatures() printf("%s%s", features_string + features_indices[i], minFeature & (Q_UINT64_C(1) << i) ? "[required]" : ""); } + if ((features = (qCompilerCpuFeatures & ~features))) { + printf("\n!!!!!!!!!!!!!!!!!!!!\n!!! Missing required features:"); + for (int i = 0; i < features_count; ++i) { + if (features & (Q_UINT64_C(1) << i)) + printf("%s", features_string + features_indices[i]); + } + printf("\n!!! Applications will likely crash with \"Invalid Instruction\"\n!!!!!!!!!!!!!!!!!!!!"); + } puts(""); } -- cgit v1.2.3 From 9d90bbd7b14db17a64e6a664e6f98b58efa97747 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 9 Jun 2017 16:17:34 +0200 Subject: rework detection and use of clock_gettime()/librt recent versions of glibc include clock_gettime() inside libc itself. Task-number: QTBUG-41009 Change-Id: I7401773be99682a356bf06a69571d11c4b15978b Reviewed-by: Thiago Macieira --- src/corelib/configure.json | 18 +++++++++++------- src/corelib/kernel/kernel.pri | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/configure.json b/src/corelib/configure.json index c6c5c93ddb..deb7a544ef 100644 --- a/src/corelib/configure.json +++ b/src/corelib/configure.json @@ -84,6 +84,14 @@ "-ldl" ] }, + "librt": { + "label": "clock_gettime()", + "test": "unix/clock-gettime", + "sources": [ + "", + "-lrt" + ] + }, "pcre2": { "label": "PCRE2", "test": "unix/pcre2", @@ -119,15 +127,11 @@ "type": "compile", "test": "common/atomicfptr" }, - "clock-gettime": { - "label": "clock_gettime()", - "type": "compile", - "test": "unix/clock-gettime" - }, "clock-monotonic": { "label": "POSIX monotonic clock", "type": "compile", - "test": "unix/clock-monotonic" + "test": "unix/clock-monotonic", + "use": "librt" }, "cloexec": { "label": "O_CLOEXEC", @@ -199,7 +203,7 @@ "features": { "clock-gettime": { "label": "clock_gettime()", - "condition": "tests.clock-gettime", + "condition": "config.unix && libs.librt", "output": [ "privateFeature" ] }, "clock-monotonic": { diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index 0e6ff17b8f..29bd5bbc6c 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -162,7 +162,7 @@ unix|integrity { QMAKE_USE_PRIVATE += glib } - qtConfig(clock-gettime): include($$QT_SOURCE_TREE/config.tests/unix/clock-gettime/clock-gettime.pri) + qtConfig(clock-gettime): QMAKE_USE_PRIVATE += librt !android { SOURCES += kernel/qsharedmemory_posix.cpp \ -- cgit v1.2.3 From 8b080e59c5019112f5699db5c2c101f76b3da88f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 11 May 2017 15:39:15 +0200 Subject: rename qglobalstatic.cpp -> qglobalstatic.qdoc it contains no code. Change-Id: Ie8a43abb2db3d040f7046206adf2bf555960dd9c Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira --- src/corelib/global/global.pri | 1 - src/corelib/global/qglobalstatic.cpp | 522 ---------------------------------- src/corelib/global/qglobalstatic.qdoc | 520 +++++++++++++++++++++++++++++++++ 3 files changed, 520 insertions(+), 523 deletions(-) delete mode 100644 src/corelib/global/qglobalstatic.cpp create mode 100644 src/corelib/global/qglobalstatic.qdoc (limited to 'src/corelib') diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index f162dd95dd..b76d1ef43c 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -27,7 +27,6 @@ HEADERS += \ SOURCES += \ global/archdetect.cpp \ global/qglobal.cpp \ - global/qglobalstatic.cpp \ global/qlibraryinfo.cpp \ global/qmalloc.cpp \ global/qnumeric.cpp \ diff --git a/src/corelib/global/qglobalstatic.cpp b/src/corelib/global/qglobalstatic.cpp deleted file mode 100644 index d1c522a79a..0000000000 --- a/src/corelib/global/qglobalstatic.cpp +++ /dev/null @@ -1,522 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglobalstatic.h" - -/*! - \macro Q_GLOBAL_STATIC(Type, VariableName) - \since 5.1 - \relates QGlobalStatic - - Creates a global and static object of type \l QGlobalStatic, of name \a - VariableName and that behaves as a pointer to \a Type. The object created - by Q_GLOBAL_STATIC initializes itself on the first use, which means that it - will not increase the application or the library's load time. Additionally, - the object is initialized in a thread-safe manner on all platforms. - - The typical use of this macro is as follows, in a global context (that is, - outside of any function bodies): - - \code - Q_GLOBAL_STATIC(MyType, staticType) - \endcode - - This macro is intended to replace global static objects that are not POD - (Plain Old Data, or in C++11 terms, not made of a trivial type), hence the - name. For example, the following C++ code creates a global static: - - \code - static MyType staticType; - \endcode - - Compared to Q_GLOBAL_STATIC, and assuming that \c MyType is a class or - struct that has a constructor, a destructor, or is otherwise non-POD, the - above has the following drawbacks: - - \list - \li it requires load-time initialization of \c MyType (that is, the - default constructor for \c MyType is called when the library or - application is loaded); - - \li the type will be initialized even if it is never used; - - \li the order of initialization and destruction among different - translation units is not determined, leading to possible uses before - initialization or after destruction; - - \li if it is found inside a function (that is, not global), it will be - initialized on first use, but many current compilers (as of 2013) do - not guarantee that the initialization will be thread-safe; - \endlist - - The Q_GLOBAL_STATIC macro solves all of the above problems by guaranteeing - thread-safe initialization on first use and allowing the user to query for - whether the type has already been destroyed, to avoid the - use-after-destruction problem (see QGlobalStatic::isDestroyed()). - - \section1 Constructor and Destructor - - For Q_GLOBAL_STATIC, the type \c Type must be publicly - default-constructible and publicly destructible. For - Q_GLOBAL_STATIC_WITH_ARGS(), there must be a public constructor that - matches the arguments passed. - - It is not possible to use Q_GLOBAL_STATIC with types that have protected or - private default constructors or destructors (for Q_GLOBAL_STATIC_WITH_ARGS(), - a protected or private constructor matching the arguments). If the type in - question has those members as protected, it is possible to overcome the - issue by deriving from the type and creating public a constructor and - destructor. If the type has them as private, a friend declaration is - necessary before deriving. - - For example, the following is enough to create \c MyType based on a - previously-defined \c MyOtherType which has a protected default constructor - and/or a protected destructor (or has them as private, but that defines \c - MyType as a friend). - - \code - class MyType : public MyOtherType { }; - Q_GLOBAL_STATIC(MyType, staticType) - \endcode - - No body for \c MyType is required since the destructor is an implicit - member and so is the default constructor if no other constructors are - defined. For use with Q_GLOBAL_STATIC_WITH_ARGS(), however, a suitable - constructor body is necessary: - - \code - class MyType : public MyOtherType - { - public: - MyType(int i) : MyOtherType(i) {} - }; - Q_GLOBAL_STATIC_WITH_ARGS(MyType, staticType, (42)) - \endcode - - Alternatively, if the compiler supports C++11 inheriting constructors, one could write: - - \code - class MyType : public MyOtherType - { - public: - using MyOtherType::MyOtherType; - }; - Q_GLOBAL_STATIC_WITH_ARGS(MyType, staticType, (42)) - \endcode - - \section1 Placement - - The Q_GLOBAL_STATIC macro creates a type that is necessarily static, at the - global scope. It is not possible to place the Q_GLOBAL_STATIC macro inside - a function (doing so will result in compilation errors). - - More importantly, this macro should be placed in source files, never in - headers. Since the resulting object is has static linkage, if the macro is - placed in a header and included by multiple source files, the object will - be defined multiple times and will not cause linking errors. Instead, each - translation unit will refer to a different object, which could lead to - subtle and hard-to-track errors. - - \section1 Non-recommended uses - - Note that the macro is not recommended for use with types that are POD or - that have C++11 constexpr constructors (trivially constructible and - destructible). For those types, it is still recommended to use regular - static, whether global or function-local. - - This macro will work, but it will add unnecessary overhead. - - \section1 Reentrancy, Thread-safety, Deadlocks, and Exception-safety on Construction - - The Q_GLOBAL_STATIC macro creates an object that initializes itself on - first use in a thread-safe manner: if multiple threads attempt to - initialize the object at the same time, only one thread will proceed to - initialize, while all other threads wait for completion. - - If the initialization process throws an exception, the initialization is - deemed not complete and will be attempted again when control reaches any - use of the object. If there are any threads waiting for initialization, one - of them will be woken up to attempt to initialize. - - The macro makes no guarantee about reentrancy from the same thread. If the - global static object is accessed directly or indirectly from inside the - constructor, a deadlock will surely happen. - - In addition, if two Q_GLOBAL_STATIC objects are being initialized on two - different threads and each one's initialization sequence accesses the - other, a deadlock might happen. For that reason, it is recommended to keep - global static constructors simple or, failing that, to ensure that there's - no cross-dependency of uses of global static during construction. - - \section1 Destruction - - If the object is never used during the lifetime of the program, aside from - the QGlobalStatic::exists() and QGlobalStatic::isDestroyed() functions, the - contents of type \a Type will not be created and there will not be any - exit-time operation. - - If the object is created, it will be destroyed at exit-time, similar to the - C \c atexit function. On most systems, in fact, the destructor will also be - called if the library or plugin is unloaded from memory before exit. - - Since the destruction is meant to happen at program exit, no thread-safety - is provided. This includes the case of plugin or library unload. In - addition, since destructors are not supposed to throw exceptions, no - exception safety is provided either. - - However, reentrancy is permitted: during destruction, it is possible to - access the global static object and the pointer returned will be the same - as it was before destruction began. After the destruction has completed, - accessing the global static object is not permitted, except as noted in the - \l QGlobalStatic API. - - \omit - \section1 Compatibility with Qt 4 and Qt 5.0 - - This macro, in its current form and behavior, was introduced in Qt 5.1. - Prior to that version, Qt had another macro with the same name that was - private API. This section is not meant to document how to use - Q_GLOBAL_STATIC in those versions, but instead to serve as a porting guide - for Qt code that used those macros. - - The Qt 4 Q_GLOBAL_STATIC macro differed in behavior in the following ways: - - \list - \li the object created was not of type \l QGlobalStatic, but instead - it was a function that returned a pointer to \a Type; that means the - \l QGlobalStatic API was not present; - - \li the initialization was thread-safe, but not guaranteed to be - unique: instead, if N threads tried to initialize the object at the - same time, N objects would be created on the heap and N-1 would be - destroyed; - - \li the object was always created on the heap. - \endlist - - \section1 Implementation Details - - Q_GLOBAL_STATIC is implemented by creating a QBasicAtomicInt called the \c - guard and a free, inline function called \c innerFunction. The guard - variable is initialized to value 0 (chosen so that the guard can be placed - in the .bss section of the binary file), which denotes that construction - has not yet taken place (uninitialized). The inner function is implemented - by the helper macro Q_GLOBAL_STATIC_INTERNAL. - - Both the guard variable and the inner function are passed as template - parameters to QGlobalStatic, along with the type \a Type. Both should also - have static linkage or be placed inside an anonymous namespace, so that the - visibility of Q_GLOBAL_STATIC is that of a global static. To permit - multiple Q_GLOBAL_STATIC per translation unit, the guard variable and the - inner function must have unique names, which can be accomplished by - concatenating with \a VariableName or by placing them in a namespace that - has \a VariableName as part of the name. To simplify and improve - readability on Q_GLOBAL_STATIC_INTERNAL, we chose the namespace solution. - It's also required for C++98 builds, since static symbols cannot be used as - template parameters. - - The guard variable can assume the following values: - - \list - \li -2: object was once initialized but has been destroyed already; - \li -1: object was initialized and is still valid; - \li 0: object was not initialized yet; - \li +1: object is being initialized and any threads encountering this - value must wait for completion (not used in the current implementation). - \endlist - - Collectively, all positive values indicate that the initialization is - progressing and must be waited on, whereas all negative values indicate - that the initialization has terminated and must not be attempted again. - Positive values are not used in the current implementation, but were in - earlier versions. They could be used again in the future. - - The QGlobalStatic::exists() and QGlobalStatic::isDestroyed() functions - operate solely on the guard variable: the former returns \c true if the guard - is negative, whereas the latter returns \c true only if it is -2. - - The Q_GLOBAL_STATIC_INTERNAL macro implements the actual construction and - destruction. There are two implementations of it: one for compilers that - support thread-safe initialization of function-local statics and one for - compilers that don't. Thread-safe initialization is required by C++11 in - [stmt.decl], but as of the time of this writing, only compilers based on - the IA-64 C++ ABI implemented it properly. The implementation requiring - thread-safe initialization is also used on the Qt bootstrapped tools, which - define QT_NO_THREAD. - - The implementation requiring thread-safe initialization from the compiler - is the simplest: it creates the \a Type object as a function-local static - and returns its address. The actual object is actually inside a holder - structure so holder's destructor can set the guard variable to the value -2 - (destroyed) when the type has finished destruction. Since we need to set - the guard \b after the destruction has finished, this code needs to be in a - base struct's destructor. And it only sets to -2 (destroyed) if it finds - the guard at -1 (initialized): this is done to ensure that the guard isn't - set to -2 in the event the type's constructor threw an exception. A holder - structure is used to avoid creating two statics, which the ABI might - require duplicating the thread-safe control structures for. - - The other implementation is similar to Qt 4's Q_GLOBAL_STATIC, but unlike - that one, it uses a \l QBasicMutex to provide locking. It is also more - efficient memory-wise. It use a simple double-checked locking of the mutex - and then creates the contents on the heap. After that, it creates a - function-local structure called "Cleanup", whose destructor will be run at - program exit and will actually destroy the contents. - - \endomit - - \sa Q_GLOBAL_STATIC_WITH_ARGS(), QGlobalStatic -*/ - -/*! - \macro Q_GLOBAL_STATIC_WITH_ARGS(Type, VariableName, Arguments) - \since 5.1 - \relates QGlobalStatic - - Creates a global and static object of type \l QGlobalStatic, of name \a - VariableName, initialized by the arguments \a Arguments and that behaves as - a pointer to \a Type. The object created by Q_GLOBAL_STATIC_WITH_ARGS - initializes itself on the first use, which means that it will not increase - the application or the library's load time. Additionally, the object is - initialized in a thread-safe manner on all platforms. - - The typical use of this macro is as follows, in a global context (that is, - outside of any function bodies): - - \code - Q_GLOBAL_STATIC_WITH_ARGS(MyType, staticType, (42, "Hello", "World")) - \endcode - - The \a Arguments macro parameter must always include the parentheses or, if - C++11 uniform initialization is allowed, the braces. - - Aside from the actual initialization of the contents with the supplied - arguments, this macro behaves identically to Q_GLOBAL_STATIC(). Please - see that macro's documentation for more information. - - \sa Q_GLOBAL_STATIC(), QGlobalStatic -*/ - -/*! - \class QGlobalStatic - \threadsafe - \inmodule QtCore - \since 5.1 - \brief The QGlobalStatic class is used to implement a global static object - - The QGlobalStatic class is the front-end API exported when - Q_GLOBAL_STATIC() is used. See the documentation for the macro for a - discussion on when to use it and its requirements. - - Normally, you will never use this class directly, but instead you will use - the Q_GLOBAL_STATIC() or Q_GLOBAL_STATIC_WITH_ARGS() macros, as - follows: - - \code - Q_GLOBAL_STATIC(MyType, staticType) - \endcode - - The above example creates an object of type QGlobalStatic called \c - staticType. After the above declaration, the \c staticType object may be - used as if it were a pointer, guaranteed to be initialized exactly once. In - addition to the use as a pointer, the object offers two methods to - determine the current status of the global: exists() and isDestroyed(). - - \sa Q_GLOBAL_STATIC(), Q_GLOBAL_STATIC_WITH_ARGS() -*/ - -/*! - \typedef QGlobalStatic::Type - - This type is equivalent to the \c Type parameter passed to the - Q_GLOBAL_STATIC() or Q_GLOBAL_STATIC_WITH_ARGS() macros. It is used in the - return types of some functions. -*/ - -/*! - \fn bool QGlobalStatic::isDestroyed() const - - This function returns \c true if the global static object has already - completed destruction (that is, if the destructor for the type has already - returned). In specific, note that this function returns \c false if - the destruction is still in progress. - - Once this function has returned true once, it will never return - false again until either the program is restarted or the plugin or library - containing the global static is unloaded and reloaded. - - This function is safe to call at any point in the program execution: it - cannot fail and cannot cause a deadlock. Additionally, it will not cause - the contents to be created if they have not yet been created. - - This function is useful in code that may be executed at program shutdown, - to determine whether the contents may still be accessed or not. - - \omit - Due to the non-atomic nature of destruction, it's possible that - QGlobalStatic::isDestroyed might return false for a short time after the - destructor has finished. However, since the destructor is only run in an - environment where concurrent multithreaded access is impossible, no one can - see that state. (omitted because it's useless information) - \endomit - - \sa exists() -*/ - -/*! - \fn bool QGlobalStatic::exists() const - - This function returns \c true if the global static object has already - completed initialization (that is, if the constructor for the type has - already returned). In specific, note that this function returns \c false if - the initialization is still in progress. - - Once this function has returned true once, it will never return false again - until either the program is restarted or the plugin or library containing - the global static is unloaded and reloaded. - - This function is safe to call at any point in the program execution: it - cannot fail and cannot cause a deadlock. Additionally, it will not cause - the contents to be created if they have not yet been created. - - This function is useful if one can determine the initial conditions of the - global static object and would prefer to avoid a possibly expensive - construction operation. - - For example, in the following code sample, this function is used to - short-circuit the creation of the global static called \c globalState and - returns a default value: - - \code - Q_GLOBAL_STATIC(MyType, globalState) - QString someState() - { - if (globalState.exists()) - return globalState->someState; - return QString(); - } - \endcode - - \b{Thread-safety notice:} this function is thread-safe in the sense that it - may be called from any thread at any time and will always return a valid - reply. But due to the non-atomic nature of construction, this function may - return false for a short time after the construction has completed. - - \b{Memory ordering notice:} this function does not impose any memory - ordering guarantees. That is instead provided by the accessor functions - that return the pointer or reference to the contents. If you bypass the - accessor functions and attempt to access some global state set by the - constructor, be sure to use the correct memory ordering semantics provided - by \l QAtomicInt or \l QAtomicPointer. - - \sa isDestroyed() -*/ - -/*! - \fn QGlobalStatic::operator Type*() - - This function returns the address of the contents of this global static. If - the contents have not yet been created, they will be created thread-safely - by this function. If the contents have already been destroyed, this - function will return a null pointer. - - This function can be used, for example, to store the pointer to the - contents of the global static in a local variable, thus avoiding multiple - calls to the function. The implementation of Q_GLOBAL_STATIC() is quite - efficient already, but in performance-critical sections it might be useful - to help the compiler a little. For example: - - \code - Q_GLOBAL_STATIC(MyType, globalState) - QString someState() - { - MyType *state = globalState; - if (!state) { - // we're in a post-destruction state - return QString(); - } - if (state->condition) - return state->value1; - else - return state->value2; - } - \endcode - - \sa operator->(), operator*() -*/ - -/*! - \fn Type *QGlobalStatic::operator()() - \deprecated - - This function returns the address of the contents of this global static. If - the contents have not yet been created, they will be created thread-safely - by this function. If the contents have already been destroyed, this - function will return a null pointer. - - This function is equivalent to \l {operator Type *()}. It is provided for - compatibility with the private Q_GLOBAL_STATIC implementation that existed - in Qt 4.x and 5.0. New code should avoid using it and should instead treat - the object as a smart pointer. -*/ - -/*! - \fn Type *QGlobalStatic::operator->() - - This function returns the address of the contents of this global static. If - the contents have not yet been created, they will be created thread-safely - by this function. - - This function does not check if the contents have already been destroyed and - will never return null. If this function is called after the object has - been destroyed, it will return a dangling pointer that should not be - dereferenced. -*/ - -/*! - \fn Type &QGlobalStatic::operator*() - - This function returns a reference to the contents of this global static. If - the contents have not yet been created, they will be created thread-safely - by this function. - - This function does not check if the contents have already been destroyed. - If this function is called after the object has been destroyed, it will - return an invalid reference that must not be used. -*/ diff --git a/src/corelib/global/qglobalstatic.qdoc b/src/corelib/global/qglobalstatic.qdoc new file mode 100644 index 0000000000..8c34739d38 --- /dev/null +++ b/src/corelib/global/qglobalstatic.qdoc @@ -0,0 +1,520 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Intel Corporation. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \macro Q_GLOBAL_STATIC(Type, VariableName) + \since 5.1 + \relates QGlobalStatic + + Creates a global and static object of type \l QGlobalStatic, of name \a + VariableName and that behaves as a pointer to \a Type. The object created + by Q_GLOBAL_STATIC initializes itself on the first use, which means that it + will not increase the application or the library's load time. Additionally, + the object is initialized in a thread-safe manner on all platforms. + + The typical use of this macro is as follows, in a global context (that is, + outside of any function bodies): + + \code + Q_GLOBAL_STATIC(MyType, staticType) + \endcode + + This macro is intended to replace global static objects that are not POD + (Plain Old Data, or in C++11 terms, not made of a trivial type), hence the + name. For example, the following C++ code creates a global static: + + \code + static MyType staticType; + \endcode + + Compared to Q_GLOBAL_STATIC, and assuming that \c MyType is a class or + struct that has a constructor, a destructor, or is otherwise non-POD, the + above has the following drawbacks: + + \list + \li it requires load-time initialization of \c MyType (that is, the + default constructor for \c MyType is called when the library or + application is loaded); + + \li the type will be initialized even if it is never used; + + \li the order of initialization and destruction among different + translation units is not determined, leading to possible uses before + initialization or after destruction; + + \li if it is found inside a function (that is, not global), it will be + initialized on first use, but many current compilers (as of 2013) do + not guarantee that the initialization will be thread-safe; + \endlist + + The Q_GLOBAL_STATIC macro solves all of the above problems by guaranteeing + thread-safe initialization on first use and allowing the user to query for + whether the type has already been destroyed, to avoid the + use-after-destruction problem (see QGlobalStatic::isDestroyed()). + + \section1 Constructor and Destructor + + For Q_GLOBAL_STATIC, the type \c Type must be publicly + default-constructible and publicly destructible. For + Q_GLOBAL_STATIC_WITH_ARGS(), there must be a public constructor that + matches the arguments passed. + + It is not possible to use Q_GLOBAL_STATIC with types that have protected or + private default constructors or destructors (for Q_GLOBAL_STATIC_WITH_ARGS(), + a protected or private constructor matching the arguments). If the type in + question has those members as protected, it is possible to overcome the + issue by deriving from the type and creating public a constructor and + destructor. If the type has them as private, a friend declaration is + necessary before deriving. + + For example, the following is enough to create \c MyType based on a + previously-defined \c MyOtherType which has a protected default constructor + and/or a protected destructor (or has them as private, but that defines \c + MyType as a friend). + + \code + class MyType : public MyOtherType { }; + Q_GLOBAL_STATIC(MyType, staticType) + \endcode + + No body for \c MyType is required since the destructor is an implicit + member and so is the default constructor if no other constructors are + defined. For use with Q_GLOBAL_STATIC_WITH_ARGS(), however, a suitable + constructor body is necessary: + + \code + class MyType : public MyOtherType + { + public: + MyType(int i) : MyOtherType(i) {} + }; + Q_GLOBAL_STATIC_WITH_ARGS(MyType, staticType, (42)) + \endcode + + Alternatively, if the compiler supports C++11 inheriting constructors, one could write: + + \code + class MyType : public MyOtherType + { + public: + using MyOtherType::MyOtherType; + }; + Q_GLOBAL_STATIC_WITH_ARGS(MyType, staticType, (42)) + \endcode + + \section1 Placement + + The Q_GLOBAL_STATIC macro creates a type that is necessarily static, at the + global scope. It is not possible to place the Q_GLOBAL_STATIC macro inside + a function (doing so will result in compilation errors). + + More importantly, this macro should be placed in source files, never in + headers. Since the resulting object is has static linkage, if the macro is + placed in a header and included by multiple source files, the object will + be defined multiple times and will not cause linking errors. Instead, each + translation unit will refer to a different object, which could lead to + subtle and hard-to-track errors. + + \section1 Non-recommended uses + + Note that the macro is not recommended for use with types that are POD or + that have C++11 constexpr constructors (trivially constructible and + destructible). For those types, it is still recommended to use regular + static, whether global or function-local. + + This macro will work, but it will add unnecessary overhead. + + \section1 Reentrancy, Thread-safety, Deadlocks, and Exception-safety on Construction + + The Q_GLOBAL_STATIC macro creates an object that initializes itself on + first use in a thread-safe manner: if multiple threads attempt to + initialize the object at the same time, only one thread will proceed to + initialize, while all other threads wait for completion. + + If the initialization process throws an exception, the initialization is + deemed not complete and will be attempted again when control reaches any + use of the object. If there are any threads waiting for initialization, one + of them will be woken up to attempt to initialize. + + The macro makes no guarantee about reentrancy from the same thread. If the + global static object is accessed directly or indirectly from inside the + constructor, a deadlock will surely happen. + + In addition, if two Q_GLOBAL_STATIC objects are being initialized on two + different threads and each one's initialization sequence accesses the + other, a deadlock might happen. For that reason, it is recommended to keep + global static constructors simple or, failing that, to ensure that there's + no cross-dependency of uses of global static during construction. + + \section1 Destruction + + If the object is never used during the lifetime of the program, aside from + the QGlobalStatic::exists() and QGlobalStatic::isDestroyed() functions, the + contents of type \a Type will not be created and there will not be any + exit-time operation. + + If the object is created, it will be destroyed at exit-time, similar to the + C \c atexit function. On most systems, in fact, the destructor will also be + called if the library or plugin is unloaded from memory before exit. + + Since the destruction is meant to happen at program exit, no thread-safety + is provided. This includes the case of plugin or library unload. In + addition, since destructors are not supposed to throw exceptions, no + exception safety is provided either. + + However, reentrancy is permitted: during destruction, it is possible to + access the global static object and the pointer returned will be the same + as it was before destruction began. After the destruction has completed, + accessing the global static object is not permitted, except as noted in the + \l QGlobalStatic API. + + \omit + \section1 Compatibility with Qt 4 and Qt 5.0 + + This macro, in its current form and behavior, was introduced in Qt 5.1. + Prior to that version, Qt had another macro with the same name that was + private API. This section is not meant to document how to use + Q_GLOBAL_STATIC in those versions, but instead to serve as a porting guide + for Qt code that used those macros. + + The Qt 4 Q_GLOBAL_STATIC macro differed in behavior in the following ways: + + \list + \li the object created was not of type \l QGlobalStatic, but instead + it was a function that returned a pointer to \a Type; that means the + \l QGlobalStatic API was not present; + + \li the initialization was thread-safe, but not guaranteed to be + unique: instead, if N threads tried to initialize the object at the + same time, N objects would be created on the heap and N-1 would be + destroyed; + + \li the object was always created on the heap. + \endlist + + \section1 Implementation Details + + Q_GLOBAL_STATIC is implemented by creating a QBasicAtomicInt called the \c + guard and a free, inline function called \c innerFunction. The guard + variable is initialized to value 0 (chosen so that the guard can be placed + in the .bss section of the binary file), which denotes that construction + has not yet taken place (uninitialized). The inner function is implemented + by the helper macro Q_GLOBAL_STATIC_INTERNAL. + + Both the guard variable and the inner function are passed as template + parameters to QGlobalStatic, along with the type \a Type. Both should also + have static linkage or be placed inside an anonymous namespace, so that the + visibility of Q_GLOBAL_STATIC is that of a global static. To permit + multiple Q_GLOBAL_STATIC per translation unit, the guard variable and the + inner function must have unique names, which can be accomplished by + concatenating with \a VariableName or by placing them in a namespace that + has \a VariableName as part of the name. To simplify and improve + readability on Q_GLOBAL_STATIC_INTERNAL, we chose the namespace solution. + It's also required for C++98 builds, since static symbols cannot be used as + template parameters. + + The guard variable can assume the following values: + + \list + \li -2: object was once initialized but has been destroyed already; + \li -1: object was initialized and is still valid; + \li 0: object was not initialized yet; + \li +1: object is being initialized and any threads encountering this + value must wait for completion (not used in the current implementation). + \endlist + + Collectively, all positive values indicate that the initialization is + progressing and must be waited on, whereas all negative values indicate + that the initialization has terminated and must not be attempted again. + Positive values are not used in the current implementation, but were in + earlier versions. They could be used again in the future. + + The QGlobalStatic::exists() and QGlobalStatic::isDestroyed() functions + operate solely on the guard variable: the former returns \c true if the guard + is negative, whereas the latter returns \c true only if it is -2. + + The Q_GLOBAL_STATIC_INTERNAL macro implements the actual construction and + destruction. There are two implementations of it: one for compilers that + support thread-safe initialization of function-local statics and one for + compilers that don't. Thread-safe initialization is required by C++11 in + [stmt.decl], but as of the time of this writing, only compilers based on + the IA-64 C++ ABI implemented it properly. The implementation requiring + thread-safe initialization is also used on the Qt bootstrapped tools, which + define QT_NO_THREAD. + + The implementation requiring thread-safe initialization from the compiler + is the simplest: it creates the \a Type object as a function-local static + and returns its address. The actual object is actually inside a holder + structure so holder's destructor can set the guard variable to the value -2 + (destroyed) when the type has finished destruction. Since we need to set + the guard \b after the destruction has finished, this code needs to be in a + base struct's destructor. And it only sets to -2 (destroyed) if it finds + the guard at -1 (initialized): this is done to ensure that the guard isn't + set to -2 in the event the type's constructor threw an exception. A holder + structure is used to avoid creating two statics, which the ABI might + require duplicating the thread-safe control structures for. + + The other implementation is similar to Qt 4's Q_GLOBAL_STATIC, but unlike + that one, it uses a \l QBasicMutex to provide locking. It is also more + efficient memory-wise. It use a simple double-checked locking of the mutex + and then creates the contents on the heap. After that, it creates a + function-local structure called "Cleanup", whose destructor will be run at + program exit and will actually destroy the contents. + + \endomit + + \sa Q_GLOBAL_STATIC_WITH_ARGS(), QGlobalStatic +*/ + +/*! + \macro Q_GLOBAL_STATIC_WITH_ARGS(Type, VariableName, Arguments) + \since 5.1 + \relates QGlobalStatic + + Creates a global and static object of type \l QGlobalStatic, of name \a + VariableName, initialized by the arguments \a Arguments and that behaves as + a pointer to \a Type. The object created by Q_GLOBAL_STATIC_WITH_ARGS + initializes itself on the first use, which means that it will not increase + the application or the library's load time. Additionally, the object is + initialized in a thread-safe manner on all platforms. + + The typical use of this macro is as follows, in a global context (that is, + outside of any function bodies): + + \code + Q_GLOBAL_STATIC_WITH_ARGS(MyType, staticType, (42, "Hello", "World")) + \endcode + + The \a Arguments macro parameter must always include the parentheses or, if + C++11 uniform initialization is allowed, the braces. + + Aside from the actual initialization of the contents with the supplied + arguments, this macro behaves identically to Q_GLOBAL_STATIC(). Please + see that macro's documentation for more information. + + \sa Q_GLOBAL_STATIC(), QGlobalStatic +*/ + +/*! + \class QGlobalStatic + \threadsafe + \inmodule QtCore + \since 5.1 + \brief The QGlobalStatic class is used to implement a global static object + + The QGlobalStatic class is the front-end API exported when + Q_GLOBAL_STATIC() is used. See the documentation for the macro for a + discussion on when to use it and its requirements. + + Normally, you will never use this class directly, but instead you will use + the Q_GLOBAL_STATIC() or Q_GLOBAL_STATIC_WITH_ARGS() macros, as + follows: + + \code + Q_GLOBAL_STATIC(MyType, staticType) + \endcode + + The above example creates an object of type QGlobalStatic called \c + staticType. After the above declaration, the \c staticType object may be + used as if it were a pointer, guaranteed to be initialized exactly once. In + addition to the use as a pointer, the object offers two methods to + determine the current status of the global: exists() and isDestroyed(). + + \sa Q_GLOBAL_STATIC(), Q_GLOBAL_STATIC_WITH_ARGS() +*/ + +/*! + \typedef QGlobalStatic::Type + + This type is equivalent to the \c Type parameter passed to the + Q_GLOBAL_STATIC() or Q_GLOBAL_STATIC_WITH_ARGS() macros. It is used in the + return types of some functions. +*/ + +/*! + \fn bool QGlobalStatic::isDestroyed() const + + This function returns \c true if the global static object has already + completed destruction (that is, if the destructor for the type has already + returned). In specific, note that this function returns \c false if + the destruction is still in progress. + + Once this function has returned true once, it will never return + false again until either the program is restarted or the plugin or library + containing the global static is unloaded and reloaded. + + This function is safe to call at any point in the program execution: it + cannot fail and cannot cause a deadlock. Additionally, it will not cause + the contents to be created if they have not yet been created. + + This function is useful in code that may be executed at program shutdown, + to determine whether the contents may still be accessed or not. + + \omit + Due to the non-atomic nature of destruction, it's possible that + QGlobalStatic::isDestroyed might return false for a short time after the + destructor has finished. However, since the destructor is only run in an + environment where concurrent multithreaded access is impossible, no one can + see that state. (omitted because it's useless information) + \endomit + + \sa exists() +*/ + +/*! + \fn bool QGlobalStatic::exists() const + + This function returns \c true if the global static object has already + completed initialization (that is, if the constructor for the type has + already returned). In specific, note that this function returns \c false if + the initialization is still in progress. + + Once this function has returned true once, it will never return false again + until either the program is restarted or the plugin or library containing + the global static is unloaded and reloaded. + + This function is safe to call at any point in the program execution: it + cannot fail and cannot cause a deadlock. Additionally, it will not cause + the contents to be created if they have not yet been created. + + This function is useful if one can determine the initial conditions of the + global static object and would prefer to avoid a possibly expensive + construction operation. + + For example, in the following code sample, this function is used to + short-circuit the creation of the global static called \c globalState and + returns a default value: + + \code + Q_GLOBAL_STATIC(MyType, globalState) + QString someState() + { + if (globalState.exists()) + return globalState->someState; + return QString(); + } + \endcode + + \b{Thread-safety notice:} this function is thread-safe in the sense that it + may be called from any thread at any time and will always return a valid + reply. But due to the non-atomic nature of construction, this function may + return false for a short time after the construction has completed. + + \b{Memory ordering notice:} this function does not impose any memory + ordering guarantees. That is instead provided by the accessor functions + that return the pointer or reference to the contents. If you bypass the + accessor functions and attempt to access some global state set by the + constructor, be sure to use the correct memory ordering semantics provided + by \l QAtomicInt or \l QAtomicPointer. + + \sa isDestroyed() +*/ + +/*! + \fn QGlobalStatic::operator Type*() + + This function returns the address of the contents of this global static. If + the contents have not yet been created, they will be created thread-safely + by this function. If the contents have already been destroyed, this + function will return a null pointer. + + This function can be used, for example, to store the pointer to the + contents of the global static in a local variable, thus avoiding multiple + calls to the function. The implementation of Q_GLOBAL_STATIC() is quite + efficient already, but in performance-critical sections it might be useful + to help the compiler a little. For example: + + \code + Q_GLOBAL_STATIC(MyType, globalState) + QString someState() + { + MyType *state = globalState; + if (!state) { + // we're in a post-destruction state + return QString(); + } + if (state->condition) + return state->value1; + else + return state->value2; + } + \endcode + + \sa operator->(), operator*() +*/ + +/*! + \fn Type *QGlobalStatic::operator()() + \deprecated + + This function returns the address of the contents of this global static. If + the contents have not yet been created, they will be created thread-safely + by this function. If the contents have already been destroyed, this + function will return a null pointer. + + This function is equivalent to \l {operator Type *()}. It is provided for + compatibility with the private Q_GLOBAL_STATIC implementation that existed + in Qt 4.x and 5.0. New code should avoid using it and should instead treat + the object as a smart pointer. +*/ + +/*! + \fn Type *QGlobalStatic::operator->() + + This function returns the address of the contents of this global static. If + the contents have not yet been created, they will be created thread-safely + by this function. + + This function does not check if the contents have already been destroyed and + will never return null. If this function is called after the object has + been destroyed, it will return a dangling pointer that should not be + dereferenced. +*/ + +/*! + \fn Type &QGlobalStatic::operator*() + + This function returns a reference to the contents of this global static. If + the contents have not yet been created, they will be created thread-safely + by this function. + + This function does not check if the contents have already been destroyed. + If this function is called after the object has been destroyed, it will + return an invalid reference that must not be used. +*/ -- cgit v1.2.3 From f5f98da54e1140cfc340e5077735c63d209edd7d Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 15 Jun 2017 17:40:25 +0200 Subject: Fix reading qle_signedbitfield as int The type-cast to int for qle_signedbitfield was wrong for all cases where width + pos != 32. The class is currently only used two places though, both where that happen to apply. Change-Id: I108c565b75c9f29dd49b5e2e39f84910d17ead85 Reviewed-by: Lars Knoll --- src/corelib/json/qjson_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h index 0c78fadfc7..c012ec2662 100644 --- a/src/corelib/json/qjson_p.h +++ b/src/corelib/json/qjson_p.h @@ -243,7 +243,7 @@ public: uint i = qFromLittleEndian(val); i <<= 32 - width - pos; int t = (int) i; - t >>= pos; + t >>= 32 - width; return t; } bool operator !() const { -- cgit v1.2.3