forked from OSchip/llvm-project
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. llvm-svn: 92549
This commit is contained in:
parent
646aacb097
commit
de8e7447b6
|
@ -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
|
||||
|
||||
|
|
|
@ -88,8 +88,10 @@ class GRExprEngine : public GRSubEngine {
|
|||
// destructor is called before the rest of the GRExprEngine is destroyed.
|
||||
GRBugReporter BR;
|
||||
|
||||
llvm::OwningPtr<GRTransferFuncs> 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.
|
||||
|
@ -174,6 +172,10 @@ public:
|
|||
/// 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; }
|
||||
|
||||
|
|
|
@ -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<std::pair<void *, Checker *> >::iterator checker_begin() const;
|
||||
std::vector<std::pair<void *, Checker *> >::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<StoreManager> StoreMgr;
|
||||
|
@ -418,25 +413,18 @@ private:
|
|||
/// 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<std::pair<void *, Checker*> > *Checkers;
|
||||
|
||||
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<std::pair<void *, Checker *> > &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<std::pair<void *, Checker *> >::iterator
|
||||
GRState::checker_begin() const {
|
||||
return getStateManager().getCheckers().begin();
|
||||
}
|
||||
|
||||
inline std::vector<std::pair<void *, Checker *> >::iterator
|
||||
GRState::checker_end() const {
|
||||
return getStateManager().getCheckers().end();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const GRState *GRState::add(typename GRStateTrait<T>::key_type K) const {
|
||||
return getStateManager().add<T>(this, K, get_context<T>());
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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*
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -65,25 +65,10 @@ const GRState *SimpleConstraintManager::Assume(const GRState *state,
|
|||
return Assume(state, cast<Loc>(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<std::pair<void *, Checker*> >::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<std::pair<void *, Checker*> >::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,
|
||||
|
|
|
@ -20,8 +20,9 @@
|
|||
namespace clang {
|
||||
|
||||
class SimpleConstraintManager : public ConstraintManager {
|
||||
GRSubEngine &SU;
|
||||
public:
|
||||
SimpleConstraintManager() {}
|
||||
SimpleConstraintManager(GRSubEngine &subengine) : SU(subengine) {}
|
||||
virtual ~SimpleConstraintManager();
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
|
|
|
@ -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<ExplodedNode::Auditor> 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);
|
||||
|
@ -504,10 +504,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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue