This patch did the following renaming. There should be no functional changes.

RVal => SVal
LVal => Loc
NonLVal => NonLoc
lval => loc
nonlval => nonloc

llvm-svn: 57671
This commit is contained in:
Zhongxing Xu 2008-10-17 05:57:07 +00:00
parent 0dd213f8f5
commit 27f174214d
25 changed files with 870 additions and 867 deletions

View File

@ -27,7 +27,7 @@ namespace llvm {
namespace clang {
class RVal;
class SVal;
class BasicValueFactory {
typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> >
@ -42,12 +42,12 @@ class BasicValueFactory {
APSIntSetTy APSIntSet;
SymIntCSetTy SymIntCSet;
void* PersistentRVals;
void* PersistentRValPairs;
void* PersistentSVals;
void* PersistentSValPairs;
public:
BasicValueFactory(ASTContext& ctx, llvm::BumpPtrAllocator& Alloc)
: Ctx(ctx), BPAlloc(Alloc), PersistentRVals(0), PersistentRValPairs(0) {}
: Ctx(ctx), BPAlloc(Alloc), PersistentSVals(0), PersistentSValPairs(0) {}
~BasicValueFactory();
@ -72,13 +72,13 @@ public:
const llvm::APSInt& V1,
const llvm::APSInt& V2);
const std::pair<RVal, uintptr_t>&
getPersistentRValWithData(const RVal& V, uintptr_t Data);
const std::pair<SVal, uintptr_t>&
getPersistentSValWithData(const SVal& V, uintptr_t Data);
const std::pair<RVal, RVal>&
getPersistentRValPair(const RVal& V1, const RVal& V2);
const std::pair<SVal, SVal>&
getPersistentSValPair(const SVal& V1, const SVal& V2);
const RVal* getPersistentRVal(RVal X);
const SVal* getPersistentSVal(SVal X);
};
} // end clang namespace

View File

@ -25,14 +25,14 @@ namespace clang {
class GRState;
class GRStateManager;
class RVal;
class SVal;
class SymbolID;
class ConstraintManager {
public:
virtual ~ConstraintManager();
virtual const GRState* Assume(const GRState* St, RVal Cond, bool Assumption,
bool& isFeasible) = 0;
virtual const GRState* Assume(const GRState* St, SVal Cond,
bool Assumption, bool& isFeasible) = 0;
virtual const GRState* AddNE(const GRState* St, SymbolID sym,
const llvm::APSInt& V) = 0;

View File

@ -36,7 +36,7 @@ private:
friend class EnvironmentManager;
// Type definitions.
typedef llvm::ImmutableMap<Expr*,RVal> BindingsTy;
typedef llvm::ImmutableMap<Expr*,SVal> BindingsTy;
// Data.
BindingsTy SubExprBindings;
@ -55,28 +55,28 @@ public:
beb_iterator beb_begin() const { return BlkExprBindings.begin(); }
beb_iterator beb_end() const { return BlkExprBindings.end(); }
RVal LookupSubExpr(Expr* E) const {
const RVal* X = SubExprBindings.lookup(E);
SVal LookupSubExpr(Expr* E) const {
const SVal* X = SubExprBindings.lookup(E);
return X ? *X : UnknownVal();
}
RVal LookupBlkExpr(Expr* E) const {
const RVal* X = BlkExprBindings.lookup(E);
SVal LookupBlkExpr(Expr* E) const {
const SVal* X = BlkExprBindings.lookup(E);
return X ? *X : UnknownVal();
}
RVal LookupExpr(Expr* E) const {
const RVal* X = SubExprBindings.lookup(E);
SVal LookupExpr(Expr* E) const {
const SVal* X = SubExprBindings.lookup(E);
if (X) return *X;
X = BlkExprBindings.lookup(E);
return X ? *X : UnknownVal();
}
RVal GetRVal(Expr* Ex, BasicValueFactory& BasicVals) const;
RVal GetRVal(const Expr* Ex, BasicValueFactory& BasicVals) const {
return GetRVal(const_cast<Expr*>(Ex), BasicVals);
SVal GetSVal(Expr* Ex, BasicValueFactory& BasicVals) const;
SVal GetSVal(const Expr* Ex, BasicValueFactory& BasicVals) const {
return GetSVal(const_cast<Expr*>(Ex), BasicVals);
}
RVal GetBlkExprRVal(Expr* Ex, BasicValueFactory& BasicVals) const;
SVal GetBlkExprSVal(Expr* Ex, BasicValueFactory& BasicVals) const;
/// Profile - Profile the contents of an Environment object for use
/// in a FoldingSet.
@ -120,11 +120,11 @@ public:
return Environment(F.Remove(Env.SubExprBindings, E), Env.BlkExprBindings);
}
Environment AddBlkExpr(const Environment& Env, Expr* E, RVal V) {
return Environment(Env.SubExprBindings, F.Add(Env.BlkExprBindings, E, V));
Environment AddBlkExpr(const Environment& Env, Expr* E, SVal V) {
return Environment(Env.SubExprBindings, F.Add(Env.BlkExprBindings, E, V));
}
Environment AddSubExpr(const Environment& Env, Expr* E, RVal V) {
Environment AddSubExpr(const Environment& Env, Expr* E, SVal V) {
return Environment(F.Add(Env.SubExprBindings, E, V), Env.BlkExprBindings);
}
@ -139,7 +139,7 @@ public:
return Environment(F.GetEmptyMap(), F.GetEmptyMap());
}
Environment SetRVal(const Environment& Env, Expr* E, RVal V,
Environment SetSVal(const Environment& Env, Expr* E, SVal V,
bool isBlkExpr, bool Invalidate);
Environment RemoveDeadBindings(Environment Env, Stmt* Loc,

View File

@ -252,11 +252,11 @@ public:
}
bool isImplicitBadDivide(const NodeTy* N) const {
return N->isSink() && ImplicitBadDivides.count(const_cast<NodeTy*>(N)) != 0;
return N->isSink() && ImplicitBadDivides.count(const_cast<NodeTy*>(N)) != 0;
}
bool isExplicitBadDivide(const NodeTy* N) const {
return N->isSink() && ExplicitBadDivides.count(const_cast<NodeTy*>(N)) != 0;
return N->isSink() && ExplicitBadDivides.count(const_cast<NodeTy*>(N)) != 0;
}
bool isNoReturnCall(const NodeTy* N) const {
@ -402,52 +402,52 @@ protected:
public:
const GRState* SetRVal(const GRState* St, Expr* Ex, RVal V) {
return StateMgr.SetRVal(St, Ex, V);
const GRState* SetSVal(const GRState* St, Expr* Ex, SVal V) {
return StateMgr.SetSVal(St, Ex, V);
}
const GRState* SetRVal(const GRState* St, const Expr* Ex, RVal V) {
return SetRVal(St, const_cast<Expr*>(Ex), V);
const GRState* SetSVal(const GRState* St, const Expr* Ex, SVal V) {
return SetSVal(St, const_cast<Expr*>(Ex), V);
}
protected:
const GRState* SetBlkExprRVal(const GRState* St, Expr* Ex, RVal V) {
return StateMgr.SetRVal(St, Ex, V, true, false);
const GRState* SetBlkExprSVal(const GRState* St, Expr* Ex, SVal V) {
return StateMgr.SetSVal(St, Ex, V, true, false);
}
const GRState* SetRVal(const GRState* St, LVal LV, RVal V) {
return StateMgr.SetRVal(St, LV, V);
const GRState* SetSVal(const GRState* St, Loc LV, SVal V) {
return StateMgr.SetSVal(St, LV, V);
}
RVal GetRVal(const GRState* St, Expr* Ex) {
return StateMgr.GetRVal(St, Ex);
SVal GetSVal(const GRState* St, Expr* Ex) {
return StateMgr.GetSVal(St, Ex);
}
RVal GetRVal(const GRState* St, const Expr* Ex) {
return GetRVal(St, const_cast<Expr*>(Ex));
SVal GetSVal(const GRState* St, const Expr* Ex) {
return GetSVal(St, const_cast<Expr*>(Ex));
}
RVal GetBlkExprRVal(const GRState* St, Expr* Ex) {
return StateMgr.GetBlkExprRVal(St, Ex);
SVal GetBlkExprSVal(const GRState* St, Expr* Ex) {
return StateMgr.GetBlkExprSVal(St, Ex);
}
RVal GetRVal(const GRState* St, LVal LV, QualType T = QualType()) {
return StateMgr.GetRVal(St, LV, T);
SVal GetSVal(const GRState* St, Loc LV, QualType T = QualType()) {
return StateMgr.GetSVal(St, LV, T);
}
inline NonLVal MakeConstantVal(uint64_t X, Expr* Ex) {
return NonLVal::MakeVal(getBasicVals(), X, Ex->getType());
inline NonLoc MakeConstantVal(uint64_t X, Expr* Ex) {
return NonLoc::MakeVal(getBasicVals(), X, Ex->getType());
}
/// Assume - Create new state by assuming that a given expression
/// is true or false.
const GRState* Assume(const GRState* St, RVal Cond, bool Assumption,
const GRState* Assume(const GRState* St, SVal Cond, bool Assumption,
bool& isFeasible) {
return StateMgr.Assume(St, Cond, Assumption, isFeasible);
}
const GRState* Assume(const GRState* St, LVal Cond, bool Assumption,
const GRState* Assume(const GRState* St, Loc Cond, bool Assumption,
bool& isFeasible) {
return StateMgr.Assume(St, Cond, Assumption, isFeasible);
}
@ -539,44 +539,44 @@ protected:
bool asLValue);
bool CheckDivideZero(Expr* Ex, const GRState* St, NodeTy* Pred,
RVal Denom);
SVal Denom);
RVal EvalCast(RVal X, QualType CastT) {
SVal EvalCast(SVal X, QualType CastT) {
if (X.isUnknownOrUndef())
return X;
if (isa<LVal>(X))
return getTF().EvalCast(*this, cast<LVal>(X), CastT);
if (isa<Loc>(X))
return getTF().EvalCast(*this, cast<Loc>(X), CastT);
else
return getTF().EvalCast(*this, cast<NonLVal>(X), CastT);
return getTF().EvalCast(*this, cast<NonLoc>(X), CastT);
}
RVal EvalMinus(UnaryOperator* U, RVal X) {
return X.isValid() ? getTF().EvalMinus(*this, U, cast<NonLVal>(X)) : X;
SVal EvalMinus(UnaryOperator* U, SVal X) {
return X.isValid() ? getTF().EvalMinus(*this, U, cast<NonLoc>(X)) : X;
}
RVal EvalComplement(RVal X) {
return X.isValid() ? getTF().EvalComplement(*this, cast<NonLVal>(X)) : X;
SVal EvalComplement(SVal X) {
return X.isValid() ? getTF().EvalComplement(*this, cast<NonLoc>(X)) : X;
}
RVal EvalBinOp(BinaryOperator::Opcode Op, NonLVal L, NonLVal R) {
SVal EvalBinOp(BinaryOperator::Opcode Op, NonLoc L, NonLoc R) {
return R.isValid() ? getTF().DetermEvalBinOpNN(getStateManager(), Op, L, R)
: R;
}
RVal EvalBinOp(BinaryOperator::Opcode Op, NonLVal L, RVal R) {
SVal EvalBinOp(BinaryOperator::Opcode Op, NonLoc L, SVal R) {
return R.isValid() ? getTF().DetermEvalBinOpNN(getStateManager(), Op, L,
cast<NonLVal>(R)) : R;
cast<NonLoc>(R)) : R;
}
void EvalBinOp(ExplodedNodeSet<GRState>& Dst, Expr* Ex,
BinaryOperator::Opcode Op, NonLVal L, NonLVal R,
BinaryOperator::Opcode Op, NonLoc L, NonLoc R,
ExplodedNode<GRState>* Pred);
void EvalBinOp(GRStateSet& OStates, const GRState* St, Expr* Ex,
BinaryOperator::Opcode Op, NonLVal L, NonLVal R);
BinaryOperator::Opcode Op, NonLoc L, NonLoc R);
RVal EvalBinOp(BinaryOperator::Opcode Op, RVal L, RVal R) {
SVal EvalBinOp(BinaryOperator::Opcode Op, SVal L, SVal R) {
if (L.isUndef() || R.isUndef())
return UndefinedVal();
@ -584,30 +584,30 @@ protected:
if (L.isUnknown() || R.isUnknown())
return UnknownVal();
if (isa<LVal>(L)) {
if (isa<LVal>(R))
return getTF().EvalBinOp(*this, Op, cast<LVal>(L), cast<LVal>(R));
if (isa<Loc>(L)) {
if (isa<Loc>(R))
return getTF().EvalBinOp(*this, Op, cast<Loc>(L), cast<Loc>(R));
else
return getTF().EvalBinOp(*this, Op, cast<LVal>(L), cast<NonLVal>(R));
return getTF().EvalBinOp(*this, Op, cast<Loc>(L), cast<NonLoc>(R));
}
if (isa<LVal>(R)) {
if (isa<Loc>(R)) {
// Support pointer arithmetic where the increment/decrement operand
// is on the left and the pointer on the right.
assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub);
// Commute the operands.
return getTF().EvalBinOp(*this, Op, cast<LVal>(R),
cast<NonLVal>(L));
return getTF().EvalBinOp(*this, Op, cast<Loc>(R),
cast<NonLoc>(L));
}
else
return getTF().DetermEvalBinOpNN(getStateManager(), Op, cast<NonLVal>(L),
cast<NonLVal>(R));
return getTF().DetermEvalBinOpNN(getStateManager(), Op, cast<NonLoc>(L),
cast<NonLoc>(R));
}
void EvalCall(NodeSet& Dst, CallExpr* CE, RVal L, NodeTy* Pred) {
void EvalCall(NodeSet& Dst, CallExpr* CE, SVal L, NodeTy* Pred) {
assert (Builder && "GRStmtNodeBuilder must be defined.");
getTF().EvalCall(Dst, *this, *Builder, CE, L, Pred);
}
@ -618,24 +618,25 @@ protected:
}
void EvalStore(NodeSet& Dst, Expr* E, NodeTy* Pred, const GRState* St,
RVal TargetLV, RVal Val);
SVal TargetLV, SVal Val);
void EvalStore(NodeSet& Dst, Expr* E, Expr* StoreE, NodeTy* Pred,
const GRState* St, RVal TargetLV, RVal Val);
const GRState* St, SVal TargetLV, SVal Val);
// FIXME: The "CheckOnly" option exists only because Array and Field
// loads aren't fully implemented. Eventually this option will go away.
void EvalLoad(NodeSet& Dst, Expr* Ex, NodeTy* Pred,
const GRState* St, RVal location, bool CheckOnly = false);
const GRState* St, SVal location, bool CheckOnly = false);
const GRState* EvalLocation(Expr* Ex, NodeTy* Pred,
const GRState* St, RVal location,
bool isLoad = false);
const GRState* St, SVal location,
bool isLoad = false);
void EvalReturn(NodeSet& Dst, ReturnStmt* s, NodeTy* Pred);
const GRState* MarkBranch(const GRState* St, Stmt* Terminator, bool branchTaken);
const GRState* MarkBranch(const GRState* St, Stmt* Terminator,
bool branchTaken);
};
} // end clang namespace

View File

@ -61,7 +61,7 @@ template <typename T> struct GRStateTrait {
};
//===----------------------------------------------------------------------===//
// GRState- An ImmutableMap type Stmt*/Decl*/Symbols to RVals.
// GRState- An ImmutableMap type Stmt*/Decl*/Symbols to SVals.
//===----------------------------------------------------------------------===//
/// GRState - This class encapsulates the actual data values for
@ -129,7 +129,7 @@ public:
Profile(ID, this);
}
RVal LookupExpr(Expr* E) const {
SVal LookupExpr(Expr* E) const {
return Env.LookupExpr(E);
}
@ -174,7 +174,7 @@ public:
// Tags used for the Generic Data Map.
struct NullDerefTag {
static int TagInt;
typedef const RVal* data_type;
typedef const SVal* data_type;
};
};
@ -251,7 +251,7 @@ private:
/// a particular function. This is used to unique states.
llvm::FoldingSet<GRState> StateSet;
/// ValueMgr - Object that manages the data for all created RVals.
/// ValueMgr - Object that manages the data for all created SVals.
BasicValueFactory BasicVals;
/// SymMgr - Object that manages the symbol information.
@ -268,7 +268,7 @@ private:
CFG& cfg;
/// TF - Object that represents a bundle of transfer functions
/// for manipulating and creating RVals.
/// for manipulating and creating SVals.
GRTransferFuncs* TF;
/// Liveness - live-variables information of the ValueDecl* and block-level
@ -282,8 +282,8 @@ private:
}
// FIXME: Remove when we do lazy initializaton of variable bindings.
// const GRState* BindVar(const GRState* St, VarDecl* D, RVal V) {
// return SetRVal(St, getLVal(D), V);
// const GRState* BindVar(const GRState* St, VarDecl* D, SVal V) {
// return SetSVal(St, getLoc(D), V);
// }
public:
@ -342,44 +342,44 @@ public:
}
// Get the lvalue for a variable reference.
RVal GetLValue(const GRState* St, const VarDecl* D) {
SVal GetLValue(const GRState* St, const VarDecl* D) {
return StoreMgr->getLValueVar(St, D);
}
// Get the lvalue for an ivar reference.
RVal GetLValue(const GRState* St, const ObjCIvarDecl* D, RVal Base) {
SVal GetLValue(const GRState* St, const ObjCIvarDecl* D, SVal Base) {
return StoreMgr->getLValueIvar(St, D, Base);
}
// Get the lvalue for a field reference.
RVal GetLValue(const GRState* St, const FieldDecl* D, RVal Base) {
SVal GetLValue(const GRState* St, const FieldDecl* D, SVal Base) {
return StoreMgr->getLValueField(St, D, Base);
}
// Get the lvalue for an array index.
RVal GetLValue(const GRState* St, RVal Base, RVal Idx) {
SVal GetLValue(const GRState* St, SVal Base, SVal Idx) {
return StoreMgr->getLValueElement(St, Base, Idx);
}
// Methods that query & manipulate the Environment.
RVal GetRVal(const GRState* St, Expr* Ex) {
return St->getEnvironment().GetRVal(Ex, BasicVals);
SVal GetSVal(const GRState* St, Expr* Ex) {
return St->getEnvironment().GetSVal(Ex, BasicVals);
}
RVal GetRVal(const GRState* St, const Expr* Ex) {
return St->getEnvironment().GetRVal(Ex, BasicVals);
SVal GetSVal(const GRState* St, const Expr* Ex) {
return St->getEnvironment().GetSVal(Ex, BasicVals);
}
RVal GetBlkExprRVal(const GRState* St, Expr* Ex) {
return St->getEnvironment().GetBlkExprRVal(Ex, BasicVals);
SVal GetBlkExprSVal(const GRState* St, Expr* Ex) {
return St->getEnvironment().GetBlkExprSVal(Ex, BasicVals);
}
const GRState* SetRVal(const GRState* St, Expr* Ex, RVal V,
const GRState* SetSVal(const GRState* St, Expr* Ex, SVal V,
bool isBlkExpr, bool Invalidate) {
const Environment& OldEnv = St->getEnvironment();
Environment NewEnv = EnvMgr.SetRVal(OldEnv, Ex, V, isBlkExpr, Invalidate);
Environment NewEnv = EnvMgr.SetSVal(OldEnv, Ex, V, isBlkExpr, Invalidate);
if (NewEnv == OldEnv)
return St;
@ -389,7 +389,7 @@ public:
return getPersistentState(NewSt);
}
const GRState* SetRVal(const GRState* St, Expr* Ex, RVal V,
const GRState* SetSVal(const GRState* St, Expr* Ex, SVal V,
bool Invalidate = true) {
bool isBlkExpr = false;
@ -403,7 +403,7 @@ public:
return St;
}
return SetRVal(St, Ex, V, isBlkExpr, Invalidate);
return SetSVal(St, Ex, V, isBlkExpr, Invalidate);
}
// Methods that manipulate the GDM.
@ -421,21 +421,21 @@ public:
}
RVal GetRVal(const GRState* St, LVal LV, QualType T = QualType()) {
return StoreMgr->GetRVal(St->getStore(), LV, T);
SVal GetSVal(const GRState* St, Loc LV, QualType T = QualType()) {
return StoreMgr->GetSVal(St->getStore(), LV, T);
}
void SetRVal(GRState& St, LVal LV, RVal V) {
St.St = StoreMgr->SetRVal(St.St, LV, V);
void SetSVal(GRState& St, Loc LV, SVal V) {
St.St = StoreMgr->SetSVal(St.St, LV, V);
}
const GRState* SetRVal(const GRState* St, LVal LV, RVal V);
const GRState* SetSVal(const GRState* St, Loc LV, SVal V);
void Unbind(GRState& St, LVal LV) {
void Unbind(GRState& St, Loc LV) {
St.St = StoreMgr->Remove(St.St, LV);
}
const GRState* Unbind(const GRState* St, LVal LV);
const GRState* Unbind(const GRState* St, Loc LV);
const GRState* getPersistentState(GRState& Impl);
@ -482,7 +482,7 @@ public:
return GRStateTrait<T>::MakeContext(p);
}
const GRState* Assume(const GRState* St, RVal Cond, bool Assumption,
const GRState* Assume(const GRState* St, SVal Cond, bool Assumption,
bool& isFeasible) {
return ConstraintMgr->Assume(St, Cond, Assumption, isFeasible);
}
@ -510,33 +510,33 @@ public:
operator const GRState*() const { return St; }
GRStateManager& getManager() const { return *Mgr; }
RVal GetRVal(Expr* Ex) {
return Mgr->GetRVal(St, Ex);
SVal GetSVal(Expr* Ex) {
return Mgr->GetSVal(St, Ex);
}
RVal GetBlkExprRVal(Expr* Ex) {
return Mgr->GetBlkExprRVal(St, Ex);
SVal GetBlkExprSVal(Expr* Ex) {
return Mgr->GetBlkExprSVal(St, Ex);
}
RVal GetRVal(LVal LV, QualType T = QualType()) {
return Mgr->GetRVal(St, LV, T);
SVal GetSVal(Loc LV, QualType T = QualType()) {
return Mgr->GetSVal(St, LV, T);
}
GRStateRef SetRVal(Expr* Ex, RVal V, bool isBlkExpr, bool Invalidate) {
return GRStateRef(Mgr->SetRVal(St, Ex, V, isBlkExpr, Invalidate), *Mgr);
GRStateRef SetSVal(Expr* Ex, SVal V, bool isBlkExpr, bool Invalidate) {
return GRStateRef(Mgr->SetSVal(St, Ex, V, isBlkExpr, Invalidate), *Mgr);
}
GRStateRef SetRVal(Expr* Ex, RVal V, bool Invalidate = true) {
return GRStateRef(Mgr->SetRVal(St, Ex, V, Invalidate), *Mgr);
GRStateRef SetSVal(Expr* Ex, SVal V, bool Invalidate = true) {
return GRStateRef(Mgr->SetSVal(St, Ex, V, Invalidate), *Mgr);
}
GRStateRef SetRVal(LVal LV, RVal V) {
GRStateRef SetSVal(Loc LV, SVal V) {
GRState StImpl = *St;
Mgr->SetRVal(StImpl, LV, V);
Mgr->SetSVal(StImpl, LV, V);
return GRStateRef(Mgr->getPersistentState(StImpl), *Mgr);
}
GRStateRef Unbind(LVal LV) {
GRStateRef Unbind(Loc LV) {
return GRStateRef(Mgr->Unbind(St, LV), *Mgr);
}
@ -591,7 +591,7 @@ public:
}
// Lvalue methods.
RVal GetLValue(const VarDecl* VD) {
SVal GetLValue(const VarDecl* VD) {
return Mgr->GetLValue(St, VD);
}

View File

@ -32,9 +32,9 @@ class GRTransferFuncs {
protected:
virtual RVal DetermEvalBinOpNN(GRStateManager& StateMgr,
virtual SVal DetermEvalBinOpNN(GRStateManager& StateMgr,
BinaryOperator::Opcode Op,
NonLVal L, NonLVal R) {
NonLoc L, NonLoc R) {
return UnknownVal();
}
@ -48,34 +48,34 @@ public:
// Casts.
virtual RVal EvalCast(GRExprEngine& Engine, NonLVal V, QualType CastT) =0;
virtual RVal EvalCast(GRExprEngine& Engine, LVal V, QualType CastT) = 0;
virtual SVal EvalCast(GRExprEngine& Engine, NonLoc V, QualType CastT) =0;
virtual SVal EvalCast(GRExprEngine& Engine, Loc V, QualType CastT) = 0;
// Unary Operators.
virtual RVal EvalMinus(GRExprEngine& Engine, UnaryOperator* U, NonLVal X) = 0;
virtual SVal EvalMinus(GRExprEngine& Engine, UnaryOperator* U, NonLoc X) = 0;
virtual RVal EvalComplement(GRExprEngine& Engine, NonLVal X) = 0;
virtual SVal EvalComplement(GRExprEngine& Engine, NonLoc X) = 0;
// Binary Operators.
virtual void EvalBinOpNN(GRStateSet& OStates, GRStateManager& StateMgr,
const GRState* St, Expr* Ex,
BinaryOperator::Opcode Op, NonLVal L, NonLVal R);
BinaryOperator::Opcode Op, NonLoc L, NonLoc R);
virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
LVal L, LVal R) = 0;
virtual SVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
Loc L, Loc R) = 0;
// Pointer arithmetic.
virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
LVal L, NonLVal R) = 0;
virtual SVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
Loc L, NonLoc R) = 0;
// Calls.
virtual void EvalCall(ExplodedNodeSet<GRState>& Dst,
GRExprEngine& Engine,
GRStmtNodeBuilder<GRState>& Builder,
CallExpr* CE, RVal L,
CallExpr* CE, SVal L,
ExplodedNode<GRState>* Pred) {}
virtual void EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
@ -88,12 +88,12 @@ public:
/// EvalStore - Evaluate the effects of a store, creating a new node
/// the represents the effect of binding 'Val' to the location 'TargetLV'.
// TargetLV is guaranteed to either be an UnknownVal or an LVal.
// TargetLV is guaranteed to either be an UnknownVal or an Loc.
virtual void EvalStore(ExplodedNodeSet<GRState>& Dst,
GRExprEngine& Engine,
GRStmtNodeBuilder<GRState>& Builder,
Expr* E, ExplodedNode<GRState>* Pred,
const GRState* St, RVal TargetLV, RVal Val);
const GRState* St, SVal TargetLV, SVal Val);
// End-of-path and dead symbol notification.
@ -121,7 +121,7 @@ public:
virtual const GRState* EvalAssume(GRStateManager& VMgr,
const GRState* St,
RVal Cond, bool Assumption,
SVal Cond, bool Assumption,
bool& isFeasible) {
return St;
}

View File

@ -1,4 +1,4 @@
//== RValues.h - Abstract RValues for Path-Sens. Value Tracking -*- C++ -*--==//
//== SValues.h - Abstract Values for Static Analysis ---------*- C++ -*--==//
//
// The LLVM Compiler Infrastructure
//
@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
// This file defines RVal, LVal, and NonLVal, classes that represent
// This file defines SVal, Loc, and NonLoc, classes that represent
// abstract r-values for use with path-sensitive value tracking.
//
//===----------------------------------------------------------------------===//
@ -19,17 +19,17 @@
#include "llvm/Support/Casting.h"
//==------------------------------------------------------------------------==//
// Base RVal types.
//==------------------------------------------------------------------------==//
// Base SVal types.
//==------------------------------------------------------------------------==//
namespace clang {
class MemRegion;
class GRStateManager;
class RVal {
class SVal {
public:
enum BaseKind { UndefinedKind, UnknownKind, LValKind, NonLValKind };
enum BaseKind { UndefinedKind, UnknownKind, LocKind, NonLocKind };
enum { BaseBits = 2, BaseMask = 0x3 };
protected:
@ -37,18 +37,18 @@ protected:
unsigned Kind;
protected:
RVal(const void* d, bool isLVal, unsigned ValKind)
SVal(const void* d, bool isLoc, unsigned ValKind)
: Data(const_cast<void*>(d)),
Kind((isLVal ? LValKind : NonLValKind) | (ValKind << BaseBits)) {}
Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
explicit RVal(BaseKind k, void* D = NULL)
explicit SVal(BaseKind k, void* D = NULL)
: Data(D), Kind(k) {}
public:
~RVal() {};
~SVal() {};
/// BufferTy - A temporary buffer to hold a set of RVals.
typedef llvm::SmallVector<RVal,5> BufferTy;
/// BufferTy - A temporary buffer to hold a set of SVals.
typedef llvm::SmallVector<SVal,5> BufferTy;
inline unsigned getRawKind() const { return Kind; }
inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
@ -59,16 +59,16 @@ public:
ID.AddPointer(reinterpret_cast<void*>(Data));
}
inline bool operator==(const RVal& R) const {
inline bool operator==(const SVal& R) const {
return getRawKind() == R.getRawKind() && Data == R.Data;
}
inline bool operator!=(const RVal& R) const {
inline bool operator!=(const SVal& R) const {
return !(*this == R);
}
static RVal GetSymbolValue(SymbolManager& SymMgr, VarDecl *D);
static SVal GetSymbolValue(SymbolManager& SymMgr, VarDecl *D);
inline bool isUnknown() const {
return getRawKind() == UnknownKind;
@ -96,134 +96,134 @@ public:
symbol_iterator symbol_end() const;
// Implement isa<T> support.
static inline bool classof(const RVal*) { return true; }
static inline bool classof(const SVal*) { return true; }
};
class UnknownVal : public RVal {
class UnknownVal : public SVal {
public:
UnknownVal() : RVal(UnknownKind) {}
UnknownVal() : SVal(UnknownKind) {}
static inline bool classof(const RVal* V) {
static inline bool classof(const SVal* V) {
return V->getBaseKind() == UnknownKind;
}
};
class UndefinedVal : public RVal {
class UndefinedVal : public SVal {
public:
UndefinedVal() : RVal(UndefinedKind) {}
UndefinedVal(void* D) : RVal(UndefinedKind, D) {}
UndefinedVal() : SVal(UndefinedKind) {}
UndefinedVal(void* D) : SVal(UndefinedKind, D) {}
static inline bool classof(const RVal* V) {
static inline bool classof(const SVal* V) {
return V->getBaseKind() == UndefinedKind;
}
void* getData() const { return Data; }
};
class NonLVal : public RVal {
class NonLoc : public SVal {
protected:
NonLVal(unsigned SubKind, const void* d) : RVal(d, false, SubKind) {}
NonLoc(unsigned SubKind, const void* d) : SVal(d, false, SubKind) {}
public:
void print(std::ostream& Out) const;
// Utility methods to create NonLVals.
static NonLVal MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T);
// Utility methods to create NonLocs.
static NonLoc MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T);
static NonLVal MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I);
static NonLoc MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I);
static NonLVal MakeIntTruthVal(BasicValueFactory& BasicVals, bool b);
static NonLoc MakeIntTruthVal(BasicValueFactory& BasicVals, bool b);
// Implement isa<T> support.
static inline bool classof(const RVal* V) {
return V->getBaseKind() == NonLValKind;
static inline bool classof(const SVal* V) {
return V->getBaseKind() == NonLocKind;
}
};
class LVal : public RVal {
class Loc : public SVal {
protected:
LVal(unsigned SubKind, const void* D)
: RVal(const_cast<void*>(D), true, SubKind) {}
Loc(unsigned SubKind, const void* D)
: SVal(const_cast<void*>(D), true, SubKind) {}
// Equality operators.
NonLVal EQ(BasicValueFactory& BasicVals, const LVal& R) const;
NonLVal NE(BasicValueFactory& BasicVals, const LVal& R) const;
NonLoc EQ(BasicValueFactory& BasicVals, const Loc& R) const;
NonLoc NE(BasicValueFactory& BasicVals, const Loc& R) const;
public:
void print(std::ostream& Out) const;
static LVal MakeVal(AddrLabelExpr* E);
static Loc MakeVal(AddrLabelExpr* E);
static LVal MakeVal(StringLiteral* S);
static Loc MakeVal(StringLiteral* S);
// Implement isa<T> support.
static inline bool classof(const RVal* V) {
return V->getBaseKind() == LValKind;
static inline bool classof(const SVal* V) {
return V->getBaseKind() == LocKind;
}
static inline bool IsLValType(QualType T) {
static inline bool IsLocType(QualType T) {
return T->isPointerType() || T->isObjCQualifiedIdType()
|| T->isBlockPointerType();
}
};
//==------------------------------------------------------------------------==//
// Subclasses of NonLVal.
//==------------------------------------------------------------------------==//
// Subclasses of NonLoc.
//==------------------------------------------------------------------------==//
namespace nonlval {
namespace nonloc {
enum Kind { ConcreteIntKind, SymbolValKind, SymIntConstraintValKind,
LValAsIntegerKind };
LocAsIntegerKind };
class SymbolVal : public NonLVal {
class SymbolVal : public NonLoc {
public:
SymbolVal(unsigned SymID)
: NonLVal(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
: NonLoc(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
SymbolID getSymbol() const {
return (SymbolID) reinterpret_cast<uintptr_t>(Data);
}
static inline bool classof(const RVal* V) {
return V->getBaseKind() == NonLValKind &&
static inline bool classof(const SVal* V) {
return V->getBaseKind() == NonLocKind &&
V->getSubKind() == SymbolValKind;
}
static inline bool classof(const NonLVal* V) {
static inline bool classof(const NonLoc* V) {
return V->getSubKind() == SymbolValKind;
}
};
class SymIntConstraintVal : public NonLVal {
class SymIntConstraintVal : public NonLoc {
public:
SymIntConstraintVal(const SymIntConstraint& C)
: NonLVal(SymIntConstraintValKind, reinterpret_cast<const void*>(&C)) {}
: NonLoc(SymIntConstraintValKind, reinterpret_cast<const void*>(&C)) {}
const SymIntConstraint& getConstraint() const {
return *reinterpret_cast<SymIntConstraint*>(Data);
}
static inline bool classof(const RVal* V) {
return V->getBaseKind() == NonLValKind &&
static inline bool classof(const SVal* V) {
return V->getBaseKind() == NonLocKind &&
V->getSubKind() == SymIntConstraintValKind;
}
static inline bool classof(const NonLVal* V) {
static inline bool classof(const NonLoc* V) {
return V->getSubKind() == SymIntConstraintValKind;
}
};
class ConcreteInt : public NonLVal {
class ConcreteInt : public NonLoc {
public:
ConcreteInt(const llvm::APSInt& V) : NonLVal(ConcreteIntKind, &V) {}
ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {}
const llvm::APSInt& getValue() const {
return *static_cast<llvm::APSInt*>(Data);
}
// Transfer functions for binary/unary operations on ConcreteInts.
RVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
SVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
const ConcreteInt& R) const;
ConcreteInt EvalComplement(BasicValueFactory& BasicVals) const;
@ -231,105 +231,105 @@ public:
ConcreteInt EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const;
// Implement isa<T> support.
static inline bool classof(const RVal* V) {
return V->getBaseKind() == NonLValKind &&
static inline bool classof(const SVal* V) {
return V->getBaseKind() == NonLocKind &&
V->getSubKind() == ConcreteIntKind;
}
static inline bool classof(const NonLVal* V) {
static inline bool classof(const NonLoc* V) {
return V->getSubKind() == ConcreteIntKind;
}
};
class LValAsInteger : public NonLVal {
LValAsInteger(const std::pair<RVal, uintptr_t>& data) :
NonLVal(LValAsIntegerKind, &data) {
assert (isa<LVal>(data.first));
class LocAsInteger : public NonLoc {
LocAsInteger(const std::pair<SVal, uintptr_t>& data) :
NonLoc(LocAsIntegerKind, &data) {
assert (isa<Loc>(data.first));
}
public:
LVal getLVal() const {
return cast<LVal>(((std::pair<RVal, uintptr_t>*) Data)->first);
Loc getLoc() const {
return cast<Loc>(((std::pair<SVal, uintptr_t>*) Data)->first);
}
const LVal& getPersistentLVal() const {
const RVal& V = ((std::pair<RVal, uintptr_t>*) Data)->first;
return cast<LVal>(V);
const Loc& getPersistentLoc() const {
const SVal& V = ((std::pair<SVal, uintptr_t>*) Data)->first;
return cast<Loc>(V);
}
unsigned getNumBits() const {
return ((std::pair<RVal, unsigned>*) Data)->second;
return ((std::pair<SVal, unsigned>*) Data)->second;
}
// Implement isa<T> support.
static inline bool classof(const RVal* V) {
return V->getBaseKind() == NonLValKind &&
V->getSubKind() == LValAsIntegerKind;
static inline bool classof(const SVal* V) {
return V->getBaseKind() == NonLocKind &&
V->getSubKind() == LocAsIntegerKind;
}
static inline bool classof(const NonLVal* V) {
return V->getSubKind() == LValAsIntegerKind;
static inline bool classof(const NonLoc* V) {
return V->getSubKind() == LocAsIntegerKind;
}
static inline LValAsInteger Make(BasicValueFactory& Vals, LVal V,
static inline LocAsInteger Make(BasicValueFactory& Vals, Loc V,
unsigned Bits) {
return LValAsInteger(Vals.getPersistentRValWithData(V, Bits));
return LocAsInteger(Vals.getPersistentSValWithData(V, Bits));
}
};
} // end namespace clang::nonlval
} // end namespace clang::nonloc
//==------------------------------------------------------------------------==//
// Subclasses of LVal.
//==------------------------------------------------------------------------==//
// Subclasses of Loc.
//==------------------------------------------------------------------------==//
namespace lval {
namespace loc {
enum Kind { SymbolValKind, GotoLabelKind, MemRegionKind, FuncValKind,
ConcreteIntKind, StringLiteralValKind };
class SymbolVal : public LVal {
class SymbolVal : public Loc {
public:
SymbolVal(unsigned SymID)
: LVal(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
: Loc(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
SymbolID getSymbol() const {
return (SymbolID) reinterpret_cast<uintptr_t>(Data);
}
static inline bool classof(const RVal* V) {
return V->getBaseKind() == LValKind &&
static inline bool classof(const SVal* V) {
return V->getBaseKind() == LocKind &&
V->getSubKind() == SymbolValKind;
}
static inline bool classof(const LVal* V) {
static inline bool classof(const Loc* V) {
return V->getSubKind() == SymbolValKind;
}
};
class GotoLabel : public LVal {
class GotoLabel : public Loc {
public:
GotoLabel(LabelStmt* Label) : LVal(GotoLabelKind, Label) {}
GotoLabel(LabelStmt* Label) : Loc(GotoLabelKind, Label) {}
LabelStmt* getLabel() const {
return static_cast<LabelStmt*>(Data);
}
static inline bool classof(const RVal* V) {
return V->getBaseKind() == LValKind &&
static inline bool classof(const SVal* V) {
return V->getBaseKind() == LocKind &&
V->getSubKind() == GotoLabelKind;
}
static inline bool classof(const LVal* V) {
static inline bool classof(const Loc* V) {
return V->getSubKind() == GotoLabelKind;
}
};
class MemRegionVal : public LVal {
class MemRegionVal : public Loc {
public:
MemRegionVal(const MemRegion* r) : LVal(MemRegionKind, r) {}
MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {}
MemRegion* getRegion() const {
return static_cast<MemRegion*>(Data);
@ -344,19 +344,19 @@ public:
}
// Implement isa<T> support.
static inline bool classof(const RVal* V) {
return V->getBaseKind() == LValKind &&
static inline bool classof(const SVal* V) {
return V->getBaseKind() == LocKind &&
V->getSubKind() == MemRegionKind;
}
static inline bool classof(const LVal* V) {
static inline bool classof(const Loc* V) {
return V->getSubKind() == MemRegionKind;
}
};
class FuncVal : public LVal {
class FuncVal : public Loc {
public:
FuncVal(const FunctionDecl* fd) : LVal(FuncValKind, fd) {}
FuncVal(const FunctionDecl* fd) : Loc(FuncValKind, fd) {}
FunctionDecl* getDecl() const {
return static_cast<FunctionDecl*>(Data);
@ -371,57 +371,57 @@ public:
}
// Implement isa<T> support.
static inline bool classof(const RVal* V) {
return V->getBaseKind() == LValKind &&
static inline bool classof(const SVal* V) {
return V->getBaseKind() == LocKind &&
V->getSubKind() == FuncValKind;
}
static inline bool classof(const LVal* V) {
static inline bool classof(const Loc* V) {
return V->getSubKind() == FuncValKind;
}
};
class ConcreteInt : public LVal {
class ConcreteInt : public Loc {
public:
ConcreteInt(const llvm::APSInt& V) : LVal(ConcreteIntKind, &V) {}
ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {}
const llvm::APSInt& getValue() const {
return *static_cast<llvm::APSInt*>(Data);
}
// Transfer functions for binary/unary operations on ConcreteInts.
RVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
SVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
const ConcreteInt& R) const;
// Implement isa<T> support.
static inline bool classof(const RVal* V) {
return V->getBaseKind() == LValKind &&
static inline bool classof(const SVal* V) {
return V->getBaseKind() == LocKind &&
V->getSubKind() == ConcreteIntKind;
}
static inline bool classof(const LVal* V) {
static inline bool classof(const Loc* V) {
return V->getSubKind() == ConcreteIntKind;
}
};
class StringLiteralVal : public LVal {
class StringLiteralVal : public Loc {
public:
StringLiteralVal(StringLiteral* L) : LVal(StringLiteralValKind, L) {}
StringLiteralVal(StringLiteral* L) : Loc(StringLiteralValKind, L) {}
StringLiteral* getLiteral() const { return (StringLiteral*) Data; }
// Implement isa<T> support.
static inline bool classof(const RVal* V) {
return V->getBaseKind() == LValKind &&
static inline bool classof(const SVal* V) {
return V->getBaseKind() == LocKind &&
V->getSubKind() == StringLiteralValKind;
}
static inline bool classof(const LVal* V) {
static inline bool classof(const Loc* V) {
return V->getSubKind() == StringLiteralValKind;
}
};
} // end clang::lval namespace
} // end clang::loc namespace
} // end clang namespace
#endif

View File

@ -40,21 +40,22 @@ public:
typedef llvm::DenseSet<SymbolID> DeadSymbolsTy;
virtual ~StoreManager() {}
virtual RVal GetRVal(Store St, LVal LV, QualType T = QualType()) = 0;
virtual Store SetRVal(Store St, LVal LV, RVal V) = 0;
virtual Store Remove(Store St, LVal LV) = 0;
virtual SVal GetSVal(Store St, Loc LV, QualType T = QualType()) = 0;
virtual Store SetSVal(Store St, Loc LV, SVal V) = 0;
virtual Store Remove(Store St, Loc LV) = 0;
virtual Store getInitialStore() = 0;
virtual MemRegionManager& getRegionManager() = 0;
virtual RVal getLValueVar(const GRState* St, const VarDecl* VD) = 0;
virtual SVal getLValueVar(const GRState* St, const VarDecl* VD) = 0;
virtual RVal getLValueIvar(const GRState* St, const ObjCIvarDecl* D,
RVal Base)=0;
virtual SVal getLValueIvar(const GRState* St, const ObjCIvarDecl* D,
SVal Base)=0;
virtual RVal getLValueField(const GRState* St, const FieldDecl* D,
RVal Base) = 0;
virtual SVal getLValueField(const GRState* St, const FieldDecl* D,
SVal Base) = 0;
virtual RVal getLValueElement(const GRState* St, RVal Base, RVal Offset) = 0;
virtual SVal getLValueElement(const GRState* St,
SVal Base, SVal Offset) = 0;
virtual Store
@ -64,7 +65,8 @@ public:
virtual Store AddDecl(Store store,
const VarDecl* VD, Expr* Ex,
RVal InitVal = UndefinedVal(), unsigned Count = 0) = 0;
SVal InitVal = UndefinedVal(),
unsigned Count = 0) = 0;
virtual void print(Store store, std::ostream& Out,
const char* nl, const char *sep) = 0;
@ -73,7 +75,7 @@ public:
public:
virtual ~BindingsHandler();
virtual bool HandleBinding(StoreManager& SMgr, Store store,
MemRegion* R, RVal val) = 0;
MemRegion* R, SVal val) = 0;
};
/// iterBindings - Iterate over the bindings in the Store.

View File

@ -198,7 +198,7 @@ public:
}
};
// Constraints on symbols. Usually wrapped by RValues.
// Constraints on symbols. Usually wrapped by SValues.
class SymIntConstraint : public llvm::FoldingSetNode {
SymbolID Symbol;

View File

@ -33,19 +33,19 @@ class VISIBILITY_HIDDEN BasicConstraintManager : public ConstraintManager {
public:
BasicConstraintManager(GRStateManager& statemgr) : StateMgr(statemgr) {}
virtual const GRState* Assume(const GRState* St, RVal Cond,
virtual const GRState* Assume(const GRState* St, SVal Cond,
bool Assumption, bool& isFeasible);
const GRState* Assume(const GRState* St, LVal Cond, bool Assumption,
const GRState* Assume(const GRState* St, Loc Cond, bool Assumption,
bool& isFeasible);
const GRState* AssumeAux(const GRState* St, LVal Cond,bool Assumption,
const GRState* AssumeAux(const GRState* St, Loc Cond,bool Assumption,
bool& isFeasible);
const GRState* Assume(const GRState* St, NonLVal Cond, bool Assumption,
const GRState* Assume(const GRState* St, NonLoc Cond, bool Assumption,
bool& isFeasible);
const GRState* AssumeAux(const GRState* St, NonLVal Cond, bool Assumption,
const GRState* AssumeAux(const GRState* St, NonLoc Cond, bool Assumption,
bool& isFeasible);
const GRState* AssumeSymInt(const GRState* St, bool Assumption,
@ -92,52 +92,52 @@ ConstraintManager* clang::CreateBasicConstraintManager(GRStateManager& StateMgr)
return new BasicConstraintManager(StateMgr);
}
const GRState* BasicConstraintManager::Assume(const GRState* St, RVal Cond,
const GRState* BasicConstraintManager::Assume(const GRState* St, SVal Cond,
bool Assumption, bool& isFeasible) {
if (Cond.isUnknown()) {
isFeasible = true;
return St;
}
if (isa<NonLVal>(Cond))
return Assume(St, cast<NonLVal>(Cond), Assumption, isFeasible);
if (isa<NonLoc>(Cond))
return Assume(St, cast<NonLoc>(Cond), Assumption, isFeasible);
else
return Assume(St, cast<LVal>(Cond), Assumption, isFeasible);
return Assume(St, cast<Loc>(Cond), Assumption, isFeasible);
}
const GRState* BasicConstraintManager::Assume(const GRState* St, LVal Cond,
const GRState* BasicConstraintManager::Assume(const GRState* St, Loc Cond,
bool Assumption, bool& isFeasible) {
St = AssumeAux(St, Cond, Assumption, isFeasible);
// TF->EvalAssume(*this, St, Cond, Assumption, isFeasible)
return St;
}
const GRState* BasicConstraintManager::AssumeAux(const GRState* St, LVal Cond,
const GRState* BasicConstraintManager::AssumeAux(const GRState* St, Loc Cond,
bool Assumption, bool& isFeasible) {
BasicValueFactory& BasicVals = StateMgr.getBasicVals();
switch (Cond.getSubKind()) {
default:
assert (false && "'Assume' not implemented for this LVal.");
assert (false && "'Assume' not implemented for this Loc.");
return St;
case lval::SymbolValKind:
case loc::SymbolValKind:
if (Assumption)
return AssumeSymNE(St, cast<lval::SymbolVal>(Cond).getSymbol(),
return AssumeSymNE(St, cast<loc::SymbolVal>(Cond).getSymbol(),
BasicVals.getZeroWithPtrWidth(), isFeasible);
else
return AssumeSymEQ(St, cast<lval::SymbolVal>(Cond).getSymbol(),
return AssumeSymEQ(St, cast<loc::SymbolVal>(Cond).getSymbol(),
BasicVals.getZeroWithPtrWidth(), isFeasible);
case lval::MemRegionKind:
case lval::FuncValKind:
case lval::GotoLabelKind:
case lval::StringLiteralValKind:
case loc::MemRegionKind:
case loc::FuncValKind:
case loc::GotoLabelKind:
case loc::StringLiteralValKind:
isFeasible = Assumption;
return St;
case lval::ConcreteIntKind: {
bool b = cast<lval::ConcreteInt>(Cond).getValue() != 0;
case loc::ConcreteIntKind: {
bool b = cast<loc::ConcreteInt>(Cond).getValue() != 0;
isFeasible = b ? Assumption : !Assumption;
return St;
}
@ -145,7 +145,7 @@ const GRState* BasicConstraintManager::AssumeAux(const GRState* St, LVal Cond,
}
const GRState*
BasicConstraintManager::Assume(const GRState* St, NonLVal Cond, bool Assumption,
BasicConstraintManager::Assume(const GRState* St, NonLoc Cond, bool Assumption,
bool& isFeasible) {
St = AssumeAux(St, Cond, Assumption, isFeasible);
// TF->EvalAssume() does nothing now.
@ -153,17 +153,17 @@ BasicConstraintManager::Assume(const GRState* St, NonLVal Cond, bool Assumption,
}
const GRState*
BasicConstraintManager::AssumeAux(const GRState* St,NonLVal Cond,
BasicConstraintManager::AssumeAux(const GRState* St,NonLoc Cond,
bool Assumption, bool& isFeasible) {
BasicValueFactory& BasicVals = StateMgr.getBasicVals();
SymbolManager& SymMgr = StateMgr.getSymbolManager();
switch (Cond.getSubKind()) {
default:
assert(false && "'Assume' not implemented for this NonLVal");
assert(false && "'Assume' not implemented for this NonLoc");
case nonlval::SymbolValKind: {
nonlval::SymbolVal& SV = cast<nonlval::SymbolVal>(Cond);
case nonloc::SymbolValKind: {
nonloc::SymbolVal& SV = cast<nonloc::SymbolVal>(Cond);
SymbolID sym = SV.getSymbol();
if (Assumption)
@ -174,20 +174,20 @@ BasicConstraintManager::AssumeAux(const GRState* St,NonLVal Cond,
isFeasible);
}
case nonlval::SymIntConstraintValKind:
case nonloc::SymIntConstraintValKind:
return
AssumeSymInt(St, Assumption,
cast<nonlval::SymIntConstraintVal>(Cond).getConstraint(),
cast<nonloc::SymIntConstraintVal>(Cond).getConstraint(),
isFeasible);
case nonlval::ConcreteIntKind: {
bool b = cast<nonlval::ConcreteInt>(Cond).getValue() != 0;
case nonloc::ConcreteIntKind: {
bool b = cast<nonloc::ConcreteInt>(Cond).getValue() != 0;
isFeasible = b ? Assumption : !Assumption;
return St;
}
case nonlval::LValAsIntegerKind:
return AssumeAux(St, cast<nonlval::LValAsInteger>(Cond).getLVal(),
case nonloc::LocAsIntegerKind:
return AssumeAux(St, cast<nonloc::LocAsInteger>(Cond).getLoc(),
Assumption, isFeasible);
} // end switch
}

View File

@ -118,7 +118,7 @@ class VISIBILITY_HIDDEN BasicObjCFoundationChecks : public GRSimpleAPICheck {
typedef std::vector<BugReport*> ErrorsTy;
ErrorsTy Errors;
RVal GetRVal(const GRState* St, Expr* E) { return VMgr->GetRVal(St, E); }
SVal GetSVal(const GRState* St, Expr* E) { return VMgr->GetSVal(St, E); }
bool isNSString(ObjCInterfaceType* T, const char* suffix);
bool AuditNSString(NodeTy* N, ObjCMessageExpr* ME);
@ -193,8 +193,8 @@ bool BasicObjCFoundationChecks::Audit(ExplodedNode<GRState>* N,
return false;
}
static inline bool isNil(RVal X) {
return isa<lval::ConcreteInt>(X);
static inline bool isNil(SVal X) {
return isa<loc::ConcreteInt>(X);
}
//===----------------------------------------------------------------------===//
@ -214,7 +214,7 @@ bool BasicObjCFoundationChecks::CheckNilArg(NodeTy* N, unsigned Arg) {
Expr * E = ME->getArg(Arg);
if (isNil(GetRVal(N->getState(), E))) {
if (isNil(GetSVal(N->getState(), E))) {
WarnNilArg(N, ME, Arg);
return true;
}
@ -350,7 +350,7 @@ class VISIBILITY_HIDDEN AuditCFNumberCreate : public GRSimpleAPICheck {
IdentifierInfo* II;
GRStateManager* VMgr;
RVal GetRVal(const GRState* St, Expr* E) { return VMgr->GetRVal(St, E); }
SVal GetSVal(const GRState* St, Expr* E) { return VMgr->GetSVal(St, E); }
public:
@ -468,18 +468,18 @@ static const char* GetCFNumberTypeStr(uint64_t i) {
bool AuditCFNumberCreate::Audit(ExplodedNode<GRState>* N,GRStateManager&){
CallExpr* CE = cast<CallExpr>(cast<PostStmt>(N->getLocation()).getStmt());
Expr* Callee = CE->getCallee();
RVal CallV = GetRVal(N->getState(), Callee);
lval::FuncVal* FuncV = dyn_cast<lval::FuncVal>(&CallV);
SVal CallV = GetSVal(N->getState(), Callee);
loc::FuncVal* FuncV = dyn_cast<loc::FuncVal>(&CallV);
if (!FuncV || FuncV->getDecl()->getIdentifier() != II || CE->getNumArgs()!=3)
return false;
// Get the value of the "theType" argument.
RVal TheTypeVal = GetRVal(N->getState(), CE->getArg(1));
SVal TheTypeVal = GetSVal(N->getState(), CE->getArg(1));
// FIXME: We really should allow ranges of valid theType values, and
// bifurcate the state appropriately.
nonlval::ConcreteInt* V = dyn_cast<nonlval::ConcreteInt>(&TheTypeVal);
nonloc::ConcreteInt* V = dyn_cast<nonloc::ConcreteInt>(&TheTypeVal);
if (!V)
return false;
@ -494,11 +494,11 @@ bool AuditCFNumberCreate::Audit(ExplodedNode<GRState>* N,GRStateManager&){
// Look at the value of the integer being passed by reference. Essentially
// we want to catch cases where the value passed in is not equal to the
// size of the type being created.
RVal TheValueExpr = GetRVal(N->getState(), CE->getArg(2));
SVal TheValueExpr = GetSVal(N->getState(), CE->getArg(2));
// FIXME: Eventually we should handle arbitrary locations. We can do this
// by having an enhanced memory model that does low-level typing.
lval::MemRegionVal* LV = dyn_cast<lval::MemRegionVal>(&TheValueExpr);
loc::MemRegionVal* LV = dyn_cast<loc::MemRegionVal>(&TheValueExpr);
if (!LV)
return false;

View File

@ -19,7 +19,7 @@
using namespace clang;
typedef llvm::ImmutableMap<const VarDecl*,RVal> VarBindingsTy;
typedef llvm::ImmutableMap<const VarDecl*,SVal> VarBindingsTy;
namespace {
@ -34,23 +34,23 @@ public:
virtual ~BasicStoreManager() {}
virtual RVal GetRVal(Store St, LVal LV, QualType T);
virtual Store SetRVal(Store St, LVal LV, RVal V);
virtual Store Remove(Store St, LVal LV);
virtual SVal GetSVal(Store St, Loc LV, QualType T);
virtual Store SetSVal(Store St, Loc LV, SVal V);
virtual Store Remove(Store St, Loc LV);
virtual Store getInitialStore();
virtual MemRegionManager& getRegionManager() { return MRMgr; }
// FIXME: Investigate what is using this. This method should be removed.
virtual LVal getLVal(const VarDecl* VD) {
return lval::MemRegionVal(MRMgr.getVarRegion(VD));
virtual Loc getLoc(const VarDecl* VD) {
return loc::MemRegionVal(MRMgr.getVarRegion(VD));
}
RVal getLValueVar(const GRState* St, const VarDecl* VD);
RVal getLValueIvar(const GRState* St, const ObjCIvarDecl* D, RVal Base);
RVal getLValueField(const GRState* St, const FieldDecl* D, RVal Base);
RVal getLValueElement(const GRState* St, RVal Base, RVal Offset);
SVal getLValueVar(const GRState* St, const VarDecl* VD);
SVal getLValueIvar(const GRState* St, const ObjCIvarDecl* D, SVal Base);
SVal getLValueField(const GRState* St, const FieldDecl* D, SVal Base);
SVal getLValueElement(const GRState* St, SVal Base, SVal Offset);
virtual Store
RemoveDeadBindings(Store store, Stmt* Loc, const LiveVariables& Live,
@ -61,7 +61,7 @@ public:
virtual Store AddDecl(Store store,
const VarDecl* VD, Expr* Ex,
RVal InitVal = UndefinedVal(), unsigned Count = 0);
SVal InitVal = UndefinedVal(), unsigned Count = 0);
static inline VarBindingsTy GetVarBindings(Store store) {
return VarBindingsTy(static_cast<const VarBindingsTy::TreeTy*>(store));
@ -78,27 +78,27 @@ public:
StoreManager* clang::CreateBasicStoreManager(GRStateManager& StMgr) {
return new BasicStoreManager(StMgr);
}
RVal BasicStoreManager::getLValueVar(const GRState* St, const VarDecl* VD) {
return lval::MemRegionVal(MRMgr.getVarRegion(VD));
SVal BasicStoreManager::getLValueVar(const GRState* St, const VarDecl* VD) {
return loc::MemRegionVal(MRMgr.getVarRegion(VD));
}
RVal BasicStoreManager::getLValueIvar(const GRState* St, const ObjCIvarDecl* D,
RVal Base) {
SVal BasicStoreManager::getLValueIvar(const GRState* St, const ObjCIvarDecl* D,
SVal Base) {
return UnknownVal();
}
RVal BasicStoreManager::getLValueField(const GRState* St, const FieldDecl* D,
RVal Base) {
SVal BasicStoreManager::getLValueField(const GRState* St, const FieldDecl* D,
SVal Base) {
return UnknownVal();
}
RVal BasicStoreManager::getLValueElement(const GRState* St, RVal Base,
RVal Offset) {
SVal BasicStoreManager::getLValueElement(const GRState* St, SVal Base,
SVal Offset) {
return UnknownVal();
}
RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) {
SVal BasicStoreManager::GetSVal(Store St, Loc LV, QualType T) {
if (isa<UnknownVal>(LV))
return UnknownVal();
@ -107,9 +107,9 @@ RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) {
switch (LV.getSubKind()) {
case lval::MemRegionKind: {
case loc::MemRegionKind: {
VarRegion* R =
dyn_cast<VarRegion>(cast<lval::MemRegionVal>(LV).getRegion());
dyn_cast<VarRegion>(cast<loc::MemRegionVal>(LV).getRegion());
if (!R)
return UnknownVal();
@ -119,34 +119,34 @@ RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) {
return T ? *T : UnknownVal();
}
case lval::SymbolValKind:
case loc::SymbolValKind:
return UnknownVal();
case lval::ConcreteIntKind:
// Some clients may call GetRVal with such an option simply because
// they are doing a quick scan through their LVals (potentially to
case loc::ConcreteIntKind:
// Some clients may call GetSVal with such an option simply because
// they are doing a quick scan through their Locs (potentially to
// invalidate their bindings). Just return Undefined.
return UndefinedVal();
case lval::FuncValKind:
case loc::FuncValKind:
return LV;
case lval::StringLiteralValKind:
case loc::StringLiteralValKind:
// FIXME: Implement better support for fetching characters from strings.
return UnknownVal();
default:
assert (false && "Invalid LVal.");
assert (false && "Invalid Loc.");
break;
}
return UnknownVal();
}
Store BasicStoreManager::SetRVal(Store store, LVal LV, RVal V) {
Store BasicStoreManager::SetSVal(Store store, Loc LV, SVal V) {
switch (LV.getSubKind()) {
case lval::MemRegionKind: {
case loc::MemRegionKind: {
VarRegion* R =
dyn_cast<VarRegion>(cast<lval::MemRegionVal>(LV).getRegion());
dyn_cast<VarRegion>(cast<loc::MemRegionVal>(LV).getRegion());
if (!R)
return store;
@ -157,16 +157,16 @@ Store BasicStoreManager::SetRVal(Store store, LVal LV, RVal V) {
: VBFactory.Add(B, R->getDecl(), V).getRoot();
}
default:
assert ("SetRVal for given LVal type not yet implemented.");
assert ("SetSVal for given Loc type not yet implemented.");
return store;
}
}
Store BasicStoreManager::Remove(Store store, LVal LV) {
Store BasicStoreManager::Remove(Store store, Loc LV) {
switch (LV.getSubKind()) {
case lval::MemRegionKind: {
case loc::MemRegionKind: {
VarRegion* R =
dyn_cast<VarRegion>(cast<lval::MemRegionVal>(LV).getRegion());
dyn_cast<VarRegion>(cast<loc::MemRegionVal>(LV).getRegion());
if (!R)
return store;
@ -175,7 +175,7 @@ Store BasicStoreManager::Remove(Store store, LVal LV) {
return VBFactory.Remove(B,R->getDecl()).getRoot();
}
default:
assert ("Remove for given LVal type not yet implemented.");
assert ("Remove for given Loc type not yet implemented.");
return store;
}
}
@ -187,13 +187,13 @@ BasicStoreManager::RemoveDeadBindings(Store store, Stmt* Loc,
LiveSymbolsTy& LSymbols, DeadSymbolsTy& DSymbols) {
VarBindingsTy B = GetVarBindings(store);
typedef RVal::symbol_iterator symbol_iterator;
typedef SVal::symbol_iterator symbol_iterator;
// Iterate over the variable bindings.
for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I)
if (Liveness.isLive(Loc, I.getKey())) {
RegionRoots.push_back(MRMgr.getVarRegion(I.getKey()));
RVal X = I.getData();
SVal X = I.getData();
for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
LSymbols.insert(*SI);
@ -212,15 +212,15 @@ BasicStoreManager::RemoveDeadBindings(Store store, Stmt* Loc,
Marked.insert(R);
// FIXME: Do we need the QualType here, since regions are partially
// typed?
RVal X = GetRVal(store, lval::MemRegionVal(R), QualType());
SVal X = GetSVal(store, loc::MemRegionVal(R), QualType());
for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
LSymbols.insert(*SI);
if (!isa<lval::MemRegionVal>(X))
if (!isa<loc::MemRegionVal>(X))
continue;
const lval::MemRegionVal& LVD = cast<lval::MemRegionVal>(X);
const loc::MemRegionVal& LVD = cast<loc::MemRegionVal>(X);
RegionRoots.push_back(cast<VarRegion>(LVD.getRegion()));
}
@ -229,8 +229,8 @@ BasicStoreManager::RemoveDeadBindings(Store store, Stmt* Loc,
const VarRegion* R = cast<VarRegion>(MRMgr.getVarRegion(I.getKey()));
if (!Marked.count(R)) {
store = Remove(store, lval::MemRegionVal(R));
RVal X = I.getData();
store = Remove(store, loc::MemRegionVal(R));
SVal X = I.getData();
for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
if (!LSymbols.count(*SI)) DSymbols.insert(*SI);
@ -260,15 +260,15 @@ Store BasicStoreManager::getInitialStore() {
// Only handle pointers and integers for now.
QualType T = VD->getType();
if (LVal::IsLValType(T) || T->isIntegerType()) {
if (Loc::IsLocType(T) || T->isIntegerType()) {
// Initialize globals and parameters to symbolic values.
// Initialize local variables to undefined.
RVal X = (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
SVal X = (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
isa<ImplicitParamDecl>(VD))
? RVal::GetSymbolValue(StateMgr.getSymbolManager(), VD)
? SVal::GetSymbolValue(StateMgr.getSymbolManager(), VD)
: UndefinedVal();
St = SetRVal(St, lval::MemRegionVal(MRMgr.getVarRegion(VD)), X);
St = SetSVal(St, loc::MemRegionVal(MRMgr.getVarRegion(VD)), X);
}
}
}
@ -277,7 +277,7 @@ Store BasicStoreManager::getInitialStore() {
Store BasicStoreManager::AddDecl(Store store,
const VarDecl* VD, Expr* Ex,
RVal InitVal, unsigned Count) {
SVal InitVal, unsigned Count) {
BasicValueFactory& BasicVals = StateMgr.getBasicVals();
SymbolManager& SymMgr = StateMgr.getSymbolManager();
@ -307,35 +307,35 @@ Store BasicStoreManager::AddDecl(Store store,
// unsigned) zero;
if (!Ex) {
QualType T = VD->getType();
if (LVal::IsLValType(T))
store = SetRVal(store, getLVal(VD),
lval::ConcreteInt(BasicVals.getValue(0, T)));
if (Loc::IsLocType(T))
store = SetSVal(store, getLoc(VD),
loc::ConcreteInt(BasicVals.getValue(0, T)));
else if (T->isIntegerType())
store = SetRVal(store, getLVal(VD),
nonlval::ConcreteInt(BasicVals.getValue(0, T)));
store = SetSVal(store, getLoc(VD),
nonloc::ConcreteInt(BasicVals.getValue(0, T)));
else {
// assert(0 && "ignore other types of variables");
}
} else {
store = SetRVal(store, getLVal(VD), InitVal);
store = SetSVal(store, getLoc(VD), InitVal);
}
}
} else {
// Process local scalar variables.
QualType T = VD->getType();
if (LVal::IsLValType(T) || T->isIntegerType()) {
RVal V = Ex ? InitVal : UndefinedVal();
if (Loc::IsLocType(T) || T->isIntegerType()) {
SVal V = Ex ? InitVal : UndefinedVal();
if (Ex && InitVal.isUnknown()) {
// EXPERIMENTAL: "Conjured" symbols.
SymbolID Sym = SymMgr.getConjuredSymbol(Ex, Count);
V = LVal::IsLValType(Ex->getType())
? cast<RVal>(lval::SymbolVal(Sym))
: cast<RVal>(nonlval::SymbolVal(Sym));
V = Loc::IsLocType(Ex->getType())
? cast<SVal>(loc::SymbolVal(Sym))
: cast<SVal>(nonloc::SymbolVal(Sym));
}
store = SetRVal(store, getLVal(VD), V);
store = SetSVal(store, getLoc(VD), V);
}
}

View File

@ -18,31 +18,31 @@
using namespace clang;
typedef std::pair<RVal, uintptr_t> RValData;
typedef std::pair<RVal, RVal> RValPair;
typedef std::pair<SVal, uintptr_t> SValData;
typedef std::pair<SVal, SVal> SValPair;
namespace llvm {
template<> struct FoldingSetTrait<RValData> {
static inline void Profile(const RValData& X, llvm::FoldingSetNodeID& ID) {
template<> struct FoldingSetTrait<SValData> {
static inline void Profile(const SValData& X, llvm::FoldingSetNodeID& ID) {
X.first.Profile(ID);
ID.AddPointer( (void*) X.second);
}
};
template<> struct FoldingSetTrait<RValPair> {
static inline void Profile(const RValPair& X, llvm::FoldingSetNodeID& ID) {
template<> struct FoldingSetTrait<SValPair> {
static inline void Profile(const SValPair& X, llvm::FoldingSetNodeID& ID) {
X.first.Profile(ID);
X.second.Profile(ID);
}
};
}
typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<RValData> >
PersistentRValsTy;
typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValData> >
PersistentSValsTy;
typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<RValPair> >
PersistentRValPairsTy;
typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValPair> >
PersistentSValPairsTy;
BasicValueFactory::~BasicValueFactory() {
// Note that the dstor for the contents of APSIntSet will never be called,
@ -51,8 +51,8 @@ BasicValueFactory::~BasicValueFactory() {
for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
I->getValue().~APSInt();
delete (PersistentRValsTy*) PersistentRVals;
delete (PersistentRValPairsTy*) PersistentRValPairs;
delete (PersistentSValsTy*) PersistentSVals;
delete (PersistentSValPairsTy*) PersistentSValPairs;
}
const llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) {
@ -197,20 +197,20 @@ BasicValueFactory::EvaluateAPSInt(BinaryOperator::Opcode Op,
}
const std::pair<RVal, uintptr_t>&
BasicValueFactory::getPersistentRValWithData(const RVal& V, uintptr_t Data) {
const std::pair<SVal, uintptr_t>&
BasicValueFactory::getPersistentSValWithData(const SVal& V, uintptr_t Data) {
// Lazily create the folding set.
if (!PersistentRVals) PersistentRVals = new PersistentRValsTy();
if (!PersistentSVals) PersistentSVals = new PersistentSValsTy();
llvm::FoldingSetNodeID ID;
void* InsertPos;
V.Profile(ID);
ID.AddPointer((void*) Data);
PersistentRValsTy& Map = *((PersistentRValsTy*) PersistentRVals);
PersistentSValsTy& Map = *((PersistentSValsTy*) PersistentSVals);
typedef llvm::FoldingSetNodeWrapper<RValData> FoldNodeTy;
typedef llvm::FoldingSetNodeWrapper<SValData> FoldNodeTy;
FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
if (!P) {
@ -222,20 +222,20 @@ BasicValueFactory::getPersistentRValWithData(const RVal& V, uintptr_t Data) {
return P->getValue();
}
const std::pair<RVal, RVal>&
BasicValueFactory::getPersistentRValPair(const RVal& V1, const RVal& V2) {
const std::pair<SVal, SVal>&
BasicValueFactory::getPersistentSValPair(const SVal& V1, const SVal& V2) {
// Lazily create the folding set.
if (!PersistentRValPairs) PersistentRValPairs = new PersistentRValPairsTy();
if (!PersistentSValPairs) PersistentSValPairs = new PersistentSValPairsTy();
llvm::FoldingSetNodeID ID;
void* InsertPos;
V1.Profile(ID);
V2.Profile(ID);
PersistentRValPairsTy& Map = *((PersistentRValPairsTy*) PersistentRValPairs);
PersistentSValPairsTy& Map = *((PersistentSValPairsTy*) PersistentSValPairs);
typedef llvm::FoldingSetNodeWrapper<RValPair> FoldNodeTy;
typedef llvm::FoldingSetNodeWrapper<SValPair> FoldNodeTy;
FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
if (!P) {
@ -247,8 +247,8 @@ BasicValueFactory::getPersistentRValPair(const RVal& V1, const RVal& V2) {
return P->getValue();
}
const RVal* BasicValueFactory::getPersistentRVal(RVal X) {
return &getPersistentRValWithData(X, 0).first;
const SVal* BasicValueFactory::getPersistentSVal(SVal X) {
return &getPersistentSValWithData(X, 0).first;
}

View File

@ -292,7 +292,7 @@ MakeReportGraph(ExplodedGraph<GRState>* G, ExplodedNode<GRState>* N) {
static VarDecl* GetMostRecentVarDeclBinding(ExplodedNode<GRState>* N,
GRStateManager& VMgr,
RVal X) {
SVal X) {
for ( ; N ; N = N->pred_empty() ? 0 : *N->pred_begin()) {
@ -306,7 +306,7 @@ static VarDecl* GetMostRecentVarDeclBinding(ExplodedNode<GRState>* N,
if (!DR)
continue;
RVal Y = VMgr.GetRVal(N->getState(), DR);
SVal Y = VMgr.GetSVal(N->getState(), DR);
if (X != Y)
continue;
@ -341,13 +341,13 @@ public:
PathDiagnostic& pd, BugReporter& br)
: Sym(sym), PrevSt(prevst), S(s), VMgr(vmgr), Pred(pred), PD(pd), BR(br) {}
bool HandleBinding(StoreManager& SMgr, Store store, MemRegion* R, RVal V) {
bool HandleBinding(StoreManager& SMgr, Store store, MemRegion* R, SVal V) {
SymbolID ScanSym;
if (lval::SymbolVal* SV = dyn_cast<lval::SymbolVal>(&V))
if (loc::SymbolVal* SV = dyn_cast<loc::SymbolVal>(&V))
ScanSym = SV->getSymbol();
else if (nonlval::SymbolVal* SV = dyn_cast<nonlval::SymbolVal>(&V))
else if (nonloc::SymbolVal* SV = dyn_cast<nonloc::SymbolVal>(&V))
ScanSym = SV->getSymbol();
else
return true;
@ -356,7 +356,7 @@ public:
return true;
// Check if the previous state has this binding.
RVal X = VMgr.GetRVal(PrevSt, lval::MemRegionVal(R));
SVal X = VMgr.GetSVal(PrevSt, loc::MemRegionVal(R));
if (X == V) // Same binding?
return true;
@ -443,12 +443,12 @@ public:
PathDiagnostic& pd)
: N(n), S(s), BR(br), PD(pd) {}
bool HandleBinding(StoreManager& SMgr, Store store, MemRegion* R, RVal V) {
bool HandleBinding(StoreManager& SMgr, Store store, MemRegion* R, SVal V) {
SymbolID ScanSym;
if (lval::SymbolVal* SV = dyn_cast<lval::SymbolVal>(&V))
if (loc::SymbolVal* SV = dyn_cast<loc::SymbolVal>(&V))
ScanSym = SV->getSymbol();
else if (nonlval::SymbolVal* SV = dyn_cast<nonlval::SymbolVal>(&V))
else if (nonloc::SymbolVal* SV = dyn_cast<nonloc::SymbolVal>(&V))
ScanSym = SV->getSymbol();
else
return true;

View File

@ -1297,7 +1297,7 @@ public:
virtual void EvalCall(ExplodedNodeSet<GRState>& Dst,
GRExprEngine& Eng,
GRStmtNodeBuilder<GRState>& Builder,
CallExpr* CE, RVal L,
CallExpr* CE, SVal L,
ExplodedNode<GRState>* Pred);
@ -1319,7 +1319,7 @@ public:
GRExprEngine& Engine,
GRStmtNodeBuilder<GRState>& Builder,
Expr* E, ExplodedNode<GRState>* Pred,
const GRState* St, RVal TargetLV, RVal Val);
const GRState* St, SVal TargetLV, SVal Val);
// End-of-path.
virtual void EvalEndPath(GRExprEngine& Engine,
@ -1343,7 +1343,7 @@ public:
// Assumptions.
virtual const GRState* EvalAssume(GRStateManager& VMgr,
const GRState* St, RVal Cond,
const GRState* St, SVal Cond,
bool Assumption, bool& isFeasible);
// Error iterators.
@ -1473,10 +1473,10 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
SymbolID ErrorSym = 0;
for (ExprIterator I = arg_beg; I != arg_end; ++I, ++idx) {
RVal V = state.GetRVal(*I);
SVal V = state.GetSVal(*I);
if (isa<lval::SymbolVal>(V)) {
SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
if (isa<loc::SymbolVal>(V)) {
SymbolID Sym = cast<loc::SymbolVal>(V).getSymbol();
if (RefBindings::data_type* T = state.get<RefBindings>(Sym))
if (Update(state, Sym, *T, GetArgE(Summ, idx), hasErr)) {
ErrorExpr = *I;
@ -1484,12 +1484,12 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
break;
}
}
else if (isa<LVal>(V)) {
else if (isa<Loc>(V)) {
#if 0
// Nuke all arguments passed by reference.
StateMgr.Unbind(StVals, cast<LVal>(V));
StateMgr.Unbind(StVals, cast<Loc>(V));
#else
if (lval::MemRegionVal* MR = dyn_cast<lval::MemRegionVal>(&V)) {
if (loc::MemRegionVal* MR = dyn_cast<loc::MemRegionVal>(&V)) {
if (GetArgE(Summ, idx) == DoNothingByRef)
continue;
@ -1506,10 +1506,10 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
// disambiguate conjured symbols.
// Is the invalidated variable something that we were tracking?
RVal X = state.GetRVal(*MR);
SVal X = state.GetSVal(*MR);
if (isa<lval::SymbolVal>(X)) {
SymbolID Sym = cast<lval::SymbolVal>(X).getSymbol();
if (isa<loc::SymbolVal>(X)) {
SymbolID Sym = cast<loc::SymbolVal>(X).getSymbol();
state = state.remove<RefBindings>(Sym);
}
@ -1521,29 +1521,29 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
SymbolID NewSym =
Eng.getSymbolManager().getConjuredSymbol(*I, T, Count);
state = state.SetRVal(*MR,
LVal::IsLValType(T)
? cast<RVal>(lval::SymbolVal(NewSym))
: cast<RVal>(nonlval::SymbolVal(NewSym)));
state = state.SetSVal(*MR,
Loc::IsLocType(T)
? cast<SVal>(loc::SymbolVal(NewSym))
: cast<SVal>(nonloc::SymbolVal(NewSym)));
}
else
state = state.SetRVal(*MR, UnknownVal());
state = state.SetSVal(*MR, UnknownVal());
}
else {
// Nuke all other arguments passed by reference.
state = state.Unbind(cast<LVal>(V));
state = state.Unbind(cast<Loc>(V));
}
#endif
}
else if (isa<nonlval::LValAsInteger>(V))
state = state.Unbind(cast<nonlval::LValAsInteger>(V).getLVal());
else if (isa<nonloc::LocAsInteger>(V))
state = state.Unbind(cast<nonloc::LocAsInteger>(V).getLoc());
}
// Evaluate the effect on the message receiver.
if (!ErrorExpr && Receiver) {
RVal V = state.GetRVal(Receiver);
if (isa<lval::SymbolVal>(V)) {
SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
SVal V = state.GetSVal(Receiver);
if (isa<loc::SymbolVal>(V)) {
SymbolID Sym = cast<loc::SymbolVal>(V).getSymbol();
if (const RefVal* T = state.get<RefBindings>(Sym))
if (Update(state, Sym, *T, GetReceiverE(Summ), hasErr)) {
ErrorExpr = Receiver;
@ -1576,11 +1576,11 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
unsigned Count = Builder.getCurrentBlockCount();
SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count);
RVal X = LVal::IsLValType(Ex->getType())
? cast<RVal>(lval::SymbolVal(Sym))
: cast<RVal>(nonlval::SymbolVal(Sym));
SVal X = Loc::IsLocType(Ex->getType())
? cast<SVal>(loc::SymbolVal(Sym))
: cast<SVal>(nonloc::SymbolVal(Sym));
state = state.SetRVal(Ex, X, false);
state = state.SetSVal(Ex, X, false);
}
break;
@ -1589,15 +1589,15 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
unsigned idx = RE.getIndex();
assert (arg_end >= arg_beg);
assert (idx < (unsigned) (arg_end - arg_beg));
RVal V = state.GetRVal(*(arg_beg+idx));
state = state.SetRVal(Ex, V, false);
SVal V = state.GetSVal(*(arg_beg+idx));
state = state.SetSVal(Ex, V, false);
break;
}
case RetEffect::ReceiverAlias: {
assert (Receiver);
RVal V = state.GetRVal(Receiver);
state = state.SetRVal(Ex, V, false);
SVal V = state.GetSVal(Receiver);
state = state.SetSVal(Ex, V, false);
break;
}
@ -1608,7 +1608,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
QualType RetT = GetReturnType(Ex, Eng.getContext());
state = state.set<RefBindings>(Sym, RefVal::makeOwned(RetT));
state = state.SetRVal(Ex, lval::SymbolVal(Sym), false);
state = state.SetSVal(Ex, loc::SymbolVal(Sym), false);
#if 0
RefBindings B = GetRefBindings(StImpl);
@ -1628,7 +1628,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
QualType RetT = GetReturnType(Ex, Eng.getContext());
state = state.set<RefBindings>(Sym, RefVal::makeNotOwned(RetT));
state = state.SetRVal(Ex, lval::SymbolVal(Sym), false);
state = state.SetSVal(Ex, loc::SymbolVal(Sym), false);
break;
}
}
@ -1644,11 +1644,11 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
void CFRefCount::EvalCall(ExplodedNodeSet<GRState>& Dst,
GRExprEngine& Eng,
GRStmtNodeBuilder<GRState>& Builder,
CallExpr* CE, RVal L,
CallExpr* CE, SVal L,
ExplodedNode<GRState>* Pred) {
RetainSummary* Summ = !isa<lval::FuncVal>(L) ? 0
: Summaries.getSummary(cast<lval::FuncVal>(L).getDecl());
RetainSummary* Summ = !isa<loc::FuncVal>(L) ? 0
: Summaries.getSummary(cast<loc::FuncVal>(L).getDecl());
EvalSummary(Dst, Eng, Builder, CE, 0, Summ,
CE->arg_begin(), CE->arg_end(), Pred);
@ -1669,10 +1669,10 @@ void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
// FIXME: Wouldn't it be great if this code could be reduced? It's just
// a chain of lookups.
const GRState* St = Builder.GetState(Pred);
RVal V = Eng.getStateManager().GetRVal(St, Receiver );
SVal V = Eng.getStateManager().GetSVal(St, Receiver );
if (isa<lval::SymbolVal>(V)) {
SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
if (isa<loc::SymbolVal>(V)) {
SymbolID Sym = cast<loc::SymbolVal>(V).getSymbol();
if (const RefVal* T = St->get<RefBindings>(Sym)) {
QualType Ty = T->getType();
@ -1702,29 +1702,29 @@ void CFRefCount::EvalStore(ExplodedNodeSet<GRState>& Dst,
GRExprEngine& Eng,
GRStmtNodeBuilder<GRState>& Builder,
Expr* E, ExplodedNode<GRState>* Pred,
const GRState* St, RVal TargetLV, RVal Val) {
const GRState* St, SVal TargetLV, SVal Val) {
// Check if we have a binding for "Val" and if we are storing it to something
// we don't understand or otherwise the value "escapes" the function.
if (!isa<lval::SymbolVal>(Val))
if (!isa<loc::SymbolVal>(Val))
return;
// Are we storing to something that causes the value to "escape"?
bool escapes = false;
if (!isa<lval::MemRegionVal>(TargetLV))
if (!isa<loc::MemRegionVal>(TargetLV))
escapes = true;
else {
MemRegion* R = cast<lval::MemRegionVal>(TargetLV).getRegion();
MemRegion* R = cast<loc::MemRegionVal>(TargetLV).getRegion();
escapes = !Eng.getStateManager().hasStackStorage(R);
}
if (!escapes)
return;
SymbolID Sym = cast<lval::SymbolVal>(Val).getSymbol();
SymbolID Sym = cast<loc::SymbolVal>(Val).getSymbol();
GRStateRef state(St, Eng.getStateManager());
@ -1849,13 +1849,13 @@ void CFRefCount::EvalReturn(ExplodedNodeSet<GRState>& Dst,
if (!RetE) return;
GRStateRef state(Builder.GetState(Pred), Eng.getStateManager());
RVal V = state.GetRVal(RetE);
SVal V = state.GetSVal(RetE);
if (!isa<lval::SymbolVal>(V))
if (!isa<loc::SymbolVal>(V))
return;
// Get the reference count binding (if any).
SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
SymbolID Sym = cast<loc::SymbolVal>(V).getSymbol();
const RefVal* T = state.get<RefBindings>(Sym);
if (!T)
@ -1892,7 +1892,7 @@ void CFRefCount::EvalReturn(ExplodedNodeSet<GRState>& Dst,
const GRState* CFRefCount::EvalAssume(GRStateManager& VMgr,
const GRState* St,
RVal Cond, bool Assumption,
SVal Cond, bool Assumption,
bool& isFeasible) {
// FIXME: We may add to the interface of EvalAssume the list of symbols
@ -2303,9 +2303,9 @@ PathDiagnosticPiece* CFRefReport::VisitNode(ExplodedNode<GRState>* N,
for (Stmt::child_iterator I = S->child_begin(), E = S->child_end(); I!=E; ++I)
if (Expr* Exp = dyn_cast_or_null<Expr>(*I)) {
RVal X = VSM.GetRVal(CurrSt, Exp);
SVal X = VSM.GetSVal(CurrSt, Exp);
if (lval::SymbolVal* SV = dyn_cast<lval::SymbolVal>(&X))
if (loc::SymbolVal* SV = dyn_cast<loc::SymbolVal>(&X))
if (SV->getSymbol() == Sym) {
P->addRange(Exp->getSourceRange()); break;
}
@ -2324,12 +2324,12 @@ class VISIBILITY_HIDDEN FindUniqueBinding :
public:
FindUniqueBinding(SymbolID sym) : Sym(sym), Binding(0), First(true) {}
bool HandleBinding(StoreManager& SMgr, Store store, MemRegion* R, RVal val) {
if (const lval::SymbolVal* SV = dyn_cast<lval::SymbolVal>(&val)) {
bool HandleBinding(StoreManager& SMgr, Store store, MemRegion* R, SVal val) {
if (const loc::SymbolVal* SV = dyn_cast<loc::SymbolVal>(&val)) {
if (SV->getSymbol() != Sym)
return true;
}
else if (const nonlval::SymbolVal* SV=dyn_cast<nonlval::SymbolVal>(&val)) {
else if (const nonloc::SymbolVal* SV=dyn_cast<nonloc::SymbolVal>(&val)) {
if (SV->getSymbol() != Sym)
return true;
}

View File

@ -216,11 +216,11 @@ void NSErrorCheck::CheckParamDeref(VarDecl* Param, GRStateRef rootState,
GRExprEngine& Eng, GRBugReporter& BR,
bool isNSErrorWarning) {
RVal ParamRVal = rootState.GetLValue(Param);
SVal ParamSVal = rootState.GetLValue(Param);
// FIXME: For now assume that ParamRVal is symbolic. We need to generalize
// FIXME: For now assume that ParamSVal is symbolic. We need to generalize
// this later.
lval::SymbolVal* SV = dyn_cast<lval::SymbolVal>(&ParamRVal);
loc::SymbolVal* SV = dyn_cast<loc::SymbolVal>(&ParamSVal);
if (!SV) return;
// Iterate over the implicit-null dereferences.
@ -228,8 +228,8 @@ void NSErrorCheck::CheckParamDeref(VarDecl* Param, GRStateRef rootState,
E=Eng.implicit_null_derefs_end(); I!=E; ++I) {
GRStateRef state = GRStateRef((*I)->getState(), Eng.getStateManager());
const RVal* X = state.get<GRState::NullDerefTag>();
const lval::SymbolVal* SVX = dyn_cast_or_null<lval::SymbolVal>(X);
const SVal* X = state.get<GRState::NullDerefTag>();
const loc::SymbolVal* SVX = dyn_cast_or_null<loc::SymbolVal>(X);
if (!SVX || SVX->getSymbol() != SV->getSymbol()) continue;
// Emit an error.

View File

@ -18,14 +18,14 @@
using namespace clang;
RVal Environment::GetRVal(Expr* E, BasicValueFactory& BasicVals) const {
SVal Environment::GetSVal(Expr* E, BasicValueFactory& BasicVals) const {
for (;;) {
switch (E->getStmtClass()) {
case Stmt::AddrLabelExprClass:
return LVal::MakeVal(cast<AddrLabelExpr>(E));
return Loc::MakeVal(cast<AddrLabelExpr>(E));
// ParenExprs are no-ops.
@ -35,15 +35,15 @@ RVal Environment::GetRVal(Expr* E, BasicValueFactory& BasicVals) const {
case Stmt::CharacterLiteralClass: {
CharacterLiteral* C = cast<CharacterLiteral>(E);
return NonLVal::MakeVal(BasicVals, C->getValue(), C->getType());
return NonLoc::MakeVal(BasicVals, C->getValue(), C->getType());
}
case Stmt::IntegerLiteralClass: {
return NonLVal::MakeVal(BasicVals, cast<IntegerLiteral>(E));
return NonLoc::MakeVal(BasicVals, cast<IntegerLiteral>(E));
}
case Stmt::StringLiteralClass:
return LVal::MakeVal(cast<StringLiteral>(E));
return Loc::MakeVal(cast<StringLiteral>(E));
// Casts where the source and target type are the same
// are no-ops. We blast through these to get the descendant
@ -73,18 +73,18 @@ RVal Environment::GetRVal(Expr* E, BasicValueFactory& BasicVals) const {
return LookupExpr(E);
}
RVal Environment::GetBlkExprRVal(Expr* E, BasicValueFactory& BasicVals) const {
SVal Environment::GetBlkExprSVal(Expr* E, BasicValueFactory& BasicVals) const {
E = E->IgnoreParens();
switch (E->getStmtClass()) {
case Stmt::CharacterLiteralClass: {
CharacterLiteral* C = cast<CharacterLiteral>(E);
return NonLVal::MakeVal(BasicVals, C->getValue(), C->getType());
return NonLoc::MakeVal(BasicVals, C->getValue(), C->getType());
}
case Stmt::IntegerLiteralClass: {
return NonLVal::MakeVal(BasicVals, cast<IntegerLiteral>(E));
return NonLoc::MakeVal(BasicVals, cast<IntegerLiteral>(E));
}
default:
@ -92,7 +92,7 @@ RVal Environment::GetBlkExprRVal(Expr* E, BasicValueFactory& BasicVals) const {
}
}
Environment EnvironmentManager::SetRVal(const Environment& Env, Expr* E, RVal V,
Environment EnvironmentManager::SetSVal(const Environment& Env, Expr* E, SVal V,
bool isBlkExpr, bool Invalidate) {
assert (E);
@ -121,25 +121,25 @@ EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
Expr* BlkExpr = I.getKey();
if (Liveness.isLive(Loc, BlkExpr)) {
RVal X = I.getData();
SVal X = I.getData();
// If the block expr's value is a memory region, then mark that region.
if (isa<lval::MemRegionVal>(X))
DRoots.push_back(cast<lval::MemRegionVal>(X).getRegion());
if (isa<loc::MemRegionVal>(X))
DRoots.push_back(cast<loc::MemRegionVal>(X).getRegion());
// Mark all symbols in the block expr's value.
for (RVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
for (SVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
SI != SE; ++SI) {
LSymbols.insert(*SI);
}
} else {
// The block expr is dead.
RVal X = I.getData();
SVal X = I.getData();
// Do not misclean LogicalExpr or ConditionalOperator. It is dead at the
// beginning of itself, but we need its UndefinedVal to determine its
// RVal.
// SVal.
if (X.isUndef() && cast<UndefinedVal>(X).getData())
continue;

View File

@ -302,7 +302,7 @@ void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) {
}
else if (B->getOpcode() == BinaryOperator::Comma) {
const GRState* St = GetState(Pred);
MakeNode(Dst, B, Pred, SetRVal(St, B, GetRVal(St, B->getRHS())));
MakeNode(Dst, B, Pred, SetSVal(St, B, GetSVal(St, B->getRHS())));
break;
}
@ -385,7 +385,7 @@ void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) {
assert (!SE->getSubStmt()->body_empty());
if (Expr* LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin()))
MakeNode(Dst, SE, Pred, SetRVal(St, SE, GetRVal(St, LastExpr)));
MakeNode(Dst, SE, Pred, SetSVal(St, SE, GetSVal(St, LastExpr)));
else
Dst.Add(Pred);
@ -473,7 +473,7 @@ const GRState* GRExprEngine::MarkBranch(const GRState* St,
(Op == BinaryOperator::LOr && !branchTaken)
? B->getRHS() : B->getLHS();
return SetBlkExprRVal(St, B, UndefinedVal(Ex));
return SetBlkExprSVal(St, B, UndefinedVal(Ex));
}
case Stmt::ConditionalOperatorClass: { // ?:
@ -490,7 +490,7 @@ const GRState* GRExprEngine::MarkBranch(const GRState* St,
else
Ex = C->getRHS();
return SetBlkExprRVal(St, C, UndefinedVal(Ex));
return SetBlkExprSVal(St, C, UndefinedVal(Ex));
}
case Stmt::ChooseExprClass: { // ?:
@ -498,7 +498,7 @@ const GRState* GRExprEngine::MarkBranch(const GRState* St,
ChooseExpr* C = cast<ChooseExpr>(Terminator);
Expr* Ex = branchTaken ? C->getLHS() : C->getRHS();
return SetBlkExprRVal(St, C, UndefinedVal(Ex));
return SetBlkExprSVal(St, C, UndefinedVal(Ex));
}
}
}
@ -516,18 +516,18 @@ void GRExprEngine::ProcessBranch(Expr* Condition, Stmt* Term,
return;
}
RVal V = GetRVal(PrevState, Condition);
SVal V = GetSVal(PrevState, Condition);
switch (V.getBaseKind()) {
default:
break;
case RVal::UnknownKind:
case SVal::UnknownKind:
builder.generateNode(MarkBranch(PrevState, Term, true), true);
builder.generateNode(MarkBranch(PrevState, Term, false), false);
return;
case RVal::UndefinedKind: {
case SVal::UndefinedKind: {
NodeTy* N = builder.generateNode(PrevState, true);
if (N) {
@ -566,7 +566,7 @@ void GRExprEngine::ProcessBranch(Expr* Condition, Stmt* Term,
void GRExprEngine::ProcessIndirectGoto(IndirectGotoNodeBuilder& builder) {
const GRState* St = builder.getState();
RVal V = GetRVal(St, builder.getTarget());
SVal V = GetSVal(St, builder.getTarget());
// Three possibilities:
//
@ -577,8 +577,8 @@ void GRExprEngine::ProcessIndirectGoto(IndirectGotoNodeBuilder& builder) {
typedef IndirectGotoNodeBuilder::iterator iterator;
if (isa<lval::GotoLabel>(V)) {
LabelStmt* L = cast<lval::GotoLabel>(V).getLabel();
if (isa<loc::GotoLabel>(V)) {
LabelStmt* L = cast<loc::GotoLabel>(V).getLabel();
for (iterator I=builder.begin(), E=builder.end(); I != E; ++I) {
if (I.getLabel() == L) {
@ -591,7 +591,7 @@ void GRExprEngine::ProcessIndirectGoto(IndirectGotoNodeBuilder& builder) {
return;
}
if (isa<lval::ConcreteInt>(V) || isa<UndefinedVal>(V)) {
if (isa<loc::ConcreteInt>(V) || isa<UndefinedVal>(V)) {
// Dispatch to the first target and mark it as a sink.
NodeTy* N = builder.generateNode(builder.begin(), St, true);
UndefBranches.insert(N);
@ -613,7 +613,7 @@ void GRExprEngine::VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R,
assert (Ex == CurrentStmt && getCFG().isBlkExpr(Ex));
const GRState* St = GetState(Pred);
RVal X = GetBlkExprRVal(St, Ex);
SVal X = GetBlkExprSVal(St, Ex);
assert (X.isUndef());
@ -621,10 +621,10 @@ void GRExprEngine::VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R,
assert (SE);
X = GetBlkExprRVal(St, SE);
X = GetBlkExprSVal(St, SE);
// Make sure that we invalidate the previous binding.
MakeNode(Dst, Ex, Pred, StateMgr.SetRVal(St, Ex, X, true, true));
MakeNode(Dst, Ex, Pred, StateMgr.SetSVal(St, Ex, X, true, true));
}
/// ProcessSwitch - Called by GRCoreEngine. Used to generate successor
@ -635,7 +635,7 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) {
const GRState* St = builder.getState();
Expr* CondE = builder.getCondition();
RVal CondV = GetRVal(St, CondE);
SVal CondV = GetSVal(St, CondE);
if (CondV.isUndef()) {
NodeTy* N = builder.generateDefaultCaseNode(St, true);
@ -683,9 +683,9 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) {
// This should be easy once we have "ranges" for NonLVals.
do {
nonlval::ConcreteInt CaseVal(getBasicVals().getValue(V1));
nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1));
RVal Res = EvalBinOp(BinaryOperator::EQ, CondV, CaseVal);
SVal Res = EvalBinOp(BinaryOperator::EQ, CondV, CaseVal);
// Now "assume" that the case matches.
@ -698,7 +698,7 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) {
// If CondV evaluates to a constant, then we know that this
// is the *only* case that we can take, so stop evaluating the
// others.
if (isa<nonlval::ConcreteInt>(CondV))
if (isa<nonloc::ConcreteInt>(CondV))
return;
}
@ -741,7 +741,7 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred,
assert (B == CurrentStmt && getCFG().isBlkExpr(B));
const GRState* St = GetState(Pred);
RVal X = GetBlkExprRVal(St, B);
SVal X = GetBlkExprSVal(St, B);
assert (X.isUndef());
@ -751,12 +751,12 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred,
if (Ex == B->getRHS()) {
X = GetBlkExprRVal(St, Ex);
X = GetBlkExprSVal(St, Ex);
// Handle undefined values.
if (X.isUndef()) {
MakeNode(Dst, B, Pred, SetBlkExprRVal(St, B, X));
MakeNode(Dst, B, Pred, SetBlkExprSVal(St, B, X));
return;
}
@ -772,14 +772,14 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred,
if (isFeasible)
MakeNode(Dst, B, Pred,
SetBlkExprRVal(NewState, B, MakeConstantVal(1U, B)));
SetBlkExprSVal(NewState, B, MakeConstantVal(1U, B)));
isFeasible = false;
NewState = Assume(St, X, false, isFeasible);
if (isFeasible)
MakeNode(Dst, B, Pred,
SetBlkExprRVal(NewState, B, MakeConstantVal(0U, B)));
SetBlkExprSVal(NewState, B, MakeConstantVal(0U, B)));
}
else {
// We took the LHS expression. Depending on whether we are '&&' or
@ -787,7 +787,7 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred,
// the short-circuiting.
X = MakeConstantVal( B->getOpcode() == BinaryOperator::LAnd ? 0U : 1U, B);
MakeNode(Dst, B, Pred, SetBlkExprRVal(St, B, X));
MakeNode(Dst, B, Pred, SetBlkExprSVal(St, B, X));
}
}
@ -804,7 +804,7 @@ void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* Ex, NodeTy* Pred, NodeSet& Dst,
if (const VarDecl* VD = dyn_cast<VarDecl>(D)) {
RVal V = StateMgr.GetLValue(St, VD);
SVal V = StateMgr.GetLValue(St, VD);
if (VD->getType()->isArrayType()) {
// C++ standard says array of type T should be implicitly converted to
@ -813,12 +813,12 @@ void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* Ex, NodeTy* Pred, NodeSet& Dst,
// this in a transfer function in the future. We represent both lvalue and
// rvalue of array of type T as the corresponding MemRegionVal of it.
MakeNode(Dst, Ex, Pred, SetRVal(St, Ex, V));
MakeNode(Dst, Ex, Pred, SetSVal(St, Ex, V));
return;
}
if (asLValue)
MakeNode(Dst, Ex, Pred, SetRVal(St, Ex, V));
MakeNode(Dst, Ex, Pred, SetSVal(St, Ex, V));
else
EvalLoad(Dst, Ex, Pred, St, V);
return;
@ -827,17 +827,17 @@ void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* Ex, NodeTy* Pred, NodeSet& Dst,
assert(!asLValue && "EnumConstantDecl does not have lvalue.");
BasicValueFactory& BasicVals = StateMgr.getBasicVals();
RVal V = nonlval::ConcreteInt(BasicVals.getValue(ED->getInitVal()));
MakeNode(Dst, Ex, Pred, SetRVal(St, Ex, V));
SVal V = nonloc::ConcreteInt(BasicVals.getValue(ED->getInitVal()));
MakeNode(Dst, Ex, Pred, SetSVal(St, Ex, V));
return;
} else if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(D)) {
// We return the lval::FuncVal for an FunctionDecl in both rvalue
// We return the loc::FuncVal for an FunctionDecl in both rvalue
// and lvalue contexts.
// FIXME: Does this need to be revised? We were getting cases in
// real code that did this.
RVal V = lval::FuncVal(FD);
MakeNode(Dst, Ex, Pred, SetRVal(St, Ex, V));
SVal V = loc::FuncVal(FD);
MakeNode(Dst, Ex, Pred, SetSVal(St, Ex, V));
return;
}
@ -860,10 +860,10 @@ void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A, NodeTy* Pred,
for (NodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end(); I2!=E2; ++I2) {
const GRState* St = GetState(*I2);
RVal V = StateMgr.GetLValue(St, GetRVal(St, Base), GetRVal(St, Idx));
SVal V = StateMgr.GetLValue(St, GetSVal(St, Base), GetSVal(St, Idx));
if (asLValue)
MakeNode(Dst, A, *I2, SetRVal(St, A, V));
MakeNode(Dst, A, *I2, SetSVal(St, A, V));
else
EvalLoad(Dst, A, *I2, St, V);
}
@ -883,17 +883,17 @@ void GRExprEngine::VisitMemberExpr(MemberExpr* M, NodeTy* Pred,
// FIXME: Should we insert some assumption logic in here to determine
// if "Base" is a valid piece of memory? Before we put this assumption
// later when using FieldOffset lvals (which we no longer have).
RVal L = StateMgr.GetLValue(St, M->getMemberDecl(), GetRVal(St, Base));
SVal L = StateMgr.GetLValue(St, M->getMemberDecl(), GetSVal(St, Base));
if (asLValue)
MakeNode(Dst, M, *I, SetRVal(St, M, L));
MakeNode(Dst, M, *I, SetSVal(St, M, L));
else
EvalLoad(Dst, M, *I, St, L);
}
}
void GRExprEngine::EvalStore(NodeSet& Dst, Expr* Ex, NodeTy* Pred,
const GRState* St, RVal location, RVal Val) {
const GRState* St, SVal location, SVal Val) {
assert (Builder && "GRStmtNodeBuilder must be defined.");
@ -925,7 +925,7 @@ void GRExprEngine::EvalStore(NodeSet& Dst, Expr* Ex, NodeTy* Pred,
}
void GRExprEngine::EvalLoad(NodeSet& Dst, Expr* Ex, NodeTy* Pred,
const GRState* St, RVal location,
const GRState* St, SVal location,
bool CheckOnly) {
// Evaluate the location (checks for bad dereferences).
@ -948,15 +948,15 @@ void GRExprEngine::EvalLoad(NodeSet& Dst, Expr* Ex, NodeTy* Pred,
MakeNode(Dst, Ex, Pred, St, K);
else if (location.isUnknown()) {
// This is important. We must nuke the old binding.
MakeNode(Dst, Ex, Pred, SetRVal(St, Ex, UnknownVal()), K);
MakeNode(Dst, Ex, Pred, SetSVal(St, Ex, UnknownVal()), K);
}
else
MakeNode(Dst, Ex, Pred, SetRVal(St, Ex, GetRVal(St, cast<LVal>(location),
MakeNode(Dst, Ex, Pred, SetSVal(St, Ex, GetSVal(St, cast<Loc>(location),
Ex->getType())), K);
}
void GRExprEngine::EvalStore(NodeSet& Dst, Expr* Ex, Expr* StoreE, NodeTy* Pred,
const GRState* St, RVal location, RVal Val) {
const GRState* St, SVal location, SVal Val) {
NodeSet TmpDst;
EvalStore(TmpDst, StoreE, Pred, St, location, Val);
@ -967,7 +967,7 @@ void GRExprEngine::EvalStore(NodeSet& Dst, Expr* Ex, Expr* StoreE, NodeTy* Pred,
const GRState* GRExprEngine::EvalLocation(Expr* Ex, NodeTy* Pred,
const GRState* St,
RVal location, bool isLoad) {
SVal location, bool isLoad) {
// Check for loads/stores from/to undefined values.
if (location.isUndef()) {
@ -992,7 +992,7 @@ const GRState* GRExprEngine::EvalLocation(Expr* Ex, NodeTy* Pred,
//
// We add these assumptions.
LVal LV = cast<LVal>(location);
Loc LV = cast<Loc>(location);
// "Assume" that the pointer is not NULL.
@ -1008,7 +1008,7 @@ const GRState* GRExprEngine::EvalLocation(Expr* Ex, NodeTy* Pred,
if (isFeasibleNull) {
// Use the Generic Data Map to mark in the state what lval was null.
const RVal* PersistentLV = getBasicVals().getPersistentRVal(LV);
const SVal* PersistentLV = getBasicVals().getPersistentSVal(LV);
StNull = StNull.set<GRState::NullDerefTag>(PersistentLV);
// We don't use "MakeNode" here because the node will be a sink
@ -1066,14 +1066,14 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
for (NodeSet::iterator DI = DstTmp.begin(), DE = DstTmp.end(); DI!=DE; ++DI) {
const GRState* St = GetState(*DI);
RVal L = GetRVal(St, Callee);
SVal L = GetSVal(St, Callee);
// FIXME: Add support for symbolic function calls (calls involving
// function pointer values that are symbolic).
// Check for undefined control-flow or calls to NULL.
if (L.isUndef() || isa<lval::ConcreteInt>(L)) {
if (L.isUndef() || isa<loc::ConcreteInt>(L)) {
NodeTy* N = Builder->generateNode(CE, St, *DI);
if (N) {
@ -1088,9 +1088,9 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
SaveAndRestore<bool> OldSink(Builder->BuildSinks);
if (isa<lval::FuncVal>(L)) {
if (isa<loc::FuncVal>(L)) {
FunctionDecl* FD = cast<lval::FuncVal>(L).getDecl();
FunctionDecl* FD = cast<loc::FuncVal>(L).getDecl();
if (FD->getAttr<NoReturnAttr>())
Builder->BuildSinks = true;
@ -1113,10 +1113,10 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
if (!memcmp(s, "panic", 5)) Builder->BuildSinks = true;
else if (!memcmp(s, "error", 5)) {
if (CE->getNumArgs() > 0) {
RVal X = GetRVal(St, *CE->arg_begin());
SVal X = GetSVal(St, *CE->arg_begin());
// FIXME: use Assume to inspect the possible symbolic value of
// X. Also check the specific signature of error().
nonlval::ConcreteInt* CI = dyn_cast<nonlval::ConcreteInt>(&X);
nonloc::ConcreteInt* CI = dyn_cast<nonloc::ConcreteInt>(&X);
if (CI && CI->getValue() != 0)
Builder->BuildSinks = true;
}
@ -1168,17 +1168,17 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
// Evaluate the call.
if (isa<lval::FuncVal>(L)) {
if (isa<loc::FuncVal>(L)) {
IdentifierInfo* Info = cast<lval::FuncVal>(L).getDecl()->getIdentifier();
IdentifierInfo* Info = cast<loc::FuncVal>(L).getDecl()->getIdentifier();
if (unsigned id = Info->getBuiltinID())
switch (id) {
case Builtin::BI__builtin_expect: {
// For __builtin_expect, just return the value of the subexpression.
assert (CE->arg_begin() != CE->arg_end());
RVal X = GetRVal(St, *(CE->arg_begin()));
MakeNode(Dst, CE, *DI, SetRVal(St, CE, X));
SVal X = GetSVal(St, *(CE->arg_begin()));
MakeNode(Dst, CE, *DI, SetSVal(St, CE, X));
continue;
}
@ -1194,7 +1194,7 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
I != E; ++I) {
if (GetRVal(GetState(*DI), *I).isUndef()) {
if (GetSVal(GetState(*DI), *I).isUndef()) {
NodeTy* N = Builder->generateNode(CE, GetState(*DI), *DI);
if (N) {
@ -1239,11 +1239,11 @@ void GRExprEngine::VisitObjCIvarRefExpr(ObjCIvarRefExpr* Ex,
for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
const GRState* St = GetState(*I);
RVal BaseVal = GetRVal(St, Base);
RVal location = StateMgr.GetLValue(St, Ex->getDecl(), BaseVal);
SVal BaseVal = GetSVal(St, Base);
SVal location = StateMgr.GetLValue(St, Ex->getDecl(), BaseVal);
if (asLValue)
MakeNode(Dst, Ex, *I, SetRVal(St, Ex, location));
MakeNode(Dst, Ex, *I, SetSVal(St, Ex, location));
else
EvalLoad(Dst, Ex, *I, St, location);
}
@ -1303,7 +1303,7 @@ void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME,
if (Expr* Receiver = ME->getReceiver()) {
RVal L = GetRVal(St, Receiver);
SVal L = GetSVal(St, Receiver);
// Check for undefined control-flow or calls to NULL.
@ -1374,7 +1374,7 @@ void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME,
for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end();
I != E; ++I) {
if (GetRVal(St, *I).isUndef()) {
if (GetSVal(St, *I).isUndef()) {
// Generate an error node for passing an uninitialized/undefined value
// as an argument to a message expression. This node is a sink.
@ -1442,7 +1442,7 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){
for (NodeSet::iterator I1 = S1.begin(), E1 = S1.end(); I1 != E1; ++I1) {
NodeTy* N = *I1;
const GRState* St = GetState(N);
RVal V = GetRVal(St, Ex);
SVal V = GetSVal(St, Ex);
// Unknown?
@ -1454,7 +1454,7 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){
// Undefined?
if (V.isUndef()) {
MakeNode(Dst, CastE, N, SetRVal(St, CastE, V));
MakeNode(Dst, CastE, N, SetSVal(St, CastE, V));
continue;
}
@ -1463,35 +1463,35 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){
if (C.getCanonicalType(T).getUnqualifiedType() ==
C.getCanonicalType(ExTy).getUnqualifiedType()) {
MakeNode(Dst, CastE, N, SetRVal(St, CastE, V));
MakeNode(Dst, CastE, N, SetSVal(St, CastE, V));
continue;
}
// Check for casts from pointers to integers.
if (T->isIntegerType() && LVal::IsLValType(ExTy)) {
if (T->isIntegerType() && Loc::IsLocType(ExTy)) {
unsigned bits = getContext().getTypeSize(ExTy);
// FIXME: Determine if the number of bits of the target type is
// equal or exceeds the number of bits to store the pointer value.
// If not, flag an error.
V = nonlval::LValAsInteger::Make(getBasicVals(), cast<LVal>(V), bits);
MakeNode(Dst, CastE, N, SetRVal(St, CastE, V));
V = nonloc::LocAsInteger::Make(getBasicVals(), cast<Loc>(V), bits);
MakeNode(Dst, CastE, N, SetSVal(St, CastE, V));
continue;
}
// Check for casts from integers to pointers.
if (LVal::IsLValType(T) && ExTy->isIntegerType())
if (nonlval::LValAsInteger *LV = dyn_cast<nonlval::LValAsInteger>(&V)) {
if (Loc::IsLocType(T) && ExTy->isIntegerType())
if (nonloc::LocAsInteger *LV = dyn_cast<nonloc::LocAsInteger>(&V)) {
// Just unpackage the lval and return it.
V = LV->getLVal();
MakeNode(Dst, CastE, N, SetRVal(St, CastE, V));
V = LV->getLoc();
MakeNode(Dst, CastE, N, SetSVal(St, CastE, V));
continue;
}
// All other cases.
MakeNode(Dst, CastE, N, SetRVal(St, CastE, EvalCast(V, CastE->getType())));
MakeNode(Dst, CastE, N, SetSVal(St, CastE, EvalCast(V, CastE->getType())));
}
}
@ -1559,8 +1559,8 @@ void GRExprEngine::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr* Ex,
amt = getContext().getTypeAlign(T) / 8;
MakeNode(Dst, Ex, Pred,
SetRVal(GetState(Pred), Ex,
NonLVal::MakeVal(getBasicVals(), amt, Ex->getType())));
SetSVal(GetState(Pred), Ex,
NonLoc::MakeVal(getBasicVals(), amt, Ex->getType())));
}
@ -1581,10 +1581,10 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
const GRState* St = GetState(*I);
RVal location = GetRVal(St, Ex);
SVal location = GetSVal(St, Ex);
if (asLValue)
MakeNode(Dst, U, *I, SetRVal(St, U, location));
MakeNode(Dst, U, *I, SetSVal(St, U, location));
else
EvalLoad(Dst, U, *I, St, location);
}
@ -1600,7 +1600,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
// FIXME: We don't have complex RValues yet.
// FIXME: We don't have complex SValues yet.
if (Ex->getType()->isAnyComplexType()) {
// Just report "Unknown."
Dst.Add(*I);
@ -1610,7 +1610,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
// For all other types, UnaryOperator::Real is an identity operation.
assert (U->getType() == Ex->getType());
const GRState* St = GetState(*I);
MakeNode(Dst, U, *I, SetRVal(St, U, GetRVal(St, Ex)));
MakeNode(Dst, U, *I, SetSVal(St, U, GetSVal(St, Ex)));
}
return;
@ -1623,7 +1623,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
Visit(Ex, Pred, Tmp);
for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
// FIXME: We don't have complex RValues yet.
// FIXME: We don't have complex SValues yet.
if (Ex->getType()->isAnyComplexType()) {
// Just report "Unknown."
Dst.Add(*I);
@ -1633,8 +1633,8 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
// For all other types, UnaryOperator::Float returns 0.
assert (Ex->getType()->isIntegerType());
const GRState* St = GetState(*I);
RVal X = NonLVal::MakeVal(getBasicVals(), 0, Ex->getType());
MakeNode(Dst, U, *I, SetRVal(St, U, X));
SVal X = NonLoc::MakeVal(getBasicVals(), 0, Ex->getType());
MakeNode(Dst, U, *I, SetSVal(St, U, X));
}
return;
@ -1659,7 +1659,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
const GRState* St = GetState(*I);
MakeNode(Dst, U, *I, SetRVal(St, U, GetRVal(St, Ex)));
MakeNode(Dst, U, *I, SetSVal(St, U, GetSVal(St, Ex)));
}
return;
@ -1674,8 +1674,8 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
const GRState* St = GetState(*I);
RVal V = GetRVal(St, Ex);
St = SetRVal(St, U, V);
SVal V = GetSVal(St, Ex);
St = SetSVal(St, U, V);
MakeNode(Dst, U, *I, St);
}
@ -1695,7 +1695,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
const GRState* St = GetState(*I);
// Get the value of the subexpression.
RVal V = GetRVal(St, Ex);
SVal V = GetSVal(St, Ex);
// Perform promotions.
// FIXME: This is the right thing to do, but it currently breaks
@ -1703,7 +1703,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
// V = EvalCast(V, U->getType());
if (V.isUnknownOrUndef()) {
MakeNode(Dst, U, *I, SetRVal(St, U, V));
MakeNode(Dst, U, *I, SetSVal(St, U, V));
continue;
}
@ -1714,12 +1714,12 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
case UnaryOperator::Not:
// FIXME: Do we need to handle promotions?
St = SetRVal(St, U, EvalComplement(cast<NonLVal>(V)));
St = SetSVal(St, U, EvalComplement(cast<NonLoc>(V)));
break;
case UnaryOperator::Minus:
// FIXME: Do we need to handle promotions?
St = SetRVal(St, U, EvalMinus(U, cast<NonLVal>(V)));
St = SetSVal(St, U, EvalMinus(U, cast<NonLoc>(V)));
break;
case UnaryOperator::LNot:
@ -1729,18 +1729,18 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
// Note: technically we do "E == 0", but this is the same in the
// transfer functions as "0 == E".
if (isa<LVal>(V)) {
lval::ConcreteInt X(getBasicVals().getZeroWithPtrWidth());
RVal Result = EvalBinOp(BinaryOperator::EQ, cast<LVal>(V), X);
St = SetRVal(St, U, Result);
if (isa<Loc>(V)) {
loc::ConcreteInt X(getBasicVals().getZeroWithPtrWidth());
SVal Result = EvalBinOp(BinaryOperator::EQ, cast<Loc>(V), X);
St = SetSVal(St, U, Result);
}
else {
nonlval::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
#if 0
RVal Result = EvalBinOp(BinaryOperator::EQ, cast<NonLVal>(V), X);
St = SetRVal(St, U, Result);
SVal Result = EvalBinOp(BinaryOperator::EQ, cast<NonLoc>(V), X);
St = SetSVal(St, U, Result);
#else
EvalBinOp(Dst, U, BinaryOperator::EQ, cast<NonLVal>(V), X, *I);
EvalBinOp(Dst, U, BinaryOperator::EQ, cast<NonLoc>(V), X, *I);
continue;
#endif
}
@ -1765,7 +1765,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
uint64_t size = getContext().getTypeSize(T) / 8;
const GRState* St = GetState(Pred);
St = SetRVal(St, U, NonLVal::MakeVal(getBasicVals(), size, U->getType()));
St = SetSVal(St, U, NonLoc::MakeVal(getBasicVals(), size, U->getType()));
MakeNode(Dst, U, Pred, St);
return;
@ -1782,7 +1782,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
for (NodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) {
const GRState* St = GetState(*I);
RVal V1 = GetRVal(St, Ex);
SVal V1 = GetSVal(St, Ex);
// Perform a load.
NodeSet Tmp2;
@ -1791,11 +1791,11 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
for (NodeSet::iterator I2 = Tmp2.begin(), E2 = Tmp2.end(); I2!=E2; ++I2) {
St = GetState(*I2);
RVal V2 = GetRVal(St, Ex);
SVal V2 = GetSVal(St, Ex);
// Propagate unknown and undefined values.
if (V2.isUnknownOrUndef()) {
MakeNode(Dst, U, *I2, SetRVal(St, U, V2));
MakeNode(Dst, U, *I2, SetSVal(St, U, V2));
continue;
}
@ -1804,8 +1804,8 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
BinaryOperator::Opcode Op = U->isIncrementOp() ? BinaryOperator::Add
: BinaryOperator::Sub;
RVal Result = EvalBinOp(Op, V2, MakeConstantVal(1U, U));
St = SetRVal(St, U, U->isPostfix() ? V2 : Result);
SVal Result = EvalBinOp(Op, V2, MakeConstantVal(1U, U));
St = SetSVal(St, U, U->isPostfix() ? V2 : Result);
// Perform the store.
EvalStore(Dst, U, *I2, St, V1, Result);
@ -1842,7 +1842,7 @@ void GRExprEngine::VisitAsmStmtHelperInputs(AsmStmt* A,
if (I == E) {
// We have processed both the inputs and the outputs. All of the outputs
// should evaluate to LVals. Nuke all of their values.
// should evaluate to Locs. Nuke all of their values.
// FIXME: Some day in the future it would be nice to allow a "plug-in"
// which interprets the inline asm and stores proper results in the
@ -1853,11 +1853,11 @@ void GRExprEngine::VisitAsmStmtHelperInputs(AsmStmt* A,
for (AsmStmt::outputs_iterator OI = A->begin_outputs(),
OE = A->end_outputs(); OI != OE; ++OI) {
RVal X = GetRVal(St, *OI);
assert (!isa<NonLVal>(X)); // Should be an Lval, or unknown, undef.
SVal X = GetSVal(St, *OI);
assert (!isa<NonLoc>(X)); // Should be an Lval, or unknown, undef.
if (isa<LVal>(X))
St = SetRVal(St, cast<LVal>(X), UnknownVal());
if (isa<Loc>(X))
St = SetSVal(St, cast<Loc>(X), UnknownVal());
}
MakeNode(Dst, A, Pred, St);
@ -1909,12 +1909,12 @@ void GRExprEngine::VisitReturnStmt(ReturnStmt* S, NodeTy* Pred, NodeSet& Dst) {
Visit(R, Pred, Tmp);
for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
RVal X = GetRVal((*I)->getState(), R);
SVal X = GetSVal((*I)->getState(), R);
if (isa<lval::MemRegionVal>(X)) {
if (isa<loc::MemRegionVal>(X)) {
// Determine if the value is on the stack.
const MemRegion* R = cast<lval::MemRegionVal>(&X)->getRegion();
const MemRegion* R = cast<loc::MemRegionVal>(&X)->getRegion();
if (R && getStateManager().hasStackStorage(R)) {
@ -1946,7 +1946,7 @@ void GRExprEngine::VisitReturnStmt(ReturnStmt* S, NodeTy* Pred, NodeSet& Dst) {
//===----------------------------------------------------------------------===//
bool GRExprEngine::CheckDivideZero(Expr* Ex, const GRState* St,
NodeTy* Pred, RVal Denom) {
NodeTy* Pred, SVal Denom) {
// Divide by undefined? (potentially zero)
@ -2003,7 +2003,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
for (NodeSet::iterator I1=Tmp1.begin(), E1=Tmp1.end(); I1 != E1; ++I1) {
RVal LeftV = GetRVal((*I1)->getState(), LHS);
SVal LeftV = GetSVal((*I1)->getState(), LHS);
// Process the RHS.
@ -2015,7 +2015,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
for (NodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end(); I2 != E2; ++I2) {
const GRState* St = GetState(*I2);
RVal RightV = GetRVal(St, RHS);
SVal RightV = GetSVal(St, RHS);
BinaryOperator::Opcode Op = B->getOpcode();
switch (Op) {
@ -2028,15 +2028,15 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
unsigned Count = Builder->getCurrentBlockCount();
SymbolID Sym = SymMgr.getConjuredSymbol(B->getRHS(), Count);
RightV = LVal::IsLValType(B->getRHS()->getType())
? cast<RVal>(lval::SymbolVal(Sym))
: cast<RVal>(nonlval::SymbolVal(Sym));
RightV = Loc::IsLocType(B->getRHS()->getType())
? cast<SVal>(loc::SymbolVal(Sym))
: cast<SVal>(nonloc::SymbolVal(Sym));
}
// Simulate the effects of a "store": bind the value of the RHS
// to the L-Value represented by the LHS.
EvalStore(Dst, B, LHS, *I2, SetRVal(St, B, RightV), LeftV, RightV);
EvalStore(Dst, B, LHS, *I2, SetSVal(St, B, RightV), LeftV, RightV);
continue;
}
@ -2059,7 +2059,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
// Process non-assignements except commas or short-circuited
// logical expressions (LAnd and LOr).
RVal Result = EvalBinOp(Op, LeftV, RightV);
SVal Result = EvalBinOp(Op, LeftV, RightV);
if (Result.isUnknown()) {
Dst.Add(*I2);
@ -2081,7 +2081,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
// Otherwise, create a new node.
MakeNode(Dst, B, *I2, SetRVal(St, B, Result));
MakeNode(Dst, B, *I2, SetSVal(St, B, Result));
continue;
}
}
@ -2096,23 +2096,23 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
// Perform a load (the LHS). This performs the checks for
// null dereferences, and so on.
NodeSet Tmp3;
RVal location = GetRVal(St, LHS);
SVal location = GetSVal(St, LHS);
EvalLoad(Tmp3, LHS, *I2, St, location);
for (NodeSet::iterator I3=Tmp3.begin(), E3=Tmp3.end(); I3!=E3; ++I3) {
St = GetState(*I3);
RVal V = GetRVal(St, LHS);
SVal V = GetSVal(St, LHS);
// Propagate undefined values (left-side).
if (V.isUndef()) {
EvalStore(Dst, B, LHS, *I3, SetRVal(St, B, V), location, V);
EvalStore(Dst, B, LHS, *I3, SetSVal(St, B, V), location, V);
continue;
}
// Propagate unknown values (left and right-side).
if (RightV.isUnknown() || V.isUnknown()) {
EvalStore(Dst, B, LHS, *I3, SetRVal(St, B, UnknownVal()), location,
EvalStore(Dst, B, LHS, *I3, SetSVal(St, B, UnknownVal()), location,
UnknownVal());
continue;
}
@ -2139,13 +2139,13 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
}
else if (RightV.isUndef()) {
// Propagate undefined values (right-side).
EvalStore(Dst, B, LHS, *I3, SetRVal(St, B, RightV), location, RightV);
EvalStore(Dst, B, LHS, *I3, SetSVal(St, B, RightV), location, RightV);
continue;
}
// Compute the result of the operation.
RVal Result = EvalCast(EvalBinOp(Op, V, RightV), B->getType());
SVal Result = EvalCast(EvalBinOp(Op, V, RightV), B->getType());
if (Result.isUndef()) {
@ -2159,7 +2159,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
continue;
}
EvalStore(Dst, B, LHS, *I3, SetRVal(St, B, Result), location, Result);
EvalStore(Dst, B, LHS, *I3, SetSVal(St, B, Result), location, Result);
}
}
}
@ -2171,7 +2171,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
void GRExprEngine::EvalBinOp(ExplodedNodeSet<GRState>& Dst, Expr* Ex,
BinaryOperator::Opcode Op,
NonLVal L, NonLVal R,
NonLoc L, NonLoc R,
ExplodedNode<GRState>* Pred) {
GRStateSet OStates;
@ -2183,7 +2183,7 @@ void GRExprEngine::EvalBinOp(ExplodedNodeSet<GRState>& Dst, Expr* Ex,
void GRExprEngine::EvalBinOp(GRStateSet& OStates, const GRState* St,
Expr* Ex, BinaryOperator::Opcode Op,
NonLVal L, NonLVal R) {
NonLoc L, NonLoc R) {
GRStateSet::AutoPopulate AP(OStates, St);
if (R.isValid()) getTF().EvalBinOpNN(OStates, StateMgr, St, Ex, Op, L, R);
@ -2263,7 +2263,7 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :
else if (GraphPrintCheckerState->isUndefDeref(N))
Out << "\\|Dereference of undefialied value.\\l";
else if (GraphPrintCheckerState->isUndefStore(N))
Out << "\\|Store to Undefined LVal.";
Out << "\\|Store to Undefined Loc.";
else if (GraphPrintCheckerState->isExplicitBadDivide(N))
Out << "\\|Explicit divide-by zero or undefined value.";
else if (GraphPrintCheckerState->isImplicitBadDivide(N))

View File

@ -194,8 +194,8 @@ public:
assert (E && "Return expression cannot be NULL");
// Get the value associated with E.
lval::MemRegionVal V =
cast<lval::MemRegionVal>(Eng.getStateManager().GetRVal(N->getState(),
loc::MemRegionVal V =
cast<loc::MemRegionVal>(Eng.getStateManager().GetSVal(N->getState(),
E));
// Generate a report for this bug.
@ -235,7 +235,7 @@ class VISIBILITY_HIDDEN UndefBranch : public BuiltinBug {
return Ex;
}
bool MatchesCriteria(Expr* Ex) { return VM.GetRVal(St, Ex).isUndef(); }
bool MatchesCriteria(Expr* Ex) { return VM.GetSVal(St, Ex).isUndef(); }
};
public:
@ -303,12 +303,12 @@ public:
CallExpr* CE = cast<CallExpr>(cast<PostStmt>(N->getLocation()).getStmt());
const GRState* state = N->getState();
RVal X = VMgr.GetRVal(state, CE->getCallee());
SVal X = VMgr.GetSVal(state, CE->getCallee());
if (!isa<lval::FuncVal>(X))
if (!isa<loc::FuncVal>(X))
return false;
FunctionDecl* FD = dyn_cast<FunctionDecl>(cast<lval::FuncVal>(X).getDecl());
FunctionDecl* FD = dyn_cast<FunctionDecl>(cast<loc::FuncVal>(X).getDecl());
const NonNullAttr* Att = FD->getAttr<NonNullAttr>();
if (!Att)

View File

@ -36,32 +36,32 @@ GRTransferFuncs* clang::MakeGRSimpleValsTF() { return new GRSimpleVals(); }
// Transfer function for Casts.
//===----------------------------------------------------------------------===//
RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, NonLVal X, QualType T) {
SVal GRSimpleVals::EvalCast(GRExprEngine& Eng, NonLoc X, QualType T) {
if (!isa<nonlval::ConcreteInt>(X))
if (!isa<nonloc::ConcreteInt>(X))
return UnknownVal();
bool isLValType = LVal::IsLValType(T);
bool isLocType = Loc::IsLocType(T);
// Only handle casts from integers to integers.
if (!isLValType && !T->isIntegerType())
if (!isLocType && !T->isIntegerType())
return UnknownVal();
BasicValueFactory& BasicVals = Eng.getBasicVals();
llvm::APSInt V = cast<nonlval::ConcreteInt>(X).getValue();
V.setIsUnsigned(T->isUnsignedIntegerType() || LVal::IsLValType(T));
llvm::APSInt V = cast<nonloc::ConcreteInt>(X).getValue();
V.setIsUnsigned(T->isUnsignedIntegerType() || Loc::IsLocType(T));
V.extOrTrunc(Eng.getContext().getTypeSize(T));
if (isLValType)
return lval::ConcreteInt(BasicVals.getValue(V));
if (isLocType)
return loc::ConcreteInt(BasicVals.getValue(V));
else
return nonlval::ConcreteInt(BasicVals.getValue(V));
return nonloc::ConcreteInt(BasicVals.getValue(V));
}
// Casts.
RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, LVal X, QualType T) {
SVal GRSimpleVals::EvalCast(GRExprEngine& Eng, Loc X, QualType T) {
// Casts from pointers -> pointers, just return the lval.
//
@ -69,43 +69,43 @@ RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, LVal X, QualType T) {
// can be introduced by the frontend for corner cases, e.g
// casting from va_list* to __builtin_va_list&.
//
if (LVal::IsLValType(T) || T->isReferenceType())
if (Loc::IsLocType(T) || T->isReferenceType())
return X;
assert (T->isIntegerType());
if (!isa<lval::ConcreteInt>(X))
if (!isa<loc::ConcreteInt>(X))
return UnknownVal();
BasicValueFactory& BasicVals = Eng.getBasicVals();
llvm::APSInt V = cast<lval::ConcreteInt>(X).getValue();
V.setIsUnsigned(T->isUnsignedIntegerType() || LVal::IsLValType(T));
llvm::APSInt V = cast<loc::ConcreteInt>(X).getValue();
V.setIsUnsigned(T->isUnsignedIntegerType() || Loc::IsLocType(T));
V.extOrTrunc(Eng.getContext().getTypeSize(T));
return nonlval::ConcreteInt(BasicVals.getValue(V));
return nonloc::ConcreteInt(BasicVals.getValue(V));
}
// Unary operators.
RVal GRSimpleVals::EvalMinus(GRExprEngine& Eng, UnaryOperator* U, NonLVal X){
SVal GRSimpleVals::EvalMinus(GRExprEngine& Eng, UnaryOperator* U, NonLoc X){
switch (X.getSubKind()) {
case nonlval::ConcreteIntKind:
return cast<nonlval::ConcreteInt>(X).EvalMinus(Eng.getBasicVals(), U);
case nonloc::ConcreteIntKind:
return cast<nonloc::ConcreteInt>(X).EvalMinus(Eng.getBasicVals(), U);
default:
return UnknownVal();
}
}
RVal GRSimpleVals::EvalComplement(GRExprEngine& Eng, NonLVal X) {
SVal GRSimpleVals::EvalComplement(GRExprEngine& Eng, NonLoc X) {
switch (X.getSubKind()) {
case nonlval::ConcreteIntKind:
return cast<nonlval::ConcreteInt>(X).EvalComplement(Eng.getBasicVals());
case nonloc::ConcreteIntKind:
return cast<nonloc::ConcreteInt>(X).EvalComplement(Eng.getBasicVals());
default:
return UnknownVal();
@ -123,9 +123,9 @@ static unsigned char LNotOpMap[] = {
(unsigned char) BinaryOperator::EQ /* NE => EQ */
};
RVal GRSimpleVals::DetermEvalBinOpNN(GRStateManager& StateMgr,
SVal GRSimpleVals::DetermEvalBinOpNN(GRStateManager& StateMgr,
BinaryOperator::Opcode Op,
NonLVal L, NonLVal R) {
NonLoc L, NonLoc R) {
BasicValueFactory& BasicVals = StateMgr.getBasicVals();
unsigned subkind = L.getSubKind();
@ -136,14 +136,14 @@ RVal GRSimpleVals::DetermEvalBinOpNN(GRStateManager& StateMgr,
default:
return UnknownVal();
case nonlval::SymIntConstraintValKind: {
case nonloc::SymIntConstraintValKind: {
// Logical not?
if (!(Op == BinaryOperator::EQ && R.isZeroConstant()))
return UnknownVal();
const SymIntConstraint& C =
cast<nonlval::SymIntConstraintVal>(L).getConstraint();
cast<nonloc::SymIntConstraintVal>(L).getConstraint();
BinaryOperator::Opcode Opc = C.getOpcode();
@ -163,19 +163,19 @@ RVal GRSimpleVals::DetermEvalBinOpNN(GRStateManager& StateMgr,
const SymIntConstraint& CNew =
BasicVals.getConstraint(C.getSymbol(), Opc, C.getInt());
return nonlval::SymIntConstraintVal(CNew);
return nonloc::SymIntConstraintVal(CNew);
}
case nonlval::ConcreteIntKind:
case nonloc::ConcreteIntKind:
if (isa<nonlval::ConcreteInt>(R)) {
const nonlval::ConcreteInt& L_CI = cast<nonlval::ConcreteInt>(L);
const nonlval::ConcreteInt& R_CI = cast<nonlval::ConcreteInt>(R);
if (isa<nonloc::ConcreteInt>(R)) {
const nonloc::ConcreteInt& L_CI = cast<nonloc::ConcreteInt>(L);
const nonloc::ConcreteInt& R_CI = cast<nonloc::ConcreteInt>(R);
return L_CI.EvalBinOp(BasicVals, Op, R_CI);
}
else {
subkind = R.getSubKind();
NonLVal tmp = R;
NonLoc tmp = R;
R = L;
L = tmp;
@ -191,13 +191,13 @@ RVal GRSimpleVals::DetermEvalBinOpNN(GRStateManager& StateMgr,
continue;
}
case nonlval::SymbolValKind:
if (isa<nonlval::ConcreteInt>(R)) {
case nonloc::SymbolValKind:
if (isa<nonloc::ConcreteInt>(R)) {
const SymIntConstraint& C =
BasicVals.getConstraint(cast<nonlval::SymbolVal>(L).getSymbol(), Op,
cast<nonlval::ConcreteInt>(R).getValue());
BasicVals.getConstraint(cast<nonloc::SymbolVal>(L).getSymbol(), Op,
cast<nonloc::ConcreteInt>(R).getValue());
return nonlval::SymIntConstraintVal(C);
return nonloc::SymIntConstraintVal(C);
}
else
return UnknownVal();
@ -208,8 +208,8 @@ RVal GRSimpleVals::DetermEvalBinOpNN(GRStateManager& StateMgr,
// Binary Operators (except assignments and comma).
RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
LVal L, LVal R) {
SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
Loc L, Loc R) {
switch (Op) {
@ -226,52 +226,52 @@ RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
// Pointer arithmetic.
RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
LVal L, NonLVal R) {
SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
Loc L, NonLoc R) {
return UnknownVal();
}
// Equality operators for LVals.
// Equality operators for Locs.
RVal GRSimpleVals::EvalEQ(GRExprEngine& Eng, LVal L, LVal R) {
SVal GRSimpleVals::EvalEQ(GRExprEngine& Eng, Loc L, Loc R) {
BasicValueFactory& BasicVals = Eng.getBasicVals();
switch (L.getSubKind()) {
default:
assert(false && "EQ not implemented for this LVal.");
assert(false && "EQ not implemented for this Loc.");
return UnknownVal();
case lval::ConcreteIntKind:
case loc::ConcreteIntKind:
if (isa<lval::ConcreteInt>(R)) {
bool b = cast<lval::ConcreteInt>(L).getValue() ==
cast<lval::ConcreteInt>(R).getValue();
if (isa<loc::ConcreteInt>(R)) {
bool b = cast<loc::ConcreteInt>(L).getValue() ==
cast<loc::ConcreteInt>(R).getValue();
return NonLVal::MakeIntTruthVal(BasicVals, b);
return NonLoc::MakeIntTruthVal(BasicVals, b);
}
else if (isa<lval::SymbolVal>(R)) {
else if (isa<loc::SymbolVal>(R)) {
const SymIntConstraint& C =
BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
BasicVals.getConstraint(cast<loc::SymbolVal>(R).getSymbol(),
BinaryOperator::EQ,
cast<lval::ConcreteInt>(L).getValue());
cast<loc::ConcreteInt>(L).getValue());
return nonlval::SymIntConstraintVal(C);
return nonloc::SymIntConstraintVal(C);
}
break;
case lval::SymbolValKind: {
case loc::SymbolValKind: {
if (isa<lval::ConcreteInt>(R)) {
if (isa<loc::ConcreteInt>(R)) {
const SymIntConstraint& C =
BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
BasicVals.getConstraint(cast<loc::SymbolVal>(L).getSymbol(),
BinaryOperator::EQ,
cast<lval::ConcreteInt>(R).getValue());
cast<loc::ConcreteInt>(R).getValue());
return nonlval::SymIntConstraintVal(C);
return nonloc::SymIntConstraintVal(C);
}
// FIXME: Implement == for lval Symbols. This is mainly useful
@ -282,53 +282,53 @@ RVal GRSimpleVals::EvalEQ(GRExprEngine& Eng, LVal L, LVal R) {
return UnknownVal();
}
case lval::MemRegionKind:
case lval::FuncValKind:
case lval::GotoLabelKind:
case lval::StringLiteralValKind:
return NonLVal::MakeIntTruthVal(BasicVals, L == R);
case loc::MemRegionKind:
case loc::FuncValKind:
case loc::GotoLabelKind:
case loc::StringLiteralValKind:
return NonLoc::MakeIntTruthVal(BasicVals, L == R);
}
return NonLVal::MakeIntTruthVal(BasicVals, false);
return NonLoc::MakeIntTruthVal(BasicVals, false);
}
RVal GRSimpleVals::EvalNE(GRExprEngine& Eng, LVal L, LVal R) {
SVal GRSimpleVals::EvalNE(GRExprEngine& Eng, Loc L, Loc R) {
BasicValueFactory& BasicVals = Eng.getBasicVals();
switch (L.getSubKind()) {
default:
assert(false && "NE not implemented for this LVal.");
assert(false && "NE not implemented for this Loc.");
return UnknownVal();
case lval::ConcreteIntKind:
case loc::ConcreteIntKind:
if (isa<lval::ConcreteInt>(R)) {
bool b = cast<lval::ConcreteInt>(L).getValue() !=
cast<lval::ConcreteInt>(R).getValue();
if (isa<loc::ConcreteInt>(R)) {
bool b = cast<loc::ConcreteInt>(L).getValue() !=
cast<loc::ConcreteInt>(R).getValue();
return NonLVal::MakeIntTruthVal(BasicVals, b);
return NonLoc::MakeIntTruthVal(BasicVals, b);
}
else if (isa<lval::SymbolVal>(R)) {
else if (isa<loc::SymbolVal>(R)) {
const SymIntConstraint& C =
BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
BasicVals.getConstraint(cast<loc::SymbolVal>(R).getSymbol(),
BinaryOperator::NE,
cast<lval::ConcreteInt>(L).getValue());
cast<loc::ConcreteInt>(L).getValue());
return nonlval::SymIntConstraintVal(C);
return nonloc::SymIntConstraintVal(C);
}
break;
case lval::SymbolValKind: {
if (isa<lval::ConcreteInt>(R)) {
case loc::SymbolValKind: {
if (isa<loc::ConcreteInt>(R)) {
const SymIntConstraint& C =
BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
BasicVals.getConstraint(cast<loc::SymbolVal>(L).getSymbol(),
BinaryOperator::NE,
cast<lval::ConcreteInt>(R).getValue());
cast<loc::ConcreteInt>(R).getValue());
return nonlval::SymIntConstraintVal(C);
return nonloc::SymIntConstraintVal(C);
}
// FIXME: Implement != for lval Symbols. This is mainly useful
@ -341,14 +341,14 @@ RVal GRSimpleVals::EvalNE(GRExprEngine& Eng, LVal L, LVal R) {
break;
}
case lval::MemRegionKind:
case lval::FuncValKind:
case lval::GotoLabelKind:
case lval::StringLiteralValKind:
return NonLVal::MakeIntTruthVal(BasicVals, L != R);
case loc::MemRegionKind:
case loc::FuncValKind:
case loc::GotoLabelKind:
case loc::StringLiteralValKind:
return NonLoc::MakeIntTruthVal(BasicVals, L != R);
}
return NonLVal::MakeIntTruthVal(BasicVals, true);
return NonLoc::MakeIntTruthVal(BasicVals, true);
}
//===----------------------------------------------------------------------===//
@ -358,23 +358,23 @@ RVal GRSimpleVals::EvalNE(GRExprEngine& Eng, LVal L, LVal R) {
void GRSimpleVals::EvalCall(ExplodedNodeSet<GRState>& Dst,
GRExprEngine& Eng,
GRStmtNodeBuilder<GRState>& Builder,
CallExpr* CE, RVal L,
CallExpr* CE, SVal L,
ExplodedNode<GRState>* Pred) {
GRStateManager& StateMgr = Eng.getStateManager();
const GRState* St = Builder.GetState(Pred);
// Invalidate all arguments passed in by reference (LVals).
// Invalidate all arguments passed in by reference (Locs).
for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
I != E; ++I) {
RVal V = StateMgr.GetRVal(St, *I);
SVal V = StateMgr.GetSVal(St, *I);
if (isa<LVal>(V))
St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
else if (isa<nonlval::LValAsInteger>(V))
St = StateMgr.SetRVal(St, cast<nonlval::LValAsInteger>(V).getLVal(),
if (isa<Loc>(V))
St = StateMgr.SetSVal(St, cast<Loc>(V), UnknownVal());
else if (isa<nonloc::LocAsInteger>(V))
St = StateMgr.SetSVal(St, cast<nonloc::LocAsInteger>(V).getLoc(),
UnknownVal());
}
@ -385,11 +385,11 @@ void GRSimpleVals::EvalCall(ExplodedNodeSet<GRState>& Dst,
unsigned Count = Builder.getCurrentBlockCount();
SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(CE, Count);
RVal X = LVal::IsLValType(CE->getType())
? cast<RVal>(lval::SymbolVal(Sym))
: cast<RVal>(nonlval::SymbolVal(Sym));
SVal X = Loc::IsLocType(CE->getType())
? cast<SVal>(loc::SymbolVal(Sym))
: cast<SVal>(nonloc::SymbolVal(Sym));
St = StateMgr.SetRVal(St, CE, X, Eng.getCFG().isBlkExpr(CE), false);
St = StateMgr.SetSVal(St, CE, X, Eng.getCFG().isBlkExpr(CE), false);
}
Builder.MakeNode(Dst, CE, Pred, St);
@ -415,10 +415,10 @@ void GRSimpleVals::EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end();
I != E; ++I) {
RVal V = StateMgr.GetRVal(St, *I);
SVal V = StateMgr.GetSVal(St, *I);
if (isa<LVal>(V))
St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
if (isa<Loc>(V))
St = StateMgr.SetSVal(St, cast<Loc>(V), UnknownVal());
}
Builder.MakeNode(Dst, ME, Pred, St);

View File

@ -27,9 +27,9 @@ class ASTContext;
class GRSimpleVals : public GRTransferFuncs {
protected:
virtual RVal DetermEvalBinOpNN(GRStateManager& StateMgr,
virtual SVal DetermEvalBinOpNN(GRStateManager& StateMgr,
BinaryOperator::Opcode Op,
NonLVal L, NonLVal R);
NonLoc L, NonLoc R);
public:
GRSimpleVals() {}
@ -37,31 +37,31 @@ public:
// Casts.
virtual RVal EvalCast(GRExprEngine& Engine, NonLVal V, QualType CastT);
virtual RVal EvalCast(GRExprEngine& Engine, LVal V, QualType CastT);
virtual SVal EvalCast(GRExprEngine& Engine, NonLoc V, QualType CastT);
virtual SVal EvalCast(GRExprEngine& Engine, Loc V, QualType CastT);
// Unary Operators.
virtual RVal EvalMinus(GRExprEngine& Engine, UnaryOperator* U, NonLVal X);
virtual SVal EvalMinus(GRExprEngine& Engine, UnaryOperator* U, NonLoc X);
virtual RVal EvalComplement(GRExprEngine& Engine, NonLVal X);
virtual SVal EvalComplement(GRExprEngine& Engine, NonLoc X);
// Binary Operators.
virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
LVal L, LVal R);
virtual SVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
Loc L, Loc R);
// Pointer arithmetic.
virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
LVal L, NonLVal R);
virtual SVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
Loc L, NonLoc R);
// Calls.
virtual void EvalCall(ExplodedNodeSet<GRState>& Dst,
GRExprEngine& Engine,
GRStmtNodeBuilder<GRState>& Builder,
CallExpr* CE, RVal L,
CallExpr* CE, SVal L,
ExplodedNode<GRState>* Pred);
virtual void EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
@ -77,10 +77,10 @@ public:
protected:
// Equality operators for LVals.
// Equality operators for Locs.
RVal EvalEQ(GRExprEngine& Engine, LVal L, LVal R);
RVal EvalNE(GRExprEngine& Engine, LVal L, LVal R);
SVal EvalEQ(GRExprEngine& Engine, Loc L, Loc R);
SVal EvalNE(GRExprEngine& Engine, Loc L, Loc R);
};
} // end clang namespace

View File

@ -59,11 +59,11 @@ GRStateManager::RemoveDeadBindings(const GRState* St, Stmt* Loc,
LSymbols, DSymbols);
}
const GRState* GRStateManager::SetRVal(const GRState* St, LVal LV,
RVal V) {
const GRState* GRStateManager::SetSVal(const GRState* St, Loc LV,
SVal V) {
Store OldStore = St->getStore();
Store NewStore = StoreMgr->SetRVal(OldStore, LV, V);
Store NewStore = StoreMgr->SetSVal(OldStore, LV, V);
if (NewStore == OldStore)
return St;
@ -80,7 +80,7 @@ const GRState* GRStateManager::AddDecl(const GRState* St, const VarDecl* VD,
if (Ex)
NewStore = StoreMgr->AddDecl(OldStore, VD, Ex,
GetRVal(St, Ex), Count);
GetSVal(St, Ex), Count);
else
NewStore = StoreMgr->AddDecl(OldStore, VD, Ex);
@ -92,7 +92,7 @@ const GRState* GRStateManager::AddDecl(const GRState* St, const VarDecl* VD,
return getPersistentState(NewSt);
}
const GRState* GRStateManager::Unbind(const GRState* St, LVal LV) {
const GRState* GRStateManager::Unbind(const GRState* St, Loc LV) {
Store OldStore = St->getStore();
Store NewStore = StoreMgr->Remove(OldStore, LV);
@ -240,18 +240,18 @@ const GRState* GRStateManager::addGDM(const GRState* St, void* Key, void* Data){
bool GRStateManager::isEqual(const GRState* state, Expr* Ex,
const llvm::APSInt& Y) {
RVal V = GetRVal(state, Ex);
SVal V = GetSVal(state, Ex);
if (lval::ConcreteInt* X = dyn_cast<lval::ConcreteInt>(&V))
if (loc::ConcreteInt* X = dyn_cast<loc::ConcreteInt>(&V))
return X->getValue() == Y;
if (nonlval::ConcreteInt* X = dyn_cast<nonlval::ConcreteInt>(&V))
if (nonloc::ConcreteInt* X = dyn_cast<nonloc::ConcreteInt>(&V))
return X->getValue() == Y;
if (nonlval::SymbolVal* X = dyn_cast<nonlval::SymbolVal>(&V))
if (nonloc::SymbolVal* X = dyn_cast<nonloc::SymbolVal>(&V))
return ConstraintMgr->isEqual(state, X->getSymbol(), Y);
if (lval::SymbolVal* X = dyn_cast<lval::SymbolVal>(&V))
if (loc::SymbolVal* X = dyn_cast<loc::SymbolVal>(&V))
return ConstraintMgr->isEqual(state, X->getSymbol(), Y);
return false;

View File

@ -23,7 +23,7 @@ void GRTransferFuncs::EvalStore(ExplodedNodeSet<GRState>& Dst,
GRExprEngine& Eng,
GRStmtNodeBuilder<GRState>& Builder,
Expr* E, ExplodedNode<GRState>* Pred,
const GRState* St, RVal TargetLV, RVal Val) {
const GRState* St, SVal TargetLV, SVal Val) {
// This code basically matches the "safety-net" logic of GRExprEngine:
// bind Val to TargetLV, and create a new node. We replicate it here
@ -35,14 +35,14 @@ void GRTransferFuncs::EvalStore(ExplodedNodeSet<GRState>& Dst,
Builder.MakeNode(Dst, E, Pred, St);
else
Builder.MakeNode(Dst, E, Pred,
Eng.getStateManager().SetRVal(St, cast<LVal>(TargetLV), Val));
Eng.getStateManager().SetSVal(St, cast<Loc>(TargetLV), Val));
}
void GRTransferFuncs::EvalBinOpNN(GRStateSet& OStates,
GRStateManager& StateMgr,
const GRState *St, Expr* Ex,
BinaryOperator::Opcode Op,
NonLVal L, NonLVal R) {
NonLoc L, NonLoc R) {
OStates.Add(StateMgr.SetRVal(St, Ex, DetermEvalBinOpNN(StateMgr, Op, L, R)));
OStates.Add(StateMgr.SetSVal(St, Ex, DetermEvalBinOpNN(StateMgr, Op, L, R)));
}

View File

@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
// This file defines RVal, LVal, and NonLVal, classes that represent
// This file defines SVal, Loc, and NonLoc, classes that represent
// abstract r-values for use with path-sensitive value tracking.
//
//===----------------------------------------------------------------------===//
@ -25,23 +25,23 @@ using llvm::APSInt;
// Symbol Iteration.
//===----------------------------------------------------------------------===//
RVal::symbol_iterator RVal::symbol_begin() const {
SVal::symbol_iterator SVal::symbol_begin() const {
// FIXME: This is a rat's nest. Cleanup.
if (isa<lval::SymbolVal>(this))
if (isa<loc::SymbolVal>(this))
return (symbol_iterator) (&Data);
else if (isa<nonlval::SymbolVal>(this))
else if (isa<nonloc::SymbolVal>(this))
return (symbol_iterator) (&Data);
else if (isa<nonlval::SymIntConstraintVal>(this)) {
else if (isa<nonloc::SymIntConstraintVal>(this)) {
const SymIntConstraint& C =
cast<nonlval::SymIntConstraintVal>(this)->getConstraint();
cast<nonloc::SymIntConstraintVal>(this)->getConstraint();
return (symbol_iterator) &C.getSymbol();
}
else if (isa<nonlval::LValAsInteger>(this)) {
const nonlval::LValAsInteger& V = cast<nonlval::LValAsInteger>(*this);
return V.getPersistentLVal().symbol_begin();
else if (isa<nonloc::LocAsInteger>(this)) {
const nonloc::LocAsInteger& V = cast<nonloc::LocAsInteger>(*this);
return V.getPersistentLoc().symbol_begin();
}
// FIXME: We need to iterate over the symbols of regions.
@ -49,7 +49,7 @@ RVal::symbol_iterator RVal::symbol_begin() const {
return NULL;
}
RVal::symbol_iterator RVal::symbol_end() const {
SVal::symbol_iterator SVal::symbol_end() const {
symbol_iterator X = symbol_begin();
return X ? X+1 : NULL;
}
@ -58,56 +58,56 @@ RVal::symbol_iterator RVal::symbol_end() const {
// Useful predicates.
//===----------------------------------------------------------------------===//
bool RVal::isZeroConstant() const {
if (isa<lval::ConcreteInt>(*this))
return cast<lval::ConcreteInt>(*this).getValue() == 0;
else if (isa<nonlval::ConcreteInt>(*this))
return cast<nonlval::ConcreteInt>(*this).getValue() == 0;
bool SVal::isZeroConstant() const {
if (isa<loc::ConcreteInt>(*this))
return cast<loc::ConcreteInt>(*this).getValue() == 0;
else if (isa<nonloc::ConcreteInt>(*this))
return cast<nonloc::ConcreteInt>(*this).getValue() == 0;
else
return false;
}
//===----------------------------------------------------------------------===//
// Transfer function dispatch for Non-LVals.
// Transfer function dispatch for Non-Locs.
//===----------------------------------------------------------------------===//
RVal nonlval::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals,
SVal nonloc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals,
BinaryOperator::Opcode Op,
const nonlval::ConcreteInt& R) const {
const nonloc::ConcreteInt& R) const {
const llvm::APSInt* X =
BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue());
if (X)
return nonlval::ConcreteInt(*X);
return nonloc::ConcreteInt(*X);
else
return UndefinedVal();
}
// Bitwise-Complement.
nonlval::ConcreteInt
nonlval::ConcreteInt::EvalComplement(BasicValueFactory& BasicVals) const {
nonloc::ConcreteInt
nonloc::ConcreteInt::EvalComplement(BasicValueFactory& BasicVals) const {
return BasicVals.getValue(~getValue());
}
// Unary Minus.
nonlval::ConcreteInt
nonlval::ConcreteInt::EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const {
nonloc::ConcreteInt
nonloc::ConcreteInt::EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const {
assert (U->getType() == U->getSubExpr()->getType());
assert (U->getType()->isIntegerType());
return BasicVals.getValue(-getValue());
}
//===----------------------------------------------------------------------===//
// Transfer function dispatch for LVals.
// Transfer function dispatch for Locs.
//===----------------------------------------------------------------------===//
RVal
lval::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
const lval::ConcreteInt& R) const {
SVal
loc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
const loc::ConcreteInt& R) const {
assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub ||
(Op >= BinaryOperator::LT && Op <= BinaryOperator::NE));
@ -115,180 +115,180 @@ lval::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcod
const llvm::APSInt* X = BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue());
if (X)
return lval::ConcreteInt(*X);
return loc::ConcreteInt(*X);
else
return UndefinedVal();
}
NonLVal LVal::EQ(BasicValueFactory& BasicVals, const LVal& R) const {
NonLoc Loc::EQ(BasicValueFactory& BasicVals, const Loc& R) const {
switch (getSubKind()) {
default:
assert(false && "EQ not implemented for this LVal.");
assert(false && "EQ not implemented for this Loc.");
break;
case lval::ConcreteIntKind:
if (isa<lval::ConcreteInt>(R)) {
bool b = cast<lval::ConcreteInt>(this)->getValue() ==
cast<lval::ConcreteInt>(R).getValue();
case loc::ConcreteIntKind:
if (isa<loc::ConcreteInt>(R)) {
bool b = cast<loc::ConcreteInt>(this)->getValue() ==
cast<loc::ConcreteInt>(R).getValue();
return NonLVal::MakeIntTruthVal(BasicVals, b);
return NonLoc::MakeIntTruthVal(BasicVals, b);
}
else if (isa<lval::SymbolVal>(R)) {
else if (isa<loc::SymbolVal>(R)) {
const SymIntConstraint& C =
BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
BasicVals.getConstraint(cast<loc::SymbolVal>(R).getSymbol(),
BinaryOperator::EQ,
cast<lval::ConcreteInt>(this)->getValue());
cast<loc::ConcreteInt>(this)->getValue());
return nonlval::SymIntConstraintVal(C);
return nonloc::SymIntConstraintVal(C);
}
break;
case lval::SymbolValKind: {
if (isa<lval::ConcreteInt>(R)) {
case loc::SymbolValKind: {
if (isa<loc::ConcreteInt>(R)) {
const SymIntConstraint& C =
BasicVals.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
BasicVals.getConstraint(cast<loc::SymbolVal>(this)->getSymbol(),
BinaryOperator::EQ,
cast<lval::ConcreteInt>(R).getValue());
cast<loc::ConcreteInt>(R).getValue());
return nonlval::SymIntConstraintVal(C);
return nonloc::SymIntConstraintVal(C);
}
assert (!isa<lval::SymbolVal>(R) && "FIXME: Implement unification.");
assert (!isa<loc::SymbolVal>(R) && "FIXME: Implement unification.");
break;
}
case lval::MemRegionKind:
if (isa<lval::MemRegionVal>(R)) {
bool b = cast<lval::MemRegionVal>(*this) == cast<lval::MemRegionVal>(R);
return NonLVal::MakeIntTruthVal(BasicVals, b);
case loc::MemRegionKind:
if (isa<loc::MemRegionVal>(R)) {
bool b = cast<loc::MemRegionVal>(*this) == cast<loc::MemRegionVal>(R);
return NonLoc::MakeIntTruthVal(BasicVals, b);
}
break;
}
return NonLVal::MakeIntTruthVal(BasicVals, false);
return NonLoc::MakeIntTruthVal(BasicVals, false);
}
NonLVal LVal::NE(BasicValueFactory& BasicVals, const LVal& R) const {
NonLoc Loc::NE(BasicValueFactory& BasicVals, const Loc& R) const {
switch (getSubKind()) {
default:
assert(false && "NE not implemented for this LVal.");
assert(false && "NE not implemented for this Loc.");
break;
case lval::ConcreteIntKind:
if (isa<lval::ConcreteInt>(R)) {
bool b = cast<lval::ConcreteInt>(this)->getValue() !=
cast<lval::ConcreteInt>(R).getValue();
case loc::ConcreteIntKind:
if (isa<loc::ConcreteInt>(R)) {
bool b = cast<loc::ConcreteInt>(this)->getValue() !=
cast<loc::ConcreteInt>(R).getValue();
return NonLVal::MakeIntTruthVal(BasicVals, b);
return NonLoc::MakeIntTruthVal(BasicVals, b);
}
else if (isa<lval::SymbolVal>(R)) {
else if (isa<loc::SymbolVal>(R)) {
const SymIntConstraint& C =
BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
BasicVals.getConstraint(cast<loc::SymbolVal>(R).getSymbol(),
BinaryOperator::NE,
cast<lval::ConcreteInt>(this)->getValue());
cast<loc::ConcreteInt>(this)->getValue());
return nonlval::SymIntConstraintVal(C);
return nonloc::SymIntConstraintVal(C);
}
break;
case lval::SymbolValKind: {
if (isa<lval::ConcreteInt>(R)) {
case loc::SymbolValKind: {
if (isa<loc::ConcreteInt>(R)) {
const SymIntConstraint& C =
BasicVals.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
BasicVals.getConstraint(cast<loc::SymbolVal>(this)->getSymbol(),
BinaryOperator::NE,
cast<lval::ConcreteInt>(R).getValue());
cast<loc::ConcreteInt>(R).getValue());
return nonlval::SymIntConstraintVal(C);
return nonloc::SymIntConstraintVal(C);
}
assert (!isa<lval::SymbolVal>(R) && "FIXME: Implement sym !=.");
assert (!isa<loc::SymbolVal>(R) && "FIXME: Implement sym !=.");
break;
}
case lval::MemRegionKind:
if (isa<lval::MemRegionVal>(R)) {
bool b = cast<lval::MemRegionVal>(*this)==cast<lval::MemRegionVal>(R);
return NonLVal::MakeIntTruthVal(BasicVals, b);
case loc::MemRegionKind:
if (isa<loc::MemRegionVal>(R)) {
bool b = cast<loc::MemRegionVal>(*this)==cast<loc::MemRegionVal>(R);
return NonLoc::MakeIntTruthVal(BasicVals, b);
}
break;
}
return NonLVal::MakeIntTruthVal(BasicVals, true);
return NonLoc::MakeIntTruthVal(BasicVals, true);
}
//===----------------------------------------------------------------------===//
// Utility methods for constructing Non-LVals.
// Utility methods for constructing Non-Locs.
//===----------------------------------------------------------------------===//
NonLVal NonLVal::MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T) {
return nonlval::ConcreteInt(BasicVals.getValue(X, T));
NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T) {
return nonloc::ConcreteInt(BasicVals.getValue(X, T));
}
NonLVal NonLVal::MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I) {
NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I) {
return nonlval::ConcreteInt(BasicVals.getValue(APSInt(I->getValue(),
return nonloc::ConcreteInt(BasicVals.getValue(APSInt(I->getValue(),
I->getType()->isUnsignedIntegerType())));
}
NonLVal NonLVal::MakeIntTruthVal(BasicValueFactory& BasicVals, bool b) {
return nonlval::ConcreteInt(BasicVals.getTruthValue(b));
NonLoc NonLoc::MakeIntTruthVal(BasicValueFactory& BasicVals, bool b) {
return nonloc::ConcreteInt(BasicVals.getTruthValue(b));
}
RVal RVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) {
SVal SVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) {
QualType T = D->getType();
if (LVal::IsLValType(T))
return lval::SymbolVal(SymMgr.getSymbol(D));
if (Loc::IsLocType(T))
return loc::SymbolVal(SymMgr.getSymbol(D));
return nonlval::SymbolVal(SymMgr.getSymbol(D));
return nonloc::SymbolVal(SymMgr.getSymbol(D));
}
//===----------------------------------------------------------------------===//
// Utility methods for constructing LVals.
// Utility methods for constructing Locs.
//===----------------------------------------------------------------------===//
LVal LVal::MakeVal(AddrLabelExpr* E) { return lval::GotoLabel(E->getLabel()); }
Loc Loc::MakeVal(AddrLabelExpr* E) { return loc::GotoLabel(E->getLabel()); }
LVal LVal::MakeVal(StringLiteral* S) {
return lval::StringLiteralVal(S);
Loc Loc::MakeVal(StringLiteral* S) {
return loc::StringLiteralVal(S);
}
//===----------------------------------------------------------------------===//
// Pretty-Printing.
//===----------------------------------------------------------------------===//
void RVal::printStdErr() const { print(*llvm::cerr.stream()); }
void SVal::printStdErr() const { print(*llvm::cerr.stream()); }
void RVal::print(std::ostream& Out) const {
void SVal::print(std::ostream& Out) const {
switch (getBaseKind()) {
case UnknownKind:
Out << "Invalid"; break;
case NonLValKind:
cast<NonLVal>(this)->print(Out); break;
case NonLocKind:
cast<NonLoc>(this)->print(Out); break;
case LValKind:
cast<LVal>(this)->print(Out); break;
case LocKind:
cast<Loc>(this)->print(Out); break;
case UndefinedKind:
Out << "Undefined"; break;
default:
assert (false && "Invalid RVal.");
assert (false && "Invalid SVal.");
}
}
@ -316,25 +316,25 @@ static void printOpcode(std::ostream& Out, BinaryOperator::Opcode Op) {
}
}
void NonLVal::print(std::ostream& Out) const {
void NonLoc::print(std::ostream& Out) const {
switch (getSubKind()) {
case nonlval::ConcreteIntKind:
Out << cast<nonlval::ConcreteInt>(this)->getValue().getZExtValue();
case nonloc::ConcreteIntKind:
Out << cast<nonloc::ConcreteInt>(this)->getValue().getZExtValue();
if (cast<nonlval::ConcreteInt>(this)->getValue().isUnsigned())
if (cast<nonloc::ConcreteInt>(this)->getValue().isUnsigned())
Out << 'U';
break;
case nonlval::SymbolValKind:
Out << '$' << cast<nonlval::SymbolVal>(this)->getSymbol();
case nonloc::SymbolValKind:
Out << '$' << cast<nonloc::SymbolVal>(this)->getSymbol();
break;
case nonlval::SymIntConstraintValKind: {
const nonlval::SymIntConstraintVal& C =
*cast<nonlval::SymIntConstraintVal>(this);
case nonloc::SymIntConstraintValKind: {
const nonloc::SymIntConstraintVal& C =
*cast<nonloc::SymIntConstraintVal>(this);
Out << '$' << C.getConstraint().getSymbol() << ' ';
printOpcode(Out, C.getConstraint().getOpcode());
@ -346,54 +346,54 @@ void NonLVal::print(std::ostream& Out) const {
break;
}
case nonlval::LValAsIntegerKind: {
const nonlval::LValAsInteger& C = *cast<nonlval::LValAsInteger>(this);
C.getLVal().print(Out);
case nonloc::LocAsIntegerKind: {
const nonloc::LocAsInteger& C = *cast<nonloc::LocAsInteger>(this);
C.getLoc().print(Out);
Out << " [as " << C.getNumBits() << " bit integer]";
break;
}
default:
assert (false && "Pretty-printed not implemented for this NonLVal.");
assert (false && "Pretty-printed not implemented for this NonLoc.");
break;
}
}
void LVal::print(std::ostream& Out) const {
void Loc::print(std::ostream& Out) const {
switch (getSubKind()) {
case lval::ConcreteIntKind:
Out << cast<lval::ConcreteInt>(this)->getValue().getZExtValue()
<< " (LVal)";
case loc::ConcreteIntKind:
Out << cast<loc::ConcreteInt>(this)->getValue().getZExtValue()
<< " (Loc)";
break;
case lval::SymbolValKind:
Out << '$' << cast<lval::SymbolVal>(this)->getSymbol();
case loc::SymbolValKind:
Out << '$' << cast<loc::SymbolVal>(this)->getSymbol();
break;
case lval::GotoLabelKind:
case loc::GotoLabelKind:
Out << "&&"
<< cast<lval::GotoLabel>(this)->getLabel()->getID()->getName();
<< cast<loc::GotoLabel>(this)->getLabel()->getID()->getName();
break;
case lval::MemRegionKind:
Out << '&' << cast<lval::MemRegionVal>(this)->getRegion()->getString();
case loc::MemRegionKind:
Out << '&' << cast<loc::MemRegionVal>(this)->getRegion()->getString();
break;
case lval::FuncValKind:
case loc::FuncValKind:
Out << "function "
<< cast<lval::FuncVal>(this)->getDecl()->getIdentifier()->getName();
<< cast<loc::FuncVal>(this)->getDecl()->getIdentifier()->getName();
break;
case lval::StringLiteralValKind:
case loc::StringLiteralValKind:
Out << "literal \""
<< cast<lval::StringLiteralVal>(this)->getLiteral()->getStrData()
<< cast<loc::StringLiteralVal>(this)->getLiteral()->getStrData()
<< "\"";
break;
default:
assert (false && "Pretty-printing not implemented for this LVal.");
assert (false && "Pretty-printing not implemented for this Loc.");
break;
}
}

View File

@ -23,7 +23,7 @@
using namespace clang;
typedef llvm::ImmutableMap<const MemRegion*, RVal> RegionBindingsTy;
typedef llvm::ImmutableMap<const MemRegion*, SVal> RegionBindingsTy;
namespace {
@ -38,7 +38,7 @@ public:
virtual ~RegionStoreManager() {}
Store SetRVal(Store St, LVal LV, RVal V);
Store SetSVal(Store St, Loc LV, SVal V);
Store getInitialStore();
@ -49,10 +49,10 @@ public:
} // end anonymous namespace
Store RegionStoreManager::SetRVal(Store store, LVal LV, RVal V) {
assert(LV.getSubKind() == lval::MemRegionKind);
Store RegionStoreManager::SetSVal(Store store, Loc LV, SVal V) {
assert(LV.getSubKind() == loc::MemRegionKind);
MemRegion* R = cast<lval::MemRegionVal>(LV).getRegion();
MemRegion* R = cast<loc::MemRegionVal>(LV).getRegion();
if (!R)
return store;
@ -79,16 +79,16 @@ Store RegionStoreManager::getInitialStore() {
QualType T = VD->getType();
// Only handle pointers and integers for now.
if (LVal::IsLValType(T) || T->isIntegerType()) {
if (Loc::IsLocType(T) || T->isIntegerType()) {
MemRegion* R = MRMgr.getVarRegion(VD);
// Initialize globals and parameters to symbolic values.
// Initialize local variables to undefined.
RVal X = (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
SVal X = (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
isa<ImplicitParamDecl>(VD))
? RVal::GetSymbolValue(StateMgr.getSymbolManager(), VD)
? SVal::GetSymbolValue(StateMgr.getSymbolManager(), VD)
: UndefinedVal();
St = SetRVal(St, lval::MemRegionVal(R), X);
St = SetSVal(St, loc::MemRegionVal(R), X);
}
}
}