diff options
author | Semih Yavuz <semih.yavuz@qt.io> | 2023-01-30 22:33:00 +0100 |
---|---|---|
committer | Semih Yavuz <semih.yavuz@qt.io> | 2023-01-31 19:12:30 +0100 |
commit | 66bc0019684519e6ccf3c9910c1bbd9902a13911 (patch) | |
tree | 2acf3aa4b7a23d28beef35b85f4d77594dc3b492 /src | |
parent | db71a35b1e20b028e4e07c8229551fea8ac0eafb (diff) |
qmlcachegen: fix nonstrict equality code generation
We should generate type checking code for only strict comparison
of var against null/undefined types or vice versa cases. The non-
strict comparison should be handled elsewhere. Removed pragma Strict to
allow to add warning emitting tests of non-strict comparison.
This amends 6a816a9e0dfc2b41a4f86c721679f2517ec27eb6
Pick-to: 6.5
Fixes: QTBUG-110769
Change-Id: I7f9a457e71a621a005f377216e841bec01667454
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qmlcompiler/qqmljscodegenerator.cpp | 10 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljstypepropagator.cpp | 2 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljsutils.cpp | 6 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljsutils_p.h | 6 |
4 files changed, 13 insertions, 11 deletions
diff --git a/src/qmlcompiler/qqmljscodegenerator.cpp b/src/qmlcompiler/qqmljscodegenerator.cpp index 8ebd38d753..a1be6ae37a 100644 --- a/src/qmlcompiler/qqmljscodegenerator.cpp +++ b/src/qmlcompiler/qqmljscodegenerator.cpp @@ -2614,6 +2614,8 @@ void QQmlJSCodeGenerator::generateExceptionCheck() void QQmlJSCodeGenerator::generateEqualityOperation(int lhs, const QString &function, bool invert) { const QQmlJSRegisterContent lhsContent = registerType(lhs); + const bool strictlyComparableWithVar = function == "strictlyEquals"_L1 + && canStrictlyCompareWithVar(m_typeResolver, lhsContent, m_state.accumulatorIn()); auto isComparable = [&]() { if (m_typeResolver->isPrimitive(lhsContent) && m_typeResolver->isPrimitive(m_state.accumulatorIn())) { @@ -2623,7 +2625,7 @@ void QQmlJSCodeGenerator::generateEqualityOperation(int lhs, const QString &func return true; if (m_typeResolver->isNumeric(m_state.accumulatorIn()) && lhsContent.isEnumeration()) return true; - if (canCompareWithVar(m_typeResolver, lhsContent, m_state.accumulatorIn())) + if (strictlyComparableWithVar) return true; if (canCompareWithQObject(m_typeResolver, lhsContent, m_state.accumulatorIn())) return true; @@ -2631,8 +2633,8 @@ void QQmlJSCodeGenerator::generateEqualityOperation(int lhs, const QString &func }; if (!isComparable()) { - reject(u"equality comparison on non-primitive types %1 and %2"_s.arg( - m_state.accumulatorIn().descriptiveName(), lhsContent.descriptiveName())); + reject(u"incomparable types %1 and %2"_s.arg(m_state.accumulatorIn().descriptiveName(), + lhsContent.descriptiveName())); } const QQmlJSScope::ConstPtr lhsType = lhsContent.storedType(); @@ -2653,7 +2655,7 @@ void QQmlJSCodeGenerator::generateEqualityOperation(int lhs, const QString &func // null === null and undefined === undefined m_body += invert ? u"false"_s : u"true"_s; } - } else if (canCompareWithVar(m_typeResolver, lhsContent, m_state.accumulatorIn())) { + } else if (strictlyComparableWithVar) { // Determine which side is holding a storable type if (const auto registerVariableName = registerVariable(lhs); !registerVariableName.isEmpty()) { diff --git a/src/qmlcompiler/qqmljstypepropagator.cpp b/src/qmlcompiler/qqmljstypepropagator.cpp index 153e93fdbc..380042e2fe 100644 --- a/src/qmlcompiler/qqmljstypepropagator.cpp +++ b/src/qmlcompiler/qqmljstypepropagator.cpp @@ -1867,7 +1867,7 @@ void QQmlJSTypePropagator::recordEqualsType(int lhs) } // We don't modify types if the types are comparable with QObject or var - if (canCompareWithVar(m_typeResolver, lhsRegister, accumulatorIn) + if (canStrictlyCompareWithVar(m_typeResolver, lhsRegister, accumulatorIn) || canCompareWithQObject(m_typeResolver, lhsRegister, accumulatorIn)) { addReadRegister(lhs, lhsRegister); addReadAccumulator(accumulatorIn); diff --git a/src/qmlcompiler/qqmljsutils.cpp b/src/qmlcompiler/qqmljsutils.cpp index b582bf67fc..410f6b0d14 100644 --- a/src/qmlcompiler/qqmljsutils.cpp +++ b/src/qmlcompiler/qqmljsutils.cpp @@ -202,9 +202,9 @@ QQmlJSUtils::sourceDirectoryPath(const QQmlJSImporter *importer, const QString & Utility method that checks if one of the registers is var, and the other can be efficiently compared to it */ -bool canCompareWithVar(const QQmlJSTypeResolver *typeResolver, - const QQmlJSRegisterContent &lhsContent, - const QQmlJSRegisterContent &rhsContent) +bool canStrictlyCompareWithVar(const QQmlJSTypeResolver *typeResolver, + const QQmlJSRegisterContent &lhsContent, + const QQmlJSRegisterContent &rhsContent) { Q_ASSERT(typeResolver); const auto varType = typeResolver->varType(); diff --git a/src/qmlcompiler/qqmljsutils_p.h b/src/qmlcompiler/qqmljsutils_p.h index beea718216..15425d0cab 100644 --- a/src/qmlcompiler/qqmljsutils_p.h +++ b/src/qmlcompiler/qqmljsutils_p.h @@ -367,9 +367,9 @@ struct Q_QMLCOMPILER_PRIVATE_EXPORT QQmlJSUtils sourceDirectoryPath(const QQmlJSImporter *importer, const QString &buildDirectoryPath); }; -bool Q_QMLCOMPILER_PRIVATE_EXPORT canCompareWithVar(const QQmlJSTypeResolver *typeResolver, - const QQmlJSRegisterContent &lhsContent, - const QQmlJSRegisterContent &rhsContent); +bool Q_QMLCOMPILER_PRIVATE_EXPORT canStrictlyCompareWithVar( + const QQmlJSTypeResolver *typeResolver, const QQmlJSRegisterContent &lhsContent, + const QQmlJSRegisterContent &rhsContent); bool Q_QMLCOMPILER_PRIVATE_EXPORT canCompareWithQObject(const QQmlJSTypeResolver *typeResolver, const QQmlJSRegisterContent &lhsContent, |