Index: include/clang/Analysis/PathSensitive/MemRegion.h
===================================================================
--- include/clang/Analysis/PathSensitive/MemRegion.h	（版本 57780）
+++ include/clang/Analysis/PathSensitive/MemRegion.h	（工作副本）
@@ -19,6 +19,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/Analysis/PathSensitive/SymbolManager.h"
+#include "clang/Analysis/PathSensitive/RValues.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/Support/Allocator.h"
@@ -37,7 +38,8 @@
   enum Kind { MemSpaceRegionKind, SymbolicRegionKind,
               // Typed regions.
               BEG_TYPED_REGIONS,
-              VarRegionKind, FieldRegionKind, ObjCIvarRegionKind,
+              VarRegionKind, FieldRegionKind, ElementRegionKind,
+              ObjCIvarRegionKind,
               AnonTypedRegionKind, AnonPointeeRegionKind,
               END_TYPED_REGIONS };  
 private:
@@ -257,7 +259,27 @@
     return R->getKind() == ObjCIvarRegionKind;
   }
 };
-  
+
+class ElementRegion : public SubRegion {
+  friend class MemRegionManager;
+
+  SVal Index;
+
+  ElementRegion(SVal Idx, const MemRegion* sReg)
+    : SubRegion(sReg, ElementRegionKind), Index(Idx) {}
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, SVal Idx, 
+                            const MemRegion* superRegion);
+
+public:
+
+  void Profile(llvm::FoldingSetNodeID& ID) const;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == ElementRegionKind;
+  }
+};
+
 //===----------------------------------------------------------------------===//
 // MemRegionManager - Factory object for creating regions.
 //===----------------------------------------------------------------------===//
@@ -305,7 +327,9 @@
     return getVarRegion(vd, vd->hasLocalStorage() ? getStackRegion() 
                         : getGlobalsRegion());
   }
-  
+
+  ElementRegion* getElementRegion(SVal Idx, const MemRegion* superRegion);
+
   /// getFieldRegion - Retrieve or create the memory region associated with
   ///  a specified FieldDecl.  'superRegion' corresponds to the containing
   ///  memory region (which typically represents the memory representing
Index: lib/Analysis/BasicStore.cpp
===================================================================
--- lib/Analysis/BasicStore.cpp	（版本 57780）
+++ lib/Analysis/BasicStore.cpp	（工作副本）
@@ -42,7 +42,6 @@
 
   virtual MemRegionManager& getRegionManager() { return MRMgr; }
 
-  // FIXME: Investigate what is using this. This method should be removed.
   virtual Loc getLoc(const VarDecl* VD) {
     return loc::MemRegionVal(MRMgr.getVarRegion(VD));
   }
@@ -148,7 +147,15 @@
       
       if (!R)
         return UnknownVal();
-        
+
+      // We let an array variable's rvalue be its lvalue, because we have to
+      // process code like: int a[10]; int (*p)[10]; p = &a; (*p)[3] = 1; The
+      // other benifit is that we can save the special handling of array
+      // variables in VisitDeclRefExpr().
+      if (const VarRegion* VR = dyn_cast<VarRegion>(R))
+        if (VR->getDecl()->getType()->isArrayType())
+          return LV;
+
       VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));      
       VarBindingsTy::data_type* T = B.lookup(R->getDecl());      
       return T ? *T : UnknownVal();
Index: lib/Analysis/RegionStore.cpp
===================================================================
--- lib/Analysis/RegionStore.cpp	（版本 57780）
+++ lib/Analysis/RegionStore.cpp	（工作副本）
@@ -38,10 +38,20 @@
 
   virtual ~RegionStoreManager() {}
 
+  SVal GetSVal(Store S, Loc L, QualType T);
   Store SetSVal(Store St, Loc LV, SVal V);
 
   Store getInitialStore();
 
+  Store AddDecl(Store store, const VarDecl* VD, Expr* Ex, SVal InitVal, 
+                unsigned Count);
+
+  Loc getVarLoc(const VarDecl* VD) {
+    return loc::MemRegionVal(MRMgr.getVarRegion(VD));
+  }
+
+  Loc getElementLoc(const VarDecl* VD, SVal Idx);
+
   static inline RegionBindingsTy GetRegionBindings(Store store) {
    return RegionBindingsTy(static_cast<const RegionBindingsTy::TreeTy*>(store));
   }
@@ -49,6 +59,52 @@
 
 } // end anonymous namespace
 
+Loc RegionStoreManager::getElementLoc(const VarDecl* VD, SVal Idx) {
+  MemRegion* R = MRMgr.getVarRegion(VD);
+  ElementRegion* ER = MRMgr.getElementRegion(Idx, R);
+  return loc::MemRegionVal(ER);
+}
+
+SVal RegionStoreManager::GetSVal(Store S, Loc L, QualType T) {
+  assert(!isa<UnknownVal>(L) && "location unknown");
+  assert(!isa<UndefinedVal>(L) && "location undefined");
+
+  switch (L.getSubKind()) {
+  case loc::MemRegionKind: {
+    const MemRegion* R = cast<loc::MemRegionVal>(L).getRegion();
+    assert(R && "bad region");
+
+    // We let an array variable's rvalue be its lvalue, because we have to
+    // process code like: int a[10]; int (*p)[10]; p = &a; (*p)[3] = 1; The
+    // other benifit is that we can save the special handling of array variables
+    // in VisitDeclRefExpr().
+    if (const VarRegion* VR = dyn_cast<VarRegion>(R))
+      if (VR->getDecl()->getType()->isArrayType())
+        return L;
+
+    RegionBindingsTy B(static_cast<const RegionBindingsTy::TreeTy*>(S));
+    RegionBindingsTy::data_type* V = B.lookup(R);
+    return V ? *V : UnknownVal();
+  }
+
+  case loc::SymbolValKind:
+    return UnknownVal();
+
+  case loc::ConcreteIntKind:
+    return UndefinedVal(); // As in BasicStoreManager.
+
+  case loc::FuncValKind:
+    return L;
+
+  case loc::StringLiteralValKind:
+    return UnknownVal();
+
+  default:
+    assert(false && "Invalid Location");
+    break;
+  }
+}
+
 Store RegionStoreManager::SetSVal(Store store, Loc LV, SVal V) {
   assert(LV.getSubKind() == loc::MemRegionKind);
 
@@ -80,7 +136,6 @@
       QualType T = VD->getType();
       // Only handle pointers and integers for now.
       if (Loc::IsLocType(T) || T->isIntegerType()) {
-        MemRegion* R = MRMgr.getVarRegion(VD);
         // Initialize globals and parameters to symbolic values.
         // Initialize local variables to undefined.
         SVal X = (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
@@ -88,9 +143,73 @@
                  ? SVal::GetSymbolValue(StateMgr.getSymbolManager(), VD)
                  : UndefinedVal();
 
-        St = SetSVal(St, loc::MemRegionVal(R), X);
+        St = SetSVal(St, getVarLoc(VD), X);
       }
     }
   }
   return St;
 }
+
+Store RegionStoreManager::AddDecl(Store store,
+                                  const VarDecl* VD, Expr* Ex,
+                                  SVal InitVal, unsigned Count) {
+  BasicValueFactory& BasicVals = StateMgr.getBasicVals();
+  SymbolManager& SymMgr = StateMgr.getSymbolManager();
+
+  if (VD->hasGlobalStorage()) {
+    // Static global variables should not be visited here.
+    assert(!(VD->getStorageClass() == VarDecl::Static &&
+             VD->isFileVarDecl()));
+    // Process static variables.
+    if (VD->getStorageClass() == VarDecl::Static) {
+      if (!Ex) {
+        // Only handle pointer and integer static variables.
+
+        QualType T = VD->getType();
+
+        if (Loc::IsLocType(T))
+          store = SetSVal(store, getVarLoc(VD),
+                          loc::ConcreteInt(BasicVals.getValue(0, T)));
+
+        else if (T->isIntegerType())
+          store = SetSVal(store, getVarLoc(VD),
+                          loc::ConcreteInt(BasicVals.getValue(0, T)));
+        else
+          assert("ignore other types of variables");
+      } else {
+        store = SetSVal(store, getVarLoc(VD), InitVal);
+      }
+    }
+  } else {
+    // Process local variables.
+
+    QualType T = VD->getType();
+
+    if (Loc::IsLocType(T) || T->isIntegerType()) {
+      SVal V = Ex ? InitVal : UndefinedVal();
+      if (Ex && InitVal.isUnknown()) {
+        // "Conjured" symbols.
+        SymbolID Sym = SymMgr.getConjuredSymbol(Ex, Count);
+        V = Loc::IsLocType(Ex->getType())
+          ? cast<SVal>(loc::SymbolVal(Sym))
+          : cast<SVal>(nonloc::SymbolVal(Sym));
+      }
+      store = SetSVal(store, getVarLoc(VD), V);
+
+    } else if (T->isArrayType()) {
+      // Only handle constant size array.
+      if (ConstantArrayType* CAT=dyn_cast<ConstantArrayType>(T.getTypePtr())) {
+        llvm::APInt Size = CAT->getSize();
+        for (llvm::APInt i = llvm::APInt::getNullValue(Size.getBitWidth());
+             i != Size; ++i) {
+          SVal Idx = nonloc::ConcreteInt(llvm::APSInt(i));
+          store = SetSVal(store, getElementLoc(VD, Idx), UndefinedVal());
+        }
+      }
+    } else if (T->isStructureType()) {
+      // FIXME: Implement struct initialization.
+    }
+  }
+  return store;
+}
+
Index: lib/Analysis/MemRegion.cpp
===================================================================
--- lib/Analysis/MemRegion.cpp	（版本 57780）
+++ lib/Analysis/MemRegion.cpp	（工作副本）
@@ -65,6 +65,16 @@
   SymbolicRegion::ProfileRegion(ID, sym);
 }
 
+void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SVal Idx, 
+                                  const MemRegion* superRegion) {
+  ID.AddInteger(MemRegion::ElementRegionKind);
+  ID.AddPointer(superRegion);
+  Idx.Profile(ID);
+}
+
+void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+  ElementRegion::ProfileRegion(ID, Index, superRegion);
+}
 //===----------------------------------------------------------------------===//
 // Region pretty-printing.
 //===----------------------------------------------------------------------===//
@@ -141,6 +151,24 @@
   return R;
 }
 
+ElementRegion* MemRegionManager::getElementRegion(SVal Idx,
+                                                  const MemRegion* superRegion){
+  llvm::FoldingSetNodeID ID;
+  ElementRegion::ProfileRegion(ID, Idx, superRegion);
+
+  void* InsertPos;
+  MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
+  ElementRegion* R = cast_or_null<ElementRegion>(data);
+
+  if (!R) {
+    R = (ElementRegion*) A.Allocate<ElementRegion>();
+    new (R) ElementRegion(Idx, superRegion);
+    Regions.InsertNode(R, InsertPos);
+  }
+
+  return R;
+}
+
 /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
 SymbolicRegion* MemRegionManager::getSymbolicRegion(const SymbolID sym) {
   
Index: lib/Analysis/GRExprEngine.cpp
===================================================================
--- lib/Analysis/GRExprEngine.cpp	（版本 57780）
+++ lib/Analysis/GRExprEngine.cpp	（工作副本）
@@ -829,17 +829,6 @@
 
     SVal V = StateMgr.GetLValue(St, VD);
 
-    if (VD->getType()->isArrayType()) {
-      // C++ standard says array of type T should be implicitly converted to
-      // pointer to type T in some cases. Currently we don't do this cast in
-      // VisitCast(), because BasicStore is not field sensitive. We shall do
-      // this in a transfer function in the future. We represent both lvalue and
-      // rvalue of array of type T as the corresponding MemRegionVal of it.
-
-      MakeNode(Dst, Ex, Pred, SetSVal(St, Ex, V));
-      return;
-    }
-    
     if (asLValue)
       MakeNode(Dst, Ex, Pred, SetSVal(St, Ex, V));
     else
@@ -1532,11 +1521,6 @@
   
   const VarDecl* VD = dyn_cast<VarDecl>(D);
   
-  // FIXME: Add support for local arrays.
-  if (VD->getType()->isArrayType()) {
-    return;
-  }
-  
   Expr* Ex = const_cast<Expr*>(VD->getInit());
 
   // FIXME: static variables may have an initializer, but the second
