End paths when calling a function marked "noreturn."

llvm-svn: 47690
This commit is contained in:
Ted Kremenek 2008-02-27 20:43:44 +00:00
parent f7146ca3bc
commit 5668972630
2 changed files with 29 additions and 5 deletions

View File

@ -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);
}
}

View File

@ -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(); }