QmlJS checks: Add tests and fix small bugs for 'unreachable'.

Change-Id: Iaf9febc841130fa913fcc071ed0bf28ff9e0b63b
Reviewed-on: http://codereview.qt-project.org/5149
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@nokia.com>
This commit is contained in:
Christian Kamm
2011-09-19 15:28:05 +02:00
parent a4570dec9f
commit a225f7a0af
2 changed files with 126 additions and 11 deletions

View File

@@ -311,8 +311,10 @@ protected:
{
_state = Break;
if (!ast->label.isEmpty()) {
if (Node *target = _labels.value(ast->label.toString()))
if (Node *target = _labels.value(ast->label.toString())) {
_labelledBreaks.insert(target);
_state = ReturnOrThrow; // unwind until label is hit
}
}
return false;
}
@@ -360,7 +362,7 @@ protected:
handleClause(it->clause->statements, &result, &lastWasFallthrough);
}
if (lastWasFallthrough)
if (lastWasFallthrough || !ast->block->defaultClause)
result = ReachesEnd;
if (result == Break || _labelledBreaks.contains(ast))
result = ReachesEnd;
@@ -382,20 +384,29 @@ protected:
return false;
}
bool loopStatement(Node *loop, Statement *body)
bool preconditionLoopStatement(Node *, Statement *body)
{
check(body);
if (_state != ReturnOrThrow || _labelledBreaks.contains(loop))
_state = ReachesEnd;
_state = ReachesEnd; // condition could be false...
return false;
}
virtual bool visit(WhileStatement *ast) { return loopStatement(ast, ast->statement); }
virtual bool visit(ForStatement *ast) { return loopStatement(ast, ast->statement); }
virtual bool visit(ForEachStatement *ast) { return loopStatement(ast, ast->statement); }
virtual bool visit(DoWhileStatement *ast) { return loopStatement(ast, ast->statement); }
virtual bool visit(LocalForStatement *ast) { return loopStatement(ast, ast->statement); }
virtual bool visit(LocalForEachStatement *ast) { return loopStatement(ast, ast->statement); }
virtual bool visit(WhileStatement *ast) { return preconditionLoopStatement(ast, ast->statement); }
virtual bool visit(ForStatement *ast) { return preconditionLoopStatement(ast, ast->statement); }
virtual bool visit(ForEachStatement *ast) { return preconditionLoopStatement(ast, ast->statement); }
virtual bool visit(LocalForStatement *ast) { return preconditionLoopStatement(ast, ast->statement); }
virtual bool visit(LocalForEachStatement *ast) { return preconditionLoopStatement(ast, ast->statement); }
virtual bool visit(DoWhileStatement *ast)
{
check(ast->statement);
// not necessarily an infinite loop due to labelled breaks
if (_state == Continue)
_state = ReturnOrThrow;
if (_state == Break || _labelledBreaks.contains(ast))
_state = ReachesEnd;
return false;
}
};
class MarkUnreachableCode : protected ReachesEndCheck