aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordy Rose <jediknil@belkadan.com>2010-07-27 03:39:53 +0000
committerJordy Rose <jediknil@belkadan.com>2010-07-27 03:39:53 +0000
commit5e04bdde8e74d991feffe9cf95d731f7e473dbb7 (patch)
tree5be5d97ae63f9d16690e687c80a0a87617b52414
parent94e3d1f0349634235606be77c08b3a48a6d563d6 (diff)
Don't warn about unreachable code if the block starts with __builtin_unreachable().
The next step is to warn if a block labeled unreachable is, in fact, reachable. Somewhat related to PR810. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109487 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Checker/UnreachableCodeChecker.cpp17
-rw-r--r--test/Analysis/unreachable-code-path.c6
2 files changed, 22 insertions, 1 deletions
diff --git a/lib/Checker/UnreachableCodeChecker.cpp b/lib/Checker/UnreachableCodeChecker.cpp
index 0af49a33fb..9ee3d02d26 100644
--- a/lib/Checker/UnreachableCodeChecker.cpp
+++ b/lib/Checker/UnreachableCodeChecker.cpp
@@ -10,7 +10,7 @@
// path-sensitive analysis. We mark any path visited, and then walk the CFG as a
// post-analysis to determine what was never visited.
//
-// A similar flow-sensitive only check exists in Analysis/UnreachableCode.cpp
+// A similar flow-sensitive only check exists in Analysis/ReachableCode.cpp
//===----------------------------------------------------------------------===//
#include "clang/Checker/PathSensitive/CheckerVisitor.h"
@@ -19,6 +19,7 @@
#include "clang/Checker/BugReporter/BugReporter.h"
#include "GRExprEngineExperimentalChecks.h"
#include "clang/AST/StmtCXX.h"
+#include "clang/Basic/Builtins.h"
#include "llvm/ADT/SmallPtrSet.h"
// The number of CFGBlock pointers we want to reserve memory for. This is used
@@ -79,6 +80,8 @@ void UnreachableCodeChecker::VisitEndAnalysis(ExplodedGraph &G,
if (!C)
return;
+ ASTContext &Ctx = B.getContext();
+
// Find CFGBlocks that were not covered by any node
for (CFG::const_iterator I = C->begin(); I != C->end(); ++I) {
const CFGBlock *CB = *I;
@@ -96,6 +99,18 @@ void UnreachableCodeChecker::VisitEndAnalysis(ExplodedGraph &G,
if (S.getBegin().isMacroID() || S.getEnd().isMacroID() || S.isInvalid()
|| SL.isInvalid())
continue;
+
+ // Special case for __builtin_unreachable.
+ // FIXME: This should be extended to include other unreachable markers,
+ // such as llvm_unreachable.
+ if (!CB->empty()) {
+ const Stmt *First = CB->front();
+ if (const CallExpr *CE = dyn_cast<CallExpr>(First)) {
+ if (CE->isBuiltinCall(Ctx) == Builtin::BI__builtin_unreachable)
+ continue;
+ }
+ }
+
B.EmitBasicReport("Unreachable code", "This statement is never executed",
SL, S);
}
diff --git a/test/Analysis/unreachable-code-path.c b/test/Analysis/unreachable-code-path.c
index cfe0408c3f..e7e1d0b3eb 100644
--- a/test/Analysis/unreachable-code-path.c
+++ b/test/Analysis/unreachable-code-path.c
@@ -53,3 +53,9 @@ void test5(const char *c) {
}
}
+void test6(const char *c) {
+ if (c) return;
+ if (!c) return;
+ __builtin_unreachable(); // no-warning
+}
+