From 1c72ef092f3d931639cf44b4f4f9d0eedc1baa8f Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Sat, 16 Aug 2008 00:49:49 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54835 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../clang/Analysis/PathSensitive/GRState.h | 94 +++++++---- .../Analysis/PathSensitive/GRTransferFuncs.h | 2 +- lib/Analysis/CFRefCount.cpp | 18 +- lib/Analysis/GRExprEngine.cpp | 122 +------------- lib/Analysis/GRState.cpp | 154 ++++++++++++++---- 5 files changed, 195 insertions(+), 195 deletions(-) diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h index 504383fd12..8b2c72d849 100644 --- a/include/clang/Analysis/PathSensitive/GRState.h +++ b/include/clang/Analysis/PathSensitive/GRState.h @@ -58,7 +58,6 @@ public: // Typedefs. typedef llvm::ImmutableSet IntSetTy; typedef llvm::ImmutableMap GenericDataMap; - typedef llvm::ImmutableMap ConstNotEqTy; typedef llvm::ImmutableMap ConstEqTy; typedef GRStateManager ManagerTy; @@ -74,18 +73,15 @@ private: // 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 @@ public: 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 @@ public: V->Env.Profile(ID); ID.AddPointer(V->St); V->GDM.Profile(ID); - V->ConstNotEq.Profile(ID); V->ConstEq.Profile(ID); } @@ -138,7 +132,6 @@ public: // Iterators. - // FIXME: We'll be removing the VarBindings iterator very soon. Right now // it assumes that Store is a VarBindingsTy. typedef llvm::ImmutableMap VarBindingsTy; @@ -151,7 +144,6 @@ public: VarBindingsTy B(static_cast(St)); return B.end(); } - typedef Environment::seb_iterator seb_iterator; seb_iterator seb_begin() const { return Env.seb_begin(); } @@ -160,15 +152,7 @@ public: 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 @@ public: }; 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 { @@ -246,17 +227,29 @@ public: //===----------------------------------------------------------------------===// // GRStateManager - Factory object for GRStates. //===----------------------------------------------------------------------===// + +class GRStateRef; class GRStateManager { friend class GRExprEngine; + friend class GRStateRef; private: EnvironmentManager EnvMgr; llvm::OwningPtr 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 > 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 Printers; /// StateSet - FoldingSet containing all the states created for analyzing /// a particular function. This is used to unique states. @@ -304,12 +297,13 @@ public: 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 @@ public: 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 @@ public: GRStateTrait::MakeVoidPtr(GRStateTrait::Remove(st->get(), K, C))); } + + void* FindGDMContext(void* index, + void* (*CreateContext)(llvm::BumpPtrAllocator&), + void (*DeleteContext)(void*)); + + template + typename GRStateTrait::context_type get_context() { + void* p = FindGDMContext(GRStateTrait::GDMIndex(), + GRStateTrait::CreateContext, + GRStateTrait::DeleteContext); + + return GRStateTrait::MakeContext(p); + } + // Assumption logic. const GRState* Assume(const GRState* St, RVal Cond, bool Assumption, bool& isFeasible) { @@ -505,8 +516,8 @@ public: 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 @@ public: GRStateRef set(typename GRStateTrait::data_type D) { return GRStateRef(Mgr->set(St, D), *Mgr); } - + + template + typename GRStateTrait::context_type get_context() { + return Mgr->get_context(); + } + template GRStateRef set(typename GRStateTrait::key_type K, typename GRStateTrait::value_type E, @@ -547,11 +563,25 @@ public: return GRStateRef(Mgr->set(St, K, E, C), *Mgr); } + template + GRStateRef set(typename GRStateTrait::key_type K, + typename GRStateTrait::value_type E) { + return GRStateRef(Mgr->set(St, K, E, get_context()), *Mgr); + } + template GRStateRef remove(typename GRStateTrait::key_type K, typename GRStateTrait::context_type C) { return GRStateRef(Mgr->remove(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; }; diff --git a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h index 86b52cb949..ad12328eda 100644 --- a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h +++ b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h @@ -43,7 +43,7 @@ public: GRTransferFuncs() {} virtual ~GRTransferFuncs() {} - virtual void getStatePrinters(std::vector& Printers) {} + virtual void RegisterPrinters(std::vector& Printers) {} virtual void RegisterChecks(GRExprEngine& Eng); // Casts. diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 9a769988a1..2fdd0290e1 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -1264,7 +1264,6 @@ private: 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 @@ public: virtual void RegisterChecks(GRExprEngine& Eng); - virtual void getStatePrinters(std::vector& Printers) { - Printers.push_back(&Printer); + virtual void RegisterPrinters(std::vector& Printers) { + Printers.push_back(new BindingsPrinter()); } bool isGCEnabled() const { return Summaries.isGCEnabled(); } @@ -1598,7 +1597,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, ? cast(lval::SymbolVal(Sym)) : cast(nonlval::SymbolVal(Sym)); - state = state.SetRVal(Ex, X, Eng.getCFG().isBlkExpr(Ex), false); + state = state.SetRVal(Ex, X, false); } break; @@ -1608,14 +1607,14 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, 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 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, QualType RetT = GetReturnType(Ex, Eng.getContext()); state = state.set(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 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, QualType RetT = GetReturnType(Ex, Eng.getContext()); state = state.set(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; } } diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index f4ffcb12e0..896f473df8 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -177,7 +177,8 @@ void GRExprEngine::EmitWarnings(BugReporterData& BRData) { 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 @@ void GRExprEngine::EvalBinOp(GRStateSet& OStates, const GRState* St, #ifndef NDEBUG static GRExprEngine* GraphPrintCheckerState; static SourceManager* GraphPrintSourceManager; -static GRState::Printer **GraphStatePrinterBeg, **GraphStatePrinterEnd; namespace llvm { template<> struct VISIBILITY_HIDDEN DOTGraphTraits : 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 @@ struct VISIBILITY_HIDDEN DOTGraphTraits : 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 @@ void GRExprEngine::ViewGraph(bool trim) { GraphPrintCheckerState = this; GraphPrintSourceManager = &getContext().getSourceManager(); - // Get the state printers. - std::vector 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 @@ void GRExprEngine::ViewGraph(NodeTy** Beg, NodeTy** End) { #ifndef NDEBUG GraphPrintCheckerState = this; GraphPrintSourceManager = &getContext().getSourceManager(); - - // Get the state printers. - std::vector 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 @@ void GRExprEngine::ViewGraph(NodeTy** Beg, NodeTy** End) { GraphPrintCheckerState = NULL; GraphPrintSourceManager = NULL; - GraphStatePrinterBeg = NULL; - GraphStatePrinterEnd = NULL; #endif } diff --git a/lib/Analysis/GRState.cpp b/lib/Analysis/GRState.cpp index b945803804..5522600d84 100644 --- a/lib/Analysis/GRState.cpp +++ b/lib/Analysis/GRState.cpp @@ -17,10 +17,71 @@ using namespace clang; +GRStateManager::~GRStateManager() { + for (std::vector::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 ConstNotEqTy; + +static int ConstNotEqTyIndex = 0; + +namespace clang { + template<> struct GRStateTrait { + 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(sym); // See if V is present in the NE-set. return T ? T->contains(&V) : false; @@ -42,8 +103,8 @@ const llvm::APSInt* GRState::getSymVal(SymbolID sym) const { 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 @@ GRStateManager::RemoveDeadBindings(const GRState* St, Stmt* Loc, 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 @@ GRStateManager::RemoveDeadBindings(const GRState* St, Stmt* Loc, } } - 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::Factory& CNEFactory = state.get_context(); + + 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(CNE); } const GRState* GRStateManager::SetRVal(const GRState* St, LVal LV, @@ -148,21 +213,19 @@ const GRState* GRStateManager::Unbind(const GRState* St, LVal LV) { 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(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(sym, S); } const GRState* GRStateManager::AddEQ(const GRState* St, SymbolID sym, @@ -179,7 +242,7 @@ const GRState* GRStateManager::AddEQ(const GRState* St, SymbolID sym, 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 @@ const GRState* GRStateManager::getPersistentState(GRState& State) { 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 @@ void GRState::print(std::ostream& Out, Printer** Beg, Printer** End, // Print != constraints. // FIXME: Make just another printer do this. - - if (!ConstNotEq.isEmpty()) { + + ConstNotEqTy CNE = get(); + + 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 @@ void GRState::print(std::ostream& Out, Printer** Beg, Printer** End, 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 @@ void* const* GRState::FindGDM(void* K) const { return GDM.lookup(K); } +void* +GRStateManager::FindGDMContext(void* K, + void* (*CreateContext)(llvm::BumpPtrAllocator&), + void (*DeleteContext)(void*)) { + + std::pair& 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 @@ const GRState* GRStateManager::addGDM(const GRState* St, void* Key, void* Data){ //===----------------------------------------------------------------------===// 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(&V)) @@ -348,8 +436,7 @@ bool GRStateManager::isEqual(const GRState* state, Expr* Ex, 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 @@ const GRState* GRStateManager::AssumeAux(const GRState* St, LVal Cond, return AssumeSymEQ(St, cast(Cond).getSymbol(), BasicVals.getZeroWithPtrWidth(), isFeasible); - case lval::DeclValKind: case lval::FuncValKind: case lval::GotoLabelKind: -- 2.40.0