From: Ted Kremenek Date: Mon, 30 Mar 2009 17:53:05 +0000 (+0000) Subject: Add version of GRExprEngine::AddCheck that registered a GRSimpleAPICheck that X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=536aa02b29ea2bdffff2cc507ed04f6b56737116;p=clang Add version of GRExprEngine::AddCheck that registered a GRSimpleAPICheck that will be called for every expression in a basic block. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68041 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 4c0abdcb09..1dee5d267a 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -395,6 +395,7 @@ public: } void AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C); + void AddCheck(GRSimpleAPICheck* A); /// ProcessStmt - Called by GRCoreEngine. Used to generate new successor /// nodes by processing the 'effects' of a block-level statement. diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 41f6453a90..2b5808f562 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -46,9 +46,11 @@ class VISIBILITY_HIDDEN MappedBatchAuditor : public GRSimpleAPICheck { MapTy M; Checks::Factory F; + Checks AllStmts; public: - MappedBatchAuditor(llvm::BumpPtrAllocator& Alloc) : F(Alloc) {} + MappedBatchAuditor(llvm::BumpPtrAllocator& Alloc) : + F(Alloc), AllStmts(F.GetEmptyList()) {} virtual ~MappedBatchAuditor() { llvm::DenseSet AlreadyVisited; @@ -66,26 +68,33 @@ public: } } - void AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C) { + void AddCheck(GRSimpleAPICheck *A, Stmt::StmtClass C) { assert (A && "Check cannot be null."); void* key = reinterpret_cast((uintptr_t) C); MapTy::iterator I = M.find(key); M[key] = F.Concat(A, I == M.end() ? F.GetEmptyList() : I->second); } + + void AddCheck(GRSimpleAPICheck *A) { + assert (A && "Check cannot be null."); + AllStmts = F.Concat(A, AllStmts); + } virtual bool Audit(NodeTy* N, GRStateManager& VMgr) { + // First handle the auditors that accept all statements. + bool isSink = false; + for (Checks::iterator I = AllStmts.begin(), E = AllStmts.end(); I!=E; ++I) + isSink |= (*I)->Audit(N, VMgr); + + // Next handle the auditors that accept only specific statements. Stmt* S = cast(N->getLocation()).getStmt(); void* key = reinterpret_cast((uintptr_t) S->getStmtClass()); MapTy::iterator MI = M.find(key); - - if (MI == M.end()) - return false; - - bool isSink = false; + if (MI != M.end()) { + for (Checks::iterator I=MI->second.begin(), E=MI->second.end(); I!=E; ++I) + isSink |= (*I)->Audit(N, VMgr); + } - for (Checks::iterator I=MI->second.begin(), E=MI->second.end(); I!=E; ++I) - isSink |= (*I)->Audit(N, VMgr); - return isSink; } }; @@ -143,6 +152,13 @@ void GRExprEngine::AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C) { ((MappedBatchAuditor*) BatchAuditor.get())->AddCheck(A, C); } +void GRExprEngine::AddCheck(GRSimpleAPICheck *A) { + if (!BatchAuditor) + BatchAuditor.reset(new MappedBatchAuditor(getGraph().getAllocator())); + + ((MappedBatchAuditor*) BatchAuditor.get())->AddCheck(A); +} + const GRState* GRExprEngine::getInitialState() { return StateMgr.getInitialState(); }