summaryrefslogtreecommitdiffstats
path: root/src/corelib/global
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@qt.io>2022-01-31 17:19:06 +0100
committerMarc Mutz <marc.mutz@qt.io>2022-03-26 17:15:02 +0100
commit80b6bcc385863a38d499685af9b8e857e46cbdba (patch)
tree252b745a2b8dd617224f49cf89139cd5baef317c /src/corelib/global
parentedb64351cd0896d27af15d54d5fa868c7567eced (diff)
Short live Q_CONSTINIT!
It expands to the first available of - constinit (C++20) - [[clang::require_constant_initialization]] (Clang) - __constinit (GCC >= 10) Use it around the code (on and near static QBasicAtomic; this patch makes no attempt to find all statics in qtbase). [ChangeLog][QtCore][QtGlobal] Added macro Q_CONSTINIT. Fixes: QTBUG-100484 Change-Id: I11e0363a7acb3464476859d12ec7f94319d82be7 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/corelib/global')
-rw-r--r--src/corelib/global/qglobal.cpp29
-rw-r--r--src/corelib/global/qglobal.h10
-rw-r--r--src/corelib/global/qglobalstatic.h4
-rw-r--r--src/corelib/global/qlogging.cpp6
4 files changed, 43 insertions, 6 deletions
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 067172efa4..1bbabed781 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -3344,7 +3344,7 @@ Q_CORE_EXPORT Q_DECL_CONST_FUNCTION unsigned int qt_int_sqrt(unsigned int n)
// In the C runtime on all platforms access to the environment is not thread-safe. We
// add thread-safety for the Qt wrappers.
-static QBasicMutex environmentMutex;
+Q_CONSTINIT static QBasicMutex environmentMutex;
/*
Wraps tzset(), which accesses the environment, so should only be called while
@@ -4115,6 +4115,33 @@ bool qunsetenv(const char *varName)
*/
/*!
+ \macro Q_CONSTINIT
+ \relates <QtGlobal>
+ \since 6.4
+
+ \brief Enforces constant initialization when supported by the compiler.
+
+ If the compiler supports the C++20 \c{constinit} keyword, Clang's
+ \c{[[clang::require_constant_initialization]]} or GCC's \c{__constinit},
+ then this macro expands to the first one of these that is available,
+ otherwise it expands to nothing.
+
+ Variables marked as \c{constinit} cause a compile-error if their
+ initialization would have to be performed at runtime.
+
+ For constants, you can use \c{constexpr} since C++11, but \c{constexpr}
+ makes variables \c{const}, too, whereas \c{constinit} ensures constant
+ initialization, but doesn't make the variable \c{const}:
+
+ \table
+ \header \li Keyword \li Added \li immutable \li constant-initialized
+ \row \li \c{const} \li C++98 \li yes \li not required
+ \row \li \c{constexpr} \li C++11 \li yes \li required
+ \row \li \c{constinit} \li C++20 \li no \li required
+ \endtable
+*/
+
+/*!
\macro QT_POINTER_SIZE
\relates <QtGlobal>
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index e69e55977b..18851cd120 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -1165,6 +1165,16 @@ constexpr std::underlying_type_t<Enum> qToUnderlying(Enum e) noexcept
#define Q_IMPLICIT
#endif
+#ifdef __cpp_constinit
+# define Q_CONSTINIT constinit
+#elif defined(__has_cpp_attribute) && __has_cpp_attribute(clang::require_constant_initialization)
+# define Q_CONSTINIT [[clang::require_constant_initialization]]
+#elif defined(Q_CC_GNU) && Q_CC_GNU >= 1000
+# define Q_CONSTINIT __constinit
+#else
+# define Q_CONSTINIT
+#endif
+
template <typename T> inline T *qGetPtrHelper(T *ptr) noexcept { return ptr; }
template <typename Ptr> inline auto qGetPtrHelper(Ptr &ptr) noexcept -> decltype(ptr.get())
{ static_assert(noexcept(ptr.get()), "Smart d pointers for Q_DECLARE_PRIVATE must have noexcept get()"); return ptr.get(); }
diff --git a/src/corelib/global/qglobalstatic.h b/src/corelib/global/qglobalstatic.h
index aaa01262a7..beecc1f000 100644
--- a/src/corelib/global/qglobalstatic.h
+++ b/src/corelib/global/qglobalstatic.h
@@ -63,7 +63,7 @@ template <typename QGS> union Holder
using PlainType = std::remove_cv_t<Type>;
static constexpr bool ConstructionIsNoexcept = noexcept(QGS::innerFunction(nullptr));
- static inline QBasicAtomicInteger<qint8> guard = { QtGlobalStatic::Uninitialized };
+ Q_CONSTINIT static inline QBasicAtomicInteger<qint8> guard = { QtGlobalStatic::Uninitialized };
// union's sole member
PlainType storage;
@@ -144,7 +144,7 @@ protected:
new (pointer) QGS_Type ARGS; \
} \
}; } \
- static QGlobalStatic<QtGlobalStatic::Holder<Q_QGS_ ## NAME>> NAME; \
+ Q_CONSTINIT static QGlobalStatic<QtGlobalStatic::Holder<Q_QGS_ ## NAME>> NAME; \
QT_WARNING_POP
/**/
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 254894961e..6302fc9d80 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -1096,7 +1096,7 @@ struct QMessagePattern
Q_DECLARE_TYPEINFO(QMessagePattern::BacktraceParams, Q_RELOCATABLE_TYPE);
#endif
-QBasicMutex QMessagePattern::mutex;
+Q_CONSTINIT QBasicMutex QMessagePattern::mutex;
QMessagePattern::QMessagePattern()
{
@@ -1750,7 +1750,7 @@ static bool android_default_message_handler(QtMsgType type,
static void win_outputDebugString_helper(const QString &message)
{
const qsizetype maxOutputStringLength = 32766;
- static QBasicMutex m;
+ Q_CONSTINIT static QBasicMutex m;
auto locker = qt_unique_lock(m);
// fast path: Avoid string copies if one output is enough
if (message.length() <= maxOutputStringLength) {
@@ -1827,7 +1827,7 @@ static void stderr_message_handler(QtMsgType type, const QMessageLogContext &con
#ifdef Q_OS_WASM
// Prevent thread cross-talk, which causes Emscripten to log
// non-valid UTF-8. FIXME: remove once we upgrade to emsdk > 2.0.30
- static QBasicMutex m;
+ Q_CONSTINIT static QBasicMutex m;
auto locker = qt_unique_lock(m);
#endif