aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-01-10 15:34:38 +0100
committerLars Knoll <lars.knoll@qt.io>2018-01-12 07:04:44 +0000
commit4588e73020731c5e9527734f89bc55f7630435e1 (patch)
tree5945c242ac7ead6f3e1d0e2cfd46e85858d5aa1a
parent4a29f6881be30d34b2f171727eb13a08457c6d7b (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.cpp14
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions_p.h2
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp15
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)