forked from OSchip/llvm-project
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:
parent
0dd213f8f5
commit
27f174214d
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue