End paths when calling a function marked "noreturn."


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47690 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Analysis/GRExprEngine.cpp b/Analysis/GRExprEngine.cpp
index f227160..45dbac7 100644
--- a/Analysis/GRExprEngine.cpp
+++ b/Analysis/GRExprEngine.cpp
@@ -550,6 +550,21 @@
     else
       St = EvalCall(CE, cast<LVal>(L), (*DI)->getState());
     
+    // Check for the "noreturn" attribute.
+    
+    if (isa<lval::FuncVal>(L))
+      if (cast<lval::FuncVal>(L).getDecl()->getAttr<NoReturnAttr>()) {
+        
+        NodeTy* N = Builder->generateNode(CE, St, *DI);
+          
+        if (N) {
+          N->markAsSink();
+          NoReturnCalls.insert(N);
+        }
+        
+        continue;
+      }
+    
     Nodify(Dst, CE, *DI, St);
   }
 }
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h
index 13abf53..6b96ccf 100644
--- a/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h
@@ -87,20 +87,25 @@
   
   /// CurrentStmt - The current block-level statement.
   Stmt* CurrentStmt;
+
+  typedef llvm::SmallPtrSet<NodeTy*,2> UninitBranchesTy;  
+  typedef llvm::SmallPtrSet<NodeTy*,2> UninitStoresTy;
+  typedef llvm::SmallPtrSet<NodeTy*,2> BadDerefTy;
+  typedef llvm::SmallPtrSet<NodeTy*,2> BadDividesTy;
+  typedef llvm::SmallPtrSet<NodeTy*,2> NoReturnCallsTy;  
   
   /// UninitBranches - Nodes in the ExplodedGraph that result from
   ///  taking a branch based on an uninitialized value.
-  typedef llvm::SmallPtrSet<NodeTy*,5> UninitBranchesTy;
   UninitBranchesTy UninitBranches;
-
-  typedef llvm::SmallPtrSet<NodeTy*,5> UninitStoresTy;
-  typedef llvm::SmallPtrSet<NodeTy*,5> BadDerefTy;
-  typedef llvm::SmallPtrSet<NodeTy*,5> BadDividesTy;
   
   /// UninitStores - Sinks in the ExplodedGraph that result from
   ///  making a store to an uninitialized lvalue.
   UninitStoresTy UninitStores;
   
+  /// NoReturnCalls - Sinks in the ExplodedGraph that result from
+  //  calling a function with the attribute "noreturn".
+  NoReturnCallsTy NoReturnCalls;
+  
   /// ImplicitNullDeref - Nodes in the ExplodedGraph that result from
   ///  taking a dereference on a symbolic pointer that MAY be NULL.
   BadDerefTy ImplicitNullDeref;
@@ -176,6 +181,10 @@
     return N->isSink() && BadDivides.count(const_cast<NodeTy*>(N)) != 0; 
   }
   
+  bool isNoReturnCall(const NodeTy* N) const {
+    return N->isSink() && NoReturnCalls.count(const_cast<NodeTy*>(N)) != 0;
+  }
+
   typedef BadDerefTy::iterator null_deref_iterator;
   null_deref_iterator null_derefs_begin() { return ExplicitNullDeref.begin(); }
   null_deref_iterator null_derefs_end() { return ExplicitNullDeref.end(); }