[PATCH] D43221: Teach Wreturn-type, Wunreachable-code, and alpha.deadcode.UnreachableCode to treat __assume(0) like __builtin_unreachable.

2018-02-13 Thread Nico Weber via Phabricator via cfe-commits
thakis closed this revision.
thakis added a comment.

r325052, thanks!


https://reviews.llvm.org/D43221



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43221: Teach Wreturn-type, Wunreachable-code, and alpha.deadcode.UnreachableCode to treat __assume(0) like __builtin_unreachable.

2018-02-13 Thread Reid Kleckner via Phabricator via cfe-commits
rnk accepted this revision.
rnk added a comment.
This revision is now accepted and ready to land.

lgtm

It looks like we already generate llvm.assume() for these and that eventually 
behaves the same as the unreachable instruction. Neat. :)


https://reviews.llvm.org/D43221



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43221: Teach Wreturn-type, Wunreachable-code, and alpha.deadcode.UnreachableCode to treat __assume(0) like __builtin_unreachable.

2018-02-12 Thread Nico Weber via Phabricator via cfe-commits
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
=