diff options
author | Christian Kamm <christian.d.kamm@nokia.com> | 2011-09-19 15:28:05 +0200 |
---|---|---|
committer | Christian Kamm <christian.d.kamm@nokia.com> | 2011-09-20 13:21:03 +0200 |
commit | a225f7a0afd817bf0a48cf65d5d56d6d010f7a74 (patch) | |
tree | e89ce9340cb85b91e6ad55368aee44b274d67eae /src/libs/qmljs/qmljscheck.cpp | |
parent | a4570dec9fa451a024dc444d389cf63adb2abb0b (diff) | |
download | qt-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.cpp | 33 |
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 |