diff options
author | Alex Lorenz <arphaman@gmail.com> | 2017-04-11 15:36:06 +0000 |
---|---|---|
committer | Alex Lorenz <arphaman@gmail.com> | 2017-04-11 15:36:06 +0000 |
commit | 46103e0ede41cef3ddce5f5194c258f6de607acd (patch) | |
tree | 7849b6bc8ecc2aeff65befd45b780d3ffca1aa41 | |
parent | f127821140b107f35aad84b4b214d12bfa19ba8b (diff) | |
download | llvm-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.cpp | 11 | ||||
-rw-r--r-- | clang/test/Sema/warn-unreachable.c | 37 |
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 +} |