- constify some uses of MemRegion* (MemRegion should be immutable).
- Added new region "SymbolicRegion", which maps symbol values to the region domain.
- Enhanced BasicStore::getFieldLValue() to return a FieldRegion (using SymbolicRegion)
- Added some utility methods to GRState for fetch svals from the store.
- Fixed regression in CheckNSError (we weren't getting the value bound to the parameter)


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57717 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp
index 7998ef4..e1220ce 100644
--- a/lib/Analysis/BasicStore.cpp
+++ b/lib/Analysis/BasicStore.cpp
@@ -90,7 +90,41 @@
   
 SVal BasicStoreManager::getLValueField(const GRState* St, const FieldDecl* D,
                                        SVal Base) {
-  return UnknownVal();
+
+  if (Base.isUnknownOrUndef())
+    return Base;
+  
+  Loc BaseL = cast<Loc>(Base);  
+  const MemRegion* BaseR = 0;
+  
+  switch(BaseL.getSubKind()) {
+    case loc::SymbolValKind:
+      BaseR = MRMgr.getSymbolicRegion(cast<loc::SymbolVal>(&BaseL)->getSymbol());
+      break;
+      
+    case loc::GotoLabelKind:
+    case loc::FuncValKind:
+      // Technically we can get here if people do funny things with casts.
+      return UndefinedVal();
+
+    case loc::MemRegionKind:
+      BaseR = cast<loc::MemRegionVal>(BaseL).getRegion();
+      break;
+      
+    case loc::ConcreteIntKind:
+    case loc::StringLiteralValKind:
+      // While these seem funny, this can happen through casts.
+      // FIXME: What we should return is the field offset.  For example,
+      //  add the field offset to the integer value.  That way funny things
+      //  like this work properly:  &(((struct foo *) 0xa)->f)
+      return Base;
+
+    default:
+      assert ("Unhandled Base.");
+      return Base;
+  }
+  
+  return loc::MemRegionVal(MRMgr.getFieldRegion(D, BaseR));
 }
 
 SVal BasicStoreManager::getLValueElement(const GRState* St, SVal Base,
@@ -108,7 +142,7 @@
   switch (LV.getSubKind()) {
 
     case loc::MemRegionKind: {
-      VarRegion* R =
+      const VarRegion* R =
         dyn_cast<VarRegion>(cast<loc::MemRegionVal>(LV).getRegion());
       
       if (!R)
@@ -145,7 +179,7 @@
 Store BasicStoreManager::SetSVal(Store store, Loc LV, SVal V) {    
   switch (LV.getSubKind()) {      
     case loc::MemRegionKind: {
-      VarRegion* R =
+      const VarRegion* R =
         dyn_cast<VarRegion>(cast<loc::MemRegionVal>(LV).getRegion());
       
       if (!R)
@@ -165,8 +199,8 @@
 Store BasicStoreManager::Remove(Store store, Loc LV) {
   switch (LV.getSubKind()) {
     case loc::MemRegionKind: {
-      VarRegion* R =
-      dyn_cast<VarRegion>(cast<loc::MemRegionVal>(LV).getRegion());
+      const VarRegion* R =
+        dyn_cast<VarRegion>(cast<loc::MemRegionVal>(LV).getRegion());
       
       if (!R)
         return store;