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