aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/GRExprEngine.cpp
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-09-09 15:08:12 +0000
committerMike Stump <mrs@apple.com>2009-09-09 15:08:12 +0000
commit1eb4433ac451dc16f4133a88af2d002ac26c58ef (patch)
tree07065b80cb7787bb7b9ffcb985196007a57e86f7 /lib/Analysis/GRExprEngine.cpp
parent79d39f92590cf2e91bf81486b02cd1156d13ca54 (diff)
Remove tabs, and whitespace cleanups.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81346 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/GRExprEngine.cpp')
-rw-r--r--lib/Analysis/GRExprEngine.cpp1247
1 files changed, 623 insertions, 624 deletions
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 053da67c7d..b4b69cdcd6 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -44,7 +44,7 @@ namespace {
class VISIBILITY_HIDDEN MappedBatchAuditor : public GRSimpleAPICheck {
typedef llvm::ImmutableList<GRSimpleAPICheck*> Checks;
typedef llvm::DenseMap<void*,Checks> MapTy;
-
+
MapTy M;
Checks::Factory F;
Checks AllStmts;
@@ -52,18 +52,18 @@ class VISIBILITY_HIDDEN MappedBatchAuditor : public GRSimpleAPICheck {
public:
MappedBatchAuditor(llvm::BumpPtrAllocator& Alloc) :
F(Alloc), AllStmts(F.GetEmptyList()) {}
-
+
virtual ~MappedBatchAuditor() {
llvm::DenseSet<GRSimpleAPICheck*> AlreadyVisited;
-
+
for (MapTy::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI)
for (Checks::iterator I=MI->second.begin(), E=MI->second.end(); I!=E;++I){
GRSimpleAPICheck* check = *I;
-
+
if (AlreadyVisited.count(check))
continue;
-
+
AlreadyVisited.insert(check);
delete check;
}
@@ -75,10 +75,10 @@ public:
MapTy::iterator I = M.find(key);
M[key] = F.Concat(A, I == M.end() ? F.GetEmptyList() : I->second);
}
-
+
void AddCheck(GRSimpleAPICheck *A) {
assert (A && "Check cannot be null.");
- AllStmts = F.Concat(A, AllStmts);
+ AllStmts = F.Concat(A, AllStmts);
}
virtual bool Audit(ExplodedNode* N, GRStateManager& VMgr) {
@@ -86,17 +86,17 @@ public:
bool isSink = false;
for (Checks::iterator I = AllStmts.begin(), E = AllStmts.end(); I!=E; ++I)
isSink |= (*I)->Audit(N, VMgr);
-
+
// Next handle the auditors that accept only specific statements.
const Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
void* key = reinterpret_cast<void*>((uintptr_t) S->getStmtClass());
MapTy::iterator MI = M.find(key);
- if (MI != M.end()) {
+ if (MI != M.end()) {
for (Checks::iterator I=MI->second.begin(), E=MI->second.end(); I!=E; ++I)
isSink |= (*I)->Audit(N, VMgr);
}
-
- return isSink;
+
+ return isSink;
}
};
@@ -105,30 +105,30 @@ public:
//===----------------------------------------------------------------------===//
// Checker worklist routines.
//===----------------------------------------------------------------------===//
-
-void GRExprEngine::CheckerVisit(Stmt *S, ExplodedNodeSet &Dst,
+
+void GRExprEngine::CheckerVisit(Stmt *S, ExplodedNodeSet &Dst,
ExplodedNodeSet &Src, bool isPrevisit) {
-
+
if (Checkers.empty()) {
Dst = Src;
return;
}
-
+
ExplodedNodeSet Tmp;
ExplodedNodeSet *PrevSet = &Src;
-
+
for (std::vector<Checker*>::iterator I = Checkers.begin(), E = Checkers.end();
I != E; ++I) {
- ExplodedNodeSet *CurrSet = (I+1 == E) ? &Dst
+ ExplodedNodeSet *CurrSet = (I+1 == E) ? &Dst
: (PrevSet == &Tmp) ? &Src : &Tmp;
CurrSet->clear();
Checker *checker = *I;
-
+
for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
NI != NE; ++NI)
checker->GR_Visit(*CurrSet, *Builder, *this, S, *NI, isPrevisit);
-
+
// Update which NodeSet is the current one.
PrevSet = CurrSet;
}
@@ -149,20 +149,20 @@ static inline Selector GetNullarySelector(const char* name, ASTContext& Ctx) {
GRExprEngine::GRExprEngine(AnalysisManager &mgr)
: AMgr(mgr),
- CoreEngine(mgr.getASTContext(), *this),
+ CoreEngine(mgr.getASTContext(), *this),
G(CoreEngine.getGraph()),
Builder(NULL),
- StateMgr(G.getContext(), mgr.getStoreManagerCreator(),
+ StateMgr(G.getContext(), mgr.getStoreManagerCreator(),
mgr.getConstraintManagerCreator(), G.getAllocator()),
SymMgr(StateMgr.getSymbolManager()),
ValMgr(StateMgr.getValueManager()),
SVator(ValMgr.getSValuator()),
CurrentStmt(NULL),
NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
- RaiseSel(GetNullarySelector("raise", G.getContext())),
+ RaiseSel(GetNullarySelector("raise", G.getContext())),
BR(mgr, *this) {}
-GRExprEngine::~GRExprEngine() {
+GRExprEngine::~GRExprEngine() {
BR.FlushReports();
delete [] NSExceptionInstanceRaiseSelectors;
for (std::vector<Checker*>::iterator I=Checkers.begin(), E=Checkers.end();
@@ -184,7 +184,7 @@ void GRExprEngine::setTransferFunctions(GRTransferFuncs* tf) {
void GRExprEngine::AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C) {
if (!BatchAuditor)
BatchAuditor.reset(new MappedBatchAuditor(getGraph().getAllocator()));
-
+
((MappedBatchAuditor*) BatchAuditor.get())->AddCheck(A, C);
}
@@ -197,7 +197,7 @@ void GRExprEngine::AddCheck(GRSimpleAPICheck *A) {
const GRState* GRExprEngine::getInitialState(const LocationContext *InitLoc) {
const GRState *state = StateMgr.getInitialState(InitLoc);
-
+
// Precondition: the first argument of 'main' is an integer guaranteed
// to be > 0.
// FIXME: It would be nice if we had a more general mechanism to add
@@ -212,13 +212,13 @@ const GRState* GRExprEngine::getInitialState(const LocationContext *InitLoc) {
SVal V = state->getSVal(loc::MemRegionVal(R));
SVal Constraint = EvalBinOp(state, BinaryOperator::GT, V,
ValMgr.makeZeroVal(T),
- getContext().IntTy);
+ getContext().IntTy);
if (const GRState *newState = state->assume(Constraint, true))
state = newState;
}
}
-
+
return state;
}
@@ -227,31 +227,31 @@ const GRState* GRExprEngine::getInitialState(const LocationContext *InitLoc) {
//===----------------------------------------------------------------------===//
void GRExprEngine::ProcessStmt(Stmt* S, GRStmtNodeBuilder& builder) {
-
+
PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
S->getLocStart(),
"Error evaluating statement");
-
+
Builder = &builder;
EntryNode = builder.getLastNode();
-
+
// FIXME: Consolidate.
CurrentStmt = S;
StateMgr.CurrentStmt = S;
-
+
// Set up our simple checks.
if (BatchAuditor)
Builder->setAuditor(BatchAuditor.get());
-
- // Create the cleaned state.
- SymbolReaper SymReaper(*AMgr.getLiveVariables(), SymMgr);
+
+ // Create the cleaned state.
+ SymbolReaper SymReaper(*AMgr.getLiveVariables(), SymMgr);
CleanedState = AMgr.shouldPurgeDead()
? StateMgr.RemoveDeadBindings(EntryNode->getState(), CurrentStmt, SymReaper)
: EntryNode->getState();
// Process any special transfer function for dead symbols.
ExplodedNodeSet Tmp;
-
+
if (!SymReaper.hasDeadSymbols())
Tmp.Add(EntryNode);
else {
@@ -260,36 +260,36 @@ void GRExprEngine::ProcessStmt(Stmt* S, GRStmtNodeBuilder& builder) {
SaveAndRestore<bool> OldPurgeDeadSymbols(Builder->PurgingDeadSymbols);
Builder->PurgingDeadSymbols = true;
-
- getTF().EvalDeadSymbols(Tmp, *this, *Builder, EntryNode, S,
+
+ getTF().EvalDeadSymbols(Tmp, *this, *Builder, EntryNode, S,
CleanedState, SymReaper);
if (!Builder->BuildSinks && !Builder->HasGeneratedNode)
Tmp.Add(EntryNode);
}
-
+
bool HasAutoGenerated = false;
for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
ExplodedNodeSet Dst;
-
- // Set the cleaned state.
+
+ // Set the cleaned state.
Builder->SetCleanedState(*I == EntryNode ? CleanedState : GetState(*I));
-
- // Visit the statement.
+
+ // Visit the statement.
Visit(S, *I, Dst);
// Do we need to auto-generate a node? We only need to do this to generate
// a node with a "cleaned" state; GRCoreEngine will actually handle
- // auto-transitions for other cases.
+ // auto-transitions for other cases.
if (Dst.size() == 1 && *Dst.begin() == EntryNode
&& !Builder->HasGeneratedNode && !HasAutoGenerated) {
HasAutoGenerated = true;
builder.generateNode(S, GetState(EntryNode), *I);
}
}
-
+
// NULL out these variables to cleanup.
CleanedState = NULL;
EntryNode = NULL;
@@ -297,11 +297,11 @@ void GRExprEngine::ProcessStmt(Stmt* S, GRStmtNodeBuilder& builder) {
// FIXME: Consolidate.
StateMgr.CurrentStmt = 0;
CurrentStmt = 0;
-
+
Builder = NULL;
}
-void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
+void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
S->getLocStart(),
"Error evaluating statement");
@@ -309,32 +309,32 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
// FIXME: add metadata to the CFG so that we can disable
// this check when we KNOW that there is no block-level subexpression.
// The motivation is that this check requires a hashtable lookup.
-
+
if (S != CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(S)) {
Dst.Add(Pred);
return;
}
-
+
switch (S->getStmtClass()) {
-
+
default:
// Cases we intentionally have "default" handle:
// AddrLabelExpr, IntegerLiteral, CharacterLiteral
-
+
Dst.Add(Pred); // No-op. Simply propagate the current state unchanged.
break;
-
+
case Stmt::ArraySubscriptExprClass:
VisitArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst, false);
break;
-
+
case Stmt::AsmStmtClass:
VisitAsmStmt(cast<AsmStmt>(S), Pred, Dst);
break;
-
+
case Stmt::BinaryOperatorClass: {
BinaryOperator* B = cast<BinaryOperator>(S);
-
+
if (B->isLogicalOp()) {
VisitLogicalExpr(B, Pred, Dst);
break;
@@ -348,7 +348,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
if (AMgr.shouldEagerlyAssume() && (B->isRelationalOp() || B->isEqualityOp())) {
ExplodedNodeSet Tmp;
VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp);
- EvalEagerlyAssume(Dst, Tmp, cast<Expr>(S));
+ EvalEagerlyAssume(Dst, Tmp, cast<Expr>(S));
}
else
VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
@@ -365,13 +365,13 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
// FIXME: ChooseExpr is really a constant. We need to fix
// the CFG do not model them as explicit control-flow.
-
+
case Stmt::ChooseExprClass: { // __builtin_choose_expr
ChooseExpr* C = cast<ChooseExpr>(S);
VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
break;
}
-
+
case Stmt::CompoundAssignOperatorClass:
VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
break;
@@ -379,22 +379,22 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
case Stmt::CompoundLiteralExprClass:
VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst, false);
break;
-
+
case Stmt::ConditionalOperatorClass: { // '?' operator
ConditionalOperator* C = cast<ConditionalOperator>(S);
VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
break;
}
-
+
case Stmt::DeclRefExprClass:
case Stmt::QualifiedDeclRefExprClass:
VisitDeclRefExpr(cast<DeclRefExpr>(S), Pred, Dst, false);
break;
-
+
case Stmt::DeclStmtClass:
VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
break;
-
+
case Stmt::ImplicitCastExprClass:
case Stmt::CStyleCastExprClass: {
CastExpr* C = cast<CastExpr>(S);
@@ -405,11 +405,11 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
case Stmt::InitListExprClass:
VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst);
break;
-
+
case Stmt::MemberExprClass:
VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst, false);
break;
-
+
case Stmt::ObjCIvarRefExprClass:
VisitObjCIvarRefExpr(cast<ObjCIvarRefExpr>(S), Pred, Dst, false);
break;
@@ -417,12 +417,12 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
case Stmt::ObjCForCollectionStmtClass:
VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S), Pred, Dst);
break;
-
+
case Stmt::ObjCMessageExprClass: {
VisitObjCMessageExpr(cast<ObjCMessageExpr>(S), Pred, Dst);
break;
}
-
+
case Stmt::ObjCAtThrowStmtClass: {
// FIXME: This is not complete. We basically treat @throw as
// an abort.
@@ -431,19 +431,19 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
MakeNode(Dst, S, Pred, GetState(Pred));
break;
}
-
+
case Stmt::ParenExprClass:
Visit(cast<ParenExpr>(S)->getSubExpr()->IgnoreParens(), Pred, Dst);
break;
-
+
case Stmt::ReturnStmtClass:
VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst);
break;
-
+
case Stmt::SizeOfAlignOfExprClass:
VisitSizeOfAlignOfExpr(cast<SizeOfAlignOfExpr>(S), Pred, Dst);
break;
-
+
case Stmt::StmtExprClass: {
StmtExpr* SE = cast<StmtExpr>(S);
@@ -454,21 +454,21 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
Dst.Add(Pred);
break;
}
-
+
if (Expr* LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
const GRState* state = GetState(Pred);
MakeNode(Dst, SE, Pred, state->BindExpr(SE, state->getSVal(LastExpr)));
}
else
Dst.Add(Pred);
-
+
break;
}
case Stmt::StringLiteralClass:
VisitLValue(cast<StringLiteral>(S), Pred, Dst);
break;
-
+
case Stmt::UnaryOperatorClass: {
UnaryOperator *U = cast<UnaryOperator>(S);
if (AMgr.shouldEagerlyAssume() && (U->getOpcode() == UnaryOperator::LNot)) {
@@ -483,43 +483,43 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
}
}
-void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
+void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
ExplodedNodeSet& Dst) {
-
+
Ex = Ex->IgnoreParens();
-
+
if (Ex != CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(Ex)) {
Dst.Add(Pred);
return;
}
-
+
switch (Ex->getStmtClass()) {
-
+
case Stmt::ArraySubscriptExprClass:
VisitArraySubscriptExpr(cast<ArraySubscriptExpr>(Ex), Pred, Dst, true);
return;
-
+
case Stmt::DeclRefExprClass:
case Stmt::QualifiedDeclRefExprClass:
VisitDeclRefExpr(cast<DeclRefExpr>(Ex), Pred, Dst, true);
return;
-
+
case Stmt::ObjCIvarRefExprClass:
VisitObjCIvarRefExpr(cast<ObjCIvarRefExpr>(Ex), Pred, Dst, true);
return;
-
+
case Stmt::UnaryOperatorClass:
VisitUnaryOperator(cast<UnaryOperator>(Ex), Pred, Dst, true);
return;
-
+
case Stmt::MemberExprClass:
VisitMemberExpr(cast<MemberExpr>(Ex), Pred, Dst, true);
return;
-
+
case Stmt::CompoundLiteralExprClass:
VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(Ex), Pred, Dst, true);
return;
-
+
case Stmt::ObjCPropertyRefExprClass:
case Stmt::ObjCImplicitSetterGetterRefExprClass:
// FIXME: Property assignments are lvalues, but not really "locations".
@@ -542,7 +542,7 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, V));
return;
}
-
+
default:
// Arbitrary subexpressions can return aggregate temporaries that
// can be used in a lvalue context. We need to enhance our support
@@ -551,7 +551,7 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
assert ((Ex->getType()->isAggregateType()) &&
"Other kinds of expressions with non-aggregate/union types do"
" not have lvalues.");
-
+
Visit(Ex, Pred, Dst);
}
}
@@ -562,7 +562,7 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, const GRState*,
GRBlockCounter BC) {
-
+
return BC.getNumVisited(B->getBlockID()) < 3;
}
@@ -586,53 +586,53 @@ ExplodedNode* GRExprEngine::MakeNode(ExplodedNodeSet& Dst, Stmt* S,
const GRState* GRExprEngine::MarkBranch(const GRState* state,
Stmt* Terminator,
bool branchTaken) {
-
+
switch (Terminator->getStmtClass()) {
default:
return state;
-
+
case Stmt::BinaryOperatorClass: { // '&&' and '||'
-
+
BinaryOperator* B = cast<BinaryOperator>(Terminator);
BinaryOperator::Opcode Op = B->getOpcode();
-
+
assert (Op == BinaryOperator::LAnd || Op == BinaryOperator::LOr);
-
+
// For &&, if we take the true branch, then the value of the whole
// expression is that of the RHS expression.
//
// For ||, if we take the false branch, then the value of the whole
// expression is that of the RHS expression.
-
+
Expr* Ex = (Op == BinaryOperator::LAnd && branchTaken) ||
- (Op == BinaryOperator::LOr && !branchTaken)
+ (Op == BinaryOperator::LOr && !branchTaken)
? B->getRHS() : B->getLHS();
-
+
return state->BindExpr(B, UndefinedVal(Ex));
}
-
+
case Stmt::ConditionalOperatorClass: { // ?:
-
+
ConditionalOperator* C = cast<ConditionalOperator>(Terminator);
-
+
// For ?, if branchTaken == true then the value is either the LHS or
// the condition itself. (GNU extension).
-
- Expr* Ex;
-
+
+ Expr* Ex;
+
if (branchTaken)
- Ex = C->getLHS() ? C->getLHS() : C->getCond();
+ Ex = C->getLHS() ? C->getLHS() : C->getCond();
else
Ex = C->getRHS();
-
+
return state->BindExpr(C, UndefinedVal(Ex));
}
-
+
case Stmt::ChooseExprClass: { // ?:
-
+
ChooseExpr* C = cast<ChooseExpr>(Terminator);
-
- Expr* Ex = branchTaken ? C->getLHS() : C->getRHS();
+
+ Expr* Ex = branchTaken ? C->getLHS() : C->getRHS();
return state->BindExpr(C, UndefinedVal(Ex));
}
}
@@ -652,19 +652,19 @@ static SVal RecoverCastedSymbol(GRStateManager& StateMgr, const GRState* state,
uint64_t bits = 0;
bool bitsInit = false;
-
+
while (CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
QualType T = CE->getType();
if (!T->isIntegerType())
return UnknownVal();
-
+
uint64_t newBits = Ctx.getTypeSize(T);
if (!bitsInit || newBits < bits) {
bitsInit = true;
bits = newBits;
}
-
+
Ex = CE->getSubExpr();
}
@@ -673,26 +673,26 @@ static SVal RecoverCastedSymbol(GRStateManager& StateMgr, const GRState* state,
if (!bitsInit || !T->isIntegerType() || Ctx.getTypeSize(T) > bits)
return UnknownVal();
-
+
return state->getSVal(Ex);
}
void GRExprEngine::ProcessBranch(Stmt* Condition, Stmt* Term,
GRBranchNodeBuilder& builder) {
-
+
// Check for NULL conditions; e.g. "for(;;)"
- if (!Condition) {
+ if (!Condition) {
builder.markInfeasible(false);
return;
}
-
+
PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
Condition->getLocStart(),
"Error evaluating branch");
- const GRState* PrevState = builder.getState();
+ const GRState* PrevState = builder.getState();
SVal V = PrevState->getSVal(Condition);
-
+
switch (V.getBaseKind()) {
default:
break;
@@ -707,32 +707,32 @@ void GRExprEngine::ProcessBranch(Stmt* Condition, Stmt* Term,
SVal recovered = RecoverCastedSymbol(getStateManager(),
builder.getState(), Condition,
getContext());
-
+
if (!recovered.isUnknown()) {
V = recovered;
break;
}
}
}
-
+
builder.generateNode(MarkBranch(PrevState, Term, true), true);
builder.generateNode(MarkBranch(PrevState, Term, false), false);
return;
}
-
- case SVal::UndefinedKind: {
+
+ case SVal::UndefinedKind: {
ExplodedNode* N = builder.generateNode(PrevState, true);
if (N) {
N->markAsSink();
UndefBranches.insert(N);
}
-
+
builder.markInfeasible(false);
return;
- }
+ }
}
-
+
// Process the true branch.
if (builder.isFeasible(true)) {
if (const GRState *state = PrevState->assume(V, true))
@@ -740,8 +740,8 @@ void GRExprEngine::ProcessBranch(Stmt* Condition, Stmt* Term,
else
builder.markInfeasible(true);
}
-
- // Process the false branch.
+
+ // Process the false branch.
if (builder.isFeasible(false)) {
if (const GRState *state = PrevState->assume(V, false))
builder.generateNode(MarkBranch(state, Term, false), false);
@@ -754,28 +754,28 @@ void GRExprEngine::ProcessBranch(Stmt* Condition, Stmt* Term,
/// nodes by processing the 'effects' of a computed goto jump.
void GRExprEngine::ProcessIndirectGoto(GRIndirectGotoNodeBuilder& builder) {
- const GRState *state = builder.getState();
+ const GRState *state = builder.getState();
SVal V = state->getSVal(builder.getTarget());
-
+
// Three possibilities:
//
// (1) We know the computed label.
// (2) The label is NULL (or some other constant), or Undefined.
// (3) We have no clue about the label. Dispatch to all targets.
//
-
+
typedef GRIndirectGotoNodeBuilder::iterator iterator;
if (isa<loc::GotoLabel>(V)) {
LabelStmt* L = cast<loc::GotoLabel>(V).getLabel();
-
+
for (iterator I=builder.begin(), E=builder.end(); I != E; ++I) {
if (I.getLabel() == L) {
builder.generateNode(I, state);
return;
}
}
-
+
assert (false && "No block with label.");
return;
}
@@ -786,10 +786,10 @@ void GRExprEngine::ProcessIndirectGoto(GRIndirectGotoNodeBuilder& builder) {
UndefBranches.insert(N);
return;
}
-
+
// This is really a catch-all. We don't support symbolics yet.
// FIXME: Implement dispatch for symbolic pointers.
-
+
for (iterator I=builder.begin(), E=builder.end(); I != E; ++I)
builder.generateNode(I, state);
}
@@ -797,27 +797,27 @@ void GRExprEngine::ProcessIndirectGoto(GRIndirectGotoNodeBuilder& builder) {
void GRExprEngine::VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R,
ExplodedNode* Pred, ExplodedNodeSet& Dst) {
-
+
assert (Ex == CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(Ex));
-
+
const GRState* state = GetState(Pred);
SVal X = state->getSVal(Ex);
-
+
assert (X.isUndef());
-
+
Expr *SE = (Expr*) cast<UndefinedVal>(X).getData();
- assert(SE);
+ assert(SE);
X = state->getSVal(SE);
-
+
// Make sure that we invalidate the previous binding.
MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, X, true));
}
/// ProcessSwitch - Called by GRCoreEngine. Used to generate successor
/// nodes by processing the 'effects' of a switch statement.
-void GRExprEngine::ProcessSwitch(GRSwitchNodeBuilder& builder) {
- typedef GRSwitchNodeBuilder::iterator iterator;
- const GRState* state = builder.getState();
+void GRExprEngine::ProcessSwitch(GRSwitchNodeBuilder& builder) {
+ typedef GRSwitchNodeBuilder::iterator iterator;
+ const GRState* state = builder.getState();
Expr* CondE = builder.getCondition();
SVal CondV = state->getSVal(CondE);
@@ -827,55 +827,55 @@ void GRExprEngine::ProcessSwitch(GRSwitchNodeBuilder& builder) {
return;
}
- const GRState* DefaultSt = state;
+ const GRState* DefaultSt = state;
bool defaultIsFeasible = false;
-
+
for (iterator I = builder.begin(), EI = builder.end(); I != EI; ++I) {
CaseStmt* Case = cast<CaseStmt>(I.getCase());
// Evaluate the LHS of the case value.
Expr::EvalResult V1;
- bool b = Case->getLHS()->Evaluate(V1, getContext());
-
+ bool b = Case->getLHS()->Evaluate(V1, getContext());
+
// Sanity checks. These go away in Release builds.
- assert(b && V1.Val.isInt() && !V1.HasSideEffects
+ assert(b && V1.Val.isInt() && !V1.HasSideEffects
&& "Case condition must evaluate to an integer constant.");
- b = b; // silence unused variable warning
- assert(V1.Val.getInt().getBitWidth() ==
+ b = b; // silence unused variable warning
+ assert(V1.Val.getInt().getBitWidth() ==
getContext().getTypeSize(CondE->getType()));
-
+
// Get the RHS of the case, if it exists.
Expr::EvalResult V2;
-
+
if (Expr* E = Case->getRHS()) {
b = E->Evaluate(V2, getContext());
- assert(b && V2.Val.isInt() && !V2.HasSideEffects
+ assert(b && V2.Val.isInt() && !V2.HasSideEffects
&& "Case condition must evaluate to an integer constant.");
b = b; // silence unused variable warning
}
else
V2 = V1;
-
+
// FIXME: Eventually we should replace the logic below with a range
// comparison, rather than concretize the values within the range.
// This should be easy once we have "ranges" for NonLVals.
-
+
do {
- nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1.Val.getInt()));
+ nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1.Val.getInt()));
SVal Res = EvalBinOp(DefaultSt, BinaryOperator::EQ, CondV, CaseVal,
getContext().IntTy);
-
- // Now "assume" that the case matches.
+
+ // Now "assume" that the case matches.
if (const GRState* stateNew = state->assume(Res, true)) {
builder.generateCaseStmtNode(I, stateNew);
-
+
// If CondV evaluates to a constant, then we know that this
// is the *only* case that we can take, so stop evaluating the
// others.
if (isa<nonloc::ConcreteInt>(CondV))
return;
}
-
+
// Now "assume" that the case doesn't match. Add this state
// to the default state (if it is feasible).
if (const GRState *stateNew = DefaultSt->assume(Res, false)) {
@@ -886,15 +886,15 @@ void GRExprEngine::ProcessSwitch(GRSwitchNodeBuilder& builder) {
// Concretize the next value in the range.
if (V1.Val.getInt() == V2.Val.getInt())
break;
-
+
++V1.Val.getInt();
assert (V1.Val.getInt() <= V2.Val.getInt());
-
+
} while (true);
}
-
+
// If we reach here, than we know that the default branch is
- // possible.
+ // possible.
if (defaultIsFeasible) builder.generateDefaultCaseNode(DefaultSt);
}
@@ -904,62 +904,62 @@ void GRExprEngine::ProcessSwitch(GRSwitchNodeBuilder& builder) {
void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
ExplodedNodeSet& Dst) {
-
+
assert(B->getOpcode() == BinaryOperator::LAnd ||
B->getOpcode() == BinaryOperator::LOr);
-
+
assert(B == CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(B));
-
+
const GRState* state = GetState(Pred);
SVal X = state->getSVal(B);
assert(X.isUndef());
-
+
Expr* Ex = (Expr*) cast<UndefinedVal>(X).getData();
-
+
assert(Ex);
-
+
if (Ex == B->getRHS()) {
-
+
X = state->getSVal(Ex);
-
+
// Handle undefined values.
-
+
if (X.isUndef()) {
MakeNode(Dst, B, Pred, state->BindExpr(B, X));
return;
}
-
+
// We took the RHS. Because the value of the '&&' or '||' expression must
// evaluate to 0 or 1, we must assume the value of the RHS evaluates to 0
// or 1. Alternatively, we could take a lazy approach, and calculate this
// value later when necessary. We don't have the machinery in place for
// this right now, and since most logical expressions are used for branches,
- // the payoff is not likely to be large. Instead, we do eager evaluation.
+ // the payoff is not likely to be large. Instead, we do eager evaluation.
if (const GRState *newState = state->assume(X, true))
- MakeNode(Dst, B, Pred,
+ MakeNode(Dst, B, Pred,
newState->BindExpr(B, ValMgr.makeIntVal(1U, B->getType())));
-
+
if (const GRState *newState = state->assume(X, false))
- MakeNode(Dst, B, Pred,
+ MakeNode(Dst, B, Pred,
newState->BindExpr(B, ValMgr.makeIntVal(0U, B->getType())));
}
else {
// We took the LHS expression. Depending on whether we are '&&' or
// '||' we know what the value of the expression is via properties of
// the short-circuiting.
- X = ValMgr.makeIntVal(B->getOpcode() == BinaryOperator::LAnd ? 0U : 1U,
+ X = ValMgr.makeIntVal(B->getOpcode() == BinaryOperator::LAnd ? 0U : 1U,
B->getType());
MakeNode(Dst, B, Pred, state->BindExpr(B, X));
}
}
-
+
//===----------------------------------------------------------------------===//
// Transfer functions: Loads and stores.
//===----------------------------------------------------------------------===//
-void GRExprEngine::VisitDeclRefExpr(DeclRefExpr *Ex, ExplodedNode *Pred,
+void GRExprEngine::VisitDeclRefExpr(DeclRefExpr *Ex, ExplodedNode *Pred,
ExplodedNodeSet &Dst, bool asLValue) {
-
+
const GRState* state = GetState(Pred);
const NamedDecl* D = Ex->getDecl();
@@ -989,20 +989,20 @@ void GRExprEngine::VisitDeclRefExpr(DeclRefExpr *Ex, ExplodedNode *Pred,
ProgramPoint::PostLValueKind);
return;
}
-
+
assert (false &&
"ValueDecl support for this ValueDecl not implemented.");
}
/// VisitArraySubscriptExpr - Transfer function for array accesses
-void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A,
+void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A,
ExplodedNode* Pred,
ExplodedNodeSet& Dst, bool asLValue){
-
+
Expr* Base = A->getBase()->IgnoreParens();
Expr* Idx = A->getIdx()->IgnoreParens();
ExplodedNodeSet Tmp;
-
+
if (Base->getType()->isVectorType()) {
// For vector types get its lvalue.
// FIXME: This may not be correct. Is the rvalue of a vector its location?
@@ -1010,13 +1010,13 @@ void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A,
// semantics.
VisitLValue(Base, Pred, Tmp);
}
- else
+ else
Visit(Base, Pred, Tmp); // Get Base's rvalue, which should be an LocVal.
-
+
for (ExplodedNodeSet::iterator I1=Tmp.begin(), E1=Tmp.end(); I1!=E1; ++I1) {
ExplodedNodeSet Tmp2;
Visit(Idx, *I1, Tmp2); // Evaluate the index.
-
+
for (ExplodedNodeSet::iterator I2=Tmp2.begin(),E2=Tmp2.end();I2!=E2; ++I2) {
const GRState* state = GetState(*I2);
SVal V = state->getLValue(A->getType(), state->getSVal(Base),
@@ -1034,15 +1034,15 @@ void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A,
/// VisitMemberExpr - Transfer function for member expressions.
void GRExprEngine::VisitMemberExpr(MemberExpr* M, ExplodedNode* Pred,
ExplodedNodeSet& Dst, bool asLValue) {
-
+
Expr* Base = M->getBase()->IgnoreParens();
ExplodedNodeSet Tmp;
-
- if (M->isArrow())
+
+ if (M->isArrow())
Visit(Base, Pred, Tmp); // p->f = ... or ... = p->f
else
VisitLValue(Base, Pred, Tmp); // x.f = ... or ... = x.f
-
+
FieldDecl *Field = dyn_cast<FieldDecl>(M->getMemberDecl());
if (!Field) // FIXME: skipping member expressions for non-fields
return;
@@ -1068,7 +1068,7 @@ void GRExprEngine::EvalBind(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
const GRState* state, SVal location, SVal Val) {
const GRState* newState = 0;
-
+
if (location.isUnknown()) {
// We know that the new state will be the same as the old state since
// the location of the binding is "unknown". Consequently, there
@@ -1086,7 +1086,7 @@ void GRExprEngine::EvalBind(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
// doesn't do anything, just auto-propagate the current state.
GRStmtNodeBuilderRef BuilderRef(Dst, *Builder, *this, Pred, newState, Ex,
newState != state);
-
+
getTF().EvalBind(BuilderRef, location, Val);
}
@@ -1099,19 +1099,19 @@ void GRExprEngine::EvalBind(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
void GRExprEngine::EvalStore(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
const GRState* state, SVal location, SVal Val,
const void *tag) {
-
+
assert (Builder && "GRStmtNodeBuilder must be defined.");
-
+
// Evaluate the location (checks for bad dereferences).
Pred = EvalLocation(Ex, Pred, state, location, tag);
-
+
if (!Pred)
return;
assert (!location.isUndef());
state = GetState(Pred);
- // Proceed with the store.