From: Zhongxing Xu Date: Thu, 24 Dec 2009 03:34:38 +0000 (+0000) Subject: As Ted suggested, record the callsite information with the StackFrameContext. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=62d399e1880aacd9dc494fce374245b0da915ada;p=clang As Ted suggested, record the callsite information with the StackFrameContext. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92121 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/AnalysisContext.h b/include/clang/Analysis/PathSensitive/AnalysisContext.h index abc33b7784..63ba558e3d 100644 --- a/include/clang/Analysis/PathSensitive/AnalysisContext.h +++ b/include/clang/Analysis/PathSensitive/AnalysisContext.h @@ -27,6 +27,7 @@ namespace clang { class Decl; class Stmt; class CFG; +class CFGBlock; class LiveVariables; class ParentMap; class ImplicitParamDecl; @@ -136,23 +137,38 @@ public: }; class StackFrameContext : public LocationContext { + // The callsite where this stack frame is established. const Stmt *CallSite; + // The parent block of the callsite. + const CFGBlock *Block; + + // The index of the callsite in the CFGBlock. + unsigned Index; + friend class LocationContextManager; StackFrameContext(AnalysisContext *ctx, const LocationContext *parent, - const Stmt *s) - : LocationContext(StackFrame, ctx, parent), CallSite(s) {} + const Stmt *s, const CFGBlock *blk, unsigned idx) + : LocationContext(StackFrame, ctx, parent), CallSite(s), Block(blk), + Index(idx) {} public: ~StackFrameContext() {} const Stmt *getCallSite() const { return CallSite; } + const CFGBlock *getCallSiteBlock() const { return Block; } + + unsigned getIndex() const { return Index; } + void Profile(llvm::FoldingSetNodeID &ID); static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx, - const LocationContext *parent, const Stmt *s) { + const LocationContext *parent, const Stmt *s, + const CFGBlock *blk, unsigned idx) { ProfileCommon(ID, StackFrame, ctx, parent, s); + ID.AddPointer(blk); + ID.AddInteger(idx); } static bool classof(const LocationContext* Ctx) { @@ -230,7 +246,8 @@ public: const StackFrameContext *getStackFrame(AnalysisContext *ctx, const LocationContext *parent, - const Stmt *s); + const Stmt *s, const CFGBlock *blk, + unsigned idx); const ScopeContext *getScope(AnalysisContext *ctx, const LocationContext *parent, diff --git a/include/clang/Analysis/PathSensitive/AnalysisManager.h b/include/clang/Analysis/PathSensitive/AnalysisManager.h index 70a5082821..8288864f2b 100644 --- a/include/clang/Analysis/PathSensitive/AnalysisManager.h +++ b/include/clang/Analysis/PathSensitive/AnalysisManager.h @@ -132,14 +132,15 @@ public: // Get the top level stack frame. const StackFrameContext *getStackFrame(Decl const *D) { - return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), 0, 0); + return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), 0, 0, 0, 0); } // Get a stack frame with parent. StackFrameContext const *getStackFrame(Decl const *D, LocationContext const *Parent, - Stmt const *S) { - return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), Parent, S); + Stmt const *S, const CFGBlock *Blk, + unsigned Idx) { + return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), Parent, S, Blk,Idx); } }; diff --git a/lib/Analysis/AnalysisContext.cpp b/lib/Analysis/AnalysisContext.cpp index 05e5196c5b..97e6d914d4 100644 --- a/lib/Analysis/AnalysisContext.cpp +++ b/lib/Analysis/AnalysisContext.cpp @@ -105,7 +105,7 @@ void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID, } void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getAnalysisContext(), getParent(), CallSite); + Profile(ID, getAnalysisContext(), getParent(), CallSite, Block, Index); } void ScopeContext::Profile(llvm::FoldingSetNodeID &ID) { @@ -145,8 +145,18 @@ LocationContextManager::getLocationContext(AnalysisContext *ctx, const StackFrameContext* LocationContextManager::getStackFrame(AnalysisContext *ctx, const LocationContext *parent, - const Stmt *s) { - return getLocationContext(ctx, parent, s); + const Stmt *s, const CFGBlock *blk, + unsigned idx) { + llvm::FoldingSetNodeID ID; + StackFrameContext::Profile(ID, ctx, parent, s, blk, idx); + void *InsertPos; + StackFrameContext *L = + cast_or_null(Contexts.FindNodeOrInsertPos(ID, InsertPos)); + if (!L) { + L = new StackFrameContext(ctx, parent, s, blk, idx); + Contexts.InsertNode(L, InsertPos); + } + return L; } const ScopeContext * diff --git a/lib/Analysis/CallInliner.cpp b/lib/Analysis/CallInliner.cpp index 618d82354e..d18bbcc017 100644 --- a/lib/Analysis/CallInliner.cpp +++ b/lib/Analysis/CallInliner.cpp @@ -19,11 +19,6 @@ 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 > CallSitePosition; - public: static void *getTag() { static int x; @@ -43,7 +38,7 @@ bool CallInliner::EvalCallExpr(CheckerContext &C, const CallExpr *CE) { const GRState *state = C.getState(); const Expr *Callee = CE->getCallee(); SVal L = state->getSVal(Callee); - + const FunctionDecl *FD = L.getAsFunctionDecl(); if (!FD) return false; @@ -51,9 +46,11 @@ bool CallInliner::EvalCallExpr(CheckerContext &C, const CallExpr *CE) { if (!FD->isThisDeclarationADefinition()) return false; + GRStmtNodeBuilder &Builder = C.getNodeBuilder(); // Make a new LocationContext. const StackFrameContext *LocCtx = C.getAnalysisManager().getStackFrame(FD, - C.getPredecessor()->getLocationContext(), CE); + C.getPredecessor()->getLocationContext(), CE, + Builder.getBlock(), Builder.getIndex()); CFGBlock const *Entry = &(LocCtx->getCFG()->getEntry()); @@ -72,7 +69,7 @@ bool CallInliner::EvalCallExpr(CheckerContext &C, const CallExpr *CE) { bool isNew; GRExprEngine &Eng = C.getEngine(); ExplodedNode *Pred = C.getPredecessor(); - GRStmtNodeBuilder &Builder = C.getNodeBuilder(); + ExplodedNode *SuccN = Eng.getGraph().getNode(Loc, state, &isNew); SuccN->addPredecessor(Pred, Eng.getGraph()); @@ -83,8 +80,6 @@ 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; } @@ -107,13 +102,12 @@ void CallInliner::EvalEndPath(GREndPathNodeBuilder &B, void *tag, 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.getWorkList().Enqueue(Succ, + *const_cast(LocCtx->getCallSiteBlock()), + LocCtx->getIndex() + 1); B.HasGeneratedNode = true; }