diff options
author | Sami Shalayel <sami.shalayel@qt.io> | 2022-09-09 11:26:00 +0200 |
---|---|---|
committer | Sami Shalayel <sami.shalayel@qt.io> | 2022-09-12 12:02:59 +0200 |
commit | fa2d761e6f5357dfb1469e9cdb81b88e8ed5bcfd (patch) | |
tree | 861539ceec78d85c27406c86e89bb282e09a6f94 | |
parent | d9fe92c7f72c7d7610dd960ee42479a64cf26bee (diff) |
qqmlprivate.h: make static constexpr members c++11 compliant
Newest gcc versions (latest 11 and 12) decided to be c++11 compliant for
static constexpr members, meaning that they need a redundant definition
at namespace scope. This behavior is required for c++11 but deprecated
and not required starting with c++17.
Added those definitions for all static constexpr members in
qqmlprivate.h with appropriate comment.
Fixes: QTBUG-106377
Change-Id: Idb3b3d38218f3a66908de259ae765db2aeb1febb
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r-- | src/qml/qml/qqmlprivate.h | 39 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 27 |
2 files changed, 66 insertions, 0 deletions
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h index a772d95d0c..173e02d22e 100644 --- a/src/qml/qml/qqmlprivate.h +++ b/src/qml/qml/qqmlprivate.h @@ -187,6 +187,23 @@ namespace QQmlPrivate = QQmlPrivate::createSingletonInstance<T>; }; + // from https://en.cppreference.com/w/cpp/language/static: + // If a const non-inline (since C++17) static data member or a constexpr + // static data member (since C++11)(until C++17) is odr-used, a definition + // at namespace scope is still required, but it cannot have an initializer. + // + // If a static data member is declared constexpr, it is implicitly inline + // and does not need to be redeclared at namespace scope. This redeclaration + // without an initializer (formerly required as shown above) is still + // permitted, but is deprecated. + // + // TL;DR: redundant definitions for static constexpr are required in c++11 + // but deprecated in c++17. + template<typename T> + constexpr CreateIntoFunction Constructors<T, true>::createInto; + template<typename T> + constexpr CreateSingletonFunction Constructors<T, true>::createSingletonInstance; + template<typename T> struct Constructors<T, false> { @@ -194,6 +211,12 @@ namespace QQmlPrivate static constexpr CreateSingletonFunction createSingletonInstance = nullptr; }; + // see comment above over the Constructors<T, true> definitions. + template<typename T> + constexpr CreateIntoFunction Constructors<T, false>::createInto; + template<typename T> + constexpr CreateSingletonFunction Constructors<T, false>::createSingletonInstance; + template<typename T, bool IsVoid = std::is_void<T>::value> struct ExtendedType; @@ -205,6 +228,12 @@ namespace QQmlPrivate static constexpr const QMetaObject *staticMetaObject = nullptr; }; + // see comment above over the Constructors<T, true> definitions. + template<typename T> + constexpr const CreateParentFunction ExtendedType<T, true>::createParent; + template<typename T> + constexpr const QMetaObject* ExtendedType<T, true>::staticMetaObject; + // If it's not void, we actually want an error if the ctor or the metaobject is missing. template<typename T> struct ExtendedType<T, false> @@ -213,6 +242,12 @@ namespace QQmlPrivate static constexpr const QMetaObject *staticMetaObject = &T::staticMetaObject; }; + // see comment above over the Constructors<T, true> definitions. + template<typename T> + constexpr const CreateParentFunction ExtendedType<T, false>::createParent; + template<typename T> + constexpr const QMetaObject* ExtendedType<T, false>::staticMetaObject; + template<class From, class To, int N> struct StaticCastSelectorClass { @@ -577,6 +612,10 @@ namespace QQmlPrivate static constexpr bool Value = false; }; + // see comment above over the Constructors<T, true> definitions. + template<typename T, class C> + constexpr bool QmlSingleton<T, C>::Value; + template<class T> struct QmlSingleton<T, QmlVoidT<typename T::QmlIsSingleton>> { diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 48cf20cf38..f3c8d87a8f 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -28,6 +28,7 @@ #include <qtest.h> #include <QtQml/qqmlengine.h> #include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlprivate.h> #include <QtQml/qqmlincubator.h> #include <QtCore/qcoreapplication.h> #include <QtCore/qfile.h> @@ -338,6 +339,7 @@ private slots: void hangOnWarning(); void ambiguousContainingType(); + void staticConstexprMembers(); private: QQmlEngine engine; @@ -5891,6 +5893,31 @@ void tst_qqmllanguage::ambiguousContainingType() QVERIFY(!o.isNull()); } } + void tst_qqmllanguage::staticConstexprMembers() { + // this tests if the symbols are correclty defined for c++11 (gcc 11 and 12), and should + // not have any linker errors + using T = QObject; + using T2 = QObject; + + auto f1 = QQmlPrivate::Constructors<T, true>::createSingletonInstance; + auto f2 = QQmlPrivate::Constructors<T, false>::createSingletonInstance; + auto f3 = QQmlPrivate::Constructors<T, true>::createInto; + + auto f4 = QQmlPrivate::ExtendedType<T, true>::createParent; + auto f5 = QQmlPrivate::ExtendedType<T, false>::createParent; + auto f6 = QQmlPrivate::ExtendedType<T, true>::staticMetaObject; + + auto f7 = QQmlPrivate::QmlSingleton<T, T2>::Value; + + Q_UNUSED(f1); + Q_UNUSED(f2); + Q_UNUSED(f3); + Q_UNUSED(f3); + Q_UNUSED(f4); + Q_UNUSED(f5); + Q_UNUSED(f6); + Q_UNUSED(f7); + } QTEST_MAIN(tst_qqmllanguage) |