Ping.

Attached is an updated patch, please review if you have a chance.

Sorry for delaying on this one...Anna's away for the next week, and this is a 
pretty significant change, so I don't think we should move too quickly on it. 
I'll put together some comments later this week if I get the chance.

As usual, thanks for working on all this!
Jordan


On Apr 25, 2013, at 10:04 , Anton Yartsev <[email protected]> wrote:

Hi Jordan, hi Anna, hi all

The patch is motivated by our discussions about CStringChecker and invalidation.

The patch allows to associate a processing behavior with a particular region or 
symbol.
With this things like preserving contents of regions (either hi- or low-level 
ones) or processing of the only top-level region can be implemented easily 
without passing extra parameters around. The patch also reduces the number of 
existing parameters and uniforms the processing.
The CausesPointerEscape could also be implemented in this way, need exploration.

The patch causes no regression.

Please review.

--
Anton

<RegionAndSymHandlingTraits_v1.patch>

--
Anton

Index: include/clang/StaticAnalyzer/Core/Checker.h
===================================================================
--- include/clang/StaticAnalyzer/Core/Checker.h	(revision 182426)
+++ include/clang/StaticAnalyzer/Core/Checker.h	(working copy)
@@ -320,18 +320,33 @@
 class PointerEscape {
   template <typename CHECKER>
   static ProgramStateRef
-  _checkPointerEscape(void *checker,
+  _checkPointerEscape(void *Checker,
                      ProgramStateRef State,
                      const InvalidatedSymbols &Escaped,
                      const CallEvent *Call,
                      PointerEscapeKind Kind,
-                    bool IsConst) {
-    if (!IsConst)
-      return ((const CHECKER *)checker)->checkPointerEscape(State,
+                     RegionAndSymHandlingTraits *HTraits) {
+
+    if (!HTraits)
+      return ((const CHECKER *)Checker)->checkPointerEscape(State,
                                                             Escaped,
                                                             Call,
                                                             Kind);
-    return State;
+
+    InvalidatedSymbols RegularEscape;
+    for (InvalidatedSymbols::const_iterator I = Escaped.begin(), 
+                                            E = Escaped.end(); I != E; ++I)
+      if (!HTraits->hasTrait(*I,
+              RegionAndSymHandlingTraits::TK_PreserveContents))
+        RegularEscape.insert(*I);
+
+    if (RegularEscape.empty())
+      return State;
+
+    return ((const CHECKER *)Checker)->checkPointerEscape(State,
+                                                          RegularEscape,
+                                                          Call,
+                                                          Kind);
   }
 
 public:
@@ -346,18 +361,30 @@
 class ConstPointerEscape {
   template <typename CHECKER>
   static ProgramStateRef
-  _checkConstPointerEscape(void *checker,
+  _checkConstPointerEscape(void *Checker,
                       ProgramStateRef State,
                       const InvalidatedSymbols &Escaped,
                       const CallEvent *Call,
                       PointerEscapeKind Kind,
-                      bool IsConst) {
-    if (IsConst)
-      return ((const CHECKER *)checker)->checkConstPointerEscape(State,
-                                                                 Escaped,
-                                                                 Call,
-                                                                 Kind);
-    return State;
+                      RegionAndSymHandlingTraits *HTraits) {
+
+    if (!HTraits)
+      return State;
+
+    InvalidatedSymbols ConstEscape;
+    for (InvalidatedSymbols::const_iterator I = Escaped.begin(), 
+                                            E = Escaped.end(); I != E; ++I)
+      if (HTraits->hasTrait(*I,
+              RegionAndSymHandlingTraits::TK_PreserveContents))
+        ConstEscape.insert(*I);
+
+    if (ConstEscape.empty())
+      return State;
+
+    return ((const CHECKER *)Checker)->checkConstPointerEscape(State,
+                                                               ConstEscape,
+                                                               Call,
+                                                               Kind);
   }
 
 public:
Index: include/clang/StaticAnalyzer/Core/CheckerManager.h
===================================================================
--- include/clang/StaticAnalyzer/Core/CheckerManager.h	(revision 182426)
+++ include/clang/StaticAnalyzer/Core/CheckerManager.h	(working copy)
@@ -366,14 +366,16 @@
   /// \param Escaped The list of escaped symbols.
   /// \param Call The corresponding CallEvent, if the symbols escape as 
   ///        parameters to the given call.
-  /// \param IsConst Specifies if the pointer is const.
+  /// \param Kind The reason of pointer escape.
+  /// \param HTraits Information about special handling for a particular 
+  ///        region/symbol.
   /// \returns Checkers can modify the state by returning a new one.
   ProgramStateRef 
   runCheckersForPointerEscape(ProgramStateRef State,
                               const InvalidatedSymbols &Escaped,
                               const CallEvent *Call,
                               PointerEscapeKind Kind,
-                              bool IsConst = false);
+                              RegionAndSymHandlingTraits *HTraits = NULL);
 
   /// \brief Run checkers for handling assumptions on symbolic values.
   ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
@@ -465,7 +467,7 @@
                                      const InvalidatedSymbols &Escaped,
                                      const CallEvent *Call,
                                      PointerEscapeKind Kind,
-                                     bool IsConst)>
+                                     RegionAndSymHandlingTraits *HTraits)>
       CheckPointerEscapeFunc;
   
   typedef CheckerFn<ProgramStateRef (ProgramStateRef,
Index: include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
===================================================================
--- include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h	(revision 182426)
+++ include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h	(working copy)
@@ -476,14 +476,13 @@
                                               SVal Loc, SVal Val);
   /// Call PointerEscape callback when a value escapes as a result of
   /// region invalidation.
-  /// \param[in] IsConst Specifies that the pointer is const.
   ProgramStateRef notifyCheckersOfPointerEscape(
                             ProgramStateRef State,
                             const InvalidatedSymbols *Invalidated,
                             ArrayRef<const MemRegion *> ExplicitRegions,
                             ArrayRef<const MemRegion *> Regions,
                             const CallEvent *Call,
-                            bool IsConst);
+                            RegionAndSymHandlingTraits &HTraits);
 
 public:
   // FIXME: 'tag' should be removed, and a LocationContext should be used
Index: include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
===================================================================
--- include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h	(revision 182426)
+++ include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h	(working copy)
@@ -1304,6 +1304,64 @@
 inline ASTContext &MemRegion::getContext() const {
   return getMemRegionManager()->getContext();
 }
+
+//===----------------------------------------------------------------------===//
+// Means for storing region/symbol handling traits.
+//===----------------------------------------------------------------------===//
+
+/// Information about special handling for a particular region/symbol.
+class RegionAndSymHandlingTraits {
+  typedef unsigned char StorageTypeForKinds;
+  llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap;
+  llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap;
+
+  typedef llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator
+      MRTraitsMapConstItTy;
+  typedef llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator
+      SymTraitsMapConstItTy;
+
+public:
+  enum TraitKinds {
+    TK_PreserveContents = 0x1,
+    TK_DoNotInvalidateIndirections = 0x2
+    // Do not forget to extend StorageTypeForKinds if number of traits exceed 
+    // the number of bits StorageTypeForKinds can store.
+  };
+
+  void setTrait(SymbolRef Sym, TraitKinds TK) {
+    SymTraitsMap[Sym] |= TK;
+  }
+
+  void setTrait(const MemRegion *MR, TraitKinds TK) {
+    assert(MR);
+    if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
+      setTrait(SR->getSymbol(), TK);
+    else
+      MRTraitsMap[MR] |= TK;
+  }
+
+  bool hasTrait(SymbolRef Sym, TraitKinds TK) {
+    SymTraitsMapConstItTy I = SymTraitsMap.find(Sym);
+    if (I != SymTraitsMap.end())
+      return I->second & TK;
+
+    return false;    
+  }
+
+  bool hasTrait(const MemRegion *MR, TraitKinds TK) {
+    if (!MR)
+      return false;
+
+    if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
+      return hasTrait(SR->getSymbol(), TK);
+
+    MRTraitsMapConstItTy I = MRTraitsMap.find(MR);
+    if (I != MRTraitsMap.end())
+      return I->second & TK;
+
+    return false;
+  }
+};
   
 } // end GR namespace
 
Index: include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
===================================================================
--- include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h	(revision 182426)
+++ include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h	(working copy)
@@ -232,22 +232,21 @@
   /// \param IS the set of invalidated symbols.
   /// \param Call if non-null, the invalidated regions represent parameters to
   ///        the call and should be considered directly invalidated.
-  /// \param ConstRegions the set of regions whose contents are accessible,
-  ///        even though the regions themselves should not be invalidated.
+  /// \param HTraits information about special handling for a particular 
+  ///        region/symbol.
   ProgramStateRef
   invalidateRegions(ArrayRef<const MemRegion *> Regions, const Expr *E,
                     unsigned BlockCount, const LocationContext *LCtx,
                     bool CausesPointerEscape, InvalidatedSymbols *IS = 0,
                     const CallEvent *Call = 0,
-                    ArrayRef<const MemRegion *> ConstRegions =
-                      ArrayRef<const MemRegion *>()) const;
+                    RegionAndSymHandlingTraits *HTraits = 0) const;
 
   ProgramStateRef
   invalidateRegions(ArrayRef<SVal> Regions, const Expr *E,
                     unsigned BlockCount, const LocationContext *LCtx,
                     bool CausesPointerEscape, InvalidatedSymbols *IS = 0,
                     const CallEvent *Call = 0,
-                    ArrayRef<SVal> ConstRegions = ArrayRef<SVal>()) const;
+                    RegionAndSymHandlingTraits *HTraits = 0) const;
 
   /// enterStackFrame - Returns the state for entry to the given stack frame,
   ///  preserving the current state.
@@ -425,9 +424,9 @@
                         const Expr *E, unsigned BlockCount,
                         const LocationContext *LCtx,
                         bool ResultsInSymbolEscape,
-                        InvalidatedSymbols &IS,
-                        const CallEvent *Call,
-                        ArrayRef<SVal> ConstValues) const;
+                        InvalidatedSymbols *IS,
+                        RegionAndSymHandlingTraits *HTraits,
+                        const CallEvent *Call) const;
 };
 
 //===----------------------------------------------------------------------===//
Index: include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
===================================================================
--- include/clang/StaticAnalyzer/Core/PathSensitive/Store.h	(revision 182426)
+++ include/clang/StaticAnalyzer/Core/PathSensitive/Store.h	(working copy)
@@ -164,8 +164,6 @@
   ///  the given regions. Optionally, invalidates non-static globals as well.
   /// \param[in] store The initial store
   /// \param[in] Values The values to invalidate.
-  /// \param[in] ConstValues The values to invalidate; these are known to be
-  ///   const, so only regions accesible from them should be invalidated.
   /// \param[in] E The current statement being evaluated. Used to conjure
   ///   symbols to mark the values of invalidated regions.
   /// \param[in] Count The current block count. Used to conjure
@@ -174,28 +172,23 @@
   ///   globals should get invalidated.
   /// \param[in,out] IS A set to fill with any symbols that are no longer
   ///   accessible. Pass \c NULL if this information will not be used.
-  /// \param[in,out] ConstIS A set to fill with any symbols corresponding to
-  ///   the ConstValues.
+  /// \param[in] HTraits Information about special handling for a particular 
+  ///   region/symbol.
   /// \param[in,out] InvalidatedTopLevel A vector to fill with regions
-  ////  explicitely being invalidated. Pass \c NULL if this
+  ////  explicitly being invalidated. Pass \c NULL if this
   ///   information will not be used.
-  /// \param[in,out] InvalidatedTopLevelConst A vector to fill with const 
-  ////  regions explicitely being invalidated. Pass \c NULL if this
-  ///   information will not be used.
   /// \param[in,out] Invalidated A vector to fill with any regions being
   ///   invalidated. This should include any regions explicitly invalidated
   ///   even if they do not currently have bindings. Pass \c NULL if this
   ///   information will not be used.
   virtual StoreRef invalidateRegions(Store store,
                                   ArrayRef<SVal> Values,
-                                  ArrayRef<SVal> ConstValues,
                                   const Expr *E, unsigned Count,
                                   const LocationContext *LCtx,
                                   const CallEvent *Call,
                                   InvalidatedSymbols &IS,
-                                  InvalidatedSymbols &ConstIS,
+                                  RegionAndSymHandlingTraits &HTraits,
                                   InvalidatedRegions *InvalidatedTopLevel,
-                                  InvalidatedRegions *InvalidatedTopLevelConst,
                                   InvalidatedRegions *Invalidated) = 0;
 
   /// enterStackFrame - Let the StoreManager to do something when execution
Index: include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
===================================================================
--- include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h	(revision 182426)
+++ include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h	(working copy)
@@ -134,7 +134,7 @@
                            ArrayRef<const MemRegion *> ExplicitRegions,
                            ArrayRef<const MemRegion *> Regions,
                            const CallEvent *Call,
-                           bool IsConst = false) = 0;
+                           RegionAndSymHandlingTraits &HTraits) = 0;
 
   /// printState - Called by ProgramStateManager to print checker-specific data.
   virtual void printState(raw_ostream &Out, ProgramStateRef State,
Index: lib/StaticAnalyzer/Core/CallEvent.cpp
===================================================================
--- lib/StaticAnalyzer/Core/CallEvent.cpp	(revision 182426)
+++ lib/StaticAnalyzer/Core/CallEvent.cpp	(working copy)
@@ -140,8 +140,8 @@
                                              ProgramStateRef Orig) const {
   ProgramStateRef Result = (Orig ? Orig : getState());
 
-  SmallVector<SVal, 8> ConstValues;
   SmallVector<SVal, 8> ValuesToInvalidate;
+  RegionAndSymHandlingTraits HTraits;
 
   getExtraInvalidatedValues(ValuesToInvalidate);
 
@@ -154,9 +154,12 @@
     // Mark this region for invalidation.  We batch invalidate regions
     // below for efficiency.
     if (PreserveArgs.count(Idx))
-      ConstValues.push_back(getArgSVal(Idx));
-    else
-      ValuesToInvalidate.push_back(getArgSVal(Idx));
+      if (const MemRegion *MR = getArgSVal(Idx).getAsRegion())
+        HTraits.setTrait(MR->StripCasts(), 
+                         RegionAndSymHandlingTraits::TK_PreserveContents);
+        // TODO: Factor this out + handle the lower level const pointers.
+
+    ValuesToInvalidate.push_back(getArgSVal(Idx));
   }
 
   // Invalidate designated regions using the batch invalidation API.
@@ -165,7 +168,7 @@
   return Result->invalidateRegions(ValuesToInvalidate, getOriginExpr(),
                                    BlockCount, getLocationContext(),
                                    /*CausedByPointerEscape*/ true,
-                                   /*Symbols=*/0, this, ConstValues);
+                                   /*Symbols=*/0, this, &HTraits);
 }
 
 ProgramPoint CallEvent::getProgramPoint(bool IsPreVisit,
Index: lib/StaticAnalyzer/Core/CheckerManager.cpp
===================================================================
--- lib/StaticAnalyzer/Core/CheckerManager.cpp	(revision 182426)
+++ lib/StaticAnalyzer/Core/CheckerManager.cpp	(working copy)
@@ -490,7 +490,7 @@
                                            const InvalidatedSymbols &Escaped,
                                            const CallEvent *Call,
                                            PointerEscapeKind Kind,
-                                           bool IsConst) {
+                                           RegionAndSymHandlingTraits *HTraits) {
   assert((Call != NULL ||
           (Kind != PSK_DirectEscapeOnCall &&
            Kind != PSK_IndirectEscapeOnCall)) &&
@@ -500,7 +500,7 @@
       //  way), bail out.
       if (!State)
         return NULL;
-      State = PointerEscapeCheckers[i](State, Escaped, Call, Kind, IsConst);
+      State = PointerEscapeCheckers[i](State, Escaped, Call, Kind, HTraits);
     }
   return State;
 }
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngine.cpp	(revision 182426)
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp	(working copy)
@@ -1804,7 +1804,7 @@
     ArrayRef<const MemRegion *> ExplicitRegions,
     ArrayRef<const MemRegion *> Regions,
     const CallEvent *Call,
-    bool IsConst) {
+    RegionAndSymHandlingTraits &HTraits) {
   
   if (!Invalidated || Invalidated->empty())
     return State;
@@ -1814,18 +1814,8 @@
                                                            *Invalidated,
                                                            0,
                                                            PSK_EscapeOther,
-                                                           IsConst);
+                                                           &HTraits);
 
-  // Note: Due to current limitations of RegionStore, we only process the top
-  // level const pointers correctly. The lower level const pointers are
-  // currently treated as non-const.
-  if (IsConst)
-    return getCheckerManager().runCheckersForPointerEscape(State,
-                                                        *Invalidated,
-                                                        Call,
-                                                        PSK_DirectEscapeOnCall,
-                                                        true);
-
   // If the symbols were invalidated by a call, we want to find out which ones 
   // were invalidated directly due to being arguments to the call.
   InvalidatedSymbols SymbolsDirectlyInvalidated;
@@ -1846,12 +1836,12 @@
 
   if (!SymbolsDirectlyInvalidated.empty())
     State = getCheckerManager().runCheckersForPointerEscape(State,
-        SymbolsDirectlyInvalidated, Call, PSK_DirectEscapeOnCall);
+        SymbolsDirectlyInvalidated, Call, PSK_DirectEscapeOnCall, &HTraits);
 
   // Notify about the symbols that get indirectly invalidated by the call.
   if (!SymbolsIndirectlyInvalidated.empty())
     State = getCheckerManager().runCheckersForPointerEscape(State,
-        SymbolsIndirectlyInvalidated, Call, PSK_IndirectEscapeOnCall);
+        SymbolsIndirectlyInvalidated, Call, PSK_IndirectEscapeOnCall, &HTraits);
 
   return State;
 }
Index: lib/StaticAnalyzer/Core/ProgramState.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ProgramState.cpp	(revision 182426)
+++ lib/StaticAnalyzer/Core/ProgramState.cpp	(working copy)
@@ -142,25 +142,14 @@
                                 bool CausedByPointerEscape,
                                 InvalidatedSymbols *IS,
                                 const CallEvent *Call,
-                                RegionList ConstRegions) const {
+                                RegionAndSymHandlingTraits *HTraits) const {
   SmallVector<SVal, 8> Values;
   for (RegionList::const_iterator I = Regions.begin(),
                                   End = Regions.end(); I != End; ++I)
     Values.push_back(loc::MemRegionVal(*I));
 
-  SmallVector<SVal, 8> ConstValues;
-  for (RegionList::const_iterator I = ConstRegions.begin(),
-                                  End = ConstRegions.end(); I != End; ++I)
-    ConstValues.push_back(loc::MemRegionVal(*I));
-
-  if (!IS) {
-    InvalidatedSymbols invalidated;
-    return invalidateRegionsImpl(Values, E, Count, LCtx,
-                                 CausedByPointerEscape,
-                                 invalidated, Call, ConstValues);
-  }
   return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
-                               *IS, Call, ConstValues);
+                               IS, HTraits, Call);
 }
 
 ProgramStateRef
@@ -170,15 +159,10 @@
                                 bool CausedByPointerEscape,
                                 InvalidatedSymbols *IS,
                                 const CallEvent *Call,
-                                ValueList ConstValues) const {
-  if (!IS) {
-    InvalidatedSymbols invalidated;
-    return invalidateRegionsImpl(Values, E, Count, LCtx,
-                                 CausedByPointerEscape,
-                                 invalidated, Call, ConstValues);
-  }
+                                RegionAndSymHandlingTraits *HTraits) const {
+
   return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
-                               *IS, Call, ConstValues);
+                               IS, HTraits, Call);
 }
 
 ProgramStateRef
@@ -186,49 +170,45 @@
                                     const Expr *E, unsigned Count,
                                     const LocationContext *LCtx,
                                     bool CausedByPointerEscape,
-                                    InvalidatedSymbols &IS,
-                                    const CallEvent *Call,
-                                    ValueList ConstValues) const {
+                                    InvalidatedSymbols *IS,
+                                    RegionAndSymHandlingTraits *HTraits,
+                                    const CallEvent *Call) const {
   ProgramStateManager &Mgr = getStateManager();
   SubEngine* Eng = Mgr.getOwningEngine();
   InvalidatedSymbols ConstIS;
 
+  InvalidatedSymbols Invalidated;
+  if (!IS)
+    IS = &Invalidated;
+
+  RegionAndSymHandlingTraits HTraitsLocal;
+  if (!HTraits)
+    HTraits = &HTraitsLocal;
+
   if (Eng) {
     StoreManager::InvalidatedRegions TopLevelInvalidated;
-    StoreManager::InvalidatedRegions TopLevelConstInvalidated;
     StoreManager::InvalidatedRegions Invalidated;
     const StoreRef &newStore
-    = Mgr.StoreMgr->invalidateRegions(getStore(), Values, ConstValues,
-                                      E, Count, LCtx, Call,
-                                      IS, ConstIS,
-                                      &TopLevelInvalidated,
-                                      &TopLevelConstInvalidated,
+    = Mgr.StoreMgr->invalidateRegions(getStore(), Values, E, Count, LCtx, Call,
+                                      *IS, *HTraits, &TopLevelInvalidated,
                                       &Invalidated);
 
     ProgramStateRef newState = makeWithStore(newStore);
 
     if (CausedByPointerEscape) {
-      newState = Eng->notifyCheckersOfPointerEscape(newState, &IS,
+      newState = Eng->notifyCheckersOfPointerEscape(newState, IS,
                                                     TopLevelInvalidated,
-                                                    Invalidated, Call);
-      if (!ConstValues.empty()) {
-        StoreManager::InvalidatedRegions Empty;
-        newState = Eng->notifyCheckersOfPointerEscape(newState, &ConstIS,
-                                                      TopLevelConstInvalidated,
-                                                      Empty, Call,
-                                                      true);
-      }
+                                                    Invalidated, Call, 
+                                                    *HTraits);
     }
 
-    return Eng->processRegionChanges(newState, &IS,
-                                     TopLevelInvalidated, Invalidated,
-                                     Call);
+    return Eng->processRegionChanges(newState, IS, TopLevelInvalidated, 
+                                     Invalidated, Call);
   }
 
   const StoreRef &newStore =
-  Mgr.StoreMgr->invalidateRegions(getStore(), Values, ConstValues,
-                                  E, Count, LCtx, Call,
-                                  IS, ConstIS, NULL, NULL, NULL);
+  Mgr.StoreMgr->invalidateRegions(getStore(), Values, E, Count, LCtx, Call,
+                                  *IS, *HTraits, NULL, NULL);
   return makeWithStore(newStore);
 }
 
Index: lib/StaticAnalyzer/Core/RegionStore.cpp
===================================================================
--- lib/StaticAnalyzer/Core/RegionStore.cpp	(revision 182426)
+++ lib/StaticAnalyzer/Core/RegionStore.cpp	(working copy)
@@ -349,7 +349,6 @@
   /// regions.
   void populateWorkList(invalidateRegionsWorker &W,
                         ArrayRef<SVal> Values,
-                        bool IsArrayOfConstRegions,
                         InvalidatedRegions *TopLevelRegions);
 
 public:
@@ -395,15 +394,13 @@
 
   StoreRef invalidateRegions(Store store,
                              ArrayRef<SVal> Values,
-                             ArrayRef<SVal> ConstValues,
                              const Expr *E, unsigned Count,
                              const LocationContext *LCtx,
                              const CallEvent *Call,
                              InvalidatedSymbols &IS,
-                             InvalidatedSymbols &ConstIS,
+                             RegionAndSymHandlingTraits &HTraits,
                              InvalidatedRegions *Invalidated,
-                             InvalidatedRegions *InvalidatedTopLevel,
-                             InvalidatedRegions *InvalidatedTopLevelConst);
+                             InvalidatedRegions *InvalidatedTopLevel);
 
   bool scanReachableSymbols(Store S, const MemRegion *R,
                             ScanReachableSymbols &Callbacks);
@@ -639,7 +636,7 @@
 class ClusterAnalysis  {
 protected:
   typedef llvm::DenseMap<const MemRegion *, const ClusterBindings *> ClusterMap;
-  typedef llvm::PointerIntPair<const MemRegion *, 1, bool> WorkListElement;
+  typedef const MemRegion * WorkListElement;
   typedef SmallVector<WorkListElement, 10> WorkList;
 
   llvm::SmallPtrSet<const ClusterBindings *, 16> Visited;
@@ -711,18 +708,17 @@
     return true;
   }
 
-  bool AddToWorkList(const MemRegion *R, bool Flag = false) {
+  bool AddToWorkList(const MemRegion *R) {
     const MemRegion *BaseR = R->getBaseRegion();
-    return AddToWorkList(WorkListElement(BaseR, Flag), getCluster(BaseR));
+    return AddToWorkList(WorkListElement(BaseR), getCluster(BaseR));
   }
 
   void RunWorkList() {
     while (!WL.empty()) {
       WorkListElement E = WL.pop_back_val();
-      const MemRegion *BaseR = E.getPointer();
+      const MemRegion *BaseR = E;
 
-      static_cast<DERIVED*>(this)->VisitCluster(BaseR, getCluster(BaseR),
-                                                E.getInt());
+      static_cast<DERIVED*>(this)->VisitCluster(BaseR, getCluster(BaseR));
     }
   }
 
@@ -942,7 +938,7 @@
   unsigned Count;
   const LocationContext *LCtx;
   InvalidatedSymbols &IS;
-  InvalidatedSymbols &ConstIS;
+  RegionAndSymHandlingTraits &HTraits;
   StoreManager::InvalidatedRegions *Regions;
 public:
   invalidateRegionsWorker(RegionStoreManager &rm,
@@ -951,16 +947,15 @@
                           const Expr *ex, unsigned count,
                           const LocationContext *lctx,
                           InvalidatedSymbols &is,
-                          InvalidatedSymbols &inConstIS,
+                          RegionAndSymHandlingTraits &HTraitsIn,
                           StoreManager::InvalidatedRegions *r,
                           GlobalsFilterKind GFK)
     : ClusterAnalysis<invalidateRegionsWorker>(rm, stateMgr, b, GFK),
-      Ex(ex), Count(count), LCtx(lctx), IS(is), ConstIS(inConstIS), Regions(r){}
+      Ex(ex), Count(count), LCtx(lctx), IS(is), HTraits(HTraitsIn), Regions(r){}
 
   /// \param IsConst Specifies if the region we are invalidating is constant.
   /// If it is, we invalidate all subregions, but not the base region itself.
-  void VisitCluster(const MemRegion *baseR, const ClusterBindings *C,
-                    bool IsConst);
+  void VisitCluster(const MemRegion *baseR, const ClusterBindings *C);
   void VisitBinding(SVal V);
 };
 }
@@ -991,14 +986,17 @@
 }
 
 void invalidateRegionsWorker::VisitCluster(const MemRegion *baseR,
-                                           const ClusterBindings *C,
-                                           bool IsConst) {
+                                           const ClusterBindings *C) {
+
+  bool PreserveRegionsContents = 
+      HTraits.hasTrait(baseR, RegionAndSymHandlingTraits::TK_PreserveContents);
+
   if (C) {
     for (ClusterBindings::iterator I = C->begin(), E = C->end(); I != E; ++I)
       VisitBinding(I.getData());
 
-    // Invalidate the contents of a non-const base region.
-    if (!IsConst)
+    // Invalidate regions contents.
+    if (!PreserveRegionsContents)
       B = B.remove(baseR);
   }
 
@@ -1030,18 +1028,11 @@
   }
 
   // Symbolic region?
-  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR)) {
-    SymbolRef RegionSym = SR->getSymbol();
+  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR))
+    IS.insert(SR->getSymbol());
 
-    // Mark that symbol touched by the invalidation.
-    if (IsConst)
-      ConstIS.insert(RegionSym);
-    else
-      IS.insert(RegionSym);
-  }
-
-  // Nothing else should be done for a const region.
-  if (IsConst)
+  // Nothing else should be done in the case when we preserve regions context.
+  if (PreserveRegionsContents)
     return;
 
   // Otherwise, we have a normal data region. Record that we touched the region.
@@ -1050,7 +1041,7 @@
 
   if (isa<AllocaRegion>(baseR) || isa<SymbolicRegion>(baseR)) {
     // Invalidate the region by setting its default value to
-    // conjured symbol. The type of the symbol is irrelavant.
+    // conjured symbol. The type of the symbol is irrelevant.
     DefinedOrUnknownSVal V =
       svalBuilder.conjureSymbolVal(baseR, Ex, LCtx, Ctx.IntTy, Count);
     B = B.addBinding(baseR, BindingKey::Default, V);
@@ -1072,7 +1063,7 @@
 
   if (T->isStructureOrClassType()) {
     // Invalidate the region by setting its default value to
-    // conjured symbol. The type of the symbol is irrelavant.
+    // conjured symbol. The type of the symbol is irrelevant.
     DefinedOrUnknownSVal V = svalBuilder.conjureSymbolVal(baseR, Ex, LCtx,
                                                           Ctx.IntTy, Count);
     B = B.addBinding(baseR, BindingKey::Default, V);
@@ -1121,7 +1112,6 @@
 
 void RegionStoreManager::populateWorkList(invalidateRegionsWorker &W,
                                           ArrayRef<SVal> Values,
-                                          bool IsArrayOfConstRegions,
                                           InvalidatedRegions *TopLevelRegions) {
   for (ArrayRef<SVal>::iterator I = Values.begin(),
                                 E = Values.end(); I != E; ++I) {
@@ -1136,7 +1126,7 @@
         // Note: the last argument is false here because these are
         // non-top-level regions.
         if (const MemRegion *R = (*I).getAsRegion())
-          W.AddToWorkList(R, /*IsConst=*/ false);
+          W.AddToWorkList(R);
       }
       continue;
     }
@@ -1144,7 +1134,7 @@
     if (const MemRegion *R = V.getAsRegion()) {
       if (TopLevelRegions)
         TopLevelRegions->push_back(R);
-      W.AddToWorkList(R, /*IsConst=*/ IsArrayOfConstRegions);
+      W.AddToWorkList(R);
       continue;
     }
   }
@@ -1153,14 +1143,12 @@
 StoreRef
 RegionStoreManager::invalidateRegions(Store store,
                                       ArrayRef<SVal> Values,
-                                      ArrayRef<SVal> ConstValues,
                                       const Expr *Ex, unsigned Count,
                                       const LocationContext *LCtx,
                                       const CallEvent *Call,
                                       InvalidatedSymbols &IS,
-                                      InvalidatedSymbols &ConstIS,
+                                      RegionAndSymHandlingTraits &HTraits,
                                       InvalidatedRegions *TopLevelRegions,
-                                      InvalidatedRegions *TopLevelConstRegions,
                                       InvalidatedRegions *Invalidated) {
   GlobalsFilterKind GlobalsFilter;
   if (Call) {
@@ -1173,17 +1161,14 @@
   }
 
   RegionBindingsRef B = getRegionBindings(store);
-  invalidateRegionsWorker W(*this, StateMgr, B, Ex, Count, LCtx, IS, ConstIS,
+  invalidateRegionsWorker W(*this, StateMgr, B, Ex, Count, LCtx, IS, HTraits,
                             Invalidated, GlobalsFilter);
 
   // Scan the bindings and generate the clusters.
   W.GenerateClusters();
 
   // Add the regions to the worklist.
-  populateWorkList(W, Values, /*IsArrayOfConstRegions*/ false,
-                   TopLevelRegions);
-  populateWorkList(W, ConstValues, /*IsArrayOfConstRegions*/ true,
-                   TopLevelConstRegions);
+  populateWorkList(W, Values, TopLevelRegions);
 
   W.RunWorkList();
 
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to