summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/ReachableCode.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2014-03-15 05:47:06 +0000
committerTed Kremenek <kremenek@apple.com>2014-03-15 05:47:06 +0000
commitad8753c00eac02acf9ef30aceb316721abf7ef6c (patch)
tree7fa4d91b787da562f7e338ecd51c2ba63ebe1369 /clang/lib/Analysis/ReachableCode.cpp
parentfb6b25b5e4cf09cf971f83d20a6b6eea9f04842c (diff)
downloadbcm5719-llvm-ad8753c00eac02acf9ef30aceb316721abf7ef6c.tar.gz
bcm5719-llvm-ad8753c00eac02acf9ef30aceb316721abf7ef6c.zip
Further refine -Wunreachable-code groups so that -Wno-unreachable-code-break doesn't turn off all unreachable code warnings.
Also relax unreachable 'break' and 'return' to not check for being preceded by a call to 'noreturn'. That turns out to not be so interesting in practice. llvm-svn: 204000
Diffstat (limited to 'clang/lib/Analysis/ReachableCode.cpp')
-rw-r--r--clang/lib/Analysis/ReachableCode.cpp61
1 files changed, 27 insertions, 34 deletions
diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp
index 09b0efd0e68..d297d03775d 100644
--- a/clang/lib/Analysis/ReachableCode.cpp
+++ b/clang/lib/Analysis/ReachableCode.cpp
@@ -136,8 +136,7 @@ static bool isTrivialExpression(const Expr *Ex) {
isEnumConstant(Ex);
}
-static bool isTrivialReturnOrDoWhile(const CFGBlock *B, const Stmt *S,
- reachable_code::UnreachableKind &UK) {
+static bool isTrivialDoWhile(const CFGBlock *B, const Stmt *S) {
// Check if the block ends with a do...while() and see if 'S' is the
// condition.
if (const Stmt *Term = B->getTerminator()) {
@@ -146,7 +145,10 @@ static bool isTrivialReturnOrDoWhile(const CFGBlock *B, const Stmt *S,
return Cond == S && isTrivialExpression(Cond);
}
}
+ return false;
+}
+static bool isTrivialReturn(const CFGBlock *B, const Stmt *S) {
// 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.
@@ -156,30 +158,11 @@ static bool isTrivialReturnOrDoWhile(const CFGBlock *B, const Stmt *S,
if (const ReturnStmt *RS = dyn_cast<ReturnStmt>(CS->getStmt())) {
// Determine if we need to lock at the body of the block
// before the dead return.
- bool LookAtBody = false;
- if (RS == S) {
- LookAtBody = true;
- UK = reachable_code::UK_TrivialReturn;
- }
- else {
- const Expr *RE = RS->getRetValue();
- if (RE) {
- RE = stripExprSugar(RE->IgnoreParenCasts());
- if (RE == S) {
- UK = reachable_code::UK_TrivialReturn;
- LookAtBody = isTrivialExpression(RE);
- }
- }
- }
-
- if (LookAtBody) {
- // More than one predecessor? Restrict the heuristic
- // to looking at return statements directly dominated
- // by a noreturn call.
- if (B->pred_size() != 1)
- return false;
-
- return bodyEndsWithNoReturn(*B->pred_begin());
+ if (RS == S)
+ return true;
+ if (const Expr *RE = RS->getRetValue()) {
+ RE = stripExprSugar(RE->IgnoreParenCasts());
+ return RE == S && isTrivialExpression(RE);
}
}
break;
@@ -606,15 +589,25 @@ void DeadCodeScan::reportDeadCode(const CFGBlock *B,
// The kind of unreachable code found.
reachable_code::UnreachableKind UK = reachable_code::UK_Other;
- // Suppress idiomatic cases of calling a noreturn function just
- // before executing a 'break'. If there is other code after the 'break'
- // in the block then don't suppress the warning.
- if (isBreakPrecededByNoReturn(B, S, UK))
- return;
+ do {
+ // Suppress idiomatic cases of calling a noreturn function just
+ // before executing a 'break'. If there is other code after the 'break'
+ // in the block then don't suppress the warning.
+ if (isa<BreakStmt>(S)) {
+ UK = reachable_code::UK_Break;
+ break;
+ }
- // Suppress trivial 'return' statements that are dead.
- if (UK == reachable_code::UK_Other && isTrivialReturnOrDoWhile(B, S, UK))
- return;
+ if (isTrivialDoWhile(B, S))
+ return;
+
+ // Suppress trivial 'return' statements that are dead.
+ if (isTrivialReturn(B, S)) {
+ UK = reachable_code::UK_TrivialReturn;
+ break;
+ }
+
+ } while(false);
SourceRange R1, R2;
SourceLocation Loc = GetUnreachableLoc(S, R1, R2);
OpenPOWER on IntegriCloud