aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSami Shalayel <sami.shalayel@qt.io>2022-09-09 11:26:00 +0200
committerSami Shalayel <sami.shalayel@qt.io>2022-09-12 12:02:59 +0200
commitfa2d761e6f5357dfb1469e9cdb81b88e8ed5bcfd (patch)
tree861539ceec78d85c27406c86e89bb282e09a6f94
parentd9fe92c7f72c7d7610dd960ee42479a64cf26bee (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.h39
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp27
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)