r325052 - Teach Wreturn-type, Wunreachable-code, and alpha.deadcode.UnreachableCode to treat __assume(0) like __builtin_unreachable.
Nico Weber via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 13 13:31:47 PST 2018
Author: nico
Date: Tue Feb 13 13:31:47 2018
New Revision: 325052
URL: http://llvm.org/viewvc/llvm-project?rev=325052&view=rev
Log:
Teach Wreturn-type, Wunreachable-code, and alpha.deadcode.UnreachableCode to treat __assume(0) like __builtin_unreachable.
Fixes PR29134.
https://reviews.llvm.org/D43221
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/Analysis/CFG.cpp
cfe/trunk/lib/Analysis/ReachableCode.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
cfe/trunk/test/Analysis/unreachable-code-path.c
cfe/trunk/test/Sema/return.c
cfe/trunk/test/Sema/warn-unreachable.c
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=325052&r1=325051&r2=325052&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Tue Feb 13 13:31:47 2018
@@ -2357,6 +2357,10 @@ public:
SourceLocation getLocStart() const LLVM_READONLY;
SourceLocation getLocEnd() const LLVM_READONLY;
+ /// Return true if this is a call to __assume() or __builtin_assume() with
+ /// a non-value-dependent constant parameter evaluating as false.
+ bool isBuiltinAssumeFalse(const ASTContext &Ctx) const;
+
bool isCallToStdMove() const {
const FunctionDecl* FD = getDirectCallee();
return getNumArgs() == 1 && FD && FD->isInStdNamespace() &&
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=325052&r1=325051&r2=325052&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Tue Feb 13 13:31:47 2018
@@ -2917,6 +2917,18 @@ bool Expr::isConstantInitializer(ASTCont
return false;
}
+bool CallExpr::isBuiltinAssumeFalse(const ASTContext &Ctx) const {
+ const FunctionDecl* FD = getDirectCallee();
+ if (!FD || (FD->getBuiltinID() != Builtin::BI__assume &&
+ FD->getBuiltinID() != Builtin::BI__builtin_assume))
+ return false;
+
+ const Expr* Arg = getArg(0);
+ bool ArgVal;
+ return !Arg->isValueDependent() &&
+ Arg->EvaluateAsBooleanCondition(ArgVal, Ctx) && !ArgVal;
+}
+
namespace {
/// \brief Look for any side effects within a Stmt.
class SideEffectFinder : public ConstEvaluatedExprVisitor<SideEffectFinder> {
Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=325052&r1=325051&r2=325052&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Tue Feb 13 13:31:47 2018
@@ -2134,7 +2134,7 @@ CFGBlock *CFGBuilder::VisitCallExpr(Call
bool OmitArguments = false;
if (FunctionDecl *FD = C->getDirectCallee()) {
- if (FD->isNoReturn())
+ if (FD->isNoReturn() || C->isBuiltinAssumeFalse(*Context))
NoReturn = true;
if (FD->hasAttr<NoThrowAttr>())
AddEHEdge = false;
Modified: cfe/trunk/lib/Analysis/ReachableCode.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ReachableCode.cpp?rev=325052&r1=325051&r2=325052&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/ReachableCode.cpp (original)
+++ cfe/trunk/lib/Analysis/ReachableCode.cpp Tue Feb 13 13:31:47 2018
@@ -66,6 +66,21 @@ static bool isBuiltinUnreachable(const S
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<CFGStmt> CS = B->back().getAs<CFGStmt>()) {
+ if (const auto *CE = dyn_cast<CallExpr>(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,6 +387,7 @@ namespace {
llvm::BitVector &Reachable;
SmallVector<const CFGBlock *, 10> WorkList;
Preprocessor &PP;
+ ASTContext &C;
typedef SmallVector<std::pair<const CFGBlock *, const Stmt *>, 12>
DeferredLocsTy;
@@ -379,10 +395,10 @@ namespace {
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 @@ void DeadCodeScan::reportDeadCode(const
if (isa<BreakStmt>(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 @@ void FindUnreachableCode(AnalysisDeclCon
if (reachable[block->getBlockID()])
continue;
- DeadCodeScan DS(reachable, PP);
+ DeadCodeScan DS(reachable, PP, AC.getASTContext());
numReachable += DS.scanBackwards(block, CB);
if (numReachable == cfg->getNumBlockIDs())
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp?rev=325052&r1=325051&r2=325052&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp Tue Feb 13 13:31:47 2018
@@ -132,7 +132,8 @@ void UnreachableCodeChecker::checkEndAna
ci != ce; ++ci) {
if (Optional<CFGStmt> S = (*ci).getAs<CFGStmt>())
if (const CallExpr *CE = dyn_cast<CallExpr>(S->getStmt())) {
- if (CE->getBuiltinCallee() == Builtin::BI__builtin_unreachable) {
+ if (CE->getBuiltinCallee() == Builtin::BI__builtin_unreachable ||
+ CE->isBuiltinAssumeFalse(Eng.getContext())) {
foundUnreachable = true;
break;
}
Modified: cfe/trunk/test/Analysis/unreachable-code-path.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/unreachable-code-path.c?rev=325052&r1=325051&r2=325052&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/unreachable-code-path.c (original)
+++ cfe/trunk/test/Analysis/unreachable-code-path.c Tue Feb 13 13:31:47 2018
@@ -63,6 +63,7 @@ void test6(const char *c) {
if (c) return;
if (!c) return;
__builtin_unreachable(); // no-warning
+ __builtin_assume(0); // no-warning
}
// Compile-time constant false positives
Modified: cfe/trunk/test/Sema/return.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/return.c?rev=325052&r1=325051&r2=325052&view=diff
==============================================================================
--- cfe/trunk/test/Sema/return.c (original)
+++ cfe/trunk/test/Sema/return.c Tue Feb 13 13:31:47 2018
@@ -283,6 +283,18 @@ lbl:
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 {\
Modified: cfe/trunk/test/Sema/warn-unreachable.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-unreachable.c?rev=325052&r1=325051&r2=325052&view=diff
==============================================================================
--- cfe/trunk/test/Sema/warn-unreachable.c (original)
+++ cfe/trunk/test/Sema/warn-unreachable.c Tue Feb 13 13:31:47 2018
@@ -468,6 +468,7 @@ int pr13910_foo(int x) {
else
return x;
__builtin_unreachable(); // expected no warning
+ __builtin_assume(0); // expected no warning
}
int pr13910_bar(int x) {
@@ -485,16 +486,19 @@ int pr13910_bar2(int x) {
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
}
More information about the cfe-commits
mailing list