thakis created this revision.
thakis added reviewers: rsmith, rnk.
Herald added a subscriber: whisperity.
Fixes PR29134.
https://reviews.llvm.org/D43221
Files:
include/clang/AST/Expr.h
lib/AST/Expr.cpp
lib/Analysis/CFG.cpp
lib/Analysis/ReachableCode.cpp
lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
test/Analysis/unreachable-code-path.c
test/Sema/return.c
test/Sema/warn-unreachable.c
Index: test/Sema/warn-unreachable.c
===
--- test/Sema/warn-unreachable.c
+++ test/Sema/warn-unreachable.c
@@ -468,6 +468,7 @@
else
return x;
__builtin_unreachable(); // expected no warning
+ __builtin_assume(0); // expected no warning
}
int pr13910_bar(int x) {
@@ -485,16 +486,19 @@
return x;
pr13910_foo(x); // expected-warning {{code will never be executed}}
__builtin_unreachable(); // expected no warning
+ __builtin_assume(0); // expected no warning
pr13910_foo(x); // expected-warning {{code will never be executed}}
}
void pr13910_noreturn() {
raze();
__builtin_unreachable(); // expected no warning
+ __builtin_assume(0); // expected no warning
}
void pr13910_assert() {
myassert(0 && "unreachable");
return;
__builtin_unreachable(); // expected no warning
+ __builtin_assume(0); // expected no warning
}
Index: test/Sema/return.c
===
--- test/Sema/return.c
+++ test/Sema/return.c
@@ -283,6 +283,18 @@
goto lbl;
}
+int test36a(int b) {
+ if (b)
+return 43;
+ __builtin_unreachable();
+}
+
+int test36b(int b) {
+ if (b)
+return 43;
+ __builtin_assume(0);
+}
+
// PR19074.
void abort(void) __attribute__((noreturn));
#define av_assert0(cond) do {\
Index: test/Analysis/unreachable-code-path.c
===
--- test/Analysis/unreachable-code-path.c
+++ test/Analysis/unreachable-code-path.c
@@ -63,6 +63,7 @@
if (c) return;
if (!c) return;
__builtin_unreachable(); // no-warning
+ __builtin_assume(0); // no-warning
}
// Compile-time constant false positives
Index: lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
===
--- lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
+++ lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
@@ -132,7 +132,8 @@
ci != ce; ++ci) {
if (Optional S = (*ci).getAs())
if (const CallExpr *CE = dyn_cast(S->getStmt())) {
-if (CE->getBuiltinCallee() == Builtin::BI__builtin_unreachable) {
+if (CE->getBuiltinCallee() == Builtin::BI__builtin_unreachable ||
+CE->isBuiltinAssumeFalse(Eng.getContext())) {
foundUnreachable = true;
break;
}
Index: lib/Analysis/ReachableCode.cpp
===
--- lib/Analysis/ReachableCode.cpp
+++ lib/Analysis/ReachableCode.cpp
@@ -66,6 +66,21 @@
return false;
}
+static bool isBuiltinAssumeFalse(const CFGBlock *B, const Stmt *S,
+ ASTContext &C) {
+ if (B->empty()) {
+// Happens if S is B's terminator and B contains nothing else
+// (e.g. a CFGBlock containing only a goto).
+return false;
+ }
+ if (Optional CS = B->back().getAs()) {
+if (const auto *CE = dyn_cast(CS->getStmt())) {
+ return CE->getCallee()->IgnoreCasts() == S && CE->isBuiltinAssumeFalse(C);
+}
+ }
+ 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
@@ -372,17 +387,18 @@
llvm::BitVector &Reachable;
SmallVector WorkList;
Preprocessor &PP;
+ASTContext &C;
typedef SmallVector, 12>
DeferredLocsTy;
DeferredLocsTy DeferredLocs;
public:
-DeadCodeScan(llvm::BitVector &reachable, Preprocessor &PP)
+DeadCodeScan(llvm::BitVector &reachable, Preprocessor &PP, ASTContext &C)
: Visited(reachable.size()),
Reachable(reachable),
- PP(PP) {}
+ PP(PP), C(C) {}
void enqueue(const CFGBlock *block);
unsigned scanBackwards(const CFGBlock *Start,
@@ -600,7 +616,8 @@
if (isa(S)) {
UK = reachable_code::UK_Break;
- } else if (isTrivialDoWhile(B, S) || isBuiltinUnreachable(S)) {
+ } else if (isTrivialDoWhile(B, S) || isBuiltinUnreachable(S) ||
+ isBuiltinAssumeFalse(B, S, C)) {
return;
}
else if (isDeadReturn(B, S)) {
@@ -693,7 +710,7 @@
if (reachable[block->getBlockID()])
continue;
-DeadCodeScan DS(reachable, PP);
+DeadCodeScan DS(reachable, PP, AC.getASTContext());
numReachable += DS.scanBackwards(block, CB);
if (numReachable == cfg->getNumBlockIDs())
Index: lib/Analysis/CFG.cpp
=