Rename all 'EvalXXX' methods in libChecker to

'evalXXX'.

llvm-svn: 120609
This commit is contained in:
Ted Kremenek 2010-12-01 21:57:22 +00:00
parent 87240d4b9c
commit dc891429e4
31 changed files with 342 additions and 342 deletions

View File

@ -179,7 +179,7 @@ public:
return SValListFactory.add(X, L); 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& V1,
const llvm::APSInt& V2); const llvm::APSInt& V2);

View File

@ -207,20 +207,20 @@ private:
_PostVisit(C, S); _PostVisit(C, S);
} }
bool GR_EvalNilReceiver(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder, bool GR_evalNilReceiver(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
GRExprEngine &Eng, const ObjCMessageExpr *ME, GRExprEngine &Eng, const ObjCMessageExpr *ME,
ExplodedNode *Pred, const GRState *state, void *tag) { ExplodedNode *Pred, const GRState *state, void *tag) {
CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind, CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
0, ME, state); 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, GRExprEngine &Eng, const CallExpr *CE,
ExplodedNode *Pred, void *tag) { ExplodedNode *Pred, void *tag) {
CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind, CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
0, CE); 0, CE);
return EvalCallExpr(C, CE); return evalCallExpr(C, CE);
} }
// FIXME: Remove the 'tag' option. // FIXME: Remove the 'tag' option.
@ -250,12 +250,12 @@ private:
VisitLocation(C, S, location); 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, GRExprEngine &Eng, const Stmt *S, ExplodedNode *Pred,
SymbolReaper &SymReaper, void *tag) { SymbolReaper &SymReaper, void *tag) {
CheckerContext C(Dst, Builder, Eng, Pred, tag, CheckerContext C(Dst, Builder, Eng, Pred, tag,
ProgramPoint::PostPurgeDeadSymbolsKind, 0, S); ProgramPoint::PostPurgeDeadSymbolsKind, 0, S);
EvalDeadSymbols(C, SymReaper); evalDeadSymbols(C, SymReaper);
} }
public: public:
@ -265,8 +265,8 @@ public:
virtual void VisitLocation(CheckerContext &C, const Stmt *S, SVal location) {} virtual void VisitLocation(CheckerContext &C, const Stmt *S, SVal location) {}
virtual void PreVisitBind(CheckerContext &C, const Stmt *StoreE, virtual void PreVisitBind(CheckerContext &C, const Stmt *StoreE,
SVal location, SVal val) {} SVal location, SVal val) {}
virtual void EvalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper) {} virtual void evalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper) {}
virtual void EvalEndPath(GREndPathNodeBuilder &B, void *tag, virtual void evalEndPath(GREndPathNodeBuilder &B, void *tag,
GRExprEngine &Eng) {} GRExprEngine &Eng) {}
virtual void MarkLiveSymbols(const GRState *state, SymbolReaper &SymReaper) {} virtual void MarkLiveSymbols(const GRState *state, SymbolReaper &SymReaper) {}
@ -275,15 +275,15 @@ public:
GRExprEngine &Eng, GRExprEngine &Eng,
const Stmt *Condition, void *tag) {} const Stmt *Condition, void *tag) {}
virtual bool EvalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME) { virtual bool evalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME) {
return false; return false;
} }
virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE) { virtual bool evalCallExpr(CheckerContext &C, const CallExpr *CE) {
return false; return false;
} }
virtual const GRState *EvalAssume(const GRState *state, SVal Cond, virtual const GRState *evalAssume(const GRState *state, SVal Cond,
bool Assumption, bool *respondsToCallback) { bool Assumption, bool *respondsToCallback) {
*respondsToCallback = false; *respondsToCallback = false;
return state; return state;

View File

@ -224,7 +224,7 @@ public:
/// Called by GRCoreEngine when the analysis worklist has terminated. /// Called by GRCoreEngine when the analysis worklist has terminated.
void ProcessEndWorklist(bool hasWorkRemaining); 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. /// making assumptions about state values.
const GRState *ProcessAssume(const GRState *state, SVal cond,bool assumption); const GRState *ProcessAssume(const GRState *state, SVal cond,bool assumption);
@ -303,7 +303,7 @@ public:
/// other functions that handle specific kinds of statements. /// other functions that handle specific kinds of statements.
void Visit(const Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst); 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 /// a DeclRefExpr, it evaluates to the MemRegionVal which represents its
/// storage location. Note that not all kinds of expressions has lvalue. /// storage location. Note that not all kinds of expressions has lvalue.
void VisitLValue(const Expr* Ex, ExplodedNode* Pred, ExplodedNodeSet& Dst); void VisitLValue(const Expr* Ex, ExplodedNode* Pred, ExplodedNodeSet& Dst);
@ -466,61 +466,61 @@ public:
const StackFrameContext *frameCtx); const StackFrameContext *frameCtx);
/// Evaluate arguments with a work list algorithm. /// Evaluate arguments with a work list algorithm.
void EvalArguments(ConstExprIterator AI, ConstExprIterator AE, void evalArguments(ConstExprIterator AI, ConstExprIterator AE,
const FunctionProtoType *FnType, const FunctionProtoType *FnType,
ExplodedNode *Pred, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExplodedNodeSet &Dst,
bool FstArgAsLValue = false); bool FstArgAsLValue = false);
/// Evaluate method call itself. Used for CXXMethodCallExpr and /// Evaluate method call itself. Used for CXXMethodCallExpr and
/// CXXOperatorCallExpr. /// CXXOperatorCallExpr.
void EvalMethodCall(const CallExpr *MCE, const CXXMethodDecl *MD, void evalMethodCall(const CallExpr *MCE, const CXXMethodDecl *MD,
const Expr *ThisExpr, ExplodedNode *Pred, const Expr *ThisExpr, ExplodedNode *Pred,
ExplodedNodeSet &Src, ExplodedNodeSet &Dst); 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) /// expressions of the form 'x != 0' and generate new nodes (stored in Dst)
/// with those assumptions. /// with those assumptions.
void EvalEagerlyAssume(ExplodedNodeSet& Dst, ExplodedNodeSet& Src, void evalEagerlyAssume(ExplodedNodeSet& Dst, ExplodedNodeSet& Src,
const Expr *Ex); const Expr *Ex);
SVal EvalMinus(SVal X) { SVal evalMinus(SVal X) {
return X.isValid() ? svalBuilder.EvalMinus(cast<NonLoc>(X)) : X; return X.isValid() ? svalBuilder.evalMinus(cast<NonLoc>(X)) : X;
} }
SVal EvalComplement(SVal X) { SVal evalComplement(SVal X) {
return X.isValid() ? svalBuilder.EvalComplement(cast<NonLoc>(X)) : X; return X.isValid() ? svalBuilder.evalComplement(cast<NonLoc>(X)) : X;
} }
public: public:
SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op, SVal evalBinOp(const GRState *state, BinaryOperator::Opcode op,
NonLoc L, NonLoc R, QualType T) { 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) { 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) { SVal LHS, SVal RHS, QualType T) {
return svalBuilder.EvalBinOp(ST, Op, LHS, RHS, T); return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T);
} }
protected: protected:
void EvalObjCMessageExpr(ExplodedNodeSet& Dst, const ObjCMessageExpr* ME, void evalObjCMessageExpr(ExplodedNodeSet& Dst, const ObjCMessageExpr* ME,
ExplodedNode* Pred, const GRState *state) { ExplodedNode* Pred, const GRState *state) {
assert (Builder && "GRStmtNodeBuilder must be defined."); 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, const GRState* MarkBranch(const GRState* St, const Stmt* Terminator,
bool branchTaken); bool branchTaken);
/// EvalBind - Handle the semantics of binding a value to a specific location. /// evalBind - Handle the semantics of binding a value to a specific location.
/// This method is used by EvalStore, VisitDeclStmt, and others. /// This method is used by evalStore, VisitDeclStmt, and others.
void EvalBind(ExplodedNodeSet& Dst, const Stmt* StoreE, ExplodedNode* Pred, void evalBind(ExplodedNodeSet& Dst, const Stmt* StoreE, ExplodedNode* Pred,
const GRState* St, SVal location, SVal Val, const GRState* St, SVal location, SVal Val,
bool atDeclInit = false); bool atDeclInit = false);
@ -531,23 +531,23 @@ public:
// be the same as Pred->state, and when 'location' may not be the // be the same as Pred->state, and when 'location' may not be the
// same as state->getLValue(Ex). // same as state->getLValue(Ex).
/// Simulate a read of the result of 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, const GRState* St, SVal location, const void *tag = 0,
QualType LoadTy = QualType()); QualType LoadTy = QualType());
// FIXME: 'tag' should be removed, and a LocationContext should be used // FIXME: 'tag' should be removed, and a LocationContext should be used
// instead. // 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, ExplodedNode* Pred, const GRState* St, SVal TargetLV, SVal Val,
const void *tag = 0); const void *tag = 0);
private: 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, const GRState* St, SVal location, const void *tag,
QualType LoadTy); QualType LoadTy);
// FIXME: 'tag' should be removed, and a LocationContext should be used // FIXME: 'tag' should be removed, and a LocationContext should be used
// instead. // 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 GRState* St, SVal location,
const void *tag, bool isLoad); const void *tag, bool isLoad);

View File

@ -39,13 +39,13 @@ public:
// Calls. // Calls.
virtual void EvalCall(ExplodedNodeSet& Dst, virtual void evalCall(ExplodedNodeSet& Dst,
GRExprEngine& Engine, GRExprEngine& Engine,
GRStmtNodeBuilder& Builder, GRStmtNodeBuilder& Builder,
const CallExpr* CE, SVal L, const CallExpr* CE, SVal L,
ExplodedNode* Pred) {} ExplodedNode* Pred) {}
virtual void EvalObjCMessageExpr(ExplodedNodeSet& Dst, virtual void evalObjCMessageExpr(ExplodedNodeSet& Dst,
GRExprEngine& Engine, GRExprEngine& Engine,
GRStmtNodeBuilder& Builder, GRStmtNodeBuilder& Builder,
const ObjCMessageExpr* ME, const ObjCMessageExpr* ME,
@ -54,15 +54,15 @@ public:
// Stores. // 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. // End-of-path and dead symbol notification.
virtual void EvalEndPath(GRExprEngine& Engine, virtual void evalEndPath(GRExprEngine& Engine,
GREndPathNodeBuilder& Builder) {} GREndPathNodeBuilder& Builder) {}
virtual void EvalDeadSymbols(ExplodedNodeSet& Dst, virtual void evalDeadSymbols(ExplodedNodeSet& Dst,
GRExprEngine& Engine, GRExprEngine& Engine,
GRStmtNodeBuilder& Builder, GRStmtNodeBuilder& Builder,
ExplodedNode* Pred, ExplodedNode* Pred,
@ -70,14 +70,14 @@ public:
SymbolReaper& SymReaper) {} SymbolReaper& SymReaper) {}
// Return statements. // Return statements.
virtual void EvalReturn(ExplodedNodeSet& Dst, virtual void evalReturn(ExplodedNodeSet& Dst,
GRExprEngine& Engine, GRExprEngine& Engine,
GRStmtNodeBuilder& Builder, GRStmtNodeBuilder& Builder,
const ReturnStmt* S, const ReturnStmt* S,
ExplodedNode* Pred) {} ExplodedNode* Pred) {}
// Assumptions. // Assumptions.
virtual const GRState* EvalAssume(const GRState *state, virtual const GRState* evalAssume(const GRState *state,
SVal Cond, bool Assumption) { SVal Cond, bool Assumption) {
return state; return state;
} }

View File

@ -31,36 +31,36 @@ protected:
public: public:
// FIXME: Make these protected again one RegionStoreManager correctly // FIXME: Make these protected again one RegionStoreManager correctly
// handles loads from differening bound value types. // handles loads from differening bound value types.
virtual SVal EvalCastNL(NonLoc val, QualType castTy) = 0; virtual SVal evalCastNL(NonLoc val, QualType castTy) = 0;
virtual SVal EvalCastL(Loc val, QualType castTy) = 0; virtual SVal evalCastL(Loc val, QualType castTy) = 0;
public: public:
SValBuilder(ValueManager &valMgr) : ValMgr(valMgr) {} SValBuilder(ValueManager &valMgr) : ValMgr(valMgr) {}
virtual ~SValBuilder() {} 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; 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; 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; 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. /// (integer) value, that value is returned. Otherwise, returns NULL.
virtual const llvm::APSInt *getKnownValue(const GRState *state, SVal V) = 0; 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); SVal L, SVal R, QualType T);
DefinedOrUnknownSVal EvalEQ(const GRState *ST, DefinedOrUnknownSVal L, DefinedOrUnknownSVal evalEQ(const GRState *ST, DefinedOrUnknownSVal L,
DefinedOrUnknownSVal R); DefinedOrUnknownSVal R);
}; };

View File

@ -489,7 +489,7 @@ public:
} }
// Transfer functions for binary/unary operations on ConcreteInts. // 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; const ConcreteInt& R) const;
// Implement isa<T> support. // Implement isa<T> support.

View File

@ -152,8 +152,8 @@ public:
const MemRegion *CastRegion(const MemRegion *region, QualType CastToTy); const MemRegion *CastRegion(const MemRegion *region, QualType CastToTy);
/// EvalBinOp - Perform pointer arithmetic. /// evalBinOp - Perform pointer arithmetic.
virtual SVal EvalBinOp(BinaryOperator::Opcode Op, virtual SVal evalBinOp(BinaryOperator::Opcode Op,
Loc lhs, NonLoc rhs, QualType resultTy) { Loc lhs, NonLoc rhs, QualType resultTy) {
return UnknownVal(); return UnknownVal();
} }

View File

@ -458,7 +458,7 @@ public:
/// isDead - Returns whether or not a symbol has been confirmed dead. This /// isDead - Returns whether or not a symbol has been confirmed dead. This
/// should only be called once all marking of dead symbols has completed. /// 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 { bool isDead(SymbolRef sym) const {
return TheDead.count(sym); return TheDead.count(sym);
} }

View File

@ -89,7 +89,7 @@ void AdjustedReturnValueChecker::PostVisitCallExpr(CheckerContext &C,
// FIXME: Do more checking and actual emit an error. At least performing // FIXME: Do more checking and actual emit an error. At least performing
// the cast avoids some assertion failures elsewhere. // the cast avoids some assertion failures elsewhere.
SValBuilder &svalBuilder = C.getSValBuilder(); SValBuilder &svalBuilder = C.getSValBuilder();
V = svalBuilder.EvalCast(V, expectedResultTy, actualResultTy); V = svalBuilder.evalCast(V, expectedResultTy, actualResultTy);
C.GenerateNode(state->BindExpr(CE, V)); C.GenerateNode(state->BindExpr(CE, V));
} }
} }

View File

@ -414,7 +414,7 @@ void CFRetainReleaseChecker::PreVisitCallExpr(CheckerContext& C,
// Make an expression asserting that they're equal. // Make an expression asserting that they're equal.
SValBuilder &svalBuilder = ValMgr.getSValBuilder(); SValBuilder &svalBuilder = ValMgr.getSValBuilder();
DefinedOrUnknownSVal ArgIsNull = svalBuilder.EvalEQ(state, Zero, *DefArgVal); DefinedOrUnknownSVal ArgIsNull = svalBuilder.evalEQ(state, Zero, *DefArgVal);
// Are they equal? // Are they equal?
const GRState *stateTrue, *stateFalse; const GRState *stateTrue, *stateFalse;

View File

@ -142,7 +142,7 @@ BasicValueFactory::getLazyCompoundValData(const void *store,
} }
const llvm::APSInt* const llvm::APSInt*
BasicValueFactory::EvaluateAPSInt(BinaryOperator::Opcode Op, BasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op,
const llvm::APSInt& V1, const llvm::APSInt& V2) { const llvm::APSInt& V1, const llvm::APSInt& V2) {
switch (Op) { switch (Op) {

View File

@ -22,7 +22,7 @@ namespace {
class BuiltinFunctionChecker : public Checker { class BuiltinFunctionChecker : public Checker {
public: public:
static void *getTag() { static int tag = 0; return &tag; } 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()); 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 GRState *state = C.getState();
const Expr *Callee = CE->getCallee(); const Expr *Callee = CE->getCallee();
SVal L = state->getSVal(Callee); SVal L = state->getSVal(Callee);
@ -72,7 +72,7 @@ bool BuiltinFunctionChecker::EvalCallExpr(CheckerContext &C,const CallExpr *CE){
SValBuilder& svalBuilder = ValMgr.getSValBuilder(); SValBuilder& svalBuilder = ValMgr.getSValBuilder();
DefinedOrUnknownSVal ExtentMatchesSizeArg = DefinedOrUnknownSVal ExtentMatchesSizeArg =
svalBuilder.EvalEQ(state, Extent, Size); svalBuilder.evalEQ(state, Extent, Size);
state = state->Assume(ExtentMatchesSizeArg, true); state = state->Assume(ExtentMatchesSizeArg, true);
C.GenerateNode(state->BindExpr(CE, loc::MemRegionVal(R))); C.GenerateNode(state->BindExpr(CE, loc::MemRegionVal(R)));

View File

@ -1710,7 +1710,7 @@ public:
// Calls. // Calls.
void EvalSummary(ExplodedNodeSet& Dst, void evalSummary(ExplodedNodeSet& Dst,
GRExprEngine& Eng, GRExprEngine& Eng,
GRStmtNodeBuilder& Builder, GRStmtNodeBuilder& Builder,
const Expr* Ex, const Expr* Ex,
@ -1720,28 +1720,28 @@ public:
ConstExprIterator arg_beg, ConstExprIterator arg_end, ConstExprIterator arg_beg, ConstExprIterator arg_end,
ExplodedNode* Pred, const GRState *state); ExplodedNode* Pred, const GRState *state);
virtual void EvalCall(ExplodedNodeSet& Dst, virtual void evalCall(ExplodedNodeSet& Dst,
GRExprEngine& Eng, GRExprEngine& Eng,
GRStmtNodeBuilder& Builder, GRStmtNodeBuilder& Builder,
const CallExpr* CE, SVal L, const CallExpr* CE, SVal L,
ExplodedNode* Pred); ExplodedNode* Pred);
virtual void EvalObjCMessageExpr(ExplodedNodeSet& Dst, virtual void evalObjCMessageExpr(ExplodedNodeSet& Dst,
GRExprEngine& Engine, GRExprEngine& Engine,
GRStmtNodeBuilder& Builder, GRStmtNodeBuilder& Builder,
const ObjCMessageExpr* ME, const ObjCMessageExpr* ME,
ExplodedNode* Pred, ExplodedNode* Pred,
const GRState *state); const GRState *state);
// Stores. // Stores.
virtual void EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val); virtual void evalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val);
// End-of-path. // End-of-path.
virtual void EvalEndPath(GRExprEngine& Engine, virtual void evalEndPath(GRExprEngine& Engine,
GREndPathNodeBuilder& Builder); GREndPathNodeBuilder& Builder);
virtual void EvalDeadSymbols(ExplodedNodeSet& Dst, virtual void evalDeadSymbols(ExplodedNodeSet& Dst,
GRExprEngine& Engine, GRExprEngine& Engine,
GRStmtNodeBuilder& Builder, GRStmtNodeBuilder& Builder,
ExplodedNode* Pred, ExplodedNode* Pred,
@ -1754,7 +1754,7 @@ public:
SymbolRef Sym, RefVal V, bool &stop); SymbolRef Sym, RefVal V, bool &stop);
// Return statements. // Return statements.
virtual void EvalReturn(ExplodedNodeSet& Dst, virtual void evalReturn(ExplodedNodeSet& Dst,
GRExprEngine& Engine, GRExprEngine& Engine,
GRStmtNodeBuilder& Builder, GRStmtNodeBuilder& Builder,
const ReturnStmt* S, const ReturnStmt* S,
@ -1762,7 +1762,7 @@ public:
// Assumptions. // Assumptions.
virtual const GRState *EvalAssume(const GRState* state, SVal condition, virtual const GRState *evalAssume(const GRState* state, SVal condition,
bool assumption); bool assumption);
}; };
@ -2494,7 +2494,7 @@ static QualType GetReturnType(const Expr* RetE, ASTContext& Ctx) {
return RetTy; return RetTy;
} }
void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, void CFRefCount::evalSummary(ExplodedNodeSet& Dst,
GRExprEngine& Eng, GRExprEngine& Eng,
GRStmtNodeBuilder& Builder, GRStmtNodeBuilder& Builder,
const Expr* Ex, const Expr* Ex,
@ -2756,7 +2756,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
} }
void CFRefCount::EvalCall(ExplodedNodeSet& Dst, void CFRefCount::evalCall(ExplodedNodeSet& Dst,
GRExprEngine& Eng, GRExprEngine& Eng,
GRStmtNodeBuilder& Builder, GRStmtNodeBuilder& Builder,
const CallExpr* CE, SVal L, const CallExpr* CE, SVal L,
@ -2777,11 +2777,11 @@ void CFRefCount::EvalCall(ExplodedNodeSet& Dst,
} }
assert(Summ); 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)); CE->arg_begin(), CE->arg_end(), Pred, Builder.GetState(Pred));
} }
void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet& Dst, void CFRefCount::evalObjCMessageExpr(ExplodedNodeSet& Dst,
GRExprEngine& Eng, GRExprEngine& Eng,
GRStmtNodeBuilder& Builder, GRStmtNodeBuilder& Builder,
const ObjCMessageExpr* ME, const ObjCMessageExpr* ME,
@ -2793,7 +2793,7 @@ void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet& Dst,
: Summaries.getClassMethodSummary(ME); : Summaries.getClassMethodSummary(ME);
assert(Summ && "RetainSummary is null"); assert(Summ && "RetainSummary is null");
EvalSummary(Dst, Eng, Builder, ME, evalSummary(Dst, Eng, Builder, ME,
InstanceReceiver(ME, Pred->getLocationContext()), *Summ, NULL, InstanceReceiver(ME, Pred->getLocationContext()), *Summ, NULL,
ME->arg_begin(), ME->arg_end(), Pred, state); ME->arg_begin(), ME->arg_end(), Pred, state);
} }
@ -2813,7 +2813,7 @@ public:
} // end anonymous namespace } // 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"? // Are we storing to something that causes the value to "escape"?
bool escapes = false; bool escapes = false;
@ -2852,7 +2852,7 @@ void CFRefCount::EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) {
// Return statements. // Return statements.
void CFRefCount::EvalReturn(ExplodedNodeSet& Dst, void CFRefCount::evalReturn(ExplodedNodeSet& Dst,
GRExprEngine& Eng, GRExprEngine& Eng,
GRStmtNodeBuilder& Builder, GRStmtNodeBuilder& Builder,
const ReturnStmt* S, const ReturnStmt* S,
@ -2994,14 +2994,14 @@ void CFRefCount::EvalReturn(ExplodedNodeSet& Dst,
// Assumptions. // Assumptions.
const GRState* CFRefCount::EvalAssume(const GRState *state, const GRState* CFRefCount::evalAssume(const GRState *state,
SVal Cond, bool Assumption) { 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 // 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 // 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 // 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. // other places.
RefBindings B = state->get<RefBindings>(); RefBindings B = state->get<RefBindings>();
@ -3270,7 +3270,7 @@ CFRefCount::ProcessLeaks(const GRState * state,
return N; return N;
} }
void CFRefCount::EvalEndPath(GRExprEngine& Eng, void CFRefCount::evalEndPath(GRExprEngine& Eng,
GREndPathNodeBuilder& Builder) { GREndPathNodeBuilder& Builder) {
const GRState *state = Builder.getState(); const GRState *state = Builder.getState();
@ -3297,7 +3297,7 @@ void CFRefCount::EvalEndPath(GRExprEngine& Eng,
ProcessLeaks(state, Leaked, Bd, Eng, Pred); ProcessLeaks(state, Leaked, Bd, Eng, Pred);
} }
void CFRefCount::EvalDeadSymbols(ExplodedNodeSet& Dst, void CFRefCount::evalDeadSymbols(ExplodedNodeSet& Dst,
GRExprEngine& Eng, GRExprEngine& Eng,
GRStmtNodeBuilder& Builder, GRStmtNodeBuilder& Builder,
ExplodedNode* Pred, ExplodedNode* Pred,

View File

@ -29,10 +29,10 @@ public:
{} {}
static void *getTag() { static int tag; return &tag; } 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 PreVisitDeclStmt(CheckerContext &C, const DeclStmt *DS);
void MarkLiveSymbols(const GRState *state, SymbolReaper &SR); void MarkLiveSymbols(const GRState *state, SymbolReaper &SR);
void EvalDeadSymbols(CheckerContext &C, SymbolReaper &SR); void evalDeadSymbols(CheckerContext &C, SymbolReaper &SR);
bool WantsRegionChangeUpdate(const GRState *state); bool WantsRegionChangeUpdate(const GRState *state);
const GRState *EvalRegionChanges(const GRState *state, const GRState *EvalRegionChanges(const GRState *state,
@ -42,20 +42,20 @@ public:
typedef void (CStringChecker::*FnCheck)(CheckerContext &, const CallExpr *); typedef void (CStringChecker::*FnCheck)(CheckerContext &, const CallExpr *);
void EvalMemcpy(CheckerContext &C, const CallExpr *CE); void evalMemcpy(CheckerContext &C, const CallExpr *CE);
void EvalMemmove(CheckerContext &C, const CallExpr *CE); void evalMemmove(CheckerContext &C, const CallExpr *CE);
void EvalBcopy(CheckerContext &C, const CallExpr *CE); void evalBcopy(CheckerContext &C, const CallExpr *CE);
void EvalCopyCommon(CheckerContext &C, const GRState *state, void evalCopyCommon(CheckerContext &C, const GRState *state,
const Expr *Size, const Expr *Source, const Expr *Dest, const Expr *Size, const Expr *Source, const Expr *Dest,
bool Restricted = false); 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 evalStrcpy(CheckerContext &C, const CallExpr *CE);
void EvalStpcpy(CheckerContext &C, const CallExpr *CE); void evalStpcpy(CheckerContext &C, const CallExpr *CE);
void EvalStrcpyCommon(CheckerContext &C, const CallExpr *CE, bool ReturnEnd); void evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, bool ReturnEnd);
// Utility methods // Utility methods
std::pair<const GRState*, const GRState*> std::pair<const GRState*, const GRState*>
@ -125,7 +125,7 @@ CStringChecker::AssumeZero(CheckerContext &C, const GRState *state, SVal V,
SValBuilder &SV = ValMgr.getSValBuilder(); SValBuilder &SV = ValMgr.getSValBuilder();
DefinedOrUnknownSVal Zero = ValMgr.makeZeroVal(Ty); DefinedOrUnknownSVal Zero = ValMgr.makeZeroVal(Ty);
DefinedOrUnknownSVal ValIsZero = SV.EvalEQ(state, *Val, Zero); DefinedOrUnknownSVal ValIsZero = SV.evalEQ(state, *Val, Zero);
return state->Assume(ValIsZero); 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. // Compute the offset of the last element to be accessed: size-1.
NonLoc One = cast<NonLoc>(VM.makeIntVal(1, SizeTy)); 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)); *Length, One, SizeTy));
// Check that the first buffer is sufficently long. // 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)) { 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); LastOffset, PtrTy);
state = CheckLocation(C, state, FirstBuf, BufEnd, FirstIsDestination); state = CheckLocation(C, state, FirstBuf, BufEnd, FirstIsDestination);
@ -287,9 +287,9 @@ const GRState *CStringChecker::CheckBufferAccess(CheckerContext &C,
if (!state) if (!state)
return NULL; return NULL;
BufStart = SV.EvalCast(BufVal, PtrTy, SecondBuf->getType()); BufStart = SV.evalCast(BufVal, PtrTy, SecondBuf->getType());
if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) { 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); LastOffset, PtrTy);
state = CheckLocation(C, state, SecondBuf, BufEnd); state = CheckLocation(C, state, SecondBuf, BufEnd);
} }
@ -330,7 +330,7 @@ const GRState *CStringChecker::CheckOverlap(CheckerContext &C,
return state; return state;
// Are the two values the same? // 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); llvm::tie(stateTrue, stateFalse) = state->Assume(EqualTest);
if (stateTrue && !stateFalse) { if (stateTrue && !stateFalse) {
@ -345,7 +345,7 @@ const GRState *CStringChecker::CheckOverlap(CheckerContext &C,
// Which value comes first? // Which value comes first?
QualType CmpTy = Ctx.IntTy; QualType CmpTy = Ctx.IntTy;
SVal Reverse = SV.EvalBinOpLL(state, BO_GT, SVal Reverse = SV.evalBinOpLL(state, BO_GT,
*FirstLoc, *SecondLoc, CmpTy); *FirstLoc, *SecondLoc, CmpTy);
DefinedOrUnknownSVal *ReverseTest = dyn_cast<DefinedOrUnknownSVal>(&Reverse); DefinedOrUnknownSVal *ReverseTest = dyn_cast<DefinedOrUnknownSVal>(&Reverse);
if (!ReverseTest) if (!ReverseTest)
@ -379,20 +379,20 @@ const GRState *CStringChecker::CheckOverlap(CheckerContext &C,
// Convert the first buffer's start address to char*. // Convert the first buffer's start address to char*.
// Bail out if the cast fails. // Bail out if the cast fails.
QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy); 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); Loc *FirstStartLoc = dyn_cast<Loc>(&FirstStart);
if (!FirstStartLoc) if (!FirstStartLoc)
return state; return state;
// Compute the end of the first buffer. Bail out if THAT fails. // 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); *FirstStartLoc, *Length, CharPtrTy);
Loc *FirstEndLoc = dyn_cast<Loc>(&FirstEnd); Loc *FirstEndLoc = dyn_cast<Loc>(&FirstEnd);
if (!FirstEndLoc) if (!FirstEndLoc)
return state; return state;
// Is the end of the first buffer past the start of the second buffer? // 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); *FirstEndLoc, *SecondLoc, CmpTy);
DefinedOrUnknownSVal *OverlapTest = dyn_cast<DefinedOrUnknownSVal>(&Overlap); DefinedOrUnknownSVal *OverlapTest = dyn_cast<DefinedOrUnknownSVal>(&Overlap);
if (!OverlapTest) 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 *Size, const Expr *Dest,
const Expr *Source, bool Restricted) { const Expr *Source, bool Restricted) {
// See if the size argument is zero. // 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); // void *memcpy(void *restrict dst, const void *restrict src, size_t n);
// The return value is the address of the destination buffer. // The return value is the address of the destination buffer.
const Expr *Dest = CE->getArg(0); const Expr *Dest = CE->getArg(0);
const GRState *state = C.getState(); const GRState *state = C.getState();
state = state->BindExpr(CE, state->getSVal(Dest)); 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); // void *memmove(void *dst, const void *src, size_t n);
// The return value is the address of the destination buffer. // The return value is the address of the destination buffer.
const Expr *Dest = CE->getArg(0); const Expr *Dest = CE->getArg(0);
const GRState *state = C.getState(); const GRState *state = C.getState();
state = state->BindExpr(CE, state->getSVal(Dest)); 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); // 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); // int memcmp(const void *s1, const void *s2, size_t n);
const Expr *Left = CE->getArg(0); const Expr *Left = CE->getArg(0);
const Expr *Right = CE->getArg(1); 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)); DefinedOrUnknownSVal RV = cast<DefinedOrUnknownSVal>(state->getSVal(Right));
// See if they are the same. // See if they are the same.
DefinedOrUnknownSVal SameBuf = SV.EvalEQ(state, LV, RV); DefinedOrUnknownSVal SameBuf = SV.evalEQ(state, LV, RV);
const GRState *StSameBuf, *StNotSameBuf; const GRState *StSameBuf, *StNotSameBuf;
llvm::tie(StSameBuf, StNotSameBuf) = state->Assume(SameBuf); 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); // size_t strlen(const char *s);
const GRState *state = C.getState(); const GRState *state = C.getState();
const Expr *Arg = CE->getArg(0); 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); // 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); // 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) { bool ReturnEnd) {
const GRState *state = C.getState(); const GRState *state = C.getState();
@ -852,7 +852,7 @@ void CStringChecker::EvalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
if (NonLoc *KnownStrLen = dyn_cast<NonLoc>(&StrLen)) { if (NonLoc *KnownStrLen = dyn_cast<NonLoc>(&StrLen)) {
SValBuilder &SV = C.getSValBuilder(); SValBuilder &SV = C.getSValBuilder();
SVal LastElement = SV.EvalBinOpLN(state, BO_Add, SVal LastElement = SV.evalBinOpLN(state, BO_Add,
*DstRegVal, *KnownStrLen, *DstRegVal, *KnownStrLen,
Dst->getType()); Dst->getType());
@ -894,7 +894,7 @@ void CStringChecker::EvalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
// The driver method, and other Checker callbacks. // 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 // Get the callee. All the functions we care about are C functions
// with simple identifiers. // with simple identifiers.
const GRState *state = C.getState(); const GRState *state = C.getState();
@ -912,22 +912,22 @@ bool CStringChecker::EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
if (Name.startswith("__builtin_")) if (Name.startswith("__builtin_"))
Name = Name.substr(10); Name = Name.substr(10);
FnCheck EvalFunction = llvm::StringSwitch<FnCheck>(Name) FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name)
.Cases("memcpy", "__memcpy_chk", &CStringChecker::EvalMemcpy) .Cases("memcpy", "__memcpy_chk", &CStringChecker::evalMemcpy)
.Cases("memcmp", "bcmp", &CStringChecker::EvalMemcmp) .Cases("memcmp", "bcmp", &CStringChecker::evalMemcmp)
.Cases("memmove", "__memmove_chk", &CStringChecker::EvalMemmove) .Cases("memmove", "__memmove_chk", &CStringChecker::evalMemmove)
.Cases("strcpy", "__strcpy_chk", &CStringChecker::EvalStrcpy) .Cases("strcpy", "__strcpy_chk", &CStringChecker::evalStrcpy)
.Cases("stpcpy", "__stpcpy_chk", &CStringChecker::EvalStpcpy) .Cases("stpcpy", "__stpcpy_chk", &CStringChecker::evalStpcpy)
.Case("strlen", &CStringChecker::EvalStrlen) .Case("strlen", &CStringChecker::evalStrlen)
.Case("bcopy", &CStringChecker::EvalBcopy) .Case("bcopy", &CStringChecker::evalBcopy)
.Default(NULL); .Default(NULL);
// If the callee isn't a string function, let another checker handle it. // If the callee isn't a string function, let another checker handle it.
if (!EvalFunction) if (!evalFunction)
return false; return false;
// Check and evaluate the call. // Check and evaluate the call.
(this->*EvalFunction)(C, CE); (this->*evalFunction)(C, CE);
return true; 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()) if (!SR.hasDeadSymbols())
return; return;

View File

@ -41,7 +41,7 @@ public:
void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE); void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE);
void PreVisitObjCMessageExpr(CheckerContext &C, const ObjCMessageExpr *ME); void PreVisitObjCMessageExpr(CheckerContext &C, const ObjCMessageExpr *ME);
bool EvalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME); bool evalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME);
private: private:
bool PreVisitProcessArg(CheckerContext &C, const Expr *Ex, bool PreVisitProcessArg(CheckerContext &C, const Expr *Ex,
@ -244,7 +244,7 @@ void CallAndMessageChecker::PreVisitObjCMessageExpr(CheckerContext &C,
return; return;
} }
bool CallAndMessageChecker::EvalNilReceiver(CheckerContext &C, bool CallAndMessageChecker::evalNilReceiver(CheckerContext &C,
const ObjCMessageExpr *ME) { const ObjCMessageExpr *ME) {
HandleNilReceiver(C, C.getState(), ME); HandleNilReceiver(C, C.getState(), ME);
return true; // Nil receiver is not handled elsewhere. return true; // Nil receiver is not handled elsewhere.

View File

@ -48,7 +48,7 @@ public:
return &x; 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); virtual void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE);
private: private:
@ -62,7 +62,7 @@ void clang::RegisterChrootChecker(GRExprEngine &Eng) {
Eng.registerCheck(new ChrootChecker()); 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 GRState *state = C.getState();
const Expr *Callee = CE->getCallee(); const Expr *Callee = CE->getCallee();
SVal L = state->getSVal(Callee); SVal L = state->getSVal(Callee);

View File

@ -28,7 +28,7 @@ public:
}; };
} }
void GRExprEngine::EvalArguments(ConstExprIterator AI, ConstExprIterator AE, void GRExprEngine::evalArguments(ConstExprIterator AI, ConstExprIterator AE,
const FunctionProtoType *FnType, const FunctionProtoType *FnType,
ExplodedNode *Pred, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExplodedNodeSet &Dst,
bool FstArgAsLValue) { bool FstArgAsLValue) {
@ -125,9 +125,9 @@ void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E,
// Evaluate other arguments. // Evaluate other arguments.
ExplodedNodeSet ArgsEvaluated; ExplodedNodeSet argsEvaluated;
const FunctionProtoType *FnType = CD->getType()->getAs<FunctionProtoType>(); 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. // The callee stack frame context used to create the 'this' parameter region.
const StackFrameContext *SFC = AMgr.getStackFrame(CD, const StackFrameContext *SFC = AMgr.getStackFrame(CD,
Pred->getLocationContext(), Pred->getLocationContext(),
@ -137,8 +137,8 @@ void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E,
SFC); SFC);
CallEnter Loc(E, SFC, Pred->getLocationContext()); CallEnter Loc(E, SFC, Pred->getLocationContext());
for (ExplodedNodeSet::iterator NI = ArgsEvaluated.begin(), for (ExplodedNodeSet::iterator NI = argsEvaluated.begin(),
NE = ArgsEvaluated.end(); NI != NE; ++NI) { NE = argsEvaluated.end(); NI != NE; ++NI) {
const GRState *state = GetState(*NI); const GRState *state = GetState(*NI);
// Setup 'this' region, so that the ctor is evaluated on the object pointed // Setup 'this' region, so that the ctor is evaluated on the object pointed
// by 'Dest'. // by 'Dest'.
@ -182,27 +182,27 @@ void GRExprEngine::VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE,
assert(FnType && "Method type not available"); assert(FnType && "Method type not available");
// Evaluate explicit arguments with a worklist. // Evaluate explicit arguments with a worklist.
ExplodedNodeSet ArgsEvaluated; ExplodedNodeSet argsEvaluated;
EvalArguments(MCE->arg_begin(), MCE->arg_end(), FnType, Pred, ArgsEvaluated); evalArguments(MCE->arg_begin(), MCE->arg_end(), FnType, Pred, argsEvaluated);
// Evaluate the implicit object argument. // Evaluate the implicit object argument.
ExplodedNodeSet AllArgsEvaluated; ExplodedNodeSet AllargsEvaluated;
const MemberExpr *ME = dyn_cast<MemberExpr>(MCE->getCallee()->IgnoreParens()); const MemberExpr *ME = dyn_cast<MemberExpr>(MCE->getCallee()->IgnoreParens());
if (!ME) if (!ME)
return; return;
Expr *ObjArgExpr = ME->getBase(); Expr *ObjArgExpr = ME->getBase();
for (ExplodedNodeSet::iterator I = ArgsEvaluated.begin(), for (ExplodedNodeSet::iterator I = argsEvaluated.begin(),
E = ArgsEvaluated.end(); I != E; ++I) { E = argsEvaluated.end(); I != E; ++I) {
if (ME->isArrow()) if (ME->isArrow())
Visit(ObjArgExpr, *I, AllArgsEvaluated); Visit(ObjArgExpr, *I, AllargsEvaluated);
else else
VisitLValue(ObjArgExpr, *I, AllArgsEvaluated); VisitLValue(ObjArgExpr, *I, AllargsEvaluated);
} }
// Now evaluate the call itself. // Now evaluate the call itself.
const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl()); const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
assert(MD && "not a CXXMethodDecl?"); 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, 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) // Evaluate arguments treating the first one (object method is called on)
// as alvalue. // as alvalue.
ExplodedNodeSet ArgsEvaluated; ExplodedNodeSet argsEvaluated;
EvalArguments(C->arg_begin(), C->arg_end(), Proto, Pred, ArgsEvaluated, true); evalArguments(C->arg_begin(), C->arg_end(), Proto, Pred, argsEvaluated, true);
// Now evaluate the call itself. // 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, const Expr *ThisExpr, ExplodedNode *Pred,
ExplodedNodeSet &Src, ExplodedNodeSet &Dst) { ExplodedNodeSet &Src, ExplodedNodeSet &Dst) {
// Allow checkers to pre-visit the member call. // 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(); const CXXConstructorDecl *CD = CNE->getConstructor();
if (CD) if (CD)
FnType = CD->getType()->getAs<FunctionProtoType>(); FnType = CD->getType()->getAs<FunctionProtoType>();
ExplodedNodeSet ArgsEvaluated; ExplodedNodeSet argsEvaluated;
EvalArguments(CNE->constructor_arg_begin(), CNE->constructor_arg_end(), evalArguments(CNE->constructor_arg_begin(), CNE->constructor_arg_end(),
FnType, Pred, ArgsEvaluated); FnType, Pred, argsEvaluated);
// Initialize the object region and bind the 'new' expression. // Initialize the object region and bind the 'new' expression.
for (ExplodedNodeSet::iterator I = ArgsEvaluated.begin(), for (ExplodedNodeSet::iterator I = argsEvaluated.begin(),
E = ArgsEvaluated.end(); I != E; ++I) { E = argsEvaluated.end(); I != E; ++I) {
const GRState *state = GetState(*I); const GRState *state = GetState(*I);
if (ObjTy->isRecordType()) { if (ObjTy->isRecordType()) {
@ -310,10 +310,10 @@ void GRExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
void GRExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, void GRExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
ExplodedNode *Pred,ExplodedNodeSet &Dst) { ExplodedNode *Pred,ExplodedNodeSet &Dst) {
// Should do more checking. // Should do more checking.
ExplodedNodeSet ArgEvaluated; ExplodedNodeSet Argevaluated;
Visit(CDE->getArgument(), Pred, ArgEvaluated); Visit(CDE->getArgument(), Pred, Argevaluated);
for (ExplodedNodeSet::iterator I = ArgEvaluated.begin(), for (ExplodedNodeSet::iterator I = Argevaluated.begin(),
E = ArgEvaluated.end(); I != E; ++I) { E = Argevaluated.end(); I != E; ++I) {
const GRState *state = GetState(*I); const GRState *state = GetState(*I);
MakeNode(Dst, CDE, *I, state); MakeNode(Dst, CDE, *I, state);
} }

View File

@ -186,23 +186,23 @@ void GRExprEngine::CheckerEvalNilReceiver(const ObjCMessageExpr *ME,
ExplodedNodeSet &Dst, ExplodedNodeSet &Dst,
const GRState *state, const GRState *state,
ExplodedNode *Pred) { ExplodedNode *Pred) {
bool Evaluated = false; bool evaluated = false;
ExplodedNodeSet DstTmp; ExplodedNodeSet DstTmp;
for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end();I!=E;++I) { for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end();I!=E;++I) {
void *tag = I->first; void *tag = I->first;
Checker *checker = I->second; 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)) { tag)) {
Evaluated = true; evaluated = true;
break; break;
} else } else
// The checker didn't evaluate the expr. Restore the Dst. // The checker didn't evaluate the expr. Restore the Dst.
DstTmp.clear(); DstTmp.clear();
} }
if (Evaluated) if (evaluated)
Dst.insert(DstTmp); Dst.insert(DstTmp);
else else
Dst.insert(Pred); Dst.insert(Pred);
@ -214,27 +214,27 @@ void GRExprEngine::CheckerEvalNilReceiver(const ObjCMessageExpr *ME,
bool GRExprEngine::CheckerEvalCall(const CallExpr *CE, bool GRExprEngine::CheckerEvalCall(const CallExpr *CE,
ExplodedNodeSet &Dst, ExplodedNodeSet &Dst,
ExplodedNode *Pred) { ExplodedNode *Pred) {
bool Evaluated = false; bool evaluated = false;
ExplodedNodeSet DstTmp; ExplodedNodeSet DstTmp;
for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end();I!=E;++I) { for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end();I!=E;++I) {
void *tag = I->first; void *tag = I->first;
Checker *checker = I->second; Checker *checker = I->second;
if (checker->GR_EvalCallExpr(DstTmp, *Builder, *this, CE, Pred, tag)) { if (checker->GR_evalCallExpr(DstTmp, *Builder, *this, CE, Pred, tag)) {
Evaluated = true; evaluated = true;
break; break;
} else } else
// The checker didn't evaluate the expr. Restore the DstTmp set. // The checker didn't evaluate the expr. Restore the DstTmp set.
DstTmp.clear(); DstTmp.clear();
} }
if (Evaluated) if (evaluated)
Dst.insert(DstTmp); Dst.insert(DstTmp);
else else
Dst.insert(Pred); Dst.insert(Pred);
return Evaluated; return evaluated;
} }
// FIXME: This is largely copy-paste from CheckerVisit(). Need to // FIXME: This is largely copy-paste from CheckerVisit(). Need to
@ -382,7 +382,7 @@ const GRState* GRExprEngine::getInitialState(const LocationContext *InitLoc) {
break; break;
SVal V = state->getSVal(loc::MemRegionVal(R)); 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), ValMgr.makeZeroVal(T),
getContext().IntTy); getContext().IntTy);
@ -420,7 +420,7 @@ const GRState* GRExprEngine::getInitialState(const LocationContext *InitLoc) {
// Top-level transfer function logic (Dispatcher). // 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. /// logic for handling assumptions on symbolic values.
const GRState *GRExprEngine::ProcessAssume(const GRState *state, SVal cond, const GRState *GRExprEngine::ProcessAssume(const GRState *state, SVal cond,
bool assumption) { bool assumption) {
@ -456,7 +456,7 @@ const GRState *GRExprEngine::ProcessAssume(const GRState *state, SVal cond,
Checker *C = I->second; Checker *C = I->second;
bool respondsToCallback = true; 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. // Check if we're building the cache of checkers that care about Assumes.
if (NewCO.get() && respondsToCallback) if (NewCO.get() && respondsToCallback)
@ -473,7 +473,7 @@ const GRState *GRExprEngine::ProcessAssume(const GRState *state, SVal cond,
if (!state) if (!state)
return NULL; return NULL;
return TF->EvalAssume(state, cond, assumption); return TF->evalAssume(state, cond, assumption);
} }
bool GRExprEngine::WantsRegionChangeUpdate(const GRState* state) { bool GRExprEngine::WantsRegionChangeUpdate(const GRState* state) {
@ -613,7 +613,7 @@ void GRExprEngine::ProcessStmt(const CFGStmt S, GRStmtNodeBuilder& builder) {
// FIXME: This should soon be removed. // FIXME: This should soon be removed.
ExplodedNodeSet Tmp2; ExplodedNodeSet Tmp2;
getTF().EvalDeadSymbols(Tmp2, *this, *Builder, EntryNode, getTF().evalDeadSymbols(Tmp2, *this, *Builder, EntryNode,
CleanedState, SymReaper); CleanedState, SymReaper);
if (Checkers.empty()) if (Checkers.empty())
@ -635,7 +635,7 @@ void GRExprEngine::ProcessStmt(const CFGStmt S, GRStmtNodeBuilder& builder) {
Checker *checker = I->second; Checker *checker = I->second;
for (ExplodedNodeSet::iterator NI = SrcSet->begin(), NE = SrcSet->end(); for (ExplodedNodeSet::iterator NI = SrcSet->begin(), NE = SrcSet->end();
NI != NE; ++NI) NI != NE; ++NI)
checker->GR_EvalDeadSymbols(*DstSet, *Builder, *this, CurrentStmt, checker->GR_evalDeadSymbols(*DstSet, *Builder, *this, CurrentStmt,
*NI, SymReaper, tag); *NI, SymReaper, tag);
SrcSet = DstSet; SrcSet = DstSet;
} }
@ -907,7 +907,7 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
(B->isRelationalOp() || B->isEqualityOp())) { (B->isRelationalOp() || B->isEqualityOp())) {
ExplodedNodeSet Tmp; ExplodedNodeSet Tmp;
VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp, false); VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp, false);
EvalEagerlyAssume(Dst, Tmp, cast<Expr>(S)); evalEagerlyAssume(Dst, Tmp, cast<Expr>(S));
} }
else else
VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst, false); 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)) { if (AMgr.shouldEagerlyAssume()&&(U->getOpcode() == UO_LNot)) {
ExplodedNodeSet Tmp; ExplodedNodeSet Tmp;
VisitUnaryOperator(U, Pred, Tmp, false); VisitUnaryOperator(U, Pred, Tmp, false);
EvalEagerlyAssume(Dst, Tmp, U); evalEagerlyAssume(Dst, Tmp, U);
} }
else else
VisitUnaryOperator(U, Pred, Dst, false); 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 /// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path
/// nodes when the control reaches the end of a function. /// nodes when the control reaches the end of a function.
void GRExprEngine::ProcessEndPath(GREndPathNodeBuilder& builder) { void GRExprEngine::ProcessEndPath(GREndPathNodeBuilder& builder) {
getTF().EvalEndPath(*this, builder); getTF().evalEndPath(*this, builder);
StateMgr.EndPath(builder.getState()); StateMgr.EndPath(builder.getState());
for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end(); I!=E;++I){ for (CheckersOrdered::iterator I=Checkers.begin(),E=Checkers.end(); I!=E;++I){
void *tag = I->first; void *tag = I->first;
Checker *checker = I->second; Checker *checker = I->second;
checker->EvalEndPath(builder, tag, *this); checker->evalEndPath(builder, tag, *this);
} }
} }
@ -1597,7 +1597,7 @@ void GRExprEngine::ProcessSwitch(GRSwitchNodeBuilder& builder) {
do { do {
nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1.Val.getInt())); nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1.Val.getInt()));
DefinedOrUnknownSVal Res = svalBuilder.EvalEQ(DefaultSt ? DefaultSt : state, DefinedOrUnknownSVal Res = svalBuilder.evalEQ(DefaultSt ? DefaultSt : state,
CondV, CaseVal); CondV, CaseVal);
// Now "assume" that the case matches. // Now "assume" that the case matches.
@ -1804,7 +1804,7 @@ void GRExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D,
ProgramPoint::PostLValueKind); ProgramPoint::PostLValueKind);
} }
else else
EvalLoad(Dst, Ex, Pred, state, V); evalLoad(Dst, Ex, Pred, state, V);
return; return;
} else if (const EnumConstantDecl* ED = dyn_cast<EnumConstantDecl>(D)) { } 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), MakeNode(Dst, A, *I2, state->BindExpr(A, V),
ProgramPoint::PostLValueKind); ProgramPoint::PostLValueKind);
else 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) if (asLValue)
MakeNode(Dst, M, *I, state->BindExpr(M, L), ProgramPoint::PostLValueKind); MakeNode(Dst, M, *I, state->BindExpr(M, L), ProgramPoint::PostLValueKind);
else 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. /// evalBind - Handle the semantics of binding a value to a specific location.
/// This method is used by EvalStore and (soon) VisitDeclStmt, and others. /// This method is used by evalStore and (soon) VisitDeclStmt, and others.
void GRExprEngine::EvalBind(ExplodedNodeSet& Dst, const Stmt* StoreE, void GRExprEngine::evalBind(ExplodedNodeSet& Dst, const Stmt* StoreE,
ExplodedNode* Pred, const GRState* state, ExplodedNode* Pred, const GRState* state,
SVal location, SVal Val, bool atDeclInit) { 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, GRStmtNodeBuilderRef BuilderRef(Dst, *Builder, *this, *I, newState, StoreE,
true); 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 Dst The node set to store generated state nodes
/// @param AssignE The assignment expression if the store happens in an /// @param AssignE The assignment expression if the store happens in an
/// assignment. /// assignment.
@ -1958,7 +1958,7 @@ void GRExprEngine::EvalBind(ExplodedNodeSet& Dst, const Stmt* StoreE,
/// @param state The current simulation state /// @param state The current simulation state
/// @param location The location to store the value /// @param location The location to store the value
/// @param Val The value to be stored /// @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, const Expr* LocationE,
ExplodedNode* Pred, ExplodedNode* Pred,
const GRState* state, SVal location, SVal Val, 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). // Evaluate the location (checks for bad dereferences).
ExplodedNodeSet Tmp; ExplodedNodeSet Tmp;
EvalLocation(Tmp, LocationE, Pred, state, location, tag, false); evalLocation(Tmp, LocationE, Pred, state, location, tag, false);
if (Tmp.empty()) if (Tmp.empty())
return; return;
@ -1984,10 +1984,10 @@ void GRExprEngine::EvalStore(ExplodedNodeSet& Dst, const Expr *AssignE,
const Expr *StoreE = AssignE ? AssignE : LocationE; const Expr *StoreE = AssignE ? AssignE : LocationE;
for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) 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, ExplodedNode* Pred,
const GRState* state, SVal location, const GRState* state, SVal location,
const void *tag, QualType LoadTy) { const void *tag, QualType LoadTy) {
@ -2003,30 +2003,30 @@ void GRExprEngine::EvalLoad(ExplodedNodeSet& Dst, const Expr *Ex,
if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) { if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) {
static int loadReferenceTag = 0; static int loadReferenceTag = 0;
ExplodedNodeSet Tmp; ExplodedNodeSet Tmp;
EvalLoadCommon(Tmp, Ex, Pred, state, location, &loadReferenceTag, evalLoadCommon(Tmp, Ex, Pred, state, location, &loadReferenceTag,
getContext().getPointerType(RT->getPointeeType())); getContext().getPointerType(RT->getPointeeType()));
// Perform the load from the referenced value. // Perform the load from the referenced value.
for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end() ; I!=E; ++I) { for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end() ; I!=E; ++I) {
state = GetState(*I); state = GetState(*I);
location = state->getSVal(Ex); location = state->getSVal(Ex);
EvalLoadCommon(Dst, Ex, *I, state, location, tag, LoadTy); evalLoadCommon(Dst, Ex, *I, state, location, tag, LoadTy);
} }
return; 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, ExplodedNode* Pred,
const GRState* state, SVal location, const GRState* state, SVal location,
const void *tag, QualType LoadTy) { const void *tag, QualType LoadTy) {
// Evaluate the location (checks for bad dereferences). // Evaluate the location (checks for bad dereferences).
ExplodedNodeSet Tmp; ExplodedNodeSet Tmp;
EvalLocation(Tmp, Ex, Pred, state, location, tag, true); evalLocation(Tmp, Ex, Pred, state, location, tag, true);
if (Tmp.empty()) if (Tmp.empty())
return; 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, ExplodedNode* Pred,
const GRState* state, SVal location, const GRState* state, SVal location,
const void *tag, bool isLoad) { const void *tag, bool isLoad) {
@ -2150,7 +2150,7 @@ void GRExprEngine::VisitCall(const CallExpr* CE, ExplodedNode* Pred,
// Evaluate the arguments. // Evaluate the arguments.
ExplodedNodeSet ArgsEvaluated; 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. // Now process the call itself.
ExplodedNodeSet DstTmp; ExplodedNodeSet DstTmp;
@ -2193,18 +2193,18 @@ void GRExprEngine::VisitCall(const CallExpr* CE, ExplodedNode* Pred,
DI_Checker != DE_Checker; ++DI_Checker) { DI_Checker != DE_Checker; ++DI_Checker) {
// Dispatch to the plug-in transfer function. // Dispatch to the plug-in transfer function.
unsigned OldSize = DstTmp3.size(); unsigned oldSize = DstTmp3.size();
SaveOr OldHasGen(Builder->HasGeneratedNode); SaveOr OldHasGen(Builder->HasGeneratedNode);
Pred = *DI_Checker; Pred = *DI_Checker;
// Dispatch to transfer function logic to handle the call itself. // Dispatch to transfer function logic to handle the call itself.
// FIXME: Allow us to chain together transfer functions. // FIXME: Allow us to chain together transfer functions.
assert(Builder && "GRStmtNodeBuilder must be defined."); 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 // Handle the case where no nodes where generated. Auto-generate that
// contains the updated state if we aren't generating sinks. // contains the updated state if we aren't generating sinks.
if (!Builder->BuildSinks && DstTmp3.size() == OldSize && if (!Builder->BuildSinks && DstTmp3.size() == oldSize &&
!Builder->HasGeneratedNode) !Builder->HasGeneratedNode)
MakeNode(DstTmp3, CE, Pred, state); 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(); for (ExplodedNodeSet::iterator NI = DstTmp4.begin(), NE = DstTmp4.end();
NI!=NE; ++NI) { NI!=NE; ++NI) {
const GRState *state = GetState(*NI); const GRState *state = GetState(*NI);
EvalLoad(Dst, CE, *NI, state, state->getSVal(CE), evalLoad(Dst, CE, *NI, state, state->getSVal(CE),
&ConvertToRvalueTag, LoadTy); &ConvertToRvalueTag, LoadTy);
} }
} }
@ -2245,7 +2245,7 @@ void GRExprEngine::VisitCall(const CallExpr* CE, ExplodedNode* Pred,
static std::pair<const void*,const void*> EagerlyAssumeTag static std::pair<const void*,const void*> EagerlyAssumeTag
= std::pair<const void*,const void*>(&EagerlyAssumeTag,static_cast<void*>(0)); = 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) { const Expr *Ex) {
for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) { for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) {
ExplodedNode *Pred = *I; ExplodedNode *Pred = *I;
@ -2322,7 +2322,7 @@ void GRExprEngine::VisitObjCIvarRefExpr(const ObjCIvarRefExpr* Ex,
if (asLValue) if (asLValue)
MakeNode(Dst, Ex, *I, state->BindExpr(Ex, location)); MakeNode(Dst, Ex, *I, state->BindExpr(Ex, location));
else 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. // Check if the location we are writing back to is a null pointer.
const Stmt* elem = S->getElement(); const Stmt* elem = S->getElement();
ExplodedNodeSet Tmp; ExplodedNodeSet Tmp;
EvalLocation(Tmp, elem, Pred, GetState(Pred), ElementV, NULL, false); evalLocation(Tmp, elem, Pred, GetState(Pred), ElementV, NULL, false);
if (Tmp.empty()) if (Tmp.empty())
return; return;
@ -2490,14 +2490,14 @@ void GRExprEngine::VisitObjCMessageExpr(const ObjCMessageExpr* ME,
CheckerVisit(ME, DstPrevisit, ArgsEvaluated, PreVisitStmtCallback); CheckerVisit(ME, DstPrevisit, ArgsEvaluated, PreVisitStmtCallback);
// Proceed with evaluate the message expression. // Proceed with evaluate the message expression.
ExplodedNodeSet DstEval; ExplodedNodeSet dstEval;
for (ExplodedNodeSet::iterator DI = DstPrevisit.begin(), for (ExplodedNodeSet::iterator DI = DstPrevisit.begin(),
DE = DstPrevisit.end(); DI != DE; ++DI) { DE = DstPrevisit.end(); DI != DE; ++DI) {
Pred = *DI; Pred = *DI;
bool RaisesException = false; bool RaisesException = false;
unsigned OldSize = DstEval.size(); unsigned oldSize = dstEval.size();
SaveAndRestore<bool> OldSink(Builder->BuildSinks); SaveAndRestore<bool> OldSink(Builder->BuildSinks);
SaveOr OldHasGen(Builder->HasGeneratedNode); 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 // 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. // non-nil. We handle must be nil, and merge the rest two into non-nil.
if (nilState && !notNilState) { if (nilState && !notNilState) {
CheckerEvalNilReceiver(ME, DstEval, nilState, Pred); CheckerEvalNilReceiver(ME, dstEval, nilState, Pred);
continue; continue;
} }
@ -2529,7 +2529,7 @@ void GRExprEngine::VisitObjCMessageExpr(const ObjCMessageExpr* ME,
Builder->BuildSinks = true; Builder->BuildSinks = true;
// Dispatch to plug-in transfer function. // Dispatch to plug-in transfer function.
EvalObjCMessageExpr(DstEval, ME, Pred, notNilState); evalObjCMessageExpr(dstEval, ME, Pred, notNilState);
} }
else if (ObjCInterfaceDecl *Iface = ME->getReceiverInterface()) { else if (ObjCInterfaceDecl *Iface = ME->getReceiverInterface()) {
IdentifierInfo* ClsName = Iface->getIdentifier(); IdentifierInfo* ClsName = Iface->getIdentifier();
@ -2577,20 +2577,20 @@ void GRExprEngine::VisitObjCMessageExpr(const ObjCMessageExpr* ME,
Builder->BuildSinks = true; Builder->BuildSinks = true;
// Dispatch to plug-in transfer function. // 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 // Handle the case where no nodes where generated. Auto-generate that
// contains the updated state if we aren't generating sinks. // contains the updated state if we aren't generating sinks.
if (!Builder->BuildSinks && DstEval.size() == OldSize && if (!Builder->BuildSinks && dstEval.size() == oldSize &&
!Builder->HasGeneratedNode) !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 // Finally, perform the post-condition check of the ObjCMessageExpr and store
// the created nodes in 'Dst'. // the created nodes in 'Dst'.
if (!(!asLValue && ReceiverReturnsReference(ME))) { if (!(!asLValue && ReceiverReturnsReference(ME))) {
CheckerVisit(ME, Dst, DstEval, PostVisitStmtCallback); CheckerVisit(ME, Dst, dstEval, PostVisitStmtCallback);
return; return;
} }
@ -2600,14 +2600,14 @@ void GRExprEngine::VisitObjCMessageExpr(const ObjCMessageExpr* ME,
// FIXME: This conversion doesn't actually happen unless the result // FIXME: This conversion doesn't actually happen unless the result
// of ObjCMessageExpr is consumed by another expression. // of ObjCMessageExpr is consumed by another expression.
ExplodedNodeSet DstRValueConvert; ExplodedNodeSet DstRValueConvert;
CheckerVisit(ME, DstRValueConvert, DstEval, PostVisitStmtCallback); CheckerVisit(ME, DstRValueConvert, dstEval, PostVisitStmtCallback);
QualType LoadTy = ME->getType(); QualType LoadTy = ME->getType();
static int *ConvertToRvalueTag = 0; static int *ConvertToRvalueTag = 0;
for (ExplodedNodeSet::iterator NI = DstRValueConvert.begin(), for (ExplodedNodeSet::iterator NI = DstRValueConvert.begin(),
NE = DstRValueConvert.end(); NI != NE; ++NI) { NE = DstRValueConvert.end(); NI != NE; ++NI) {
const GRState *state = GetState(*NI); const GRState *state = GetState(*NI);
EvalLoad(Dst, ME, *NI, state, state->getSVal(ME), evalLoad(Dst, ME, *NI, state, state->getSVal(ME),
&ConvertToRvalueTag, LoadTy); &ConvertToRvalueTag, LoadTy);
} }
} }
@ -2696,7 +2696,7 @@ void GRExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
ExplodedNode* N = *I; ExplodedNode* N = *I;
const GRState* state = GetState(N); const GRState* state = GetState(N);
SVal V = state->getSVal(Ex); SVal V = state->getSVal(Ex);
V = svalBuilder.EvalCast(V, T, ExTy); V = svalBuilder.evalCast(V, T, ExTy);
state = state->BindExpr(CastE, V); state = state->BindExpr(CastE, V);
MakeNode(Dst, CastE, N, state); MakeNode(Dst, CastE, N, state);
} }
@ -2805,7 +2805,7 @@ void GRExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
Builder->getCurrentBlockCount()); Builder->getCurrentBlockCount());
} }
EvalBind(Dst, DS, *I, state, evalBind(Dst, DS, *I, state,
loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true); loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true);
} }
else { else {
@ -2837,7 +2837,7 @@ void GRExprEngine::VisitCondInit(const VarDecl *VD, const Stmt *S,
Builder->getCurrentBlockCount()); Builder->getCurrentBlockCount());
} }
EvalBind(Dst, S, N, state, evalBind(Dst, S, N, state,
loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true); 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), MakeNode(Dst, U, *I, state->BindExpr(U, location),
ProgramPoint::PostLValueKind); ProgramPoint::PostLValueKind);
else else
EvalLoad(Dst, U, *I, state, location); evalLoad(Dst, U, *I, state, location);
} }
return; return;
@ -3159,7 +3159,7 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U,
// QualType SrcT = getContext().getCanonicalType(Ex->getType()); // QualType SrcT = getContext().getCanonicalType(Ex->getType());
// //
// if (DstT != SrcT) // Perform promotions. // if (DstT != SrcT) // Perform promotions.
// V = EvalCast(V, DstT); // V = evalCast(V, DstT);
// //
// if (V.isUnknownOrUndef()) { // if (V.isUnknownOrUndef()) {
// MakeNode(Dst, U, *I, BindExpr(St, U, V)); // MakeNode(Dst, U, *I, BindExpr(St, U, V));
@ -3173,12 +3173,12 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U,
case UO_Not: case UO_Not:
// FIXME: Do we need to handle promotions? // FIXME: Do we need to handle promotions?
state = state->BindExpr(U, EvalComplement(cast<NonLoc>(V))); state = state->BindExpr(U, evalComplement(cast<NonLoc>(V)));
break; break;
case UO_Minus: case UO_Minus:
// FIXME: Do we need to handle promotions? // FIXME: Do we need to handle promotions?
state = state->BindExpr(U, EvalMinus(cast<NonLoc>(V))); state = state->BindExpr(U, evalMinus(cast<NonLoc>(V)));
break; break;
case UO_LNot: case UO_LNot:
@ -3191,12 +3191,12 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U,
if (isa<Loc>(V)) { if (isa<Loc>(V)) {
Loc X = ValMgr.makeNull(); Loc X = ValMgr.makeNull();
Result = EvalBinOp(state, BO_EQ, cast<Loc>(V), X, Result = evalBinOp(state, BO_EQ, cast<Loc>(V), X,
U->getType()); U->getType());
} }
else { else {
nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType())); 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()); U->getType());
} }
@ -3226,7 +3226,7 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U,
// Perform a load. // Perform a load.
ExplodedNodeSet Tmp2; 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) { for (ExplodedNodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end();I2!=E2;++I2) {
@ -3254,7 +3254,7 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U,
else else
RHS = ValMgr.makeIntVal(1, U->getType()); 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. // Conjure a new symbol if necessary to recover precision.
if (Result.isUnknown() || !getConstraintManager().canReasonAbout(Result)){ if (Result.isUnknown() || !getConstraintManager().canReasonAbout(Result)){
@ -3268,12 +3268,12 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U,
// propagate that constraint. // propagate that constraint.
if (Loc::IsLocType(U->getType())) { if (Loc::IsLocType(U->getType())) {
DefinedOrUnknownSVal Constraint = DefinedOrUnknownSVal Constraint =
svalBuilder.EvalEQ(state, V2, ValMgr.makeZeroVal(U->getType())); svalBuilder.evalEQ(state, V2, ValMgr.makeZeroVal(U->getType()));
if (!state->Assume(Constraint, true)) { if (!state->Assume(Constraint, true)) {
// It isn't feasible for the original value to be null. // It isn't feasible for the original value to be null.
// Propagate this constraint. // Propagate this constraint.
Constraint = svalBuilder.EvalEQ(state, SymVal, Constraint = svalBuilder.evalEQ(state, SymVal,
ValMgr.makeZeroVal(U->getType())); ValMgr.makeZeroVal(U->getType()));
@ -3286,7 +3286,7 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U,
state = state->BindExpr(U, U->isPostfix() ? V2 : Result); state = state->BindExpr(U, U->isPostfix() ? V2 : Result);
// Perform the store. // 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); SaveAndRestore<bool> OldSink(Builder->BuildSinks);
SaveOr OldHasGen(Builder->HasGeneratedNode); 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. // Handle the case where no nodes where generated.
if (!Builder->BuildSinks && Dst.size() == size && 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 // Simulate the effects of a "store": bind the value of the RHS
// to the L-Value represented by the LHS. // 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; continue;
} }
if (!B->isAssignmentOp()) { if (!B->isAssignmentOp()) {
// Process non-assignments except commas or short-circuited // Process non-assignments except commas or short-circuited
// logical expressions (LAnd and LOr). // 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()) { if (Result.isUnknown()) {
MakeNode(Tmp3, B, *I2, state); MakeNode(Tmp3, B, *I2, state);
@ -3496,7 +3496,7 @@ void GRExprEngine::VisitBinaryOperator(const BinaryOperator* B,
// null dereferences, and so on. // null dereferences, and so on.
ExplodedNodeSet Tmp4; ExplodedNodeSet Tmp4;
SVal location = state->getSVal(LHS); 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; for (ExplodedNodeSet::iterator I4=Tmp4.begin(), E4=Tmp4.end(); I4!=E4;
++I4) { ++I4) {
@ -3516,10 +3516,10 @@ void GRExprEngine::VisitBinaryOperator(const BinaryOperator* B,
QualType RTy = getContext().getCanonicalType(RHS->getType()); QualType RTy = getContext().getCanonicalType(RHS->getType());
// Promote LHS. // Promote LHS.
V = svalBuilder.EvalCast(V, CLHSTy, LTy); V = svalBuilder.evalCast(V, CLHSTy, LTy);
// Compute the result of the operation. // 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); B->getType(), CTy);
// EXPERIMENTAL: "Conjured" symbols. // EXPERIMENTAL: "Conjured" symbols.
@ -3538,15 +3538,15 @@ void GRExprEngine::VisitBinaryOperator(const BinaryOperator* B,
LHSVal = ValMgr.getConjuredSymbolVal(NULL, B->getRHS(), LTy, Count); LHSVal = ValMgr.getConjuredSymbolVal(NULL, B->getRHS(), LTy, Count);
// However, we need to convert the symbol to the computation type. // However, we need to convert the symbol to the computation type.
Result = svalBuilder.EvalCast(LHSVal, CTy, LTy); Result = svalBuilder.evalCast(LHSVal, CTy, LTy);
} }
else { else {
// The left-hand side may bind to a different value then the // The left-hand side may bind to a different value then the
// computation type. // 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); location, LHSVal);
} }
} }

View File

@ -251,27 +251,27 @@ const GRState *GRState::AssumeInBound(DefinedOrUnknownSVal Idx,
nonloc::ConcreteInt Min = BVF.getMinValue(IndexTy); nonloc::ConcreteInt Min = BVF.getMinValue(IndexTy);
// Adjust the index. // Adjust the index.
SVal NewIdx = SV.EvalBinOpNN(this, BO_Add, SVal newIdx = SV.evalBinOpNN(this, BO_Add,
cast<NonLoc>(Idx), Min, IndexTy); cast<NonLoc>(Idx), Min, IndexTy);
if (NewIdx.isUnknownOrUndef()) if (newIdx.isUnknownOrUndef())
return this; return this;
// Adjust the upper bound. // Adjust the upper bound.
SVal NewBound = SV.EvalBinOpNN(this, BO_Add, SVal NewBound = SV.evalBinOpNN(this, BO_Add,
cast<NonLoc>(UpperBound), Min, IndexTy); cast<NonLoc>(UpperBound), Min, IndexTy);
if (NewBound.isUnknownOrUndef()) if (NewBound.isUnknownOrUndef())
return this; return this;
// Build the actual comparison. // Build the actual comparison.
SVal InBound = SV.EvalBinOpNN(this, BO_LT, SVal inBound = SV.evalBinOpNN(this, BO_LT,
cast<NonLoc>(NewIdx), cast<NonLoc>(NewBound), cast<NonLoc>(newIdx), cast<NonLoc>(NewBound),
Ctx.IntTy); Ctx.IntTy);
if (InBound.isUnknownOrUndef()) if (inBound.isUnknownOrUndef())
return this; return this;
// Finally, let the constraint manager take care of it. // Finally, let the constraint manager take care of it.
ConstraintManager &CM = SM.getConstraintManager(); 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) { const GRState* GRStateManager::getInitialState(const LocationContext *InitLoc) {

View File

@ -75,11 +75,11 @@ public:
BT_BadFree(0), BT_BadFree(0),
II_malloc(0), II_free(0), II_realloc(0), II_calloc(0) {} II_malloc(0), II_free(0), II_realloc(0), II_calloc(0) {}
static void *getTag(); static void *getTag();
bool EvalCallExpr(CheckerContext &C, const CallExpr *CE); bool evalCallExpr(CheckerContext &C, const CallExpr *CE);
void EvalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper); void evalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper);
void EvalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng); void evalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng);
void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *S); 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); bool *respondsToCallback);
void VisitLocation(CheckerContext &C, const Stmt *S, SVal l); void VisitLocation(CheckerContext &C, const Stmt *S, SVal l);
virtual void PreVisitBind(CheckerContext &C, const Stmt *StoreE, virtual void PreVisitBind(CheckerContext &C, const Stmt *StoreE,
@ -132,7 +132,7 @@ void *MallocChecker::getTag() {
return &x; return &x;
} }
bool MallocChecker::EvalCallExpr(CheckerContext &C, const CallExpr *CE) { bool MallocChecker::evalCallExpr(CheckerContext &C, const CallExpr *CE) {
const GRState *state = C.getState(); const GRState *state = C.getState();
const Expr *Callee = CE->getCallee(); const Expr *Callee = CE->getCallee();
SVal L = state->getSVal(Callee); SVal L = state->getSVal(Callee);
@ -243,7 +243,7 @@ const GRState *MallocChecker::MallocMemAux(CheckerContext &C,
SValBuilder &svalBuilder = ValMgr.getSValBuilder(); SValBuilder &svalBuilder = ValMgr.getSValBuilder();
DefinedOrUnknownSVal ExtentMatchesSize = DefinedOrUnknownSVal ExtentMatchesSize =
svalBuilder.EvalEQ(state, Extent, DefinedSize); svalBuilder.evalEQ(state, Extent, DefinedSize);
state = state->Assume(ExtentMatchesSize, true); state = state->Assume(ExtentMatchesSize, true);
SymbolRef Sym = RetVal.getAsLocSymbol(); SymbolRef Sym = RetVal.getAsLocSymbol();
@ -506,7 +506,7 @@ void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) {
ValueManager &ValMgr = C.getValueManager(); ValueManager &ValMgr = C.getValueManager();
SValBuilder &svalBuilder = C.getSValBuilder(); 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 the ptr is NULL, the call is equivalent to malloc(size).
if (const GRState *stateEqual = state->Assume(PtrEQ, true)) { 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); const Expr *Arg1 = CE->getArg(1);
DefinedOrUnknownSVal Arg1Val = DefinedOrUnknownSVal Arg1Val =
cast<DefinedOrUnknownSVal>(stateNotEqual->getSVal(Arg1)); cast<DefinedOrUnknownSVal>(stateNotEqual->getSVal(Arg1));
DefinedOrUnknownSVal SizeZero = svalBuilder.EvalEQ(stateNotEqual, Arg1Val, DefinedOrUnknownSVal SizeZero = svalBuilder.evalEQ(stateNotEqual, Arg1Val,
ValMgr.makeIntValWithPtrWidth(0, false)); ValMgr.makeIntValWithPtrWidth(0, false));
if (const GRState *stateSizeZero = stateNotEqual->Assume(SizeZero, true)) { 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 Count = state->getSVal(CE->getArg(0));
SVal EleSize = state->getSVal(CE->getArg(1)); 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()); ValMgr.getContext().getSizeType());
SVal Zero = ValMgr.makeZeroVal(ValMgr.getContext().CharTy); SVal Zero = ValMgr.makeZeroVal(ValMgr.getContext().CharTy);
@ -565,7 +565,7 @@ void MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE) {
C.addTransition(state); C.addTransition(state);
} }
void MallocChecker::EvalDeadSymbols(CheckerContext &C,SymbolReaper &SymReaper) { void MallocChecker::evalDeadSymbols(CheckerContext &C,SymbolReaper &SymReaper) {
if (!SymReaper.hasDeadSymbols()) if (!SymReaper.hasDeadSymbols())
return; return;
@ -595,7 +595,7 @@ void MallocChecker::EvalDeadSymbols(CheckerContext &C,SymbolReaper &SymReaper) {
C.GenerateNode(state); C.GenerateNode(state);
} }
void MallocChecker::EvalEndPath(GREndPathNodeBuilder &B, void *tag, void MallocChecker::evalEndPath(GREndPathNodeBuilder &B, void *tag,
GRExprEngine &Eng) { GRExprEngine &Eng) {
SaveAndRestore<bool> OldHasGen(B.HasGeneratedNode); SaveAndRestore<bool> OldHasGen(B.HasGeneratedNode);
const GRState *state = B.getState(); const GRState *state = B.getState();
@ -639,7 +639,7 @@ void MallocChecker::PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *S) {
C.addTransition(state); C.addTransition(state);
} }
const GRState *MallocChecker::EvalAssume(const GRState *state, SVal Cond, const GRState *MallocChecker::evalAssume(const GRState *state, SVal Cond,
bool Assumption, bool Assumption,
bool * /* respondsToCallback */) { bool * /* respondsToCallback */) {
// If a symblic region is assumed to NULL, set its state to AllocateFailed. // If a symblic region is assumed to NULL, set its state to AllocateFailed.

View File

@ -22,10 +22,10 @@ namespace {
class OSAtomicChecker : public Checker { class OSAtomicChecker : public Checker {
public: public:
static void *getTag() { static int tag = 0; return &tag; } 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: 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()); 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 GRState *state = C.getState();
const Expr *Callee = CE->getCallee(); const Expr *Callee = CE->getCallee();
SVal L = state->getSVal(Callee); SVal L = state->getSVal(Callee);
@ -52,13 +52,13 @@ bool OSAtomicChecker::EvalCallExpr(CheckerContext &C,const CallExpr *CE) {
// Check for compare and swap. // Check for compare and swap.
if (FName.startswith("OSAtomicCompareAndSwap") || if (FName.startswith("OSAtomicCompareAndSwap") ||
FName.startswith("objc_atomicCompareAndSwap")) FName.startswith("objc_atomicCompareAndSwap"))
return EvalOSAtomicCompareAndSwap(C, CE); return evalOSAtomicCompareAndSwap(C, CE);
// FIXME: Other atomics. // FIXME: Other atomics.
return false; return false;
} }
bool OSAtomicChecker::EvalOSAtomicCompareAndSwap(CheckerContext &C, bool OSAtomicChecker::evalOSAtomicCompareAndSwap(CheckerContext &C,
const CallExpr *CE) { const CallExpr *CE) {
// Not enough arguments to match OSAtomicCompareAndSwap? // Not enough arguments to match OSAtomicCompareAndSwap?
if (CE->getNumArgs() != 3) if (CE->getNumArgs() != 3)
@ -112,7 +112,7 @@ bool OSAtomicChecker::EvalOSAtomicCompareAndSwap(CheckerContext &C,
dyn_cast_or_null<TypedRegion>(location.getAsRegion())) { dyn_cast_or_null<TypedRegion>(location.getAsRegion())) {
LoadTy = TR->getValueType(); LoadTy = TR->getValueType();
} }
Engine.EvalLoad(Tmp, theValueExpr, C.getPredecessor(), Engine.evalLoad(Tmp, theValueExpr, C.getPredecessor(),
state, location, OSAtomicLoadTag, LoadTy); state, location, OSAtomicLoadTag, LoadTy);
if (Tmp.empty()) { if (Tmp.empty()) {
@ -145,7 +145,7 @@ bool OSAtomicChecker::EvalOSAtomicCompareAndSwap(CheckerContext &C,
SValBuilder &svalBuilder = Engine.getSValBuilder(); SValBuilder &svalBuilder = Engine.getSValBuilder();
// Perform the comparison. // Perform the comparison.
DefinedOrUnknownSVal Cmp = svalBuilder.EvalEQ(stateLoad,theValueVal,oldValueVal); DefinedOrUnknownSVal Cmp = svalBuilder.evalEQ(stateLoad,theValueVal,oldValueVal);
const GRState *stateEqual = stateLoad->Assume(Cmp, true); const GRState *stateEqual = stateLoad->Assume(Cmp, true);
@ -158,10 +158,10 @@ bool OSAtomicChecker::EvalOSAtomicCompareAndSwap(CheckerContext &C,
// Handle implicit value casts. // Handle implicit value casts.
if (const TypedRegion *R = if (const TypedRegion *R =
dyn_cast_or_null<TypedRegion>(location.getAsRegion())) { 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); stateEqual, location, val, OSAtomicStoreTag);
if (TmpStore.empty()) { if (TmpStore.empty()) {

View File

@ -227,7 +227,7 @@ public:
/// For DerivedToBase casts, create a CXXBaseObjectRegion and return it. /// For DerivedToBase casts, create a CXXBaseObjectRegion and return it.
virtual SVal evalDerivedToBase(SVal derived, QualType basePtrType); 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) { Store getInitialStore(const LocationContext *InitLoc) {
return RBFactory.getEmptyMap().getRoot(); return RBFactory.getEmptyMap().getRoot();
@ -819,7 +819,7 @@ SVal RegionStoreManager::evalDerivedToBase(SVal derived, QualType basePtrType) {
// Pointer arithmetic. // Pointer arithmetic.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R, SVal RegionStoreManager::evalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R,
QualType resultTy) { QualType resultTy) {
// Assume the base location is MemRegionVal. // Assume the base location is MemRegionVal.
if (!isa<loc::MemRegionVal>(L)) if (!isa<loc::MemRegionVal>(L))
@ -1307,7 +1307,7 @@ SVal RegionStoreManager::RetrieveVar(Store store, const VarRegion *R) {
if (const IntegerLiteral *IL = if (const IntegerLiteral *IL =
dyn_cast<IntegerLiteral>(Init->IgnoreParenCasts())) { dyn_cast<IntegerLiteral>(Init->IgnoreParenCasts())) {
const nonloc::ConcreteInt &V = ValMgr.makeIntVal(IL); const nonloc::ConcreteInt &V = ValMgr.makeIntVal(IL);
return ValMgr.getSValBuilder().EvalCast(V, Init->getType(), return ValMgr.getSValBuilder().evalCast(V, Init->getType(),
IL->getType()); IL->getType());
} }
} }

View File

@ -18,7 +18,7 @@
using namespace clang; 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) { SVal L, SVal R, QualType T) {
if (L.isUndef() || R.isUndef()) 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>(L)) {
if (isa<Loc>(R)) 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)) { if (isa<Loc>(R)) {
@ -40,21 +40,21 @@ SVal SValBuilder::EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
assert(Op == BO_Add); assert(Op == BO_Add);
// Commute the operands. // 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 L,
DefinedOrUnknownSVal R) { DefinedOrUnknownSVal R) {
return cast<DefinedOrUnknownSVal>(EvalBinOp(ST, BO_EQ, L, R, return cast<DefinedOrUnknownSVal>(evalBinOp(ST, BO_EQ, L, R,
ValMgr.getContext().IntTy)); ValMgr.getContext().IntTy));
} }
// FIXME: should rewrite according to the cast kind. // 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) if (val.isUnknownOrUndef() || castTy == originalTy)
return val; return val;
@ -72,11 +72,11 @@ SVal SValBuilder::EvalCast(SVal val, QualType castTy, QualType originalTy) {
// Check for casts from integers to integers. // Check for casts from integers to integers.
if (castTy->isIntegerType() && originalTy->isIntegerType()) if (castTy->isIntegerType() && originalTy->isIntegerType())
return EvalCastNL(cast<NonLoc>(val), castTy); return evalCastNL(cast<NonLoc>(val), castTy);
// Check for casts from pointers to integers. // Check for casts from pointers to integers.
if (castTy->isIntegerType() && Loc::IsLocType(originalTy)) 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. // Check for casts from integers to pointers.
if (Loc::IsLocType(castTy) && originalTy->isIntegerType()) { if (Loc::IsLocType(castTy) && originalTy->isIntegerType()) {
@ -115,7 +115,7 @@ SVal SValBuilder::EvalCast(SVal val, QualType castTy, QualType originalTy) {
// need the original decayed type. // need the original decayed type.
// QualType elemTy = cast<ArrayType>(originalTy)->getElementType(); // QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
// QualType pointerTy = C.getPointerType(elemTy); // 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. // 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 // Delegate to store manager to get the result of casting a region to a
// different type. If the MemRegion* returned is NULL, this expression // different type. If the MemRegion* returned is NULL, this expression
// evaluates to UnknownVal. // Evaluates to UnknownVal.
R = storeMgr.CastRegion(R, castTy); R = storeMgr.CastRegion(R, castTy);
return R ? SVal(loc::MemRegionVal(R)) : UnknownVal(); return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
} }
DispatchCast: DispatchCast:
// All other cases. // All other cases.
return isa<Loc>(val) ? EvalCastL(cast<Loc>(val), castTy) return isa<Loc>(val) ? evalCastL(cast<Loc>(val), castTy)
: EvalCastNL(cast<NonLoc>(val), castTy); : evalCastNL(cast<NonLoc>(val), castTy);
} }

View File

@ -225,7 +225,7 @@ SVal nonloc::ConcreteInt::evalBinOp(ValueManager &ValMgr,
BinaryOperator::Opcode Op, BinaryOperator::Opcode Op,
const nonloc::ConcreteInt& R) const { const nonloc::ConcreteInt& R) const {
const llvm::APSInt* X = const llvm::APSInt* X =
ValMgr.getBasicValueFactory().EvaluateAPSInt(Op, getValue(), R.getValue()); ValMgr.getBasicValueFactory().evalAPSInt(Op, getValue(), R.getValue());
if (X) if (X)
return nonloc::ConcreteInt(*X); return nonloc::ConcreteInt(*X);
@ -246,14 +246,14 @@ nonloc::ConcreteInt nonloc::ConcreteInt::evalMinus(ValueManager &ValMgr) const {
// Transfer function dispatch for Locs. // Transfer function dispatch for Locs.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
SVal loc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals, SVal loc::ConcreteInt::evalBinOp(BasicValueFactory& BasicVals,
BinaryOperator::Opcode Op, BinaryOperator::Opcode Op,
const loc::ConcreteInt& R) const { const loc::ConcreteInt& R) const {
assert (Op == BO_Add || Op == BO_Sub || assert (Op == BO_Add || Op == BO_Sub ||
(Op >= BO_LT && Op <= BO_NE)); (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) if (X)
return loc::ConcreteInt(*X); return loc::ConcreteInt(*X);

View File

@ -19,23 +19,23 @@ using namespace clang;
namespace { namespace {
class SimpleSValBuilder : public SValBuilder { class SimpleSValBuilder : public SValBuilder {
protected: protected:
virtual SVal EvalCastNL(NonLoc val, QualType castTy); virtual SVal evalCastNL(NonLoc val, QualType castTy);
virtual SVal EvalCastL(Loc val, QualType castTy); virtual SVal evalCastL(Loc val, QualType castTy);
public: public:
SimpleSValBuilder(ValueManager &valMgr) : SValBuilder(valMgr) {} SimpleSValBuilder(ValueManager &valMgr) : SValBuilder(valMgr) {}
virtual ~SimpleSValBuilder() {} virtual ~SimpleSValBuilder() {}
virtual SVal EvalMinus(NonLoc val); virtual SVal evalMinus(NonLoc val);
virtual SVal EvalComplement(NonLoc val); virtual SVal evalComplement(NonLoc val);
virtual SVal EvalBinOpNN(const GRState *state, BinaryOperator::Opcode op, virtual SVal evalBinOpNN(const GRState *state, BinaryOperator::Opcode op,
NonLoc lhs, NonLoc rhs, QualType resultTy); 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); 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); 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. /// (integer) value, that value is returned. Otherwise, returns NULL.
virtual const llvm::APSInt *getKnownValue(const GRState *state, SVal V); virtual const llvm::APSInt *getKnownValue(const GRState *state, SVal V);
@ -52,7 +52,7 @@ SValBuilder *clang::createSimpleSValBuilder(ValueManager &valMgr) {
// Transfer function for Casts. // Transfer function for Casts.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
SVal SimpleSValBuilder::EvalCastNL(NonLoc val, QualType castTy) { SVal SimpleSValBuilder::evalCastNL(NonLoc val, QualType castTy) {
bool isLocType = Loc::IsLocType(castTy); bool isLocType = Loc::IsLocType(castTy);
@ -104,7 +104,7 @@ SVal SimpleSValBuilder::EvalCastNL(NonLoc val, QualType castTy) {
return ValMgr.makeIntVal(i); 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. // Casts from pointers -> pointers, just return the lval.
// //
@ -142,7 +142,7 @@ SVal SimpleSValBuilder::EvalCastL(Loc val, QualType castTy) {
// Transfer function for unary operators. // Transfer function for unary operators.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
SVal SimpleSValBuilder::EvalMinus(NonLoc val) { SVal SimpleSValBuilder::evalMinus(NonLoc val) {
switch (val.getSubKind()) { switch (val.getSubKind()) {
case nonloc::ConcreteIntKind: case nonloc::ConcreteIntKind:
return cast<nonloc::ConcreteInt>(val).evalMinus(ValMgr); 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()) { switch (X.getSubKind()) {
case nonloc::ConcreteIntKind: case nonloc::ConcreteIntKind:
return cast<nonloc::ConcreteInt>(X).evalComplement(ValMgr); 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. // 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 (isIdempotent) {
if (SymbolRef LHSSym = dyn_cast<SymbolData>(LHS)) if (SymbolRef LHSSym = dyn_cast<SymbolData>(LHS))
return EvalCastNL(nonloc::SymbolVal(LHSSym), resultTy); return evalCastNL(nonloc::SymbolVal(LHSSym), resultTy);
return EvalCastNL(nonloc::SymExprVal(LHS), resultTy); return evalCastNL(nonloc::SymExprVal(LHS), resultTy);
} }
// If we reach this point, the expression cannot be simplified. // 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); return ValMgr.makeNonLoc(LHS, op, RHS, resultTy);
} }
SVal SimpleSValBuilder::EvalBinOpNN(const GRState *state, SVal SimpleSValBuilder::evalBinOpNN(const GRState *state,
BinaryOperator::Opcode op, BinaryOperator::Opcode op,
NonLoc lhs, NonLoc rhs, NonLoc lhs, NonLoc rhs,
QualType resultTy) { QualType resultTy) {
@ -288,7 +288,7 @@ SVal SimpleSValBuilder::EvalBinOpNN(const GRState *state,
return ValMgr.makeIntVal(0, resultTy); return ValMgr.makeIntVal(0, resultTy);
case BO_Or: case BO_Or:
case BO_And: case BO_And:
return EvalCastNL(lhs, resultTy); return evalCastNL(lhs, resultTy);
} }
while (1) { while (1) {
@ -299,7 +299,7 @@ SVal SimpleSValBuilder::EvalBinOpNN(const GRState *state,
Loc lhsL = cast<nonloc::LocAsInteger>(lhs).getLoc(); Loc lhsL = cast<nonloc::LocAsInteger>(lhs).getLoc();
switch (rhs.getSubKind()) { switch (rhs.getSubKind()) {
case nonloc::LocAsIntegerKind: case nonloc::LocAsIntegerKind:
return EvalBinOpLL(state, op, lhsL, return evalBinOpLL(state, op, lhsL,
cast<nonloc::LocAsInteger>(rhs).getLoc(), cast<nonloc::LocAsInteger>(rhs).getLoc(),
resultTy); resultTy);
case nonloc::ConcreteIntKind: { case nonloc::ConcreteIntKind: {
@ -308,7 +308,7 @@ SVal SimpleSValBuilder::EvalBinOpNN(const GRState *state,
llvm::APSInt i = cast<nonloc::ConcreteInt>(rhs).getValue(); llvm::APSInt i = cast<nonloc::ConcreteInt>(rhs).getValue();
i.setIsUnsigned(true); i.setIsUnsigned(true);
i.extOrTrunc(Ctx.getTypeSize(Ctx.VoidPtrTy)); 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: default:
switch (op) { switch (op) {
@ -402,9 +402,9 @@ SVal SimpleSValBuilder::EvalBinOpNN(const GRState *state,
const llvm::APSInt *newRHS; const llvm::APSInt *newRHS;
if (lop == op) if (lop == op)
newRHS = BVF.EvaluateAPSInt(BO_Add, first, second); newRHS = BVF.evalAPSInt(BO_Add, first, second);
else else
newRHS = BVF.EvaluateAPSInt(BO_Sub, first, second); newRHS = BVF.evalAPSInt(BO_Sub, first, second);
return MakeSymIntVal(symIntExpr->getLHS(), lop, *newRHS, resultTy); 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(). // 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, BinaryOperator::Opcode op,
Loc lhs, Loc rhs, Loc lhs, Loc rhs,
QualType resultTy) { QualType resultTy) {
// Only comparisons and subtractions are valid operations on two pointers. // 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]. // 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 // calling this function with another operation (PR7527). We don't attempt to
// model this for now, but it could be useful, particularly when the // 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*. // "location" is actually an integer value that's been passed through a void*.
@ -559,7 +559,7 @@ SVal SimpleSValBuilder::EvalBinOpLL(const GRState *state,
default: default:
break; break;
case BO_Sub: case BO_Sub:
return EvalCastL(lhs, resultTy); return evalCastL(lhs, resultTy);
case BO_EQ: case BO_EQ:
case BO_LE: case BO_LE:
case BO_LT: case BO_LT:
@ -593,9 +593,9 @@ SVal SimpleSValBuilder::EvalBinOpLL(const GRState *state,
// If both operands are constants, just perform the operation. // If both operands are constants, just perform the operation.
if (loc::ConcreteInt *rInt = dyn_cast<loc::ConcreteInt>(&rhs)) { if (loc::ConcreteInt *rInt = dyn_cast<loc::ConcreteInt>(&rhs)) {
BasicValueFactory &BVF = ValMgr.getBasicValueFactory(); 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)) if (Loc *Result = dyn_cast<Loc>(&ResultVal))
return EvalCastL(*Result, resultTy); return evalCastL(*Result, resultTy);
else else
return UnknownVal(); return UnknownVal();
} }
@ -640,7 +640,7 @@ SVal SimpleSValBuilder::EvalBinOpLL(const GRState *state,
default: default:
break; break;
case BO_Sub: case BO_Sub:
return EvalCastL(lhs, resultTy); return evalCastL(lhs, resultTy);
case BO_EQ: case BO_EQ:
case BO_LT: case BO_LT:
case BO_LE: case BO_LE:
@ -705,7 +705,7 @@ SVal SimpleSValBuilder::EvalBinOpLL(const GRState *state,
NonLoc *LeftIndex = dyn_cast<NonLoc>(&LeftIndexVal); NonLoc *LeftIndex = dyn_cast<NonLoc>(&LeftIndexVal);
if (!LeftIndex) if (!LeftIndex)
return UnknownVal(); return UnknownVal();
LeftIndexVal = EvalCastNL(*LeftIndex, resultTy); LeftIndexVal = evalCastNL(*LeftIndex, resultTy);
LeftIndex = dyn_cast<NonLoc>(&LeftIndexVal); LeftIndex = dyn_cast<NonLoc>(&LeftIndexVal);
if (!LeftIndex) if (!LeftIndex)
return UnknownVal(); return UnknownVal();
@ -715,14 +715,14 @@ SVal SimpleSValBuilder::EvalBinOpLL(const GRState *state,
NonLoc *RightIndex = dyn_cast<NonLoc>(&RightIndexVal); NonLoc *RightIndex = dyn_cast<NonLoc>(&RightIndexVal);
if (!RightIndex) if (!RightIndex)
return UnknownVal(); return UnknownVal();
RightIndexVal = EvalCastNL(*RightIndex, resultTy); RightIndexVal = evalCastNL(*RightIndex, resultTy);
RightIndex = dyn_cast<NonLoc>(&RightIndexVal); RightIndex = dyn_cast<NonLoc>(&RightIndexVal);
if (!RightIndex) if (!RightIndex)
return UnknownVal(); return UnknownVal();
// Actually perform the operation. // Actually perform the operation.
// EvalBinOpNN expects the two indexes to already be the right type. // evalBinOpNN expects the two indexes to already be the right type.
return EvalBinOpNN(state, op, *LeftIndex, *RightIndex, resultTy); return evalBinOpNN(state, op, *LeftIndex, *RightIndex, resultTy);
} }
// If the element indexes aren't comparable, see if the raw offsets are. // 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, BinaryOperator::Opcode op,
Loc lhs, NonLoc rhs, QualType resultTy) { Loc lhs, NonLoc rhs, QualType resultTy) {
// Special case: 'rhs' is an integer that has the same width as a pointer and // 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()) if (x->isSigned())
x = &ValMgr.getBasicValueFactory().getValue(*x, true); 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. // Delegate remaining pointer arithmetic to the StoreManager.
return state->getStateManager().getStoreManager().EvalBinOp(op, lhs, return state->getStateManager().getStoreManager().evalBinOp(op, lhs,
rhs, resultTy); rhs, resultTy);
} }

View File

@ -32,7 +32,7 @@ public:
return &x; return &x;
} }
void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *RS); void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *RS);
void EvalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng); void evalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng);
private: private:
void EmitStackError(CheckerContext &C, const MemRegion *R, const Expr *RetE); void EmitStackError(CheckerContext &C, const MemRegion *R, const Expr *RetE);
SourceRange GenName(llvm::raw_ostream &os, const MemRegion *R, 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) { GRExprEngine &Eng) {
SaveAndRestore<bool> OldHasGen(B.HasGeneratedNode); SaveAndRestore<bool> OldHasGen(B.HasGeneratedNode);
const GRState *state = B.getState(); const GRState *state = B.getState();

View File

@ -225,9 +225,9 @@ SVal StoreManager::CastRetrievedVal(SVal V, const TypedRegion *R,
} }
if (const Loc *L = dyn_cast<Loc>(&V)) 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)) else if (const NonLoc *NL = dyn_cast<NonLoc>(&V))
return ValMgr.getSValBuilder().EvalCastNL(*NL, castTy); return ValMgr.getSValBuilder().evalCastNL(*NL, castTy);
return V; return V;
} }

View File

@ -72,9 +72,9 @@ public:
return &x; return &x;
} }
virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE); virtual bool evalCallExpr(CheckerContext &C, const CallExpr *CE);
void EvalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper); void evalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper);
void EvalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng); void evalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng);
void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *S); void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *S);
private: private:
@ -115,7 +115,7 @@ void clang::RegisterStreamChecker(GRExprEngine &Eng) {
Eng.registerCheck(new StreamChecker()); 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 GRState *state = C.getState();
const Expr *Callee = CE->getCallee(); const Expr *Callee = CE->getCallee();
SVal L = state->getSVal(Callee); SVal L = state->getSVal(Callee);
@ -395,7 +395,7 @@ const GRState *StreamChecker::CheckDoubleClose(const CallExpr *CE,
return state->set<StreamState>(Sym, StreamState::getClosed(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(), for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
E = SymReaper.dead_end(); I != E; ++I) { E = SymReaper.dead_end(); I != E; ++I) {
SymbolRef Sym = *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) { GRExprEngine &Eng) {
SaveAndRestore<bool> OldHasGen(B.HasGeneratedNode); SaveAndRestore<bool> OldHasGen(B.HasGeneratedNode);
const GRState *state = B.getState(); const GRState *state = B.getState();

View File

@ -101,7 +101,7 @@ static void CheckOpen(CheckerContext &C, UnixAPIChecker &UC,
NonLoc ocreateFlag = NonLoc ocreateFlag =
cast<NonLoc>(C.getValueManager().makeIntVal(UC.Val_O_CREAT.getValue(), cast<NonLoc>(C.getValueManager().makeIntVal(UC.Val_O_CREAT.getValue(),
oflagsEx->getType())); oflagsEx->getType()));
SVal maskedFlagsUC = C.getSValBuilder().EvalBinOpNN(state, BO_And, SVal maskedFlagsUC = C.getSValBuilder().evalBinOpNN(state, BO_And,
oflags, ocreateFlag, oflags, ocreateFlag,
oflagsEx->getType()); oflagsEx->getType());
if (maskedFlagsUC.isUnknownOrUndef()) if (maskedFlagsUC.isUnknownOrUndef())

View File

@ -110,21 +110,21 @@ void VLASizeChecker::PreVisitDeclStmt(CheckerContext &C, const DeclStmt *DS) {
ValueManager &ValMgr = C.getValueManager(); ValueManager &ValMgr = C.getValueManager();
SValBuilder &SV = ValMgr.getSValBuilder(); SValBuilder &SV = ValMgr.getSValBuilder();
QualType SizeTy = Ctx.getSizeType(); 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. // Get the element size.
CharUnits EleSize = Ctx.getTypeSizeInChars(VLA->getElementType()); CharUnits EleSize = Ctx.getTypeSizeInChars(VLA->getElementType());
SVal EleSizeVal = ValMgr.makeIntVal(EleSize.getQuantity(), SizeTy); SVal EleSizeVal = ValMgr.makeIntVal(EleSize.getQuantity(), SizeTy);
// Multiply the array length by the element size. // 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); cast<NonLoc>(EleSizeVal), SizeTy);
// Finally, Assume that the array's extent matches the given size. // Finally, Assume that the array's extent matches the given size.
const LocationContext *LC = C.getPredecessor()->getLocationContext(); const LocationContext *LC = C.getPredecessor()->getLocationContext();
DefinedOrUnknownSVal Extent = state->getRegion(VD, LC)->getExtent(ValMgr); DefinedOrUnknownSVal Extent = state->getRegion(VD, LC)->getExtent(ValMgr);
DefinedOrUnknownSVal ArraySize = cast<DefinedOrUnknownSVal>(ArraySizeVal); DefinedOrUnknownSVal ArraySize = cast<DefinedOrUnknownSVal>(ArraySizeVal);
DefinedOrUnknownSVal SizeIsKnown = SV.EvalEQ(state, Extent, ArraySize); DefinedOrUnknownSVal SizeIsKnown = SV.evalEQ(state, Extent, ArraySize);
state = state->Assume(SizeIsKnown, true); state = state->Assume(SizeIsKnown, true);
// Assume should not fail at this point. // Assume should not fail at this point.

View File

@ -67,7 +67,7 @@ SVal ValueManager::convertToArrayIndex(SVal V) {
return V; return V;
} }
return svalBuilder->EvalCastNL(cast<NonLoc>(V), ArrayIndexTy); return svalBuilder->evalCastNL(cast<NonLoc>(V), ArrayIndexTy);
} }
DefinedOrUnknownSVal DefinedOrUnknownSVal