Remove tabs, and whitespace cleanups.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81346 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 053da67..b4b69cd 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -44,7 +44,7 @@
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 @@
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 @@
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 @@
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 @@
//===----------------------------------------------------------------------===//
// 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 @@
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::AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C) {
if (!BatchAuditor)
BatchAuditor.reset(new MappedBatchAuditor(getGraph().getAllocator()));
-
+
((MappedBatchAuditor*) BatchAuditor.get())->AddCheck(A, C);
}
@@ -197,7 +197,7 @@
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 @@
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 @@
//===----------------------------------------------------------------------===//
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 @@
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 @@
// 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 @@
// 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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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::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 @@
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 @@
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 @@
bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, const GRState*,
GRBlockCounter BC) {
-
+
return BC.getNumVisited(B->getBlockID()) < 3;
}
@@ -586,53 +586,53 @@
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 @@
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 @@
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 @@
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 @@
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 @@
/// 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 @@
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::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 @@
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 @@
// 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::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 @@
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 @@
// 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 @@
/// 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 @@
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 @@
// 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::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.
+ // Proceed with the store.
SaveAndRestore<ProgramPoint::Kind> OldSPointKind(Builder->PointKind);
SaveAndRestore<const void*> OldTag(Builder->Tag);
Builder->PointKind = ProgramPoint::PostStoreKind;
@@ -1123,14 +1123,14 @@
const GRState* state, SVal location,
const void *tag) {
- // Evaluate the location (checks for bad dereferences).
+ // Evaluate the location (checks for bad dereferences).
Pred = EvalLocation(Ex, Pred, state, location, tag);
-
+
if (!Pred)
return;
-
+
state = GetState(Pred);
-
+
// Proceed with the load.
ProgramPoint::Kind K = ProgramPoint::PostLoadKind;
@@ -1144,7 +1144,7 @@
}
else {
SVal V = state->getSVal(cast<Loc>(location), Ex->getType());
-
+
// Casts can create weird scenarios where a location must be implicitly
// converted to something else. For example:
//
@@ -1152,19 +1152,19 @@
// int *y = (int*) &x; // void** -> int* cast.
// invalidate(y); // 'x' now binds to a symbolic region
// int z = *y;
- //
+ //
//if (isa<Loc>(V) && !Loc::IsLocType(Ex->getType())) {
// V = EvalCast(V, Ex->getType());
//}
-
+
MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, V), K, tag);
}
}
-void GRExprEngine::EvalStore(ExplodedNodeSet& Dst, Expr* Ex, Expr* StoreE,
- ExplodedNode* Pred, const GRState* state,
+void GRExprEngine::EvalStore(ExplodedNodeSet& Dst, Expr* Ex, Expr* StoreE,
+ ExplodedNode* Pred, const GRState* state,
SVal location, SVal Val, const void *tag) {
-
+
ExplodedNodeSet TmpDst;
EvalStore(TmpDst, StoreE, Pred, state, location, Val, tag);
@@ -1175,60 +1175,60 @@
ExplodedNode* GRExprEngine::EvalLocation(Stmt* Ex, ExplodedNode* Pred,
const GRState* state, SVal location,
const void *tag) {
-
+
SaveAndRestore<const void*> OldTag(Builder->Tag);
Builder->Tag = tag;
-
- // Check for loads/stores from/to undefined values.
+
+ // Check for loads/stores from/to undefined values.
if (location.isUndef()) {
ExplodedNode* N =
Builder->generateNode(Ex, state, Pred,
ProgramPoint::PostUndefLocationCheckFailedKind);
-
+
if (N) {
N->markAsSink();
UndefDeref.insert(N);
}
-
+
return 0;
}
-
+
// Check for loads/stores from/to unknown locations. Treat as No-Ops.
if (location.isUnknown())
return Pred;
-
+
// During a load, one of two possible situations arise:
// (1) A crash, because the location (pointer) was NULL.
// (2) The location (pointer) is not NULL, and the dereference works.
- //
+ //
// We add these assumptions.
-
- Loc LV = cast<Loc>(location);
-
+
+ Loc LV = cast<Loc>(location);
+
// "Assume" that the pointer is not NULL.
const GRState *StNotNull = state->assume(LV, true);
-
+
// "Assume" that the pointer is NULL.
const GRState *StNull = state->assume(LV, false);
- if (StNull) {
+ if (StNull) {
// Use the Generic Data Map to mark in the state what lval was null.
const SVal* PersistentLV = getBasicVals().getPersistentSVal(LV);
StNull = StNull->set<GRState::NullDerefTag>(PersistentLV);
-
+
// We don't use "MakeNode" here because the node will be a sink
// and we have no intention of processing it later.
ExplodedNode* NullNode =
- Builder->generateNode(Ex, StNull, Pred,
+ Builder->generateNode(Ex, StNull, Pred,
ProgramPoint::PostNullCheckFailedKind);
- if (NullNode) {
- NullNode->markAsSink();
+ if (NullNode) {
+ NullNode->markAsSink();
if (StNotNull) ImplicitNullDeref.insert(NullNode);
else ExplicitNullDeref.insert(NullNode);
}
}
-
+
if (!StNotNull)
return NULL;
@@ -1245,9 +1245,9 @@
SVal NumElements = getStoreManager().getSizeInElements(StNotNull,
ER->getSuperRegion());
- const GRState * StInBound = StNotNull->assumeInBound(Idx, NumElements,
+ const GRState * StInBound = StNotNull->assumeInBound(Idx, NumElements,
true);
- const GRState* StOutBound = StNotNull->assumeInBound(Idx, NumElements,
+ const GRState* StOutBound = StNotNull->assumeInBound(Idx, NumElements,
false);
if (StOutBound) {
@@ -1273,7 +1273,7 @@
}
}
#endif
-
+
// Generate a new node indicating the checks succeed.
return Builder->generateNode(Ex, StNotNull, Pred,
ProgramPoint::PostLocationChecksSucceedKind);
@@ -1292,45 +1292,45 @@
static bool EvalOSAtomicCompareAndSwap(ExplodedNodeSet& Dst,
GRExprEngine& Engine,
GRStmtNodeBuilder& Builder,
- CallExpr* CE, SVal L,
+ CallExpr* CE, SVal L,
ExplodedNode* Pred) {
// Not enough arguments to match OSAtomicCompareAndSwap?
if (CE->getNumArgs() != 3)
return false;
-
+
ASTContext &C = Engine.getContext();
Expr *oldValueExpr = CE->getArg(0);
QualType oldValueType = C.getCanonicalType(oldValueExpr->getType());
Expr *newValueExpr = CE->getArg(1);
QualType newValueType = C.getCanonicalType(newValueExpr->getType());
-
+
// Do the types of 'oldValue' and 'newValue' match?
if (oldValueType != newValueType)
return false;
-
+
Expr *theValueExpr = CE->getArg(2);
const PointerType *theValueType =
theValueExpr->getType()->getAs<PointerType>();
-
+
// theValueType not a pointer?
if (!theValueType)
return false;
-
+
QualType theValueTypePointee =
C.getCanonicalType(theValueType->getPointeeType()).getUnqualifiedType();
-
+
// The pointee must match newValueType and oldValueType.
if (theValueTypePointee != newValueType)
return false;
-
+
static unsigned magic_load = 0;
static unsigned magic_store = 0;
const void *OSAtomicLoadTag = &magic_load;
const void *OSAtomicStoreTag = &magic_store;
-
+
// Load 'theValue'.
const GRState *state = Pred->getState();
ExplodedNodeSet Tmp;
@@ -1339,41 +1339,41 @@
for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end();
I != E; ++I) {
-
+
ExplodedNode *N = *I;
const GRState *stateLoad = N->getState();
SVal theValueVal = stateLoad->getSVal(theValueExpr);
SVal oldValueVal = stateLoad->getSVal(oldValueExpr);
-
+
// FIXME: Issue an error.
if (theValueVal.isUndef() || oldValueVal.isUndef()) {
- return false;
+ return false;
}
-
+
SValuator &SVator = Engine.getSValuator();
-
+
// Perform the comparison.
SVal Cmp = SVator.EvalBinOp(stateLoad, BinaryOperator::EQ, theValueVal,
oldValueVal, Engine.getContext().IntTy);
const GRState *stateEqual = stateLoad->assume(Cmp, true);
-
+
// Were they equal?
if (stateEqual) {
// Perform the store.
ExplodedNodeSet TmpStore;
SVal val = stateEqual->getSVal(newValueExpr);
-
+
// Handle implicit value casts.
if (const TypedRegion *R =
dyn_cast_or_null<TypedRegion>(location.getAsRegion())) {
llvm::tie(state, val) = SVator.EvalCast(val, state, R->getValueType(C),
newValueExpr->getType());
- }
-
- Engine.EvalStore(TmpStore, theValueExpr, N, stateEqual, location,
+ }
+
+ Engine.EvalStore(TmpStore, theValueExpr, N, stateEqual, location,
val, OSAtomicStoreTag);
-
+
// Now bind the result of the comparison.
for (ExplodedNodeSet::iterator I2 = TmpStore.begin(),
E2 = TmpStore.end(); I2 != E2; ++I2) {
@@ -1383,14 +1383,14 @@
Engine.MakeNode(Dst, CE, predNew, stateNew->BindExpr(CE, Res));
}
}
-
+
// Were they not equal?
if (const GRState *stateNotEqual = stateLoad->assume(Cmp, false)) {
SVal Res = Engine.getValueManager().makeTruthVal(false, CE->getType());
Engine.MakeNode(Dst, CE, N, stateNotEqual->BindExpr(CE, Res));
}
}
-
+
return true;
}
@@ -1404,7 +1404,7 @@
return false;
const char *FName = FD->getNameAsCString();
-
+
// Check for compare and swap.
if (strncmp(FName, "OSAtomicCompareAndSwap", 22) == 0 ||
strncmp(FName, "objc_atomicCompareAndSwap", 25) == 0)
@@ -1418,12 +1418,12 @@
// Transfer function: Function calls.
//===----------------------------------------------------------------------===//
static void MarkNoReturnFunction(const FunctionDecl *FD, CallExpr *CE,
- const GRState *state,
+ const GRState *state,
GRStmtNodeBuilder *Builder) {
if (!FD)
return;
- if (FD->getAttr<NoReturnAttr>() ||
+ if (FD->getAttr<NoReturnAttr>() ||
FD->getAttr<AnalyzerNoReturnAttr>())
Builder->BuildSinks = true;
else {
@@ -1432,11 +1432,11 @@
// potentially cache these results.
const char* s = FD->getIdentifier()->getName();
unsigned n = strlen(s);
-
+
switch (n) {
default:
break;
-
+
case 4:
if (!memcmp(s, "exit", 4)) Builder->BuildSinks = true;
break;
@@ -1460,37 +1460,37 @@
Builder->BuildSinks = true;
break;
}
-
+
// FIXME: This is just a wrapper around throwing an exception.
// Eventually inter-procedural analysis should handle this easily.
if (!memcmp(s, "ziperr", 6)) Builder->BuildSinks = true;
break;
-
+
case 7:
if (!memcmp(s, "assfail", 7)) Builder->BuildSinks = true;
break;
-
+
case 8:
- if (!memcmp(s ,"db_error", 8) ||
+ if (!memcmp(s ,"db_error", 8) ||
!memcmp(s, "__assert", 8))
Builder->BuildSinks = true;
break;
-
+
case 12:
if (!memcmp(s, "__assert_rtn", 12)) Builder->BuildSinks = true;
break;
-
+
case 13:
if (!memcmp(s, "__assert_fail", 13)) Builder->BuildSinks = true;
break;
-
+
case 14:
if (!memcmp(s, "dtrace_assfail", 14) ||
!memcmp(s, "yy_fatal_error", 14))
Builder->BuildSinks = true;
break;
-
+
case 26:
if (!memcmp(s, "_XCAssertionFailureHandler", 26) ||
!memcmp(s, "_DTAssertionFailureHandler", 26) ||
@@ -1499,7 +1499,7 @@
break;
}
-
+
}
}
@@ -1508,7 +1508,7 @@
ExplodedNodeSet &Dst) {
if (!FD)
return false;
-
+
unsigned id = FD->getBuiltinID(getContext());
if (!id)
return false;
@@ -1518,18 +1518,18 @@
switch (id) {
case Builtin::BI__builtin_expect: {
// For __builtin_expect, just return the value of the subexpression.
- assert (CE->arg_begin() != CE->arg_end());
+ assert (CE->arg_begin() != CE->arg_end());
SVal X = state->getSVal(*(CE->arg_begin()));
MakeNode(Dst, CE, Pred, state->BindExpr(CE, X));
return true;
}
-
+
case Builtin::BI__builtin_alloca: {
// FIXME: Refactor into StoreManager itself?
MemRegionManager& RM = getStateManager().getRegionManager();
const MemRegion* R =
RM.getAllocaRegion(CE, Builder->getCurrentBlockCount());
-
+
// Set the extent of the region in bytes. This enables us to use the
// SVal of the argument directly. If we save the extent in bits, we
// cannot represent values like symbol*8.
@@ -1543,22 +1543,21 @@
return false;
}
-void GRExprEngine::EvalCall(ExplodedNodeSet& Dst, CallExpr* CE, SVal L,
+void GRExprEngine::EvalCall(ExplodedNodeSet& Dst, CallExpr* CE, SVal L,
ExplodedNode* Pred) {
assert (Builder && "GRStmtNodeBuilder must be defined.");
-
+
// FIXME: Allow us to chain together transfer functions.
if (EvalOSAtomic(Dst, *this, *Builder, CE, L, Pred))
return;
-
+
getTF().EvalCall(Dst, *this, *Builder, CE, L, Pred);
}
void GRExprEngine::VisitCall(CallExpr* CE, ExplodedNode* Pred,
CallExpr::arg_iterator AI,
CallExpr::arg_iterator AE,
- ExplodedNodeSet& Dst)
-{
+ ExplodedNodeSet& Dst) {
// Determine the type of function we're calling (if available).
const FunctionProtoType *Proto = NULL;
QualType FnType = CE->getCallee()->IgnoreParens()->getType();
@@ -1571,10 +1570,10 @@
void GRExprEngine::VisitCallRec(CallExpr* CE, ExplodedNode* Pred,
CallExpr::arg_iterator AI,
CallExpr::arg_iterator AE,
- ExplodedNodeSet& Dst,
- const FunctionProtoType *Proto,
+ ExplodedNodeSet& Dst,
+ const FunctionProtoType *Proto,
unsigned ParamIdx) {
-
+
// Process the arguments.
if (AI != AE) {
// If the call argument is being bound to a reference parameter,
@@ -1583,17 +1582,17 @@
if (Proto && ParamIdx < Proto->getNumArgs())
VisitAsLvalue = Proto->getArgType(ParamIdx)->isReferenceType();
- ExplodedNodeSet DstTmp;
+ ExplodedNodeSet DstTmp;
if (VisitAsLvalue)
- VisitLValue(*AI, Pred, DstTmp);
+ VisitLValue(*AI, Pred, DstTmp);
else
- Visit(*AI, Pred, DstTmp);
+ Visit(*AI, Pred, DstTmp);
++AI;
-
+
for (ExplodedNodeSet::iterator DI=DstTmp.begin(), DE=DstTmp.end(); DI != DE;
++DI)
VisitCallRec(CE, *DI, AI, AE, Dst, Proto, ParamIdx + 1);
-
+
return;
}
@@ -1601,17 +1600,17 @@
// the callee expression.
ExplodedNodeSet DstTmp;
Expr* Callee = CE->getCallee()->IgnoreParens();
-
+
{ // Enter new scope to make the lifetime of 'DstTmp2' bounded.
ExplodedNodeSet DstTmp2;
Visit(Callee, Pred, DstTmp2);
-
+
// Perform the previsit of the CallExpr, storing the results in DstTmp.
CheckerVisit(CE, DstTmp, DstTmp2, true);
}
-
+
// Finally, evaluate the function call.
- for (ExplodedNodeSet::iterator DI = DstTmp.begin(), DE = DstTmp.end();
+ for (ExplodedNodeSet::iterator DI = DstTmp.begin(), DE = DstTmp.end();
DI != DE; ++DI) {
const GRState* state = GetState(*DI);
@@ -1621,25 +1620,25 @@
// function pointer values that are symbolic).
// Check for the "noreturn" attribute.
-
+
SaveAndRestore<bool> OldSink(Builder->BuildSinks);
const FunctionDecl* FD = L.getAsFunctionDecl();
MarkNoReturnFunction(FD, CE, state, Builder);
-
+
// Evaluate the call.
if (EvalBuiltinFunction(FD, CE, *DI, Dst))
continue;
- // Dispatch to the plug-in transfer function.
-
+ // Dispatch to the plug-in transfer function.
+
unsigned size = Dst.size();
SaveOr OldHasGen(Builder->HasGeneratedNode);
EvalCall(Dst, CE, L, *DI);
-
+
// Handle the case where no nodes where generated. Auto-generate that
// contains the updated state if we aren't generating sinks.
-
+
if (!Builder->BuildSinks && Dst.size() == size &&
!Builder->HasGeneratedNode)
MakeNode(Dst, CE, *DI, state);
@@ -1656,31 +1655,31 @@
void GRExprEngine::EvalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, Expr *Ex) {
for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) {
ExplodedNode *Pred = *I;
-
+
// Test if the previous node was as the same expression. This can happen
// when the expression fails to evaluate to anything meaningful and
// (as an optimization) we don't generate a node.
- ProgramPoint P = Pred->getLocation();
+ ProgramPoint P = Pred->getLocation();
if (!isa<PostStmt>(P) || cast<PostStmt>(P).getStmt() != Ex) {
- Dst.Add(Pred);
+ Dst.Add(Pred);
continue;
- }
+ }
- const GRState* state = Pred->getState();
- SVal V = state->getSVal(Ex);
+ const GRState* state = Pred->getState();
+ SVal V = state->getSVal(Ex);
if (isa<nonloc::SymExprVal>(V)) {
// First assume that the condition is true.
if (const GRState *stateTrue = state->assume(V, true)) {
- stateTrue = stateTrue->BindExpr(Ex,
+ stateTrue = stateTrue->BindExpr(Ex,
ValMgr.makeIntVal(1U, Ex->getType()));
- Dst.Add(Builder->generateNode(PostStmtCustom(Ex,
+ Dst.Add(Builder->generateNode(PostStmtCustom(Ex,
&EagerlyAssumeTag, Pred->getLocationContext()),
stateTrue, Pred));
}
-
+
// Next, assume that the condition is false.
if (const GRState *stateFalse = state->assume(V, false)) {
- stateFalse = stateFalse->BindExpr(Ex,
+ stateFalse = stateFalse->BindExpr(Ex,
ValMgr.makeIntVal(0U, Ex->getType()));
Dst.Add(Builder->generateNode(PostStmtCustom(Ex, &EagerlyAssumeTag,
Pred->getLocationContext()),
@@ -1699,16 +1698,16 @@
void GRExprEngine::VisitObjCIvarRefExpr(ObjCIvarRefExpr* Ex,
ExplodedNode* Pred, ExplodedNodeSet& Dst,
bool asLValue) {
-
+
Expr* Base = cast<Expr>(Ex->getBase());
ExplodedNodeSet Tmp;
Visit(Base, Pred, Tmp);
-
+
for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
const GRState* state = GetState(*I);
SVal BaseVal = state->getSVal(Base);
SVal location = state->getLValue(Ex->getDecl(), BaseVal);
-
+
if (asLValue)
MakeNode(Dst, Ex, *I, state->BindExpr(Ex, location));
else
@@ -1722,7 +1721,7 @@
void GRExprEngine::VisitObjCForCollectionStmt(ObjCForCollectionStmt* S,
ExplodedNode* Pred, ExplodedNodeSet& Dst) {
-
+
// ObjCForCollectionStmts are processed in two places. This method
// handles the case where an ObjCForCollectionStmt* occurs as one of the
// statements within a basic block. This transfer function does two things:
@@ -1734,7 +1733,7 @@
// whether or not the container has any more elements. This value
// will be tested in ProcessBranch. We need to explicitly bind
// this value because a container can contain nil elements.
- //
+ //
// FIXME: Eventually this logic should actually do dispatches to
// 'countByEnumeratingWithState:objects:count:' (NSFastEnumeration).
// This will require simulating a temporary NSFastEnumerationState, either
@@ -1747,10 +1746,10 @@
// For now: simulate (1) by assigning either a symbol or nil if the
// container is empty. Thus this transfer function will by default
// result in state splitting.
-
+
Stmt* elem = S->getElement();
SVal ElementV;
-
+
if (DeclStmt* DS = dyn_cast<DeclStmt>(elem)) {
VarDecl* ElemD = cast<VarDecl>(DS->getSingleDecl());
assert (ElemD->getInit() == 0);
@@ -1761,7 +1760,7 @@
ExplodedNodeSet Tmp;
VisitLValue(cast<Expr>(elem), Pred, Tmp);
-
+
for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) {
const GRState* state = GetState(*I);
VisitObjCForCollectionStmtAux(S, *I, Dst, state->getSVal(elem));
@@ -1771,27 +1770,27 @@
void GRExprEngine::VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S,
ExplodedNode* Pred, ExplodedNodeSet& Dst,
SVal ElementV) {
-
-
+
+
// Get the current state. Use 'EvalLocation' to determine if it is a null
// pointer, etc.
Stmt* elem = S->getElement();
-
+
Pred = EvalLocation(elem, Pred, GetState(Pred), ElementV);
if (!Pred)
return;
-
+
const GRState *state = GetState(Pred);
// Handle the case where the container still has elements.
SVal TrueV = ValMgr.makeTruthVal(1);
const GRState *hasElems = state->BindExpr(S, TrueV);
-
+
// Handle the case where the container has no elements.
SVal FalseV = ValMgr.makeTruthVal(0);
const GRState *noElems = state->BindExpr(S, FalseV);
-
+
if (loc::MemRegionVal* MV = dyn_cast<loc::MemRegionVal>(&ElementV))
if (const TypedRegion* R = dyn_cast<TypedRegion>(MV->getRegion())) {
// FIXME: The proper thing to do is to really iterate over the
@@ -1805,10 +1804,10 @@
hasElems = hasElems->bindLoc(ElementV, V);
// Bind the location to 'nil' on the false branch.
- SVal nilV = ValMgr.makeIntVal(0, T);
- noElems = noElems->bindLoc(ElementV, nilV);
+ SVal nilV = ValMgr.makeIntVal(0, T);
+ noElems = noElems->bindLoc(ElementV, nilV);
}
-
+
// Create the new nodes.
MakeNode(Dst, S, Pred, hasElems);
MakeNode(Dst, S, Pred, noElems);
@@ -1820,38 +1819,38 @@
void GRExprEngine::VisitObjCMessageExpr(ObjCMessageExpr* ME, ExplodedNode* Pred,
ExplodedNodeSet& Dst){
-
+
VisitObjCMessageExprArgHelper(ME, ME->arg_begin(), ME->arg_end(),
Pred, Dst);
-}
+}
void GRExprEngine::VisitObjCMessageExprArgHelper(ObjCMessageExpr* ME,
ObjCMessageExpr::arg_iterator AI,
ObjCMessageExpr::arg_iterator AE,
ExplodedNode* Pred, ExplodedNodeSet& Dst) {
if (AI == AE) {
-
+
// Process the receiver.
-
+
if (Expr* Receiver = ME->getReceiver()) {
ExplodedNodeSet Tmp;
Visit(Receiver, Pred, Tmp);
-
+
for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI)
VisitObjCMessageExprDispatchHelper(ME, *NI, Dst);
-
+
return;
}
-
+
VisitObjCMessageExprDispatchHelper(ME, Pred, Dst);
return;
}
-
+
ExplodedNodeSet Tmp;
Visit(*AI, Pred, Tmp);
-
+
++AI;
-
+
for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI)
VisitObjCMessageExprArgHelper(ME, AI, AE, *NI, Dst);
}
@@ -1859,53 +1858,53 @@
void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME,
ExplodedNode* Pred,
ExplodedNodeSet& Dst) {
-
- // FIXME: More logic for the processing the method call.
-
+
+ // FIXME: More logic for the processing the method call.
+
const GRState* state = GetState(Pred);
bool RaisesException = false;
-
-
+
+
if (Expr* Receiver = ME->getReceiver()) {
-
+
SVal L = state->getSVal(Receiver);
-
- // Check for undefined control-flow.
+
+ // Check for undefined control-flow.
if (L.isUndef()) {
ExplodedNode* N = Builder->generateNode(ME, state, Pred);
-
+
if (N) {
N->markAsSink();
UndefReceivers.insert(N);
}
-
+
return;
}
-
- // "Assume" that the receiver is not NULL.
+
+ // "Assume" that the receiver is not NULL.
const GRState *StNotNull = state->assume(L, true);
-
- // "Assume" that the receiver is NULL.
+
+ // "Assume" that the receiver is NULL.
const GRState *StNull = state->assume(L, false);
-
+
if (StNull) {
QualType RetTy = ME->getType();
-
+
// Check if the receiver was nil and the return value a struct.
- if(RetTy->isRecordType()) {
+ if (RetTy->isRecordType()) {
if (BR.getParentMap().isConsumedExpr(ME)) {
// The [0 ...] expressions will return garbage. Flag either an
// explicit or implicit error. Because of the structure of this
// function we currently do not bifurfacte the state graph at
// this point.
// FIXME: We should bifurcate and fill the returned struct with
- // garbage.
+ // garbage.
if (ExplodedNode* N = Builder->generateNode(ME, StNull, Pred)) {
N->markAsSink();
if (StNotNull)
NilReceiverStructRetImplicit.insert(N);
else
- NilReceiverStructRetExplicit.insert(N);
+ NilReceiverStructRetExplicit.insert(N);
}
}
}
@@ -1918,13 +1917,13 @@
// sizeof(return type)
const uint64_t returnTypeSize = Ctx.getTypeSize(ME->getType());
- if(voidPtrSize < returnTypeSize) {
+ if (voidPtrSize < returnTypeSize) {
if (ExplodedNode* N = Builder->generateNode(ME, StNull, Pred)) {
N->markAsSink();
- if(StNotNull)
+ if (StNotNull)
NilReceiverLargerThanVoidPtrRetImplicit.insert(N);
else
- NilReceiverLargerThanVoidPtrRetExplicit.insert(N);
+ NilReceiverLargerThanVoidPtrRetExplicit.insert(N);
}
}
else if (!StNotNull) {
@@ -1952,99 +1951,99 @@
// of this method should assume that the receiver is not nil.
if (!StNotNull)
return;
-
+
state = StNotNull;
}
-
+
// Check if the "raise" message was sent.
if (ME->getSelector() == RaiseSel)
RaisesException = true;
}
else {
-
+
IdentifierInfo* ClsName = ME->getClassName();
Selector S = ME->getSelector();
-
+
// Check for special instance methods.
-
- if (!NSExceptionII) {
+
+ if (!NSExceptionII) {
ASTContext& Ctx = getContext();
-
+
NSExceptionII = &Ctx.Idents.get("NSException");
}
-
+
if (ClsName == NSExceptionII) {
-
+
enum { NUM_RAISE_SELECTORS = 2 };
-
+
// Lazily create a cache of the selectors.
if (!NSExceptionInstanceRaiseSelectors) {
-
+
ASTContext& Ctx = getContext();
-
+
NSExceptionInstanceRaiseSelectors = new Selector[NUM_RAISE_SELECTORS];
-
+
llvm::SmallVector<IdentifierInfo*, NUM_RAISE_SELECTORS> II;
unsigned idx = 0;
-
- // raise:format:
+
+ // raise:format:
II.push_back(&Ctx.Idents.get("raise"));
- II.push_back(&Ctx.Idents.get("format"));
+ II.push_back(&Ctx.Idents.get("format"));
NSExceptionInstanceRaiseSelectors[idx++] =
- Ctx.Selectors.getSelector(II.size(), &II[0]);
-
- // raise:format::arguments:
+ Ctx.Selectors.getSelector(II.size(), &II[0]);
+
+ // raise:format::arguments:
II.push_back(&Ctx.Idents.get("arguments"));
NSExceptionInstanceRaiseSelectors[idx++] =
Ctx.Selectors.getSelector(II.size(), &II[0]);
}
-
+
for (unsigned i = 0; i < NUM_RAISE_SELECTORS; ++i)
if (S == NSExceptionInstanceRaiseSelectors[i]) {
RaisesException = true; break;
}
}
}
-
+
// Check for any arguments that are uninitialized/undefined.
-
+
for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end();
I != E; ++I) {
-
+
if (state->getSVal(*I).isUndef()) {
-
+
// Generate an error node for passing an uninitialized/undefined value
// as an argument to a message expression. This node is a sink.
ExplodedNode* N = Builder->generateNode(ME, state, Pred);
-
+
if (N) {
N->markAsSink();
MsgExprUndefArgs[N] = *I;
}
-
+
return;
- }
+ }
}
-
+
// Check if we raise an exception. For now treat these as sinks. Eventually
// we will want to handle exceptions properly.
-
+
SaveAndRestore<bool> OldSink(Builder->BuildSinks);
if (RaisesException)
Builder->BuildSinks = true;
-
+
// Dispatch to plug-in transfer function.
-
+
unsigned size = Dst.size();
SaveOr OldHasGen(Builder->HasGeneratedNode);
-
+
EvalObjCMessageExpr(Dst, ME, Pred);
-
+
// Handle the case where no nodes where generated. Auto-generate that
// contains the updated state if we aren't generating sinks.
-
+
if (!Builder->BuildSinks && Dst.size() == size && !Builder->HasGeneratedNode)
MakeNode(Dst, ME, Pred, state);
}
@@ -2065,9 +2064,9 @@
VisitLValue(Ex, Pred, S1);
else
Visit(Ex, Pred, S1);
-
+
// Check for casting to "void".
- if (T->isVoidType()) {
+ if (T->isVoidType()) {
for (ExplodedNodeSet::iterator I1 = S1.begin(), E1 = S1.end(); I1 != E1; ++I1)
Dst.Add(*I1);
@@ -2085,13 +2084,13 @@
}
void GRExprEngine::VisitCompoundLiteralExpr(CompoundLiteralExpr* CL,
- ExplodedNode* Pred,
- ExplodedNodeSet& Dst,
+ ExplodedNode* Pred,
+ ExplodedNodeSet& Dst,
bool asLValue) {
InitListExpr* ILE = cast<InitListExpr>(CL->getInitializer()->IgnoreParens());
ExplodedNodeSet Tmp;
Visit(ILE, Pred, Tmp);
-
+
for (ExplodedNodeSet::iterator I = Tmp.begin(), EI = Tmp.end(); I!=EI; ++I) {
const GRState* state = GetState(*I);
SVal ILV = state->getSVal(ILE);
@@ -2105,15 +2104,15 @@
}
void GRExprEngine::VisitDeclStmt(DeclStmt *DS, ExplodedNode *Pred,
- ExplodedNodeSet& Dst) {
+ ExplodedNodeSet& Dst) {
- // The CFG has one DeclStmt per Decl.
+ // The CFG has one DeclStmt per Decl.
Decl* D = *DS->decl_begin();
-
+
if (!D || !isa<VarDecl>(D))
return;
-
- const VarDecl* VD = dyn_cast<VarDecl>(D);
+
+ const VarDecl* VD = dyn_cast<VarDecl>(D);
Expr* InitEx = const_cast<Expr*>(VD->getInit());
// FIXME: static variables may have an initializer, but the second
@@ -2124,7 +2123,7 @@
Visit(InitEx, Pred, Tmp);
else
Tmp.Add(Pred);
-
+
for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
const GRState* state = GetState(*I);
unsigned Count = Builder->getCurrentBlockCount();
@@ -2133,58 +2132,58 @@
QualType T = getContext().getCanonicalType(VD->getType());
if (VariableArrayType* VLA = dyn_cast<VariableArrayType>(T)) {
// FIXME: Handle multi-dimensional VLAs.
-
+
Expr* SE = VLA->getSizeExpr();
SVal Size = state->getSVal(SE);
-
+
if (Size.isUndef()) {
if (ExplodedNode* N = Builder->generateNode(DS, state, Pred)) {
- N->markAsSink();
+ N->markAsSink();
ExplicitBadSizedVLA.insert(N);
}
continue;
}
-
- const GRState* zeroState = state->assume(Size, false);
+
+ const GRState* zeroState = state->assume(Size, false);
state = state->assume(Size, true);
-
+
if (zeroState) {
if (ExplodedNode* N = Builder->generateNode(DS, zeroState, Pred)) {
- N->markAsSink();
+ N->markAsSink();
if (state)
ImplicitBadSizedVLA.insert(N);
else
ExplicitBadSizedVLA.insert(N);
}
}
-
+
if (!state)
- continue;
+ continue;
}
-
+
// Decls without InitExpr are not initialized explicitly.
const LocationContext *LC = (*I)->getLocationContext();
if (InitEx) {
SVal InitVal = state->getSVal(InitEx);
QualType T = VD->getType();
-
+
// Recover some path-sensitivity if a scalar value evaluated to
// UnknownVal.
- if (InitVal.isUnknown() ||
+ if (InitVal.isUnknown() ||
!getConstraintManager().canReasonAbout(InitVal)) {
InitVal = ValMgr.getConjuredSymbolVal(InitEx, Count);
- }
-
+ }
+
state = state->bindDecl(VD, LC, InitVal);
-
+
// The next thing to do is check if the GRTransferFuncs object wants to
// update the state based on the new binding. If the GRTransferFunc
// object doesn't do anything, just auto-propagate the current state.
GRStmtNodeBuilderRef BuilderRef(Dst, *Builder, *this, *I, state, DS,true);
getTF().EvalBind(BuilderRef, loc::MemRegionVal(state->getRegion(VD, LC)),
- InitVal);
- }
+ InitVal);
+ }
else {
state = state->bindDeclWithNoInit(VD, LC);
MakeNode(Dst, DS, *I, state);
@@ -2200,7 +2199,7 @@
llvm::ImmutableList<SVal> Vals;
ExplodedNode* N;
InitListExpr::reverse_iterator Itr;
-
+
InitListWLItem(ExplodedNode* n, llvm::ImmutableList<SVal> vals,
InitListExpr::reverse_iterator itr)
: Vals(vals), N(n), Itr(itr) {}
@@ -2208,52 +2207,52 @@
}
-void GRExprEngine::VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
+void GRExprEngine::VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
ExplodedNodeSet& Dst) {
const GRState* state = GetState(Pred);
QualType T = getContext().getCanonicalType(E->getType());
- unsigned NumInitElements = E->getNumInits();
+ unsigned NumInitElements = E->getNumInits();
if (T->isArrayType() || T->isStructureType() ||
T->isUnionType() || T->isVectorType()) {
llvm::ImmutableList<SVal> StartVals = getBasicVals().getEmptySValList();
-
+
// Handle base case where the initializer has no elements.
// e.g: static int* myArray[] = {};
if (NumInitElements == 0) {
SVal V = ValMgr.makeCompoundVal(T, StartVals);
MakeNode(Dst, E, Pred, state->BindExpr(E, V));
return;
- }
-
+ }
+
// Create a worklist to process the initializers.
llvm::SmallVector<InitListWLItem, 10> WorkList;
- WorkList.reserve(NumInitElements);
- WorkList.push_back(InitListWLItem(Pred, StartVals, E->rbegin()));
+ WorkList.reserve(NumInitElements);
+ WorkList.push_back(InitListWLItem(Pred, StartVals, E->rbegin()));
InitListExpr::reverse_iterator ItrEnd = E->rend();
-
+
// Process the worklist until it is empty.
while (!WorkList.empty()) {
InitListWLItem X = WorkList.back();
WorkList.pop_back();
-
+
ExplodedNodeSet Tmp;
Visit(*X.Itr, X.N, Tmp);
-
+
InitListExpr::reverse_iterator NewItr = X.Itr + 1;
for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) {
// Get the last initializer value.
state = GetState(*NI);
SVal InitV = state->getSVal(cast<Expr>(*X.Itr));
-
+
// Construct the new list of values by prepending the new value to
// the already constructed list.
llvm::ImmutableList<SVal> NewVals =
getBasicVals().consVals(InitV, X.Vals);
-
+
if (NewItr == ItrEnd) {
// Now we have a list holding all init values. Make CompoundValData.
SVal V = ValMgr.makeCompoundVal(T, NewVals);
@@ -2267,7 +2266,7 @@
}
}
}
-
+
return;
}
@@ -2293,10 +2292,10 @@
ExplodedNode* Pred,
ExplodedNodeSet& Dst) {
QualType T = Ex->getTypeOfArgument();
- uint64_t amt;
-
+ uint64_t amt;
+
if (Ex->isSizeOf()) {
- if (T == getContext().VoidTy) {
+ if (T == getContext().VoidTy) {
// sizeof(void) == 1 byte.
amt = 1;
}
@@ -2307,17 +2306,17 @@
else if (T->isObjCInterfaceType()) {
// Some code tries to take the sizeof an ObjCInterfaceType, relying that
// the compiler has laid out its representation. Just report Unknown
- // for these.
+ // for these.
return;
}
else {
// All other cases.
amt = getContext().getTypeSize(T) / 8;
- }
+ }
}
else // Get alignment of the type.
amt = getContext().getTypeAlign(T) / 8;
-
+
MakeNode(Dst, Ex, Pred,
GetState(Pred)->BindExpr(Ex, ValMgr.makeIntVal(amt, Ex->getType())));
}
@@ -2327,61 +2326,61 @@
ExplodedNodeSet& Dst, bool asLValue) {
switch (U->getOpcode()) {
-
+
default:
break;
-
+
case UnaryOperator::Deref: {
-
+
Expr* Ex = U->getSubExpr()->IgnoreParens();
ExplodedNodeSet Tmp;
Visit(Ex, Pred, Tmp);
-
+
for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
-
+
const GRState* state = GetState(*I);
SVal location = state->getSVal(Ex);
-
+
if (asLValue)
MakeNode(Dst, U, *I, state->BindExpr(U, location),
ProgramPoint::PostLValueKind);
else
EvalLoad(Dst, U, *I, state, location);
- }
+ }
return;
}
-
+
case UnaryOperator::Real: {
-
+
Expr* Ex = U->getSubExpr()->IgnoreParens();
ExplodedNodeSet Tmp;
Visit(Ex, Pred, Tmp);
-
+
for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
-
+
// FIXME: We don't have complex SValues yet.
if (Ex->getType()->isAnyComplexType()) {
// Just report "Unknown."
Dst.Add(*I);
continue;
}
-
+
// For all other types, UnaryOperator::Real is an identity operation.
assert (U->getType() == Ex->getType());
const GRState* state = GetState(*I);
MakeNode(Dst, U, *I, state->BindExpr(U, state->getSVal(Ex)));
- }
-
+ }
+
return;
}
-
+
case UnaryOperator::Imag: {
-
+
Expr* Ex = U->getSubExpr()->IgnoreParens();
ExplodedNodeSet Tmp;
Visit(Ex, Pred, Tmp);
-
+
for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
// FIXME: We don't have complex SValues yet.
if (Ex->getType()->isAnyComplexType()) {
@@ -2389,25 +2388,25 @@
Dst.Add(*I);
continue;
}
-
+
// For all other types, UnaryOperator::Float returns 0.
assert (Ex->getType()->isIntegerType());
const GRState* state = GetState(*I);
SVal X = ValMgr.makeZeroVal(Ex->getType());
MakeNode(Dst, U, *I, state->BindExpr(U, X));
}
-
+
return;
}
-
- // FIXME: Just report "Unknown" for OffsetOf.
+
+ // FIXME: Just report "Unknown" for OffsetOf.
case UnaryOperator::OffsetOf:
Dst.Add(Pred);
return;
-
+
case UnaryOperator::Plus: assert (!asLValue); // FALL-THROUGH.
case UnaryOperator::Extension: {
-
+
// Unary "+" is a no-op, similar to a parentheses. We still have places
// where it may be a block-level expression, so we need to
// generate an extra node that just propagates the value of the
@@ -2416,44 +2415,44 @@
Expr* Ex = U->getSubExpr()->IgnoreParens();
ExplodedNodeSet Tmp;
Visit(Ex, Pred, Tmp);
-
- for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+
+ for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
const GRState* state = GetState(*I);
MakeNode(Dst, U, *I, state->BindExpr(U, state->getSVal(Ex)));
}
-
+
return;
}
-
+
case UnaryOperator::AddrOf: {
-
+
assert(!asLValue);
Expr* Ex = U->getSubExpr()->IgnoreParens();
ExplodedNodeSet Tmp;
VisitLValue(Ex, Pred, Tmp);
-
- for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+
+ for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
const GRState* state = GetState(*I);
SVal V = state->getSVal(Ex);
state = state->BindExpr(U, V);
MakeNode(Dst, U, *I, state);
}
- return;
+ return;
}
-
+
case UnaryOperator::LNot:
case UnaryOperator::Minus:
case UnaryOperator::Not: {
-
+
assert (!asLValue);
Expr* Ex = U->getSubExpr()->IgnoreParens();
ExplodedNodeSet Tmp;
Visit(Ex, Pred, Tmp);
-
- for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+
+ for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
const GRState* state = GetState(*I);
-
+
// Get the value of the subexpression.
SVal V = state->getSVal(Ex);
@@ -2461,41 +2460,41 @@
MakeNode(Dst, U, *I, state->BindExpr(U, V));
continue;
}
-
+
// QualType DstT = getContext().getCanonicalType(U->getType());
// QualType SrcT = getContext().getCanonicalType(Ex->getType());
-//
+//
// if (DstT != SrcT) // Perform promotions.
-// V = EvalCast(V, DstT);
-//
+// V = EvalCast(V, DstT);
+//
// if (V.isUnknownOrUndef()) {
// MakeNode(Dst, U, *I, BindExpr(St, U, V));
// continue;
// }
-
+
switch (U->getOpcode()) {
default:
assert(false && "Invalid Opcode.");
break;
-
+
case UnaryOperator::Not:
// FIXME: Do we need to handle promotions?
state = state->BindExpr(U, EvalComplement(cast<NonLoc>(V)));
- break;
-
+ break;
+
case UnaryOperator::Minus:
// FIXME: Do we need to handle promotions?
state = state->BindExpr(U, EvalMinus(cast<NonLoc>(V)));
- break;
-
- case UnaryOperator::LNot:
-
+ break;
+
+ case UnaryOperator::LNot:
+
// C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
//
// Note: technically we do "E == 0", but this is the same in the
// transfer functions as "0 == E".
SVal Result;
-
+
if (isa<Loc>(V)) {
Loc X = ValMgr.makeNull();
Result = EvalBinOp(state, BinaryOperator::EQ, cast<Loc>(V), X,
@@ -2506,15 +2505,15 @@
Result = EvalBinOp(BinaryOperator::EQ, cast<NonLoc>(V), X,
U->getType());
}
-
+
state = state->BindExpr(U, Result);
-
+
break;
}
-
+
MakeNode(Dst, U, *I, state);
}
-
+
return;
}
}
@@ -2525,28 +2524,28 @@
ExplodedNodeSet Tmp;
Expr* Ex = U->getSubExpr()->IgnoreParens();
VisitLValue(Ex, Pred, Tmp);
-
+
for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) {
-
+
const GRState* state = GetState(*I);
SVal V1 = state->getSVal(Ex);
-
- // Perform a load.
+
+ // Perform a load.
ExplodedNodeSet Tmp2;
EvalLoad(Tmp2, Ex, *I, state, V1);
for (ExplodedNodeSet::iterator I2 = Tmp2.begin(), E2 = Tmp2.end(); I2!=E2; ++I2) {
-
+
state = GetState(*I2);
SVal V2 = state->getSVal(Ex);
-
- // Propagate unknown and undefined values.
+
+ // Propagate unknown and undefined values.
if (V2.isUnknownOrUndef()) {
MakeNode(Dst, U, *I2, state->BindExpr(U, V2));
continue;
}
-
- // Handle all other values.
+
+ // Handle all other values.
BinaryOperator::Opcode Op = U->isIncrementOp() ? BinaryOperator::Add
: BinaryOperator::Sub;
@@ -2560,37 +2559,37 @@
else
RHS = ValMgr.makeIntVal(1, U->getType());
- SVal Result = EvalBinOp(state, Op, V2, RHS, U->getType());
-
+ SVal Result = EvalBinOp(state, Op, V2, RHS, U->getType());
+
// Conjure a new symbol if necessary to recover precision.
if (Result.isUnknown() || !getConstraintManager().canReasonAbout(Result)){
Result = ValMgr.getConjuredSymbolVal(Ex,
Builder->getCurrentBlockCount());
-
+
// If the value is a location, ++/-- should always preserve
// non-nullness. Check if the original value was non-null, and if so
- // propagate that constraint.
+ // propagate that constraint.
if (Loc::IsLocType(U->getType())) {
SVal Constraint = EvalBinOp(state, BinaryOperator::EQ, V2,
ValMgr.makeZeroVal(U->getType()),
- getContext().IntTy);
-
+ getContext().IntTy);
+
if (!state->assume(Constraint, true)) {
// It isn't feasible for the original value to be null.
// Propagate this constraint.
Constraint = EvalBinOp(state, BinaryOperator::EQ, Result,
ValMgr.makeZeroVal(U->getType()),
getContext().IntTy);
-
+
state = state->assume(Constraint, false);
assert(state);
- }
- }
+ }
+ }
}
-
+
state = state->BindExpr(U, U->isPostfix() ? V2 : Result);
- // Perform the store.
+ // Perform the store.
EvalStore(Dst, U, *I2, state, V1, Result);
}
}
@@ -2598,7 +2597,7 @@
void GRExprEngine::VisitAsmStmt(AsmStmt* A, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
VisitAsmStmtHelperOutputs(A, A->begin_outputs(), A->end_outputs(), Pred, Dst);
-}
+}
void GRExprEngine::VisitAsmStmtHelperOutputs(AsmStmt* A,
AsmStmt::outputs_iterator I,
@@ -2608,12 +2607,12 @@
VisitAsmStmtHelperInputs(A, A->begin_inputs(), A->end_inputs(), Pred, Dst);
return;
}
-
+
ExplodedNodeSet Tmp;
VisitLValue(*I, Pred, Tmp);
-
+
++I;
-
+
for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI)
VisitAsmStmtHelperOutputs(A, I, E, *NI, Dst);
}
@@ -2623,35 +2622,35 @@
AsmStmt::inputs_iterator E,
ExplodedNode* Pred, ExplodedNodeSet& Dst) {
if (I == E) {
-
+
// We have processed both the inputs and the outputs. All of the outputs
// should evaluate to Locs. Nuke all of their values.
-
+
// FIXME: Some day in the future it would be nice to allow a "plug-in"
// which interprets the inline asm and stores proper results in the
// outputs.
-
+
const GRState* state = GetState(Pred);
-
+
for (AsmStmt::outputs_iterator OI = A->begin_outputs(),
OE = A->end_outputs(); OI != OE; ++OI) {
-
- SVal X = state->getSVal(*OI);
+
+ SVal X = state->getSVal(*OI);
assert (!isa<NonLoc>(X)); // Should be an Lval, or unknown, undef.
-
+
if (isa<Loc>(X))
state = state->bindLoc(cast<Loc>(X), UnknownVal());
}
-
+
MakeNode(Dst, A, Pred, state);
return;
}
-
+
ExplodedNodeSet Tmp;
Visit(*I, Pred, Tmp);
-
+
++I;
-
+
for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI!=NE; ++NI)
VisitAsmStmtHelperInputs(A, I, E, *NI, Dst);
}
@@ -2659,16 +2658,16 @@
void GRExprEngine::EvalReturn(ExplodedNodeSet& Dst, ReturnStmt* S,
ExplodedNode* Pred) {
assert (Builder && "GRStmtNodeBuilder must be defined.");
-
- unsigned size = Dst.size();
+
+ unsigned size = Dst.size();
SaveAndRestore<bool> OldSink(Builder->BuildSinks);
SaveOr OldHasGen(Builder->HasGeneratedNode);
getTF().EvalReturn(Dst, *this, *Builder, S, Pred);
-
+
// Handle the case where no nodes where generated.
-
+
if (!Builder->BuildSinks && Dst.size() == size && !Builder->HasGeneratedNode)
MakeNode(Dst, S, Pred, GetState(Pred));
}
@@ -2677,7 +2676,7 @@
ExplodedNodeSet& Dst) {
Expr* R = S->getRetValue();
-
+
if (!R) {
EvalReturn(Dst, S, Pred);
return;
@@ -2688,12 +2687,12 @@
for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) {
SVal X = (*I)->getState()->getSVal(R);
-
+
// Check if we return the address of a stack variable.
if (isa<loc::MemRegionVal>(X)) {
// Determine if the value is on the stack.
const MemRegion* R = cast<loc::MemRegionVal>(&X)->getRegion();
-
+
if (R && R->hasStackStorage()) {
// Create a special node representing the error.
if (ExplodedNode* N = Builder->generateNode(S, GetState(*I), *I)) {
@@ -2711,7 +2710,7 @@
}
continue;
}
-
+
EvalReturn(Dst, S, *I);
}
}
@@ -2727,13 +2726,13 @@
ExplodedNodeSet Tmp1;
Expr* LHS = B->getLHS()->IgnoreParens();
Expr* RHS = B->getRHS()->IgnoreParens();
-
+
// FIXME: Add proper support for ObjCImplicitSetterGetterRefExpr.
if (isa<ObjCImplicitSetterGetterRefExpr>(LHS)) {
- Visit(RHS, Pred, Dst);
+ Visit(RHS, Pred, Dst);
return;
}
-
+
if (B->isAssignmentOp())
VisitLValue(LHS, Pred, Tmp1);
else
@@ -2742,18 +2741,18 @@
for (ExplodedNodeSet::iterator I1=Tmp1.begin(), E1=Tmp1.end(); I1!=E1; ++I1) {
SVal LeftV = (*I1)->getState()->getSVal(LHS);
-
+
// Process the RHS.
-
+
ExplodedNodeSet Tmp2;
Visit(RHS, *I1, Tmp2);
ExplodedNodeSet CheckedSet;
CheckerVisit(B, CheckedSet, Tmp2, true);
-
+
// With both the LHS and RHS evaluated, process the operation itself.
-
- for (ExplodedNodeSet::iterator I2=CheckedSet.begin(), E2=CheckedSet.end();
+
+ for (ExplodedNodeSet::iterator I2=CheckedSet.begin(), E2=CheckedSet.end();
I2 != E2; ++I2) {
const GRState* state = GetState(*I2);
@@ -2761,41 +2760,41 @@
SVal RightV = state->getSVal(RHS);
BinaryOperator::Opcode Op = B->getOpcode();
-
+
switch (Op) {
-
+
case BinaryOperator::Assign: {
-
+
// EXPERIMENTAL: "Conjured" symbols.
// FIXME: Handle structs.
QualType T = RHS->getType();
-
- if ((RightV.isUnknown() ||
- !getConstraintManager().canReasonAbout(RightV))
- && (Loc::IsLocType(T) ||
+
+ if ((RightV.isUnknown() ||
+ !getConstraintManager().canReasonAbout(RightV))
+ && (Loc::IsLocType(T) ||
(T->isScalarType() && T->isIntegerType()))) {
- unsigned Count = Builder->getCurrentBlockCount();
+ unsigned Count = Builder->getCurrentBlockCount();
RightV = ValMgr.getConjuredSymbolVal(B->getRHS(), Count);
}
-
+
// Simulate the effects of a "store": bind the value of the RHS
- // to the L-Value represented by the LHS.
- EvalStore(Dst, B, LHS, *I2, state->BindExpr(B, RightV),
+ // to the L-Value represented by the LHS.
+ EvalStore(Dst, B, LHS, *I2, state->BindExpr(B, RightV),
LeftV, RightV);
continue;
}
-
+
// FALL-THROUGH.
default: {
-
+
if (B->isAssignmentOp())
break;
-
+
// 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());
-
+
if (Result.isUnknown()) {
if (OldSt != state) {
// Generate a new node if we have already created a new state.
@@ -2803,30 +2802,30 @@
}
else
Dst.Add(*I2);
-
+
continue;
}
-
+
if (Result.isUndef() && !LeftV.isUndef() && !RightV.isUndef()) {
-
+
// The operands were *not* undefined, but the result is undefined.
// This is a special node that should be flagged as an error.
-
+
if (ExplodedNode* UndefNode = Builder->generateNode(B, state, *I2)){
- UndefNode->markAsSink();
+ UndefNode->markAsSink();
UndefResults.insert(UndefNode);
}
-
+
continue;
}
-
+
// Otherwise, create a new node.
-
+
MakeNode(Dst, B, *I2, state->BindExpr(B, Result));
continue;
}
}
-
+
assert (B->isCompoundAssignmentOp());
switch (Op) {
@@ -2843,26 +2842,26 @@
case BinaryOperator::XorAssign: Op = BinaryOperator::Xor; break;
case BinaryOperator::OrAssign: Op = BinaryOperator::Or; break;
}
-
+
// Perform a load (the LHS). This performs the checks for
// null dereferences, and so on.
ExplodedNodeSet Tmp3;
SVal location = state->getSVal(LHS);
EvalLoad(Tmp3, LHS, *I2, state, location);
-
- for (ExplodedNodeSet::iterator I3=Tmp3.begin(), E3=Tmp3.end(); I3!=E3;
+
+ for (ExplodedNodeSet::iterator I3=Tmp3.begin(), E3=Tmp3.end(); I3!=E3;
++I3) {
-
+
state = GetState(*I3);
SVal V = state->getSVal(LHS);
- // Propagate undefined values (left-side).
+ // Propagate undefined values (left-side).
if (V.isUndef()) {
- EvalStore(Dst, B, LHS, *I3, state->BindExpr(B, V),
+ EvalStore(Dst, B, LHS, *I3, state->BindExpr(B, V),
location, V);
continue;
}
-
+
// Propagate unknown values (left and right-side).
if (RightV.isUnknown() || V.isUnknown()) {
EvalStore(Dst, B, LHS, *I3, state->BindExpr(B, UnknownVal()),
@@ -2874,7 +2873,7 @@
//
// The LHS is not Undef/Unknown.
// The RHS is not Unknown.
-
+
// Get the computation type.
QualType CTy =
cast<CompoundAssignOperator>(B)->getComputationResultType();
@@ -2890,24 +2889,24 @@
// Promote LHS.
llvm::tie(state, V) = SVator.EvalCast(V, state, CLHSTy, LTy);
- // Evaluate operands and promote to result type.
- if (RightV.isUndef()) {
- // Propagate undefined values (right-side).
+ // Evaluate operands and promote to result type.
+ if (RightV.isUndef()) {
+ // Propagate undefined values (right-side).
EvalStore(Dst, B, LHS, *I3, state->BindExpr(B, RightV), location,
RightV);
continue;
}
-
- // Compute the result of the operation.
+
+ // Compute the result of the operation.
SVal Result;
llvm::tie(state, Result) = SVator.EvalCast(EvalBinOp(state, Op, V,
RightV, CTy),
state, B->getType(), CTy);
-
+
if (Result.isUndef()) {
// The operands were not undefined, but the result is undefined.
if (ExplodedNode* UndefNode = Builder->generateNode(B, state, *I3)) {
- UndefNode->markAsSink();
+ UndefNode->markAsSink();
UndefResults.insert(UndefNode);
}
continue;
@@ -2915,21 +2914,21 @@
// EXPERIMENTAL: "Conjured" symbols.
// FIXME: Handle structs.
-
+
SVal LHSVal;
-
- if ((Result.isUnknown() ||
+
+ if ((Result.isUnknown() ||
!getConstraintManager().canReasonAbout(Result))
- && (Loc::IsLocType(CTy)
+ && (Loc::IsLocType(CTy)
|| (CTy->isScalarType() && CTy->isIntegerType()))) {
-
+
unsigned Count = Builder->getCurrentBlockCount();
-
+
// The symbolic value is actually for the type of the left-hand side
// expression, not the computation type, as this is the value the
// LValue on the LHS will bind to.
LHSVal = ValMgr.getConjuredSymbolVal(B->getRHS(), LTy, Count);
-
+
// However, we need to convert the symbol to the computation type.
llvm::tie(state, Result) = SVator.EvalCast(LHSVal, state, CTy, LTy);
}
@@ -2938,8 +2937,8 @@
// computation type.
llvm::tie(state, LHSVal) = SVator.EvalCast(Result, state, LTy, CTy);
}
-
- EvalStore(Dst, B, LHS, *I3, state->BindExpr(B, Result),
+
+ EvalStore(Dst, B, LHS, *I3, state->BindExpr(B, Result),
location, LHSVal);
}
}
@@ -2958,9 +2957,9 @@
template<>
struct VISIBILITY_HIDDEN DOTGraphTraits<ExplodedNode*> :
public DefaultDOTGraphTraits {
-
+
static std::string getNodeAttributes(const ExplodedNode* N, void*) {
-
+
if (GraphPrintCheckerState->isImplicitNullDeref(N) ||
GraphPrintCheckerState->isExplicitNullDeref(N) ||
GraphPrintCheckerState->isUndefDeref(N) ||
@@ -2972,50 +2971,50 @@
GraphPrintCheckerState->isBadCall(N) ||
GraphPrintCheckerState->isUndefArg(N))
return "color=\"red\",style=\"filled\"";
-
+
if (GraphPrintCheckerState->isNoReturnCall(N))
return "color=\"blue\",style=\"filled\"";
-
+
return "";
}
-
+
static std::string getNodeLabel(const ExplodedNode* N, void*,bool ShortNames){
-
+
std::string sbuf;
llvm::raw_string_ostream Out(sbuf);
// Program Location.
ProgramPoint Loc = N->getLocation();
-
+
switch (Loc.getKind()) {
case ProgramPoint::BlockEntranceKind:
- Out << "Block Entrance: B"
+ Out << "Block Entrance: B"
<< cast<BlockEntrance>(Loc).getBlock()->getBlockID();
break;
-
+
case ProgramPoint::BlockExitKind:
assert (false);
break;
-
+
default: {
if (StmtPoint *L = dyn_cast<StmtPoint>(&Loc)) {
const Stmt* S = L->getStmt();
SourceLocation SLoc = S->getLocStart();
- Out << S->getStmtClassName() << ' ' << (void*) S << ' ';
+ Out << S->getStmtClassName() << ' ' << (void*) S << ' ';
LangOptions LO; // FIXME.
S->printPretty(Out, 0, PrintingPolicy(LO));
-
- if (SLoc.isFileID()) {
+
+ if (SLoc.isFileID()) {
Out << "\\lline="
<< GraphPrintSourceManager->getInstantiationLineNumber(SLoc)
<< " col="
<< GraphPrintSourceManager->getInstantiationColumnNumber(SLoc)
<< "\\l";
}
-
+
if (isa<PreStmt>(Loc))
- Out << "\\lPreStmt\\l;";
+ Out << "\\lPreStmt\\l;";
else if (isa<PostLoad>(Loc))
Out << "\\lPostLoad\\l;";
else if (isa<PostStore>(Loc))
@@ -3026,7 +3025,7 @@
Out << "\\lPostLocationChecksSucceed\\l";
else if (isa<PostNullCheckFailed>(Loc))
Out << "\\lPostNullCheckFailed\\l";
-
+
if (GraphPrintCheckerState->isImplicitNullDeref(N))
Out << "\\|Implicit-Null Dereference.\\l";
else if (GraphPrintCheckerState->isExplicitNullDeref(N))
@@ -3047,43 +3046,43 @@
Out << "\\|Call to NULL/Undefined.";
else if (GraphPrintCheckerState->isUndefArg(N))
Out << "\\|Argument in call is undefined";
-
+
break;
}
const BlockEdge& E = cast<BlockEdge>(Loc);
Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
<< E.getDst()->getBlockID() << ')';
-
+
if (Stmt* T = E.getSrc()->getTerminator()) {
-
+
SourceLocation SLoc = T->getLocStart();
-
+
Out << "\\|Terminator: ";
LangOptions LO; // FIXME.
E.getSrc()->printTerminator(Out, LO);
-
+
if (SLoc.isFileID()) {
Out << "\\lline="
<< GraphPrintSourceManager->getInstantiationLineNumber(SLoc)
<< " col="
<< GraphPrintSourceManager->getInstantiationColumnNumber(SLoc);
}
-
+
if (isa<SwitchStmt>(T)) {
Stmt* Label = E.getDst()->getLabel();
-
- if (Label) {
+
+ if (Label) {
if (CaseStmt* C = dyn_cast<CaseStmt>(Label)) {
Out << "\\lcase ";
LangOptions LO; // FIXME.
C->getLHS()->printPretty(Out, 0, PrintingPolicy(LO));
-
+
if (Stmt* RHS = C->getRHS()) {
Out << " .. ";
RHS->printPretty(Out, 0, PrintingPolicy(LO));
}
-
+
Out << ":";
}
else {
@@ -3091,7 +3090,7 @@
Out << "\\ldefault:";
}
}
- else
+ else
Out << "\\l(implicit) default:";
}
else if (isa<IndirectGotoStmt>(T)) {
@@ -3102,28 +3101,28 @@
if (*E.getSrc()->succ_begin() == E.getDst())
Out << "true";
else
- Out << "false";
+ Out << "false";
}
-
+
Out << "\\l";
}
-
+
if (GraphPrintCheckerState->isUndefControlFlow(N)) {
Out << "\\|Control-flow based on\\lUndefined value.\\l";
}
}
}
-
+
Out << "\\|StateID: " << (void*) N->getState() << "\\|";
const GRState *state = N->getState();
state->printDOT(Out);
-
+
Out << "\\l";
return Out.str();
}
};
-} // end llvm namespace
+} // end llvm namespace
#endif
#ifndef NDEBUG
@@ -3138,7 +3137,7 @@
#endif
void GRExprEngine::ViewGraph(bool trim) {
-#ifndef NDEBUG
+#ifndef NDEBUG
if (trim) {
std::vector<ExplodedNode*> Src;
@@ -3150,14 +3149,14 @@
// Iterate through the reports and get their nodes.
for (BugReporter::iterator I=BR.begin(), E=BR.end(); I!=E; ++I) {
for (BugType::const_iterator I2=(*I)->begin(), E2=(*I)->end();
- I2!=E2; ++I2) {
+ I2!=E2; ++I2) {
const BugReportEquivClass& EQ = *I2;
const BugReport &R = **EQ.begin();
ExplodedNode *N = const_cast<ExplodedNode*>(R.getEndNode());
if (N) Src.push_back(N);
}
}
-
+
ViewGraph(&Src[0], &Src[0]+Src.size());
}
else {
@@ -3165,7 +3164,7 @@
GraphPrintSourceManager = &getContext().getSourceManager();
llvm::ViewGraph(*G.roots_begin(), "GRExprEngine");
-
+
GraphPrintCheckerState = NULL;
GraphPrintSourceManager = NULL;
}
@@ -3176,14 +3175,14 @@
#ifndef NDEBUG
GraphPrintCheckerState = this;
GraphPrintSourceManager = &getContext().getSourceManager();
-
+
std::auto_ptr<ExplodedGraph> TrimmedG(G.Trim(Beg, End).first);
if (!TrimmedG.get())
llvm::errs() << "warning: Trimmed ExplodedGraph is empty.\n";
else
- llvm::ViewGraph(*TrimmedG->roots_begin(), "TrimmedGRExprEngine");
-
+ llvm::ViewGraph(*TrimmedG->roots_begin(), "TrimmedGRExprEngine");
+
GraphPrintCheckerState = NULL;
GraphPrintSourceManager = NULL;
#endif