diff options
author | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-08-15 03:17:38 +0000 |
---|---|---|
committer | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-08-15 03:17:38 +0000 |
commit | 25e695b2d574d919cc1bbddf3a2efe073d449b1c (patch) | |
tree | 69abacb15f2f0f6dcce7cc73047b6a07879f944f | |
parent | bbed6b964414145b29e7b60b3e538093734ea3f8 (diff) |
Extend the ProgramPoint to include the context information LocationContext,
which is either a stack frame context of the function or a local scope
context.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79072 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Analysis/FlowSensitive/DataflowSolver.h | 10 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/AnalysisManager.h | 24 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/ExplodedGraph.h | 5 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRCoreEngine.h | 2 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRExprEngine.h | 10 | ||||
-rw-r--r-- | include/clang/Analysis/ProgramPoint.h | 106 | ||||
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 11 | ||||
-rw-r--r-- | lib/Analysis/GRCoreEngine.cpp | 52 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 13 | ||||
-rw-r--r-- | lib/Frontend/AnalysisConsumer.cpp | 4 |
10 files changed, 139 insertions, 98 deletions
diff --git a/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/include/clang/Analysis/FlowSensitive/DataflowSolver.h index e44bf3262b..b0614e824f 100644 --- a/include/clang/Analysis/FlowSensitive/DataflowSolver.h +++ b/include/clang/Analysis/FlowSensitive/DataflowSolver.h @@ -24,7 +24,7 @@ namespace clang { //===----------------------------------------------------------------------===// /// DataflowWorkListTy - Data structure representing the worklist used for /// dataflow algorithms. -//===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// class DataflowWorkListTy { typedef llvm::SmallPtrSet<const CFGBlock*,20> BlockSet; @@ -70,11 +70,11 @@ template <> struct ItrTraits<forward_analysis_tag> { static StmtItr StmtEnd(const CFGBlock* B) { return B->end(); } static BlockEdge PrevEdge(const CFGBlock* B, const CFGBlock* Prev) { - return BlockEdge(Prev, B); + return BlockEdge(Prev, B, 0); } static BlockEdge NextEdge(const CFGBlock* B, const CFGBlock* Next) { - return BlockEdge(B, Next); + return BlockEdge(B, Next, 0); } }; @@ -93,11 +93,11 @@ template <> struct ItrTraits<backward_analysis_tag> { static StmtItr StmtEnd(const CFGBlock* B) { return B->rend(); } static BlockEdge PrevEdge(const CFGBlock* B, const CFGBlock* Prev) { - return BlockEdge(B, Prev); + return BlockEdge(B, Prev, 0); } static BlockEdge NextEdge(const CFGBlock* B, const CFGBlock* Next) { - return BlockEdge(Next, B); + return BlockEdge(Next, B, 0); } }; } // end namespace dataflow diff --git a/include/clang/Analysis/PathSensitive/AnalysisManager.h b/include/clang/Analysis/PathSensitive/AnalysisManager.h index 503c809c88..deff4818ce 100644 --- a/include/clang/Analysis/PathSensitive/AnalysisManager.h +++ b/include/clang/Analysis/PathSensitive/AnalysisManager.h @@ -23,7 +23,7 @@ namespace clang { class AnalysisManager : public BugReporterData { AnalysisContextManager ContextMgr; - AnalysisContext *RootContext; + AnalysisContext *EntryContext; LocationContextManager LocCtxMgr; @@ -59,7 +59,7 @@ public: VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge), EagerlyAssume(eager), TrimGraph(trim) { - RootContext = ContextMgr.getContext(d); + EntryContext = ContextMgr.getContext(d); } AnalysisManager(ASTContext &ctx, Diagnostic &diags, @@ -75,22 +75,22 @@ public: VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge), EagerlyAssume(eager), TrimGraph(trim) { - RootContext = 0; + EntryContext = 0; } - void setContext(Decl *D) { - RootContext = ContextMgr.getContext(D); + void setEntryContext(Decl *D) { + EntryContext = ContextMgr.getContext(D); DisplayedFunction = false; } Decl *getCodeDecl() const { assert (AScope == ScopeDecl); - return RootContext->getDecl(); + return EntryContext->getDecl(); } Stmt *getBody() const { assert (AScope == ScopeDecl); - return RootContext->getBody(); + return EntryContext->getBody(); } StoreManagerCreator getStoreManagerCreator() { @@ -102,15 +102,15 @@ public: } virtual CFG *getCFG() { - return RootContext->getCFG(); + return EntryContext->getCFG(); } virtual ParentMap &getParentMap() { - return RootContext->getParentMap(); + return EntryContext->getParentMap(); } virtual LiveVariables *getLiveVariables() { - return RootContext->getLiveVariables(); + return EntryContext->getLiveVariables(); } virtual ASTContext &getContext() { @@ -133,8 +133,8 @@ public: return PD.get(); } - StackFrameContext *getRootStackFrame() { - return LocCtxMgr.getStackFrame(RootContext, 0, 0); + StackFrameContext *getEntryStackFrame() { + return LocCtxMgr.getStackFrame(EntryContext, 0, 0); } bool shouldVisualizeGraphviz() const { return VisualizeEGDot; } diff --git a/include/clang/Analysis/PathSensitive/ExplodedGraph.h b/include/clang/Analysis/PathSensitive/ExplodedGraph.h index d3da3c105f..9b6507420b 100644 --- a/include/clang/Analysis/PathSensitive/ExplodedGraph.h +++ b/include/clang/Analysis/PathSensitive/ExplodedGraph.h @@ -39,7 +39,6 @@ class ASTContext; //===----------------------------------------------------------------------===// class ExplodedNode : public llvm::FoldingSetNode { -protected: friend class ExplodedGraph; friend class GRCoreEngine; friend class GRStmtNodeBuilder; @@ -111,6 +110,10 @@ public: /// getLocation - Returns the edge associated with the given node. ProgramPoint getLocation() const { return Location; } + const LocationContext *getLocationContext() const { + return getLocation().getContext(); + } + const GRState* getState() const { return State; } diff --git a/include/clang/Analysis/PathSensitive/GRCoreEngine.h b/include/clang/Analysis/PathSensitive/GRCoreEngine.h index e26f376a36..29336a195a 100644 --- a/include/clang/Analysis/PathSensitive/GRCoreEngine.h +++ b/include/clang/Analysis/PathSensitive/GRCoreEngine.h @@ -124,7 +124,7 @@ public: /// ExecuteWorkList - Run the worklist algorithm for a maximum number of /// steps. Returns true if there is still simulation state on the worklist. - bool ExecuteWorkList(unsigned Steps); + bool ExecuteWorkList(const LocationContext *L, unsigned Steps); CFG& getCFG() { return G->getCFG(); } }; diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 7b29039714..dcf4e56d11 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -16,6 +16,7 @@ #ifndef LLVM_CLANG_ANALYSIS_GREXPRENGINE #define LLVM_CLANG_ANALYSIS_GREXPRENGINE +#include "clang/Analysis/PathSensitive/AnalysisManager.h" #include "clang/Analysis/PathSensitive/GRSubEngine.h" #include "clang/Analysis/PathSensitive/GRCoreEngine.h" #include "clang/Analysis/PathSensitive/GRState.h" @@ -33,7 +34,8 @@ namespace clang { class Checker; class GRExprEngine : public GRSubEngine { -protected: + AnalysisManager &AMgr; + GRCoreEngine CoreEngine; /// G - the simulation graph. @@ -201,15 +203,15 @@ public: public: GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, LiveVariables& L, - BugReporterData& BRD, + AnalysisManager &mgr, bool purgeDead, bool eagerlyAssume = true, StoreManagerCreator SMC = CreateBasicStoreManager, ConstraintManagerCreator CMC = CreateBasicConstraintManager); ~GRExprEngine(); - void ExecuteWorkList(unsigned Steps = 150000) { - CoreEngine.ExecuteWorkList(Steps); + void ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) { + CoreEngine.ExecuteWorkList(L, Steps); } /// getContext - Return the ASTContext associated with this analysis. diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h index 8951e83a7c..cddcefa4e9 100644 --- a/include/clang/Analysis/ProgramPoint.h +++ b/include/clang/Analysis/ProgramPoint.h @@ -24,6 +24,8 @@ #include <utility> namespace clang { + +class LocationContext; class ProgramPoint { public: @@ -48,14 +50,20 @@ public: private: std::pair<const void *, const void *> Data; Kind K; + + // The LocationContext could be NULL to allow ProgramPoint to be used in + // context insensitive analysis. + const LocationContext *L; const void *Tag; protected: - ProgramPoint(const void* P, Kind k, const void *tag = 0) - : Data(P, NULL), K(k), Tag(tag) {} + ProgramPoint(const void* P, Kind k, const LocationContext *l, + const void *tag = 0) + : Data(P, NULL), K(k), L(l), Tag(tag) {} - ProgramPoint(const void* P1, const void* P2, Kind k, const void *tag = 0) - : Data(P1, P2), K(k), Tag(tag) {} + ProgramPoint(const void* P1, const void* P2, Kind k, const LocationContext *l, + const void *tag = 0) + : Data(P1, P2), K(k), L(l), Tag(tag) {} protected: const void* getData1() const { return Data.first; } @@ -65,6 +73,8 @@ protected: public: Kind getKind() const { return K; } + const LocationContext *getContext() const { return L; } + // For use with DenseMap. This hash is probably slow. unsigned getHashValue() const { llvm::FoldingSetNodeID ID; @@ -75,25 +85,27 @@ public: static bool classof(const ProgramPoint*) { return true; } bool operator==(const ProgramPoint & RHS) const { - return K == RHS.K && Data == RHS.Data && Tag == RHS.Tag; + return K == RHS.K && Data == RHS.Data && L == RHS.L && Tag == RHS.Tag; } bool operator!=(const ProgramPoint& RHS) const { - return K != RHS.K || Data != RHS.Data || Tag != RHS.Tag; + return K != RHS.K || Data != RHS.Data || L != RHS.L || Tag != RHS.Tag; } void Profile(llvm::FoldingSetNodeID& ID) const { ID.AddInteger((unsigned) K); ID.AddPointer(Data.first); ID.AddPointer(Data.second); + ID.AddPointer(L); ID.AddPointer(Tag); } }; class BlockEntrance : public ProgramPoint { public: - BlockEntrance(const CFGBlock* B, const void *tag = 0) - : ProgramPoint(B, BlockEntranceKind, tag) {} + BlockEntrance(const CFGBlock* B, const LocationContext *L, + const void *tag = 0) + : ProgramPoint(B, BlockEntranceKind, L, tag) {} CFGBlock* getBlock() const { return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1())); @@ -111,7 +123,8 @@ public: class BlockExit : public ProgramPoint { public: - BlockExit(const CFGBlock* B) : ProgramPoint(B, BlockExitKind) {} + BlockExit(const CFGBlock* B, const LocationContext *L) + : ProgramPoint(B, BlockExitKind, L) {} CFGBlock* getBlock() const { return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1())); @@ -133,8 +146,9 @@ public: class StmtPoint : public ProgramPoint { public: - StmtPoint(const Stmt *S, const void *p2, Kind k, const void *tag) - : ProgramPoint(S, p2, k, tag) {} + StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L, + const void *tag) + : ProgramPoint(S, p2, k, L, tag) {} const Stmt *getStmt() const { return (const Stmt*) getData1(); } @@ -150,8 +164,9 @@ public: class PreStmt : public StmtPoint { public: - PreStmt(const Stmt *S, const void *tag, const Stmt *SubStmt = 0) - : StmtPoint(S, SubStmt, PreStmtKind, tag) {} + PreStmt(const Stmt *S, const LocationContext *L, const void *tag, + const Stmt *SubStmt = 0) + : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {} const Stmt *getSubStmt() const { return (const Stmt*) getData2(); } @@ -162,15 +177,16 @@ public: class PostStmt : public StmtPoint { protected: - PostStmt(const Stmt* S, Kind k, const void *tag = 0) - : StmtPoint(S, NULL, k, tag) {} + PostStmt(const Stmt* S, Kind k, const LocationContext *L, const void *tag = 0) + : StmtPoint(S, NULL, k, L, tag) {} - PostStmt(const Stmt* S, const void* data, Kind k, const void *tag =0) - : StmtPoint(S, data, k, tag) {} + PostStmt(const Stmt* S, const void* data, Kind k, const LocationContext *L, + const void *tag =0) + : StmtPoint(S, data, k, L, tag) {} public: - explicit PostStmt(const Stmt* S, const void *tag = 0) - : StmtPoint(S, NULL, PostStmtKind, tag) {} + explicit PostStmt(const Stmt* S, const LocationContext *L,const void *tag = 0) + : StmtPoint(S, NULL, PostStmtKind, L, tag) {} static bool classof(const ProgramPoint* Location) { unsigned k = Location->getKind(); @@ -180,8 +196,9 @@ public: class PostLocationChecksSucceed : public PostStmt { public: - PostLocationChecksSucceed(const Stmt* S, const void *tag = 0) - : PostStmt(S, PostLocationChecksSucceedKind, tag) {} + PostLocationChecksSucceed(const Stmt* S, const LocationContext *L, + const void *tag = 0) + : PostStmt(S, PostLocationChecksSucceedKind, L, tag) {} static bool classof(const ProgramPoint* Location) { return Location->getKind() == PostLocationChecksSucceedKind; @@ -191,8 +208,9 @@ public: class PostStmtCustom : public PostStmt { public: PostStmtCustom(const Stmt* S, - const std::pair<const void*, const void*>* TaggedData) - : PostStmt(S, TaggedData, PostStmtCustomKind) {} + const std::pair<const void*, const void*>* TaggedData,\ + const LocationContext *L) + : PostStmt(S, TaggedData, PostStmtCustomKind, L) {} const std::pair<const void*, const void*>& getTaggedPair() const { return @@ -210,8 +228,9 @@ public: class PostOutOfBoundsCheckFailed : public PostStmt { public: - PostOutOfBoundsCheckFailed(const Stmt* S, const void *tag = 0) - : PostStmt(S, PostOutOfBoundsCheckFailedKind, tag) {} + PostOutOfBoundsCheckFailed(const Stmt* S, const LocationContext *L, + const void *tag = 0) + : PostStmt(S, PostOutOfBoundsCheckFailedKind, L, tag) {} static bool classof(const ProgramPoint* Location) { return Location->getKind() == PostOutOfBoundsCheckFailedKind; @@ -220,8 +239,9 @@ public: class PostUndefLocationCheckFailed : public PostStmt { public: - PostUndefLocationCheckFailed(const Stmt* S, const void *tag = 0) - : PostStmt(S, PostUndefLocationCheckFailedKind, tag) {} + PostUndefLocationCheckFailed(const Stmt* S, const LocationContext *L, + const void *tag = 0) + : PostStmt(S, PostUndefLocationCheckFailedKind, L, tag) {} static bool classof(const ProgramPoint* Location) { return Location->getKind() == PostUndefLocationCheckFailedKind; @@ -230,8 +250,9 @@ public: class PostNullCheckFailed : public PostStmt { public: - PostNullCheckFailed(const Stmt* S, const void *tag = 0) - : PostStmt(S, PostNullCheckFailedKind, tag) {} + PostNullCheckFailed(const Stmt* S, const LocationContext *L, + const void *tag = 0) + : PostStmt(S, PostNullCheckFailedKind, L, tag) {} static bool classof(const ProgramPoint* Location) { return Location->getKind() == PostNullCheckFailedKind; @@ -240,8 +261,8 @@ public: class PostLoad : public PostStmt { public: - PostLoad(const Stmt* S, const void *tag = 0) - : PostStmt(S, PostLoadKind, tag) {} + PostLoad(const Stmt* S, const LocationContext *L, const void *tag = 0) + : PostStmt(S, PostLoadKind, L, tag) {} static bool classof(const ProgramPoint* Location) { return Location->getKind() == PostLoadKind; @@ -250,8 +271,8 @@ public: class PostStore : public PostStmt { public: - PostStore(const Stmt* S, const void *tag = 0) - : PostStmt(S, PostStoreKind, tag) {} + PostStore(const Stmt* S, const LocationContext *L, const void *tag = 0) + : PostStmt(S, PostStoreKind, L, tag) {} static bool classof(const ProgramPoint* Location) { return Location->getKind() == PostStoreKind; @@ -260,8 +281,8 @@ public: class PostLValue : public PostStmt { public: - PostLValue(const Stmt* S, const void *tag = 0) - : PostStmt(S, PostLValueKind, tag) {} + PostLValue(const Stmt* S, const LocationContext *L, const void *tag = 0) + : PostStmt(S, PostLValueKind, L, tag) {} static bool classof(const ProgramPoint* Location) { return Location->getKind() == PostLValueKind; @@ -270,8 +291,9 @@ public: class PostPurgeDeadSymbols : public PostStmt { public: - PostPurgeDeadSymbols(const Stmt* S, const void *tag = 0) - : PostStmt(S, PostPurgeDeadSymbolsKind, tag) {} + PostPurgeDeadSymbols(const Stmt* S, const LocationContext *L, + const void *tag = 0) + : PostStmt(S, PostPurgeDeadSymbolsKind, L, tag) {} static bool classof(const ProgramPoint* Location) { return Location->getKind() == PostPurgeDeadSymbolsKind; @@ -280,8 +302,8 @@ public: class BlockEdge : public ProgramPoint { public: - BlockEdge(const CFGBlock* B1, const CFGBlock* B2) - : ProgramPoint(B1, B2, BlockEdgeKind) {} + BlockEdge(const CFGBlock* B1, const CFGBlock* B2, const LocationContext *L) + : ProgramPoint(B1, B2, BlockEdgeKind, L) {} CFGBlock* getSrc() const { return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData1())); @@ -307,13 +329,13 @@ template <> struct DenseMapInfo<clang::ProgramPoint> { static inline clang::ProgramPoint getEmptyKey() { uintptr_t x = reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7; - return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); + return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0); } static inline clang::ProgramPoint getTombstoneKey() { uintptr_t x = - reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7; - return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); + reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7; + return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0); } static unsigned getHashValue(const clang::ProgramPoint& Loc) { diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 02f427a91e..683be27cb2 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -181,7 +181,8 @@ public: ExplodedNode *MakeNode(const GRState *state, ExplodedNode *Pred) { if (SNB) - return SNB->generateNode(PostStmt(S, tag), state, Pred); + return SNB->generateNode(PostStmt(S, Pred->getLocationContext(), tag), + state, Pred); assert(ENB); return ENB->generateNode(state, Pred); @@ -3203,7 +3204,8 @@ void CFRefCount::EvalReturn(ExplodedNodeSet& Dst, static int ReturnOwnLeakTag = 0; state = state->set<RefBindings>(Sym, X); ExplodedNode *N = - Builder.generateNode(PostStmt(S, &ReturnOwnLeakTag), state, Pred); + Builder.generateNode(PostStmt(S, Pred->getLocationContext(), + &ReturnOwnLeakTag), state, Pred); if (N) { CFRefReport *report = new CFRefLeakReport(*static_cast<CFRefBug*>(leakAtReturn), *this, @@ -3224,8 +3226,9 @@ void CFRefCount::EvalReturn(ExplodedNodeSet& Dst, static int ReturnNotOwnedForOwnedTag = 0; state = state->set<RefBindings>(Sym, X ^ RefVal::ErrorReturnedNotOwned); if (ExplodedNode *N = - Builder.generateNode(PostStmt(S, &ReturnNotOwnedForOwnedTag), - state, Pred)) { + Builder.generateNode(PostStmt(S, Pred->getLocationContext(), + &ReturnNotOwnedForOwnedTag), + state, Pred)) { CFRefReport *report = new CFRefReport(*static_cast<CFRefBug*>(returnNotOwnedForOwned), *this, N, Sym); diff --git a/lib/Analysis/GRCoreEngine.cpp b/lib/Analysis/GRCoreEngine.cpp index 66c12fd00f..cd20e3ca66 100644 --- a/lib/Analysis/GRCoreEngine.cpp +++ b/lib/Analysis/GRCoreEngine.cpp @@ -146,7 +146,7 @@ void GRCoreEngine::ProcessSwitch(GRSwitchNodeBuilder& Builder) { } /// ExecuteWorkList - Run the worklist algorithm for a maximum number of steps. -bool GRCoreEngine::ExecuteWorkList(unsigned Steps) { +bool GRCoreEngine::ExecuteWorkList(const LocationContext *L, unsigned Steps) { if (G->num_roots() == 0) { // Initialize the analysis by constructing // the root if none exists. @@ -164,7 +164,7 @@ bool GRCoreEngine::ExecuteWorkList(unsigned Steps) { // Construct an edge representing the // starting location in the function. - BlockEdge StartLoc(Entry, Succ); + BlockEdge StartLoc(Entry, Succ, L); // Set the current block counter to being empty. WList->setBlockCounter(BCounterFactory.GetEmptyCounter()); @@ -230,7 +230,7 @@ void GRCoreEngine::HandleBlockEdge(const BlockEdge& L, ExplodedNode* Pred) { // FIXME: Should we allow ProcessBlockEntrance to also manipulate state? if (ProcessBlockEntrance(Blk, Pred->State, WList->getBlockCounter())) - GenerateNode(BlockEntrance(Blk), Pred->State, Pred); + GenerateNode(BlockEntrance(Blk, Pred->getLocationContext()), Pred->State, Pred); } void GRCoreEngine::HandleBlockEntrance(const BlockEntrance& L, @@ -335,7 +335,8 @@ void GRCoreEngine::HandleBlockExit(CFGBlock * B, ExplodedNode* Pred) { assert (B->succ_size() == 1 && "Blocks with no terminator should have at most 1 successor."); - GenerateNode(BlockEdge(B, *(B->succ_begin())), Pred->State, Pred); + GenerateNode(BlockEdge(B, *(B->succ_begin()), Pred->getLocationContext()), + Pred->State, Pred); } void GRCoreEngine::HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock * B, @@ -400,7 +401,7 @@ GRStmtNodeBuilder::~GRStmtNodeBuilder() { void GRStmtNodeBuilder::GenerateAutoTransition(ExplodedNode* N) { assert (!N->isSink()); - PostStmt Loc(getStmt()); + PostStmt Loc(getStmt(), N->getLocationContext()); if (Loc == N->getLocation()) { // Note: 'N' should be a fresh node because otherwise it shouldn't be @@ -418,37 +419,37 @@ void GRStmtNodeBuilder::GenerateAutoTransition(ExplodedNode* N) { } static inline PostStmt GetPostLoc(const Stmt* S, ProgramPoint::Kind K, - const void *tag) { + const LocationContext *L, const void *tag) { switch (K) { default: assert(false && "Invalid PostXXXKind."); case ProgramPoint::PostStmtKind: - return PostStmt(S, tag); + return PostStmt(S, L, tag); case ProgramPoint::PostLoadKind: - return PostLoad(S, tag); + return PostLoad(S, L, tag); case ProgramPoint::PostUndefLocationCheckFailedKind: - return PostUndefLocationCheckFailed(S, tag); + return PostUndefLocationCheckFailed(S, L, tag); case ProgramPoint::PostLocationChecksSucceedKind: - return PostLocationChecksSucceed(S, tag); + return PostLocationChecksSucceed(S, L, tag); case ProgramPoint::PostOutOfBoundsCheckFailedKind: - return PostOutOfBoundsCheckFailed(S, tag); + return PostOutOfBoundsCheckFailed(S, L, tag); case ProgramPoint::PostNullCheckFailedKind: - return PostNullCheckFailed(S, tag); + return PostNullCheckFailed(S, L, tag); case ProgramPoint::PostStoreKind: - return PostStore(S, tag); + return PostStore(S, L, tag); case ProgramPoint::PostLValueKind: - return PostLValue(S, tag); + return PostLValue(S, L, tag); case ProgramPoint::PostPurgeDeadSymbolsKind: - return PostPurgeDeadSymbols(S, tag); + return PostPurgeDeadSymbols(S, L, tag); } } @@ -458,8 +459,10 @@ GRStmtNodeBuilder::generateNodeInternal(const Stmt* S, const GRState* State, ProgramPoint::Kind K, const void *tag) { return K == ProgramPoint::PreStmtKind - ? generateNodeInternal(PreStmt(S, tag), State, Pred) - : generateNodeInternal(GetPostLoc(S, K, tag), State, Pred); + ? generateNodeInternal(PreStmt(S, Pred->getLocationContext(),tag), + State, Pred) + : generateNodeInternal(GetPostLoc(S, K, Pred->getLocationContext(), tag), + State, Pred); } ExplodedNode* @@ -491,7 +494,8 @@ ExplodedNode* GRBranchNodeBuilder::generateNode(const GRState* State, bool IsNew; ExplodedNode* Succ = - Eng.G->getNode(BlockEdge(Src, branch ? DstT : DstF), State, &IsNew); + Eng.G->getNode(BlockEdge(Src,branch ? DstT:DstF,Pred->getLocationContext()), + State, &IsNew); Succ->addPredecessor(Pred); @@ -522,7 +526,8 @@ GRIndirectGotoNodeBuilder::generateNode(const iterator& I, const GRState* St, bool isSink) { bool IsNew; - ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock()), St, &IsNew); + ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock(), + Pred->getLocationContext()), St, &IsNew); Succ->addPredecessor(Pred); @@ -545,7 +550,8 @@ GRSwitchNodeBuilder::generateCaseStmtNode(const iterator& I, const GRState* St){ bool IsNew; - ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock()), St, &IsNew); + ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock(), + Pred->getLocationContext()), St, &IsNew); Succ->addPredecessor(Pred); if (IsNew) { @@ -566,7 +572,8 @@ GRSwitchNodeBuilder::generateDefaultCaseNode(const GRState* St, bool isSink) { bool IsNew; - ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, DefaultBlock), St, &IsNew); + ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, DefaultBlock, + Pred->getLocationContext()), St, &IsNew); Succ->addPredecessor(Pred); if (IsNew) { @@ -592,7 +599,8 @@ GREndPathNodeBuilder::generateNode(const GRState* State, const void *tag, HasGeneratedNode = true; bool IsNew; - ExplodedNode* Node = Eng.G->getNode(BlockEntrance(&B, tag), State, &IsNew); + ExplodedNode* Node = Eng.G->getNode(BlockEntrance(&B, + Pred->getLocationContext(), tag), State, &IsNew); Node->addPredecessor(P ? P : Pred); diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 47f77ce3bd..849dd354bb 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -149,11 +149,12 @@ static inline Selector GetNullarySelector(const char* name, ASTContext& Ctx) { GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, - LiveVariables& L, BugReporterData& BRD, + LiveVariables& L, AnalysisManager &mgr, bool purgeDead, bool eagerlyAssume, StoreManagerCreator SMC, ConstraintManagerCreator CMC) - : CoreEngine(cfg, CD, Ctx, *this), + : AMgr(mgr), + CoreEngine(cfg, CD, Ctx, *this), G(CoreEngine.getGraph()), Liveness(L), Builder(NULL), @@ -165,7 +166,7 @@ GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL), RaiseSel(GetNullarySelector("raise", G.getContext())), PurgeDead(purgeDead), - BR(BRD, *this), + BR(mgr, *this), EagerlyAssume(eagerlyAssume) {} GRExprEngine::~GRExprEngine() { @@ -1699,7 +1700,8 @@ void GRExprEngine::EvalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, if (const GRState *stateTrue = state->assume(V, true)) { stateTrue = stateTrue->bindExpr(Ex, ValMgr.makeIntVal(1U, Ex->getType())); - Dst.Add(Builder->generateNode(PostStmtCustom(Ex, &EagerlyAssumeTag), + Dst.Add(Builder->generateNode(PostStmtCustom(Ex, + &EagerlyAssumeTag, Pred->getLocationContext()), stateTrue, Pred)); } @@ -1707,7 +1709,8 @@ void GRExprEngine::EvalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, if (const GRState *stateFalse = state->assume(V, false)) { stateFalse = stateFalse->bindExpr(Ex, ValMgr.makeIntVal(0U, Ex->getType())); - Dst.Add(Builder->generateNode(PostStmtCustom(Ex, &EagerlyAssumeTag), + Dst.Add(Builder->generateNode(PostStmtCustom(Ex, &EagerlyAssumeTag, + Pred->getLocationContext()), stateFalse, Pred)); } } diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp index 11ffdebb2b..16639e0371 100644 --- a/lib/Frontend/AnalysisConsumer.cpp +++ b/lib/Frontend/AnalysisConsumer.cpp @@ -258,7 +258,7 @@ void AnalysisConsumer::HandleCode(Decl* D, Stmt* Body, Actions& actions) { !Ctx->getSourceManager().isFromMainFile(D->getLocation())) return; - Mgr->setContext(D); + Mgr->setEntryContext(D); // Dispatch on the actions. for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I) @@ -315,7 +315,7 @@ static void ActionGRExprEngine(AnalysisManager& mgr, GRTransferFuncs* tf, } // Execute the worklist algorithm. - Eng.ExecuteWorkList(); + Eng.ExecuteWorkList(mgr.getEntryStackFrame()); // Release the auditor (if any) so that it doesn't monitor the graph // created BugReporter. |