aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2011-08-25 19:28:55 +0000
committerTed Kremenek <kremenek@apple.com>2011-08-25 19:28:55 +0000
commite7a2764b2c98859aa42a3fd36d55cd34c7fe883e (patch)
tree0e24e5a06b03348f85dc10ee01919e0735778fb3
parentd10a381d92a60d4f4c126c4e81045c8ad4636a0b (diff)
Teach -Wunreachable-code about dead code caused by macro expansions. This should suppress false positives resulting from 'assert' and friends.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138576 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/ReachableCode.cpp12
-rw-r--r--test/Sema/warn-unreachable.c12
2 files changed, 20 insertions, 4 deletions
diff --git a/lib/Analysis/ReachableCode.cpp b/lib/Analysis/ReachableCode.cpp
index e3194cb6a1..49317718c3 100644
--- a/lib/Analysis/ReachableCode.cpp
+++ b/lib/Analysis/ReachableCode.cpp
@@ -86,12 +86,10 @@ bool DeadCodeScan::isDeadCodeRoot(const clang::CFGBlock *Block) {
}
static bool isValidDeadStmt(const Stmt *S) {
- SourceLocation Loc = S->getLocStart();
- if (!(Loc.isValid() && !Loc.isMacroID()))
+ if (S->getLocStart().isInvalid())
return false;
- if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) {
+ if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(S))
return BO->getOpcode() != BO_Comma;
- }
return true;
}
@@ -144,6 +142,12 @@ unsigned DeadCodeScan::scanBackwards(const clang::CFGBlock *Start,
}
continue;
}
+
+ // Specially handle macro-expanded code.
+ if (S->getLocStart().isMacroID()) {
+ count += clang::reachable_code::ScanReachableFromBlock(Block, Reachable);
+ continue;
+ }
if (isDeadCodeRoot(Block)) {
reportDeadCode(S, CB);
diff --git a/test/Sema/warn-unreachable.c b/test/Sema/warn-unreachable.c
index 80f32cd732..8db36b7100 100644
--- a/test/Sema/warn-unreachable.c
+++ b/test/Sema/warn-unreachable.c
@@ -114,3 +114,15 @@ int test_enum_cases(enum Cases C) {
}
}
+// Handle unreachable code triggered by macro expansions.
+void __myassert_rtn(const char *, const char *, int, const char *) __attribute__((__noreturn__));
+
+#define myassert(e) \
+ (__builtin_expect(!(e), 0) ? __myassert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
+
+void test_assert() {
+ myassert(0 && "unreachable");
+ return; // no-warning
+}
+
+