From 688e8f63a2bb87469517166f90c50dec524f90c5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 21 Jun 2022 11:08:58 -0700 Subject: [PATCH] moc: fix const-init for Windows References to __declspec(dllimport) is not a constant expression on Windows, so we can't have a direct reference to a staticMetaObject. Commit 9b8493314dd77f3e96b353187816bb7ef4dedbb5 fixed the Q_OBJECT parent link (added in 5.14, kicked in for 6.0 with the ABI break), but commit 656d6f2a9b221dbd5adfc46262cb243e696d8d62 added links for Q_GADGETs too without taking the need for Windows DLLs into account. This change is a no-op everywhere but Windows. On Windows, since we store the pointer to the indirect getter function, now you may get non- null pointers from QMetaObject::superClass(). Pick-to: 6.4 Change-Id: I6d3880c7d99d4fc494c8fffd16fab51aa255106e Reviewed-by: Qt CI Bot Reviewed-by: Fabian Kosmale --- src/corelib/kernel/qobjectdefs.h | 3 ++- src/tools/moc/generator.cpp | 7 +++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index 0fca56f703..8309e43d89 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -369,6 +369,7 @@ struct Q_CORE_EXPORT QMetaObject } struct SuperData { + using Getter = const QMetaObject *(*)(); const QMetaObject *direct; SuperData() = default; constexpr SuperData(std::nullptr_t) : direct(nullptr) {} @@ -377,7 +378,6 @@ struct Q_CORE_EXPORT QMetaObject constexpr const QMetaObject *operator->() const { return operator const QMetaObject *(); } #ifdef QT_NO_DATA_RELOCATION - using Getter = const QMetaObject *(*)(); Getter indirect = nullptr; constexpr SuperData(Getter g) : direct(nullptr), indirect(g) {} constexpr operator const QMetaObject *() const @@ -385,6 +385,7 @@ struct Q_CORE_EXPORT QMetaObject template static constexpr SuperData link() { return SuperData(QMetaObject::staticMetaObject); } #else + constexpr SuperData(Getter g) : direct(g()) {} constexpr operator const QMetaObject *() const { return direct; } template static constexpr SuperData link() diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 5958ad7022..49cdf4a0ad 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -489,16 +489,15 @@ void Generator::generateCode() // // Finally create and initialize the static meta object // - fprintf(out, "%sconst QMetaObject %s::staticMetaObject = { {\n", - // ### FIXME: gadgets are not constinit on Windows! - cdef->hasQGadget ? "" : "Q_CONSTINIT ", cdef->qualified.constData()); + fprintf(out, "Q_CONSTINIT const QMetaObject %s::staticMetaObject = { {\n", + cdef->qualified.constData()); if (isQObject) fprintf(out, " nullptr,\n"); else if (cdef->superclassList.size() && !cdef->hasQGadget && !cdef->hasQNamespace) // for qobject, we know the super class must have a static metaobject fprintf(out, " QMetaObject::SuperData::link<%s::staticMetaObject>(),\n", purestSuperClass.constData()); else if (cdef->superclassList.size()) // for gadgets we need to query at compile time for it - fprintf(out, " QtPrivate::MetaObjectForType<%s>::value(),\n", purestSuperClass.constData()); + fprintf(out, " QtPrivate::MetaObjectForType<%s>::value,\n", purestSuperClass.constData()); else fprintf(out, " nullptr,\n"); fprintf(out, " qt_meta_stringdata_%s.offsetsAndSizes,\n"