[cfe-commits] r109105 - in /cfe/trunk: examples/wpa/clang-wpa.cpp include/clang/Analysis/AnalysisContext.h include/clang/Checker/PathSensitive/AnalysisManager.h include/clang/Checker/PathSensitive/GRCoreEngine.h include/clang/Checker/PathSensitive/GRExprEngine.h include/clang/Checker/PathSensitive/GRState.h include/clang/Checker/PathSensitive/GRSubEngine.h include/clang/Index/TranslationUnit.h lib/Analysis/AnalysisContext.cpp lib/Checker/GRCoreEngine.cpp lib/Checker/GRState.cpp

Zhongxing Xu xuzhongxing at gmail.com
Thu Jul 22 06:52:13 PDT 2010


Author: zhongxingxu
Date: Thu Jul 22 08:52:13 2010
New Revision: 109105

URL: http://llvm.org/viewvc/llvm-project?rev=109105&view=rev
Log:
Make a bunch of new data structures for the new analysis
engine of the new translation unit. State marshal is there but no real
work is done. End nodes are passed back.

Modified:
    cfe/trunk/examples/wpa/clang-wpa.cpp
    cfe/trunk/include/clang/Analysis/AnalysisContext.h
    cfe/trunk/include/clang/Checker/PathSensitive/AnalysisManager.h
    cfe/trunk/include/clang/Checker/PathSensitive/GRCoreEngine.h
    cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h
    cfe/trunk/include/clang/Checker/PathSensitive/GRState.h
    cfe/trunk/include/clang/Checker/PathSensitive/GRSubEngine.h
    cfe/trunk/include/clang/Index/TranslationUnit.h
    cfe/trunk/lib/Analysis/AnalysisContext.cpp
    cfe/trunk/lib/Checker/GRCoreEngine.cpp
    cfe/trunk/lib/Checker/GRState.cpp

Modified: cfe/trunk/examples/wpa/clang-wpa.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/examples/wpa/clang-wpa.cpp?rev=109105&r1=109104&r2=109105&view=diff
==============================================================================
--- cfe/trunk/examples/wpa/clang-wpa.cpp (original)
+++ cfe/trunk/examples/wpa/clang-wpa.cpp Thu Jul 22 08:52:13 2010
@@ -62,6 +62,10 @@
     return AST->getPreprocessor();
   }
 
+  virtual Diagnostic &getDiagnostic() {
+    return AST->getDiagnostics();
+  }
+
   virtual DeclReferenceMap &getDeclReferenceMap() {
     return DeclRefMap;
   }

Modified: cfe/trunk/include/clang/Analysis/AnalysisContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/AnalysisContext.h?rev=109105&r1=109104&r2=109105&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/AnalysisContext.h (original)
+++ cfe/trunk/include/clang/Analysis/AnalysisContext.h Thu Jul 22 08:52:13 2010
@@ -42,7 +42,7 @@
   const Decl *D;
 
   // TranslationUnit is NULL if we don't have multiple translation units.
-  const idx::TranslationUnit *TU;
+  idx::TranslationUnit *TU;
 
   // AnalysisContext owns the following data.
   CFG *cfg;
@@ -53,7 +53,7 @@
   llvm::BumpPtrAllocator A;
   bool AddEHEdges;
 public:
-  AnalysisContext(const Decl *d, const idx::TranslationUnit *tu,
+  AnalysisContext(const Decl *d, idx::TranslationUnit *tu,
                   bool addehedges = false)
     : D(d), TU(tu), cfg(0), builtCFG(false), liveness(0), PM(0),
       ReferencedBlockVars(0), AddEHEdges(addehedges) {}
@@ -63,7 +63,7 @@
   ASTContext &getASTContext() { return D->getASTContext(); }
   const Decl *getDecl() const { return D; }
 
-  const idx::TranslationUnit *getTranslationUnit() const { return TU; }
+  idx::TranslationUnit *getTranslationUnit() const { return TU; }
 
   /// getAddEHEdges - Return true iff we are adding exceptional edges from
   /// callExprs.  If this is false, then try/catch statements and blocks
@@ -91,7 +91,7 @@
 public:
   ~AnalysisContextManager();
 
-  AnalysisContext *getContext(const Decl *D,const idx::TranslationUnit *TU = 0);
+  AnalysisContext *getContext(const Decl *D, idx::TranslationUnit *TU = 0);
 
   // Discard all previously created AnalysisContexts.
   void clear();
@@ -121,7 +121,7 @@
 
   AnalysisContext *getAnalysisContext() const { return Ctx; }
 
-  const idx::TranslationUnit *getTranslationUnit() const { 
+  idx::TranslationUnit *getTranslationUnit() const { 
     return Ctx->getTranslationUnit(); 
   }
 

Modified: cfe/trunk/include/clang/Checker/PathSensitive/AnalysisManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/PathSensitive/AnalysisManager.h?rev=109105&r1=109104&r2=109105&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/PathSensitive/AnalysisManager.h (original)
+++ cfe/trunk/include/clang/Checker/PathSensitive/AnalysisManager.h Thu Jul 22 08:52:13 2010
@@ -99,6 +99,8 @@
     return CreateConstraintMgr;
   }
 
+  idx::Indexer *getIndexer() const { return Idxer; }
+
   virtual ASTContext &getASTContext() {
     return Ctx;
   }
@@ -160,10 +162,14 @@
     return AnaCtxMgr.getContext(D)->getParentMap();
   }
 
-  const AnalysisContext *getAnalysisContext(const Decl *D) {
+  AnalysisContext *getAnalysisContext(const Decl *D) {
     return AnaCtxMgr.getContext(D);
   }
 
+  AnalysisContext *getAnalysisContext(const Decl *D, idx::TranslationUnit *TU) {
+    return AnaCtxMgr.getContext(D, TU);
+  }
+
   const StackFrameContext *getStackFrame(AnalysisContext *Ctx,
                                          LocationContext const *Parent,
                                          Stmt const *S, const CFGBlock *Blk,
@@ -173,7 +179,7 @@
 
   // Get the top level stack frame.
   const StackFrameContext *getStackFrame(Decl const *D, 
-                                         const idx::TranslationUnit *TU) {
+                                         idx::TranslationUnit *TU) {
     return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D, TU), 0, 0, 0, 0);
   }
 

Modified: cfe/trunk/include/clang/Checker/PathSensitive/GRCoreEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/PathSensitive/GRCoreEngine.h?rev=109105&r1=109104&r2=109105&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/PathSensitive/GRCoreEngine.h (original)
+++ cfe/trunk/include/clang/Checker/PathSensitive/GRCoreEngine.h Thu Jul 22 08:52:13 2010
@@ -153,7 +153,11 @@
 
   /// ExecuteWorkList - Run the worklist algorithm for a maximum number of
   ///  steps.  Returns true if there is still simulation state on the worklist.
-  bool ExecuteWorkList(const LocationContext *L, unsigned Steps);
+  bool ExecuteWorkList(const LocationContext *L, unsigned Steps,
+                       const GRState *InitState);
+  void ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps,
+                                       const GRState *InitState, 
+                                       ExplodedNodeSet &Dst);
 };
 
 class GRStmtNodeBuilder {

Modified: cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h?rev=109105&r1=109104&r2=109105&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h Thu Jul 22 08:52:13 2010
@@ -114,13 +114,22 @@
   ~GRExprEngine();
 
   void ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
-    CoreEngine.ExecuteWorkList(L, Steps);
+    CoreEngine.ExecuteWorkList(L, Steps, 0);
+  }
+
+  /// Execute the work list with an initial state. Nodes that reaches the exit
+  /// of the function are added into the Dst set, which represent the exit
+  /// state of the function call.
+  void ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps,
+                                       const GRState *InitState, 
+                                       ExplodedNodeSet &Dst) {
+    CoreEngine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst);
   }
 
   /// getContext - Return the ASTContext associated with this analysis.
   ASTContext& getContext() const { return AMgr.getASTContext(); }
 
-  AnalysisManager &getAnalysisManager() const { return AMgr; }
+  virtual AnalysisManager &getAnalysisManager() { return AMgr; }
 
   SValuator &getSValuator() { return SVator; }
 
@@ -204,8 +213,7 @@
   ///  making assumptions about state values.
   const GRState *ProcessAssume(const GRState *state, SVal cond,bool assumption);
 
-  GRStateManager& getStateManager() { return StateMgr; }
-  const GRStateManager& getStateManager() const { return StateMgr; }
+  virtual GRStateManager& getStateManager() { return StateMgr; }
 
   StoreManager& getStoreManager() { return StateMgr.getStoreManager(); }
 

Modified: cfe/trunk/include/clang/Checker/PathSensitive/GRState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/PathSensitive/GRState.h?rev=109105&r1=109104&r2=109105&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/PathSensitive/GRState.h (original)
+++ cfe/trunk/include/clang/Checker/PathSensitive/GRState.h Thu Jul 22 08:52:13 2010
@@ -452,6 +452,10 @@
                                     const StackFrameContext *LCtx,
                                     SymbolReaper& SymReaper);
 
+  /// Marshal a new state for the callee in another translation unit.
+  /// 'state' is owned by the caller's engine.
+  const GRState *MarshalState(const GRState *state, const LocationContext *L);
+
 public:
 
   SVal ArrayToPointer(Loc Array) {

Modified: cfe/trunk/include/clang/Checker/PathSensitive/GRSubEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/PathSensitive/GRSubEngine.h?rev=109105&r1=109104&r2=109105&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/PathSensitive/GRSubEngine.h (original)
+++ cfe/trunk/include/clang/Checker/PathSensitive/GRSubEngine.h Thu Jul 22 08:52:13 2010
@@ -39,7 +39,9 @@
 
   virtual const GRState* getInitialState(const LocationContext *InitLoc) = 0;
 
-  virtual GRStateManager& getStateManager() = 0;
+  virtual AnalysisManager &getAnalysisManager() = 0;
+
+  virtual GRStateManager &getStateManager() = 0;
 
   /// Called by GRCoreEngine. Used to generate new successor
   /// nodes by processing the 'effects' of a block-level statement.

Modified: cfe/trunk/include/clang/Index/TranslationUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Index/TranslationUnit.h?rev=109105&r1=109104&r2=109105&view=diff
==============================================================================
--- cfe/trunk/include/clang/Index/TranslationUnit.h (original)
+++ cfe/trunk/include/clang/Index/TranslationUnit.h Thu Jul 22 08:52:13 2010
@@ -16,6 +16,7 @@
 
 namespace clang {
   class ASTContext;
+  class Diagnostic;
   class Preprocessor;
 
 namespace idx {
@@ -28,6 +29,7 @@
   virtual ~TranslationUnit();
   virtual ASTContext &getASTContext() = 0;
   virtual Preprocessor &getPreprocessor() = 0;
+  virtual Diagnostic &getDiagnostic() = 0;
   virtual DeclReferenceMap &getDeclReferenceMap() = 0;
   virtual SelectorMap &getSelectorMap() = 0;
 };

Modified: cfe/trunk/lib/Analysis/AnalysisContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/AnalysisContext.cpp?rev=109105&r1=109104&r2=109105&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/AnalysisContext.cpp (original)
+++ cfe/trunk/lib/Analysis/AnalysisContext.cpp Thu Jul 22 08:52:13 2010
@@ -84,7 +84,7 @@
 }
 
 AnalysisContext *AnalysisContextManager::getContext(const Decl *D,
-                                               const idx::TranslationUnit *TU) {
+                                                    idx::TranslationUnit *TU) {
   AnalysisContext *&AC = Contexts[D];
   if (!AC)
     AC = new AnalysisContext(D, TU);

Modified: cfe/trunk/lib/Checker/GRCoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/GRCoreEngine.cpp?rev=109105&r1=109104&r2=109105&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/GRCoreEngine.cpp (original)
+++ cfe/trunk/lib/Checker/GRCoreEngine.cpp Thu Jul 22 08:52:13 2010
@@ -12,8 +12,10 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/Checker/PathSensitive/AnalysisManager.h"
 #include "clang/Checker/PathSensitive/GRCoreEngine.h"
 #include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/Index/TranslationUnit.h"
 #include "clang/AST/Expr.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/ADT/DenseMap.h"
@@ -24,6 +26,12 @@
 using llvm::isa;
 using namespace clang;
 
+// This should be removed in the future.
+namespace clang {
+GRTransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
+                                  const LangOptions& lopts);
+}
+
 //===----------------------------------------------------------------------===//
 // Worklist classes for exploration of reachable states.
 //===----------------------------------------------------------------------===//
@@ -120,7 +128,8 @@
 //===----------------------------------------------------------------------===//
 
 /// ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.
-bool GRCoreEngine::ExecuteWorkList(const LocationContext *L, unsigned Steps) {
+bool GRCoreEngine::ExecuteWorkList(const LocationContext *L, unsigned Steps,
+                                   const GRState *InitState) {
 
   if (G->num_roots() == 0) { // Initialize the analysis by constructing
     // the root if none exists.
@@ -143,8 +152,11 @@
     // Set the current block counter to being empty.
     WList->setBlockCounter(BCounterFactory.GetEmptyCounter());
 
-    // Generate the root.
-    GenerateNode(StartLoc, getInitialState(L), 0);
+    if (!InitState)
+      // Generate the root.
+      GenerateNode(StartLoc, getInitialState(L), 0);
+    else
+      GenerateNode(StartLoc, InitState, 0);
   }
 
   while (Steps && WList->hasWork()) {
@@ -192,6 +204,17 @@
   return WList->hasWork();
 }
 
+void GRCoreEngine::ExecuteWorkListWithInitialState(const LocationContext *L, 
+                                                   unsigned Steps,
+                                                   const GRState *InitState, 
+                                                   ExplodedNodeSet &Dst) {
+  ExecuteWorkList(L, Steps, InitState);
+  for (llvm::SmallVectorImpl<ExplodedNode*>::iterator I = G->EndNodes.begin(), 
+                                           E = G->EndNodes.end(); I != E; ++I) {
+    Dst.Add(*I);
+  }
+}
+
 void GRCoreEngine::HandleCallEnter(const CallEnter &L, const CFGBlock *Block,
                                    unsigned Index, ExplodedNode *Pred) {
   GRCallEnterNodeBuilder Builder(*this, Pred, L.getCallExpr(), 
@@ -662,7 +685,53 @@
   // Check if the callee is in the same translation unit.
   if (CalleeCtx->getTranslationUnit() != 
       Pred->getLocationContext()->getTranslationUnit()) {
-    assert(0 && "to be implemented");
+    // 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.SubEngine.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 PCH files.
+    AnalysisManager AMgr(TU->getASTContext(), TU->getDiagnostic(), 
+                         OldMgr.getLangOptions(), 
+                         OldMgr.getPathDiagnosticClient(),
+                         OldMgr.getStoreManagerCreator(),
+                         OldMgr.getConstraintManagerCreator(),
+                         OldMgr.getIndexer(),
+                         OldMgr.getMaxNodes(), OldMgr.getMaxLoop(),
+                         OldMgr.shouldVisualizeGraphviz(),
+                         OldMgr.shouldVisualizeUbigraph(),
+                         OldMgr.shouldPurgeDead(),
+                         OldMgr.shouldEagerlyAssume(),
+                         OldMgr.shouldTrimGraph(),
+                         OldMgr.shouldInlineCall());
+    llvm::OwningPtr<GRTransferFuncs> TF(MakeCFRefCountTF(AMgr.getASTContext(),
+                                                         /* GCEnabled */ false,
+                                                        AMgr.getLangOptions()));
+    // Create the new engine.
+    GRExprEngine NewEng(AMgr, TF.take());
+
+    // Create the new LocationContext.
+    AnalysisContext *NewAnaCtx = AMgr.getAnalysisContext(CalleeCtx->getDecl(), 
+                                               CalleeCtx->getTranslationUnit());
+    const StackFrameContext *OldLocCtx = cast<StackFrameContext>(LocCtx);
+    const StackFrameContext *NewLocCtx = AMgr.getStackFrame(NewAnaCtx, 
+                                               OldLocCtx->getParent(),
+                                               OldLocCtx->getCallSite(),
+                                               OldLocCtx->getCallSiteBlock(), 
+                                               OldLocCtx->getIndex());
+
+    // Now create an initial state for the new engine.
+    const GRState *NewState = NewEng.getStateManager().MarshalState(state,
+                                                                    NewLocCtx);
+    ExplodedNodeSet ReturnNodes;
+    NewEng.ExecuteWorkListWithInitialState(NewLocCtx, AMgr.getMaxNodes(), 
+                                           NewState, ReturnNodes);
+    return;
   }
 
   // Get the callee entry block.

Modified: cfe/trunk/lib/Checker/GRState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/GRState.cpp?rev=109105&r1=109104&r2=109105&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/GRState.cpp (original)
+++ cfe/trunk/lib/Checker/GRState.cpp Thu Jul 22 08:52:13 2010
@@ -57,6 +57,17 @@
   return ConstraintMgr->RemoveDeadBindings(s, SymReaper);
 }
 
+const GRState *GRStateManager::MarshalState(const GRState *state,
+                                            const LocationContext *InitLoc) {
+  // make up an empty state for now.
+  GRState State(this,
+                EnvMgr.getInitialEnvironment(),
+                StoreMgr->getInitialStore(InitLoc),
+                GDMFactory.GetEmptyMap());
+
+  return getPersistentState(State);
+}
+
 const GRState *GRState::unbindLoc(Loc LV) const {
   Store OldStore = getStore();
   Store NewStore = getStateManager().StoreMgr->Remove(OldStore, LV);





More information about the cfe-commits mailing list