forked from OSchip/llvm-project
Rename all 'EvalXXX' methods in libChecker to
'evalXXX'. llvm-svn: 120609
This commit is contained in:
parent
87240d4b9c
commit
dc891429e4
|
@ -179,7 +179,7 @@ public:
|
|||
return SValListFactory.add(X, L);
|
||||
}
|
||||
|
||||
const llvm::APSInt* EvaluateAPSInt(BinaryOperator::Opcode Op,
|
||||
const llvm::APSInt* evalAPSInt(BinaryOperator::Opcode Op,
|
||||
const llvm::APSInt& V1,
|
||||
const llvm::APSInt& V2);
|
||||
|
||||
|
|
|
@ -207,20 +207,20 @@ private:
|
|||
_PostVisit(C, S);
|
||||
}
|
||||
|
||||
bool GR_EvalNilReceiver(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
|
||||
bool GR_evalNilReceiver(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
|
||||
GRExprEngine &Eng, const ObjCMessageExpr *ME,
|
||||
ExplodedNode *Pred, const GRState *state, void *tag) {
|
||||
CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
|
||||
0, ME, state);
|
||||
return EvalNilReceiver(C, ME);
|
||||
return evalNilReceiver(C, ME);
|
||||
}
|
||||
|
||||
bool GR_EvalCallExpr(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
|
||||
bool GR_evalCallExpr(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
|
||||
GRExprEngine &Eng, const CallExpr *CE,
|
||||
ExplodedNode *Pred, void *tag) {
|
||||
CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
|
||||
0, CE);
|
||||
return EvalCallExpr(C, CE);
|
||||
return evalCallExpr(C, CE);
|
||||
}
|
||||
|
||||
// FIXME: Remove the 'tag' option.
|
||||
|
@ -250,12 +250,12 @@ private:
|
|||
VisitLocation(C, S, location);
|
||||
}
|
||||
|
||||
void GR_EvalDeadSymbols(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
|
||||
void GR_evalDeadSymbols(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
|
||||
GRExprEngine &Eng, const Stmt *S, ExplodedNode *Pred,
|
||||
SymbolReaper &SymReaper, void *tag) {
|
||||
CheckerContext C(Dst, Builder, Eng, Pred, tag,
|
||||
ProgramPoint::PostPurgeDeadSymbolsKind, 0, S);
|
||||
EvalDeadSymbols(C, SymReaper);
|
||||
evalDeadSymbols(C, SymReaper);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -265,8 +265,8 @@ public:
|
|||
virtual void VisitLocation(CheckerContext &C, const Stmt *S, SVal location) {}
|
||||
virtual void PreVisitBind(CheckerContext &C, const Stmt *StoreE,
|
||||
SVal location, SVal val) {}
|
||||
virtual void EvalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper) {}
|
||||
virtual void EvalEndPath(GREndPathNodeBuilder &B, void *tag,
|
||||
virtual void evalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper) {}
|
||||
virtual void evalEndPath(GREndPathNodeBuilder &B, void *tag,
|
||||
GRExprEngine &Eng) {}
|
||||
|
||||
virtual void MarkLiveSymbols(const GRState *state, SymbolReaper &SymReaper) {}
|
||||
|
@ -275,15 +275,15 @@ public:
|
|||
GRExprEngine &Eng,
|
||||
const Stmt *Condition, void *tag) {}
|
||||
|
||||
virtual bool EvalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME) {
|
||||
virtual bool evalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME) {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
|
||||
virtual bool evalCallExpr(CheckerContext &C, const CallExpr *CE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual const GRState *EvalAssume(const GRState *state, SVal Cond,
|
||||
virtual const GRState *evalAssume(const GRState *state, SVal Cond,
|
||||
bool Assumption, bool *respondsToCallback) {
|
||||
*respondsToCallback = false;
|
||||
return state;
|
||||
|
|
|
@ -224,7 +224,7 @@ public:
|
|||
/// Called by GRCoreEngine when the analysis worklist has terminated.
|
||||
void ProcessEndWorklist(bool hasWorkRemaining);
|
||||
|
||||
/// EvalAssume - Callback function invoked by the ConstraintManager when
|
||||
/// evalAssume - Callback function invoked by the ConstraintManager when
|
||||
/// making assumptions about state values.
|
||||
const GRState *ProcessAssume(const GRState *state, SVal cond,bool assumption);
|
||||
|
||||
|
@ -303,7 +303,7 @@ public:
|
|||
/// other functions that handle specific kinds of statements.
|
||||
void Visit(const Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst);
|
||||
|
||||
/// VisitLValue - Evaluate the lvalue of the expression. For example, if Ex is
|
||||
/// VisitLValue - evaluate the lvalue of the expression. For example, if Ex is
|
||||
/// a DeclRefExpr, it evaluates to the MemRegionVal which represents its
|
||||
/// storage location. Note that not all kinds of expressions has lvalue.
|
||||
void VisitLValue(const Expr* Ex, ExplodedNode* Pred, ExplodedNodeSet& Dst);
|
||||
|
@ -466,61 +466,61 @@ public:
|
|||
const StackFrameContext *frameCtx);
|
||||
|
||||
/// Evaluate arguments with a work list algorithm.
|
||||
void EvalArguments(ConstExprIterator AI, ConstExprIterator AE,
|
||||
void evalArguments(ConstExprIterator AI, ConstExprIterator AE,
|
||||
const FunctionProtoType *FnType,
|
||||
ExplodedNode *Pred, ExplodedNodeSet &Dst,
|
||||
bool FstArgAsLValue = false);
|
||||
|
||||
/// Evaluate method call itself. Used for CXXMethodCallExpr and
|
||||
/// CXXOperatorCallExpr.
|
||||
void EvalMethodCall(const CallExpr *MCE, const CXXMethodDecl *MD,
|
||||
void evalMethodCall(const CallExpr *MCE, const CXXMethodDecl *MD,
|
||||
const Expr *ThisExpr, ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Src, ExplodedNodeSet &Dst);
|
||||
|
||||
/// EvalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic
|
||||
/// evalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic
|
||||
/// expressions of the form 'x != 0' and generate new nodes (stored in Dst)
|
||||
/// with those assumptions.
|
||||
void EvalEagerlyAssume(ExplodedNodeSet& Dst, ExplodedNodeSet& Src,
|
||||
void evalEagerlyAssume(ExplodedNodeSet& Dst, ExplodedNodeSet& Src,
|
||||
const Expr *Ex);
|
||||
|
||||
SVal EvalMinus(SVal X) {
|
||||
return X.isValid() ? svalBuilder.EvalMinus(cast<NonLoc>(X)) : X;
|
||||
SVal evalMinus(SVal X) {
|
||||
return X.isValid() ? svalBuilder.evalMinus(cast<NonLoc>(X)) : X;
|
||||
}
|
||||
|
||||
SVal EvalComplement(SVal X) {
|
||||
return X.isValid() ? svalBuilder.EvalComplement(cast<NonLoc>(X)) : X;
|
||||
SVal evalComplement(SVal X) {
|
||||
return X.isValid() ? svalBuilder.evalComplement(cast<NonLoc>(X)) : X;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op,
|
||||
SVal evalBinOp(const GRState *state, BinaryOperator::Opcode op,
|
||||
NonLoc L, NonLoc R, QualType T) {
|
||||
return svalBuilder.EvalBinOpNN(state, op, L, R, T);
|
||||
return svalBuilder.evalBinOpNN(state, op, L, R, T);
|
||||
}
|
||||
|
||||
SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op,
|
||||
SVal evalBinOp(const GRState *state, BinaryOperator::Opcode op,
|
||||
NonLoc L, SVal R, QualType T) {
|
||||
return R.isValid() ? svalBuilder.EvalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R;
|
||||
return R.isValid() ? svalBuilder.evalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R;
|
||||
}
|
||||
|
||||
SVal EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
|
||||
SVal evalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
|
||||
SVal LHS, SVal RHS, QualType T) {
|
||||
return svalBuilder.EvalBinOp(ST, Op, LHS, RHS, T);
|
||||
return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T);
|
||||
}
|
||||
|
||||
protected:
|
||||
void EvalObjCMessageExpr(ExplodedNodeSet& Dst, const ObjCMessageExpr* ME,
|
||||
void evalObjCMessageExpr(ExplodedNodeSet& Dst, const ObjCMessageExpr* ME,
|
||||
ExplodedNode* Pred, const GRState *state) {
|
||||
assert (Builder && "GRStmtNodeBuilder must be defined.");
|
||||
getTF().EvalObjCMessageExpr(Dst, *this, *Builder, ME, Pred, state);
|
||||
getTF().evalObjCMessageExpr(Dst, *this, *Builder, ME, Pred, state);
|
||||
}
|
||||
|
||||
const GRState* MarkBranch(const GRState* St, const Stmt* Terminator,
|
||||
bool branchTaken);
|
||||
|
||||
/// EvalBind - Handle the semantics of binding a value to a specific location.
|
||||
/// This method is used by EvalStore, VisitDeclStmt, and others.
|
||||
void EvalBind(ExplodedNodeSet& Dst, const Stmt* StoreE, ExplodedNode* Pred,
|
||||
/// evalBind - Handle the semantics of binding a value to a specific location.
|
||||
/// This method is used by evalStore, VisitDeclStmt, and others.
|
||||
void evalBind(ExplodedNodeSet& Dst, const Stmt* StoreE, ExplodedNode* Pred,
|
||||
const GRState* St, SVal location, SVal Val,
|
||||
bool atDeclInit = false);
|
||||
|
||||
|
@ -531,23 +531,23 @@ public:
|
|||
// be the same as Pred->state, and when 'location' may not be the
|
||||
// same as state->getLValue(Ex).
|
||||
/// Simulate a read of the result of Ex.
|
||||
void EvalLoad(ExplodedNodeSet& Dst, const Expr* Ex, ExplodedNode* Pred,
|
||||
void evalLoad(ExplodedNodeSet& Dst, const Expr* Ex, ExplodedNode* Pred,
|
||||
const GRState* St, SVal location, const void *tag = 0,
|
||||
QualType LoadTy = QualType());
|
||||
|
||||
// FIXME: 'tag' should be removed, and a LocationContext should be used
|
||||
// instead.
|
||||
void EvalStore(ExplodedNodeSet& Dst, const Expr* AssignE, const Expr* StoreE,
|
||||
void evalStore(ExplodedNodeSet& Dst, const Expr* AssignE, const Expr* StoreE,
|
||||
ExplodedNode* Pred, const GRState* St, SVal TargetLV, SVal Val,
|
||||
const void *tag = 0);
|
||||
private:
|
||||
void EvalLoadCommon(ExplodedNodeSet& Dst, const Expr* Ex, ExplodedNode* Pred,
|
||||
void evalLoadCommon(ExplodedNodeSet& Dst, const Expr* Ex, ExplodedNode* Pred,
|
||||
const GRState* St, SVal location, const void *tag,
|
||||
QualType LoadTy);
|
||||
|
||||
// FIXME: 'tag' should be removed, and a LocationContext should be used
|
||||
// instead.
|
||||
void EvalLocation(ExplodedNodeSet &Dst, const Stmt *S, ExplodedNode* Pred,
|
||||
void evalLocation(ExplodedNodeSet &Dst, const Stmt *S, ExplodedNode* Pred,
|
||||
const GRState* St, SVal location,
|
||||
const void *tag, bool isLoad);
|
||||
|
||||
|
|
|
@ -39,13 +39,13 @@ public:
|
|||
|
||||
// Calls.
|
||||
|
||||
virtual void EvalCall(ExplodedNodeSet& Dst,
|
||||
virtual void evalCall(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
const CallExpr* CE, SVal L,
|
||||
ExplodedNode* Pred) {}
|
||||
|
||||
virtual void EvalObjCMessageExpr(ExplodedNodeSet& Dst,
|
||||
virtual void evalObjCMessageExpr(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
const ObjCMessageExpr* ME,
|
||||
|
@ -54,15 +54,15 @@ public:
|
|||
|
||||
// Stores.
|
||||
|
||||
virtual void EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) {}
|
||||
virtual void evalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) {}
|
||||
|
||||
// End-of-path and dead symbol notification.
|
||||
|
||||
virtual void EvalEndPath(GRExprEngine& Engine,
|
||||
virtual void evalEndPath(GRExprEngine& Engine,
|
||||
GREndPathNodeBuilder& Builder) {}
|
||||
|
||||
|
||||
virtual void EvalDeadSymbols(ExplodedNodeSet& Dst,
|
||||
virtual void evalDeadSymbols(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
ExplodedNode* Pred,
|
||||
|
@ -70,14 +70,14 @@ public:
|
|||
SymbolReaper& SymReaper) {}
|
||||
|
||||
// Return statements.
|
||||
virtual void EvalReturn(ExplodedNodeSet& Dst,
|
||||
virtual void evalReturn(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
const ReturnStmt* S,
|
||||
ExplodedNode* Pred) {}
|
||||
|
||||
// Assumptions.
|
||||
virtual const GRState* EvalAssume(const GRState *state,
|
||||
virtual const GRState* evalAssume(const GRState *state,
|
||||
SVal Cond, bool Assumption) {
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -31,36 +31,36 @@ protected:
|
|||
public:
|
||||
// FIXME: Make these protected again one RegionStoreManager correctly
|
||||
// handles loads from differening bound value types.
|
||||
virtual SVal EvalCastNL(NonLoc val, QualType castTy) = 0;
|
||||
virtual SVal EvalCastL(Loc val, QualType castTy) = 0;
|
||||
virtual SVal evalCastNL(NonLoc val, QualType castTy) = 0;
|
||||
virtual SVal evalCastL(Loc val, QualType castTy) = 0;
|
||||
|
||||
public:
|
||||
SValBuilder(ValueManager &valMgr) : ValMgr(valMgr) {}
|
||||
virtual ~SValBuilder() {}
|
||||
|
||||
SVal EvalCast(SVal V, QualType castTy, QualType originalType);
|
||||
SVal evalCast(SVal V, QualType castTy, QualType originalType);
|
||||
|
||||
virtual SVal EvalMinus(NonLoc val) = 0;
|
||||
virtual SVal evalMinus(NonLoc val) = 0;
|
||||
|
||||
virtual SVal EvalComplement(NonLoc val) = 0;
|
||||
virtual SVal evalComplement(NonLoc val) = 0;
|
||||
|
||||
virtual SVal EvalBinOpNN(const GRState *state, BinaryOperator::Opcode Op,
|
||||
virtual SVal evalBinOpNN(const GRState *state, BinaryOperator::Opcode Op,
|
||||
NonLoc lhs, NonLoc rhs, QualType resultTy) = 0;
|
||||
|
||||
virtual SVal EvalBinOpLL(const GRState *state, BinaryOperator::Opcode Op,
|
||||
virtual SVal evalBinOpLL(const GRState *state, BinaryOperator::Opcode Op,
|
||||
Loc lhs, Loc rhs, QualType resultTy) = 0;
|
||||
|
||||
virtual SVal EvalBinOpLN(const GRState *state, BinaryOperator::Opcode Op,
|
||||
virtual SVal evalBinOpLN(const GRState *state, BinaryOperator::Opcode Op,
|
||||
Loc lhs, NonLoc rhs, QualType resultTy) = 0;
|
||||
|
||||
/// getKnownValue - Evaluates a given SVal. If the SVal has only one possible
|
||||
/// getKnownValue - evaluates a given SVal. If the SVal has only one possible
|
||||
/// (integer) value, that value is returned. Otherwise, returns NULL.
|
||||
virtual const llvm::APSInt *getKnownValue(const GRState *state, SVal V) = 0;
|
||||
|
||||
SVal EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
|
||||
SVal evalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
|
||||
SVal L, SVal R, QualType T);
|
||||
|
||||
DefinedOrUnknownSVal EvalEQ(const GRState *ST, DefinedOrUnknownSVal L,
|
||||
DefinedOrUnknownSVal evalEQ(const GRState *ST, DefinedOrUnknownSVal L,
|
||||
DefinedOrUnknownSVal R);
|
||||
};
|
||||
|
||||
|
|
|
@ -489,7 +489,7 @@ public:
|
|||
}
|
||||
|
||||
// Transfer functions for binary/unary operations on ConcreteInts.
|
||||
SVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
|
||||
SVal evalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
|
||||
const ConcreteInt& R) const;
|
||||
|
||||
// Implement isa<T> support.
|
||||
|
|
|
@ -152,8 +152,8 @@ public:
|
|||
const MemRegion *CastRegion(const MemRegion *region, QualType CastToTy);
|
||||
|
||||
|
||||
/// EvalBinOp - Perform pointer arithmetic.
|
||||
virtual SVal EvalBinOp(BinaryOperator::Opcode Op,
|
||||
/// evalBinOp - Perform pointer arithmetic.
|
||||
virtual SVal evalBinOp(BinaryOperator::Opcode Op,
|
||||
Loc lhs, NonLoc rhs, QualType resultTy) {
|
||||
return UnknownVal();
|
||||
}
|
||||
|
|
|
@ -458,7 +458,7 @@ public:
|
|||
|
||||
/// isDead - Returns whether or not a symbol has been confirmed dead. This
|
||||
/// should only be called once all marking of dead symbols has completed.
|
||||
/// (For checkers, this means only in the EvalDeadSymbols callback.)
|
||||
/// (For checkers, this means only in the evalDeadSymbols callback.)
|
||||
bool isDead(SymbolRef sym) const {
|
||||
return TheDead.count(sym);
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ void AdjustedReturnValueChecker::PostVisitCallExpr(CheckerContext &C,
|
|||
// FIXME: Do more checking and actual emit an error. At least performing
|
||||
// the cast avoids some assertion failures elsewhere.
|
||||
SValBuilder &svalBuilder = C.getSValBuilder();
|
||||
V = svalBuilder.EvalCast(V, expectedResultTy, actualResultTy);
|
||||
V = svalBuilder.evalCast(V, expectedResultTy, actualResultTy);
|
||||
C.GenerateNode(state->BindExpr(CE, V));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -414,7 +414,7 @@ void CFRetainReleaseChecker::PreVisitCallExpr(CheckerContext& C,
|
|||
|
||||
// Make an expression asserting that they're equal.
|
||||
SValBuilder &svalBuilder = ValMgr.getSValBuilder();
|
||||
DefinedOrUnknownSVal ArgIsNull = svalBuilder.EvalEQ(state, Zero, *DefArgVal);
|
||||
DefinedOrUnknownSVal ArgIsNull = svalBuilder.evalEQ(state, Zero, *DefArgVal);
|
||||
|
||||
// Are they equal?
|
||||
const GRState *stateTrue, *stateFalse;
|
||||
|
|
|
@ -142,7 +142,7 @@ BasicValueFactory::getLazyCompoundValData(const void *store,
|
|||
}
|
||||
|
||||
const llvm::APSInt*
|
||||
BasicValueFactory::EvaluateAPSInt(BinaryOperator::Opcode Op,
|
||||
BasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op,
|
||||
const llvm::APSInt& V1, const llvm::APSInt& V2) {
|
||||
|
||||
switch (Op) {
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace {
|
|||
class BuiltinFunctionChecker : public Checker {
|
||||
public:
|
||||
static void *getTag() { static int tag = 0; return &tag; }
|
||||
virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
|
||||
virtual bool evalCallExpr(CheckerContext &C, const CallExpr *CE);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ void clang::RegisterBuiltinFunctionChecker(GRExprEngine &Eng) {
|
|||
Eng.registerCheck(new BuiltinFunctionChecker());
|
||||
}
|
||||
|
||||
bool BuiltinFunctionChecker::EvalCallExpr(CheckerContext &C,const CallExpr *CE){
|
||||
bool BuiltinFunctionChecker::evalCallExpr(CheckerContext &C,const CallExpr *CE){
|
||||
const GRState *state = C.getState();
|
||||
const Expr *Callee = CE->getCallee();
|
||||
SVal L = state->getSVal(Callee);
|
||||
|
@ -72,7 +72,7 @@ bool BuiltinFunctionChecker::EvalCallExpr(CheckerContext &C,const CallExpr *CE){
|
|||
|
||||
SValBuilder& svalBuilder = ValMgr.getSValBuilder();
|
||||
DefinedOrUnknownSVal ExtentMatchesSizeArg =
|
||||
svalBuilder.EvalEQ(state, Extent, Size);
|
||||
svalBuilder.evalEQ(state, Extent, Size);
|
||||
state = state->Assume(ExtentMatchesSizeArg, true);
|
||||
|
||||
C.GenerateNode(state->BindExpr(CE, loc::MemRegionVal(R)));
|
||||
|
|
|
@ -1710,7 +1710,7 @@ public:
|
|||
|
||||
// Calls.
|
||||
|
||||
void EvalSummary(ExplodedNodeSet& Dst,
|
||||
void evalSummary(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
const Expr* Ex,
|
||||
|
@ -1720,28 +1720,28 @@ public:
|
|||
ConstExprIterator arg_beg, ConstExprIterator arg_end,
|
||||
ExplodedNode* Pred, const GRState *state);
|
||||
|
||||
virtual void EvalCall(ExplodedNodeSet& Dst,
|
||||
virtual void evalCall(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
const CallExpr* CE, SVal L,
|
||||
ExplodedNode* Pred);
|
||||
|
||||
|
||||
virtual void EvalObjCMessageExpr(ExplodedNodeSet& Dst,
|
||||
virtual void evalObjCMessageExpr(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
const ObjCMessageExpr* ME,
|
||||
ExplodedNode* Pred,
|
||||
const GRState *state);
|
||||
// Stores.
|
||||
virtual void EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val);
|
||||
virtual void evalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val);
|
||||
|
||||
// End-of-path.
|
||||
|
||||
virtual void EvalEndPath(GRExprEngine& Engine,
|
||||
virtual void evalEndPath(GRExprEngine& Engine,
|
||||
GREndPathNodeBuilder& Builder);
|
||||
|
||||
virtual void EvalDeadSymbols(ExplodedNodeSet& Dst,
|
||||
virtual void evalDeadSymbols(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
ExplodedNode* Pred,
|
||||
|
@ -1754,7 +1754,7 @@ public:
|
|||
SymbolRef Sym, RefVal V, bool &stop);
|
||||
// Return statements.
|
||||
|
||||
virtual void EvalReturn(ExplodedNodeSet& Dst,
|
||||
virtual void evalReturn(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Engine,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
const ReturnStmt* S,
|
||||
|
@ -1762,7 +1762,7 @@ public:
|
|||
|
||||
// Assumptions.
|
||||
|
||||
virtual const GRState *EvalAssume(const GRState* state, SVal condition,
|
||||
virtual const GRState *evalAssume(const GRState* state, SVal condition,
|
||||
bool assumption);
|
||||
};
|
||||
|
||||
|
@ -2494,7 +2494,7 @@ static QualType GetReturnType(const Expr* RetE, ASTContext& Ctx) {
|
|||
return RetTy;
|
||||
}
|
||||
|
||||
void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
|
||||
void CFRefCount::evalSummary(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
const Expr* Ex,
|
||||
|
@ -2756,7 +2756,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
|
|||
}
|
||||
|
||||
|
||||
void CFRefCount::EvalCall(ExplodedNodeSet& Dst,
|
||||
void CFRefCount::evalCall(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
const CallExpr* CE, SVal L,
|
||||
|
@ -2777,11 +2777,11 @@ void CFRefCount::EvalCall(ExplodedNodeSet& Dst,
|
|||
}
|
||||
|
||||
assert(Summ);
|
||||
EvalSummary(Dst, Eng, Builder, CE, 0, *Summ, L.getAsRegion(),
|
||||
evalSummary(Dst, Eng, Builder, CE, 0, *Summ, L.getAsRegion(),
|
||||
CE->arg_begin(), CE->arg_end(), Pred, Builder.GetState(Pred));
|
||||
}
|
||||
|
||||
void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet& Dst,
|
||||
void CFRefCount::evalObjCMessageExpr(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
const ObjCMessageExpr* ME,
|
||||
|
@ -2793,7 +2793,7 @@ void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet& Dst,
|
|||
: Summaries.getClassMethodSummary(ME);
|
||||
|
||||
assert(Summ && "RetainSummary is null");
|
||||
EvalSummary(Dst, Eng, Builder, ME,
|
||||
evalSummary(Dst, Eng, Builder, ME,
|
||||
InstanceReceiver(ME, Pred->getLocationContext()), *Summ, NULL,
|
||||
ME->arg_begin(), ME->arg_end(), Pred, state);
|
||||
}
|
||||
|
@ -2813,7 +2813,7 @@ public:
|
|||
} // end anonymous namespace
|
||||
|
||||
|
||||
void CFRefCount::EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) {
|
||||
void CFRefCount::evalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) {
|
||||
// Are we storing to something that causes the value to "escape"?
|
||||
bool escapes = false;
|
||||
|
||||
|
@ -2852,7 +2852,7 @@ void CFRefCount::EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) {
|
|||
|
||||
// Return statements.
|
||||
|
||||
void CFRefCount::EvalReturn(ExplodedNodeSet& Dst,
|
||||
void CFRefCount::evalReturn(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
const ReturnStmt* S,
|
||||
|
@ -2994,14 +2994,14 @@ void CFRefCount::EvalReturn(ExplodedNodeSet& Dst,
|
|||
|
||||
// Assumptions.
|
||||
|
||||
const GRState* CFRefCount::EvalAssume(const GRState *state,
|
||||
const GRState* CFRefCount::evalAssume(const GRState *state,
|
||||
SVal Cond, bool Assumption) {
|
||||
|
||||
// FIXME: We may add to the interface of EvalAssume the list of symbols
|
||||
// FIXME: We may add to the interface of evalAssume the list of symbols
|
||||
// whose assumptions have changed. For now we just iterate through the
|
||||
// bindings and check if any of the tracked symbols are NULL. This isn't
|
||||
// too bad since the number of symbols we will track in practice are
|
||||
// probably small and EvalAssume is only called at branches and a few
|
||||
// probably small and evalAssume is only called at branches and a few
|
||||
// other places.
|
||||
RefBindings B = state->get<RefBindings>();
|
||||
|
||||
|
@ -3270,7 +3270,7 @@ CFRefCount::ProcessLeaks(const GRState * state,
|
|||
return N;
|
||||
}
|
||||
|
||||
void CFRefCount::EvalEndPath(GRExprEngine& Eng,
|
||||
void CFRefCount::evalEndPath(GRExprEngine& Eng,
|
||||
GREndPathNodeBuilder& Builder) {
|
||||
|
||||
const GRState *state = Builder.getState();
|
||||
|
@ -3297,7 +3297,7 @@ void CFRefCount::EvalEndPath(GRExprEngine& Eng,
|
|||
ProcessLeaks(state, Leaked, Bd, Eng, Pred);
|
||||
}
|
||||
|
||||
void CFRefCount::EvalDeadSymbols(ExplodedNodeSet& Dst,
|
||||
void CFRefCount::evalDeadSymbols(ExplodedNodeSet& Dst,
|
||||
GRExprEngine& Eng,
|
||||
GRStmtNodeBuilder& Builder,
|
||||
ExplodedNode* Pred,
|
||||
|
|
|
@ -29,10 +29,10 @@ public:
|
|||
{}
|
||||
static void *getTag() { static int tag; return &tag; }
|
||||
|
||||
bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
|
||||
bool evalCallExpr(CheckerContext &C, const CallExpr *CE);
|
||||
void PreVisitDeclStmt(CheckerContext &C, const DeclStmt *DS);
|
||||
void MarkLiveSymbols(const GRState *state, SymbolReaper &SR);
|
||||
void EvalDeadSymbols(CheckerContext &C, SymbolReaper &SR);
|
||||
void evalDeadSymbols(CheckerContext &C, SymbolReaper &SR);
|
||||
bool WantsRegionChangeUpdate(const GRState *state);
|
||||
|
||||
const GRState *EvalRegionChanges(const GRState *state,
|
||||
|
@ -42,20 +42,20 @@ public:
|
|||
|
||||
typedef void (CStringChecker::*FnCheck)(CheckerContext &, const CallExpr *);
|
||||
|
||||
void EvalMemcpy(CheckerContext &C, const CallExpr *CE);
|
||||
void EvalMemmove(CheckerContext &C, const CallExpr *CE);
|
||||
void EvalBcopy(CheckerContext &C, const CallExpr *CE);
|
||||
void EvalCopyCommon(CheckerContext &C, const GRState *state,
|
||||
void evalMemcpy(CheckerContext &C, const CallExpr *CE);
|
||||
void evalMemmove(CheckerContext &C, const CallExpr *CE);
|
||||
void evalBcopy(CheckerContext &C, const CallExpr *CE);
|
||||
void evalCopyCommon(CheckerContext &C, const GRState *state,
|
||||
const Expr *Size, const Expr *Source, const Expr *Dest,
|
||||
bool Restricted = false);
|
||||
|
||||
void EvalMemcmp(CheckerContext &C, const CallExpr *CE);
|
||||
void evalMemcmp(CheckerContext &C, const CallExpr *CE);
|
||||
|
||||
void EvalStrlen(CheckerContext &C, const CallExpr *CE);
|
||||
void evalStrlen(CheckerContext &C, const CallExpr *CE);
|
||||
|
||||
void EvalStrcpy(CheckerContext &C, const CallExpr *CE);
|
||||
void EvalStpcpy(CheckerContext &C, const CallExpr *CE);
|
||||
void EvalStrcpyCommon(CheckerContext &C, const CallExpr *CE, bool ReturnEnd);
|
||||
void evalStrcpy(CheckerContext &C, const CallExpr *CE);
|
||||
void evalStpcpy(CheckerContext &C, const CallExpr *CE);
|
||||
void evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, bool ReturnEnd);
|
||||
|
||||
// Utility methods
|
||||
std::pair<const GRState*, const GRState*>
|
||||
|
@ -125,7 +125,7 @@ CStringChecker::AssumeZero(CheckerContext &C, const GRState *state, SVal V,
|
|||
SValBuilder &SV = ValMgr.getSValBuilder();
|
||||
|
||||
DefinedOrUnknownSVal Zero = ValMgr.makeZeroVal(Ty);
|
||||
DefinedOrUnknownSVal ValIsZero = SV.EvalEQ(state, *Val, Zero);
|
||||
DefinedOrUnknownSVal ValIsZero = SV.evalEQ(state, *Val, Zero);
|
||||
|
||||
return state->Assume(ValIsZero);
|
||||
}
|
||||
|
@ -265,13 +265,13 @@ const GRState *CStringChecker::CheckBufferAccess(CheckerContext &C,
|
|||
|
||||
// Compute the offset of the last element to be accessed: size-1.
|
||||
NonLoc One = cast<NonLoc>(VM.makeIntVal(1, SizeTy));
|
||||
NonLoc LastOffset = cast<NonLoc>(SV.EvalBinOpNN(state, BO_Sub,
|
||||
NonLoc LastOffset = cast<NonLoc>(SV.evalBinOpNN(state, BO_Sub,
|
||||
*Length, One, SizeTy));
|
||||
|
||||
// Check that the first buffer is sufficently long.
|
||||
SVal BufStart = SV.EvalCast(BufVal, PtrTy, FirstBuf->getType());
|
||||
SVal BufStart = SV.evalCast(BufVal, PtrTy, FirstBuf->getType());
|
||||
if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
|
||||
SVal BufEnd = SV.EvalBinOpLN(state, BO_Add, *BufLoc,
|
||||
SVal BufEnd = SV.evalBinOpLN(state, BO_Add, *BufLoc,
|
||||
LastOffset, PtrTy);
|
||||
state = CheckLocation(C, state, FirstBuf, BufEnd, FirstIsDestination);
|
||||
|
||||
|
@ -287,9 +287,9 @@ const GRState *CStringChecker::CheckBufferAccess(CheckerContext &C,
|
|||
if (!state)
|
||||
return NULL;
|
||||
|
||||
BufStart = SV.EvalCast(BufVal, PtrTy, SecondBuf->getType());
|
||||
BufStart = SV.evalCast(BufVal, PtrTy, SecondBuf->getType());
|
||||
if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
|
||||
SVal BufEnd = SV.EvalBinOpLN(state, BO_Add, *BufLoc,
|
||||
SVal BufEnd = SV.evalBinOpLN(state, BO_Add, *BufLoc,
|
||||
LastOffset, PtrTy);
|
||||
state = CheckLocation(C, state, SecondBuf, BufEnd);
|
||||
}
|
||||
|
@ -330,7 +330,7 @@ const GRState *CStringChecker::CheckOverlap(CheckerContext &C,
|
|||
return state;
|
||||
|
||||
// Are the two values the same?
|
||||
DefinedOrUnknownSVal EqualTest = SV.EvalEQ(state, *FirstLoc, *SecondLoc);
|
||||
DefinedOrUnknownSVal EqualTest = SV.evalEQ(state, *FirstLoc, *SecondLoc);
|
||||
llvm::tie(stateTrue, stateFalse) = state->Assume(EqualTest);
|
||||
|
||||
if (stateTrue && !stateFalse) {
|
||||
|
@ -345,7 +345,7 @@ const GRState *CStringChecker::CheckOverlap(CheckerContext &C,
|
|||
|
||||
// Which value comes first?
|
||||
QualType CmpTy = Ctx.IntTy;
|
||||
SVal Reverse = SV.EvalBinOpLL(state, BO_GT,
|
||||
SVal Reverse = SV.evalBinOpLL(state, BO_GT,
|
||||
*FirstLoc, *SecondLoc, CmpTy);
|
||||
DefinedOrUnknownSVal *ReverseTest = dyn_cast<DefinedOrUnknownSVal>(&Reverse);
|
||||
if (!ReverseTest)
|
||||
|
@ -379,20 +379,20 @@ const GRState *CStringChecker::CheckOverlap(CheckerContext &C,
|
|||
// Convert the first buffer's start address to char*.
|
||||
// Bail out if the cast fails.
|
||||
QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
|
||||
SVal FirstStart = SV.EvalCast(*FirstLoc, CharPtrTy, First->getType());
|
||||
SVal FirstStart = SV.evalCast(*FirstLoc, CharPtrTy, First->getType());
|
||||
Loc *FirstStartLoc = dyn_cast<Loc>(&FirstStart);
|
||||
if (!FirstStartLoc)
|
||||
return state;
|
||||
|
||||
// Compute the end of the first buffer. Bail out if THAT fails.
|
||||
SVal FirstEnd = SV.EvalBinOpLN(state, BO_Add,
|
||||
SVal FirstEnd = SV.evalBinOpLN(state, BO_Add,
|
||||
*FirstStartLoc, *Length, CharPtrTy);
|
||||
Loc *FirstEndLoc = dyn_cast<Loc>(&FirstEnd);
|
||||
if (!FirstEndLoc)
|
||||
return state;
|
||||
|
||||
// Is the end of the first buffer past the start of the second buffer?
|
||||
SVal Overlap = SV.EvalBinOpLL(state, BO_GT,
|
||||
SVal Overlap = SV.evalBinOpLL(state, BO_GT,
|
||||
*FirstEndLoc, *SecondLoc, CmpTy);
|
||||
DefinedOrUnknownSVal *OverlapTest = dyn_cast<DefinedOrUnknownSVal>(&Overlap);
|
||||
if (!OverlapTest)
|
||||
|
@ -647,10 +647,10 @@ bool CStringChecker::SummarizeRegion(llvm::raw_ostream& os, ASTContext& Ctx,
|
|||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Evaluation of individual function calls.
|
||||
// evaluation of individual function calls.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void CStringChecker::EvalCopyCommon(CheckerContext &C, const GRState *state,
|
||||
void CStringChecker::evalCopyCommon(CheckerContext &C, const GRState *state,
|
||||
const Expr *Size, const Expr *Dest,
|
||||
const Expr *Source, bool Restricted) {
|
||||
// See if the size argument is zero.
|
||||
|
@ -685,30 +685,30 @@ void CStringChecker::EvalCopyCommon(CheckerContext &C, const GRState *state,
|
|||
}
|
||||
|
||||
|
||||
void CStringChecker::EvalMemcpy(CheckerContext &C, const CallExpr *CE) {
|
||||
void CStringChecker::evalMemcpy(CheckerContext &C, const CallExpr *CE) {
|
||||
// void *memcpy(void *restrict dst, const void *restrict src, size_t n);
|
||||
// The return value is the address of the destination buffer.
|
||||
const Expr *Dest = CE->getArg(0);
|
||||
const GRState *state = C.getState();
|
||||
state = state->BindExpr(CE, state->getSVal(Dest));
|
||||
EvalCopyCommon(C, state, CE->getArg(2), Dest, CE->getArg(1), true);
|
||||
evalCopyCommon(C, state, CE->getArg(2), Dest, CE->getArg(1), true);
|
||||
}
|
||||
|
||||
void CStringChecker::EvalMemmove(CheckerContext &C, const CallExpr *CE) {
|
||||
void CStringChecker::evalMemmove(CheckerContext &C, const CallExpr *CE) {
|
||||
// void *memmove(void *dst, const void *src, size_t n);
|
||||
// The return value is the address of the destination buffer.
|
||||
const Expr *Dest = CE->getArg(0);
|
||||
const GRState *state = C.getState();
|
||||
state = state->BindExpr(CE, state->getSVal(Dest));
|
||||
EvalCopyCommon(C, state, CE->getArg(2), Dest, CE->getArg(1));
|
||||
evalCopyCommon(C, state, CE->getArg(2), Dest, CE->getArg(1));
|
||||
}
|
||||
|
||||
void CStringChecker::EvalBcopy(CheckerContext &C, const CallExpr *CE) {
|
||||
void CStringChecker::evalBcopy(CheckerContext &C, const CallExpr *CE) {
|
||||
// void bcopy(const void *src, void *dst, size_t n);
|
||||
EvalCopyCommon(C, C.getState(), CE->getArg(2), CE->getArg(1), CE->getArg(0));
|
||||
evalCopyCommon(C, C.getState(), CE->getArg(2), CE->getArg(1), CE->getArg(0));
|
||||
}
|
||||
|
||||
void CStringChecker::EvalMemcmp(CheckerContext &C, const CallExpr *CE) {
|
||||
void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) {
|
||||
// int memcmp(const void *s1, const void *s2, size_t n);
|
||||
const Expr *Left = CE->getArg(0);
|
||||
const Expr *Right = CE->getArg(1);
|
||||
|
@ -744,7 +744,7 @@ void CStringChecker::EvalMemcmp(CheckerContext &C, const CallExpr *CE) {
|
|||
DefinedOrUnknownSVal RV = cast<DefinedOrUnknownSVal>(state->getSVal(Right));
|
||||
|
||||
// See if they are the same.
|
||||
DefinedOrUnknownSVal SameBuf = SV.EvalEQ(state, LV, RV);
|
||||
DefinedOrUnknownSVal SameBuf = SV.evalEQ(state, LV, RV);
|
||||
const GRState *StSameBuf, *StNotSameBuf;
|
||||
llvm::tie(StSameBuf, StNotSameBuf) = state->Assume(SameBuf);
|
||||
|
||||
|
@ -775,7 +775,7 @@ void CStringChecker::EvalMemcmp(CheckerContext &C, const CallExpr *CE) {
|
|||
}
|
||||
}
|
||||
|
||||
void CStringChecker::EvalStrlen(CheckerContext &C, const CallExpr *CE) {
|
||||
void CStringChecker::evalStrlen(CheckerContext &C, const CallExpr *CE) {
|
||||
// size_t strlen(const char *s);
|
||||
const GRState *state = C.getState();
|
||||
const Expr *Arg = CE->getArg(0);
|
||||
|
@ -806,17 +806,17 @@ void CStringChecker::EvalStrlen(CheckerContext &C, const CallExpr *CE) {
|
|||
}
|
||||
}
|
||||
|
||||
void CStringChecker::EvalStrcpy(CheckerContext &C, const CallExpr *CE) {
|
||||
void CStringChecker::evalStrcpy(CheckerContext &C, const CallExpr *CE) {
|
||||
// char *strcpy(char *restrict dst, const char *restrict src);
|
||||
EvalStrcpyCommon(C, CE, /* ReturnEnd = */ false);
|
||||
evalStrcpyCommon(C, CE, /* ReturnEnd = */ false);
|
||||
}
|
||||
|
||||
void CStringChecker::EvalStpcpy(CheckerContext &C, const CallExpr *CE) {
|
||||
void CStringChecker::evalStpcpy(CheckerContext &C, const CallExpr *CE) {
|
||||
// char *stpcpy(char *restrict dst, const char *restrict src);
|
||||
EvalStrcpyCommon(C, CE, /* ReturnEnd = */ true);
|
||||
evalStrcpyCommon(C, CE, /* ReturnEnd = */ true);
|
||||
}
|
||||
|
||||
void CStringChecker::EvalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
|
||||
void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
|
||||
bool ReturnEnd) {
|
||||
const GRState *state = C.getState();
|
||||
|
||||
|
@ -852,7 +852,7 @@ void CStringChecker::EvalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
|
|||
if (NonLoc *KnownStrLen = dyn_cast<NonLoc>(&StrLen)) {
|
||||
SValBuilder &SV = C.getSValBuilder();
|
||||
|
||||
SVal LastElement = SV.EvalBinOpLN(state, BO_Add,
|
||||
SVal LastElement = SV.evalBinOpLN(state, BO_Add,
|
||||
*DstRegVal, *KnownStrLen,
|
||||
Dst->getType());
|
||||
|
||||
|
@ -894,7 +894,7 @@ void CStringChecker::EvalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
|
|||
// The driver method, and other Checker callbacks.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool CStringChecker::EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
|
||||
bool CStringChecker::evalCallExpr(CheckerContext &C, const CallExpr *CE) {
|
||||
// Get the callee. All the functions we care about are C functions
|
||||
// with simple identifiers.
|
||||
const GRState *state = C.getState();
|
||||
|
@ -912,22 +912,22 @@ bool CStringChecker::EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
|
|||
if (Name.startswith("__builtin_"))
|
||||
Name = Name.substr(10);
|
||||
|
||||
FnCheck EvalFunction = llvm::StringSwitch<FnCheck>(Name)
|
||||
.Cases("memcpy", "__memcpy_chk", &CStringChecker::EvalMemcpy)
|
||||
.Cases("memcmp", "bcmp", &CStringChecker::EvalMemcmp)
|
||||
.Cases("memmove", "__memmove_chk", &CStringChecker::EvalMemmove)
|
||||
.Cases("strcpy", "__strcpy_chk", &CStringChecker::EvalStrcpy)
|
||||
.Cases("stpcpy", "__stpcpy_chk", &CStringChecker::EvalStpcpy)
|
||||
.Case("strlen", &CStringChecker::EvalStrlen)
|
||||
.Case("bcopy", &CStringChecker::EvalBcopy)
|
||||
FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name)
|
||||
.Cases("memcpy", "__memcpy_chk", &CStringChecker::evalMemcpy)
|
||||
.Cases("memcmp", "bcmp", &CStringChecker::evalMemcmp)
|
||||
.Cases("memmove", "__memmove_chk", &CStringChecker::evalMemmove)
|
||||
.Cases("strcpy", "__strcpy_chk", &CStringChecker::evalStrcpy)
|
||||
.Cases("stpcpy", "__stpcpy_chk", &CStringChecker::evalStpcpy)
|
||||
.Case("strlen", &CStringChecker::evalStrlen)
|
||||
.Case("bcopy", &CStringChecker::evalBcopy)
|
||||
.Default(NULL);
|
||||
|
||||
// If the callee isn't a string function, let another checker handle it.
|
||||
if (!EvalFunction)
|
||||
if (!evalFunction)
|
||||
return false;
|
||||
|
||||
// Check and evaluate the call.
|
||||
(this->*EvalFunction)(C, CE);
|
||||
(this->*evalFunction)(C, CE);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1034,7 +1034,7 @@ void CStringChecker::MarkLiveSymbols(const GRState *state, SymbolReaper &SR) {
|
|||
}
|
||||
}
|
||||
|
||||
void CStringChecker::EvalDeadSymbols(CheckerContext &C, SymbolReaper &SR) {
|
||||
void CStringChecker::evalDeadSymbols(CheckerContext &C, SymbolReaper &SR) {
|
||||
if (!SR.hasDeadSymbols())
|
||||
return;
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
|
||||
void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE);
|
||||
void PreVisitObjCMessageExpr(CheckerContext &C, const ObjCMessageExpr *ME);
|
||||
bool EvalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME);
|
||||
bool evalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME);
|
||||
|
||||
private:
|
||||
bool PreVisitProcessArg(CheckerContext &C, const Expr *Ex,
|
||||
|
@ -244,7 +244,7 @@ void CallAndMessageChecker::PreVisitObjCMessageExpr(CheckerContext &C,
|
|||
return;
|
||||
}
|
||||
|
||||
bool CallAndMessageChecker::EvalNilReceiver(CheckerContext &C,
|
||||
bool CallAndMessageChecker::evalNilReceiver(CheckerContext &C,
|
||||
const ObjCMessageExpr *ME) {
|
||||
HandleNilReceiver(C, C.getState(), ME);
|
||||
return true; // Nil receiver is not handled elsewhere.
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
return &x;
|
||||
}
|
||||
|
||||
virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
|
||||
virtual bool evalCallExpr(CheckerContext &C, const CallExpr *CE);
|
||||
virtual void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE);
|
||||
|
||||
private:
|
||||
|
@ -62,7 +62,7 @@ void clang::RegisterChrootChecker(GRExprEngine &Eng) {
|
|||
Eng.registerCheck(new ChrootChecker());
|
||||
}
|
||||
|
||||
bool ChrootChecker::EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
|
||||
bool ChrootChecker::evalCallExpr(CheckerContext &C, const CallExpr *CE) {
|
||||
const GRState *state = C.getState();
|
||||
const Expr *Callee = CE->getCallee();
|
||||
SVal L = state->getSVal(Callee);
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
};
|
||||
}
|
||||
|
||||
void GRExprEngine::EvalArguments(ConstExprIterator AI, ConstExprIterator AE,
|
||||
void GRExprEngine::evalArguments(ConstExprIterator AI, ConstExprIterator AE,
|
||||
const FunctionProtoType *FnType,
|
||||
ExplodedNode *Pred, ExplodedNodeSet &Dst,
|
||||
bool FstArgAsLValue) {
|
||||
|
@ -125,9 +125,9 @@ void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E,
|
|||
|
||||
|
||||
// Evaluate other arguments.
|
||||
ExplodedNodeSet ArgsEvaluated;
|
||||
ExplodedNodeSet argsEvaluated;
|
||||
const FunctionProtoType *FnType = CD->getType()->getAs<FunctionProtoType>();
|
||||
EvalArguments(E->arg_begin(), E->arg_end(), FnType, Pred, ArgsEvaluated);
|
||||
evalArguments(E->arg_begin(), E->arg_end(), FnType, Pred, argsEvaluated);
|
||||
// The callee stack frame context used to create the 'this' parameter region.
|
||||
const StackFrameContext *SFC = AMgr.getStackFrame(CD,
|
||||
Pred->getLocationContext(),
|
||||
|
@ -137,8 +137,8 @@ void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E,
|
|||
SFC);
|
||||
|
||||
CallEnter Loc(E, SFC, Pred->getLocationContext());
|
||||
for (ExplodedNodeSet::iterator NI = ArgsEvaluated.begin(),
|
||||
NE = ArgsEvaluated.end(); NI != NE; ++NI) {
|
||||
for (ExplodedNodeSet::iterator NI = argsEvaluated.begin(),
|
||||
NE = argsEvaluated.end(); NI != NE; ++NI) {
|
||||
const GRState *state = GetState(*NI);
|
||||
// Setup 'this' region, so that the ctor is evaluated on the object pointed
|
||||
// by 'Dest'.
|
||||
|
@ -182,27 +182,27 @@ void GRExprEngine::VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE,
|
|||
assert(FnType && "Method type not available");
|
||||
|
||||
// Evaluate explicit arguments with a worklist.
|
||||
ExplodedNodeSet ArgsEvaluated;
|
||||
EvalArguments(MCE->arg_begin(), MCE->arg_end(), FnType, Pred, ArgsEvaluated);
|
||||
ExplodedNodeSet argsEvaluated;
|
||||
evalArguments(MCE->arg_begin(), MCE->arg_end(), FnType, Pred, argsEvaluated);
|
||||
|
||||
// Evaluate the implicit object argument.
|
||||
ExplodedNodeSet AllArgsEvaluated;
|
||||
ExplodedNodeSet AllargsEvaluated;
|
||||
const MemberExpr *ME = dyn_cast<MemberExpr>(MCE->getCallee()->IgnoreParens());
|
||||
if (!ME)
|
||||
return;
|
||||
Expr *ObjArgExpr = ME->getBase();
|
||||
for (ExplodedNodeSet::iterator I = ArgsEvaluated.begin(),
|
||||
E = ArgsEvaluated.end(); I != E; ++I) {
|
||||
for (ExplodedNodeSet::iterator I = argsEvaluated.begin(),
|
||||
E = argsEvaluated.end(); I != E; ++I) {
|
||||
if (ME->isArrow())
|
||||
Visit(ObjArgExpr, *I, AllArgsEvaluated);
|
||||
Visit(ObjArgExpr, *I, AllargsEvaluated);
|
||||
else
|
||||
VisitLValue(ObjArgExpr, *I, AllArgsEvaluated);
|
||||
VisitLValue(ObjArgExpr, *I, AllargsEvaluated);
|
||||
}
|
||||
|
||||
// Now evaluate the call itself.
|
||||
const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
|
||||
assert(MD && "not a CXXMethodDecl?");
|
||||
EvalMethodCall(MCE, MD, ObjArgExpr, Pred, AllArgsEvaluated, Dst);
|
||||
evalMethodCall(MCE, MD, ObjArgExpr, Pred, AllargsEvaluated, Dst);
|
||||
}
|
||||
|
||||
void GRExprEngine::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *C,
|
||||
|
@ -223,14 +223,14 @@ void GRExprEngine::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *C,
|
|||
|
||||
// Evaluate arguments treating the first one (object method is called on)
|
||||
// as alvalue.
|
||||
ExplodedNodeSet ArgsEvaluated;
|
||||
EvalArguments(C->arg_begin(), C->arg_end(), Proto, Pred, ArgsEvaluated, true);
|
||||
ExplodedNodeSet argsEvaluated;
|
||||
evalArguments(C->arg_begin(), C->arg_end(), Proto, Pred, argsEvaluated, true);
|
||||
|
||||
// Now evaluate the call itself.
|
||||
EvalMethodCall(C, MD, C->getArg(0), Pred, ArgsEvaluated, Dst);
|
||||
evalMethodCall(C, MD, C->getArg(0), Pred, argsEvaluated, Dst);
|
||||
}
|
||||
|
||||
void GRExprEngine::EvalMethodCall(const CallExpr *MCE, const CXXMethodDecl *MD,
|
||||
void GRExprEngine::evalMethodCall(const CallExpr *MCE, const CXXMethodDecl *MD,
|
||||
const Expr *ThisExpr, ExplodedNode *Pred,
|
||||
ExplodedNodeSet &Src, ExplodedNodeSet &Dst) {
|
||||
// Allow checkers to pre-visit the member call.
|
||||
|
@ -281,13 +281,13 @@ void GRExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
|
|||
const CXXConstructorDecl *CD = CNE->getConstructor();
|
||||
if (CD)
|
||||
FnType = CD->getType()->getAs<FunctionProtoType>();
|
||||
ExplodedNodeSet ArgsEvaluated;
|
||||
EvalArguments(CNE->constructor_arg_begin(), CNE->constructor_arg_end(),
|
||||
FnType, Pred, ArgsEvaluated);
|
||||
ExplodedNodeSet argsEvaluated;
|
||||
evalArguments(CNE->constructor_arg_begin(), CNE->constructor_arg_end(),
|
||||
FnType, Pred, argsEvaluated);
|
||||
|
||||
// Initialize the object region and bind the 'new' expression.
|
||||
for (ExplodedNodeSet::iterator I = ArgsEvaluated.begin(),
|
||||
E = ArgsEvaluated.end(); I != E; ++I) {
|
||||
for (ExplodedNodeSet::iterator I = argsEvaluated.begin(),
|
||||
E = argsEvaluated.end(); I != E; ++I) {
|
||||
const GRState *state = GetState(*I);
|
||||
|
||||
if (ObjTy->isRecordType()) {
|
||||
|
@ -310,10 +310,10 @@ void GRExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
|
|||
void GRExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
|
||||
ExplodedNode *Pred,ExplodedNodeSet &Dst) {
|
||||
// Should do more checking.
|
||||
ExplodedNodeSet ArgEvaluated;
|
||||
Visit(CDE->getArgument(), Pred, ArgEvaluated);
|
||||
for (ExplodedNodeSet::iterator I = ArgEvaluated.begin(),
|
||||
E = ArgEvaluated.end(); I != E; ++I) {
|
||||
ExplodedNodeSet Argevaluated;
|
||||
Visit(CDE->getArgument(), Pred, Argevaluated);
|
||||
for (ExplodedNodeSet::iterator I = Argevaluated.begin(),
|
||||
E = Argevaluated.end(); I != E; ++I) {
|
||||
const GRState *state = GetState(*I);
|
||||
MakeNode(Dst, CDE, *I, state);
|
||||
}
|
||||
|
|
|
@ -186,23 +186,23 @@ void GRExprEngine::CheckerEvalNilReceiver(const ObjCMessageExpr *ME,
|
|||
ExplodedNodeSet &Dst,
|
||||
const GRState *state,
|
||||
ExplodedNode *Pred) {
|
||||
bool Evaluated = false;
|
||||
bool evaluated = false;
|
||||
ExplodedNodeSet DstTmp;
|
||||
|
||||
for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end();I!=E;++I) {
|
||||
void *tag = I->first;
|
||||
Checker *checker = I->second;
|
||||
|
||||
if (checker->GR_EvalNilReceiver(DstTmp, *Builder, *this, ME, Pred, state,
|
||||
if (checker->GR_evalNilReceiver(DstTmp, *Builder, *this, ME, Pred, state,
|
||||
tag)) {
|
||||
Evaluated = true;
|
||||
evaluated = true;
|
||||
break;
|
||||
} else
|
||||
// The checker didn't evaluate the expr. Restore the Dst.
|
||||
DstTmp.clear();
|
||||
}
|
||||
|
||||
if (Evaluated)
|
||||
if (evaluated)
|
||||
Dst.insert(DstTmp);
|
||||
else
|
||||
Dst.insert(Pred);
|
||||
|
@ -214,27 +214,27 @@ void GRExprEngine::CheckerEvalNilReceiver(const ObjCMessageExpr *ME,
|
|||
bool GRExprEngine::CheckerEvalCall(const CallExpr *CE,
|
||||
ExplodedNodeSet &Dst,
|
||||
ExplodedNode *Pred) {
|
||||
bool Evaluated = false;
|
||||
bool evaluated = false;
|
||||
ExplodedNodeSet DstTmp;
|
||||
|
||||
for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end();I!=E;++I) {
|
||||
void *tag = I->first;
|
||||
Checker *checker = I->second;
|
||||
|
||||
if (checker->GR_EvalCallExpr(DstTmp, *Builder, *this, CE, Pred, tag)) {
|
||||
Evaluated = true;
|
||||
if (checker->GR_evalCallExpr(DstTmp, *Builder, *this, CE, Pred, tag)) {
|
||||
evaluated = true;
|
||||
break;
|
||||
} else
|
||||
// The checker didn't evaluate the expr. Restore the DstTmp set.
|
||||
DstTmp.clear();
|
||||
}
|
||||
|
||||
if (Evaluated)
|
||||
if (evaluated)
|
||||
Dst.insert(DstTmp);
|
||||
else
|
||||
Dst.insert(Pred);
|
||||
|
||||
return Evaluated;
|
||||
return evaluated;
|
||||
}
|
||||
|
||||
// FIXME: This is largely copy-paste from CheckerVisit(). Need to
|
||||
|
@ -382,7 +382,7 @@ const GRState* GRExprEngine::getInitialState(const LocationContext *InitLoc) {
|
|||
break;
|
||||
|
||||
SVal V = state->getSVal(loc::MemRegionVal(R));
|
||||
SVal Constraint_untested = EvalBinOp(state, BO_GT, V,
|
||||
SVal Constraint_untested = evalBinOp(state, BO_GT, V,
|
||||
ValMgr.makeZeroVal(T),
|
||||
getContext().IntTy);
|
||||
|
||||
|
@ -420,7 +420,7 @@ const GRState* GRExprEngine::getInitialState(const LocationContext *InitLoc) {
|
|||
// Top-level transfer function logic (Dispatcher).
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// EvalAssume - Called by ConstraintManager. Used to call checker-specific
|
||||
/// evalAssume - Called by ConstraintManager. Used to call checker-specific
|
||||
/// logic for handling assumptions on symbolic values.
|
||||
const GRState *GRExprEngine::ProcessAssume(const GRState *state, SVal cond,
|
||||
bool assumption) {
|
||||
|
@ -456,7 +456,7 @@ const GRState *GRExprEngine::ProcessAssume(const GRState *state, SVal cond,
|
|||
Checker *C = I->second;
|
||||
bool respondsToCallback = true;
|
||||
|
||||
state = C->EvalAssume(state, cond, assumption, &respondsToCallback);
|
||||
state = C->evalAssume(state, cond, assumption, &respondsToCallback);
|
||||
|
||||
// Check if we're building the cache of checkers that care about Assumes.
|
||||
if (NewCO.get() && respondsToCallback)
|
||||
|
@ -473,7 +473,7 @@ const GRState *GRExprEngine::ProcessAssume(const GRState *state, SVal cond,
|
|||
if (!state)
|
||||
return NULL;
|
||||
|
||||
return TF->EvalAssume(state, cond, assumption);
|
||||
return TF->evalAssume(state, cond, assumption);
|
||||
}
|
||||
|
||||
bool GRExprEngine::WantsRegionChangeUpdate(const GRState* state) {
|
||||
|
@ -613,7 +613,7 @@ void GRExprEngine::ProcessStmt(const CFGStmt S, GRStmtNodeBuilder& builder) {
|
|||
|
||||
// FIXME: This should soon be removed.
|
||||
ExplodedNodeSet Tmp2;
|
||||
getTF().EvalDeadSymbols(Tmp2, *this, *Builder, EntryNode,
|
||||
getTF().evalDeadSymbols(Tmp2, *this, *Builder, EntryNode,
|
||||
CleanedState, SymReaper);
|
||||
|
||||
if (Checkers.empty())
|
||||
|
@ -635,7 +635,7 @@ void GRExprEngine::ProcessStmt(const CFGStmt S, GRStmtNodeBuilder& builder) {
|
|||
Checker *checker = I->second;
|
||||
for (ExplodedNodeSet::iterator NI = SrcSet->begin(), NE = SrcSet->end();
|
||||
NI != NE; ++NI)
|
||||
checker->GR_EvalDeadSymbols(*DstSet, *Builder, *this, CurrentStmt,
|
||||
checker->GR_evalDeadSymbols(*DstSet, *Builder, *this, CurrentStmt,
|
||||
*NI, SymReaper, tag);
|
||||
SrcSet = DstSet;
|
||||
}
|
||||
|
@ -907,7 +907,7 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
|
|||
(B->isRelationalOp() || B->isEqualityOp())) {
|
||||
ExplodedNodeSet Tmp;
|
||||
VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp, false);
|
||||
EvalEagerlyAssume(Dst, Tmp, cast<Expr>(S));
|
||||
evalEagerlyAssume(Dst, Tmp, cast<Expr>(S));
|
||||
}
|
||||
else
|
||||
VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst, false);
|
||||
|
@ -1092,7 +1092,7 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
|
|||
if (AMgr.shouldEagerlyAssume()&&(U->getOpcode() == UO_LNot)) {
|
||||
ExplodedNodeSet Tmp;
|
||||
VisitUnaryOperator(U, Pred, Tmp, false);
|
||||
EvalEagerlyAssume(Dst, Tmp, U);
|
||||
evalEagerlyAssume(Dst, Tmp, U);
|
||||
}
|
||||
else
|
||||
VisitUnaryOperator(U, Pred, Dst, false);
|
||||
|
@ -1534,12 +1534,12 @@ void GRExprEngine::VisitGuardedExpr(const Expr* Ex, const Expr* L,
|
|||
/// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path
|
||||
/// nodes when the control reaches the end of a function.
|
||||
void GRExprEngine::ProcessEndPath(GREndPathNodeBuilder& builder) {
|
||||
getTF().EvalEndPath(*this, builder);
|
||||
getTF().evalEndPath(*this, builder);
|
||||
StateMgr.EndPath(builder.getState());
|
||||
for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end(); I!=E;++I){
|
||||
void *tag = I->first;
|
||||
Checker *checker = I->second;
|
||||
checker->EvalEndPath(builder, tag, *this);
|
||||
checker->evalEndPath(builder, tag, *this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1597,7 +1597,7 @@ void GRExprEngine::ProcessSwitch(GRSwitchNodeBuilder& builder) {
|
|||
|
||||
do {
|
||||
nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1.Val.getInt()));
|
||||
DefinedOrUnknownSVal Res = svalBuilder.EvalEQ(DefaultSt ? DefaultSt : state,
|
||||
DefinedOrUnknownSVal Res = svalBuilder.evalEQ(DefaultSt ? DefaultSt : state,
|
||||
CondV, CaseVal);
|
||||
|
||||
// Now "assume" that the case matches.
|
||||
|
@ -1804,7 +1804,7 @@ void GRExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D,
|
|||
ProgramPoint::PostLValueKind);
|
||||
}
|
||||
else
|
||||
EvalLoad(Dst, Ex, Pred, state, V);
|
||||
evalLoad(Dst, Ex, Pred, state, V);
|
||||
|
||||
return;
|
||||
} else if (const EnumConstantDecl* ED = dyn_cast<EnumConstantDecl>(D)) {
|
||||
|
@ -1861,7 +1861,7 @@ void GRExprEngine::VisitArraySubscriptExpr(const ArraySubscriptExpr* A,
|
|||
MakeNode(Dst, A, *I2, state->BindExpr(A, V),
|
||||
ProgramPoint::PostLValueKind);
|
||||
else
|
||||
EvalLoad(Dst, A, *I2, state, V);
|
||||
evalLoad(Dst, A, *I2, state, V);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1892,13 +1892,13 @@ void GRExprEngine::VisitMemberExpr(const MemberExpr* M, ExplodedNode* Pred,
|
|||
if (asLValue)
|
||||
MakeNode(Dst, M, *I, state->BindExpr(M, L), ProgramPoint::PostLValueKind);
|
||||
else
|
||||
EvalLoad(Dst, M, *I, state, L);
|
||||
evalLoad(Dst, M, *I, state, L);
|
||||
}
|
||||
}
|
||||
|
||||
/// EvalBind - Handle the semantics of binding a value to a specific location.
|
||||
/// This method is used by EvalStore and (soon) VisitDeclStmt, and others.
|
||||
void GRExprEngine::EvalBind(ExplodedNodeSet& Dst, const Stmt* StoreE,
|
||||
/// evalBind - Handle the semantics of binding a value to a specific location.
|
||||
/// This method is used by evalStore and (soon) VisitDeclStmt, and others.
|
||||
void GRExprEngine::evalBind(ExplodedNodeSet& Dst, const Stmt* StoreE,
|
||||
ExplodedNode* Pred, const GRState* state,
|
||||
SVal location, SVal Val, bool atDeclInit) {
|
||||
|
||||
|
@ -1946,11 +1946,11 @@ void GRExprEngine::EvalBind(ExplodedNodeSet& Dst, const Stmt* StoreE,
|
|||
GRStmtNodeBuilderRef BuilderRef(Dst, *Builder, *this, *I, newState, StoreE,
|
||||
true);
|
||||
|
||||
getTF().EvalBind(BuilderRef, location, Val);
|
||||
getTF().evalBind(BuilderRef, location, Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// EvalStore - Handle the semantics of a store via an assignment.
|
||||
/// evalStore - Handle the semantics of a store via an assignment.
|
||||
/// @param Dst The node set to store generated state nodes
|
||||
/// @param AssignE The assignment expression if the store happens in an
|
||||
/// assignment.
|
||||
|
@ -1958,7 +1958,7 @@ void GRExprEngine::EvalBind(ExplodedNodeSet& Dst, const Stmt* StoreE,
|
|||
/// @param state The current simulation state
|
||||
/// @param location The location to store the value
|
||||
/// @param Val The value to be stored
|
||||
void GRExprEngine::EvalStore(ExplodedNodeSet& Dst, const Expr *AssignE,
|
||||
void GRExprEngine::evalStore(ExplodedNodeSet& Dst, const Expr *AssignE,
|
||||
const Expr* LocationE,
|
||||
ExplodedNode* Pred,
|
||||
const GRState* state, SVal location, SVal Val,
|
||||
|
@ -1968,7 +1968,7 @@ void GRExprEngine::EvalStore(ExplodedNodeSet& Dst, const Expr *AssignE,
|
|||
|
||||
// Evaluate the location (checks for bad dereferences).
|
||||
ExplodedNodeSet Tmp;
|
||||
EvalLocation(Tmp, LocationE, Pred, state, location, tag, false);
|
||||
evalLocation(Tmp, LocationE, Pred, state, location, tag, false);
|
||||
|
||||
if (Tmp.empty())
|
||||
return;
|
||||
|
@ -1984,10 +1984,10 @@ void GRExprEngine::EvalStore(ExplodedNodeSet& Dst, const Expr *AssignE,
|
|||
const Expr *StoreE = AssignE ? AssignE : LocationE;
|
||||
|
||||
for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI)
|
||||
EvalBind(Dst, StoreE, *NI, GetState(*NI), location, Val);
|
||||
evalBind(Dst, StoreE, *NI, GetState(*NI), location, Val);
|
||||
}
|
||||
|
||||
void GRExprEngine::EvalLoad(ExplodedNodeSet& Dst, const Expr *Ex,
|
||||
void GRExprEngine::evalLoad(ExplodedNodeSet& Dst, const Expr *Ex,
|
||||
ExplodedNode* Pred,
|
||||
const GRState* state, SVal location,
|
||||
const void *tag, QualType LoadTy) {
|
||||
|
@ -2003,30 +2003,30 @@ void GRExprEngine::EvalLoad(ExplodedNodeSet& Dst, const Expr *Ex,
|
|||
if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) {
|
||||
static int loadReferenceTag = 0;
|
||||
ExplodedNodeSet Tmp;
|
||||
EvalLoadCommon(Tmp, Ex, Pred, state, location, &loadReferenceTag,
|
||||
evalLoadCommon(Tmp, Ex, Pred, state, location, &loadReferenceTag,
|
||||
getContext().getPointerType(RT->getPointeeType()));
|
||||
|
||||
// Perform the load from the referenced value.
|
||||
for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end() ; I!=E; ++I) {
|
||||
state = GetState(*I);
|
||||
location = state->getSVal(Ex);
|
||||
EvalLoadCommon(Dst, Ex, *I, state, location, tag, LoadTy);
|
||||
evalLoadCommon(Dst, Ex, *I, state, location, tag, LoadTy);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
EvalLoadCommon(Dst, Ex, Pred, state, location, tag, LoadTy);
|
||||
evalLoadCommon(Dst, Ex, Pred, state, location, tag, LoadTy);
|
||||
}
|
||||
|
||||
void GRExprEngine::EvalLoadCommon(ExplodedNodeSet& Dst, const Expr *Ex,
|
||||
void GRExprEngine::evalLoadCommon(ExplodedNodeSet& Dst, const Expr *Ex,
|
||||
ExplodedNode* Pred,
|
||||
const GRState* state, SVal location,
|
||||
const void *tag, QualType LoadTy) {
|
||||
|
||||
// Evaluate the location (checks for bad dereferences).
|
||||
ExplodedNodeSet Tmp;
|
||||
EvalLocation(Tmp, Ex, Pred, state, location, tag, true);
|
||||
evalLocation(Tmp, Ex, Pred, state, location, tag, true);
|
||||
|
||||
if (Tmp.empty())
|
||||
return;
|
||||
|
@ -2055,7 +2055,7 @@ void GRExprEngine::EvalLoadCommon(ExplodedNodeSet& Dst, const Expr *Ex,
|
|||
}
|
||||
}
|
||||
|
||||
void GRExprEngine::EvalLocation(ExplodedNodeSet &Dst, const Stmt *S,
|
||||
void GRExprEngine::evalLocation(ExplodedNodeSet &Dst, const Stmt *S,
|
||||
ExplodedNode* Pred,
|
||||
const GRState* state, SVal location,
|
||||
const void *tag, bool isLoad) {
|
||||
|
@ -2150,7 +2150,7 @@ void GRExprEngine::VisitCall(const CallExpr* CE, ExplodedNode* Pred,
|
|||
|
||||
// Evaluate the arguments.
|
||||
ExplodedNodeSet ArgsEvaluated;
|
||||
EvalArguments(CE->arg_begin(), CE->arg_end(), Proto, Pred, ArgsEvaluated);
|
||||
evalArguments(CE->arg_begin(), CE->arg_end(), Proto, Pred, ArgsEvaluated);
|
||||
|
||||
// Now process the call itself.
|
||||
ExplodedNodeSet DstTmp;
|
||||
|
@ -2193,18 +2193,18 @@ void GRExprEngine::VisitCall(const CallExpr* CE, ExplodedNode* Pred,
|
|||
DI_Checker != DE_Checker; ++DI_Checker) {
|
||||
|
||||
// Dispatch to the plug-in transfer function.
|
||||
unsigned OldSize = DstTmp3.size();
|
||||
unsigned oldSize = DstTmp3.size();
|
||||
SaveOr OldHasGen(Builder->HasGeneratedNode);
|
||||
Pred = *DI_Checker;
|
||||
|
||||
// Dispatch to transfer function logic to handle the call itself.
|
||||
// FIXME: Allow us to chain together transfer functions.
|
||||
assert(Builder && "GRStmtNodeBuilder must be defined.");
|
||||
getTF().EvalCall(DstTmp3, *this, *Builder, CE, L, Pred);
|
||||
getTF().evalCall(DstTmp3, *this, *Builder, CE, L, Pred);
|
||||
|
||||
// Handle the case where no nodes where generated. Auto-generate that
|
||||
// contains the updated state if we aren't generating sinks.
|
||||
if (!Builder->BuildSinks && DstTmp3.size() == OldSize &&
|
||||
if (!Builder->BuildSinks && DstTmp3.size() == oldSize &&
|
||||
!Builder->HasGeneratedNode)
|
||||
MakeNode(DstTmp3, CE, Pred, state);
|
||||
}
|
||||
|
@ -2233,7 +2233,7 @@ void GRExprEngine::VisitCall(const CallExpr* CE, ExplodedNode* Pred,
|
|||
for (ExplodedNodeSet::iterator NI = DstTmp4.begin(), NE = DstTmp4.end();
|
||||
NI!=NE; ++NI) {
|
||||
const GRState *state = GetState(*NI);
|
||||
EvalLoad(Dst, CE, *NI, state, state->getSVal(CE),
|
||||
evalLoad(Dst, CE, *NI, state, state->getSVal(CE),
|
||||
&ConvertToRvalueTag, LoadTy);
|
||||
}
|
||||
}
|
||||
|
@ -2245,7 +2245,7 @@ void GRExprEngine::VisitCall(const CallExpr* CE, ExplodedNode* Pred,
|
|||
static std::pair<const void*,const void*> EagerlyAssumeTag
|
||||
= std::pair<const void*,const void*>(&EagerlyAssumeTag,static_cast<void*>(0));
|
||||
|
||||
void GRExprEngine::EvalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
|
||||
void GRExprEngine::evalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
|
||||
const Expr *Ex) {
|
||||
for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) {
|
||||
ExplodedNode *Pred = *I;
|
||||
|
@ -2322,7 +2322,7 @@ void GRExprEngine::VisitObjCIvarRefExpr(const ObjCIvarRefExpr* Ex,
|
|||
if (asLValue)
|
||||
MakeNode(Dst, Ex, *I, state->BindExpr(Ex, location));
|
||||
else
|
||||
EvalLoad(Dst, Ex, *I, state, location);
|
||||
evalLoad(Dst, Ex, *I, state, location);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2385,7 +2385,7 @@ void GRExprEngine::VisitObjCForCollectionStmtAux(const ObjCForCollectionStmt* S,
|
|||
// Check if the location we are writing back to is a null pointer.
|
||||
const Stmt* elem = S->getElement();
|
||||
ExplodedNodeSet Tmp;
|
||||
EvalLocation(Tmp, elem, Pred, GetState(Pred), ElementV, NULL, false);
|
||||
evalLocation(Tmp, elem, Pred, GetState(Pred), ElementV, NULL, false);
|
||||
|
||||
if (Tmp.empty())
|
||||
return;
|
||||
|
@ -2490,14 +2490,14 @@ void GRExprEngine::VisitObjCMessageExpr(const ObjCMessageExpr* ME,
|
|||
CheckerVisit(ME, DstPrevisit, ArgsEvaluated, PreVisitStmtCallback);
|
||||
|
||||
// Proceed with evaluate the message expression.
|
||||
ExplodedNodeSet DstEval;
|
||||
ExplodedNodeSet dstEval;
|
||||
|
||||
for (ExplodedNodeSet::iterator DI = DstPrevisit.begin(),
|
||||
DE = DstPrevisit.end(); DI != DE; ++DI) {
|
||||
|
||||
Pred = *DI;
|
||||
bool RaisesException = false;
|
||||
unsigned OldSize = DstEval.size();
|
||||
unsigned oldSize = dstEval.size();
|
||||
SaveAndRestore<bool> OldSink(Builder->BuildSinks);
|
||||
SaveOr OldHasGen(Builder->HasGeneratedNode);
|
||||
|
||||
|
@ -2514,7 +2514,7 @@ void GRExprEngine::VisitObjCMessageExpr(const ObjCMessageExpr* ME,
|
|||
// There are three cases: can be nil or non-nil, must be nil, must be
|
||||
// non-nil. We handle must be nil, and merge the rest two into non-nil.
|
||||
if (nilState && !notNilState) {
|
||||
CheckerEvalNilReceiver(ME, DstEval, nilState, Pred);
|
||||
CheckerEvalNilReceiver(ME, dstEval, nilState, Pred);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2529,7 +2529,7 @@ void GRExprEngine::VisitObjCMessageExpr(const ObjCMessageExpr* ME,
|
|||
Builder->BuildSinks = true;
|
||||
|
||||
// Dispatch to plug-in transfer function.
|
||||
EvalObjCMessageExpr(DstEval, ME, Pred, notNilState);
|
||||
evalObjCMessageExpr(dstEval, ME, Pred, notNilState);
|
||||
}
|
||||
else if (ObjCInterfaceDecl *Iface = ME->getReceiverInterface()) {
|
||||
IdentifierInfo* ClsName = Iface->getIdentifier();
|
||||
|
@ -2577,20 +2577,20 @@ void GRExprEngine::VisitObjCMessageExpr(const ObjCMessageExpr* ME,
|
|||
Builder->BuildSinks = true;
|
||||
|
||||
// Dispatch to plug-in transfer function.
|
||||
EvalObjCMessageExpr(DstEval, ME, Pred, Builder->GetState(Pred));
|
||||
evalObjCMessageExpr(dstEval, ME, Pred, Builder->GetState(Pred));
|
||||
}
|
||||
|
||||
// Handle the case where no nodes where generated. Auto-generate that
|
||||
// contains the updated state if we aren't generating sinks.
|
||||
if (!Builder->BuildSinks && DstEval.size() == OldSize &&
|
||||
if (!Builder->BuildSinks && dstEval.size() == oldSize &&
|
||||
!Builder->HasGeneratedNode)
|
||||
MakeNode(DstEval, ME, Pred, GetState(Pred));
|
||||
MakeNode(dstEval, ME, Pred, GetState(Pred));
|
||||
}
|
||||
|
||||
// Finally, perform the post-condition check of the ObjCMessageExpr and store
|
||||
// the created nodes in 'Dst'.
|
||||
if (!(!asLValue && ReceiverReturnsReference(ME))) {
|
||||
CheckerVisit(ME, Dst, DstEval, PostVisitStmtCallback);
|
||||
CheckerVisit(ME, Dst, dstEval, PostVisitStmtCallback);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2600,14 +2600,14 @@ void GRExprEngine::VisitObjCMessageExpr(const ObjCMessageExpr* ME,
|
|||
// FIXME: This conversion doesn't actually happen unless the result
|
||||
// of ObjCMessageExpr is consumed by another expression.
|
||||
ExplodedNodeSet DstRValueConvert;
|
||||
CheckerVisit(ME, DstRValueConvert, DstEval, PostVisitStmtCallback);
|
||||
CheckerVisit(ME, DstRValueConvert, dstEval, PostVisitStmtCallback);
|
||||
QualType LoadTy = ME->getType();
|
||||
|
||||
static int *ConvertToRvalueTag = 0;
|
||||
for (ExplodedNodeSet::iterator NI = DstRValueConvert.begin(),
|
||||
NE = DstRValueConvert.end(); NI != NE; ++NI) {
|
||||
const GRState *state = GetState(*NI);
|
||||
EvalLoad(Dst, ME, *NI, state, state->getSVal(ME),
|
||||
evalLoad(Dst, ME, *NI, state, state->getSVal(ME),
|
||||
&ConvertToRvalueTag, LoadTy);
|
||||
}
|
||||
}
|
||||
|
@ -2696,7 +2696,7 @@ void GRExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
|
|||
ExplodedNode* N = *I;
|
||||
const GRState* state = GetState(N);
|
||||
SVal V = state->getSVal(Ex);
|
||||
V = svalBuilder.EvalCast(V, T, ExTy);
|
||||
V = svalBuilder.evalCast(V, T, ExTy);
|
||||
state = state->BindExpr(CastE, V);
|
||||
MakeNode(Dst, CastE, N, state);
|
||||
}
|
||||
|
@ -2805,7 +2805,7 @@ void GRExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
|
|||
Builder->getCurrentBlockCount());
|
||||
}
|
||||
|
||||
EvalBind(Dst, DS, *I, state,
|
||||
evalBind(Dst, DS, *I, state,
|
||||
loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true);
|
||||
}
|
||||
else {
|
||||
|
@ -2837,7 +2837,7 @@ void GRExprEngine::VisitCondInit(const VarDecl *VD, const Stmt *S,
|
|||
Builder->getCurrentBlockCount());
|
||||
}
|
||||
|
||||
EvalBind(Dst, S, N, state,
|
||||
evalBind(Dst, S, N, state,
|
||||
loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true);
|
||||
}
|
||||
}
|
||||
|
@ -3041,7 +3041,7 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U,
|
|||
MakeNode(Dst, U, *I, state->BindExpr(U, location),
|
||||
ProgramPoint::PostLValueKind);
|
||||
else
|
||||
EvalLoad(Dst, U, *I, state, location);
|
||||
evalLoad(Dst, U, *I, state, location);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -3159,7 +3159,7 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U,
|
|||
// QualType SrcT = getContext().getCanonicalType(Ex->getType());
|
||||
//
|
||||
// if (DstT != SrcT) // Perform promotions.
|
||||
// V = EvalCast(V, DstT);
|
||||
// V = evalCast(V, DstT);
|
||||
//
|
||||
// if (V.isUnknownOrUndef()) {
|
||||
// MakeNode(Dst, U, *I, BindExpr(St, U, V));
|
||||
|
@ -3173,12 +3173,12 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U,
|
|||
|
||||
case UO_Not:
|
||||
// FIXME: Do we need to handle promotions?
|
||||
state = state->BindExpr(U, EvalComplement(cast<NonLoc>(V)));
|
||||
state = state->BindExpr(U, evalComplement(cast<NonLoc>(V)));
|
||||
break;
|
||||
|
||||
case UO_Minus:
|
||||
// FIXME: Do we need to handle promotions?
|
||||
state = state->BindExpr(U, EvalMinus(cast<NonLoc>(V)));
|
||||
state = state->BindExpr(U, evalMinus(cast<NonLoc>(V)));
|
||||
break;
|
||||
|
||||
case UO_LNot:
|
||||
|
@ -3191,12 +3191,12 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U,
|
|||
|
||||
if (isa<Loc>(V)) {
|
||||
Loc X = ValMgr.makeNull();
|
||||
Result = EvalBinOp(state, BO_EQ, cast<Loc>(V), X,
|
||||
Result = evalBinOp(state, BO_EQ, cast<Loc>(V), X,
|
||||
U->getType());
|
||||
}
|
||||
else {
|
||||
nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
|
||||
Result = EvalBinOp(state, BO_EQ, cast<NonLoc>(V), X,
|
||||
Result = evalBinOp(state, BO_EQ, cast<NonLoc>(V), X,
|
||||
U->getType());
|
||||
}
|
||||
|
||||
|
@ -3226,7 +3226,7 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U,
|
|||
|
||||
// Perform a load.
|
||||
ExplodedNodeSet Tmp2;
|
||||
EvalLoad(Tmp2, Ex, *I, state, V1);
|
||||
evalLoad(Tmp2, Ex, *I, state, V1);
|
||||
|
||||
for (ExplodedNodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end();I2!=E2;++I2) {
|
||||
|
||||
|
@ -3254,7 +3254,7 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U,
|
|||
else
|
||||
RHS = ValMgr.makeIntVal(1, U->getType());
|
||||
|
||||
SVal Result = EvalBinOp(state, Op, V2, RHS, U->getType());
|
||||
SVal Result = evalBinOp(state, Op, V2, RHS, U->getType());
|
||||
|
||||
// Conjure a new symbol if necessary to recover precision.
|
||||
if (Result.isUnknown() || !getConstraintManager().canReasonAbout(Result)){
|
||||
|
@ -3268,12 +3268,12 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U,
|
|||
// propagate that constraint.
|
||||
if (Loc::IsLocType(U->getType())) {
|
||||
DefinedOrUnknownSVal Constraint =
|
||||
svalBuilder.EvalEQ(state, V2, ValMgr.makeZeroVal(U->getType()));
|
||||
svalBuilder.evalEQ(state, V2, ValMgr.makeZeroVal(U->getType()));
|
||||
|
||||
if (!state->Assume(Constraint, true)) {
|
||||
// It isn't feasible for the original value to be null.
|
||||
// Propagate this constraint.
|
||||
Constraint = svalBuilder.EvalEQ(state, SymVal,
|
||||
Constraint = svalBuilder.evalEQ(state, SymVal,
|
||||
ValMgr.makeZeroVal(U->getType()));
|
||||
|
||||
|
||||
|
@ -3286,7 +3286,7 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U,
|
|||
state = state->BindExpr(U, U->isPostfix() ? V2 : Result);
|
||||
|
||||
// Perform the store.
|
||||
EvalStore(Dst, NULL, U, *I2, state, V1, Result);
|
||||
evalStore(Dst, NULL, U, *I2, state, V1, Result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3388,7 +3388,7 @@ void GRExprEngine::VisitReturnStmt(const ReturnStmt *RS, ExplodedNode *Pred,
|
|||
SaveAndRestore<bool> OldSink(Builder->BuildSinks);
|
||||
SaveOr OldHasGen(Builder->HasGeneratedNode);
|
||||
|
||||
getTF().EvalReturn(Dst, *this, *Builder, RS, Pred);
|
||||
getTF().evalReturn(Dst, *this, *Builder, RS, Pred);
|
||||
|
||||
// Handle the case where no nodes where generated.
|
||||
if (!Builder->BuildSinks && Dst.size() == size &&
|
||||
|
@ -3455,14 +3455,14 @@ void GRExprEngine::VisitBinaryOperator(const BinaryOperator* B,
|
|||
|
||||
// Simulate the effects of a "store": bind the value of the RHS
|
||||
// to the L-Value represented by the LHS.
|
||||
EvalStore(Tmp3, B, LHS, *I2, state->BindExpr(B, ExprVal), LeftV,RightV);
|
||||
evalStore(Tmp3, B, LHS, *I2, state->BindExpr(B, ExprVal), LeftV,RightV);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!B->isAssignmentOp()) {
|
||||
// Process non-assignments except commas or short-circuited
|
||||
// logical expressions (LAnd and LOr).
|
||||
SVal Result = EvalBinOp(state, Op, LeftV, RightV, B->getType());
|
||||
SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType());
|
||||
|
||||
if (Result.isUnknown()) {
|
||||
MakeNode(Tmp3, B, *I2, state);
|
||||
|
@ -3496,7 +3496,7 @@ void GRExprEngine::VisitBinaryOperator(const BinaryOperator* B,
|
|||
// null dereferences, and so on.
|
||||
ExplodedNodeSet Tmp4;
|
||||
SVal location = state->getSVal(LHS);
|
||||
EvalLoad(Tmp4, LHS, *I2, state, location);
|
||||
evalLoad(Tmp4, LHS, *I2, state, location);
|
||||
|
||||
for (ExplodedNodeSet::iterator I4=Tmp4.begin(), E4=Tmp4.end(); I4!=E4;
|
||||
++I4) {
|
||||
|
@ -3516,10 +3516,10 @@ void GRExprEngine::VisitBinaryOperator(const BinaryOperator* B,
|
|||
QualType RTy = getContext().getCanonicalType(RHS->getType());
|
||||
|
||||
// Promote LHS.
|
||||
V = svalBuilder.EvalCast(V, CLHSTy, LTy);
|
||||
V = svalBuilder.evalCast(V, CLHSTy, LTy);
|
||||
|
||||
// Compute the result of the operation.
|
||||
SVal Result = svalBuilder.EvalCast(EvalBinOp(state, Op, V, RightV, CTy),
|
||||
SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy),
|
||||
B->getType(), CTy);
|
||||
|
||||
// EXPERIMENTAL: "Conjured" symbols.
|
||||
|
@ -3538,15 +3538,15 @@ void GRExprEngine::VisitBinaryOperator(const BinaryOperator* B,
|
|||
LHSVal = ValMgr.getConjuredSymbolVal(NULL, B->getRHS(), LTy, Count);
|
||||
|
||||
// However, we need to convert the symbol to the computation type.
|
||||
Result = svalBuilder.EvalCast(LHSVal, CTy, LTy);
|
||||
Result = svalBuilder.evalCast(LHSVal, CTy, LTy);
|
||||
}
|
||||
else {
|
||||
// The left-hand side may bind to a different value then the
|
||||
// computation type.
|
||||
LHSVal = svalBuilder.EvalCast(Result, LTy, CTy);
|
||||
LHSVal = svalBuilder.evalCast(Result, LTy, CTy);
|
||||
}
|
||||
|
||||
EvalStore(Tmp3, B, LHS, *I4, state->BindExpr(B, Result),
|
||||
evalStore(Tmp3, B, LHS, *I4, state->BindExpr(B, Result),
|
||||
location, LHSVal);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -251,27 +251,27 @@ const GRState *GRState::AssumeInBound(DefinedOrUnknownSVal Idx,
|
|||
nonloc::ConcreteInt Min = BVF.getMinValue(IndexTy);
|
||||
|
||||
// Adjust the index.
|
||||
SVal NewIdx = SV.EvalBinOpNN(this, BO_Add,
|
||||
SVal newIdx = SV.evalBinOpNN(this, BO_Add,
|
||||
cast<NonLoc>(Idx), Min, IndexTy);
|
||||
if (NewIdx.isUnknownOrUndef())
|
||||
if (newIdx.isUnknownOrUndef())
|
||||
return this;
|
||||
|
||||
// Adjust the upper bound.
|
||||
SVal NewBound = SV.EvalBinOpNN(this, BO_Add,
|
||||
SVal NewBound = SV.evalBinOpNN(this, BO_Add,
|
||||
cast<NonLoc>(UpperBound), Min, IndexTy);
|
||||
if (NewBound.isUnknownOrUndef())
|
||||
return this;
|
||||
|
||||
// Build the actual comparison.
|
||||
SVal InBound = SV.EvalBinOpNN(this, BO_LT,
|
||||
cast<NonLoc>(NewIdx), cast<NonLoc>(NewBound),
|
||||
SVal inBound = SV.evalBinOpNN(this, BO_LT,
|
||||
cast<NonLoc>(newIdx), cast<NonLoc>(NewBound),
|
||||
Ctx.IntTy);
|
||||
if (InBound.isUnknownOrUndef())
|
||||
if (inBound.isUnknownOrUndef())
|
||||
return this;
|
||||
|
||||
// Finally, let the constraint manager take care of it.
|
||||
ConstraintManager &CM = SM.getConstraintManager();
|
||||
return CM.Assume(this, cast<DefinedSVal>(InBound), Assumption);
|
||||
return CM.Assume(this, cast<DefinedSVal>(inBound), Assumption);
|
||||
}
|
||||
|
||||
const GRState* GRStateManager::getInitialState(const LocationContext *InitLoc) {
|
||||
|
|
|
@ -75,11 +75,11 @@ public:
|
|||
BT_BadFree(0),
|
||||
II_malloc(0), II_free(0), II_realloc(0), II_calloc(0) {}
|
||||
static void *getTag();
|
||||
bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
|
||||
void EvalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper);
|
||||
void EvalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng);
|
||||
bool evalCallExpr(CheckerContext &C, const CallExpr *CE);
|
||||
void evalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper);
|
||||
void evalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng);
|
||||
void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *S);
|
||||
const GRState *EvalAssume(const GRState *state, SVal Cond, bool Assumption,
|
||||
const GRState *evalAssume(const GRState *state, SVal Cond, bool Assumption,
|
||||
bool *respondsToCallback);
|
||||
void VisitLocation(CheckerContext &C, const Stmt *S, SVal l);
|
||||
virtual void PreVisitBind(CheckerContext &C, const Stmt *StoreE,
|
||||
|
@ -132,7 +132,7 @@ void *MallocChecker::getTag() {
|
|||
return &x;
|
||||
}
|
||||
|
||||
bool MallocChecker::EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
|
||||
bool MallocChecker::evalCallExpr(CheckerContext &C, const CallExpr *CE) {
|
||||
const GRState *state = C.getState();
|
||||
const Expr *Callee = CE->getCallee();
|
||||
SVal L = state->getSVal(Callee);
|
||||
|
@ -243,7 +243,7 @@ const GRState *MallocChecker::MallocMemAux(CheckerContext &C,
|
|||
|
||||
SValBuilder &svalBuilder = ValMgr.getSValBuilder();
|
||||
DefinedOrUnknownSVal ExtentMatchesSize =
|
||||
svalBuilder.EvalEQ(state, Extent, DefinedSize);
|
||||
svalBuilder.evalEQ(state, Extent, DefinedSize);
|
||||
state = state->Assume(ExtentMatchesSize, true);
|
||||
|
||||
SymbolRef Sym = RetVal.getAsLocSymbol();
|
||||
|
@ -506,7 +506,7 @@ void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) {
|
|||
ValueManager &ValMgr = C.getValueManager();
|
||||
SValBuilder &svalBuilder = C.getSValBuilder();
|
||||
|
||||
DefinedOrUnknownSVal PtrEQ = svalBuilder.EvalEQ(state, Arg0Val, ValMgr.makeNull());
|
||||
DefinedOrUnknownSVal PtrEQ = svalBuilder.evalEQ(state, Arg0Val, ValMgr.makeNull());
|
||||
|
||||
// If the ptr is NULL, the call is equivalent to malloc(size).
|
||||
if (const GRState *stateEqual = state->Assume(PtrEQ, true)) {
|
||||
|
@ -527,7 +527,7 @@ void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) {
|
|||
const Expr *Arg1 = CE->getArg(1);
|
||||
DefinedOrUnknownSVal Arg1Val =
|
||||
cast<DefinedOrUnknownSVal>(stateNotEqual->getSVal(Arg1));
|
||||
DefinedOrUnknownSVal SizeZero = svalBuilder.EvalEQ(stateNotEqual, Arg1Val,
|
||||
DefinedOrUnknownSVal SizeZero = svalBuilder.evalEQ(stateNotEqual, Arg1Val,
|
||||
ValMgr.makeIntValWithPtrWidth(0, false));
|
||||
|
||||
if (const GRState *stateSizeZero = stateNotEqual->Assume(SizeZero, true)) {
|
||||
|
@ -556,7 +556,7 @@ void MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE) {
|
|||
|
||||
SVal Count = state->getSVal(CE->getArg(0));
|
||||
SVal EleSize = state->getSVal(CE->getArg(1));
|
||||
SVal TotalSize = svalBuilder.EvalBinOp(state, BO_Mul, Count, EleSize,
|
||||
SVal TotalSize = svalBuilder.evalBinOp(state, BO_Mul, Count, EleSize,
|
||||
ValMgr.getContext().getSizeType());
|
||||
|
||||
SVal Zero = ValMgr.makeZeroVal(ValMgr.getContext().CharTy);
|
||||
|
@ -565,7 +565,7 @@ void MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE) {
|
|||
C.addTransition(state);
|
||||
}
|
||||
|
||||
void MallocChecker::EvalDeadSymbols(CheckerContext &C,SymbolReaper &SymReaper) {
|
||||
void MallocChecker::evalDeadSymbols(CheckerContext &C,SymbolReaper &SymReaper) {
|
||||
if (!SymReaper.hasDeadSymbols())
|
||||
return;
|
||||
|
||||
|
@ -595,7 +595,7 @@ void MallocChecker::EvalDeadSymbols(CheckerContext &C,SymbolReaper &SymReaper) {
|
|||
C.GenerateNode(state);
|
||||
}
|
||||
|
||||
void MallocChecker::EvalEndPath(GREndPathNodeBuilder &B, void *tag,
|
||||
void MallocChecker::evalEndPath(GREndPathNodeBuilder &B, void *tag,
|
||||
GRExprEngine &Eng) {
|
||||
SaveAndRestore<bool> OldHasGen(B.HasGeneratedNode);
|
||||
const GRState *state = B.getState();
|
||||
|
@ -639,7 +639,7 @@ void MallocChecker::PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *S) {
|
|||
C.addTransition(state);
|
||||
}
|
||||
|
||||
const GRState *MallocChecker::EvalAssume(const GRState *state, SVal Cond,
|
||||
const GRState *MallocChecker::evalAssume(const GRState *state, SVal Cond,
|
||||
bool Assumption,
|
||||
bool * /* respondsToCallback */) {
|
||||
// If a symblic region is assumed to NULL, set its state to AllocateFailed.
|
||||
|
|
|
@ -22,10 +22,10 @@ namespace {
|
|||
class OSAtomicChecker : public Checker {
|
||||
public:
|
||||
static void *getTag() { static int tag = 0; return &tag; }
|
||||
virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
|
||||
virtual bool evalCallExpr(CheckerContext &C, const CallExpr *CE);
|
||||
|
||||
private:
|
||||
bool EvalOSAtomicCompareAndSwap(CheckerContext &C, const CallExpr *CE);
|
||||
bool evalOSAtomicCompareAndSwap(CheckerContext &C, const CallExpr *CE);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ void clang::RegisterOSAtomicChecker(GRExprEngine &Eng) {
|
|||
Eng.registerCheck(new OSAtomicChecker());
|
||||
}
|
||||
|
||||
bool OSAtomicChecker::EvalCallExpr(CheckerContext &C,const CallExpr *CE) {
|
||||
bool OSAtomicChecker::evalCallExpr(CheckerContext &C,const CallExpr *CE) {
|
||||
const GRState *state = C.getState();
|
||||
const Expr *Callee = CE->getCallee();
|
||||
SVal L = state->getSVal(Callee);
|
||||
|
@ -52,13 +52,13 @@ bool OSAtomicChecker::EvalCallExpr(CheckerContext &C,const CallExpr *CE) {
|
|||
// Check for compare and swap.
|
||||
if (FName.startswith("OSAtomicCompareAndSwap") ||
|
||||
FName.startswith("objc_atomicCompareAndSwap"))
|
||||
return EvalOSAtomicCompareAndSwap(C, CE);
|
||||
return evalOSAtomicCompareAndSwap(C, CE);
|
||||
|
||||
// FIXME: Other atomics.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OSAtomicChecker::EvalOSAtomicCompareAndSwap(CheckerContext &C,
|
||||
bool OSAtomicChecker::evalOSAtomicCompareAndSwap(CheckerContext &C,
|
||||
const CallExpr *CE) {
|
||||
// Not enough arguments to match OSAtomicCompareAndSwap?
|
||||
if (CE->getNumArgs() != 3)
|
||||
|
@ -112,7 +112,7 @@ bool OSAtomicChecker::EvalOSAtomicCompareAndSwap(CheckerContext &C,
|
|||
dyn_cast_or_null<TypedRegion>(location.getAsRegion())) {
|
||||
LoadTy = TR->getValueType();
|
||||
}
|
||||
Engine.EvalLoad(Tmp, theValueExpr, C.getPredecessor(),
|
||||
Engine.evalLoad(Tmp, theValueExpr, C.getPredecessor(),
|
||||
state, location, OSAtomicLoadTag, LoadTy);
|
||||
|
||||
if (Tmp.empty()) {
|
||||
|
@ -145,7 +145,7 @@ bool OSAtomicChecker::EvalOSAtomicCompareAndSwap(CheckerContext &C,
|
|||
SValBuilder &svalBuilder = Engine.getSValBuilder();
|
||||
|
||||
// Perform the comparison.
|
||||
DefinedOrUnknownSVal Cmp = svalBuilder.EvalEQ(stateLoad,theValueVal,oldValueVal);
|
||||
DefinedOrUnknownSVal Cmp = svalBuilder.evalEQ(stateLoad,theValueVal,oldValueVal);
|
||||
|
||||
const GRState *stateEqual = stateLoad->Assume(Cmp, true);
|
||||
|
||||
|
@ -158,10 +158,10 @@ bool OSAtomicChecker::EvalOSAtomicCompareAndSwap(CheckerContext &C,
|
|||
// Handle implicit value casts.
|
||||
if (const TypedRegion *R =
|
||||
dyn_cast_or_null<TypedRegion>(location.getAsRegion())) {
|
||||
val = svalBuilder.EvalCast(val,R->getValueType(), newValueExpr->getType());
|
||||
val = svalBuilder.evalCast(val,R->getValueType(), newValueExpr->getType());
|
||||
}
|
||||
|
||||
Engine.EvalStore(TmpStore, NULL, theValueExpr, N,
|
||||
Engine.evalStore(TmpStore, NULL, theValueExpr, N,
|
||||
stateEqual, location, val, OSAtomicStoreTag);
|
||||
|
||||
if (TmpStore.empty()) {
|
||||
|
|
|
@ -227,7 +227,7 @@ public:
|
|||
/// For DerivedToBase casts, create a CXXBaseObjectRegion and return it.
|
||||
virtual SVal evalDerivedToBase(SVal derived, QualType basePtrType);
|
||||
|
||||
SVal EvalBinOp(BinaryOperator::Opcode Op,Loc L, NonLoc R, QualType resultTy);
|
||||
SVal evalBinOp(BinaryOperator::Opcode Op,Loc L, NonLoc R, QualType resultTy);
|
||||
|
||||
Store getInitialStore(const LocationContext *InitLoc) {
|
||||
return RBFactory.getEmptyMap().getRoot();
|
||||
|
@ -819,7 +819,7 @@ SVal RegionStoreManager::evalDerivedToBase(SVal derived, QualType basePtrType) {
|
|||
// Pointer arithmetic.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R,
|
||||
SVal RegionStoreManager::evalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R,
|
||||
QualType resultTy) {
|
||||
// Assume the base location is MemRegionVal.
|
||||
if (!isa<loc::MemRegionVal>(L))
|
||||
|
@ -1307,7 +1307,7 @@ SVal RegionStoreManager::RetrieveVar(Store store, const VarRegion *R) {
|
|||
if (const IntegerLiteral *IL =
|
||||
dyn_cast<IntegerLiteral>(Init->IgnoreParenCasts())) {
|
||||
const nonloc::ConcreteInt &V = ValMgr.makeIntVal(IL);
|
||||
return ValMgr.getSValBuilder().EvalCast(V, Init->getType(),
|
||||
return ValMgr.getSValBuilder().evalCast(V, Init->getType(),
|
||||
IL->getType());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
using namespace clang;
|
||||
|
||||
|
||||
SVal SValBuilder::EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
|
||||
SVal SValBuilder::evalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
|
||||
SVal L, SVal R, QualType T) {
|
||||
|
||||
if (L.isUndef() || R.isUndef())
|
||||
|
@ -29,9 +29,9 @@ SVal SValBuilder::EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
|
|||
|
||||
if (isa<Loc>(L)) {
|
||||
if (isa<Loc>(R))
|
||||
return EvalBinOpLL(ST, Op, cast<Loc>(L), cast<Loc>(R), T);
|
||||
return evalBinOpLL(ST, Op, cast<Loc>(L), cast<Loc>(R), T);
|
||||
|
||||
return EvalBinOpLN(ST, Op, cast<Loc>(L), cast<NonLoc>(R), T);
|
||||
return evalBinOpLN(ST, Op, cast<Loc>(L), cast<NonLoc>(R), T);
|
||||
}
|
||||
|
||||
if (isa<Loc>(R)) {
|
||||
|
@ -40,21 +40,21 @@ SVal SValBuilder::EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
|
|||
assert(Op == BO_Add);
|
||||
|
||||
// Commute the operands.
|
||||
return EvalBinOpLN(ST, Op, cast<Loc>(R), cast<NonLoc>(L), T);
|
||||
return evalBinOpLN(ST, Op, cast<Loc>(R), cast<NonLoc>(L), T);
|
||||
}
|
||||
|
||||
return EvalBinOpNN(ST, Op, cast<NonLoc>(L), cast<NonLoc>(R), T);
|
||||
return evalBinOpNN(ST, Op, cast<NonLoc>(L), cast<NonLoc>(R), T);
|
||||
}
|
||||
|
||||
DefinedOrUnknownSVal SValBuilder::EvalEQ(const GRState *ST,
|
||||
DefinedOrUnknownSVal SValBuilder::evalEQ(const GRState *ST,
|
||||
DefinedOrUnknownSVal L,
|
||||
DefinedOrUnknownSVal R) {
|
||||
return cast<DefinedOrUnknownSVal>(EvalBinOp(ST, BO_EQ, L, R,
|
||||
return cast<DefinedOrUnknownSVal>(evalBinOp(ST, BO_EQ, L, R,
|
||||
ValMgr.getContext().IntTy));
|
||||
}
|
||||
|
||||
// FIXME: should rewrite according to the cast kind.
|
||||
SVal SValBuilder::EvalCast(SVal val, QualType castTy, QualType originalTy) {
|
||||
SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
|
||||
if (val.isUnknownOrUndef() || castTy == originalTy)
|
||||
return val;
|
||||
|
||||
|
@ -72,11 +72,11 @@ SVal SValBuilder::EvalCast(SVal val, QualType castTy, QualType originalTy) {
|
|||
|
||||
// Check for casts from integers to integers.
|
||||
if (castTy->isIntegerType() && originalTy->isIntegerType())
|
||||
return EvalCastNL(cast<NonLoc>(val), castTy);
|
||||
return evalCastNL(cast<NonLoc>(val), castTy);
|
||||
|
||||
// Check for casts from pointers to integers.
|
||||
if (castTy->isIntegerType() && Loc::IsLocType(originalTy))
|
||||
return EvalCastL(cast<Loc>(val), castTy);
|
||||
return evalCastL(cast<Loc>(val), castTy);
|
||||
|
||||
// Check for casts from integers to pointers.
|
||||
if (Loc::IsLocType(castTy) && originalTy->isIntegerType()) {
|
||||
|
@ -115,7 +115,7 @@ SVal SValBuilder::EvalCast(SVal val, QualType castTy, QualType originalTy) {
|
|||
// need the original decayed type.
|
||||
// QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
|
||||
// QualType pointerTy = C.getPointerType(elemTy);
|
||||
return EvalCastL(cast<Loc>(val), castTy);
|
||||
return evalCastL(cast<Loc>(val), castTy);
|
||||
}
|
||||
|
||||
// Check for casts from a region to a specific type.
|
||||
|
@ -157,13 +157,13 @@ SVal SValBuilder::EvalCast(SVal val, QualType castTy, QualType originalTy) {
|
|||
|
||||
// Delegate to store manager to get the result of casting a region to a
|
||||
// different type. If the MemRegion* returned is NULL, this expression
|
||||
// evaluates to UnknownVal.
|
||||
// Evaluates to UnknownVal.
|
||||
R = storeMgr.CastRegion(R, castTy);
|
||||
return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
|
||||
}
|
||||
|
||||
DispatchCast:
|
||||
// All other cases.
|
||||
return isa<Loc>(val) ? EvalCastL(cast<Loc>(val), castTy)
|
||||
: EvalCastNL(cast<NonLoc>(val), castTy);
|
||||
return isa<Loc>(val) ? evalCastL(cast<Loc>(val), castTy)
|
||||
: evalCastNL(cast<NonLoc>(val), castTy);
|
||||
}
|
||||
|
|
|
@ -225,7 +225,7 @@ SVal nonloc::ConcreteInt::evalBinOp(ValueManager &ValMgr,
|
|||
BinaryOperator::Opcode Op,
|
||||
const nonloc::ConcreteInt& R) const {
|
||||
const llvm::APSInt* X =
|
||||
ValMgr.getBasicValueFactory().EvaluateAPSInt(Op, getValue(), R.getValue());
|
||||
ValMgr.getBasicValueFactory().evalAPSInt(Op, getValue(), R.getValue());
|
||||
|
||||
if (X)
|
||||
return nonloc::ConcreteInt(*X);
|
||||
|
@ -246,14 +246,14 @@ nonloc::ConcreteInt nonloc::ConcreteInt::evalMinus(ValueManager &ValMgr) const {
|
|||
// Transfer function dispatch for Locs.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
SVal loc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals,
|
||||
SVal loc::ConcreteInt::evalBinOp(BasicValueFactory& BasicVals,
|
||||
BinaryOperator::Opcode Op,
|
||||
const loc::ConcreteInt& R) const {
|
||||
|
||||
assert (Op == BO_Add || Op == BO_Sub ||
|
||||
(Op >= BO_LT && Op <= BO_NE));
|
||||
|
||||
const llvm::APSInt* X = BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue());
|
||||
const llvm::APSInt* X = BasicVals.evalAPSInt(Op, getValue(), R.getValue());
|
||||
|
||||
if (X)
|
||||
return loc::ConcreteInt(*X);
|
||||
|
|
|
@ -19,23 +19,23 @@ using namespace clang;
|
|||
namespace {
|
||||
class SimpleSValBuilder : public SValBuilder {
|
||||
protected:
|
||||
virtual SVal EvalCastNL(NonLoc val, QualType castTy);
|
||||
virtual SVal EvalCastL(Loc val, QualType castTy);
|
||||
virtual SVal evalCastNL(NonLoc val, QualType castTy);
|
||||
virtual SVal evalCastL(Loc val, QualType castTy);
|
||||
|
||||
public:
|
||||
SimpleSValBuilder(ValueManager &valMgr) : SValBuilder(valMgr) {}
|
||||
virtual ~SimpleSValBuilder() {}
|
||||
|
||||
virtual SVal EvalMinus(NonLoc val);
|
||||
virtual SVal EvalComplement(NonLoc val);
|
||||
virtual SVal EvalBinOpNN(const GRState *state, BinaryOperator::Opcode op,
|
||||
virtual SVal evalMinus(NonLoc val);
|
||||
virtual SVal evalComplement(NonLoc val);
|
||||
virtual SVal evalBinOpNN(const GRState *state, BinaryOperator::Opcode op,
|
||||
NonLoc lhs, NonLoc rhs, QualType resultTy);
|
||||
virtual SVal EvalBinOpLL(const GRState *state, BinaryOperator::Opcode op,
|
||||
virtual SVal evalBinOpLL(const GRState *state, BinaryOperator::Opcode op,
|
||||
Loc lhs, Loc rhs, QualType resultTy);
|
||||
virtual SVal EvalBinOpLN(const GRState *state, BinaryOperator::Opcode op,
|
||||
virtual SVal evalBinOpLN(const GRState *state, BinaryOperator::Opcode op,
|
||||
Loc lhs, NonLoc rhs, QualType resultTy);
|
||||
|
||||
/// getKnownValue - Evaluates a given SVal. If the SVal has only one possible
|
||||
/// getKnownValue - evaluates a given SVal. If the SVal has only one possible
|
||||
/// (integer) value, that value is returned. Otherwise, returns NULL.
|
||||
virtual const llvm::APSInt *getKnownValue(const GRState *state, SVal V);
|
||||
|
||||
|
@ -52,7 +52,7 @@ SValBuilder *clang::createSimpleSValBuilder(ValueManager &valMgr) {
|
|||
// Transfer function for Casts.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
SVal SimpleSValBuilder::EvalCastNL(NonLoc val, QualType castTy) {
|
||||
SVal SimpleSValBuilder::evalCastNL(NonLoc val, QualType castTy) {
|
||||
|
||||
bool isLocType = Loc::IsLocType(castTy);
|
||||
|
||||
|
@ -104,7 +104,7 @@ SVal SimpleSValBuilder::EvalCastNL(NonLoc val, QualType castTy) {
|
|||
return ValMgr.makeIntVal(i);
|
||||
}
|
||||
|
||||
SVal SimpleSValBuilder::EvalCastL(Loc val, QualType castTy) {
|
||||
SVal SimpleSValBuilder::evalCastL(Loc val, QualType castTy) {
|
||||
|
||||
// Casts from pointers -> pointers, just return the lval.
|
||||
//
|
||||
|
@ -142,7 +142,7 @@ SVal SimpleSValBuilder::EvalCastL(Loc val, QualType castTy) {
|
|||
// Transfer function for unary operators.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
SVal SimpleSValBuilder::EvalMinus(NonLoc val) {
|
||||
SVal SimpleSValBuilder::evalMinus(NonLoc val) {
|
||||
switch (val.getSubKind()) {
|
||||
case nonloc::ConcreteIntKind:
|
||||
return cast<nonloc::ConcreteInt>(val).evalMinus(ValMgr);
|
||||
|
@ -151,7 +151,7 @@ SVal SimpleSValBuilder::EvalMinus(NonLoc val) {
|
|||
}
|
||||
}
|
||||
|
||||
SVal SimpleSValBuilder::EvalComplement(NonLoc X) {
|
||||
SVal SimpleSValBuilder::evalComplement(NonLoc X) {
|
||||
switch (X.getSubKind()) {
|
||||
case nonloc::ConcreteIntKind:
|
||||
return cast<nonloc::ConcreteInt>(X).evalComplement(ValMgr);
|
||||
|
@ -254,11 +254,11 @@ SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS,
|
|||
}
|
||||
|
||||
// Idempotent ops (like a*1) can still change the type of an expression.
|
||||
// Wrap the LHS up in a NonLoc again and let EvalCastNL do the dirty work.
|
||||
// Wrap the LHS up in a NonLoc again and let evalCastNL do the dirty work.
|
||||
if (isIdempotent) {
|
||||
if (SymbolRef LHSSym = dyn_cast<SymbolData>(LHS))
|
||||
return EvalCastNL(nonloc::SymbolVal(LHSSym), resultTy);
|
||||
return EvalCastNL(nonloc::SymExprVal(LHS), resultTy);
|
||||
return evalCastNL(nonloc::SymbolVal(LHSSym), resultTy);
|
||||
return evalCastNL(nonloc::SymExprVal(LHS), resultTy);
|
||||
}
|
||||
|
||||
// If we reach this point, the expression cannot be simplified.
|
||||
|
@ -266,7 +266,7 @@ SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS,
|
|||
return ValMgr.makeNonLoc(LHS, op, RHS, resultTy);
|
||||
}
|
||||
|
||||
SVal SimpleSValBuilder::EvalBinOpNN(const GRState *state,
|
||||
SVal SimpleSValBuilder::evalBinOpNN(const GRState *state,
|
||||
BinaryOperator::Opcode op,
|
||||
NonLoc lhs, NonLoc rhs,
|
||||
QualType resultTy) {
|
||||
|
@ -288,7 +288,7 @@ SVal SimpleSValBuilder::EvalBinOpNN(const GRState *state,
|
|||
return ValMgr.makeIntVal(0, resultTy);
|
||||
case BO_Or:
|
||||
case BO_And:
|
||||
return EvalCastNL(lhs, resultTy);
|
||||
return evalCastNL(lhs, resultTy);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
|
@ -299,7 +299,7 @@ SVal SimpleSValBuilder::EvalBinOpNN(const GRState *state,
|
|||
Loc lhsL = cast<nonloc::LocAsInteger>(lhs).getLoc();
|
||||
switch (rhs.getSubKind()) {
|
||||
case nonloc::LocAsIntegerKind:
|
||||
return EvalBinOpLL(state, op, lhsL,
|
||||
return evalBinOpLL(state, op, lhsL,
|
||||
cast<nonloc::LocAsInteger>(rhs).getLoc(),
|
||||
resultTy);
|
||||
case nonloc::ConcreteIntKind: {
|
||||
|
@ -308,7 +308,7 @@ SVal SimpleSValBuilder::EvalBinOpNN(const GRState *state,
|
|||
llvm::APSInt i = cast<nonloc::ConcreteInt>(rhs).getValue();
|
||||
i.setIsUnsigned(true);
|
||||
i.extOrTrunc(Ctx.getTypeSize(Ctx.VoidPtrTy));
|
||||
return EvalBinOpLL(state, op, lhsL, ValMgr.makeLoc(i), resultTy);
|
||||
return evalBinOpLL(state, op, lhsL, ValMgr.makeLoc(i), resultTy);
|
||||
}
|
||||
default:
|
||||
switch (op) {
|
||||
|
@ -402,9 +402,9 @@ SVal SimpleSValBuilder::EvalBinOpNN(const GRState *state,
|
|||
|
||||
const llvm::APSInt *newRHS;
|
||||
if (lop == op)
|
||||
newRHS = BVF.EvaluateAPSInt(BO_Add, first, second);
|
||||
newRHS = BVF.evalAPSInt(BO_Add, first, second);
|
||||
else
|
||||
newRHS = BVF.EvaluateAPSInt(BO_Sub, first, second);
|
||||
newRHS = BVF.evalAPSInt(BO_Sub, first, second);
|
||||
return MakeSymIntVal(symIntExpr->getLHS(), lop, *newRHS, resultTy);
|
||||
}
|
||||
}
|
||||
|
@ -515,13 +515,13 @@ SVal SimpleSValBuilder::EvalBinOpNN(const GRState *state,
|
|||
}
|
||||
|
||||
// FIXME: all this logic will change if/when we have MemRegion::getLocation().
|
||||
SVal SimpleSValBuilder::EvalBinOpLL(const GRState *state,
|
||||
SVal SimpleSValBuilder::evalBinOpLL(const GRState *state,
|
||||
BinaryOperator::Opcode op,
|
||||
Loc lhs, Loc rhs,
|
||||
QualType resultTy) {
|
||||
// Only comparisons and subtractions are valid operations on two pointers.
|
||||
// See [C99 6.5.5 through 6.5.14] or [C++0x 5.6 through 5.15].
|
||||
// However, if a pointer is casted to an integer, EvalBinOpNN may end up
|
||||
// However, if a pointer is casted to an integer, evalBinOpNN may end up
|
||||
// calling this function with another operation (PR7527). We don't attempt to
|
||||
// model this for now, but it could be useful, particularly when the
|
||||
// "location" is actually an integer value that's been passed through a void*.
|
||||
|
@ -559,7 +559,7 @@ SVal SimpleSValBuilder::EvalBinOpLL(const GRState *state,
|
|||
default:
|
||||
break;
|
||||
case BO_Sub:
|
||||
return EvalCastL(lhs, resultTy);
|
||||
return evalCastL(lhs, resultTy);
|
||||
case BO_EQ:
|
||||
case BO_LE:
|
||||
case BO_LT:
|
||||
|
@ -593,9 +593,9 @@ SVal SimpleSValBuilder::EvalBinOpLL(const GRState *state,
|
|||
// If both operands are constants, just perform the operation.
|
||||
if (loc::ConcreteInt *rInt = dyn_cast<loc::ConcreteInt>(&rhs)) {
|
||||
BasicValueFactory &BVF = ValMgr.getBasicValueFactory();
|
||||
SVal ResultVal = cast<loc::ConcreteInt>(lhs).EvalBinOp(BVF, op, *rInt);
|
||||
SVal ResultVal = cast<loc::ConcreteInt>(lhs).evalBinOp(BVF, op, *rInt);
|
||||
if (Loc *Result = dyn_cast<Loc>(&ResultVal))
|
||||
return EvalCastL(*Result, resultTy);
|
||||
return evalCastL(*Result, resultTy);
|
||||
else
|
||||
return UnknownVal();
|
||||
}
|
||||
|
@ -640,7 +640,7 @@ SVal SimpleSValBuilder::EvalBinOpLL(const GRState *state,
|
|||
default:
|
||||
break;
|
||||
case BO_Sub:
|
||||
return EvalCastL(lhs, resultTy);
|
||||
return evalCastL(lhs, resultTy);
|
||||
case BO_EQ:
|
||||
case BO_LT:
|
||||
case BO_LE:
|
||||
|
@ -705,7 +705,7 @@ SVal SimpleSValBuilder::EvalBinOpLL(const GRState *state,
|
|||
NonLoc *LeftIndex = dyn_cast<NonLoc>(&LeftIndexVal);
|
||||
if (!LeftIndex)
|
||||
return UnknownVal();
|
||||
LeftIndexVal = EvalCastNL(*LeftIndex, resultTy);
|
||||
LeftIndexVal = evalCastNL(*LeftIndex, resultTy);
|
||||
LeftIndex = dyn_cast<NonLoc>(&LeftIndexVal);
|
||||
if (!LeftIndex)
|
||||
return UnknownVal();
|
||||
|
@ -715,14 +715,14 @@ SVal SimpleSValBuilder::EvalBinOpLL(const GRState *state,
|
|||
NonLoc *RightIndex = dyn_cast<NonLoc>(&RightIndexVal);
|
||||
if (!RightIndex)
|
||||
return UnknownVal();
|
||||
RightIndexVal = EvalCastNL(*RightIndex, resultTy);
|
||||
RightIndexVal = evalCastNL(*RightIndex, resultTy);
|
||||
RightIndex = dyn_cast<NonLoc>(&RightIndexVal);
|
||||
if (!RightIndex)
|
||||
return UnknownVal();
|
||||
|
||||
// Actually perform the operation.
|
||||
// EvalBinOpNN expects the two indexes to already be the right type.
|
||||
return EvalBinOpNN(state, op, *LeftIndex, *RightIndex, resultTy);
|
||||
// evalBinOpNN expects the two indexes to already be the right type.
|
||||
return evalBinOpNN(state, op, *LeftIndex, *RightIndex, resultTy);
|
||||
}
|
||||
|
||||
// If the element indexes aren't comparable, see if the raw offsets are.
|
||||
|
@ -812,7 +812,7 @@ SVal SimpleSValBuilder::EvalBinOpLL(const GRState *state,
|
|||
}
|
||||
}
|
||||
|
||||
SVal SimpleSValBuilder::EvalBinOpLN(const GRState *state,
|
||||
SVal SimpleSValBuilder::evalBinOpLN(const GRState *state,
|
||||
BinaryOperator::Opcode op,
|
||||
Loc lhs, NonLoc rhs, QualType resultTy) {
|
||||
// Special case: 'rhs' is an integer that has the same width as a pointer and
|
||||
|
@ -829,7 +829,7 @@ SVal SimpleSValBuilder::EvalBinOpLN(const GRState *state,
|
|||
if (x->isSigned())
|
||||
x = &ValMgr.getBasicValueFactory().getValue(*x, true);
|
||||
|
||||
return EvalBinOpLL(state, op, lhs, loc::ConcreteInt(*x), resultTy);
|
||||
return evalBinOpLL(state, op, lhs, loc::ConcreteInt(*x), resultTy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -868,7 +868,7 @@ SVal SimpleSValBuilder::EvalBinOpLN(const GRState *state,
|
|||
|
||||
|
||||
// Delegate remaining pointer arithmetic to the StoreManager.
|
||||
return state->getStateManager().getStoreManager().EvalBinOp(op, lhs,
|
||||
return state->getStateManager().getStoreManager().evalBinOp(op, lhs,
|
||||
rhs, resultTy);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ public:
|
|||
return &x;
|
||||
}
|
||||
void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *RS);
|
||||
void EvalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng);
|
||||
void evalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng);
|
||||
private:
|
||||
void EmitStackError(CheckerContext &C, const MemRegion *R, const Expr *RetE);
|
||||
SourceRange GenName(llvm::raw_ostream &os, const MemRegion *R,
|
||||
|
@ -129,7 +129,7 @@ void StackAddrLeakChecker::PreVisitReturnStmt(CheckerContext &C,
|
|||
}
|
||||
}
|
||||
|
||||
void StackAddrLeakChecker::EvalEndPath(GREndPathNodeBuilder &B, void *tag,
|
||||
void StackAddrLeakChecker::evalEndPath(GREndPathNodeBuilder &B, void *tag,
|
||||
GRExprEngine &Eng) {
|
||||
SaveAndRestore<bool> OldHasGen(B.HasGeneratedNode);
|
||||
const GRState *state = B.getState();
|
||||
|
|
|
@ -225,9 +225,9 @@ SVal StoreManager::CastRetrievedVal(SVal V, const TypedRegion *R,
|
|||
}
|
||||
|
||||
if (const Loc *L = dyn_cast<Loc>(&V))
|
||||
return ValMgr.getSValBuilder().EvalCastL(*L, castTy);
|
||||
return ValMgr.getSValBuilder().evalCastL(*L, castTy);
|
||||
else if (const NonLoc *NL = dyn_cast<NonLoc>(&V))
|
||||
return ValMgr.getSValBuilder().EvalCastNL(*NL, castTy);
|
||||
return ValMgr.getSValBuilder().evalCastNL(*NL, castTy);
|
||||
|
||||
return V;
|
||||
}
|
||||
|
|
|
@ -72,9 +72,9 @@ public:
|
|||
return &x;
|
||||
}
|
||||
|
||||
virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
|
||||
void EvalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper);
|
||||
void EvalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng);
|
||||
virtual bool evalCallExpr(CheckerContext &C, const CallExpr *CE);
|
||||
void evalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper);
|
||||
void evalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng);
|
||||
void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *S);
|
||||
|
||||
private:
|
||||
|
@ -115,7 +115,7 @@ void clang::RegisterStreamChecker(GRExprEngine &Eng) {
|
|||
Eng.registerCheck(new StreamChecker());
|
||||
}
|
||||
|
||||
bool StreamChecker::EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
|
||||
bool StreamChecker::evalCallExpr(CheckerContext &C, const CallExpr *CE) {
|
||||
const GRState *state = C.getState();
|
||||
const Expr *Callee = CE->getCallee();
|
||||
SVal L = state->getSVal(Callee);
|
||||
|
@ -395,7 +395,7 @@ const GRState *StreamChecker::CheckDoubleClose(const CallExpr *CE,
|
|||
return state->set<StreamState>(Sym, StreamState::getClosed(CE));
|
||||
}
|
||||
|
||||
void StreamChecker::EvalDeadSymbols(CheckerContext &C,SymbolReaper &SymReaper) {
|
||||
void StreamChecker::evalDeadSymbols(CheckerContext &C,SymbolReaper &SymReaper) {
|
||||
for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
|
||||
E = SymReaper.dead_end(); I != E; ++I) {
|
||||
SymbolRef Sym = *I;
|
||||
|
@ -418,7 +418,7 @@ void StreamChecker::EvalDeadSymbols(CheckerContext &C,SymbolReaper &SymReaper) {
|
|||
}
|
||||
}
|
||||
|
||||
void StreamChecker::EvalEndPath(GREndPathNodeBuilder &B, void *tag,
|
||||
void StreamChecker::evalEndPath(GREndPathNodeBuilder &B, void *tag,
|
||||
GRExprEngine &Eng) {
|
||||
SaveAndRestore<bool> OldHasGen(B.HasGeneratedNode);
|
||||
const GRState *state = B.getState();
|
||||
|
|
|
@ -101,7 +101,7 @@ static void CheckOpen(CheckerContext &C, UnixAPIChecker &UC,
|
|||
NonLoc ocreateFlag =
|
||||
cast<NonLoc>(C.getValueManager().makeIntVal(UC.Val_O_CREAT.getValue(),
|
||||
oflagsEx->getType()));
|
||||
SVal maskedFlagsUC = C.getSValBuilder().EvalBinOpNN(state, BO_And,
|
||||
SVal maskedFlagsUC = C.getSValBuilder().evalBinOpNN(state, BO_And,
|
||||
oflags, ocreateFlag,
|
||||
oflagsEx->getType());
|
||||
if (maskedFlagsUC.isUnknownOrUndef())
|
||||
|
|
|
@ -110,21 +110,21 @@ void VLASizeChecker::PreVisitDeclStmt(CheckerContext &C, const DeclStmt *DS) {
|
|||
ValueManager &ValMgr = C.getValueManager();
|
||||
SValBuilder &SV = ValMgr.getSValBuilder();
|
||||
QualType SizeTy = Ctx.getSizeType();
|
||||
NonLoc ArrayLength = cast<NonLoc>(SV.EvalCast(sizeD, SizeTy, SE->getType()));
|
||||
NonLoc ArrayLength = cast<NonLoc>(SV.evalCast(sizeD, SizeTy, SE->getType()));
|
||||
|
||||
// Get the element size.
|
||||
CharUnits EleSize = Ctx.getTypeSizeInChars(VLA->getElementType());
|
||||
SVal EleSizeVal = ValMgr.makeIntVal(EleSize.getQuantity(), SizeTy);
|
||||
|
||||
// Multiply the array length by the element size.
|
||||
SVal ArraySizeVal = SV.EvalBinOpNN(state, BO_Mul, ArrayLength,
|
||||
SVal ArraySizeVal = SV.evalBinOpNN(state, BO_Mul, ArrayLength,
|
||||
cast<NonLoc>(EleSizeVal), SizeTy);
|
||||
|
||||
// Finally, Assume that the array's extent matches the given size.
|
||||
const LocationContext *LC = C.getPredecessor()->getLocationContext();
|
||||
DefinedOrUnknownSVal Extent = state->getRegion(VD, LC)->getExtent(ValMgr);
|
||||
DefinedOrUnknownSVal ArraySize = cast<DefinedOrUnknownSVal>(ArraySizeVal);
|
||||
DefinedOrUnknownSVal SizeIsKnown = SV.EvalEQ(state, Extent, ArraySize);
|
||||
DefinedOrUnknownSVal SizeIsKnown = SV.evalEQ(state, Extent, ArraySize);
|
||||
state = state->Assume(SizeIsKnown, true);
|
||||
|
||||
// Assume should not fail at this point.
|
||||
|
|
|
@ -67,7 +67,7 @@ SVal ValueManager::convertToArrayIndex(SVal V) {
|
|||
return V;
|
||||
}
|
||||
|
||||
return svalBuilder->EvalCastNL(cast<NonLoc>(V), ArrayIndexTy);
|
||||
return svalBuilder->evalCastNL(cast<NonLoc>(V), ArrayIndexTy);
|
||||
}
|
||||
|
||||
DefinedOrUnknownSVal
|
||||
|
|
Loading…
Reference in New Issue