aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSemih Yavuz <semih.yavuz@qt.io>2023-01-06 18:39:43 +0300
committerSemih Yavuz <semih.yavuz@qt.io>2023-01-10 15:09:23 +0300
commitafc7928d1a1e47ecbc9d101c4e5d5fb1c5b78326 (patch)
treeea709cb4752ba747b6670b23be2df268e8aa7ae4 /src
parent1609f8628d1469f723a762c60ccb5856637956dc (diff)
QmlCachegen: Equality comparison ability to QObject *
We should be able to compare QObject * with QObject * or a nullptr. Pick-to: 6.5 Fixes: QTBUG-109377 Change-Id: I0e9d6fdc89cbb471774d6382316dfb4813310e1d Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qmlcompiler/qqmljscodegenerator.cpp9
-rw-r--r--src/qmlcompiler/qqmljstypepropagator.cpp5
-rw-r--r--src/qmlcompiler/qqmljsutils.cpp20
-rw-r--r--src/qmlcompiler/qqmljsutils_p.h4
4 files changed, 36 insertions, 2 deletions
diff --git a/src/qmlcompiler/qqmljscodegenerator.cpp b/src/qmlcompiler/qqmljscodegenerator.cpp
index 58cecf1245..686338c1a6 100644
--- a/src/qmlcompiler/qqmljscodegenerator.cpp
+++ b/src/qmlcompiler/qqmljscodegenerator.cpp
@@ -2606,6 +2606,8 @@ void QQmlJSCodeGenerator::generateEqualityOperation(int lhs, const QString &func
return true;
if (canCompareWithVar(m_typeResolver, lhsContent, m_state.accumulatorIn()))
return true;
+ if (canCompareWithQObject(m_typeResolver, lhsContent, m_state.accumulatorIn()))
+ return true;
return false;
};
@@ -2643,6 +2645,13 @@ void QQmlJSCodeGenerator::generateEqualityOperation(int lhs, const QString &func
// lhs content is not storable and rhs is var type
generateVariantEqualityComparison(lhsContent, m_state.accumulatorVariableIn, invert);
}
+ } else if (canCompareWithQObject(m_typeResolver, lhsContent, m_state.accumulatorIn())) {
+ m_body += m_state.accumulatorVariableOut + u" = "_s;
+ m_body += u'('
+ + (isTypeStorable(m_typeResolver, lhsContent.storedType())
+ ? registerVariable(lhs)
+ : m_state.accumulatorVariableIn)
+ + (invert ? u" != "_s : u" == "_s) + u"nullptr)"_s;
} else {
m_body += m_state.accumulatorVariableOut + u" = "_s;
m_body += conversion(
diff --git a/src/qmlcompiler/qqmljstypepropagator.cpp b/src/qmlcompiler/qqmljstypepropagator.cpp
index edd4edfbbf..648cf2c7e6 100644
--- a/src/qmlcompiler/qqmljstypepropagator.cpp
+++ b/src/qmlcompiler/qqmljstypepropagator.cpp
@@ -1838,8 +1838,9 @@ void QQmlJSTypePropagator::recordEqualsType(int lhs)
}
}
- // null, void vs variant and vice versa
- if (canCompareWithVar(m_typeResolver, lhsRegister, accumulatorIn)) {
+ // We don't modify types if the types are comparable with QObject or var
+ if (canCompareWithVar(m_typeResolver, lhsRegister, accumulatorIn)
+ || canCompareWithQObject(m_typeResolver, lhsRegister, accumulatorIn)) {
addReadRegister(lhs, lhsRegister);
addReadAccumulator(accumulatorIn);
return;
diff --git a/src/qmlcompiler/qqmljsutils.cpp b/src/qmlcompiler/qqmljsutils.cpp
index 2e054c04df..b582bf67fc 100644
--- a/src/qmlcompiler/qqmljsutils.cpp
+++ b/src/qmlcompiler/qqmljsutils.cpp
@@ -222,4 +222,24 @@ bool canCompareWithVar(const QQmlJSTypeResolver *typeResolver,
|| typeResolver->equals(lhsType, voidType)));
}
+/*! \internal
+
+ Utility method that checks if one of the registers is qobject, and the other can be
+ efficiently compared to it
+*/
+bool canCompareWithQObject(const QQmlJSTypeResolver *typeResolver,
+ const QQmlJSRegisterContent &lhsContent,
+ const QQmlJSRegisterContent &rhsContent)
+{
+ Q_ASSERT(typeResolver);
+ const auto lhsType = typeResolver->containedType(lhsContent);
+ const auto rhsType = typeResolver->containedType(rhsContent);
+ return (lhsType->isReferenceType()
+ && (rhsType->isReferenceType()
+ || typeResolver->equals(rhsType, typeResolver->nullType())))
+ || (rhsType->isReferenceType()
+ && (lhsType->isReferenceType()
+ || typeResolver->equals(lhsType, typeResolver->nullType())));
+}
+
QT_END_NAMESPACE
diff --git a/src/qmlcompiler/qqmljsutils_p.h b/src/qmlcompiler/qqmljsutils_p.h
index babbcc27a2..beea718216 100644
--- a/src/qmlcompiler/qqmljsutils_p.h
+++ b/src/qmlcompiler/qqmljsutils_p.h
@@ -371,6 +371,10 @@ bool Q_QMLCOMPILER_PRIVATE_EXPORT canCompareWithVar(const QQmlJSTypeResolver *ty
const QQmlJSRegisterContent &lhsContent,
const QQmlJSRegisterContent &rhsContent);
+bool Q_QMLCOMPILER_PRIVATE_EXPORT canCompareWithQObject(const QQmlJSTypeResolver *typeResolver,
+ const QQmlJSRegisterContent &lhsContent,
+ const QQmlJSRegisterContent &rhsContent);
+
QT_END_NAMESPACE
#endif // QQMLJSUTILS_P_H