summaryrefslogtreecommitdiff
path: root/src/libs/qmljs/qmljscheck.cpp
diff options
context:
space:
mode:
authorChristian Kamm <christian.d.kamm@nokia.com>2011-09-19 15:28:05 +0200
committerChristian Kamm <christian.d.kamm@nokia.com>2011-09-20 13:21:03 +0200
commita225f7a0afd817bf0a48cf65d5d56d6d010f7a74 (patch)
treee89ce9340cb85b91e6ad55368aee44b274d67eae /src/libs/qmljs/qmljscheck.cpp
parenta4570dec9fa451a024dc444d389cf63adb2abb0b (diff)
downloadqt-creator-a225f7a0afd817bf0a48cf65d5d56d6d010f7a74.tar.gz
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>
Diffstat (limited to 'src/libs/qmljs/qmljscheck.cpp')
-rw-r--r--src/libs/qmljs/qmljscheck.cpp33
1 files changed, 22 insertions, 11 deletions
diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp
index 2ec8613515..d4c6ae16df 100644
--- a/src/libs/qmljs/qmljscheck.cpp
+++ b/src/libs/qmljs/qmljscheck.cpp
@@ -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