summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/ReachableCode.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2014-03-06 00:17:44 +0000
committerTed Kremenek <kremenek@apple.com>2014-03-06 00:17:44 +0000
commit1de2e14f2f3a0f703298f111146f61fbaec1b752 (patch)
tree664e3b3d2b9d324241dc76325447e2cd6fcee1c1 /clang/lib/Analysis/ReachableCode.cpp
parent4b047f23789699e1edde508a548ad04a9fed001b (diff)
downloadbcm5719-llvm-1de2e14f2f3a0f703298f111146f61fbaec1b752.tar.gz
bcm5719-llvm-1de2e14f2f3a0f703298f111146f61fbaec1b752.zip
[-Wunreachable-code] Handle idiomatic do...while() with an uninteresting condition.
Sometimes do..while() is used to create a scope that can be left early. In such cases, the unreachable 'while()' test is not usually interesting unless it actually does something that is observable. llvm-svn: 203036
Diffstat (limited to 'clang/lib/Analysis/ReachableCode.cpp')
-rw-r--r--clang/lib/Analysis/ReachableCode.cpp24
1 files changed, 17 insertions, 7 deletions
diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp
index 7958840b89d..9f6792e2cc7 100644
--- a/clang/lib/Analysis/ReachableCode.cpp
+++ b/clang/lib/Analysis/ReachableCode.cpp
@@ -296,10 +296,7 @@ static bool isTrivialExpression(const Expr *Ex) {
isEnumConstant(Ex);
}
-static bool isTrivialReturn(const CFGBlock *B, const Stmt *S) {
- if (B->pred_empty())
- return false;
-
+static bool isTrivialReturnOrDoWhile(const CFGBlock *B, const Stmt *S) {
const Expr *Ex = dyn_cast<Expr>(S);
if (!Ex)
return false;
@@ -307,6 +304,16 @@ static bool isTrivialReturn(const CFGBlock *B, const Stmt *S) {
if (!isTrivialExpression(Ex))
return false;
+ // Check if the block ends with a do...while() and see if 'S' is the
+ // condition.
+ if (const Stmt *Term = B->getTerminator()) {
+ if (const DoStmt *DS = dyn_cast<DoStmt>(Term))
+ if (DS->getCond() == S)
+ return true;
+ }
+
+
+
// Look to see if the block ends with a 'return', and see if 'S'
// is a substatement. The 'return' may not be the last element in
// the block because of destructors.
@@ -317,12 +324,15 @@ static bool isTrivialReturn(const CFGBlock *B, const Stmt *S) {
if (const ReturnStmt *RS = dyn_cast<ReturnStmt>(CS->getStmt())) {
const Expr *RE = RS->getRetValue();
if (RE && RE->IgnoreParenCasts() == Ex)
- return true;
+ break;
}
- break;
+ return false;
}
}
+ if (B->pred_size() == 1)
+ return bodyEndsWithNoReturn(*B->pred_begin());
+
return false;
}
@@ -336,7 +346,7 @@ void DeadCodeScan::reportDeadCode(const CFGBlock *B,
return;
// Suppress trivial 'return' statements that are dead.
- if (isTrivialReturn(B, S))
+ if (isTrivialReturnOrDoWhile(B, S))
return;
SourceRange R1, R2;
OpenPOWER on IntegriCloud