diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-05-19 15:22:28 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-05-20 11:40:14 +0200 |
commit | ae1334d827bd386ae34ed5fca8f00dcef83bc65e (patch) | |
tree | fad1d0e58e79fafc8f1dce8e912ce80f52b5f0c3 | |
parent | c9a90cdf3ce25d54a80f50de1e19ed6c555470cc (diff) |
Add Q_ASSERT for _context pointer to pacify code checker
The pointer is initialized to nullptr, set in enterEnvironment, and possibly
reset in leaveEnvironment. The static analyzer can't know that it is
always set before any of other functions is called, so assert that pre-
condition via Q_ASSERT.
Pick-to: 6.1
Change-Id: I0198505db40a93227ba52a08c29a351e85b74cc0
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
-rw-r--r-- | src/qml/compiler/qv4compilerscanfunctions.cpp | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp index a942b3d2c9..9dec968a91 100644 --- a/src/qml/compiler/qv4compilerscanfunctions.cpp +++ b/src/qml/compiler/qv4compilerscanfunctions.cpp @@ -107,6 +107,7 @@ void ScanFunctions::leaveEnvironment() void ScanFunctions::checkDirectivePrologue(StatementList *ast) { + Q_ASSERT(_context); for (StatementList *it = ast; it; it = it->next) { if (ExpressionStatement *expr = cast<ExpressionStatement *>(it->statement)) { if (StringLiteral *strLit = cast<StringLiteral *>(expr->expression)) { @@ -131,6 +132,7 @@ void ScanFunctions::checkDirectivePrologue(StatementList *ast) void ScanFunctions::checkName(QStringView name, const QQmlJS::SourceLocation &loc) { + Q_ASSERT(_context); if (_context->isStrict) { if (name == QLatin1String("implements") || name == QLatin1String("interface") @@ -161,6 +163,7 @@ void ScanFunctions::endVisit(Program *) bool ScanFunctions::visit(ESModule *ast) { enterEnvironment(ast, defaultProgramType, QStringLiteral("%ModuleCode")); + Q_ASSERT(_context); _context->isStrict = true; return true; } @@ -172,6 +175,7 @@ void ScanFunctions::endVisit(ESModule *) bool ScanFunctions::visit(ExportDeclaration *declaration) { + Q_ASSERT(_context); QString module; if (declaration->fromClause) { module = declaration->fromClause->moduleSpecifier.toString(); @@ -264,6 +268,7 @@ bool ScanFunctions::visit(ExportDeclaration *declaration) bool ScanFunctions::visit(ImportDeclaration *declaration) { + Q_ASSERT(_context); QString module; if (declaration->fromClause) { module = declaration->fromClause->moduleSpecifier.toString(); @@ -312,6 +317,7 @@ bool ScanFunctions::visit(ImportDeclaration *declaration) bool ScanFunctions::visit(CallExpression *ast) { + Q_ASSERT(_context); if (!_context->hasDirectEval) { if (IdentifierExpression *id = cast<IdentifierExpression *>(ast->base)) { if (id->name == QLatin1String("eval")) { @@ -326,6 +332,7 @@ bool ScanFunctions::visit(CallExpression *ast) bool ScanFunctions::visit(PatternElement *ast) { + Q_ASSERT(_context); if (!ast->isVariableDeclaration()) return true; @@ -361,6 +368,7 @@ bool ScanFunctions::visit(PatternElement *ast) bool ScanFunctions::visit(IdentifierExpression *ast) { + Q_ASSERT(_context); checkName(ast->name, ast->identifierToken); if (_context->usesArgumentsObject == Context::ArgumentsObjectUnknown && ast->name == QLatin1String("arguments")) _context->usesArgumentsObject = Context::ArgumentsObjectUsed; @@ -397,6 +405,7 @@ bool ScanFunctions::visit(FunctionExpression *ast) bool ScanFunctions::visit(ClassExpression *ast) { enterEnvironment(ast, ContextType::Block, QStringLiteral("%Class")); + Q_ASSERT(_context); _context->isStrict = true; _context->hasNestedFunctions = true; if (!ast->name.isEmpty()) @@ -411,6 +420,7 @@ void ScanFunctions::endVisit(ClassExpression *) bool ScanFunctions::visit(ClassDeclaration *ast) { + Q_ASSERT(_context); if (!ast->name.isEmpty()) _context->addLocalVar(ast->name.toString(), Context::VariableDeclaration, AST::VariableScope::Let); @@ -461,6 +471,7 @@ bool ScanFunctions::visit(FieldMemberExpression *ast) _cg->throwSyntaxError(ast->identifierToken, QLatin1String("Expected 'target' after 'new.'.")); return false; } + Q_ASSERT(_context); Context *c = _context; bool needContext = false; while (c->contextType == ContextType::Block || c->isArrowFunction) { @@ -487,6 +498,7 @@ bool ScanFunctions::visit(ArrayPattern *ast) bool ScanFunctions::enterFunction(FunctionExpression *ast, bool enterName) { + Q_ASSERT(_context); if (_context->isStrict && (ast->name == QLatin1String("eval") || ast->name == QLatin1String("arguments"))) _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Function name may not be eval or arguments in strict mode")); return enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName); @@ -559,10 +571,13 @@ void ScanFunctions::endVisit(ForStatement *) leaveEnvironment(); } -bool ScanFunctions::visit(ForEachStatement *ast) { +bool ScanFunctions::visit(ForEachStatement *ast) +{ enterEnvironment(ast, ContextType::Block, QStringLiteral("%Foreach")); - if (ast->expression) + if (ast->expression) { + Q_ASSERT(_context); _context->lastBlockInitializerLocation = ast->expression->lastSourceLocation(); + } Node::accept(ast->lhs, this); Node::accept(ast->expression, this); @@ -579,6 +594,7 @@ void ScanFunctions::endVisit(ForEachStatement *) bool ScanFunctions::visit(ThisExpression *) { + Q_ASSERT(_context); _context->usesThis = true; return false; } @@ -609,6 +625,7 @@ void ScanFunctions::endVisit(CaseBlock *) bool ScanFunctions::visit(Catch *ast) { + Q_ASSERT(_context); TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, _context->isStrict ? false : _allowFuncDecls); enterEnvironment(ast, ContextType::Block, QStringLiteral("%CatchBlock")); _context->isCatchBlock = true; @@ -636,6 +653,7 @@ void ScanFunctions::endVisit(Catch *) bool ScanFunctions::visit(WithStatement *ast) { + Q_ASSERT(_context); Node::accept(ast->expression, this); TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, _context->isStrict ? false : _allowFuncDecls); @@ -678,6 +696,7 @@ bool ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParamete outerContext->usesArgumentsObject = Context::ArgumentsObjectNotUsed; } + Q_ASSERT(_context); _context->name = name; if (formals && formals->containsName(QStringLiteral("arguments"))) _context->usesArgumentsObject = Context::ArgumentsObjectNotUsed; |