[cfe-commits] r54835 - in /cfe/trunk: include/clang/Analysis/PathSensitive/GRState.h include/clang/Analysis/PathSensitive/GRTransferFuncs.h lib/Analysis/CFRefCount.cpp lib/Analysis/GRExprEngine.cpp lib/Analysis/GRState.cpp
Ted Kremenek
kremenek at apple.com
Fri Aug 15 17:49:49 PDT 2008
Author: kremenek
Date: Fri Aug 15 19:49:49 2008
New Revision: 54835
URL: http://llvm.org/viewvc/llvm-project?rev=54835&view=rev
Log:
GRState:
- Remove ConstNotEq from GRState/GRStateManager (!= tracking uses GDM instead).
- GRStateManager now can book-keep "contexts" (e.g., factory objects) for uses
with data elements stored into the GDM.
- Refactor pretty-printing of states to use GRState::Printer objects
exclusively. This removed a huge amount of pretty-printing logic from
GRExprEngine.
CFRefCount
- Simplified some API calls based on refinements to the GDM api.
Modified:
cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h
cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
cfe/trunk/lib/Analysis/CFRefCount.cpp
cfe/trunk/lib/Analysis/GRExprEngine.cpp
cfe/trunk/lib/Analysis/GRState.cpp
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h?rev=54835&r1=54834&r2=54835&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h Fri Aug 15 19:49:49 2008
@@ -58,7 +58,6 @@
// Typedefs.
typedef llvm::ImmutableSet<llvm::APSInt*> IntSetTy;
typedef llvm::ImmutableMap<void*, void*> GenericDataMap;
- typedef llvm::ImmutableMap<SymbolID,IntSetTy> ConstNotEqTy;
typedef llvm::ImmutableMap<SymbolID,const llvm::APSInt*> ConstEqTy;
typedef GRStateManager ManagerTy;
@@ -74,18 +73,15 @@
// FIXME: Make these private.
public:
GenericDataMap GDM;
- ConstNotEqTy ConstNotEq;
ConstEqTy ConstEq;
public:
/// This ctor is used when creating the first GRState object.
- GRState(const Environment& env, Store st, GenericDataMap gdm,
- ConstNotEqTy CNE, ConstEqTy CE)
+ GRState(const Environment& env, Store st, GenericDataMap gdm, ConstEqTy CE)
: Env(env),
St(st),
GDM(gdm),
- ConstNotEq(CNE),
ConstEq(CE) {}
/// Copy ctor - We must explicitly define this or else the "Next" ptr
@@ -95,7 +91,6 @@
Env(RHS.Env),
St(RHS.St),
GDM(RHS.GDM),
- ConstNotEq(RHS.ConstNotEq),
ConstEq(RHS.ConstEq) {}
/// getEnvironment - Return the environment associated with this state.
@@ -115,7 +110,6 @@
V->Env.Profile(ID);
ID.AddPointer(V->St);
V->GDM.Profile(ID);
- V->ConstNotEq.Profile(ID);
V->ConstEq.Profile(ID);
}
@@ -138,7 +132,6 @@
// Iterators.
-
// FIXME: We'll be removing the VarBindings iterator very soon. Right now
// it assumes that Store is a VarBindingsTy.
typedef llvm::ImmutableMap<VarDecl*,RVal> VarBindingsTy;
@@ -151,7 +144,6 @@
VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
return B.end();
}
-
typedef Environment::seb_iterator seb_iterator;
seb_iterator seb_begin() const { return Env.seb_begin(); }
@@ -160,15 +152,7 @@
typedef Environment::beb_iterator beb_iterator;
beb_iterator beb_begin() const { return Env.beb_begin(); }
beb_iterator beb_end() const { return Env.beb_end(); }
-
- typedef ConstNotEqTy::iterator cne_iterator;
- cne_iterator cne_begin() const { return ConstNotEq.begin(); }
- cne_iterator cne_end() const { return ConstNotEq.end(); }
-
- typedef ConstEqTy::iterator ce_iterator;
- ce_iterator ce_begin() const { return ConstEq.begin(); }
- ce_iterator ce_end() const { return ConstEq.end(); }
-
+
// Trait based GDM dispatch.
void* const* FindGDM(void* K) const;
@@ -193,10 +177,7 @@
};
void print(std::ostream& Out, Printer **Beg = 0, Printer **End = 0,
- const char* nl = "\n", const char *sep = "") const;
-
- void printStdErr(Printer **Beg = 0, Printer **End = 0) const;
- void printDOT(std::ostream& Out, Printer **Beg = 0, Printer **End = 0) const;
+ const char* nl = "\n", const char *sep = "") const;
};
template<> struct GRTrait<GRState*> {
@@ -246,17 +227,29 @@
//===----------------------------------------------------------------------===//
// GRStateManager - Factory object for GRStates.
//===----------------------------------------------------------------------===//
+
+class GRStateRef;
class GRStateManager {
friend class GRExprEngine;
+ friend class GRStateRef;
private:
EnvironmentManager EnvMgr;
llvm::OwningPtr<StoreManager> StMgr;
- GRState::IntSetTy::Factory ISetFactory;
- GRState::GenericDataMap::Factory GDMFactory;
- GRState::ConstNotEqTy::Factory CNEFactory;
- GRState::ConstEqTy::Factory CEFactory;
+ GRState::IntSetTy::Factory ISetFactory;
+
+ GRState::GenericDataMap::Factory GDMFactory;
+
+ typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy;
+ GDMContextsTy GDMContexts;
+
+ // FIXME: Refactor these elsewhere.
+ GRState::ConstEqTy::Factory CEFactory;
+
+ /// Printers - A set of printer objects used for pretty-printing a GRState.
+ /// GRStateManager owns these objects.
+ std::vector<GRState::Printer*> Printers;
/// StateSet - FoldingSet containing all the states created for analyzing
/// a particular function. This is used to unique states.
@@ -304,12 +297,13 @@
StMgr(stmgr),
ISetFactory(alloc),
GDMFactory(alloc),
- CNEFactory(alloc),
CEFactory(alloc),
BasicVals(Ctx, alloc),
SymMgr(alloc),
Alloc(alloc),
cfg(c) {}
+
+ ~GRStateManager();
const GRState* getInitialState();
@@ -353,18 +347,21 @@
return getPersistentState(NewSt);
}
- const GRState* SetRVal(const GRState* St, Expr* Ex, RVal V) {
+ const GRState* SetRVal(const GRState* St, Expr* Ex, RVal V,
+ bool Invalidate = true) {
bool isBlkExpr = false;
if (Ex == CurrentStmt) {
+ // FIXME: Should this just be an assertion? When would we want to set
+ // the value of a block-level expression if it wasn't CurrentStmt?
isBlkExpr = cfg.isBlkExpr(Ex);
if (!isBlkExpr)
return St;
}
- return SetRVal(St, Ex, V, isBlkExpr, true);
+ return SetRVal(St, Ex, V, isBlkExpr, Invalidate);
}
// Methods that manipulate the GDM.
@@ -424,6 +421,20 @@
GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Remove(st->get<T>(), K, C)));
}
+
+ void* FindGDMContext(void* index,
+ void* (*CreateContext)(llvm::BumpPtrAllocator&),
+ void (*DeleteContext)(void*));
+
+ template <typename T>
+ typename GRStateTrait<T>::context_type get_context() {
+ void* p = FindGDMContext(GRStateTrait<T>::GDMIndex(),
+ GRStateTrait<T>::CreateContext,
+ GRStateTrait<T>::DeleteContext);
+
+ return GRStateTrait<T>::MakeContext(p);
+ }
+
// Assumption logic.
const GRState* Assume(const GRState* St, RVal Cond, bool Assumption,
bool& isFeasible) {
@@ -505,8 +516,8 @@
return GRStateRef(Mgr->SetRVal(St, Ex, V, isBlkExpr, Invalidate), *Mgr);
}
- GRStateRef SetRVal(Expr* Ex, RVal V) {
- return GRStateRef(Mgr->SetRVal(St, Ex, V), *Mgr);
+ GRStateRef SetRVal(Expr* Ex, RVal V, bool Invalidate = true) {
+ return GRStateRef(Mgr->SetRVal(St, Ex, V, Invalidate), *Mgr);
}
GRStateRef SetRVal(LVal LV, RVal V) {
@@ -539,7 +550,12 @@
GRStateRef set(typename GRStateTrait<T>::data_type D) {
return GRStateRef(Mgr->set<T>(St, D), *Mgr);
}
-
+
+ template <typename T>
+ typename GRStateTrait<T>::context_type get_context() {
+ return Mgr->get_context<T>();
+ }
+
template<typename T>
GRStateRef set(typename GRStateTrait<T>::key_type K,
typename GRStateTrait<T>::value_type E,
@@ -548,10 +564,24 @@
}
template<typename T>
+ GRStateRef set(typename GRStateTrait<T>::key_type K,
+ typename GRStateTrait<T>::value_type E) {
+ return GRStateRef(Mgr->set<T>(St, K, E, get_context<T>()), *Mgr);
+ }
+
+ template<typename T>
GRStateRef remove(typename GRStateTrait<T>::key_type K,
typename GRStateTrait<T>::context_type C) {
return GRStateRef(Mgr->remove<T>(St, K, C), *Mgr);
}
+
+ // Pretty-printing.
+ void print(std::ostream& Out, const char* nl = "\n",
+ const char *sep = "") const;
+
+ void printStdErr() const;
+
+ void printDOT(std::ostream& Out) const;
};
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h?rev=54835&r1=54834&r2=54835&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h Fri Aug 15 19:49:49 2008
@@ -43,7 +43,7 @@
GRTransferFuncs() {}
virtual ~GRTransferFuncs() {}
- virtual void getStatePrinters(std::vector<GRState::Printer*>& Printers) {}
+ virtual void RegisterPrinters(std::vector<GRState::Printer*>& Printers) {}
virtual void RegisterChecks(GRExprEngine& Eng);
// Casts.
Modified: cfe/trunk/lib/Analysis/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFRefCount.cpp?rev=54835&r1=54834&r2=54835&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Fri Aug 15 19:49:49 2008
@@ -1264,7 +1264,6 @@
UseAfterReleasesTy UseAfterReleases;
ReleasesNotOwnedTy ReleasesNotOwned;
LeaksTy Leaks;
- BindingsPrinter Printer;
RefBindings Update(RefBindings B, SymbolID sym, RefVal V, ArgEffect E,
RefVal::Kind& hasErr);
@@ -1301,8 +1300,8 @@
virtual void RegisterChecks(GRExprEngine& Eng);
- virtual void getStatePrinters(std::vector<GRState::Printer*>& Printers) {
- Printers.push_back(&Printer);
+ virtual void RegisterPrinters(std::vector<GRState::Printer*>& Printers) {
+ Printers.push_back(new BindingsPrinter());
}
bool isGCEnabled() const { return Summaries.isGCEnabled(); }
@@ -1598,7 +1597,7 @@
? cast<RVal>(lval::SymbolVal(Sym))
: cast<RVal>(nonlval::SymbolVal(Sym));
- state = state.SetRVal(Ex, X, Eng.getCFG().isBlkExpr(Ex), false);
+ state = state.SetRVal(Ex, X, false);
}
break;
@@ -1608,14 +1607,14 @@
assert (arg_end >= arg_beg);
assert (idx < (unsigned) (arg_end - arg_beg));
RVal V = state.GetRVal(*(arg_beg+idx));
- state = state.SetRVal(Ex, V, Eng.getCFG().isBlkExpr(Ex), false);
+ state = state.SetRVal(Ex, V, false);
break;
}
case RetEffect::ReceiverAlias: {
assert (Receiver);
RVal V = state.GetRVal(Receiver);
- state = state.SetRVal(Ex, V, Eng.getCFG().isBlkExpr(Ex), false);
+ state = state.SetRVal(Ex, V, false);
break;
}
@@ -1626,15 +1625,13 @@
QualType RetT = GetReturnType(Ex, Eng.getContext());
state = state.set<RefBindings>(Sym, RefVal::makeOwned(RetT), RefBFactory);
- state = state.SetRVal(Ex, lval::SymbolVal(Sym),
- Eng.getCFG().isBlkExpr(Ex), false);
+ state = state.SetRVal(Ex, lval::SymbolVal(Sym), false);
#if 0
RefBindings B = GetRefBindings(StImpl);
SetRefBindings(StImpl, RefBFactory.Add(B, Sym, RefVal::makeOwned(RetT)));
#endif
-
// FIXME: Add a flag to the checker where allocations are allowed to fail.
if (RE.getKind() == RetEffect::OwnedAllocatedSymbol)
state = state.AddNE(Sym, Eng.getBasicVals().getZeroWithPtrWidth());
@@ -1648,8 +1645,7 @@
QualType RetT = GetReturnType(Ex, Eng.getContext());
state = state.set<RefBindings>(Sym, RefVal::makeNotOwned(RetT), RefBFactory);
- state = state.SetRVal(Ex, lval::SymbolVal(Sym),
- Eng.getCFG().isBlkExpr(Ex), false);
+ state = state.SetRVal(Ex, lval::SymbolVal(Sym), false);
break;
}
}
Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=54835&r1=54834&r2=54835&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Fri Aug 15 19:49:49 2008
@@ -177,7 +177,8 @@
void GRExprEngine::setTransferFunctions(GRTransferFuncs* tf) {
StateMgr.TF = tf;
- getTF().RegisterChecks(*this);
+ tf->RegisterChecks(*this);
+ tf->RegisterPrinters(getStateManager().Printers);
}
void GRExprEngine::AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C) {
@@ -2266,109 +2267,12 @@
#ifndef NDEBUG
static GRExprEngine* GraphPrintCheckerState;
static SourceManager* GraphPrintSourceManager;
-static GRState::Printer **GraphStatePrinterBeg, **GraphStatePrinterEnd;
namespace llvm {
template<>
struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :
public DefaultDOTGraphTraits {
- static void PrintVarBindings(std::ostream& Out, GRState* St) {
-
- Out << "Variables:\\l";
-
- bool isFirst = true;
-
- for (GRState::vb_iterator I=St->vb_begin(), E=St->vb_end(); I!=E;++I) {
-
- if (isFirst)
- isFirst = false;
- else
- Out << "\\l";
-
- Out << ' ' << I.getKey()->getName() << " : ";
- I.getData().print(Out);
- }
-
- }
-
-
- static void PrintSubExprBindings(std::ostream& Out, GRState* St){
-
- bool isFirst = true;
-
- for (GRState::seb_iterator I=St->seb_begin(), E=St->seb_end();I!=E;++I) {
-
- if (isFirst) {
- Out << "\\l\\lSub-Expressions:\\l";
- isFirst = false;
- }
- else
- Out << "\\l";
-
- Out << " (" << (void*) I.getKey() << ") ";
- I.getKey()->printPretty(Out);
- Out << " : ";
- I.getData().print(Out);
- }
- }
-
- static void PrintBlkExprBindings(std::ostream& Out, GRState* St){
-
- bool isFirst = true;
-
- for (GRState::beb_iterator I=St->beb_begin(), E=St->beb_end(); I!=E;++I){
- if (isFirst) {
- Out << "\\l\\lBlock-level Expressions:\\l";
- isFirst = false;
- }
- else
- Out << "\\l";
-
- Out << " (" << (void*) I.getKey() << ") ";
- I.getKey()->printPretty(Out);
- Out << " : ";
- I.getData().print(Out);
- }
- }
-
- static void PrintEQ(std::ostream& Out, GRState* St) {
- GRState::ConstEqTy CE = St->ConstEq;
-
- if (CE.isEmpty())
- return;
-
- Out << "\\l\\|'==' constraints:";
-
- for (GRState::ConstEqTy::iterator I=CE.begin(), E=CE.end(); I!=E;++I)
- Out << "\\l $" << I.getKey() << " : " << I.getData()->toString();
- }
-
- static void PrintNE(std::ostream& Out, GRState* St) {
- GRState::ConstNotEqTy NE = St->ConstNotEq;
-
- if (NE.isEmpty())
- return;
-
- Out << "\\l\\|'!=' constraints:";
-
- for (GRState::ConstNotEqTy::iterator I=NE.begin(), EI=NE.end();
- I != EI; ++I){
-
- Out << "\\l $" << I.getKey() << " : ";
- bool isFirst = true;
-
- GRState::IntSetTy::iterator J=I.getData().begin(),
- EJ=I.getData().end();
- for ( ; J != EJ; ++J) {
- if (isFirst) isFirst = false;
- else Out << ", ";
-
- Out << (*J)->toString();
- }
- }
- }
-
static std::string getNodeAttributes(const GRExprEngine::NodeTy* N, void*) {
if (GraphPrintCheckerState->isImplicitNullDeref(N) ||
@@ -2509,7 +2413,8 @@
Out << "\\|StateID: " << (void*) N->getState() << "\\|";
- N->getState()->printDOT(Out, GraphStatePrinterBeg, GraphStatePrinterEnd);
+ GRStateRef state(N->getState(), GraphPrintCheckerState->getStateManager());
+ state.printDOT(Out);
Out << "\\l";
return Out.str();
@@ -2575,19 +2480,10 @@
GraphPrintCheckerState = this;
GraphPrintSourceManager = &getContext().getSourceManager();
- // Get the state printers.
- std::vector<GRState::Printer*> Printers;
- getTF().getStatePrinters(Printers);
- GraphStatePrinterBeg = Printers.empty() ? 0 : &Printers[0];
- GraphStatePrinterEnd = Printers.empty() ? 0 : &Printers[0]+Printers.size();
-
-
llvm::ViewGraph(*G.roots_begin(), "GRExprEngine");
GraphPrintCheckerState = NULL;
GraphPrintSourceManager = NULL;
- GraphStatePrinterBeg = NULL;
- GraphStatePrinterEnd = NULL;
}
#endif
}
@@ -2596,13 +2492,7 @@
#ifndef NDEBUG
GraphPrintCheckerState = this;
GraphPrintSourceManager = &getContext().getSourceManager();
-
- // Get the state printers.
- std::vector<GRState::Printer*> Printers;
- getTF().getStatePrinters(Printers);
- GraphStatePrinterBeg = Printers.empty() ? 0 : &Printers[0];
- GraphStatePrinterEnd = Printers.empty() ? 0 : &Printers[0]+Printers.size();
-
+
GRExprEngine::GraphTy* TrimmedG = G.Trim(Beg, End);
if (!TrimmedG)
@@ -2614,7 +2504,5 @@
GraphPrintCheckerState = NULL;
GraphPrintSourceManager = NULL;
- GraphStatePrinterBeg = NULL;
- GraphStatePrinterEnd = NULL;
#endif
}
Modified: cfe/trunk/lib/Analysis/GRState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRState.cpp?rev=54835&r1=54834&r2=54835&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRState.cpp (original)
+++ cfe/trunk/lib/Analysis/GRState.cpp Fri Aug 15 19:49:49 2008
@@ -17,10 +17,71 @@
using namespace clang;
+GRStateManager::~GRStateManager() {
+ for (std::vector<GRState::Printer*>::iterator I=Printers.begin(),
+ E=Printers.end(); I!=E; ++I)
+ delete *I;
+
+ for (GDMContextsTy::iterator I=GDMContexts.begin(), E=GDMContexts.end();
+ I!=E; ++I)
+ I->second.second(I->second.first);
+}
+
+//===----------------------------------------------------------------------===//
+// Basic symbolic analysis. This will eventually be refactored into a
+// separate component.
+//===----------------------------------------------------------------------===//
+
+typedef llvm::ImmutableMap<SymbolID,GRState::IntSetTy> ConstNotEqTy;
+
+static int ConstNotEqTyIndex = 0;
+
+namespace clang {
+ template<> struct GRStateTrait<ConstNotEqTy> {
+ typedef ConstNotEqTy data_type;
+ typedef ConstNotEqTy::Factory& context_type;
+ typedef SymbolID key_type;
+ typedef GRState::IntSetTy value_type;
+ typedef const GRState::IntSetTy* lookup_type;
+
+ static data_type MakeData(void* const* p) {
+ return p ? ConstNotEqTy((ConstNotEqTy::TreeTy*) *p) : ConstNotEqTy(0);
+ }
+ static void* MakeVoidPtr(ConstNotEqTy B) {
+ return B.getRoot();
+ }
+ static void* GDMIndex() {
+ return &ConstNotEqTyIndex;
+ }
+ static lookup_type Lookup(ConstNotEqTy B, SymbolID K) {
+ return B.lookup(K);
+ }
+ static data_type Set(data_type B, key_type K, value_type E,context_type F){
+ return F.Add(B, K, E);
+ }
+
+ static data_type Remove(ConstNotEqTy B, SymbolID K, context_type F) {
+ return F.Remove(B, K);
+ }
+
+ static context_type MakeContext(void* p) {
+ return *((ConstNotEqTy::Factory*) p);
+ }
+
+ static void* CreateContext(llvm::BumpPtrAllocator& Alloc) {
+ return new ConstNotEqTy::Factory(Alloc);
+ }
+
+ static void DeleteContext(void* Ctx) {
+ delete (ConstNotEqTy::Factory*) Ctx;
+ }
+ };
+}
+
bool GRState::isNotEqual(SymbolID sym, const llvm::APSInt& V) const {
// Retrieve the NE-set associated with the given symbol.
- const ConstNotEqTy::data_type* T = ConstNotEq.lookup(sym);
+ const ConstNotEqTy::data_type* T = get<ConstNotEqTy>(sym);
// See if V is present in the NE-set.
return T ? T->contains(&V) : false;
@@ -42,8 +103,8 @@
const GRState*
GRStateManager::RemoveDeadBindings(const GRState* St, Stmt* Loc,
- const LiveVariables& Liveness,
- DeadSymbolsTy& DSymbols) {
+ const LiveVariables& Liveness,
+ DeadSymbolsTy& DSymbols) {
// This code essentially performs a "mark-and-sweep" of the VariableBindings.
// The roots are any Block-level exprs and Decls that our liveness algorithm
@@ -97,7 +158,9 @@
LSymbols, DSymbols);
// Remove the dead symbols from the symbol tracker.
- for (GRState::ce_iterator I = St->ce_begin(), E=St->ce_end(); I!=E; ++I) {
+ // FIXME: Refactor into something else that manages symbol values.
+ for (GRState::ConstEqTy::iterator I = St->ConstEq.begin(),
+ E=St->ConstEq.end(); I!=E; ++I) {
SymbolID sym = I.getKey();
@@ -107,17 +170,19 @@
}
}
- for (GRState::cne_iterator I = St->cne_begin(), E=St->cne_end(); I!=E;++I){
-
- SymbolID sym = I.getKey();
-
+ GRStateRef state(getPersistentState(NewSt), *this);
+ ConstNotEqTy CNE = state.get<ConstNotEqTy>();
+ ConstNotEqTy::Factory& CNEFactory = state.get_context<ConstNotEqTy>();
+
+ for (ConstNotEqTy::iterator I = CNE.begin(), E = CNE.end(); I != E; ++I) {
+ SymbolID sym = I.getKey();
if (!LSymbols.count(sym)) {
DSymbols.insert(sym);
- NewSt.ConstNotEq = CNEFactory.Remove(NewSt.ConstNotEq, sym);
+ CNE = CNEFactory.Remove(CNE, sym);
}
}
- return getPersistentState(NewSt);
+ return state.set<ConstNotEqTy>(CNE);
}
const GRState* GRStateManager::SetRVal(const GRState* St, LVal LV,
@@ -148,21 +213,19 @@
const GRState* GRStateManager::AddNE(const GRState* St, SymbolID sym,
- const llvm::APSInt& V) {
+ const llvm::APSInt& V) {
+
+ GRStateRef state(St, *this);
// First, retrieve the NE-set associated with the given symbol.
- GRState::ConstNotEqTy::data_type* T = St->ConstNotEq.lookup(sym);
+ ConstNotEqTy::data_type* T = state.get<ConstNotEqTy>(sym);
GRState::IntSetTy S = T ? *T : ISetFactory.GetEmptySet();
// Now add V to the NE set.
S = ISetFactory.Add(S, &V);
// Create a new state with the old binding replaced.
- GRState NewSt = *St;
- NewSt.ConstNotEq = CNEFactory.Add(NewSt.ConstNotEq, sym, S);
-
- // Get the persistent copy.
- return getPersistentState(NewSt);
+ return state.set<ConstNotEqTy>(sym, S);
}
const GRState* GRStateManager::AddEQ(const GRState* St, SymbolID sym,
@@ -179,7 +242,7 @@
const GRState* GRStateManager::getInitialState() {
GRState StateImpl(EnvMgr.getInitialEnvironment(), StMgr->getInitialStore(),
- GDMFactory.GetEmptyMap(), CNEFactory.GetEmptyMap(),
+ GDMFactory.GetEmptyMap(),
CEFactory.GetEmptyMap());
return getPersistentState(StateImpl);
@@ -200,14 +263,10 @@
return I;
}
-void GRState::printDOT(std::ostream& Out,
- Printer** Beg, Printer** End) const {
- print(Out, Beg, End, "\\l", "\\|");
-}
-void GRState::printStdErr(Printer** Beg, Printer** End) const {
- print(*llvm::cerr, Beg, End);
-}
+//===----------------------------------------------------------------------===//
+// State pretty-printing.
+//===----------------------------------------------------------------------===//
void GRState::print(std::ostream& Out, Printer** Beg, Printer** End,
const char* nl, const char* sep) const {
@@ -279,14 +338,14 @@
// Print != constraints.
// FIXME: Make just another printer do this.
-
- if (!ConstNotEq.isEmpty()) {
+
+ ConstNotEqTy CNE = get<ConstNotEqTy>();
+
+ if (!CNE.isEmpty()) {
Out << nl << sep << "'!=' constraints:";
- for (ConstNotEqTy::iterator I = ConstNotEq.begin(),
- EI = ConstNotEq.end(); I != EI; ++I) {
-
+ for (ConstNotEqTy::iterator I = CNE.begin(), EI = CNE.end(); I!=EI; ++I) {
Out << nl << " $" << I.getKey() << " : ";
isFirst = true;
@@ -305,6 +364,20 @@
for ( ; Beg != End ; ++Beg) (*Beg)->Print(Out, this, nl, sep);
}
+void GRStateRef::printDOT(std::ostream& Out) const {
+ print(Out, "\\l", "\\|");
+}
+
+void GRStateRef::printStdErr() const {
+ print(*llvm::cerr);
+}
+
+void GRStateRef::print(std::ostream& Out, const char* nl, const char* sep)const{
+ GRState::Printer **beg = Mgr->Printers.empty() ? 0 : &Mgr->Printers[0];
+ GRState::Printer **end = !beg ? 0 : beg + Mgr->Printers.size();
+ St->print(Out, beg, end, nl, sep);
+}
+
//===----------------------------------------------------------------------===//
// Generic Data Map.
//===----------------------------------------------------------------------===//
@@ -313,6 +386,20 @@
return GDM.lookup(K);
}
+void*
+GRStateManager::FindGDMContext(void* K,
+ void* (*CreateContext)(llvm::BumpPtrAllocator&),
+ void (*DeleteContext)(void*)) {
+
+ std::pair<void*, void (*)(void*)>& p = GDMContexts[K];
+ if (!p.first) {
+ p.first = CreateContext(Alloc);
+ p.second = DeleteContext;
+ }
+
+ return p.first;
+}
+
const GRState* GRStateManager::addGDM(const GRState* St, void* Key, void* Data){
GRState::GenericDataMap M1 = St->getGDM();
GRState::GenericDataMap M2 = GDMFactory.Add(M1, Key, Data);
@@ -330,7 +417,8 @@
//===----------------------------------------------------------------------===//
bool GRStateManager::isEqual(const GRState* state, Expr* Ex,
- const llvm::APSInt& Y) {
+ const llvm::APSInt& Y) {
+
RVal V = GetRVal(state, Ex);
if (lval::ConcreteInt* X = dyn_cast<lval::ConcreteInt>(&V))
@@ -348,8 +436,7 @@
return false;
}
-bool GRStateManager::isEqual(const GRState* state, Expr* Ex,
- uint64_t x) {
+bool GRStateManager::isEqual(const GRState* state, Expr* Ex, uint64_t x) {
return isEqual(state, Ex, BasicVals.getValue(x, Ex->getType()));
}
@@ -382,7 +469,6 @@
return AssumeSymEQ(St, cast<lval::SymbolVal>(Cond).getSymbol(),
BasicVals.getZeroWithPtrWidth(), isFeasible);
-
case lval::DeclValKind:
case lval::FuncValKind:
case lval::GotoLabelKind:
More information about the cfe-commits
mailing list