Commit a225f7a0 authored by Christian Kamm's avatar Christian Kamm

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

Change-Id: Iaf9febc841130fa913fcc071ed0bf28ff9e0b63b
Reviewed-on: http://codereview.qt-project.org/5149Reviewed-by: default avatarQt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: default avatarFawzi Mohamed <fawzi.mohamed@nokia.com>
parent a4570dec
......@@ -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
......
import Qt 4.7
// DEFAULTMSG unreachable
Item {
function foo() {
return
x() // W 9 11
x()
}
function foo() {
throw new Object()
x() // W 9 11
x()
}
function foo() {
if (a)
return
x()
if (a)
foo();
else
return
x()
if (a)
return
else
return
x() // W 9 11
}
function foo() {
try {
throw 1
} finally {}
x() // W 9 11
}
function foo() {
try {
} finally {
return
}
x() // W 9 11
}
function foo() {
try {
} catch(a) {
return
}
x()
try {
return
} catch(a) {
}
x()
try {
return
} catch(a) {
return
}
x() // W 9 11
}
function foo() {
switch (a) {
case 0:
break
case 1:
case 2:
return
}
x()
switch (a) {
case 1:
case 2:
return
}
x()
switch (a) {
case 1:
case 2:
return
default:
return
}
x() // W 9 11
}
function foo() {
l1: do {
l2: while (b) {
return
}
x()
l3: do {
break l1
} while (b);
x() // W 13 15
} while (a);
x() // reachable via break
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment