diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-01-10 15:34:38 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-01-12 07:04:44 +0000 |
commit | 4588e73020731c5e9527734f89bc55f7630435e1 (patch) | |
tree | 5945c242ac7ead6f3e1d0e2cfd46e85858d5aa1a | |
parent | 4a29f6881be30d34b2f171727eb13a08457c6d7b (diff) |
Arguments passed to functions should shadow the function name
Task-number: QTBUG-65140
Change-Id: I6c6b24f081b31ef0f16fec9b2024485acec11c2d
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r-- | src/qml/compiler/qv4compilerscanfunctions.cpp | 14 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilerscanfunctions_p.h | 2 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 15 |
3 files changed, 25 insertions, 6 deletions
diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp index 6a9b064bd8..808e79959d 100644 --- a/src/qml/compiler/qv4compilerscanfunctions.cpp +++ b/src/qml/compiler/qv4compilerscanfunctions.cpp @@ -130,13 +130,15 @@ void ScanFunctions::checkName(const QStringRef &name, const SourceLocation &loc) } } } -void ScanFunctions::checkForArguments(AST::FormalParameterList *parameters) + +bool ScanFunctions::formalsContainName(AST::FormalParameterList *parameters, const QString &name) { while (parameters) { - if (parameters->name == QLatin1String("arguments")) - _context->usesArgumentsObject = Context::ArgumentsObjectNotUsed; + if (parameters->name == name) + return true; parameters = parameters->next; } + return false; } bool ScanFunctions::visit(Program *ast) @@ -398,9 +400,11 @@ void ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParamete } enterEnvironment(ast, FunctionCode); - checkForArguments(formals); + if (formalsContainName(formals, QStringLiteral("arguments"))) + _context->usesArgumentsObject = Context::ArgumentsObjectNotUsed; + - if (!name.isEmpty()) + if (!name.isEmpty() && !formalsContainName(formals, name)) _context->addLocalVar(name, Context::ThisFunctionName, QQmlJS::AST::VariableDeclaration::FunctionScope); _context->formals = formals; diff --git a/src/qml/compiler/qv4compilerscanfunctions_p.h b/src/qml/compiler/qv4compilerscanfunctions_p.h index 0b898e587d..526278fdd8 100644 --- a/src/qml/compiler/qv4compilerscanfunctions_p.h +++ b/src/qml/compiler/qv4compilerscanfunctions_p.h @@ -100,7 +100,7 @@ protected: void checkDirectivePrologue(AST::SourceElements *ast); void checkName(const QStringRef &name, const AST::SourceLocation &loc); - void checkForArguments(AST::FormalParameterList *parameters); + bool formalsContainName(AST::FormalParameterList *parameters, const QString &name); bool visit(AST::Program *ast) override; void endVisit(AST::Program *) override; diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 64cf27ae1f..8913fa2f2e 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -347,6 +347,7 @@ private slots: void manyArguments(); void forInIterator(); void localForInIterator(); + void shadowedFunctionName(); private: // static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter); @@ -8423,6 +8424,20 @@ void tst_qqmlecmascript::localForInIterator() QCOMPARE(ret.toString(), QStringLiteral("3")); } +void tst_qqmlecmascript::shadowedFunctionName() +{ + // verify that arguments shadow the function name + QJSEngine engine; + QJSValue v = engine.evaluate(QString::fromLatin1( + "function f(f) { return f; }\n" + "f(true)\n" + )); + QVERIFY(!v.isError()); + QVERIFY(v.isBool()); + QCOMPARE(v.toBool(), true); +} + + QTEST_MAIN(tst_qqmlecmascript) |