diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2021-02-11 13:17:29 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2021-02-11 17:37:53 +0100 |
commit | ab71cdafca87513a4e214d3af056d8990bc1eddb (patch) | |
tree | 22ec625d15eba58c018e748fee55c25a231da709 /src/qml/compiler/qv4codegen.cpp | |
parent | 80bc943025398d0cdb29e4edbe096d8ac127263e (diff) |
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.
Pick-to: 6.1
Task-number: QTBUG-89943
Change-Id: I8a9424ca8c6edd562402fe5c560ba7e8344b5585
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4codegen.cpp')
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index f642797761..38ac04ccbe 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -44,6 +44,7 @@ #include <QtCore/QStringList> #include <QtCore/QStack> #include <QtCore/qurl.h> +#include <QtCore/qloggingcategory.h> #include <QScopeGuard> #include <private/qqmljsast_p.h> #include <private/qqmljslexer_p.h> @@ -65,7 +66,10 @@ static const bool disable_lookups = false; #undef CONST #endif -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcQmlCompiler, "qt.qml.compiler"); + using namespace QV4; using namespace QV4::Compiler; using namespace QQmlJS; @@ -2378,6 +2382,17 @@ Codegen::Reference Codegen::referenceForName(const QString &name, bool isLhs, co if (resolved.isArgOrEval && isLhs) // ### add correct source location throwSyntaxError(SourceLocation(), QStringLiteral("Variable name may not be eval or arguments in strict mode")); + + if (resolved.declarationLocation.isValid() && accessLocation.isValid() + && resolved.declarationLocation.begin() > accessLocation.end()) { + qCWarning(lcQmlCompiler).nospace().noquote() + << url().toString() << ":" << accessLocation.startLine + << ":" << accessLocation.startColumn << " Variable \"" << name + << "\" is used before its declaration at " + << resolved.declarationLocation.startLine << ":" + << resolved.declarationLocation.startColumn << "."; + } + Reference r; switch (resolved.type) { case Context::ResolvedName::Local: @@ -4458,3 +4473,5 @@ QT_WARNING_POP } Q_UNREACHABLE(); } + +QT_END_NAMESPACE |