aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2017-04-11 15:36:06 +0000
committerAlex Lorenz <arphaman@gmail.com>2017-04-11 15:36:06 +0000
commit46103e0ede41cef3ddce5f5194c258f6de607acd (patch)
tree7849b6bc8ecc2aeff65befd45b780d3ffca1aa41
parentf127821140b107f35aad84b4b214d12bfa19ba8b (diff)
downloadllvm-46103e0ede41cef3ddce5f5194c258f6de607acd.zip
llvm-46103e0ede41cef3ddce5f5194c258f6de607acd.tar.gz
llvm-46103e0ede41cef3ddce5f5194c258f6de607acd.tar.bz2
Fix PR13910: Don't warn that __builtin_unreachable() is unreachable
Differential Revision: https://reviews.llvm.org/D25321 llvm-svn: 299951
-rw-r--r--clang/lib/Analysis/ReachableCode.cpp11
-rw-r--r--clang/test/Sema/warn-unreachable.c37
2 files changed, 46 insertions, 2 deletions
diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp
index 8a96744..60724ea 100644
--- a/clang/lib/Analysis/ReachableCode.cpp
+++ b/clang/lib/Analysis/ReachableCode.cpp
@@ -58,6 +58,14 @@ static bool isTrivialDoWhile(const CFGBlock *B, const Stmt *S) {
return false;
}
+static bool isBuiltinUnreachable(const Stmt *S) {
+ if (const auto *DRE = dyn_cast<DeclRefExpr>(S))
+ if (const auto *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl()))
+ return FDecl->getIdentifier() &&
+ FDecl->getBuiltinID() == Builtin::BI__builtin_unreachable;
+ return false;
+}
+
static bool isDeadReturn(const CFGBlock *B, const Stmt *S) {
// Look to see if the current control flow ends with a 'return', and see if
// 'S' is a substatement. The 'return' may not be the last element in the
@@ -592,8 +600,7 @@ void DeadCodeScan::reportDeadCode(const CFGBlock *B,
if (isa<BreakStmt>(S)) {
UK = reachable_code::UK_Break;
- }
- else if (isTrivialDoWhile(B, S)) {
+ } else if (isTrivialDoWhile(B, S) || isBuiltinUnreachable(S)) {
return;
}
else if (isDeadReturn(B, S)) {
diff --git a/clang/test/Sema/warn-unreachable.c b/clang/test/Sema/warn-unreachable.c
index 1f79216..440aa0a 100644
--- a/clang/test/Sema/warn-unreachable.c
+++ b/clang/test/Sema/warn-unreachable.c
@@ -461,3 +461,40 @@ void testTrueFalseMacros() {
if (!true) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
testTrueFalseMacros(); // expected-warning {{code will never be executed}}
}
+
+int pr13910_foo(int x) {
+ if (x == 1)
+ return 0;
+ else
+ return x;
+ __builtin_unreachable(); // expected no warning
+}
+
+int pr13910_bar(int x) {
+ switch (x) {
+ default:
+ return x + 1;
+ }
+ pr13910_foo(x); // expected-warning {{code will never be executed}}
+}
+
+int pr13910_bar2(int x) {
+ if (x == 1)
+ return 0;
+ else
+ return x;
+ pr13910_foo(x); // expected-warning {{code will never be executed}}
+ __builtin_unreachable(); // expected no warning
+ pr13910_foo(x); // expected-warning {{code will never be executed}}
+}
+
+void pr13910_noreturn() {
+ raze();
+ __builtin_unreachable(); // expected no warning
+}
+
+void pr13910_assert() {
+ myassert(0 && "unreachable");
+ return;
+ __builtin_unreachable(); // expected no warning
+}