diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2022-11-18 11:40:10 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2022-11-24 13:07:04 +0100 |
commit | 39aba03d4c4bf80a54dbf5b6735b81854dd99220 (patch) | |
tree | aafa2b2ecb0f2b1e678a602fa08c726088876e74 /src | |
parent | 0fbb39435e04e02ecff4a95983be102d57d29e94 (diff) |
QmlCompiler: Fix comparison of null and undefined
Those are not stored. If we compare null to null or undefined to
undefined, we do not have to generate a comparison at all. the result is
statically known.
Fixes: QTBUG-108634
Change-Id: I6a5323c2e0c023838609aec90d7ecc15b885dc08
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit bce216d5c086a5aa8f88d13933eeccebca316359)
Diffstat (limited to 'src')
-rw-r--r-- | src/qmlcompiler/qqmljscodegenerator.cpp | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/src/qmlcompiler/qqmljscodegenerator.cpp b/src/qmlcompiler/qqmljscodegenerator.cpp index be0a937fc0..04926ca519 100644 --- a/src/qmlcompiler/qqmljscodegenerator.cpp +++ b/src/qmlcompiler/qqmljscodegenerator.cpp @@ -35,6 +35,15 @@ using namespace Qt::StringLiterals; m_body += u"// "_s + QStringLiteral(#function) + u'\n'; \ } + +static bool isTypeStorable(const QQmlJSTypeResolver *resolver, const QQmlJSScope::ConstPtr &type) +{ + return !type.isNull() + && !resolver->equals(type, resolver->nullType()) + && !resolver->equals(type, resolver->emptyListType()) + && !resolver->equals(type, resolver->voidType()); +} + QString QQmlJSCodeGenerator::castTargetName(const QQmlJSScope::ConstPtr &type) const { return type->augmentedInternalName(); @@ -75,14 +84,6 @@ QString QQmlJSCodeGenerator::metaObject(const QQmlJSScope::ConstPtr &objectType) return QString(); } -static bool isTypeStorable(const QQmlJSTypeResolver *resolver, const QQmlJSScope::ConstPtr &type) -{ - return !type.isNull() - && !resolver->equals(type, resolver->nullType()) - && !resolver->equals(type, resolver->emptyListType()) - && !resolver->equals(type, resolver->voidType()); -} - QQmlJSAotFunction QQmlJSCodeGenerator::run( const Function *function, const InstructionAnnotations *annotations, QQmlJS::DiagnosticMessage *error) @@ -2315,9 +2316,18 @@ void QQmlJSCodeGenerator::generateEqualityOperation(int lhs, const QString &func const auto primitive = m_typeResolver->jsPrimitiveType(); if (m_typeResolver->equals(lhsType, rhsType) && !m_typeResolver->equals(lhsType, primitive)) { - m_body += conversion(m_typeResolver->boolType(), m_state.accumulatorOut().storedType(), - registerVariable(lhs) + (invert ? u" != "_s : u" == "_s) - + m_state.accumulatorVariableIn); + if (isTypeStorable(m_typeResolver, lhsType)) { + m_body += conversion(m_typeResolver->boolType(), m_state.accumulatorOut().storedType(), + registerVariable(lhs) + (invert ? u" != "_s : u" == "_s) + + m_state.accumulatorVariableIn); + } else if (m_typeResolver->equals(lhsType, m_typeResolver->emptyListType())) { + // We cannot compare two empty lists, because we don't know whether it's + // the same instance or not. "[] === []" is false, but "var a = []; a === a" is true; + reject(u"comparison of two empty lists"_s); + } else { + // null === null and undefined === undefined + m_body += invert ? u"false"_s : u"true"_s; + } } else { m_body += conversion( m_typeResolver->boolType(), m_state.accumulatorOut().storedType(), |