[cfe-commits] r62138 - in /cfe/trunk: lib/Analysis/RegionStore.cpp test/Analysis/array-struct.c

Zhongxing Xu xuzhongxing at gmail.com
Mon Jan 12 17:49:57 PST 2009


Author: zhongxingxu
Date: Mon Jan 12 19:49:57 2009
New Revision: 62138

URL: http://llvm.org/viewvc/llvm-project?rev=62138&view=rev
Log:
Add KillStruct to region store.  
 - put the killed region in the kill set.
 - set its default value to unknown.
 - removes all bindings for its subregions.  

Modified:
    cfe/trunk/lib/Analysis/RegionStore.cpp
    cfe/trunk/test/Analysis/array-struct.c

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

==============================================================================
--- cfe/trunk/lib/Analysis/RegionStore.cpp (original)
+++ cfe/trunk/lib/Analysis/RegionStore.cpp Mon Jan 12 19:49:57 2009
@@ -36,7 +36,7 @@
 //  MemRegions can be layered on top of each other.  This GDM entry tracks
 //  what are the MemRegions that layer a given MemRegion.
 //
-typedef llvm::ImmutableList<const MemRegion*> RegionViews;
+typedef llvm::ImmutableSet<const MemRegion*> RegionViews;
 namespace { class VISIBILITY_HIDDEN RegionViewMap {}; }
 static int RegionViewMapIndex = 0;
 namespace clang {
@@ -68,10 +68,11 @@
 // Region "killsets".
 //===----------------------------------------------------------------------===//
 //
-// RegionStore lazily adds value bindings to regions when the analyzer
-//  handles assignment statements.  Killsets track which default values have
-//  been killed, thus distinguishing between "unknown" values and default
-//  values.
+// RegionStore lazily adds value bindings to regions when the analyzer handles
+//  assignment statements.  Killsets track which default values have been
+//  killed, thus distinguishing between "unknown" values and default
+//  values. Regions are added to killset only when they are assigned "unknown"
+//  directly, otherwise we should have their value in the region bindings.
 //
 namespace { class VISIBILITY_HIDDEN RegionKills {}; }
 static int RegionKillsIndex = 0;
@@ -83,11 +84,11 @@
 }
 
 //===----------------------------------------------------------------------===//
-// Regions with default values of '0'.
+// Regions with default values.
 //===----------------------------------------------------------------------===//
 //
-// This GDM entry tracks what regions have a default value of 0 if they
-// have no bound value and have not been killed.
+// This GDM entry tracks what regions have a default value if they have no bound
+// value and have not been killed.
 //
 namespace { class VISIBILITY_HIDDEN RegionDefaultValue {}; }
 static int RegionDefaultValueIndex = 0;
@@ -234,6 +235,9 @@
 
   const GRState* BindStruct(const GRState* St, const TypedRegion* R, SVal V);
 
+  /// KillStruct - Set the entire struct to unknown. 
+  const GRState* KillStruct(const GRState* St, const TypedRegion* R);
+
   // Utility methods.
   BasicValueFactory& getBasicVals() { return StateMgr.getBasicVals(); }
   ASTContext& getContext() { return StateMgr.getContext(); }
@@ -241,6 +245,8 @@
 
   const GRState* AddRegionView(const GRState* St,
                                const MemRegion* View, const MemRegion* Base);
+  const GRState* RemoveRegionView(const GRState* St,
+                                  const MemRegion* View, const MemRegion* Base);
 };
 
 } // end anonymous namespace
@@ -910,6 +916,9 @@
   RecordDecl* RD = RT->getDecl();
   assert(RD->isDefinition());
 
+  if (V.isUnknown())
+    return KillStruct(St, R);
+
   nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(V);
   nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
   RecordDecl::field_iterator FI = RD->field_begin(), FE = RD->field_end();
@@ -941,6 +950,30 @@
   return St;
 }
 
+const GRState* RegionStoreManager::KillStruct(const GRState* St,
+                                              const TypedRegion* R){
+  GRStateRef state(St, StateMgr);
+
+  // Kill the struct region because it is assigned "unknown".
+  St = state.add<RegionKills>(R);
+  
+  // Set the default value of the struct region to "unknown".
+  St = state.set<RegionDefaultValue>(R, UnknownVal());
+
+  Store store = St->getStore();
+  RegionBindingsTy B = GetRegionBindings(store);
+
+  // Remove all bindings for the subregions of the struct.
+  for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
+    const MemRegion* r = I.getKey();
+    if (const SubRegion* sr = dyn_cast<SubRegion>(r))
+      if (sr->isSubRegionOf(R))
+        store = Remove(store, Loc::MakeVal(sr));
+  }
+
+  return StateMgr.MakeStateWithStore(St, store);
+}
+
 const GRState* RegionStoreManager::AddRegionView(const GRState* St,
                                                  const MemRegion* View,
                                                  const MemRegion* Base) {
@@ -948,11 +981,30 @@
 
   // First, retrieve the region view of the base region.
   const RegionViews* d = state.get<RegionViewMap>(Base);
-  RegionViews L = d ? *d : RVFactory.GetEmptyList();
+  RegionViews L = d ? *d : RVFactory.GetEmptySet();
 
   // Now add View to the region view.
-  L = RVFactory.Add(View, L);
+  L = RVFactory.Add(L, View);
 
   // Create a new state with the new region view.
   return state.set<RegionViewMap>(Base, L);
 }
+
+const GRState* RegionStoreManager::RemoveRegionView(const GRState* St,
+                                                    const MemRegion* View,
+                                                    const MemRegion* Base) {
+  GRStateRef state(St, StateMgr);
+
+  // Retrieve the region view of the base region.
+  const RegionViews* d = state.get<RegionViewMap>(Base);
+
+  // If the base region has no view, return.
+  if (!d)
+    return St;
+
+  // Remove the view.
+  RegionViews V = *d;
+  V = RVFactory.Remove(V, View);
+
+  return state.set<RegionViewMap>(Base, V);
+}

Modified: cfe/trunk/test/Analysis/array-struct.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/array-struct.c?rev=62138&r1=62137&r2=62138&view=diff

==============================================================================
--- cfe/trunk/test/Analysis/array-struct.c (original)
+++ cfe/trunk/test/Analysis/array-struct.c Mon Jan 12 19:49:57 2009
@@ -46,6 +46,7 @@
 }
 
 // Struct variable in lvalue context.
+// Assign UnknownVal to the whole struct.
 void f5() {
   struct s data;
   g1(&data);





More information about the cfe-commits mailing list