aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2021-05-19 15:22:28 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2021-05-20 11:40:14 +0200
commitae1334d827bd386ae34ed5fca8f00dcef83bc65e (patch)
treefad1d0e58e79fafc8f1dce8e912ce80f52b5f0c3
parentc9a90cdf3ce25d54a80f50de1e19ed6c555470cc (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.cpp23
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;