diff options
author | Mike Stump <mrs@apple.com> | 2009-09-09 15:08:12 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-09-09 15:08:12 +0000 |
commit | 1eb4433ac451dc16f4133a88af2d002ac26c58ef (patch) | |
tree | 07065b80cb7787bb7b9ffcb985196007a57e86f7 /lib/Analysis/GRExprEngine.cpp | |
parent | 79d39f92590cf2e91bf81486b02cd1156d13ca54 (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.cpp | 1247 |
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. |