[cfe-commits] r57285 - in /cfe/trunk: include/clang/Analysis/PathSensitive/MemRegion.h lib/Analysis/MemRegion.cpp lib/Analysis/RegionStore.cpp

Zhongxing Xu xuzhongxing at gmail.com
Tue Oct 7 19:50:46 PDT 2008


Author: zhongxingxu
Date: Tue Oct  7 21:50:44 2008
New Revision: 57285

URL: http://llvm.org/viewvc/llvm-project?rev=57285&view=rev
Log:
This is the first step to implement a field-sensitive store model. Other things are simplified: no heap shape assumption, no parameter alias assumption, etc.

Added:
    cfe/trunk/lib/Analysis/RegionStore.cpp
Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h
    cfe/trunk/lib/Analysis/MemRegion.cpp

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h?rev=57285&r1=57284&r2=57285&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h Tue Oct  7 21:50:44 2008
@@ -37,7 +37,7 @@
               // Typed regions.
               BEG_TYPED_REGIONS,
               VarRegionKind, FieldRegionKind, ObjCIvarRegionKind,
-              AnonTypedRegionKind,
+              AnonTypedRegionKind, AnonPointeeRegionKind,
               END_TYPED_REGIONS };  
 private:
   const Kind kind;
@@ -104,6 +104,7 @@
 /// AnonTypedRegion - An "anonymous" region that simply types a chunk
 ///  of memory.
 class AnonTypedRegion : public TypedRegion {
+protected:
   QualType T;
 
   friend class MemRegionManager;
@@ -112,8 +113,8 @@
     : TypedRegion(sreg, AnonTypedRegionKind), T(t) {}
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType T,
-                      const MemRegion* superRegion);
-  
+                            const MemRegion* superRegion);
+
 public:
   QualType getType() const { return T; }
   
@@ -125,6 +126,28 @@
   }
 };
 
+/// AnonPointeeRegion - anonymous regions pointed-at by pointer function
+///  parameters or pointer globals. In RegionStoreManager, we assume pointer
+///  parameters or globals point at some anonymous region initially. Such
+///  regions are not the regions associated with the pointers themselves, but
+///  are identified with the VarDecl of the parameters or globals.
+class AnonPointeeRegion : public AnonTypedRegion {
+  friend class MemRegionManager;
+  // VD - the pointer variable that points at this region.
+  const VarDecl* VD;
+
+  AnonPointeeRegion(const VarDecl* d, QualType t, MemRegion* sreg)
+    : AnonTypedRegion(t, sreg), VD(d) {}
+
+public:
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl* PVD,
+                            QualType T, const MemRegion* superRegion);
+};
+
+/// AnonHeapRegion - anonymous region created by malloc().
+class AnonHeapRegion : public AnonTypedRegion {
+};
+
 class DeclRegion : public TypedRegion {
 protected:
   const Decl* D;
@@ -213,6 +236,7 @@
   MemSpaceRegion* globals;
   MemSpaceRegion* stack;
   MemSpaceRegion* heap;
+  MemSpaceRegion* unknown;
   
 public:
   MemRegionManager(llvm::BumpPtrAllocator& a)
@@ -231,6 +255,10 @@
   /// getHeapRegion - Retrieve the memory region associated with the
   ///  generic "heap".
   MemSpaceRegion* getHeapRegion();
+
+  /// getUnknownRegion - Retrieve the memory region associated with unknown
+  /// memory space.
+  MemSpaceRegion* getUnknownRegion();
   
   /// getVarRegion - Retrieve or create the memory region associated with
   ///  a specified VarDecl.  'superRegion' corresponds to the containing
@@ -254,7 +282,9 @@
   ///   object).
   ObjCIvarRegion* getObjCIvarRegion(const ObjCIvarDecl* ivd,
                                     MemRegion* superRegion);
-  
+
+  AnonPointeeRegion* getAnonPointeeRegion(const VarDecl* d);
+
   bool hasStackStorage(const MemRegion* R);
   
 private:

Modified: cfe/trunk/lib/Analysis/MemRegion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/MemRegion.cpp?rev=57285&r1=57284&r2=57285&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/MemRegion.cpp (original)
+++ cfe/trunk/lib/Analysis/MemRegion.cpp Tue Oct  7 21:50:44 2008
@@ -32,6 +32,15 @@
   ID.AddPointer(superRegion);
 }
 
+void AnonPointeeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 
+                                      const VarDecl* VD, QualType T,
+                                      const MemRegion* superRegion) {
+  ID.AddInteger((unsigned) AnonPointeeRegionKind);
+  ID.Add(T);
+  ID.AddPointer(VD);
+  ID.AddPointer(superRegion);
+}
+
 void AnonTypedRegion::Profile(llvm::FoldingSetNodeID& ID) const {
   AnonTypedRegion::ProfileRegion(ID, T, superRegion);
 }
@@ -92,6 +101,10 @@
   return LazyAllocate(heap);
 }
 
+MemSpaceRegion* MemRegionManager::getUnknownRegion() {
+  return LazyAllocate(unknown);
+}
+
 VarRegion* MemRegionManager::getVarRegion(const VarDecl* d,
                                           MemRegion* superRegion) {
   llvm::FoldingSetNodeID ID;
@@ -146,6 +159,27 @@
   return R;
 }
 
+AnonPointeeRegion* MemRegionManager::getAnonPointeeRegion(const VarDecl* d) {
+  llvm::FoldingSetNodeID ID;
+  QualType T = d->getType();
+  QualType PointeeType = cast<PointerType>(T.getTypePtr())->getPointeeType();
+  MemRegion* superRegion = getUnknownRegion();
+
+  AnonPointeeRegion::ProfileRegion(ID, d, PointeeType, superRegion);
+
+  void* InsertPos;
+  MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
+  AnonPointeeRegion* R = cast_or_null<AnonPointeeRegion>(data);
+
+  if (!R) {
+    R = (AnonPointeeRegion*) A.Allocate<AnonPointeeRegion>();
+    new (R) AnonPointeeRegion(d, PointeeType, superRegion);
+    Regions.InsertNode(R, InsertPos);
+  }
+
+  return R;
+}
+
 bool MemRegionManager::hasStackStorage(const MemRegion* R) {
   MemSpaceRegion* S = getStackRegion();
   

Added: cfe/trunk/lib/Analysis/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RegionStore.cpp?rev=57285&view=auto

==============================================================================
--- cfe/trunk/lib/Analysis/RegionStore.cpp (added)
+++ cfe/trunk/lib/Analysis/RegionStore.cpp Tue Oct  7 21:50:44 2008
@@ -0,0 +1,96 @@
+//== RegionStore.cpp - Field-sensitive store model --------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a basic region store model. In this model, we do have field
+// sensitivity. But we assume nothing about the heap shape. So recursive data
+// structures are largely ignored. Basically we do 1-limiting analysis.
+// Parameter pointers are assumed with no aliasing. Pointee objects of
+// parameters are created lazily.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Analysis/PathSensitive/MemRegion.h"
+#include "clang/Analysis/PathSensitive/GRState.h"
+#include "clang/Analysis/Analyses/LiveVariables.h"
+
+#include "llvm/ADT/ImmutableMap.h"
+#include "llvm/Support/Compiler.h"
+
+using namespace clang;
+
+typedef llvm::ImmutableMap<const MemRegion*, RVal> RegionBindingsTy;
+
+namespace {
+
+class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager {
+  RegionBindingsTy::Factory RBFactory;
+  GRStateManager& StateMgr;
+  MemRegionManager MRMgr;
+
+public:
+  RegionStoreManager(GRStateManager& mgr) 
+    : StateMgr(mgr), MRMgr(StateMgr.getAllocator()) {}
+
+  virtual ~RegionStoreManager() {}
+
+  Store SetRVal(Store St, LVal LV, RVal V);
+
+  Store getInitialStore();
+
+  static inline RegionBindingsTy GetRegionBindings(Store store) {
+   return RegionBindingsTy(static_cast<const RegionBindingsTy::TreeTy*>(store));
+  }
+};
+
+} // end anonymous namespace
+
+Store RegionStoreManager::SetRVal(Store store, LVal LV, RVal V) {
+  assert(LV.getSubKind() == lval::MemRegionKind);
+
+  MemRegion* R = cast<lval::MemRegionVal>(LV).getRegion();
+  
+  if (!R)
+    return store;
+
+  RegionBindingsTy B = GetRegionBindings(store);
+  return V.isUnknown()
+         ? RBFactory.Remove(B, R).getRoot()
+         : RBFactory.Add(B, R, V).getRoot();
+}
+
+Store RegionStoreManager::getInitialStore() {
+  typedef LiveVariables::AnalysisDataTy LVDataTy;
+  LVDataTy& D = StateMgr.getLiveVariables().getAnalysisData();
+
+  Store St = RBFactory.GetEmptyMap().getRoot();
+
+  for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) {
+    ScopedDecl* SD = const_cast<ScopedDecl*>(I->first);
+
+    if (VarDecl* VD = dyn_cast<VarDecl>(SD)) {
+      // Punt on static variables for now.
+      if (VD->getStorageClass() == VarDecl::Static)
+        continue;
+
+      QualType T = VD->getType();
+      // Only handle pointers and integers for now.
+      if (LVal::IsLValType(T) || T->isIntegerType()) {
+        MemRegion* R = MRMgr.getVarRegion(VD);
+        // Initialize globals and parameters to symbolic values.
+        // Initialize local variables to undefined.
+        RVal X = (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
+                  isa<ImplicitParamDecl>(VD))
+                 ? RVal::GetSymbolValue(StateMgr.getSymbolManager(), VD)
+                 : UndefinedVal();
+
+        St = SetRVal(St, lval::MemRegionVal(R), X);
+      }
+    }
+  }
+  return St;
+}





More information about the cfe-commits mailing list