aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-02-27 20:43:44 +0000
committerTed Kremenek <kremenek@apple.com>2008-02-27 20:43:44 +0000
commitaffb2159712b2373a18a89ed205c1a309d3aec12 (patch)
tree3488c30f13315fc3aeab051f560366d7b1b29af5
parentaecb38368546aa2cdb58d53bbcb3e8ad46365fc6 (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.cpp15
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngine.h19
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(); }