QmlCompiler: Don't crash on CallWithSpread
When preparing for such a call, the byte code loads an "empty" constant. This has to be represented in the type system so that we don't hit the assert at the end of the instruction. Pick-to: 6.4 6.2 Task-number: QTBUG-108441 Change-Id: I66220bfae3d3a4b8e9600d84d4cfc43ac858b77e Reviewed-by: Sami Shalayel <sami.shalayel@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
8f827de1a1
commit
df01095a66
|
@ -42,6 +42,10 @@ QQmlJSTypeResolver::QQmlJSTypeResolver(QQmlJSImporter *importer)
|
|||
m_listPropertyType = builtinTypes.type(u"QQmlListProperty<QObject>"_s).scope;
|
||||
m_qObjectListType = builtinTypes.type(u"QObjectList"_s).scope;
|
||||
|
||||
QQmlJSScope::Ptr emptyType = QQmlJSScope::create();
|
||||
emptyType->setAccessSemantics(QQmlJSScope::AccessSemantics::None);
|
||||
m_emptyType = emptyType;
|
||||
|
||||
QQmlJSScope::Ptr emptyListType = QQmlJSScope::create();
|
||||
emptyListType->setInternalName(u"void*"_s);
|
||||
emptyListType->setAccessSemantics(QQmlJSScope::AccessSemantics::Sequence);
|
||||
|
@ -151,6 +155,9 @@ QQmlJSScope::ConstPtr QQmlJSTypeResolver::typeForConst(QV4::ReturnedValue rv) co
|
|||
if (value.isNull())
|
||||
return nullType();
|
||||
|
||||
if (value.isEmpty())
|
||||
return emptyType();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ public:
|
|||
void init(QQmlJSImportVisitor *visitor, QQmlJS::AST::Node *program);
|
||||
|
||||
QQmlJSScope::ConstPtr voidType() const { return m_voidType; }
|
||||
QQmlJSScope::ConstPtr emptyType() const { return m_emptyType; }
|
||||
QQmlJSScope::ConstPtr emptyListType() const { return m_emptyListType; }
|
||||
QQmlJSScope::ConstPtr nullType() const { return m_nullType; }
|
||||
QQmlJSScope::ConstPtr realType() const { return m_realType; }
|
||||
|
@ -180,6 +181,7 @@ protected:
|
|||
|
||||
QQmlJSScope::ConstPtr m_voidType;
|
||||
QQmlJSScope::ConstPtr m_emptyListType;
|
||||
QQmlJSScope::ConstPtr m_emptyType;
|
||||
QQmlJSScope::ConstPtr m_nullType;
|
||||
QQmlJSScope::ConstPtr m_numberPrototype;
|
||||
QQmlJSScope::ConstPtr m_arrayType;
|
||||
|
|
|
@ -54,6 +54,7 @@ set(qml_files
|
|||
blockComments.qml
|
||||
boundComponents.qml
|
||||
callContextPropertyLookupResult.qml
|
||||
callWithSpread.qml
|
||||
childobject.qml
|
||||
colorAsVariant.qml
|
||||
colorString.qml
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import QtQml
|
||||
|
||||
QtObject {
|
||||
Component.onCompleted: {
|
||||
let f = console.error;
|
||||
const data = [f, ["That is great!"]]
|
||||
data[0](...data[1]);
|
||||
}
|
||||
}
|
|
@ -144,6 +144,7 @@ private slots:
|
|||
void listAsArgument();
|
||||
void letAndConst();
|
||||
void signalIndexMismatch();
|
||||
void callWithSpread();
|
||||
};
|
||||
|
||||
void tst_QmlCppCodegen::initTestCase()
|
||||
|
@ -2791,6 +2792,16 @@ void tst_QmlCppCodegen::signalIndexMismatch()
|
|||
|
||||
QCOMPARE(visualIndexBeforeMoveList, QList<QVariant>({ 0, 1, 2 }));
|
||||
QCOMPARE(visualIndexAfterMoveList, QList<QVariant>({ 0, 1, 2 }));
|
||||
}
|
||||
|
||||
void tst_QmlCppCodegen::callWithSpread()
|
||||
{
|
||||
QQmlEngine engine;
|
||||
QQmlComponent c(&engine, QUrl(u"qrc:/qt/qml/TestTypes/callWithSpread.qml"_s));
|
||||
QVERIFY2(c.isReady(), qPrintable(c.errorString()));
|
||||
QTest::ignoreMessage(QtCriticalMsg, "That is great!");
|
||||
QScopedPointer<QObject> o(c.create());
|
||||
QVERIFY(!o.isNull());
|
||||
};
|
||||
|
||||
QTEST_MAIN(tst_QmlCppCodegen)
|
||||
|
|
Loading…
Reference in New Issue