Add logic for invalidating array region to CFRefCount.cpp. When invalidating
array region, set its default value to conjured symbol. When retrieving its
element, create new region value symbol for the element.

Also fix some 80 columns violations.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71548 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 5120d4f..dc9602a 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -1721,7 +1721,7 @@
 
   void ProcessNonLeakError(ExplodedNodeSet<GRState>& Dst,
                            GRStmtNodeBuilder<GRState>& Builder,
-                           Expr* NodeExpr, Expr* ErrorExpr,                        
+                           Expr* NodeExpr, Expr* ErrorExpr,
                            ExplodedNode<GRState>* Pred,
                            const GRState* St,
                            RefVal::Kind hasErr, SymbolRef Sym);
@@ -1767,7 +1767,7 @@
                    Expr* Ex,
                    Expr* Receiver,
                    const RetainSummary& Summ,
-                   ExprIterator arg_beg, ExprIterator arg_end,                             
+                   ExprIterator arg_beg, ExprIterator arg_end,
                    ExplodedNode<GRState>* Pred);
     
   virtual void EvalCall(ExplodedNodeSet<GRState>& Dst,
@@ -1995,7 +1995,7 @@
 
     CFRefReport(CFRefBug& D, const CFRefCount &tf,
                 ExplodedNode<GRState> *n, SymbolRef sym, const char* endText)
-      : RangedBugReport(D, D.getDescription(), endText, n), Sym(sym), TF(tf) {}    
+      : RangedBugReport(D, D.getDescription(), endText, n), Sym(sym), TF(tf) {}
     
     virtual ~CFRefReport() {}
     
@@ -2302,7 +2302,7 @@
             if (PrevV.getAutoreleaseCount() == CurrV.getAutoreleaseCount())
               return 0;
             
-            assert(PrevV.getAutoreleaseCount() < CurrV.getAutoreleaseCount());            
+            assert(PrevV.getAutoreleaseCount() < CurrV.getAutoreleaseCount());
             os << "Object sent -autorelease message";
             break;
           }
@@ -2623,8 +2623,10 @@
                              ExplodedNode<GRState>* Pred) {
   
   // Get the state.
-  GRStateRef state(Builder.GetState(Pred), Eng.getStateManager());
-  ASTContext& Ctx = Eng.getStateManager().getContext();
+  GRStateManager& StateMgr = Eng.getStateManager();
+  GRStateRef state(Builder.GetState(Pred), StateMgr);
+  ASTContext& Ctx = StateMgr.getContext();
+  ValueManager &ValMgr = Eng.getValueManager();
 
   // Evaluate the effect of the arguments.
   RefVal::Kind hasErr = (RefVal::Kind) 0;
@@ -2680,7 +2682,7 @@
             // with an interface to StoreManager so that this logic can be
             // approriately delegated to the respective StoreManagers while
             // still allowing us to do checker-specific logic (e.g.,
-            // invalidating reference counts), probably via callbacks.            
+            // invalidating reference counts), probably via callbacks.
             if (ER->getElementType()->isIntegralType()) {
               const MemRegion *superReg = ER->getSuperRegion();
               if (isa<VarRegion>(superReg) || isa<FieldRegion>(superReg) ||
@@ -2730,15 +2732,21 @@
                 QualType FT = FD->getType();
                 
                 if (Loc::IsLocType(FT) || 
-                    (FT->isIntegerType() && FT->isScalarType())) {                  
+                    (FT->isIntegerType() && FT->isScalarType())) {
                   const FieldRegion* FR = MRMgr.getFieldRegion(FD, R);
-                  ValueManager &ValMgr = Eng.getValueManager();
+
                   SVal V = ValMgr.getConjuredSymbolVal(*I, FT, Count);
                   state = state.BindLoc(Loc::MakeVal(FR), V);
                 }                
               }
-            }
-            else {
+            } else if (const ArrayType *AT = Ctx.getAsArrayType(T)) {
+              // Set the default value of the array to conjured symbol.
+              StoreManager& StoreMgr = Eng.getStateManager().getStoreManager();
+              SVal V = ValMgr.getConjuredSymbolVal(*I, AT->getElementType(),
+                                                   Count);
+              state = GRStateRef(StoreMgr.setDefaultValue(state, R, V), 
+                                 StateMgr);
+            } else {
               // Just blast away other values.
               state = state.BindLoc(*MR, UnknownVal());
             }
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index 9d29a90..440080d 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -276,7 +276,7 @@
   void iterBindings(Store store, BindingsHandler& f) {
     // FIXME: Implement.
   }
-
+  const GRState* setDefaultValue(const GRState* St, const MemRegion* R, SVal V);
 private:
   const GRState* BindArray(const GRState* St, const TypedRegion* R, SVal V);
 
@@ -759,8 +759,13 @@
     const MemRegion* SuperR = cast<SubRegion>(R)->getSuperRegion();
     GRStateTrait<RegionDefaultValue>::lookup_type D = 
       state.get<RegionDefaultValue>(SuperR);
-    if (D)
-      return *D;
+    if (D) {
+      // If the default value is symbolic, we need to create a new symbol.
+      if (D->hasConjuredSymbol())
+        return ValMgr.getRegionValueSymbolVal(R);
+      else
+        return *D;
+    }
   }
   
   if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R)) {
@@ -1274,3 +1279,9 @@
   GRStateRef state(St, StateMgr);
   return state.set<RegionCasts>(R, T);
 }
+
+const GRState* RegionStoreManager::setDefaultValue(const GRState* St,
+                                                   const MemRegion* R, SVal V) {
+  GRStateRef state(St, StateMgr);
+  return state.set<RegionDefaultValue>(R, V);
+}
diff --git a/lib/Analysis/SVals.cpp b/lib/Analysis/SVals.cpp
index e10ea89..e19b168 100644
--- a/lib/Analysis/SVals.cpp
+++ b/lib/Analysis/SVals.cpp
@@ -30,6 +30,31 @@
 // Utility methods.
 //===----------------------------------------------------------------------===//
 
+bool SVal::hasConjuredSymbol() const {
+  if (const nonloc::SymbolVal* SV = dyn_cast<nonloc::SymbolVal>(this)) {
+    SymbolRef sym = SV->getSymbol();
+    if (isa<SymbolConjured>(sym))
+      return true;
+  }
+
+  if (const loc::MemRegionVal *RV = dyn_cast<loc::MemRegionVal>(this)) {
+    const MemRegion *R = RV->getRegion();
+    if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
+      SymbolRef sym = SR->getSymbol();
+      if (isa<SymbolConjured>(sym))
+        return true;
+    } else if (const CodeTextRegion *CTR = dyn_cast<CodeTextRegion>(R)) {
+      if (CTR->isSymbolic()) {
+        SymbolRef sym = CTR->getSymbol();
+        if (isa<SymbolConjured>(sym))
+          return true;
+      }
+    }
+  }
+
+  return false;
+}
+
 const FunctionDecl* SVal::getAsFunctionDecl() const {
   if (const loc::MemRegionVal* X = dyn_cast<loc::MemRegionVal>(this)) {
     const MemRegion* R = X->getRegion();