From abe6c632161375df12a1ab73a9255486ba9436de Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 16 Apr 2018 11:41:31 +0200 Subject: Properly handle redeclarations of variables This is only allowed for var type variables. Also fixes an assertion we'd run into with code such as let x; var x; Change-Id: I2588cf37e0964c879c60b4fd292e7d7b5476e322 Reviewed-by: Simon Hausmann --- src/qml/compiler/qv4compilerscanfunctions.cpp | 28 ++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'src/qml/compiler/qv4compilerscanfunctions.cpp') diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp index 92df98f201..84ee452332 100644 --- a/src/qml/compiler/qv4compilerscanfunctions.cpp +++ b/src/qml/compiler/qv4compilerscanfunctions.cpp @@ -215,14 +215,10 @@ bool ScanFunctions::visit(VariableDeclaration *ast) return false; } QString name = ast->name.toString(); - const Context::Member *m = nullptr; - if (_context->memberInfo(name, &m)) { - if (m->isLexicallyScoped() || ast->isLexicallyScoped()) { - _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Identifier %1 has already been declared").arg(name)); - return false; - } + if (!_context->addLocalVar(ast->name.toString(), ast->expression ? Context::VariableDefinition : Context::VariableDeclaration, ast->scope)) { + _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Identifier %1 has already been declared").arg(name)); + return false; } - _context->addLocalVar(ast->name.toString(), ast->expression ? Context::VariableDefinition : Context::VariableDeclaration, ast->scope); return true; } @@ -397,16 +393,22 @@ bool ScanFunctions::visit(Block *ast) { void ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParameterList *formals, FunctionBody *body, FunctionExpression *expr) { - if (_context) { - _context->hasNestedFunctions = true; + Context *outerContext = _context; + enterEnvironment(ast, FunctionCode); + + if (outerContext) { + outerContext->hasNestedFunctions = true; // The identifier of a function expression cannot be referenced from the enclosing environment. - if (expr) - _context->addLocalVar(name, Context::FunctionDefinition, AST::VariableDeclaration::FunctionScope, expr); + if (expr) { + if (!outerContext->addLocalVar(name, Context::FunctionDefinition, AST::VariableDeclaration::FunctionScope, expr)) { + _cg->throwSyntaxError(ast->firstSourceLocation(), QStringLiteral("Identifier %1 has already been declared").arg(name)); + return; + } + } if (name == QLatin1String("arguments")) - _context->usesArgumentsObject = Context::ArgumentsObjectNotUsed; + outerContext->usesArgumentsObject = Context::ArgumentsObjectNotUsed; } - enterEnvironment(ast, FunctionCode); if (formalsContainName(formals, QStringLiteral("arguments"))) _context->usesArgumentsObject = Context::ArgumentsObjectNotUsed; -- cgit v1.2.3