aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/GRExprEngine.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-07-10 22:03:41 +0000
committerTed Kremenek <kremenek@apple.com>2008-07-10 22:03:41 +0000
commit4323a57627e796dcfdfdb7d47672dc09ed308eda (patch)
treed134b1a85f9ec16f0db46f4b7f6bc4e1ead64b25 /lib/Analysis/GRExprEngine.cpp
parente5690319a0e834b9bd9dcb5e444e59ecc5da3105 (diff)
Refactored most of the "Store" piece of ValueState into a Store type. The
current store implementation is now encapsulated by BasicStore. These changes prompted some long due constification of ValueState. Much of the diffs in this patch include adding "const" qualifiers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53423 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/GRExprEngine.cpp')
-rw-r--r--lib/Analysis/GRExprEngine.cpp133
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: