From ea283a44027d9b493c8cc00fc85840aa67af09d8 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 27 Sep 2023 12:25:09 +0200 Subject: Fix crash of test registersingletontype.py in Qt 6.7 In f3f8939f347370dbd2738ecb536543bf8cff4a09, a second occurrence of QQmlPrivate::RegisterSingletonType in qmlRegisterSingletonInstance() was overlooked. Take the opportunity to brace-initialize the QML register structs such that further additions to them will then show up as warnings or errors. Pick-to: 6.2 Task-number: PYSIDE-2433 Change-Id: Ia2af115193531543522d427764e70130339af007 Reviewed-by: Cristian Maureira-Fredes Reviewed-by: Shyamnath Premnadh Reviewed-by: Qt CI Bot (cherry picked from commit 74b23bae33489941dc3eb66f47ee720c723486fe) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit e335226be86c99245b55e65dea7af97ad4a63339) --- .../pyside6/libpysideqml/pysideqmlregistertype.cpp | 107 +++++++++++---------- 1 file changed, 58 insertions(+), 49 deletions(-) diff --git a/sources/pyside6/libpysideqml/pysideqmlregistertype.cpp b/sources/pyside6/libpysideqml/pysideqmlregistertype.cpp index aac584fc7..1208220ca 100644 --- a/sources/pyside6/libpysideqml/pysideqmlregistertype.cpp +++ b/sources/pyside6/libpysideqml/pysideqmlregistertype.cpp @@ -105,29 +105,46 @@ int qmlRegisterType(PyObject *pyObj, const char *uri, int versionMajor, const QMetaObject *metaObject = PySide::retrieveMetaObject(pyObjType); Q_ASSERT(metaObject); - QQmlPrivate::RegisterType type; - - // Allow registering Qt Quick items. - const bool isQuickType = quickRegisterItemFunction && quickRegisterItemFunction(pyObj, &type); - // Register as simple QObject rather than Qt Quick item. // Incref the type object, don't worry about decref'ing it because // there's no way to unregister a QML type. Py_INCREF(pyObj); - type.structVersion = 0; - const QByteArray typeName(pyObjType->tp_name); QByteArray ptrType = typeName + '*'; QByteArray listType = QByteArrayLiteral("QQmlListProperty<") + typeName + '>'; + const auto typeId = QMetaType(new QQmlMetaTypeInterface(ptrType)); + const auto listId = QMetaType(new QQmlListMetaTypeInterface(listType, typeId.iface())); + const int objectSize = static_cast(PySide::getSizeOfQObject(reinterpret_cast(pyObj))); - type.typeId = QMetaType(new QQmlMetaTypeInterface(ptrType)); - type.listId = QMetaType(new QQmlListMetaTypeInterface(listType, - type.typeId.iface())); const auto typeInfo = qmlTypeInfo(pyObj); - auto info = qmlAttachedInfo(pyObjType, typeInfo); - type.attachedPropertiesFunction = info.factory; - type.attachedPropertiesMetaObject = info.metaObject; + const auto attachedInfo = qmlAttachedInfo(pyObjType, typeInfo); + const auto extendedInfo = qmlExtendedInfo(pyObj, typeInfo); + + QQmlPrivate::RegisterType type { + QQmlPrivate::RegisterType::StructVersion::Base, // structVersion + typeId, listId, objectSize, + creatable ? createInto : nullptr, // create + pyObj, // userdata + QString::fromUtf8(noCreationReason), + nullptr, // createValueType (Remove in Qt 7) + uri, + QTypeRevision::fromVersion(versionMajor, versionMinor), // version + qmlName, // elementName + metaObject, + attachedInfo.factory, // attachedPropertiesFunction + attachedInfo.metaObject, // attachedPropertiesMetaObject + 0, 0, 0, // parserStatusCast, valueSourceCast, valueInterceptorCast + extendedInfo.factory, // extensionObjectCreate + extendedInfo.metaObject, // extensionMetaObject + nullptr, // customParser + {}, // revision + 0, // finalizerCast + QQmlPrivate::ValueTypeCreationMethod::None // creationMethod + }; + + // Allow registering Qt Quick items. + const bool isQuickType = quickRegisterItemFunction && quickRegisterItemFunction(pyObj, &type); if (!isQuickType) { // values filled by the Quick registration // QPyQmlParserStatus inherits QObject, QQmlParserStatus, so, @@ -143,22 +160,6 @@ int qmlRegisterType(PyObject *pyObj, const char *uri, int versionMajor, QQmlPrivate::StaticCastSelector::cast(); } - int objectSize = static_cast(PySide::getSizeOfQObject( - reinterpret_cast(pyObj))); - type.objectSize = objectSize; - type.create = creatable ? createInto : nullptr; - type.noCreationReason = QString::fromUtf8(noCreationReason); - type.userdata = pyObj; - type.uri = uri; - type.version = QTypeRevision::fromVersion(versionMajor, versionMinor); - type.elementName = qmlName; - - info = qmlExtendedInfo(pyObj, typeInfo); - type.extensionObjectCreate = info.factory; - type.extensionMetaObject = info.metaObject; - type.customParser = 0; - type.metaObject = metaObject; // Snapshot may have changed. - int qmlTypeId = QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); if (qmlTypeId == -1) { PyErr_Format(PyExc_TypeError, "QML meta type registration of \"%s\" failed.", @@ -209,15 +210,19 @@ int qmlRegisterSingletonType(PyObject *pyObj, const char *uri, int versionMajor, Q_ASSERT(metaObject); } - QQmlPrivate::RegisterSingletonType type; - type.structVersion = 0; - - type.uri = uri; - type.version = QTypeRevision::fromVersion(versionMajor, versionMinor); - type.typeName = qmlName; - type.instanceMetaObject = metaObject; - type.extensionMetaObject = nullptr; - type.extensionObjectCreate = nullptr; + QQmlPrivate::RegisterSingletonType type { + QQmlPrivate::RegisterType::StructVersion::Base, // structVersion + uri, + QTypeRevision::fromVersion(versionMajor, versionMinor), // version + qmlName, // typeName + {}, // scriptApi + {}, // qObjectApi + metaObject, // instanceMetaObject + {}, // typeId + nullptr, // extensionMetaObject + nullptr, // extensionObjectCreate + {} // revision + }; if (isQObject) { // FIXME: Fix this to assign new type ids each time. @@ -307,18 +312,22 @@ int qmlRegisterSingletonInstance(PyObject *pyObj, const char *uri, int versionMa const QMetaObject *metaObject = PySide::retrieveMetaObject(pyObjType); Q_ASSERT(metaObject); - QQmlPrivate::RegisterSingletonType type; - type.structVersion = 0; - - type.uri = uri; - type.version = QTypeRevision::fromVersion(versionMajor, versionMinor); - type.typeName = qmlName; - type.instanceMetaObject = metaObject; - // FIXME: Fix this to assign new type ids each time. - type.typeId = QMetaType(QMetaType::QObjectStar); - type.qObjectApi = registrationFunctor; - + const QMetaType typeId = QMetaType(QMetaType::QObjectStar); + + QQmlPrivate::RegisterSingletonType type { + QQmlPrivate::RegisterType::StructVersion::Base, // structVersion + uri, + QTypeRevision::fromVersion(versionMajor, versionMinor), // version + qmlName, // typeName + {}, // scriptApi + registrationFunctor, // qObjectApi + metaObject, // instanceMetaObject + typeId, + nullptr, // extensionMetaObject + nullptr, // extensionObjectCreate + {} // revision + }; return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &type); } -- cgit v1.2.3