diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-02-27 20:43:44 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-02-27 20:43:44 +0000 |
commit | affb2159712b2373a18a89ed205c1a309d3aec12 (patch) | |
tree | 3488c30f13315fc3aeab051f560366d7b1b29af5 | |
parent | aecb38368546aa2cdb58d53bbcb3e8ad46365fc6 (diff) |
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
-rw-r--r-- | Analysis/GRExprEngine.cpp | 15 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRExprEngine.h | 19 |
2 files changed, 29 insertions, 5 deletions
diff --git a/Analysis/GRExprEngine.cpp b/Analysis/GRExprEngine.cpp index f227160bfb..45dbac7045 100644 --- a/Analysis/GRExprEngine.cpp +++ b/Analysis/GRExprEngine.cpp @@ -550,6 +550,21 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred, 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 13abf53cb3..6b96ccf201 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -87,20 +87,25 @@ protected: /// 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 @@ public: 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(); } |