Arguments passed to functions should shadow the function name

Task-number: QTBUG-65140
Change-Id: I6c6b24f081b31ef0f16fec9b2024485acec11c2d
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Lars Knoll 2018-01-10 15:34:38 +01:00
parent 4a29f6881b
commit 4588e73020
3 changed files with 25 additions and 6 deletions

View File

@ -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) { while (parameters) {
if (parameters->name == QLatin1String("arguments")) if (parameters->name == name)
_context->usesArgumentsObject = Context::ArgumentsObjectNotUsed; return true;
parameters = parameters->next; parameters = parameters->next;
} }
return false;
} }
bool ScanFunctions::visit(Program *ast) bool ScanFunctions::visit(Program *ast)
@ -398,9 +400,11 @@ void ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParamete
} }
enterEnvironment(ast, FunctionCode); 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->addLocalVar(name, Context::ThisFunctionName, QQmlJS::AST::VariableDeclaration::FunctionScope);
_context->formals = formals; _context->formals = formals;

View File

@ -100,7 +100,7 @@ protected:
void checkDirectivePrologue(AST::SourceElements *ast); void checkDirectivePrologue(AST::SourceElements *ast);
void checkName(const QStringRef &name, const AST::SourceLocation &loc); 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; bool visit(AST::Program *ast) override;
void endVisit(AST::Program *) override; void endVisit(AST::Program *) override;

View File

@ -347,6 +347,7 @@ private slots:
void manyArguments(); void manyArguments();
void forInIterator(); void forInIterator();
void localForInIterator(); void localForInIterator();
void shadowedFunctionName();
private: private:
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter); // static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
@ -8423,6 +8424,20 @@ void tst_qqmlecmascript::localForInIterator()
QCOMPARE(ret.toString(), QStringLiteral("3")); 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) QTEST_MAIN(tst_qqmlecmascript)