diff options
Diffstat (limited to 'lib/Analysis/GRExprEngine.cpp')
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 133 |
1 files changed, 70 insertions, 63 deletions
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index c4eddb9993..96e7fae7e3 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -18,6 +18,8 @@ #include "clang/Basic/SourceManager.h" #include "llvm/Support/Streams.h" +#include "clang/Analysis/PathSensitive/BasicStore.h" + #ifndef NDEBUG #include "llvm/Support/GraphWriter.h" #include <sstream> @@ -44,7 +46,8 @@ GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, G(CoreEngine.getGraph()), Liveness(L), Builder(NULL), - StateMgr(G.getContext(), G.getAllocator()), + StateMgr(G.getContext(), CreateBasicStoreManager(G.getAllocator()), + G.getAllocator()), BasicVals(StateMgr.getBasicValueFactory()), TF(NULL), // FIXME SymMgr(StateMgr.getSymbolManager()), @@ -127,7 +130,7 @@ void GRExprEngine::AddObjCMessageExprCheck(GRSimpleAPICheck* A) { MsgExprChecks.push_back(A); } -ValueState* GRExprEngine::getInitialState() { +const ValueState* GRExprEngine::getInitialState() { // The LiveVariables information already has a compilation of all VarDecls // used in the function. Iterate through this set, and "symbolicate" @@ -144,11 +147,11 @@ ValueState* GRExprEngine::getInitialState() { if (VarDecl* VD = dyn_cast<VarDecl>(SD)) { if (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD)) { RVal X = RVal::GetSymbolValue(SymMgr, VD); - StateMgr.BindVar(StateImpl, VD, X); + StateMgr.SetRVal(StateImpl, lval::DeclVal(VD), X); } } else if (ImplicitParamDecl *IPD = dyn_cast<ImplicitParamDecl>(SD)) { RVal X = RVal::GetSymbolValue(SymMgr, IPD); - StateMgr.BindVar(StateImpl, IPD, X); + StateMgr.SetRVal(StateImpl, lval::DeclVal(IPD), X); } @@ -157,7 +160,8 @@ ValueState* GRExprEngine::getInitialState() { return StateMgr.getPersistentState(StateImpl); } -ValueState* GRExprEngine::SetRVal(ValueState* St, Expr* Ex, RVal V) { +const ValueState* GRExprEngine::SetRVal(const ValueState* St, Expr* Ex, + RVal V) { bool isBlkExpr = false; @@ -285,7 +289,7 @@ void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) { break; } else if (B->getOpcode() == BinaryOperator::Comma) { - ValueState* St = GetState(Pred); + const ValueState* St = GetState(Pred); MakeNode(Dst, B, Pred, SetRVal(St, B, GetRVal(St, B->getRHS()))); break; } @@ -364,7 +368,7 @@ void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) { case Stmt::StmtExprClass: { StmtExpr* SE = cast<StmtExpr>(S); - ValueState* St = GetState(Pred); + const ValueState* St = GetState(Pred); // FIXME: Not certain if we can have empty StmtExprs. If so, we should // probably just remove these from the CFG. @@ -420,7 +424,7 @@ void GRExprEngine::VisitLVal(Expr* Ex, NodeTy* Pred, NodeSet& Dst) { // Block entrance. (Update counters). //===----------------------------------------------------------------------===// -bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, ValueState*, +bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, const ValueState*, GRBlockCounter BC) { return BC.getNumVisited(B->getBlockID()) < 3; @@ -430,8 +434,9 @@ bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, ValueState*, // Branch processing. //===----------------------------------------------------------------------===// -ValueState* GRExprEngine::MarkBranch(ValueState* St, Stmt* Terminator, - bool branchTaken) { +const ValueState* GRExprEngine::MarkBranch(const ValueState* St, + Stmt* Terminator, + bool branchTaken) { switch (Terminator->getStmtClass()) { default: @@ -488,7 +493,8 @@ void GRExprEngine::ProcessBranch(Expr* Condition, Stmt* Term, BranchNodeBuilder& builder) { // Remove old bindings for subexpressions. - ValueState* PrevState = StateMgr.RemoveSubExprBindings(builder.getState()); + const ValueState* PrevState = + StateMgr.RemoveSubExprBindings(builder.getState()); // Check for NULL conditions; e.g. "for(;;)" if (!Condition) { @@ -523,7 +529,7 @@ void GRExprEngine::ProcessBranch(Expr* Condition, Stmt* Term, // Process the true branch. bool isFeasible = false; - ValueState* St = Assume(PrevState, V, true, isFeasible); + const ValueState* St = Assume(PrevState, V, true, isFeasible); if (isFeasible) builder.generateNode(MarkBranch(St, Term, true), true); @@ -545,7 +551,7 @@ void GRExprEngine::ProcessBranch(Expr* Condition, Stmt* Term, /// nodes by processing the 'effects' of a computed goto jump. void GRExprEngine::ProcessIndirectGoto(IndirectGotoNodeBuilder& builder) { - ValueState* St = builder.getState(); + const ValueState* St = builder.getState(); RVal V = GetRVal(St, builder.getTarget()); // Three possibilities: @@ -592,7 +598,7 @@ void GRExprEngine::VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R, assert (Ex == CurrentStmt && getCFG().isBlkExpr(Ex)); - ValueState* St = GetState(Pred); + const ValueState* St = GetState(Pred); RVal X = GetBlkExprRVal(St, Ex); assert (X.isUndef()); @@ -613,7 +619,7 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) { typedef SwitchNodeBuilder::iterator iterator; - ValueState* St = builder.getState(); + const ValueState* St = builder.getState(); Expr* CondE = builder.getCondition(); RVal CondV = GetRVal(St, CondE); @@ -623,7 +629,7 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) { return; } - ValueState* DefaultSt = St; + const ValueState* DefaultSt = St; // While most of this can be assumed (such as the signedness), having it // just computed makes sure everything makes the same assumptions end-to-end. @@ -670,7 +676,7 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) { // Now "assume" that the case matches. bool isFeasible = false; - ValueState* StNew = Assume(St, Res, true, isFeasible); + const ValueState* StNew = Assume(St, Res, true, isFeasible); if (isFeasible) { builder.generateCaseStmtNode(I, StNew); @@ -720,7 +726,7 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred, assert (B == CurrentStmt && getCFG().isBlkExpr(B)); - ValueState* St = GetState(Pred); + const ValueState* St = GetState(Pred); RVal X = GetBlkExprRVal(St, B); assert (X.isUndef()); @@ -748,7 +754,7 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred, // the payoff is not likely to be large. Instead, we do eager evaluation. bool isFeasible = false; - ValueState* NewState = Assume(St, X, true, isFeasible); + const ValueState* NewState = Assume(St, X, true, isFeasible); if (isFeasible) MakeNode(Dst, B, Pred, @@ -778,7 +784,7 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred, void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* D, NodeTy* Pred, NodeSet& Dst, bool asLVal) { - ValueState* St = GetState(Pred); + const ValueState* St = GetState(Pred); RVal X = RVal::MakeVal(BasicVals, D); if (asLVal) @@ -814,7 +820,7 @@ void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A, NodeTy* Pred, for (NodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end(); I2!=E2; ++I2) { - ValueState* St = GetState(*I2); + const ValueState* St = GetState(*I2); RVal BaseV = GetRVal(St, Base); RVal IdxV = GetRVal(St, Idx); @@ -853,7 +859,7 @@ void GRExprEngine::VisitMemberExpr(MemberExpr* M, NodeTy* Pred, VisitLVal(Base, Pred, Tmp); for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); RVal BaseV = GetRVal(St, Base); RVal V = lval::FieldOffset::Make(BasicVals, GetRVal(St, Base), @@ -871,7 +877,7 @@ void GRExprEngine::VisitMemberExpr(MemberExpr* M, NodeTy* Pred, for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); RVal BaseV = GetRVal(St, Base); if (LVal::IsLValType(Base->getType())) { @@ -900,7 +906,7 @@ void GRExprEngine::VisitMemberExpr(MemberExpr* M, NodeTy* Pred, } void GRExprEngine::EvalStore(NodeSet& Dst, Expr* Ex, NodeTy* Pred, - ValueState* St, RVal location, RVal Val) { + const ValueState* St, RVal location, RVal Val) { assert (Builder && "GRStmtNodeBuilder must be defined."); @@ -930,7 +936,8 @@ void GRExprEngine::EvalStore(NodeSet& Dst, Expr* Ex, NodeTy* Pred, } void GRExprEngine::EvalLoad(NodeSet& Dst, Expr* Ex, NodeTy* Pred, - ValueState* St, RVal location, bool CheckOnly) { + const ValueState* St, RVal location, + bool CheckOnly) { // Evaluate the location (checks for bad dereferences). @@ -958,9 +965,9 @@ void GRExprEngine::EvalLoad(NodeSet& Dst, Expr* Ex, NodeTy* Pred, Ex->getType()))); } -ValueState* GRExprEngine::EvalLocation(Expr* Ex, NodeTy* Pred, - ValueState* St, RVal location, - bool isLoad) { +const ValueState* GRExprEngine::EvalLocation(Expr* Ex, NodeTy* Pred, + const ValueState* St, + RVal location, bool isLoad) { // Check for loads/stores from/to undefined values. if (location.isUndef()) { @@ -990,12 +997,12 @@ ValueState* GRExprEngine::EvalLocation(Expr* Ex, NodeTy* Pred, // "Assume" that the pointer is not NULL. bool isFeasibleNotNull = false; - ValueState* StNotNull = Assume(St, LV, true, isFeasibleNotNull); + const ValueState* StNotNull = Assume(St, LV, true, isFeasibleNotNull); // "Assume" that the pointer is NULL. bool isFeasibleNull = false; - ValueState* StNull = Assume(St, LV, false, isFeasibleNull); + const ValueState* StNull = Assume(St, LV, false, isFeasibleNull); if (isFeasibleNull) { @@ -1053,7 +1060,7 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred, // Finally, evaluate the function call. for (NodeSet::iterator DI = DstTmp.begin(), DE = DstTmp.end(); DI!=DE; ++DI) { - ValueState* St = GetState(*DI); + const ValueState* St = GetState(*DI); RVal L = GetRVal(St, Callee); // FIXME: Add support for symbolic function calls (calls involving @@ -1246,7 +1253,7 @@ void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME, // FIXME: More logic for the processing the method call. - ValueState* St = GetState(Pred); + const ValueState* St = GetState(Pred); bool RaisesException = false; @@ -1391,7 +1398,7 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){ for (NodeSet::iterator I1 = S1.begin(), E1 = S1.end(); I1 != E1; ++I1) { NodeTy* N = *I1; - ValueState* St = GetState(N); + const ValueState* St = GetState(N); RVal V = GetRVal(St, Ex); // Unknown? @@ -1470,7 +1477,7 @@ void GRExprEngine::VisitDeclStmtAux(DeclStmt* DS, ScopedDecl* D, for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); if (!Ex && VD->hasGlobalStorage()) { @@ -1601,7 +1608,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); RVal location = GetRVal(St, Ex); if (asLVal) @@ -1630,7 +1637,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, // For all other types, UnaryOperator::Real is an identity operation. assert (U->getType() == Ex->getType()); - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); MakeNode(Dst, U, *I, SetRVal(St, U, GetRVal(St, Ex))); } @@ -1653,7 +1660,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, // For all other types, UnaryOperator::Float returns 0. assert (Ex->getType()->isIntegerType()); - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); RVal X = NonLVal::MakeVal(BasicVals, 0, Ex->getType()); MakeNode(Dst, U, *I, SetRVal(St, U, X)); } @@ -1679,7 +1686,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, Visit(Ex, Pred, Tmp); for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); MakeNode(Dst, U, *I, SetRVal(St, U, GetRVal(St, Ex))); } @@ -1694,7 +1701,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, VisitLVal(Ex, Pred, Tmp); for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); RVal V = GetRVal(St, Ex); St = SetRVal(St, U, V); MakeNode(Dst, U, *I, St); @@ -1713,7 +1720,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, Visit(Ex, Pred, Tmp); for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); RVal V = GetRVal(St, Ex); if (V.isUnknownOrUndef()) { @@ -1771,7 +1778,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, return; uint64_t size = getContext().getTypeSize(T) / 8; - ValueState* St = GetState(Pred); + const ValueState* St = GetState(Pred); St = SetRVal(St, U, NonLVal::MakeVal(BasicVals, size, U->getType())); MakeNode(Dst, U, Pred, St); @@ -1788,7 +1795,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, for (NodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) { - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); RVal V1 = GetRVal(St, Ex); // Perform a load. @@ -1855,7 +1862,7 @@ void GRExprEngine::VisitAsmStmtHelperInputs(AsmStmt* A, // which interprets the inline asm and stores proper results in the // outputs. - ValueState* St = GetState(Pred); + const ValueState* St = GetState(Pred); for (AsmStmt::outputs_iterator OI = A->begin_outputs(), OE = A->end_outputs(); OI != OE; ++OI) { @@ -1949,7 +1956,7 @@ void GRExprEngine::VisitReturnStmt(ReturnStmt* S, NodeTy* Pred, NodeSet& Dst) { // Transfer functions: Binary operators. //===----------------------------------------------------------------------===// -bool GRExprEngine::CheckDivideZero(Expr* Ex, ValueState* St, +bool GRExprEngine::CheckDivideZero(Expr* Ex, const ValueState* St, NodeTy* Pred, RVal Denom) { // Divide by undefined? (potentially zero) @@ -1969,7 +1976,7 @@ bool GRExprEngine::CheckDivideZero(Expr* Ex, ValueState* St, // First, "assume" that the denominator is 0 or undefined. bool isFeasibleZero = false; - ValueState* ZeroSt = Assume(St, Denom, false, isFeasibleZero); + const ValueState* ZeroSt = Assume(St, Denom, false, isFeasibleZero); // Second, "assume" that the denominator cannot be 0. @@ -2018,7 +2025,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, for (NodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end(); I2 != E2; ++I2) { - ValueState* St = GetState(*I2); + const ValueState* St = GetState(*I2); RVal RightV = GetRVal(St, RHS); BinaryOperator::Opcode Op = B->getOpcode(); @@ -2175,8 +2182,8 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, // "Assume" logic. //===----------------------------------------------------------------------===// -ValueState* GRExprEngine::Assume(ValueState* St, LVal Cond, - bool Assumption, bool& isFeasible) { +const ValueState* GRExprEngine::Assume(const ValueState* St, LVal Cond, + bool Assumption, bool& isFeasible) { St = AssumeAux(St, Cond, Assumption, isFeasible); @@ -2184,8 +2191,8 @@ ValueState* GRExprEngine::Assume(ValueState* St, LVal Cond, : St; } -ValueState* GRExprEngine::AssumeAux(ValueState* St, LVal Cond, - bool Assumption, bool& isFeasible) { +const ValueState* GRExprEngine::AssumeAux(const ValueState* St, LVal Cond, + bool Assumption, bool& isFeasible) { switch (Cond.getSubKind()) { default: @@ -2224,8 +2231,8 @@ ValueState* GRExprEngine::AssumeAux(ValueState* St, LVal Cond, } } -ValueState* GRExprEngine::Assume(ValueState* St, NonLVal Cond, - bool Assumption, bool& isFeasible) { +const ValueState* GRExprEngine::Assume(const ValueState* St, NonLVal Cond, + bool Assumption, bool& isFeasible) { St = AssumeAux(St, Cond, Assumption, isFeasible); @@ -2233,8 +2240,8 @@ ValueState* GRExprEngine::Assume(ValueState* St, NonLVal Cond, : St; } -ValueState* GRExprEngine::AssumeAux(ValueState* St, NonLVal Cond, - bool Assumption, bool& isFeasible) { +const ValueState* GRExprEngine::AssumeAux(const ValueState* St, NonLVal Cond, + bool Assumption, bool& isFeasible) { switch (Cond.getSubKind()) { default: assert (false && "'Assume' not implemented for this NonLVal."); @@ -2272,9 +2279,9 @@ ValueState* GRExprEngine::AssumeAux(ValueState* St, NonLVal Cond, } } -ValueState* -GRExprEngine::AssumeSymNE(ValueState* St, SymbolID sym, - const llvm::APSInt& V, bool& isFeasible) { +const ValueState* GRExprEngine::AssumeSymNE(const ValueState* St, + SymbolID sym, const llvm::APSInt& V, + bool& isFeasible) { // First, determine if sym == X, where X != V. if (const llvm::APSInt* X = St->getSymVal(sym)) { @@ -2295,9 +2302,8 @@ GRExprEngine::AssumeSymNE(ValueState* St, SymbolID sym, return StateMgr.AddNE(St, sym, V); } -ValueState* -GRExprEngine::AssumeSymEQ(ValueState* St, SymbolID sym, - const llvm::APSInt& V, bool& isFeasible) { +const ValueState* GRExprEngine::AssumeSymEQ(const ValueState* St, SymbolID sym, + const llvm::APSInt& V, bool& isFeasible) { // First, determine if sym == X, where X != V. if (const llvm::APSInt* X = St->getSymVal(sym)) { @@ -2318,9 +2324,10 @@ GRExprEngine::AssumeSymEQ(ValueState* St, SymbolID sym, return StateMgr.AddEQ(St, sym, V); } -ValueState* -GRExprEngine::AssumeSymInt(ValueState* St, bool Assumption, - const SymIntConstraint& C, bool& isFeasible) { +const ValueState* GRExprEngine::AssumeSymInt(const ValueState* St, + bool Assumption, + const SymIntConstraint& C, + bool& isFeasible) { switch (C.getOpcode()) { default: |