diff options
author | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-12-24 02:25:21 +0000 |
---|---|---|
committer | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-12-24 02:25:21 +0000 |
commit | 598278bee8e5797bc73d24d6ac8a1d6ff6413cae (patch) | |
tree | 06c79858615a4bc2b2e87029fc63837701e9cf3d /lib/Analysis/CallInliner.cpp | |
parent | 6281213d87e71b76f64c4ca62fbe7a97f18ae0a0 (diff) |
Inter-procedural analysis: now we can return from the callee.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92116 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/CallInliner.cpp')
-rw-r--r-- | lib/Analysis/CallInliner.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/Analysis/CallInliner.cpp b/lib/Analysis/CallInliner.cpp index 2f748bd8bd..618d82354e 100644 --- a/lib/Analysis/CallInliner.cpp +++ b/lib/Analysis/CallInliner.cpp @@ -19,6 +19,11 @@ using namespace clang; namespace { class CallInliner : public Checker { + + /// CallSitePosition - Map the call site to its CFG block and stmt index. This + /// is used when exiting from a callee. + llvm::DenseMap<const Stmt *, std::pair<CFGBlock*,unsigned> > CallSitePosition; + public: static void *getTag() { static int x; @@ -26,6 +31,7 @@ public: } virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE); + virtual void EvalEndPath(GREndPathNodeBuilder &B,void *tag,GRExprEngine &Eng); }; } @@ -77,6 +83,37 @@ bool CallInliner::EvalCallExpr(CheckerContext &C, const CallExpr *CE) { Builder.HasGeneratedNode = true; + // Record the call site position. + CallSitePosition[CE] = std::make_pair(Builder.getBlock(), Builder.getIndex()); return true; } +void CallInliner::EvalEndPath(GREndPathNodeBuilder &B, void *tag, + GRExprEngine &Eng) { + const GRState *state = B.getState(); + ExplodedNode *Pred = B.getPredecessor(); + const StackFrameContext *LocCtx = + cast<StackFrameContext>(Pred->getLocationContext()); + + const Stmt *CE = LocCtx->getCallSite(); + + // Check if this is the top level stack frame. + if (!LocCtx->getParent()) + return; + + PostStmt NodeLoc(CE, LocCtx->getParent()); + + bool isNew; + ExplodedNode *Succ = Eng.getGraph().getNode(NodeLoc, state, &isNew); + Succ->addPredecessor(Pred, Eng.getGraph()); + + assert(CallSitePosition.find(CE) != CallSitePosition.end()); + + // When creating the new work list unit, increment the statement index to + // point to the statement after the CallExpr. + if (isNew) + B.getWorkList().Enqueue(Succ, *CallSitePosition[CE].first, + CallSitePosition[CE].second + 1); + + B.HasGeneratedNode = true; +} |