From 06d819cd714542427ed9f70820b84004c874a9db Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 11 Feb 2021 13:17:29 +0100 Subject: QML: Warn about variables being used before their declaration This collides with injected signal parameters. qmlcachegen cannot tell those cases apart. [ChangeLog][QML][Important Behavior Changes] QML warns about JavaScript variables being used before their declaration now. This is almost always a mistake. It is particularly dangerous in the presence of injected signal parameters because qmlcachegen cannot identify a name collision between an injected signal parameter and a variable being used before its declaration. It therefore miscompiles such code. You can turn off the deprecation warning using the "qt.qml.compiler" logging category. Task-number: QTBUG-89943 Change-Id: I8a9424ca8c6edd562402fe5c560ba7e8344b5585 Reviewed-by: Fabian Kosmale (cherry picked from commit ab71cdafca87513a4e214d3af056d8990bc1eddb) Reviewed-by: Andrei Golubev --- src/qml/compiler/qv4compilercontext.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/qml/compiler/qv4compilercontext.cpp') diff --git a/src/qml/compiler/qv4compilercontext.cpp b/src/qml/compiler/qv4compilercontext.cpp index 08fb2ee993..94c7f0631e 100644 --- a/src/qml/compiler/qv4compilercontext.cpp +++ b/src/qml/compiler/qv4compilercontext.cpp @@ -80,14 +80,14 @@ bool Context::Member::requiresTDZCheck(const SourceLocation &accessLocation, boo if (accessAcrossContextBoundaries) return true; - if (!accessLocation.isValid() || !endOfInitializerLocation.isValid()) + if (!accessLocation.isValid() || !declarationLocation.isValid()) return true; - return accessLocation.begin() < endOfInitializerLocation.end(); + return accessLocation.begin() < declarationLocation.end(); } bool Context::addLocalVar(const QString &name, Context::MemberType type, VariableScope scope, FunctionExpression *function, - const QQmlJS::SourceLocation &endOfInitializer) + const QQmlJS::SourceLocation &declarationLocation) { // ### can this happen? if (name.isEmpty()) @@ -112,13 +112,13 @@ bool Context::addLocalVar(const QString &name, Context::MemberType type, Variabl // hoist var declarations to the function level if (contextType == ContextType::Block && (scope == VariableScope::Var && type != MemberType::FunctionDefinition)) - return parent->addLocalVar(name, type, scope, function, endOfInitializer); + return parent->addLocalVar(name, type, scope, function, declarationLocation); Member m; m.type = type; m.function = function; m.scope = scope; - m.endOfInitializerLocation = endOfInitializer; + m.declarationLocation = declarationLocation; members.insert(name, m); return true; } @@ -146,6 +146,7 @@ Context::ResolvedName Context::resolveName(const QString &name, const QQmlJS::So result.requiresTDZCheck = m.requiresTDZCheck(accessLocation, c != this); if (c->isStrict && (name == QLatin1String("arguments") || name == QLatin1String("eval"))) result.isArgOrEval = true; + result.declarationLocation = m.declarationLocation; return result; } const int argIdx = c->findArgument(name); -- cgit v1.2.3