From: Ted Kremenek Date: Tue, 5 Jan 2010 00:15:18 +0000 (+0000) Subject: Remove references to 'Checker' and 'GRTransferFuncs' from X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=32a58084a4c53e6938dd81bfce224db25a5976d1;p=clang Remove references to 'Checker' and 'GRTransferFuncs' from GRStateManager. Having these references was an abstraction violation, as they really should only be known about GRExprEngine. This change required adding a new 'ProcessAssume' callback in GRSubEngine. GRExprEngine implements this callback by calling 'EvalAssume' on all registered Checker objects as well as the registered GRTransferFunc object. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92549 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/ConstraintManager.h b/include/clang/Analysis/PathSensitive/ConstraintManager.h index 37a14083ac..c8292802ae 100644 --- a/include/clang/Analysis/PathSensitive/ConstraintManager.h +++ b/include/clang/Analysis/PathSensitive/ConstraintManager.h @@ -25,6 +25,7 @@ namespace clang { class GRState; class GRStateManager; +class GRSubEngine; class SVal; class ConstraintManager { @@ -64,8 +65,10 @@ public: virtual bool canReasonAbout(SVal X) const = 0; }; -ConstraintManager* CreateBasicConstraintManager(GRStateManager& statemgr); -ConstraintManager* CreateRangeConstraintManager(GRStateManager& statemgr); +ConstraintManager* CreateBasicConstraintManager(GRStateManager& statemgr, + GRSubEngine &subengine); +ConstraintManager* CreateRangeConstraintManager(GRStateManager& statemgr, + GRSubEngine &subengine); } // end clang namespace diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index e05c624384..1a420e41d1 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -87,9 +87,11 @@ class GRExprEngine : public GRSubEngine { // this object be placed at the very end of member variables so that its // destructor is called before the rest of the GRExprEngine is destroyed. GRBugReporter BR; + + llvm::OwningPtr TF; public: - GRExprEngine(AnalysisManager &mgr); + GRExprEngine(AnalysisManager &mgr, GRTransferFuncs *tf); ~GRExprEngine(); @@ -104,18 +106,14 @@ public: SValuator &getSValuator() { return SVator; } - GRTransferFuncs& getTF() { return *StateMgr.TF; } + GRTransferFuncs& getTF() { return *TF; } BugReporter& getBugReporter() { return BR; } GRStmtNodeBuilder &getBuilder() { assert(Builder); return *Builder; } - /// setTransferFunctions - void setTransferFunctionsAndCheckers(GRTransferFuncs* tf); - - void setTransferFunctions(GRTransferFuncs& tf) { - setTransferFunctionsAndCheckers(&tf); - } + // FIXME: Remove once GRTransferFuncs is no longer referenced. + void setTransferFunction(GRTransferFuncs* tf); /// ViewGraph - Visualize the ExplodedGraph created by executing the /// simulation. @@ -173,6 +171,10 @@ public: /// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path /// nodes when the control reaches the end of a function. void ProcessEndPath(GREndPathNodeBuilder& builder); + + /// EvalAssume - Callback function invoked by the ConstraintManager when + /// making assumptions about state values. + const GRState *ProcessAssume(const GRState *state, SVal cond, bool assumption); GRStateManager& getStateManager() { return StateMgr; } const GRStateManager& getStateManager() const { return StateMgr; } diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h index 424b0d77e8..11cdac0e96 100644 --- a/include/clang/Analysis/PathSensitive/GRState.h +++ b/include/clang/Analysis/PathSensitive/GRState.h @@ -40,10 +40,10 @@ namespace clang { class GRStateManager; -class GRTransferFuncs; class Checker; -typedef ConstraintManager* (*ConstraintManagerCreator)(GRStateManager&); +typedef ConstraintManager* (*ConstraintManagerCreator)(GRStateManager&, + GRSubEngine&); typedef StoreManager* (*StoreManagerCreator)(GRStateManager&); //===----------------------------------------------------------------------===// @@ -159,10 +159,6 @@ public: BasicValueFactory &getBasicVals() const; SymbolManager &getSymbolManager() const; - GRTransferFuncs &getTransferFuncs() const; - - std::vector >::iterator checker_begin() const; - std::vector >::iterator checker_end() const; //==---------------------------------------------------------------------==// // Constraints on values. @@ -391,9 +387,8 @@ public: //===----------------------------------------------------------------------===// class GRStateManager { - friend class GRExprEngine; friend class GRState; - + friend class GRExprEngine; // FIXME: Remove. private: EnvironmentManager EnvMgr; llvm::OwningPtr StoreMgr; @@ -416,27 +411,20 @@ private: ValueManager ValueMgr; /// Alloc - A BumpPtrAllocator to allocate states. - llvm::BumpPtrAllocator& Alloc; - - /// TF - Object that represents a bundle of transfer functions - /// for manipulating and creating SVals. - GRTransferFuncs* TF; - - /// Reference to all checkers in GRExprEngine. - std::vector > *Checkers; + llvm::BumpPtrAllocator &Alloc; public: - GRStateManager(ASTContext& Ctx, StoreManagerCreator CreateStoreManager, ConstraintManagerCreator CreateConstraintManager, - llvm::BumpPtrAllocator& alloc) + llvm::BumpPtrAllocator& alloc, + GRSubEngine &subeng) : EnvMgr(alloc), GDMFactory(alloc), ValueMgr(alloc, Ctx, *this), Alloc(alloc) { StoreMgr.reset((*CreateStoreManager)(*this)); - ConstraintMgr.reset((*CreateConstraintManager)(*this)); + ConstraintMgr.reset((*CreateConstraintManager)(*this, subeng)); } ~GRStateManager(); @@ -446,10 +434,6 @@ public: ASTContext &getContext() { return ValueMgr.getContext(); } const ASTContext &getContext() const { return ValueMgr.getContext(); } - GRTransferFuncs& getTransferFuncs() { return *TF; } - - std::vector > &getCheckers() { return *Checkers;} - BasicValueFactory &getBasicVals() { return ValueMgr.getBasicValueFactory(); } @@ -702,20 +686,6 @@ inline SymbolManager &GRState::getSymbolManager() const { return getStateManager().getSymbolManager(); } -inline GRTransferFuncs &GRState::getTransferFuncs() const { - return getStateManager().getTransferFuncs(); -} - -inline std::vector >::iterator -GRState::checker_begin() const { - return getStateManager().getCheckers().begin(); -} - -inline std::vector >::iterator -GRState::checker_end() const { - return getStateManager().getCheckers().end(); -} - template const GRState *GRState::add(typename GRStateTrait::key_type K) const { return getStateManager().add(this, K, get_context()); diff --git a/include/clang/Analysis/PathSensitive/GRSubEngine.h b/include/clang/Analysis/PathSensitive/GRSubEngine.h index 330742d8bf..5b383fae9b 100644 --- a/include/clang/Analysis/PathSensitive/GRSubEngine.h +++ b/include/clang/Analysis/PathSensitive/GRSubEngine.h @@ -13,6 +13,8 @@ #ifndef LLVM_CLANG_ANALYSIS_GRSUBENGINE_H #define LLVM_CLANG_ANALYSIS_GRSUBENGINE_H +#include "clang/Analysis/PathSensitive/SVals.h" + namespace clang { class Stmt; @@ -62,8 +64,12 @@ public: /// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path /// nodes when the control reaches the end of a function. virtual void ProcessEndPath(GREndPathNodeBuilder& builder) = 0; + + /// EvalAssume - Called by ConstraintManager. Used to call checker-specific + /// logic for handling assumptions on symbolic values. + virtual const GRState* ProcessAssume(const GRState *state, + SVal cond, bool assumption) = 0; }; - } #endif diff --git a/lib/Analysis/BasicConstraintManager.cpp b/lib/Analysis/BasicConstraintManager.cpp index 6c3f7b2245..6dfc470530 100644 --- a/lib/Analysis/BasicConstraintManager.cpp +++ b/lib/Analysis/BasicConstraintManager.cpp @@ -49,8 +49,9 @@ class BasicConstraintManager : public SimpleConstraintManager { GRState::IntSetTy::Factory ISetFactory; public: - BasicConstraintManager(GRStateManager& statemgr) - : ISetFactory(statemgr.getAllocator()) {} + BasicConstraintManager(GRStateManager &statemgr, GRSubEngine &subengine) + : SimpleConstraintManager(subengine), + ISetFactory(statemgr.getAllocator()) {} const GRState* AssumeSymNE(const GRState* state, SymbolRef sym, const llvm::APSInt& V); @@ -88,9 +89,9 @@ public: } // end anonymous namespace -ConstraintManager* clang::CreateBasicConstraintManager(GRStateManager& StateMgr) -{ - return new BasicConstraintManager(StateMgr); +ConstraintManager* clang::CreateBasicConstraintManager(GRStateManager& statemgr, + GRSubEngine &subengine) { + return new BasicConstraintManager(statemgr, subengine); } const GRState* diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 2ce8edd1cc..013bed04f9 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -300,23 +300,27 @@ static void RegisterInternalChecks(GRExprEngine &Eng) { RegisterOSAtomicChecker(Eng); } -GRExprEngine::GRExprEngine(AnalysisManager &mgr) +GRExprEngine::GRExprEngine(AnalysisManager &mgr, GRTransferFuncs *tf) : AMgr(mgr), CoreEngine(mgr.getASTContext(), *this), G(CoreEngine.getGraph()), Builder(NULL), StateMgr(G.getContext(), mgr.getStoreManagerCreator(), - mgr.getConstraintManagerCreator(), G.getAllocator()), + mgr.getConstraintManagerCreator(), G.getAllocator(), + *this), SymMgr(StateMgr.getSymbolManager()), ValMgr(StateMgr.getValueManager()), SVator(ValMgr.getSValuator()), CurrentStmt(NULL), NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL), RaiseSel(GetNullarySelector("raise", G.getContext())), - BR(mgr, *this) -{ + BR(mgr, *this), TF(tf) { // Register internal checks. RegisterInternalChecks(*this); + + // FIXME: Eventually remove the TF object entirely. + TF->RegisterChecks(*this); + TF->RegisterPrinters(getStateManager().Printers); } GRExprEngine::~GRExprEngine() { @@ -330,13 +334,6 @@ GRExprEngine::~GRExprEngine() { // Utility methods. //===----------------------------------------------------------------------===// -void GRExprEngine::setTransferFunctionsAndCheckers(GRTransferFuncs* tf) { - StateMgr.TF = tf; - StateMgr.Checkers = &Checkers; - tf->RegisterChecks(*this); - tf->RegisterPrinters(getStateManager().Printers); -} - void GRExprEngine::AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C) { if (!BatchAuditor) BatchAuditor.reset(new MappedBatchAuditor(getGraph().getAllocator())); @@ -415,6 +412,25 @@ const GRState* GRExprEngine::getInitialState(const LocationContext *InitLoc) { // Top-level transfer function logic (Dispatcher). //===----------------------------------------------------------------------===// +/// EvalAssume - Called by ConstraintManager. Used to call checker-specific +/// logic for handling assumptions on symbolic values. +const GRState *GRExprEngine::ProcessAssume(const GRState *state, SVal cond, + bool assumption) { + for (CheckersOrdered::iterator I = Checkers.begin(), E = Checkers.end(); + I != E; ++I) { + + if (!state) + return NULL; + + state = I->second->EvalAssume(state, cond, assumption); + } + + if (!state) + return NULL; + + return TF->EvalAssume(state, cond, assumption); +} + void GRExprEngine::ProcessStmt(CFGElement CE, GRStmtNodeBuilder& builder) { CurrentStmt = CE.getStmt(); PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), diff --git a/lib/Analysis/RangeConstraintManager.cpp b/lib/Analysis/RangeConstraintManager.cpp index 7330b62614..2cf3dfb6d0 100644 --- a/lib/Analysis/RangeConstraintManager.cpp +++ b/lib/Analysis/RangeConstraintManager.cpp @@ -234,7 +234,8 @@ namespace { class RangeConstraintManager : public SimpleConstraintManager{ RangeSet GetRange(const GRState *state, SymbolRef sym); public: - RangeConstraintManager() {} + RangeConstraintManager(GRSubEngine &subengine) + : SimpleConstraintManager(subengine) {} const GRState* AssumeSymNE(const GRState* St, SymbolRef sym, const llvm::APSInt& V); @@ -273,8 +274,9 @@ private: } // end anonymous namespace -ConstraintManager* clang::CreateRangeConstraintManager(GRStateManager&) { - return new RangeConstraintManager(); +ConstraintManager* clang::CreateRangeConstraintManager(GRStateManager&, + GRSubEngine &subeng) { + return new RangeConstraintManager(subeng); } const llvm::APSInt* RangeConstraintManager::getSymVal(const GRState* St, diff --git a/lib/Analysis/SimpleConstraintManager.cpp b/lib/Analysis/SimpleConstraintManager.cpp index 23c3b41758..eca20d574d 100644 --- a/lib/Analysis/SimpleConstraintManager.cpp +++ b/lib/Analysis/SimpleConstraintManager.cpp @@ -65,25 +65,10 @@ const GRState *SimpleConstraintManager::Assume(const GRState *state, return Assume(state, cast(Cond), Assumption); } -const GRState *SimpleConstraintManager::Assume(const GRState *state, Loc Cond, - bool Assumption) { - - state = AssumeAux(state, Cond, Assumption); - - // EvalAssume is used to call into the GRTransferFunction object to perform - // any checker-specific update of the state based on this assumption being - // true or false. - - if (!state) - return 0; - - std::vector >::iterator - I = state->checker_begin(), E = state->checker_end(); - - for (; I != E; ++I) { - state = I->second->EvalAssume(state, Cond, Assumption); - } - return state->getTransferFuncs().EvalAssume(state, Cond, Assumption); +const GRState *SimpleConstraintManager::Assume(const GRState *state, Loc cond, + bool assumption) { + state = AssumeAux(state, cond, assumption); + return SU.ProcessAssume(state, cond, assumption); } const GRState *SimpleConstraintManager::AssumeAux(const GRState *state, @@ -130,26 +115,10 @@ const GRState *SimpleConstraintManager::AssumeAux(const GRState *state, } const GRState *SimpleConstraintManager::Assume(const GRState *state, - NonLoc Cond, - bool Assumption) { - - state = AssumeAux(state, Cond, Assumption); - - // EvalAssume is used to call into the GRTransferFunction object to perform - // any checker-specific update of the state based on this assumption being - // true or false. - - if (!state) - return 0; - - std::vector >::iterator - I = state->checker_begin(), E = state->checker_end(); - - for (; I != E; ++I) { - state = I->second->EvalAssume(state, Cond, Assumption); - } - - return state->getTransferFuncs().EvalAssume(state, Cond, Assumption); + NonLoc cond, + bool assumption) { + state = AssumeAux(state, cond, assumption); + return SU.ProcessAssume(state, cond, assumption); } const GRState *SimpleConstraintManager::AssumeAux(const GRState *state, diff --git a/lib/Analysis/SimpleConstraintManager.h b/lib/Analysis/SimpleConstraintManager.h index 0c58440ac0..8182398319 100644 --- a/lib/Analysis/SimpleConstraintManager.h +++ b/lib/Analysis/SimpleConstraintManager.h @@ -20,8 +20,9 @@ namespace clang { class SimpleConstraintManager : public ConstraintManager { + GRSubEngine &SU; public: - SimpleConstraintManager() {} + SimpleConstraintManager(GRSubEngine &subengine) : SU(subengine) {} virtual ~SimpleConstraintManager(); //===------------------------------------------------------------------===// diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp index 6824d8f4eb..ad152d33bc 100644 --- a/lib/Frontend/AnalysisConsumer.cpp +++ b/lib/Frontend/AnalysisConsumer.cpp @@ -363,7 +363,7 @@ static void ActionGRExprEngine(AnalysisConsumer &C, AnalysisManager& mgr, if (!mgr.getLiveVariables(D)) return; - GRExprEngine Eng(mgr); + GRExprEngine Eng(mgr, TF.take()); if (C.Opts.EnableExperimentalInternalChecks) RegisterExperimentalInternalChecks(Eng); @@ -373,8 +373,6 @@ static void ActionGRExprEngine(AnalysisConsumer &C, AnalysisManager& mgr, if (C.Opts.EnableExperimentalChecks) RegisterExperimentalChecks(Eng); - Eng.setTransferFunctionsAndCheckers(tf); - // Set the graph auditor. llvm::OwningPtr Auditor; if (mgr.shouldVisualizeUbigraph()) { @@ -494,7 +492,9 @@ static void ActionInlineCall(AnalysisConsumer &C, AnalysisManager &mgr, // Display progress. C.DisplayFunction(D); - GRExprEngine Eng(mgr); + // FIXME: Make a fake transfer function. The GRTransferFunc interface + // eventually will be removed. + GRExprEngine Eng(mgr, new GRTransferFuncs()); if (C.Opts.EnableExperimentalInternalChecks) RegisterExperimentalInternalChecks(Eng); @@ -503,10 +503,6 @@ static void ActionInlineCall(AnalysisConsumer &C, AnalysisManager &mgr, if (C.Opts.EnableExperimentalChecks) RegisterExperimentalChecks(Eng); - - // Make a fake transfer function. The GRTransferFunc interface will be - // removed. - Eng.setTransferFunctionsAndCheckers(new GRTransferFuncs()); // Register call inliner as the last checker. RegisterCallInliner(Eng);