From 7718ae4701a70d14db6ca909cd35883dfde53aa8 Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Tue, 23 Jun 2009 09:02:15 +0000 Subject: [PATCH] Move all factory methods from SVal to ValueManager. API cleanup! llvm-svn: 73954 --- .../Analysis/PathSensitive/Environment.h | 6 +- .../Analysis/PathSensitive/GRExprEngine.h | 5 -- .../clang/Analysis/PathSensitive/GRState.h | 4 +- .../clang/Analysis/PathSensitive/SVals.h | 35 +-------- .../Analysis/PathSensitive/ValueManager.h | 78 +++++++++++++++---- clang/lib/Analysis/BasicStore.cpp | 26 +++---- clang/lib/Analysis/CFRefCount.cpp | 8 +- clang/lib/Analysis/Environment.cpp | 15 ++-- clang/lib/Analysis/GRExprEngine.cpp | 37 +++++---- clang/lib/Analysis/GRSimpleVals.cpp | 19 +++-- clang/lib/Analysis/RegionStore.cpp | 36 ++++----- clang/lib/Analysis/SVals.cpp | 59 -------------- clang/lib/Analysis/ValueManager.cpp | 38 +++------ 13 files changed, 155 insertions(+), 211 deletions(-) diff --git a/clang/include/clang/Analysis/PathSensitive/Environment.h b/clang/include/clang/Analysis/PathSensitive/Environment.h index 0fc49f5a586e..6f8a12642769 100644 --- a/clang/include/clang/Analysis/PathSensitive/Environment.h +++ b/clang/include/clang/Analysis/PathSensitive/Environment.h @@ -27,7 +27,7 @@ namespace clang { class EnvironmentManager; -class BasicValueFactory; +class ValueManager; class LiveVariables; class Environment { @@ -71,8 +71,8 @@ public: return X ? *X : UnknownVal(); } - SVal GetSVal(const Stmt* Ex, BasicValueFactory& BasicVals) const; - SVal GetBlkExprSVal(const Stmt* Ex, BasicValueFactory& BasicVals) const; + SVal GetSVal(const Stmt* Ex, ValueManager& ValMgr) const; + SVal GetBlkExprSVal(const Stmt* Ex, ValueManager& ValMgr) const; /// Profile - Profile the contents of an Environment object for use /// in a FoldingSet. diff --git a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h index 4af8a7c845a7..5db666c4b83f 100644 --- a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -481,11 +481,6 @@ protected: return N == EntryNode ? CleanedState : N->getState(); } -public: - inline NonLoc MakeConstantVal(uint64_t X, Expr* Ex) { - return NonLoc::MakeVal(getBasicVals(), X, Ex->getType()); - } - public: NodeTy* MakeNode(NodeSet& Dst, Stmt* S, NodeTy* Pred, const GRState* St, ProgramPoint::Kind K = ProgramPoint::PostStmtKind, diff --git a/clang/include/clang/Analysis/PathSensitive/GRState.h b/clang/include/clang/Analysis/PathSensitive/GRState.h index a4077207780b..2cb3f9470cf0 100644 --- a/clang/include/clang/Analysis/PathSensitive/GRState.h +++ b/clang/include/clang/Analysis/PathSensitive/GRState.h @@ -532,7 +532,7 @@ private: // Methods that query & manipulate the Environment. SVal GetSVal(const GRState* St, const Stmt* Ex) { - return St->getEnvironment().GetSVal(Ex, getBasicVals()); + return St->getEnvironment().GetSVal(Ex, ValueMgr); } SVal GetSValAsScalarOrLoc(const GRState* state, const Stmt *S) { @@ -546,7 +546,7 @@ private: } SVal GetBlkExprSVal(const GRState* St, const Stmt* Ex) { - return St->getEnvironment().GetBlkExprSVal(Ex, getBasicVals()); + return St->getEnvironment().GetBlkExprSVal(Ex, ValueMgr); } const GRState* BindExpr(const GRState* St, const Stmt* Ex, SVal V, diff --git a/clang/include/clang/Analysis/PathSensitive/SVals.h b/clang/include/clang/Analysis/PathSensitive/SVals.h index c9d1e25da789..de74dbdb17b0 100644 --- a/clang/include/clang/Analysis/PathSensitive/SVals.h +++ b/clang/include/clang/Analysis/PathSensitive/SVals.h @@ -30,6 +30,7 @@ class BasicValueFactory; class MemRegion; class MemRegionManager; class GRStateManager; +class ValueManager; class SVal { public: @@ -171,28 +172,6 @@ protected: public: void print(llvm::raw_ostream& Out) const; - // Utility methods to create NonLocs. - - static NonLoc MakeIntVal(BasicValueFactory& BasicVals, uint64_t X, - bool isUnsigned); - - static NonLoc MakeVal(BasicValueFactory& BasicVals, uint64_t X, - unsigned BitWidth, bool isUnsigned); - - static NonLoc MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T); - - static NonLoc MakeVal(BasicValueFactory& BasicVals, const IntegerLiteral *I); - - static NonLoc MakeVal(BasicValueFactory& BasicVals, const llvm::APInt& I, - bool isUnsigned); - - static NonLoc MakeVal(BasicValueFactory& BasicVals, const llvm::APSInt& I); - - static NonLoc MakeIntTruthVal(BasicValueFactory& BasicVals, bool b); - - static NonLoc MakeCompoundVal(QualType T, llvm::ImmutableList Vals, - BasicValueFactory& BasicVals); - // Implement isa support. static inline bool classof(const SVal* V) { return V->getBaseKind() == NonLocKind; @@ -210,12 +189,6 @@ public: Loc(const Loc& X) : SVal(X.Data, true, X.getSubKind()) {} Loc& operator=(const Loc& X) { memcpy(this, &X, sizeof(Loc)); return *this; } - static Loc MakeVal(const MemRegion* R); - - static Loc MakeVal(const AddrLabelExpr* E); - - static Loc MakeNull(BasicValueFactory &BasicVals); - // Implement isa support. static inline bool classof(const SVal* V) { return V->getBaseKind() == LocKind; @@ -301,6 +274,8 @@ public: }; class LocAsInteger : public NonLoc { + friend class clang::ValueManager; + LocAsInteger(const std::pair& data) : NonLoc(LocAsIntegerKind, &data) { assert (isa(data.first)); @@ -330,12 +305,10 @@ public: static inline bool classof(const NonLoc* V) { return V->getSubKind() == LocAsIntegerKind; } - - static LocAsInteger Make(BasicValueFactory& Vals, Loc V, unsigned Bits); }; class CompoundVal : public NonLoc { - friend class NonLoc; + friend class clang::ValueManager; CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {} diff --git a/clang/include/clang/Analysis/PathSensitive/ValueManager.h b/clang/include/clang/Analysis/PathSensitive/ValueManager.h index c05dac06924f..d8e557f76036 100644 --- a/clang/include/clang/Analysis/PathSensitive/ValueManager.h +++ b/clang/include/clang/Analysis/PathSensitive/ValueManager.h @@ -68,17 +68,8 @@ public: return SymMgr.getConjuredSymbol(E, VisitCount, SymbolTag); } - // Aggregation methods that use multiple submanagers. - - Loc makeRegionVal(SymbolRef Sym) { - return Loc::MakeVal(MemMgr.getSymbolicRegion(Sym)); - } - /// makeZeroVal - Construct an SVal representing '0' for the specified type. SVal makeZeroVal(QualType T); - /// makeZeroArrayIndex - Construct an SVal representing '0' index for array - /// elements. - SVal makeZeroArrayIndex(); /// GetRegionValueSymbolVal - make a unique symbol for value of R. SVal getRegionValueSymbolVal(const MemRegion* R, QualType T = QualType()); @@ -87,18 +78,77 @@ public: SVal getConjuredSymbolVal(const Expr* E, QualType T, unsigned Count); SVal getFunctionPointer(const FunctionDecl* FD); - - NonLoc makeNonLoc(SymbolRef sym); - NonLoc makeIntVal(const llvm::APSInt& V); - + NonLoc makeCompoundVal(QualType T, llvm::ImmutableList Vals) { + return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals)); + } + + NonLoc makeZeroArrayIndex() { + return nonloc::ConcreteInt(BasicVals.getZeroWithPtrWidth(false)); + } + + NonLoc makeIntVal(const IntegerLiteral* I) { + return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(), + I->getType()->isUnsignedIntegerType())); + } + + NonLoc makeIntVal(const llvm::APSInt& V) { + return nonloc::ConcreteInt(BasicVals.getValue(V)); + } + + NonLoc makeIntVal(const llvm::APInt& V, bool isUnsigned) { + return nonloc::ConcreteInt(BasicVals.getValue(V, isUnsigned)); + } + + NonLoc makeIntVal(uint64_t X, QualType T) { + return nonloc::ConcreteInt(BasicVals.getValue(X, T)); + } + + NonLoc makeIntVal(uint64_t X, bool isUnsigned) { + return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned)); + } + + NonLoc makeIntVal(uint64_t X, unsigned BitWidth, bool isUnsigned) { + return nonloc::ConcreteInt(BasicVals.getValue(X, BitWidth, isUnsigned)); + } + + NonLoc makeLocAsInteger(Loc V, unsigned Bits) { + return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(V, Bits)); + } + NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, const llvm::APSInt& rhs, QualType T); NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType T); - NonLoc makeTruthVal(bool b, QualType T); + NonLoc makeTruthVal(bool b, QualType T) { + return nonloc::ConcreteInt(BasicVals.getTruthValue(b, T)); + } + + NonLoc makeTruthVal(bool b) { + return nonloc::ConcreteInt(BasicVals.getTruthValue(b)); + } + + Loc makeNull() { + return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth()); + } + + Loc makeLoc(SymbolRef Sym) { + return loc::MemRegionVal(MemMgr.getSymbolicRegion(Sym)); + } + + Loc makeLoc(const MemRegion* R) { + return loc::MemRegionVal(R); + } + + Loc makeLoc(const AddrLabelExpr* E) { + return loc::GotoLabel(E->getLabel()); + } + + Loc makeLoc(const llvm::APSInt& V) { + return loc::ConcreteInt(BasicVals.getValue(V)); + } }; } // end clang namespace #endif diff --git a/clang/lib/Analysis/BasicStore.cpp b/clang/lib/Analysis/BasicStore.cpp index dd23f31bbeb3..6b346cd52557 100644 --- a/clang/lib/Analysis/BasicStore.cpp +++ b/clang/lib/Analysis/BasicStore.cpp @@ -63,7 +63,7 @@ public: // FIXME: Investigate what is using this. This method should be removed. virtual Loc getLoc(const VarDecl* VD) { - return Loc::MakeVal(MRMgr.getVarRegion(VD)); + return ValMgr.makeLoc(MRMgr.getVarRegion(VD)); } const GRState *BindCompoundLiteral(const GRState *state, @@ -126,17 +126,17 @@ StoreManager* clang::CreateBasicStoreManager(GRStateManager& StMgr) { } SVal BasicStoreManager::getLValueVar(const GRState *state, const VarDecl* VD) { - return Loc::MakeVal(MRMgr.getVarRegion(VD)); + return ValMgr.makeLoc(MRMgr.getVarRegion(VD)); } SVal BasicStoreManager::getLValueString(const GRState *state, const StringLiteral* S) { - return Loc::MakeVal(MRMgr.getStringRegion(S)); + return ValMgr.makeLoc(MRMgr.getStringRegion(S)); } SVal BasicStoreManager::getLValueCompoundLiteral(const GRState *state, const CompoundLiteralExpr* CL){ - return Loc::MakeVal(MRMgr.getCompoundLiteralRegion(CL)); + return ValMgr.makeLoc(MRMgr.getCompoundLiteralRegion(CL)); } SVal BasicStoreManager::getLValueIvar(const GRState *state, const ObjCIvarDecl* D, @@ -151,7 +151,7 @@ SVal BasicStoreManager::getLValueIvar(const GRState *state, const ObjCIvarDecl* const MemRegion *BaseR = cast(BaseL).getRegion(); if (BaseR == SelfRegion) - return loc::MemRegionVal(MRMgr.getObjCIvarRegion(D, BaseR)); + return ValMgr.makeLoc(MRMgr.getObjCIvarRegion(D, BaseR)); } return UnknownVal(); @@ -186,7 +186,7 @@ SVal BasicStoreManager::getLValueField(const GRState *state, SVal Base, return Base; } - return Loc::MakeVal(MRMgr.getFieldRegion(D, BaseR)); + return ValMgr.makeLoc(MRMgr.getFieldRegion(D, BaseR)); } SVal BasicStoreManager::getLValueElement(const GRState *state, @@ -242,8 +242,8 @@ SVal BasicStoreManager::getLValueElement(const GRState *state, } if (BaseR) - return Loc::MakeVal(MRMgr.getElementRegion(elementType, UnknownVal(), - BaseR, getContext())); + return ValMgr.makeLoc(MRMgr.getElementRegion(elementType, UnknownVal(), + BaseR, getContext())); else return UnknownVal(); } @@ -456,7 +456,7 @@ BasicStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc, const MemRegion* R = I.getKey(); if (!Marked.count(R)) { - store = Remove(store, Loc::MakeVal(R)); + store = Remove(store, ValMgr.makeLoc(R)); SVal X = I.getData(); for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI) @@ -483,7 +483,7 @@ Store BasicStoreManager::scanForIvars(Stmt *B, const Decl* SelfDecl, Store St) { const MemRegion *IVR = MRMgr.getObjCIvarRegion(IV->getDecl(), SelfRegion); SVal X = ValMgr.getRegionValueSymbolVal(IVR); - St = BindInternal(St, Loc::MakeVal(IVR), X); + St = BindInternal(St, ValMgr.makeLoc(IVR), X); } } } @@ -515,8 +515,8 @@ Store BasicStoreManager::getInitialStore() { SelfRegion = MRMgr.getObjCObjectRegion(MD->getClassInterface(), MRMgr.getHeapRegion()); - St = BindInternal(St, Loc::MakeVal(MRMgr.getVarRegion(PD)), - Loc::MakeVal(SelfRegion)); + St = BindInternal(St, ValMgr.makeLoc(MRMgr.getVarRegion(PD)), + ValMgr.makeLoc(SelfRegion)); // Scan the method for ivar references. While this requires an // entire AST scan, the cost should not be high in practice. @@ -541,7 +541,7 @@ Store BasicStoreManager::getInitialStore() { ? ValMgr.getRegionValueSymbolVal(R) : UndefinedVal(); - St = BindInternal(St, Loc::MakeVal(R), X); + St = BindInternal(St, ValMgr.makeLoc(R), X); } } return St; diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp index 204fbeeb4a8a..1ccd0924f378 100644 --- a/clang/lib/Analysis/CFRefCount.cpp +++ b/clang/lib/Analysis/CFRefCount.cpp @@ -2843,7 +2843,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())){ ValueManager &ValMgr = Eng.getValueManager(); SVal V = ValMgr.getConjuredSymbolVal(*I, T, Count); - state = state->bindLoc(Loc::MakeVal(R), V); + state = state->bindLoc(ValMgr.makeLoc(R), V); } else if (const RecordType *RT = T->getAsStructureType()) { // Handle structs in a not so awesome way. Here we just @@ -2873,7 +2873,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, const FieldRegion* FR = MRMgr.getFieldRegion(FD, R); SVal V = ValMgr.getConjuredSymbolVal(*I, FT, Count); - state = state->bindLoc(Loc::MakeVal(FR), V); + state = state->bindLoc(ValMgr.makeLoc(FR), V); } } } else if (const ArrayType *AT = Ctx.getAsArrayType(T)) { @@ -2987,7 +2987,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, QualType RetT = GetReturnType(Ex, ValMgr.getContext()); state = state->set(Sym, RefVal::makeOwned(RE.getObjKind(), RetT)); - state = state->bindExpr(Ex, ValMgr.makeRegionVal(Sym), false); + state = state->bindExpr(Ex, ValMgr.makeLoc(Sym), false); // FIXME: Add a flag to the checker where allocations are assumed to // *not fail. @@ -3010,7 +3010,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, QualType RetT = GetReturnType(Ex, ValMgr.getContext()); state = state->set(Sym, RefVal::makeNotOwned(RE.getObjKind(), RetT)); - state = state->bindExpr(Ex, ValMgr.makeRegionVal(Sym), false); + state = state->bindExpr(Ex, ValMgr.makeLoc(Sym), false); break; } } diff --git a/clang/lib/Analysis/Environment.cpp b/clang/lib/Analysis/Environment.cpp index 7ada6d809bd4..2b751df830c2 100644 --- a/clang/lib/Analysis/Environment.cpp +++ b/clang/lib/Analysis/Environment.cpp @@ -18,14 +18,14 @@ using namespace clang; -SVal Environment::GetSVal(const Stmt *E, BasicValueFactory& BasicVals) const { +SVal Environment::GetSVal(const Stmt *E, ValueManager& ValMgr) const { for (;;) { switch (E->getStmtClass()) { case Stmt::AddrLabelExprClass: - return Loc::MakeVal(cast(E)); + return ValMgr.makeLoc(cast(E)); // ParenExprs are no-ops. @@ -35,11 +35,11 @@ SVal Environment::GetSVal(const Stmt *E, BasicValueFactory& BasicVals) const { case Stmt::CharacterLiteralClass: { const CharacterLiteral* C = cast(E); - return NonLoc::MakeVal(BasicVals, C->getValue(), C->getType()); + return ValMgr.makeIntVal(C->getValue(), C->getType()); } case Stmt::IntegerLiteralClass: { - return NonLoc::MakeVal(BasicVals, cast(E)); + return ValMgr.makeIntVal(cast(E)); } // Casts where the source and target type are the same @@ -69,8 +69,7 @@ SVal Environment::GetSVal(const Stmt *E, BasicValueFactory& BasicVals) const { return LookupExpr(E); } -SVal Environment::GetBlkExprSVal(const Stmt *E, - BasicValueFactory& BasicVals) const { +SVal Environment::GetBlkExprSVal(const Stmt *E, ValueManager& ValMgr) const { while (1) { switch (E->getStmtClass()) { @@ -80,11 +79,11 @@ SVal Environment::GetBlkExprSVal(const Stmt *E, case Stmt::CharacterLiteralClass: { const CharacterLiteral* C = cast(E); - return NonLoc::MakeVal(BasicVals, C->getValue(), C->getType()); + return ValMgr.makeIntVal(C->getValue(), C->getType()); } case Stmt::IntegerLiteralClass: { - return NonLoc::MakeVal(BasicVals, cast(E)); + return ValMgr.makeIntVal(cast(E)); } default: diff --git a/clang/lib/Analysis/GRExprEngine.cpp b/clang/lib/Analysis/GRExprEngine.cpp index 52175ee2a001..d5f0e406bb7c 100644 --- a/clang/lib/Analysis/GRExprEngine.cpp +++ b/clang/lib/Analysis/GRExprEngine.cpp @@ -905,16 +905,19 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred, // this right now, and since most logical expressions are used for branches, // the payoff is not likely to be large. Instead, we do eager evaluation. if (const GRState *newState = state->assume(X, true)) - MakeNode(Dst, B, Pred, newState->bindBlkExpr(B, MakeConstantVal(1U, B))); + MakeNode(Dst, B, Pred, + newState->bindBlkExpr(B, ValMgr.makeIntVal(1U, B->getType()))); if (const GRState *newState = state->assume(X, false)) - MakeNode(Dst, B, Pred, newState->bindBlkExpr(B, MakeConstantVal(0U, B))); + MakeNode(Dst, B, Pred, + newState->bindBlkExpr(B, ValMgr.makeIntVal(0U, B->getType()))); } else { // We took the LHS expression. Depending on whether we are '&&' or // '||' we know what the value of the expression is via properties of // the short-circuiting. - X = MakeConstantVal( B->getOpcode() == BinaryOperator::LAnd ? 0U : 1U, B); + X = ValMgr.makeIntVal(B->getOpcode() == BinaryOperator::LAnd ? 0U : 1U, + B->getType()); MakeNode(Dst, B, Pred, state->bindBlkExpr(B, X)); } } @@ -1614,14 +1617,16 @@ void GRExprEngine::EvalEagerlyAssume(NodeSet &Dst, NodeSet &Src, Expr *Ex) { if (isa(V)) { // First assume that the condition is true. if (const GRState *stateTrue = state->assume(V, true)) { - stateTrue = stateTrue->bindExpr(Ex, MakeConstantVal(1U, Ex)); + stateTrue = stateTrue->bindExpr(Ex, + ValMgr.makeIntVal(1U, Ex->getType())); Dst.Add(Builder->generateNode(PostStmtCustom(Ex, &EagerlyAssumeTag), stateTrue, Pred)); } // Next, assume that the condition is false. if (const GRState *stateFalse = state->assume(V, false)) { - stateFalse = stateFalse->bindExpr(Ex, MakeConstantVal(0U, Ex)); + stateFalse = stateFalse->bindExpr(Ex, + ValMgr.makeIntVal(0U, Ex->getType())); Dst.Add(Builder->generateNode(PostStmtCustom(Ex, &EagerlyAssumeTag), stateFalse, Pred)); } @@ -1724,12 +1729,11 @@ void GRExprEngine::VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S, const GRState *state = GetState(Pred); // Handle the case where the container still has elements. - QualType IntTy = getContext().IntTy; - SVal TrueV = NonLoc::MakeVal(getBasicVals(), 1, IntTy); + SVal TrueV = ValMgr.makeTruthVal(1); const GRState *hasElems = state->bindExpr(S, TrueV); // Handle the case where the container has no elements. - SVal FalseV = NonLoc::MakeVal(getBasicVals(), 0, IntTy); + SVal FalseV = ValMgr.makeTruthVal(0); const GRState *noElems = state->bindExpr(S, FalseV); if (loc::MemRegionVal* MV = dyn_cast(&ElementV)) @@ -1741,11 +1745,11 @@ void GRExprEngine::VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S, assert (Loc::IsLocType(T)); unsigned Count = Builder->getCurrentBlockCount(); SymbolRef Sym = SymMgr.getConjuredSymbol(elem, T, Count); - SVal V = Loc::MakeVal(getStoreManager().getRegionManager().getSymbolicRegion(Sym)); + SVal V = ValMgr.makeLoc(Sym); hasElems = hasElems->bindLoc(ElementV, V); // Bind the location to 'nil' on the false branch. - SVal nilV = loc::ConcreteInt(getBasicVals().getValue(0, T)); + SVal nilV = ValMgr.makeIntVal(0, T); noElems = noElems->bindLoc(ElementV, nilV); } @@ -2289,7 +2293,7 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, NodeTy* Pred, // Handle base case where the initializer has no elements. // e.g: static int* myArray[] = {}; if (NumInitElements == 0) { - SVal V = NonLoc::MakeCompoundVal(T, StartVals, getBasicVals()); + SVal V = ValMgr.makeCompoundVal(T, StartVals); MakeNode(Dst, E, Pred, state->bindExpr(E, V)); return; } @@ -2322,7 +2326,7 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, NodeTy* Pred, if (NewItr == ItrEnd) { // Now we have a list holding all init values. Make CompoundValData. - SVal V = NonLoc::MakeCompoundVal(T, NewVals, getBasicVals()); + SVal V = ValMgr.makeCompoundVal(T, NewVals); // Make final state and node. MakeNode(Dst, E, *NI, state->bindExpr(E, V)); @@ -2392,8 +2396,7 @@ void GRExprEngine::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex, amt = getContext().getTypeAlign(T) / 8; MakeNode(Dst, Ex, Pred, - GetState(Pred)->bindExpr(Ex, NonLoc::MakeVal(getBasicVals(), amt, - Ex->getType()))); + GetState(Pred)->bindExpr(Ex, ValMgr.makeIntVal(amt, Ex->getType()))); } @@ -2467,7 +2470,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, // For all other types, UnaryOperator::Float returns 0. assert (Ex->getType()->isIntegerType()); const GRState* state = GetState(*I); - SVal X = NonLoc::MakeVal(getBasicVals(), 0, Ex->getType()); + SVal X = ValMgr.makeZeroVal(Ex->getType()); MakeNode(Dst, U, *I, state->bindExpr(U, X)); } @@ -2570,7 +2573,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, // transfer functions as "0 == E". if (isa(V)) { - Loc X = Loc::MakeNull(getBasicVals()); + Loc X = ValMgr.makeNull(); SVal Result = EvalBinOp(state,BinaryOperator::EQ, cast(V), X, U->getType()); state = state->bindExpr(U, Result); @@ -2628,7 +2631,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, BinaryOperator::Opcode Op = U->isIncrementOp() ? BinaryOperator::Add : BinaryOperator::Sub; - SVal Result = EvalBinOp(state, Op, V2, MakeConstantVal(1U, U), + SVal Result = EvalBinOp(state, Op, V2, ValMgr.makeIntVal(1U,U->getType()), U->getType()); // Conjure a new symbol if necessary to recover precision. diff --git a/clang/lib/Analysis/GRSimpleVals.cpp b/clang/lib/Analysis/GRSimpleVals.cpp index 878f46d9d51a..480612113d10 100644 --- a/clang/lib/Analysis/GRSimpleVals.cpp +++ b/clang/lib/Analysis/GRSimpleVals.cpp @@ -84,7 +84,7 @@ SVal GRSimpleVals::EvalCast(GRExprEngine& Eng, Loc X, QualType T) { unsigned BitWidth = Eng.getContext().getTypeSize(T); if (!isa(X)) - return nonloc::LocAsInteger::Make(BasicVals, X, BitWidth); + return Eng.getValueManager().makeLocAsInteger(X, BitWidth); llvm::APSInt V = cast(X).getValue(); V.setIsUnsigned(T->isUnsignedIntegerType() || Loc::IsLocType(T)); @@ -133,8 +133,8 @@ SVal GRSimpleVals::DetermEvalBinOpNN(GRExprEngine& Eng, BinaryOperator::Opcode Op, NonLoc L, NonLoc R, QualType T) { - BasicValueFactory& BasicVals = Eng.getBasicVals(); + ValueManager& ValMgr = Eng.getValueManager(); unsigned subkind = L.getSubKind(); while (1) { @@ -157,16 +157,15 @@ SVal GRSimpleVals::DetermEvalBinOpNN(GRExprEngine& Eng, llvm::APSInt V = cast(R).getValue(); V.setIsUnsigned(true); V.extOrTrunc(Ctx.getTypeSize(Ctx.VoidPtrTy)); - return EvalBinOp(Eng, Op, LL, - loc::ConcreteInt(BasicVals.getValue(V))); + return EvalBinOp(Eng, Op, LL, ValMgr.makeLoc(V)); } default: switch (Op) { case BinaryOperator::EQ: - return NonLoc::MakeIntTruthVal(BasicVals, false); + return ValMgr.makeTruthVal(false); case BinaryOperator::NE: - return NonLoc::MakeIntTruthVal(BasicVals, true); + return ValMgr.makeTruthVal(true); default: // This case also handles pointer arithmetic. return UnknownVal(); @@ -289,7 +288,7 @@ SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, const GRState *state, SVal GRSimpleVals::EvalEquality(GRExprEngine& Eng, Loc L, Loc R, bool isEqual) { - BasicValueFactory& BasicVals = Eng.getBasicVals(); + ValueManager& ValMgr = Eng.getValueManager(); switch (L.getSubKind()) { @@ -307,7 +306,7 @@ SVal GRSimpleVals::EvalEquality(GRExprEngine& Eng, Loc L, Loc R, bool isEqual) { if (!isEqual) b = !b; - return NonLoc::MakeIntTruthVal(BasicVals, b); + return ValMgr.makeTruthVal(b); } else if (SymbolRef Sym = R.getAsSymbol()) { const SymIntExpr * SE = @@ -339,10 +338,10 @@ SVal GRSimpleVals::EvalEquality(GRExprEngine& Eng, Loc L, Loc R, bool isEqual) { // Fall-through. case loc::GotoLabelKind: - return NonLoc::MakeIntTruthVal(BasicVals, isEqual ? L == R : L != R); + return ValMgr.makeTruthVal(isEqual ? L == R : L != R); } - return NonLoc::MakeIntTruthVal(BasicVals, isEqual ? false : true); + return ValMgr.makeTruthVal(isEqual ? false : true); } //===----------------------------------------------------------------------===// diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp index f0374bd231c5..f76807beb29e 100644 --- a/clang/lib/Analysis/RegionStore.cpp +++ b/clang/lib/Analysis/RegionStore.cpp @@ -513,7 +513,7 @@ SVal RegionStoreManager::getLValueElement(const GRState *St, if (OffI.isUnsigned()) { llvm::APSInt Tmp = OffI; Tmp.setIsSigned(true); - Offset = NonLoc::MakeVal(getBasicVals(), Tmp); + Offset = ValMgr.makeIntVal(Tmp); } } return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset, @@ -547,7 +547,7 @@ SVal RegionStoreManager::getLValueElement(const GRState *St, Tmp.setIsSigned(true); Tmp += BaseIdxI; // Compute the new offset. - NewIdx = NonLoc::MakeVal(getBasicVals(), Tmp); + NewIdx = ValMgr.makeIntVal(Tmp); } else NewIdx = nonloc::ConcreteInt(getBasicVals().getValue(BaseIdxI + OffI)); @@ -572,7 +572,7 @@ SVal RegionStoreManager::getSizeInElements(const GRState *state, if (const ConstantArrayType* CAT = dyn_cast(T)) { // return the size as signed integer. - return NonLoc::MakeVal(getBasicVals(), CAT->getSize(), false); + return ValMgr.makeIntVal(CAT->getSize(), false); } const QualType* CastTy = state->get(VR); @@ -585,19 +585,19 @@ SVal RegionStoreManager::getSizeInElements(const GRState *state, uint64_t EleSize = getContext().getTypeSize(EleTy); uint64_t VarSize = getContext().getTypeSize(VarTy); assert(VarSize != 0); - return NonLoc::MakeIntVal(getBasicVals(), VarSize / EleSize, false); + return ValMgr.makeIntVal(VarSize/EleSize, false); } // Clients can use ordinary variables as if they were arrays. These // essentially are arrays of size 1. - return NonLoc::MakeIntVal(getBasicVals(), 1, false); + return ValMgr.makeIntVal(1, false); } if (const StringRegion* SR = dyn_cast(R)) { const StringLiteral* Str = SR->getStringLiteral(); // We intentionally made the size value signed because it participates in // operations with signed indices. - return NonLoc::MakeIntVal(getBasicVals(), Str->getByteLength()+1, false); + return ValMgr.makeIntVal(Str->getByteLength()+1, false); } if (const FieldRegion* FR = dyn_cast(R)) { @@ -802,7 +802,7 @@ SVal RegionStoreManager::EvalBinOp(const GRState *state, const MemRegion* NewER = MRMgr.getElementRegion(ER->getElementType(), NewIdx,ER->getSuperRegion(), getContext()); - return Loc::MakeVal(NewER); + return ValMgr.makeLoc(NewER); } @@ -986,7 +986,7 @@ SVal RegionStoreManager::RetrieveStruct(const GRState *state, StructVal = getBasicVals().consVals(FieldValue, StructVal); } - return NonLoc::MakeCompoundVal(T, StructVal, getBasicVals()); + return ValMgr.makeCompoundVal(T, StructVal); } SVal RegionStoreManager::RetrieveArray(const GRState *state, @@ -1000,7 +1000,7 @@ SVal RegionStoreManager::RetrieveArray(const GRState *state, llvm::APSInt i = getBasicVals().getZeroWithPtrWidth(false); for (; i < Size; ++i) { - SVal Idx = NonLoc::MakeVal(getBasicVals(), i); + SVal Idx = ValMgr.makeIntVal(i); ElementRegion* ER = MRMgr.getElementRegion(CAT->getElementType(), Idx, R, getContext()); QualType ETy = ER->getElementType(); @@ -1008,7 +1008,7 @@ SVal RegionStoreManager::RetrieveArray(const GRState *state, ArrayVal = getBasicVals().consVals(ElementVal, ArrayVal); } - return NonLoc::MakeCompoundVal(T, ArrayVal, getBasicVals()); + return ValMgr.makeCompoundVal(T, ArrayVal); } //===----------------------------------------------------------------------===// @@ -1061,7 +1061,7 @@ const GRState *RegionStoreManager::BindDecl(const GRState *state, if (T->isStructureType()) return BindStruct(state, VR, InitVal); - return Bind(state, Loc::MakeVal(VR), InitVal); + return Bind(state, ValMgr.makeLoc(VR), InitVal); } // FIXME: this method should be merged into Bind(). @@ -1103,7 +1103,7 @@ const GRState *RegionStoreManager::BindArray(const GRState *state, SVal Idx = ValMgr.makeIntVal(i); ElementRegion* ER = MRMgr.getElementRegion(ElementTy, Idx,R,getContext()); - SVal V = NonLoc::MakeVal(getBasicVals(), str[j], sizeof(char)*8, true); + SVal V = ValMgr.makeIntVal(str[j], sizeof(char)*8, true); state = Bind(state, loc::MemRegionVal(ER), V); } @@ -1124,7 +1124,7 @@ const GRState *RegionStoreManager::BindArray(const GRState *state, if (CAT->getElementType()->isStructureType()) state = BindStruct(state, ER, *VI); else - state = Bind(state, Loc::MakeVal(ER), *VI); + state = Bind(state, ValMgr.makeLoc(ER), *VI); } // If the init list is shorter than the array length, bind the rest elements @@ -1134,7 +1134,7 @@ const GRState *RegionStoreManager::BindArray(const GRState *state, SVal Idx = ValMgr.makeIntVal(i); ElementRegion* ER = MRMgr.getElementRegion(ElementTy, Idx,R,getContext()); SVal V = ValMgr.makeZeroVal(ElementTy); - state = Bind(state, Loc::MakeVal(ER), V); + state = Bind(state, ValMgr.makeLoc(ER), V); ++i; } } @@ -1178,7 +1178,7 @@ RegionStoreManager::BindStruct(const GRState *state, const TypedRegion* R, FieldRegion* FR = MRMgr.getFieldRegion(*FI, R); if (Loc::IsLocType(FTy) || FTy->isIntegerType()) - state = Bind(state, Loc::MakeVal(FR), *VI); + state = Bind(state, ValMgr.makeLoc(FR), *VI); else if (FTy->isArrayType()) state = BindArray(state, FR, *VI); else if (FTy->isStructureType()) @@ -1190,7 +1190,7 @@ RegionStoreManager::BindStruct(const GRState *state, const TypedRegion* R, QualType FTy = (*FI)->getType(); if (FTy->isIntegerType()) { FieldRegion* FR = MRMgr.getFieldRegion(*FI, R); - state = Bind(state, Loc::MakeVal(FR), ValMgr.makeZeroVal(FTy)); + state = Bind(state, ValMgr.makeLoc(FR), ValMgr.makeZeroVal(FTy)); } ++FI; @@ -1213,7 +1213,7 @@ const GRState *RegionStoreManager::KillStruct(const GRState *state, const MemRegion* R = I.getKey(); if (const SubRegion* subRegion = dyn_cast(R)) if (subRegion->isSubRegionOf(R)) - store = Remove(store, Loc::MakeVal(subRegion)); + store = Remove(store, ValMgr.makeLoc(subRegion)); // FIXME: Maybe we should also remove the bindings for the "views" of the // subregions. } @@ -1409,7 +1409,7 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc, continue; // Remove this dead region from the store. - store = Remove(store, Loc::MakeVal(R)); + store = Remove(store, ValMgr.makeLoc(R)); // Mark all non-live symbols that this region references as dead. if (const SymbolicRegion* SymR = dyn_cast(R)) diff --git a/clang/lib/Analysis/SVals.cpp b/clang/lib/Analysis/SVals.cpp index a0907404ddbe..dd9490bebb96 100644 --- a/clang/lib/Analysis/SVals.cpp +++ b/clang/lib/Analysis/SVals.cpp @@ -236,65 +236,6 @@ SVal loc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals, return UndefinedVal(); } - -NonLoc NonLoc::MakeIntVal(BasicValueFactory& BasicVals, uint64_t X, - bool isUnsigned) { - return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned)); -} - -NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, uint64_t X, - unsigned BitWidth, bool isUnsigned) { - return nonloc::ConcreteInt(BasicVals.getValue(X, BitWidth, isUnsigned)); -} - -NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T) { - return nonloc::ConcreteInt(BasicVals.getValue(X, T)); -} - -NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, const IntegerLiteral* I) { - - return nonloc::ConcreteInt(BasicVals.getValue(APSInt(I->getValue(), - I->getType()->isUnsignedIntegerType()))); -} - -NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, const llvm::APInt& I, - bool isUnsigned) { - return nonloc::ConcreteInt(BasicVals.getValue(I, isUnsigned)); -} - -NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, const llvm::APSInt& I) { - return nonloc::ConcreteInt(BasicVals.getValue(I)); -} - -NonLoc NonLoc::MakeIntTruthVal(BasicValueFactory& BasicVals, bool b) { - return nonloc::ConcreteInt(BasicVals.getTruthValue(b)); -} - - -NonLoc NonLoc::MakeCompoundVal(QualType T, llvm::ImmutableList Vals, - BasicValueFactory& BasicVals) { - return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals)); -} - -nonloc::LocAsInteger nonloc::LocAsInteger::Make(BasicValueFactory& Vals, Loc V, - unsigned Bits) { - return LocAsInteger(Vals.getPersistentSValWithData(V, Bits)); -} - -//===----------------------------------------------------------------------===// -// Utility methods for constructing Locs. -//===----------------------------------------------------------------------===// - -Loc Loc::MakeVal(const MemRegion* R) { return loc::MemRegionVal(R); } - -Loc Loc::MakeVal(const AddrLabelExpr *E) { - return loc::GotoLabel(E->getLabel()); -} - -Loc Loc::MakeNull(BasicValueFactory &BasicVals) { - return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth()); -} - //===----------------------------------------------------------------------===// // Pretty-Printing. //===----------------------------------------------------------------------===// diff --git a/clang/lib/Analysis/ValueManager.cpp b/clang/lib/Analysis/ValueManager.cpp index 1a6e1e467592..724a2e92d744 100644 --- a/clang/lib/Analysis/ValueManager.cpp +++ b/clang/lib/Analysis/ValueManager.cpp @@ -24,32 +24,20 @@ using namespace llvm; SVal ValueManager::makeZeroVal(QualType T) { if (Loc::IsLocType(T)) - return Loc::MakeNull(BasicVals); + return makeNull(); if (T->isIntegerType()) - return NonLoc::MakeVal(BasicVals, 0, T); + return makeIntVal(0, T); // FIXME: Handle floats. // FIXME: Handle structs. return UnknownVal(); } -SVal ValueManager::makeZeroArrayIndex() { - return nonloc::ConcreteInt(BasicVals.getZeroWithPtrWidth(false)); -} - //===----------------------------------------------------------------------===// // Utility methods for constructing Non-Locs. //===----------------------------------------------------------------------===// -NonLoc ValueManager::makeNonLoc(SymbolRef sym) { - return nonloc::SymbolVal(sym); -} - -NonLoc ValueManager::makeIntVal(const APSInt& V) { - return nonloc::ConcreteInt(BasicVals.getValue(V)); -} - NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, const APSInt& v, QualType T) { // The Environment ensures we always get a persistent APSInt in @@ -66,9 +54,6 @@ NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, return nonloc::SymExprVal(SymMgr.getSymSymExpr(lhs, op, rhs, T)); } -NonLoc ValueManager::makeTruthVal(bool b, QualType T) { - return nonloc::ConcreteInt(BasicVals.getTruthValue(b, T)); -} SVal ValueManager::getRegionValueSymbolVal(const MemRegion* R, QualType T) { SymbolRef sym = SymMgr.getRegionValueSymbol(R, T); @@ -80,15 +65,15 @@ SVal ValueManager::getRegionValueSymbolVal(const MemRegion* R, QualType T) { // If T is of function pointer type, create a CodeTextRegion wrapping a // symbol. if (T->isFunctionPointerType()) { - return Loc::MakeVal(MemMgr.getCodeTextRegion(sym, T)); + return loc::MemRegionVal(MemMgr.getCodeTextRegion(sym, T)); } if (Loc::IsLocType(T)) - return Loc::MakeVal(MemMgr.getSymbolicRegion(sym)); + return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); // Only handle integers for now. if (T->isIntegerType() && T->isScalarType()) - return makeNonLoc(sym); + return nonloc::SymbolVal(sym); } return UnknownVal(); @@ -101,14 +86,14 @@ SVal ValueManager::getConjuredSymbolVal(const Expr* E, unsigned Count) { // If T is of function pointer type, create a CodeTextRegion wrapping a // symbol. if (T->isFunctionPointerType()) { - return Loc::MakeVal(MemMgr.getCodeTextRegion(sym, T)); + return loc::MemRegionVal(MemMgr.getCodeTextRegion(sym, T)); } if (Loc::IsLocType(T)) - return Loc::MakeVal(MemMgr.getSymbolicRegion(sym)); + return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); if (T->isIntegerType() && T->isScalarType()) - return makeNonLoc(sym); + return nonloc::SymbolVal(sym); return UnknownVal(); } @@ -121,14 +106,14 @@ SVal ValueManager::getConjuredSymbolVal(const Expr* E, QualType T, // If T is of function pointer type, create a CodeTextRegion wrapping a // symbol. if (T->isFunctionPointerType()) { - return Loc::MakeVal(MemMgr.getCodeTextRegion(sym, T)); + return loc::MemRegionVal(MemMgr.getCodeTextRegion(sym, T)); } if (Loc::IsLocType(T)) - return Loc::MakeVal(MemMgr.getSymbolicRegion(sym)); + return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); if (T->isIntegerType() && T->isScalarType()) - return makeNonLoc(sym); + return nonloc::SymbolVal(sym); return UnknownVal(); } @@ -138,4 +123,3 @@ SVal ValueManager::getFunctionPointer(const FunctionDecl* FD) { = MemMgr.getCodeTextRegion(FD, Context.getPointerType(FD->getType())); return loc::MemRegionVal(R); } -