From 3070e13dca5bbefa32acb80ce4a7b217a6220983 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Sat, 7 Jan 2012 01:03:17 +0000 Subject: [PATCH] [analyzer] Remove CallEnterNodeBuilder and simplify ExprEngine::processCallEnter(). This removes analysis of other translation units, but that was an experimental feature anyway that we will revisit later. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147705 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Core/PathSensitive/CoreEngine.h | 49 +----------- .../Core/PathSensitive/ExprEngine.h | 2 +- .../Core/PathSensitive/SubEngine.h | 3 +- lib/StaticAnalyzer/Core/CoreEngine.cpp | 78 +------------------ lib/StaticAnalyzer/Core/ExprEngine.cpp | 3 +- .../Core/ExprEngineCallAndReturn.cpp | 31 ++++++-- 6 files changed, 33 insertions(+), 133 deletions(-) diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h index af5ed273a9..041a60f60e 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h @@ -46,8 +46,6 @@ class CoreEngine { friend class IndirectGotoNodeBuilder; friend class SwitchNodeBuilder; friend class EndOfFunctionNodeBuilder; - friend class CallEnterNodeBuilder; - public: typedef std::vector > BlocksExhausted; @@ -91,9 +89,6 @@ private: void HandleBranch(const Stmt *Cond, const Stmt *Term, const CFGBlock *B, ExplodedNode *Pred); - void HandleCallEnter(const CallEnter &L, const CFGBlock *Block, - unsigned Index, ExplodedNode *Pred); - void HandleCallExit(const CallExit &L, ExplodedNode *Pred); private: CoreEngine(const CoreEngine&); // Do not implement. @@ -528,49 +523,7 @@ public: } }; -class CallEnterNodeBuilder { - CoreEngine &Eng; - - const ExplodedNode *Pred; - - // The call site. For implicit automatic object dtor, this is the trigger - // statement. - const Stmt *CE; - - // The context of the callee. - const StackFrameContext *CalleeCtx; - - // The parent block of the CallExpr. - const CFGBlock *Block; - - // The CFGBlock index of the CallExpr. - unsigned Index; - -public: - CallEnterNodeBuilder(CoreEngine &eng, const ExplodedNode *pred, - const Stmt *s, const StackFrameContext *callee, - const CFGBlock *blk, unsigned idx) - : Eng(eng), Pred(pred), CE(s), CalleeCtx(callee), Block(blk), Index(idx) {} - - const ProgramState *getState() const { return Pred->getState(); } - - const LocationContext *getLocationContext() const { - return Pred->getLocationContext(); - } - - const Stmt *getCallExpr() const { return CE; } - - const StackFrameContext *getCalleeContext() const { return CalleeCtx; } - - const CFGBlock *getBlock() const { return Block; } - - unsigned getIndex() const { return Index; } - - void generateNode(const ProgramState *state); -}; - -} // end GR namespace - +} // end ento namespace } // end clang namespace #endif diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index 47178b5d94..51173a52ec 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -185,7 +185,7 @@ public: void processEndOfFunction(NodeBuilderContext& BC); /// Generate the entry node of the callee. - void processCallEnter(CallEnterNodeBuilder &builder); + void processCallEnter(CallEnter CE, ExplodedNode *Pred); /// Generate the first post callsite node. void processCallExit(ExplodedNode *Pred); diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h index 7008ba3ea7..d1172aee0d 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h @@ -37,7 +37,6 @@ class BranchNodeBuilder; class IndirectGotoNodeBuilder; class SwitchNodeBuilder; class EndOfFunctionNodeBuilder; -class CallEnterNodeBuilder; class NodeBuilderWithSinks; class MemRegion; @@ -84,7 +83,7 @@ public: virtual void processEndOfFunction(NodeBuilderContext& BC) = 0; // Generate the entry node of the callee. - virtual void processCallEnter(CallEnterNodeBuilder &builder) = 0; + virtual void processCallEnter(CallEnter CE, ExplodedNode *Pred) = 0; // Generate the first post callsite node. virtual void processCallExit(ExplodedNode *Pred) = 0; diff --git a/lib/StaticAnalyzer/Core/CoreEngine.cpp b/lib/StaticAnalyzer/Core/CoreEngine.cpp index c505c44a97..b39b0f23b4 100644 --- a/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -215,12 +215,11 @@ bool CoreEngine::ExecuteWorkList(const LocationContext *L, unsigned Steps, break; case ProgramPoint::CallEnterKind: - HandleCallEnter(cast(Node->getLocation()), WU.getBlock(), - WU.getIndex(), Node); + SubEng.processCallEnter(cast(Node->getLocation()), Node); break; case ProgramPoint::CallExitKind: - HandleCallExit(cast(Node->getLocation()), Node); + SubEng.processCallExit(Node); break; default: @@ -246,17 +245,6 @@ void CoreEngine::ExecuteWorkListWithInitialState(const LocationContext *L, } } -void CoreEngine::HandleCallEnter(const CallEnter &L, const CFGBlock *Block, - unsigned Index, ExplodedNode *Pred) { - CallEnterNodeBuilder Builder(*this, Pred, L.getCallExpr(), - L.getCalleeContext(), Block, Index); - SubEng.processCallEnter(Builder); -} - -void CoreEngine::HandleCallExit(const CallExit &L, ExplodedNode *Pred) { - SubEng.processCallExit(Pred); -} - void CoreEngine::HandleBlockEdge(const BlockEdge &L, ExplodedNode *Pred) { const CFGBlock *Blk = L.getDst(); @@ -644,65 +632,3 @@ SwitchNodeBuilder::generateDefaultCaseNode(const ProgramState *St, return Succ; } - -void CallEnterNodeBuilder::generateNode(const ProgramState *state) { - // Check if the callee is in the same translation unit. - if (CalleeCtx->getTranslationUnit() != - Pred->getLocationContext()->getTranslationUnit()) { - // Create a new engine. We must be careful that the new engine should not - // reference data structures owned by the old engine. - - AnalysisManager &OldMgr = Eng.SubEng.getAnalysisManager(); - - // Get the callee's translation unit. - idx::TranslationUnit *TU = CalleeCtx->getTranslationUnit(); - - // Create a new AnalysisManager with components of the callee's - // TranslationUnit. - // The Diagnostic is actually shared when we create ASTUnits from AST files. - AnalysisManager AMgr(TU->getASTContext(), TU->getDiagnostic(), OldMgr); - - // Create the new engine. - // FIXME: This cast isn't really safe. - bool GCEnabled = static_cast(Eng.SubEng).isObjCGCEnabled(); - ExprEngine NewEng(AMgr, GCEnabled); - - // Create the new LocationContext. - AnalysisDeclContext *NewAnaCtx = - AMgr.getAnalysisDeclContext(CalleeCtx->getDecl(), - CalleeCtx->getTranslationUnit()); - - const StackFrameContext *OldLocCtx = CalleeCtx; - const StackFrameContext *NewLocCtx = - NewAnaCtx->getStackFrame(OldLocCtx->getParent(), - OldLocCtx->getCallSite(), - OldLocCtx->getCallSiteBlock(), - OldLocCtx->getIndex()); - - // Now create an initial state for the new engine. - const ProgramState *NewState = - NewEng.getStateManager().MarshalState(state, NewLocCtx); - ExplodedNodeSet ReturnNodes; - NewEng.ExecuteWorkListWithInitialState(NewLocCtx, AMgr.getMaxNodes(), - NewState, ReturnNodes); - return; - } - - // Get the callee entry block. - const CFGBlock *Entry = &(CalleeCtx->getCFG()->getEntry()); - assert(Entry->empty()); - assert(Entry->succ_size() == 1); - - // Get the solitary successor. - const CFGBlock *SuccB = *(Entry->succ_begin()); - - // Construct an edge representing the starting location in the callee. - BlockEdge Loc(Entry, SuccB, CalleeCtx); - - bool isNew; - ExplodedNode *Node = Eng.G->getNode(Loc, state, false, &isNew); - Node->addPredecessor(const_cast(Pred), *Eng.G); - - if (isNew) - Eng.WList->enqueue(Node); -} diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index 2ab501a267..c520cc1afa 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1616,7 +1616,8 @@ bool ExprEngine::InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, const StackFrameContext *stackFrame = AMgr.getStackFrame(AMgr.getAnalysisDeclContext(FD), Pred->getLocationContext(), - CE, currentBuilderContext->getBlock(), currentStmtIdx); + CE, currentBuilderContext->getBlock(), + currentStmtIdx); // Now we have the definition of the callee, create a CallEnter node. CallEnter Loc(CE, stackFrame, Pred->getLocationContext()); diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index 8a08c692d3..c8975cba3b 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -28,10 +28,32 @@ namespace { int ReturnExpr::TagInt; } -void ExprEngine::processCallEnter(CallEnterNodeBuilder &B) { - const ProgramState *state = - B.getState()->enterStackFrame(B.getCalleeContext()); - B.generateNode(state); +void ExprEngine::processCallEnter(CallEnter CE, ExplodedNode *Pred) { + // Get the entry block in the CFG of the callee. + const StackFrameContext *SFC = CE.getCalleeContext(); + const CFG *CalleeCFG = SFC->getCFG(); + const CFGBlock *Entry = &(CalleeCFG->getEntry()); + + // Validate the CFG. + assert(Entry->empty()); + assert(Entry->succ_size() == 1); + + // Get the solitary sucessor. + const CFGBlock *Succ = *(Entry->succ_begin()); + + // Construct an edge representing the starting location in the callee. + BlockEdge Loc(Entry, Succ, SFC); + + // Construct a new state which contains the mapping from actual to + // formal arguments. + const ProgramState *state = Pred->getState()->enterStackFrame(SFC); + + // Construct a new node and add it to the worklist. + bool isNew; + ExplodedNode *Node = G.getNode(Loc, state, false, &isNew); + Node->addPredecessor(Pred, G); + if (isNew) + Engine.getWorkList()->enqueue(Node); } void ExprEngine::processCallExit(ExplodedNode *Pred) { @@ -59,7 +81,6 @@ void ExprEngine::processCallExit(ExplodedNode *Pred) { // Always bind the region to the CXXConstructExpr. state = state->BindExpr(CCE, Pred->getLocationContext(), ThisV); } - PostStmt Loc(CE, calleeCtx->getParent()); bool isNew;