-
Suggestion
-
Resolution: Unresolved
-
P3: Somewhat important
-
None
-
None
This isn't a bug report, it's more a brainstorming exercise.
qqmlmetatype_p.h has this:
// metatype interface for composite QML types struct QQmlMetaTypeInterface : QtPrivate::QMetaTypeInterface { QByteArray name; QQmlMetaTypeInterface(QByteArray name) : QMetaTypeInterface { /*.revision=*/ QMetaTypeInterface::CurrentRevision, /*.alignment=*/ alignof(QObject *), /*.size=*/ sizeof(QObject *), /*.flags=*/ QtPrivate::QMetaTypeForType<QObject *>::flags(), /*.typeId=*/ 0, /*.metaObjectFn=*/ &dynamicQmlMetaObject, /*.name=*/ name.constData(), // HERE /*.defaultCtr=*/ [](const QMetaTypeInterface *, void *addr) { *static_cast<QObject **>(addr) = nullptr; }, /*.copyCtr=*/ [](const QMetaTypeInterface *, void *addr, const void *other) { *static_cast<QObject **>(addr) = *static_cast<QObject *const *>(other); }, /*.moveCtr=*/ [](const QMetaTypeInterface *, void *addr, void *other) { *static_cast<QObject **>(addr) = *static_cast<QObject **>(other); }, /*.dtor=*/ [](const QMetaTypeInterface *, void *) {}, /*.equals*/ nullptr, /*.lessThan*/ nullptr, /*.debugStream=*/ nullptr, /*.dataStreamOut=*/ nullptr, /*.dataStreamIn=*/ nullptr, /*.legacyRegisterOp=*/ nullptr } , name(std::move(name)) { } };
The handling of the name field when constructing the base class is relying on the stability of the returned pointer from the call of constData. Otherwise, at face value, this is installing a dangling pointer into the name field of the base class: the name parameter is passed by value and will therefore be destroyed by the end of the call to the constructor. But that's not the case, since the pointer is kept alive into the name field of of the derived class.
I don't think this is fixable or worth fixing (unless e.g. Coverity starts complaining, in which case we'll probably just insert a suppression).
What's worth mentioning is that code like this will definitely make small-string optimizations impossible in Qt-next?