ASDenysPetrov created this revision.
ASDenysPetrov added reviewers: steakhal, xazax.hun, Charusso, Szelethus, 
vsavchenko.
ASDenysPetrov added a project: clang.
Herald added subscribers: martong, dkrupp, donat.nagy, mikhail.ramalho, 
a.sidorin, rnkovacs, szepet, baloghadamsoftware.
ASDenysPetrov requested review of this revision.
Herald added a subscriber: cfe-commits.

Add `ProgramStateRef` as a new parameter to  `SValBuilder::evalCast` function 
and pass the argument through the code.
This patch is a preparatory one and does not change any behavior and serves for 
further improvements.
It makes future revisions smaller and safer.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D97296

Files:
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
  clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
  clang/lib/StaticAnalyzer/Core/CallEvent.cpp
  clang/lib/StaticAnalyzer/Core/CheckerContext.cpp
  clang/lib/StaticAnalyzer/Core/Environment.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
  clang/lib/StaticAnalyzer/Core/ProgramState.cpp
  clang/lib/StaticAnalyzer/Core/RegionStore.cpp
  clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
  clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
  clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
  clang/lib/StaticAnalyzer/Core/Store.cpp

Index: clang/lib/StaticAnalyzer/Core/Store.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/Store.cpp
+++ clang/lib/StaticAnalyzer/Core/Store.cpp
@@ -43,7 +43,7 @@
     : svalBuilder(stateMgr.getSValBuilder()), StateMgr(stateMgr),
       MRMgr(svalBuilder.getRegionManager()), Ctx(stateMgr.getContext()) {}
 
-StoreRef StoreManager::enterStackFrame(Store OldStore,
+StoreRef StoreManager::enterStackFrame(ProgramStateRef State, Store OldStore,
                                        const CallEvent &Call,
                                        const StackFrameContext *LCtx) {
   StoreRef Store = StoreRef(OldStore, *this);
@@ -52,7 +52,7 @@
   Call.getInitialStackFrameContents(LCtx, InitialBindings);
 
   for (const auto &I : InitialBindings)
-    Store = Bind(Store.getStore(), I.first.castAs<Loc>(), I.second);
+    Store = Bind(State, Store.getStore(), I.first.castAs<Loc>(), I.second);
 
   return Store;
 }
@@ -439,8 +439,8 @@
   return getLValueFieldOrIvar(decl, base);
 }
 
-SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
-                                    SVal Base) {
+SVal StoreManager::getLValueElement(ProgramStateRef State, QualType elementType,
+                                    NonLoc Offset, SVal Base) {
   // If the base is an unknown or undefined value, just return it back.
   // FIXME: For absolute pointer addresses, we just return that value back as
   //  well, although in reality we should return the offset added to that
@@ -458,7 +458,7 @@
   const auto *ElemR = dyn_cast<ElementRegion>(BaseRegion);
 
   // Convert the offset to the appropriate size and signedness.
-  Offset = svalBuilder.convertToArrayIndex(Offset).castAs<NonLoc>();
+  Offset = svalBuilder.convertToArrayIndex(State, Offset).castAs<NonLoc>();
 
   if (!ElemR) {
     // If the base region is not an ElementRegion, create one.
Index: clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -45,8 +45,9 @@
   /// with their known values (in the sense of the getKnownValue() method).
   SVal simplifySVal(ProgramStateRef State, SVal V) override;
 
-  SVal MakeSymIntVal(const SymExpr *LHS, BinaryOperator::Opcode op,
-                     const llvm::APSInt &RHS, QualType resultTy);
+  SVal MakeSymIntVal(ProgramStateRef State, const SymExpr *LHS,
+                     BinaryOperator::Opcode op, const llvm::APSInt &RHS,
+                     QualType resultTy);
 };
 } // end anonymous namespace
 
@@ -82,10 +83,10 @@
 // Transfer function for binary operators.
 //===----------------------------------------------------------------------===//
 
-SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS,
-                                    BinaryOperator::Opcode op,
-                                    const llvm::APSInt &RHS,
-                                    QualType resultTy) {
+SVal SimpleSValBuilder::MakeSymIntVal(ProgramStateRef State, const SymExpr *LHS,
+                                      BinaryOperator::Opcode op,
+                                      const llvm::APSInt &RHS,
+                                      QualType resultTy) {
   bool isIdempotent = false;
 
   // Check for a few special cases with known reductions first.
@@ -147,7 +148,7 @@
   // Wrap the LHS up in a NonLoc again and let evalCast do the
   // dirty work.
   if (isIdempotent)
-    return evalCast(nonloc::SymbolVal(LHS), resultTy);
+    return evalCast(State, nonloc::SymbolVal(LHS), resultTy);
 
   // If we reach this point, the expression cannot be simplified.
   // Make a SymbolVal for the entire expression, after converting the RHS.
@@ -393,10 +394,10 @@
       case BO_Sub:
         if (resultTy->isIntegralOrEnumerationType())
           return makeIntVal(0, resultTy);
-        return evalCast(makeIntVal(0, /*isUnsigned=*/false), resultTy);
+        return evalCast(state, makeIntVal(0, /*isUnsigned=*/false), resultTy);
       case BO_Or:
       case BO_And:
-        return evalCast(lhs, resultTy);
+        return evalCast(state, lhs, resultTy);
     }
 
   while (1) {
@@ -513,12 +514,12 @@
       case BO_Shr:
         // (~0)>>a
         if (LHSValue.isAllOnesValue() && LHSValue.isSigned())
-          return evalCast(lhs, resultTy);
+          return evalCast(state, lhs, resultTy);
         LLVM_FALLTHROUGH;
       case BO_Shl:
         // 0<<a and 0>>a
         if (LHSValue == 0)
-          return evalCast(lhs, resultTy);
+          return evalCast(state, lhs, resultTy);
         return makeSymExprValNN(op, InputLHS, InputRHS, resultTy);
       case BO_Rem:
         // 0 % x == 0
@@ -616,7 +617,7 @@
           }
 
           // Otherwise, make a SymIntExpr out of the expression.
-          return MakeSymIntVal(symIntExpr, op, *RHSValue, resultTy);
+          return MakeSymIntVal(state, symIntExpr, op, *RHSValue, resultTy);
         }
       }
 
@@ -632,7 +633,7 @@
 
       // Is the RHS a constant?
       if (const llvm::APSInt *RHSValue = getKnownValue(state, rhs))
-        return MakeSymIntVal(Sym, op, *RHSValue, resultTy);
+        return MakeSymIntVal(state, Sym, op, *RHSValue, resultTy);
 
       if (Optional<NonLoc> V = tryRearrange(state, op, lhs, rhs, resultTy))
         return *V;
@@ -733,7 +734,7 @@
       default:
         break;
       case BO_Sub:
-        return evalCast(lhs, resultTy);
+        return evalCast(state, lhs, resultTy);
       case BO_EQ:
       case BO_LE:
       case BO_LT:
@@ -770,7 +771,7 @@
       SVal ResultVal =
           lhs.castAs<loc::ConcreteInt>().evalBinOp(BasicVals, op, *rInt);
       if (Optional<NonLoc> Result = ResultVal.getAs<NonLoc>())
-        return evalCast(*Result, resultTy);
+        return evalCast(state, *Result, resultTy);
 
       assert(!ResultVal.getAs<Loc>() && "Loc-Loc ops should not produce Locs");
       return UnknownVal();
@@ -806,7 +807,7 @@
       // build an expression for use by the constraint manager.
       if (SymbolRef lSym = lhs.getAsLocSymbol(true)) {
         if (BinaryOperator::isComparisonOp(op))
-          return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
+          return MakeSymIntVal(state, lSym, op, rInt->getValue(), resultTy);
         return UnknownVal();
       }
       // Special case comparisons to NULL.
@@ -815,11 +816,11 @@
       // to be non-NULL.
       if (rInt->isZeroConstant()) {
         if (op == BO_Sub)
-          return evalCast(lhs, resultTy);
+          return evalCast(state, lhs, resultTy);
 
         if (BinaryOperator::isComparisonOp(op)) {
           QualType boolType = getContext().BoolTy;
-          NonLoc l = evalCast(lhs, boolType).castAs<NonLoc>();
+          NonLoc l = evalCast(state, lhs, boolType).castAs<NonLoc>();
           NonLoc r = makeTruthVal(false, boolType).castAs<NonLoc>();
           return evalBinOpNN(state, op, l, r, resultTy);
         }
@@ -901,7 +902,7 @@
         Optional<NonLoc> LeftIndex = LeftIndexVal.getAs<NonLoc>();
         if (!LeftIndex)
           return UnknownVal();
-        LeftIndexVal = evalCast(*LeftIndex, ArrayIndexTy);
+        LeftIndexVal = evalCast(state, *LeftIndex, ArrayIndexTy);
         LeftIndex = LeftIndexVal.getAs<NonLoc>();
         if (!LeftIndex)
           return UnknownVal();
@@ -911,7 +912,7 @@
         Optional<NonLoc> RightIndex = RightIndexVal.getAs<NonLoc>();
         if (!RightIndex)
           return UnknownVal();
-        RightIndexVal = evalCast(*RightIndex, ArrayIndexTy);
+        RightIndexVal = evalCast(state, *RightIndex, ArrayIndexTy);
         RightIndex = RightIndexVal.getAs<NonLoc>();
         if (!RightIndex)
           return UnknownVal();
@@ -1049,7 +1050,7 @@
 
   // Handle cases where 'lhs' is a region.
   if (const MemRegion *region = lhs.getAsRegion()) {
-    rhs = convertToArrayIndex(rhs).castAs<NonLoc>();
+    rhs = convertToArrayIndex(state, rhs).castAs<NonLoc>();
     SVal index = UnknownVal();
     const SubRegion *superR = nullptr;
     // We need to know the type of the pointer in order to add an integer to it.
Index: clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
+++ clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
@@ -35,7 +35,8 @@
     else
       T = SVB.getContext().VoidPtrTy;
 
-    Cond = SVB.evalCast(*LV, SVB.getContext().BoolTy, T).castAs<DefinedSVal>();
+    Cond = SVB.evalCast(State, *LV, SVB.getContext().BoolTy, T)
+               .castAs<DefinedSVal>();
   }
 
   return assume(State, Cond.castAs<NonLoc>(), Assumption);
Index: clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -96,7 +96,7 @@
   return nonloc::SymbolVal(SymMgr.getCastSymbol(operand, fromTy, toTy));
 }
 
-SVal SValBuilder::convertToArrayIndex(SVal val) {
+SVal SValBuilder::convertToArrayIndex(ProgramStateRef State, SVal val) {
   if (val.isUnknownOrUndef())
     return val;
 
@@ -107,7 +107,7 @@
       return val;
   }
 
-  return evalCast(val, ArrayIndexTy);
+  return evalCast(State, val, ArrayIndexTy);
 }
 
 nonloc::ConcreteInt SValBuilder::makeBoolVal(const CXXBoolLiteralExpr *boolean){
@@ -283,7 +283,8 @@
   return loc::MemRegionVal(getRegionManager().getCXXThisRegion(PT, SFC));
 }
 
-Optional<SVal> SValBuilder::getConstantVal(const Expr *E) {
+Optional<SVal> SValBuilder::getConstantVal(ProgramStateRef State,
+                                           const Expr *E) {
   E = E->IgnoreParens();
 
   switch (E->getStmtClass()) {
@@ -353,10 +354,10 @@
     case CK_NoOp:
     case CK_BitCast: {
       const Expr *SE = CE->getSubExpr();
-      Optional<SVal> Val = getConstantVal(SE);
+      Optional<SVal> Val = getConstantVal(State, SE);
       if (!Val)
         return None;
-      return evalCast(*Val, CE->getType(), SE->getType());
+      return evalCast(State, *Val, CE->getType(), SE->getType());
     }
     }
     // FALLTHROUGH
@@ -499,11 +500,11 @@
                                    QualType castTy, QualType originalTy) {
   // No truncations if target type is big enough.
   if (getContext().getTypeSize(castTy) >= getContext().getTypeSize(originalTy))
-    return evalCast(val, castTy, originalTy);
+    return evalCast(state, val, castTy, originalTy);
 
   SymbolRef se = val.getAsSymbol();
   if (!se) // Let evalCast handle non symbolic expressions.
-    return evalCast(val, castTy, originalTy);
+    return evalCast(state, val, castTy, originalTy);
 
   // Find the maximum value of the target type.
   APSIntType ToType(getContext().getTypeSize(castTy),
@@ -527,7 +528,7 @@
     NonLoc CastVal = makeNonLoc(se, originalTy, castTy);
     return CastVal;
   }
-  return evalCast(val, castTy, originalTy);
+  return evalCast(state, val, castTy, originalTy);
 }
 
 //===----------------------------------------------------------------------===//
@@ -537,7 +538,7 @@
 //===----------------------------------------------------------------------===//
 
 // In case when `OriginalTy.isNull() == true` we cast `V` less accurately.
-SVal SValBuilder::evalCast(SVal V, QualType CastTy,
+SVal SValBuilder::evalCast(ProgramStateRef State, SVal V, QualType CastTy,
                            QualType OriginalTy /*= QualType{}*/) {
   if (CastTy.isNull())
     return V;
@@ -564,63 +565,71 @@
   default:
     llvm_unreachable("Unknown SVal kind");
   case SVal::UndefinedValKind:
-    return evalCastKind(V.castAs<UndefinedVal>(), CastTy, OriginalTy);
+    return evalCastKind(State, V.castAs<UndefinedVal>(), CastTy, OriginalTy);
   case SVal::UnknownValKind:
-    return evalCastKind(V.castAs<UnknownVal>(), CastTy, OriginalTy);
+    return evalCastKind(State, V.castAs<UnknownVal>(), CastTy, OriginalTy);
   case SVal::LocKind:
-    return evalCastKind(V.castAs<Loc>(), CastTy, OriginalTy);
+    return evalCastKind(State, V.castAs<Loc>(), CastTy, OriginalTy);
   case SVal::NonLocKind:
-    return evalCastKind(V.castAs<NonLoc>(), CastTy, OriginalTy);
+    return evalCastKind(State, V.castAs<NonLoc>(), CastTy, OriginalTy);
   }
 }
 
-SVal SValBuilder::evalCastKind(UndefinedVal V, QualType CastTy,
-                               QualType OriginalTy) {
+SVal SValBuilder::evalCastKind(ProgramStateRef State, UndefinedVal V,
+                               QualType CastTy, QualType OriginalTy) {
   return V;
 }
 
-SVal SValBuilder::evalCastKind(UnknownVal V, QualType CastTy,
-                               QualType OriginalTy) {
+SVal SValBuilder::evalCastKind(ProgramStateRef State, UnknownVal V,
+                               QualType CastTy, QualType OriginalTy) {
   return V;
 }
 
-SVal SValBuilder::evalCastKind(Loc V, QualType CastTy, QualType OriginalTy) {
+SVal SValBuilder::evalCastKind(ProgramStateRef State, Loc V, QualType CastTy,
+                               QualType OriginalTy) {
   switch (V.getSubKind()) {
   default:
     llvm_unreachable("Unknown SVal kind");
   case loc::ConcreteIntKind:
-    return evalCastSubKind(V.castAs<loc::ConcreteInt>(), CastTy, OriginalTy);
+    return evalCastSubKind(State, V.castAs<loc::ConcreteInt>(), CastTy,
+                           OriginalTy);
   case loc::GotoLabelKind:
-    return evalCastSubKind(V.castAs<loc::GotoLabel>(), CastTy, OriginalTy);
+    return evalCastSubKind(State, V.castAs<loc::GotoLabel>(), CastTy,
+                           OriginalTy);
   case loc::MemRegionValKind:
-    return evalCastSubKind(V.castAs<loc::MemRegionVal>(), CastTy, OriginalTy);
+    return evalCastSubKind(State, V.castAs<loc::MemRegionVal>(), CastTy,
+                           OriginalTy);
   }
 }
 
-SVal SValBuilder::evalCastKind(NonLoc V, QualType CastTy, QualType OriginalTy) {
+SVal SValBuilder::evalCastKind(ProgramStateRef State, NonLoc V, QualType CastTy,
+                               QualType OriginalTy) {
   switch (V.getSubKind()) {
   default:
     llvm_unreachable("Unknown SVal kind");
   case nonloc::CompoundValKind:
-    return evalCastSubKind(V.castAs<nonloc::CompoundVal>(), CastTy, OriginalTy);
+    return evalCastSubKind(State, V.castAs<nonloc::CompoundVal>(), CastTy,
+                           OriginalTy);
   case nonloc::ConcreteIntKind:
-    return evalCastSubKind(V.castAs<nonloc::ConcreteInt>(), CastTy, OriginalTy);
+    return evalCastSubKind(State, V.castAs<nonloc::ConcreteInt>(), CastTy,
+                           OriginalTy);
   case nonloc::LazyCompoundValKind:
-    return evalCastSubKind(V.castAs<nonloc::LazyCompoundVal>(), CastTy,
+    return evalCastSubKind(State, V.castAs<nonloc::LazyCompoundVal>(), CastTy,
                            OriginalTy);
   case nonloc::LocAsIntegerKind:
-    return evalCastSubKind(V.castAs<nonloc::LocAsInteger>(), CastTy,
+    return evalCastSubKind(State, V.castAs<nonloc::LocAsInteger>(), CastTy,
                            OriginalTy);
   case nonloc::SymbolValKind:
-    return evalCastSubKind(V.castAs<nonloc::SymbolVal>(), CastTy, OriginalTy);
+    return evalCastSubKind(State, V.castAs<nonloc::SymbolVal>(), CastTy,
+                           OriginalTy);
   case nonloc::PointerToMemberKind:
-    return evalCastSubKind(V.castAs<nonloc::PointerToMember>(), CastTy,
+    return evalCastSubKind(State, V.castAs<nonloc::PointerToMember>(), CastTy,
                            OriginalTy);
   }
 }
 
-SVal SValBuilder::evalCastSubKind(loc::ConcreteInt V, QualType CastTy,
-                                  QualType OriginalTy) {
+SVal SValBuilder::evalCastSubKind(ProgramStateRef State, loc::ConcreteInt V,
+                                  QualType CastTy, QualType OriginalTy) {
   // Pointer to bool.
   if (CastTy->isBooleanType())
     return makeTruthVal(V.getValue().getBoolValue(), CastTy);
@@ -640,8 +649,8 @@
   return UnknownVal();
 }
 
-SVal SValBuilder::evalCastSubKind(loc::GotoLabel V, QualType CastTy,
-                                  QualType OriginalTy) {
+SVal SValBuilder::evalCastSubKind(ProgramStateRef State, loc::GotoLabel V,
+                                  QualType CastTy, QualType OriginalTy) {
   // Pointer to bool.
   if (CastTy->isBooleanType())
     // Labels are always true.
@@ -673,8 +682,8 @@
          ty2->getPointeeType().getCanonicalType().getTypePtr();
 }
 
-SVal SValBuilder::evalCastSubKind(loc::MemRegionVal V, QualType CastTy,
-                                  QualType OriginalTy) {
+SVal SValBuilder::evalCastSubKind(ProgramStateRef State, loc::MemRegionVal V,
+                                  QualType CastTy, QualType OriginalTy) {
   // Pointer to bool.
   if (CastTy->isBooleanType()) {
     const MemRegion *R = V.getRegion();
@@ -795,14 +804,14 @@
   return UnknownVal();
 }
 
-SVal SValBuilder::evalCastSubKind(nonloc::CompoundVal V, QualType CastTy,
-                                  QualType OriginalTy) {
+SVal SValBuilder::evalCastSubKind(ProgramStateRef State, nonloc::CompoundVal V,
+                                  QualType CastTy, QualType OriginalTy) {
   // Compound to whatever.
   return UnknownVal();
 }
 
-SVal SValBuilder::evalCastSubKind(nonloc::ConcreteInt V, QualType CastTy,
-                                  QualType OriginalTy) {
+SVal SValBuilder::evalCastSubKind(ProgramStateRef State, nonloc::ConcreteInt V,
+                                  QualType CastTy, QualType OriginalTy) {
   auto CastedValue = [V, CastTy, this]() {
     llvm::APSInt Value = V.getValue();
     BasicVals.getAPSIntType(CastTy).apply(Value);
@@ -825,20 +834,20 @@
   return UnknownVal();
 }
 
-SVal SValBuilder::evalCastSubKind(nonloc::LazyCompoundVal V, QualType CastTy,
+SVal SValBuilder::evalCastSubKind(ProgramStateRef State,
+                                  nonloc::LazyCompoundVal V, QualType CastTy,
                                   QualType OriginalTy) {
   // Compound to whatever.
   return UnknownVal();
 }
 
-SVal SValBuilder::evalCastSubKind(nonloc::LocAsInteger V, QualType CastTy,
-                                  QualType OriginalTy) {
+SVal SValBuilder::evalCastSubKind(ProgramStateRef State, nonloc::LocAsInteger V,
+                                  QualType CastTy, QualType OriginalTy) {
   Loc L = V.getLoc();
 
   // Pointer as integer to bool.
   if (CastTy->isBooleanType())
-    // Pass to Loc function.
-    return evalCastKind(L, CastTy, OriginalTy);
+    return evalCastKind(State, L, CastTy, OriginalTy);
 
   if (Loc::isLocType(CastTy) && !OriginalTy.isNull() &&
       OriginalTy->isIntegralOrEnumerationType()) {
@@ -852,7 +861,7 @@
   const MemRegion *R = L.getAsRegion();
   if (!OriginalTy.isNull() && R) {
     if (CastTy->isIntegralOrEnumerationType())
-      return evalCastSubKind(loc::MemRegionVal(R), CastTy, OriginalTy);
+      return evalCastSubKind(State, loc::MemRegionVal(R), CastTy, OriginalTy);
 
     if (Loc::isLocType(CastTy)) {
       assert(Loc::isLocType(OriginalTy) || OriginalTy->isFunctionType() ||
@@ -866,7 +875,7 @@
   } else {
     if (Loc::isLocType(CastTy)) {
       if (OriginalTy.isNull())
-        return evalCastSubKind(loc::MemRegionVal(R), CastTy, OriginalTy);
+        return evalCastSubKind(State, loc::MemRegionVal(R), CastTy, OriginalTy);
       return L;
     }
 
@@ -892,8 +901,8 @@
   return UnknownVal();
 }
 
-SVal SValBuilder::evalCastSubKind(nonloc::SymbolVal V, QualType CastTy,
-                                  QualType OriginalTy) {
+SVal SValBuilder::evalCastSubKind(ProgramStateRef State, nonloc::SymbolVal V,
+                                  QualType CastTy, QualType OriginalTy) {
   SymbolRef SE = V.getSymbol();
 
   // Symbol to bool.
@@ -927,7 +936,8 @@
   return UnknownVal();
 }
 
-SVal SValBuilder::evalCastSubKind(nonloc::PointerToMember V, QualType CastTy,
+SVal SValBuilder::evalCastSubKind(ProgramStateRef State,
+                                  nonloc::PointerToMember V, QualType CastTy,
                                   QualType OriginalTy) {
   // Member pointer to whatever.
   return V;
Index: clang/lib/StaticAnalyzer/Core/RegionStore.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -423,12 +423,10 @@
                                            RegionBindingsRef B,
                                            InvalidatedRegions *Invalidated);
 
-  StoreRef invalidateRegions(Store store,
-                             ArrayRef<SVal> Values,
-                             const Expr *E, unsigned Count,
-                             const LocationContext *LCtx,
-                             const CallEvent *Call,
-                             InvalidatedSymbols &IS,
+  StoreRef invalidateRegions(ProgramStateRef State, Store store,
+                             ArrayRef<SVal> Values, const Expr *E,
+                             unsigned Count, const LocationContext *LCtx,
+                             const CallEvent *Call, InvalidatedSymbols &IS,
                              RegionAndSymbolInvalidationTraits &ITraits,
                              InvalidatedRegions *Invalidated,
                              InvalidatedRegions *InvalidatedTopLevel) override;
@@ -440,12 +438,13 @@
                                             const SubRegion *R);
 
 public: // Part of public interface to class.
-
-  StoreRef Bind(Store store, Loc LV, SVal V) override {
-    return StoreRef(bind(getRegionBindings(store), LV, V).asStore(), *this);
+  StoreRef Bind(ProgramStateRef State, Store store, Loc LV, SVal V) override {
+    return StoreRef(bind(State, getRegionBindings(store), LV, V).asStore(),
+                    *this);
   }
 
-  RegionBindingsRef bind(RegionBindingsConstRef B, Loc LV, SVal V);
+  RegionBindingsRef bind(ProgramStateRef State, RegionBindingsConstRef B,
+                         Loc LV, SVal V);
 
   // BindDefaultInitial is only used to initialize a region with
   // a default value.
@@ -493,22 +492,22 @@
   ///
   /// \returns The updated store bindings, or \c None if binding non-lazily
   ///          would be too expensive.
-  Optional<RegionBindingsRef> tryBindSmallStruct(RegionBindingsConstRef B,
+  Optional<RegionBindingsRef> tryBindSmallStruct(ProgramStateRef State,
+                                                 RegionBindingsConstRef B,
                                                  const TypedValueRegion *R,
                                                  const RecordDecl *RD,
                                                  nonloc::LazyCompoundVal LCV);
 
   /// BindStruct - Bind a compound value to a structure.
-  RegionBindingsRef bindStruct(RegionBindingsConstRef B,
-                               const TypedValueRegion* R, SVal V);
+  RegionBindingsRef bindStruct(ProgramStateRef State, RegionBindingsConstRef B,
+                               const TypedValueRegion *R, SVal V);
 
   /// BindVector - Bind a compound value to a vector.
-  RegionBindingsRef bindVector(RegionBindingsConstRef B,
-                               const TypedValueRegion* R, SVal V);
+  RegionBindingsRef bindVector(ProgramStateRef State, RegionBindingsConstRef B,
+                               const TypedValueRegion *R, SVal V);
 
-  RegionBindingsRef bindArray(RegionBindingsConstRef B,
-                              const TypedValueRegion* R,
-                              SVal V);
+  RegionBindingsRef bindArray(ProgramStateRef State, RegionBindingsConstRef B,
+                              const TypedValueRegion *R, SVal V);
 
   /// Clears out all bindings in the given region and assigns a new value
   /// as a Default binding.
@@ -547,8 +546,8 @@
   ///       return undefined
   ///     else
   ///       return symbolic
-  SVal getBinding(Store S, Loc L, QualType T) override {
-    return getBinding(getRegionBindings(S), L, T);
+  SVal getBinding(ProgramStateRef State, Store S, Loc L, QualType T) override {
+    return getBinding(State, getRegionBindings(S), L, T);
   }
 
   Optional<SVal> getDefaultBinding(Store S, const MemRegion *R) override {
@@ -559,23 +558,28 @@
     return B.getDefaultBinding(R->getBaseRegion());
   }
 
-  SVal getBinding(RegionBindingsConstRef B, Loc L, QualType T = QualType());
+  SVal getBinding(ProgramStateRef State, RegionBindingsConstRef B, Loc L,
+                  QualType T = QualType());
 
-  SVal getBindingForElement(RegionBindingsConstRef B, const ElementRegion *R);
+  SVal getBindingForElement(ProgramStateRef State, RegionBindingsConstRef B,
+                            const ElementRegion *R);
 
-  SVal getBindingForField(RegionBindingsConstRef B, const FieldRegion *R);
+  SVal getBindingForField(ProgramStateRef State, RegionBindingsConstRef B,
+                          const FieldRegion *R);
 
   SVal getBindingForObjCIvar(RegionBindingsConstRef B, const ObjCIvarRegion *R);
 
-  SVal getBindingForVar(RegionBindingsConstRef B, const VarRegion *R);
+  SVal getBindingForVar(ProgramStateRef State, RegionBindingsConstRef B,
+                        const VarRegion *R);
 
   SVal getBindingForLazySymbol(const TypedValueRegion *R);
 
-  SVal getBindingForFieldOrElementCommon(RegionBindingsConstRef B,
+  SVal getBindingForFieldOrElementCommon(ProgramStateRef State,
+                                         RegionBindingsConstRef B,
                                          const TypedValueRegion *R,
                                          QualType Ty);
 
-  SVal getLazyBinding(const SubRegion *LazyBindingRegion,
+  SVal getLazyBinding(ProgramStateRef State, const SubRegion *LazyBindingRegion,
                       RegionBindingsRef LazyBinding);
 
   /// Get bindings for the values in a struct and return a CompoundVal, used
@@ -619,8 +623,9 @@
 
   /// removeDeadBindings - Scans the RegionStore of 'state' for dead values.
   ///  It returns a new Store with these values removed.
-  StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx,
-                              SymbolReaper& SymReaper) override;
+  StoreRef removeDeadBindings(ProgramStateRef State, Store store,
+                              const StackFrameContext *LCtx,
+                              SymbolReaper &SymReaper) override;
 
   //===------------------------------------------------------------------===//
   // Utility methods.
@@ -764,21 +769,23 @@
     return static_cast<DERIVED*>(this)->AddToWorkList(R);
   }
 
-  void RunWorkList() {
+  void RunWorkList(ProgramStateRef State) {
     while (!WL.empty()) {
       WorkListElement E = WL.pop_back_val();
       const MemRegion *BaseR = E;
 
-      static_cast<DERIVED*>(this)->VisitCluster(BaseR, getCluster(BaseR));
+      static_cast<DERIVED *>(this)->VisitCluster(State, BaseR,
+                                                 getCluster(BaseR));
     }
   }
 
   void VisitAddedToCluster(const MemRegion *baseR, const ClusterBindings &C) {}
-  void VisitCluster(const MemRegion *baseR, const ClusterBindings *C) {}
+  void VisitCluster(ProgramStateRef State, const MemRegion *baseR,
+                    const ClusterBindings *C) {}
 
-  void VisitCluster(const MemRegion *BaseR, const ClusterBindings *C,
-                    bool Flag) {
-    static_cast<DERIVED*>(this)->VisitCluster(BaseR, C);
+  void VisitCluster(ProgramStateRef State, const MemRegion *BaseR,
+                    const ClusterBindings *C, bool Flag) {
+    static_cast<DERIVED *>(this)->VisitCluster(State, BaseR, C);
   }
 };
 }
@@ -1006,7 +1013,8 @@
        Ex(ex), Count(count), LCtx(lctx), IS(is), ITraits(ITraitsIn), Regions(r),
        GlobalsFilter(GFK) {}
 
-  void VisitCluster(const MemRegion *baseR, const ClusterBindings *C);
+  void VisitCluster(ProgramStateRef State, const MemRegion *baseR,
+                    const ClusterBindings *C);
   void VisitBinding(SVal V);
 
   using ClusterAnalysis::AddToWorkList;
@@ -1055,7 +1063,8 @@
   }
 }
 
-void InvalidateRegionsWorker::VisitCluster(const MemRegion *baseR,
+void InvalidateRegionsWorker::VisitCluster(ProgramStateRef State,
+                                           const MemRegion *baseR,
                                            const ClusterBindings *C) {
 
   bool PreserveRegionsContents =
@@ -1114,7 +1123,7 @@
         // invalidate that region.  This is because a block may capture
         // a pointer value, but the thing pointed by that pointer may
         // get invalidated.
-        SVal V = RM.getBinding(B, loc::MemRegionVal(VR));
+        SVal V = RM.getBinding(State, B, loc::MemRegionVal(VR));
         if (Optional<Loc> L = V.getAs<Loc>()) {
           if (const MemRegion *LR = L->getAsRegion())
             AddToWorkList(LR);
@@ -1323,16 +1332,11 @@
   }
 }
 
-StoreRef
-RegionStoreManager::invalidateRegions(Store store,
-                                     ArrayRef<SVal> Values,
-                                     const Expr *Ex, unsigned Count,
-                                     const LocationContext *LCtx,
-                                     const CallEvent *Call,
-                                     InvalidatedSymbols &IS,
-                                     RegionAndSymbolInvalidationTraits &ITraits,
-                                     InvalidatedRegions *TopLevelRegions,
-                                     InvalidatedRegions *Invalidated) {
+StoreRef RegionStoreManager::invalidateRegions(
+    ProgramStateRef State, Store store, ArrayRef<SVal> Values, const Expr *Ex,
+    unsigned Count, const LocationContext *LCtx, const CallEvent *Call,
+    InvalidatedSymbols &IS, RegionAndSymbolInvalidationTraits &ITraits,
+    InvalidatedRegions *TopLevelRegions, InvalidatedRegions *Invalidated) {
   GlobalsFilterKind GlobalsFilter;
   if (Call) {
     if (Call->isInSystemHeader())
@@ -1353,7 +1357,7 @@
   // Add the regions to the worklist.
   populateWorkList(W, Values, TopLevelRegions);
 
-  W.RunWorkList();
+  W.RunWorkList(State);
 
   // Return the new bindings.
   B = W.getRegionBindings();
@@ -1405,7 +1409,9 @@
 // Loading values from regions.
 //===----------------------------------------------------------------------===//
 
-SVal RegionStoreManager::getBinding(RegionBindingsConstRef B, Loc L, QualType T) {
+SVal RegionStoreManager::getBinding(ProgramStateRef State,
+                                    RegionBindingsConstRef B, Loc L,
+                                    QualType T) {
   assert(!L.getAs<UnknownVal>() && "location unknown");
   assert(!L.getAs<UndefinedVal>() && "location undefined");
 
@@ -1479,7 +1485,7 @@
     return UnknownVal();
 
   if (const FieldRegion* FR = dyn_cast<FieldRegion>(R))
-    return svalBuilder.evalCast(getBindingForField(B, FR), T);
+    return svalBuilder.evalCast(State, getBindingForField(State, B, FR), T);
 
   if (const ElementRegion* ER = dyn_cast<ElementRegion>(R)) {
     // FIXME: Here we actually perform an implicit conversion from the loaded
@@ -1487,7 +1493,7 @@
     // more intelligently.  For example, an 'element' can encompass multiple
     // bound regions (e.g., several bound bytes), or could be a subset of
     // a larger value.
-    return svalBuilder.evalCast(getBindingForElement(B, ER), T);
+    return svalBuilder.evalCast(State, getBindingForElement(State, B, ER), T);
   }
 
   if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R)) {
@@ -1497,7 +1503,7 @@
     // reinterpretted, it is possible we stored a different value that could
     // fit within the ivar.  Either we need to cast these when storing them
     // or reinterpret them lazily (as we do here).
-    return svalBuilder.evalCast(getBindingForObjCIvar(B, IVR), T);
+    return svalBuilder.evalCast(State, getBindingForObjCIvar(B, IVR), T);
   }
 
   if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
@@ -1507,7 +1513,7 @@
     // variable is reinterpretted, it is possible we stored a different value
     // that could fit within the variable.  Either we need to cast these when
     // storing them or reinterpret them lazily (as we do here).
-    return svalBuilder.evalCast(getBindingForVar(B, VR), T);
+    return svalBuilder.evalCast(State, getBindingForVar(State, B, VR), T);
   }
 
   const SVal *V = B.lookup(R, BindingKey::Direct);
@@ -1626,8 +1632,9 @@
   return Result;
 }
 
-SVal RegionStoreManager::getBindingForElement(RegionBindingsConstRef B,
-                                              const ElementRegion* R) {
+SVal RegionStoreManager::getBindingForElement(ProgramStateRef State,
+                                              RegionBindingsConstRef B,
+                                              const ElementRegion *R) {
   // Check if the region has a binding.
   if (const Optional<SVal> &V = B.getDirectBinding(R))
     return *V;
@@ -1684,7 +1691,8 @@
               return svalBuilder.makeZeroVal(R->getElementType());
 
             if (const Expr *ElemInit = InitList->getInit(i))
-              if (Optional<SVal> V = svalBuilder.getConstantVal(ElemInit))
+              if (Optional<SVal> V =
+                      svalBuilder.getConstantVal(State, ElemInit))
                 return *V;
           }
         }
@@ -1729,11 +1737,12 @@
       }
     }
   }
-  return getBindingForFieldOrElementCommon(B, R, R->getElementType());
+  return getBindingForFieldOrElementCommon(State, B, R, R->getElementType());
 }
 
-SVal RegionStoreManager::getBindingForField(RegionBindingsConstRef B,
-                                            const FieldRegion* R) {
+SVal RegionStoreManager::getBindingForField(ProgramStateRef State,
+                                            RegionBindingsConstRef B,
+                                            const FieldRegion *R) {
 
   // Check if the region has a binding.
   if (const Optional<SVal> &V = B.getDirectBinding(R))
@@ -1744,7 +1753,7 @@
   QualType Ty = FD->getType();
   if (Ty.isConstQualified())
     if (const Expr *Init = FD->getInClassInitializer())
-      if (Optional<SVal> V = svalBuilder.getConstantVal(Init))
+      if (Optional<SVal> V = svalBuilder.getConstantVal(State, Init))
         return *V;
 
   // If the containing record was initialized, try to get its constant value.
@@ -1762,7 +1771,8 @@
         if (const auto *InitList = dyn_cast<InitListExpr>(Init)) {
           if (Index < InitList->getNumInits()) {
             if (const Expr *FieldInit = InitList->getInit(Index))
-              if (Optional<SVal> V = svalBuilder.getConstantVal(FieldInit))
+              if (Optional<SVal> V =
+                      svalBuilder.getConstantVal(State, FieldInit))
                 return *V;
           } else {
             return svalBuilder.makeZeroVal(Ty);
@@ -1770,7 +1780,7 @@
         }
   }
 
-  return getBindingForFieldOrElementCommon(B, R, Ty);
+  return getBindingForFieldOrElementCommon(State, B, R, Ty);
 }
 
 Optional<SVal>
@@ -1802,13 +1812,14 @@
   return None;
 }
 
-SVal RegionStoreManager::getLazyBinding(const SubRegion *LazyBindingRegion,
+SVal RegionStoreManager::getLazyBinding(ProgramStateRef State,
+                                        const SubRegion *LazyBindingRegion,
                                         RegionBindingsRef LazyBinding) {
   SVal Result;
   if (const ElementRegion *ER = dyn_cast<ElementRegion>(LazyBindingRegion))
-    Result = getBindingForElement(LazyBinding, ER);
+    Result = getBindingForElement(State, LazyBinding, ER);
   else
-    Result = getBindingForField(LazyBinding,
+    Result = getBindingForField(State, LazyBinding,
                                 cast<FieldRegion>(LazyBindingRegion));
 
   // FIXME: This is a hack to deal with RegionStore's inability to distinguish a
@@ -1831,10 +1842,9 @@
   return Result;
 }
 
-SVal
-RegionStoreManager::getBindingForFieldOrElementCommon(RegionBindingsConstRef B,
-                                                      const TypedValueRegion *R,
-                                                      QualType Ty) {
+SVal RegionStoreManager::getBindingForFieldOrElementCommon(
+    ProgramStateRef State, RegionBindingsConstRef B, const TypedValueRegion *R,
+    QualType Ty) {
 
   // At this point we have already checked in either getBindingForElement or
   // getBindingForField if 'R' has a direct binding.
@@ -1844,7 +1854,7 @@
   const SubRegion *lazyBindingRegion = nullptr;
   std::tie(lazyBindingStore, lazyBindingRegion) = findLazyBinding(B, R, R);
   if (lazyBindingRegion)
-    return getLazyBinding(lazyBindingRegion,
+    return getLazyBinding(State, lazyBindingRegion,
                           getRegionBindings(lazyBindingStore));
 
   // Record whether or not we see a symbolic index.  That can completely
@@ -1937,7 +1947,8 @@
   return getBindingForLazySymbol(R);
 }
 
-SVal RegionStoreManager::getBindingForVar(RegionBindingsConstRef B,
+SVal RegionStoreManager::getBindingForVar(ProgramStateRef State,
+                                          RegionBindingsConstRef B,
                                           const VarRegion *R) {
 
   // Check if the region has a binding.
@@ -1958,7 +1969,7 @@
   // Is 'VD' declared constant?  If so, retrieve the constant value.
   if (VD->getType().isConstQualified()) {
     if (const Expr *Init = VD->getAnyInitializer()) {
-      if (Optional<SVal> V = svalBuilder.getConstantVal(Init))
+      if (Optional<SVal> V = svalBuilder.getConstantVal(State, Init))
         return *V;
 
       // If the variable is const qualified and has an initializer but
@@ -1979,7 +1990,7 @@
     // If we're in main(), then global initializers have not become stale yet.
     if (B.isMainAnalysis())
       if (const Expr *Init = VD->getAnyInitializer())
-        if (Optional<SVal> V = svalBuilder.getConstantVal(Init))
+        if (Optional<SVal> V = svalBuilder.getConstantVal(State, Init))
           return *V;
 
     // Function-scoped static variables are default-initialized to 0; if they
@@ -2120,8 +2131,9 @@
   return StoreRef(ST, *this);
 }
 
-RegionBindingsRef
-RegionStoreManager::bind(RegionBindingsConstRef B, Loc L, SVal V) {
+RegionBindingsRef RegionStoreManager::bind(ProgramStateRef State,
+                                           RegionBindingsConstRef B, Loc L,
+                                           SVal V) {
   if (L.getAs<loc::ConcreteInt>())
     return B;
 
@@ -2132,11 +2144,11 @@
   if (const TypedValueRegion* TR = dyn_cast<TypedValueRegion>(R)) {
     QualType Ty = TR->getValueType();
     if (Ty->isArrayType())
-      return bindArray(B, TR, V);
+      return bindArray(State, B, TR, V);
     if (Ty->isStructureOrClassType())
-      return bindStruct(B, TR, V);
+      return bindStruct(State, B, TR, V);
     if (Ty->isVectorType())
-      return bindVector(B, TR, V);
+      return bindVector(State, B, TR, V);
     if (Ty->isUnionType())
       return bindAggregate(B, TR, V);
   }
@@ -2186,10 +2198,10 @@
   return B.addBinding(R, BindingKey::Default, V);
 }
 
-RegionBindingsRef
-RegionStoreManager::bindArray(RegionBindingsConstRef B,
-                              const TypedValueRegion* R,
-                              SVal Init) {
+RegionBindingsRef RegionStoreManager::bindArray(ProgramStateRef State,
+                                                RegionBindingsConstRef B,
+                                                const TypedValueRegion *R,
+                                                SVal Init) {
 
   const ArrayType *AT =cast<ArrayType>(Ctx.getCanonicalType(R->getValueType()));
   QualType ElementTy = AT->getElementType();
@@ -2202,7 +2214,7 @@
   // FIXME: It's not responsibility of the Store to transform this lvalue
   // to rvalue. ExprEngine or maybe even CFG should do this before binding.
   if (Optional<loc::MemRegionVal> MRV = Init.getAs<loc::MemRegionVal>()) {
-    SVal V = getBinding(B.asStore(), *MRV, R->getValueType());
+    SVal V = getBinding(State, B.asStore(), *MRV, R->getValueType());
     return bindAggregate(B, R, V);
   }
 
@@ -2229,11 +2241,11 @@
     const ElementRegion *ER = MRMgr.getElementRegion(ElementTy, Idx, R, Ctx);
 
     if (ElementTy->isStructureOrClassType())
-      NewB = bindStruct(NewB, ER, *VI);
+      NewB = bindStruct(State, NewB, ER, *VI);
     else if (ElementTy->isArrayType())
-      NewB = bindArray(NewB, ER, *VI);
+      NewB = bindArray(State, NewB, ER, *VI);
     else
-      NewB = bind(NewB, loc::MemRegionVal(ER), *VI);
+      NewB = bind(State, NewB, loc::MemRegionVal(ER), *VI);
   }
 
   // If the init list is shorter than the array length (or the array has
@@ -2245,8 +2257,9 @@
   return NewB;
 }
 
-RegionBindingsRef RegionStoreManager::bindVector(RegionBindingsConstRef B,
-                                                 const TypedValueRegion* R,
+RegionBindingsRef RegionStoreManager::bindVector(ProgramStateRef State,
+                                                 RegionBindingsConstRef B,
+                                                 const TypedValueRegion *R,
                                                  SVal V) {
   QualType T = R->getValueType();
   const VectorType *VT = T->castAs<VectorType>(); // Use castAs for typedefs.
@@ -2276,20 +2289,18 @@
     const ElementRegion *ER = MRMgr.getElementRegion(ElemType, Idx, R, Ctx);
 
     if (ElemType->isArrayType())
-      NewB = bindArray(NewB, ER, *VI);
+      NewB = bindArray(State, NewB, ER, *VI);
     else if (ElemType->isStructureOrClassType())
-      NewB = bindStruct(NewB, ER, *VI);
+      NewB = bindStruct(State, NewB, ER, *VI);
     else
-      NewB = bind(NewB, loc::MemRegionVal(ER), *VI);
+      NewB = bind(State, NewB, loc::MemRegionVal(ER), *VI);
   }
   return NewB;
 }
 
-Optional<RegionBindingsRef>
-RegionStoreManager::tryBindSmallStruct(RegionBindingsConstRef B,
-                                       const TypedValueRegion *R,
-                                       const RecordDecl *RD,
-                                       nonloc::LazyCompoundVal LCV) {
+Optional<RegionBindingsRef> RegionStoreManager::tryBindSmallStruct(
+    ProgramStateRef State, RegionBindingsConstRef B, const TypedValueRegion *R,
+    const RecordDecl *RD, nonloc::LazyCompoundVal LCV) {
   FieldVector Fields;
 
   if (const CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(RD))
@@ -2316,17 +2327,19 @@
 
   for (FieldVector::iterator I = Fields.begin(), E = Fields.end(); I != E; ++I){
     const FieldRegion *SourceFR = MRMgr.getFieldRegion(*I, LCV.getRegion());
-    SVal V = getBindingForField(getRegionBindings(LCV.getStore()), SourceFR);
+    SVal V =
+        getBindingForField(State, getRegionBindings(LCV.getStore()), SourceFR);
 
     const FieldRegion *DestFR = MRMgr.getFieldRegion(*I, R);
-    NewB = bind(NewB, loc::MemRegionVal(DestFR), V);
+    NewB = bind(State, NewB, loc::MemRegionVal(DestFR), V);
   }
 
   return NewB;
 }
 
-RegionBindingsRef RegionStoreManager::bindStruct(RegionBindingsConstRef B,
-                                                 const TypedValueRegion* R,
+RegionBindingsRef RegionStoreManager::bindStruct(ProgramStateRef State,
+                                                 RegionBindingsConstRef B,
+                                                 const TypedValueRegion *R,
                                                  SVal V) {
   if (!Features.supportsFields())
     return B;
@@ -2343,7 +2356,8 @@
   // Handle lazy compound values and symbolic values.
   if (Optional<nonloc::LazyCompoundVal> LCV =
         V.getAs<nonloc::LazyCompoundVal>()) {
-    if (Optional<RegionBindingsRef> NewB = tryBindSmallStruct(B, R, RD, *LCV))
+    if (Optional<RegionBindingsRef> NewB =
+            tryBindSmallStruct(State, B, R, RD, *LCV))
       return *NewB;
     return bindAggregate(B, R, V);
   }
@@ -2406,7 +2420,7 @@
       const CXXBaseObjectRegion *BR =
           MRMgr.getCXXBaseObjectRegion(BRD, R, /*IsVirtual=*/false);
 
-      NewB = bindStruct(NewB, BR, *VI);
+      NewB = bindStruct(State, NewB, BR, *VI);
 
       ++VI;
     }
@@ -2427,11 +2441,11 @@
     const FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
 
     if (FTy->isArrayType())
-      NewB = bindArray(NewB, FR, *VI);
+      NewB = bindArray(State, NewB, FR, *VI);
     else if (FTy->isStructureOrClassType())
-      NewB = bindStruct(NewB, FR, *VI);
+      NewB = bindStruct(State, NewB, FR, *VI);
     else
-      NewB = bind(NewB, loc::MemRegionVal(FR), *VI);
+      NewB = bind(State, NewB, loc::MemRegionVal(FR), *VI);
     ++VI;
   }
 
@@ -2474,7 +2488,8 @@
 
   // Called by ClusterAnalysis.
   void VisitAddedToCluster(const MemRegion *baseR, const ClusterBindings &C);
-  void VisitCluster(const MemRegion *baseR, const ClusterBindings *C);
+  void VisitCluster(ProgramStateRef State, const MemRegion *baseR,
+                    const ClusterBindings *C);
   using ClusterAnalysis<RemoveDeadBindingsWorker>::VisitCluster;
 
   using ClusterAnalysis::AddToWorkList;
@@ -2526,7 +2541,8 @@
   }
 }
 
-void RemoveDeadBindingsWorker::VisitCluster(const MemRegion *baseR,
+void RemoveDeadBindingsWorker::VisitCluster(ProgramStateRef State,
+                                            const MemRegion *baseR,
                                             const ClusterBindings *C) {
   if (!C)
     return;
@@ -2596,9 +2612,10 @@
   return Changed;
 }
 
-StoreRef RegionStoreManager::removeDeadBindings(Store store,
+StoreRef RegionStoreManager::removeDeadBindings(ProgramStateRef State,
+                                                Store store,
                                                 const StackFrameContext *LCtx,
-                                                SymbolReaper& SymReaper) {
+                                                SymbolReaper &SymReaper) {
   RegionBindingsRef B = getRegionBindings(store);
   RemoveDeadBindingsWorker W(*this, StateMgr, B, SymReaper, LCtx);
   W.GenerateClusters();
@@ -2609,7 +2626,9 @@
     W.AddToWorkList(*I);
   }
 
-  do W.RunWorkList(); while (W.UpdatePostponed());
+  do
+    W.RunWorkList(State);
+  while (W.UpdatePostponed());
 
   // We have now scanned the store, marking reachable regions and symbols
   // as live.  We now remove all the regions that are dead from the store
Index: clang/lib/StaticAnalyzer/Core/ProgramState.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ clang/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -106,8 +106,8 @@
   NewState.Env = EnvMgr.removeDeadBindings(NewState.Env, SymReaper, state);
 
   // Clean up the store.
-  StoreRef newStore = StoreMgr->removeDeadBindings(NewState.getStore(), LCtx,
-                                                   SymReaper);
+  StoreRef newStore =
+      StoreMgr->removeDeadBindings(state, NewState.getStore(), LCtx, SymReaper);
   NewState.setStore(newStore);
   SymReaper.setReapedStore(newStore);
 
@@ -119,8 +119,8 @@
                                       const LocationContext *LCtx,
                                       bool notifyChanges) const {
   ProgramStateManager &Mgr = getStateManager();
-  ProgramStateRef newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(),
-                                                             LV, V));
+  ProgramStateRef newState =
+      makeWithStore(Mgr.StoreMgr->Bind(this, getStore(), LV, V));
   const MemRegion *MR = LV.getAsRegion();
   if (MR && notifyChanges)
     return Mgr.getOwningEngine().processRegionChange(newState, MR, LCtx);
@@ -201,10 +201,9 @@
 
   StoreManager::InvalidatedRegions TopLevelInvalidated;
   StoreManager::InvalidatedRegions Invalidated;
-  const StoreRef &newStore
-  = Mgr.StoreMgr->invalidateRegions(getStore(), Values, E, Count, LCtx, Call,
-                                    *IS, *ITraits, &TopLevelInvalidated,
-                                    &Invalidated);
+  const StoreRef &newStore = Mgr.StoreMgr->invalidateRegions(
+      this, getStore(), Values, E, Count, LCtx, Call, *IS, *ITraits,
+      &TopLevelInvalidated, &Invalidated);
 
   ProgramStateRef newState = makeWithStore(newStore);
 
@@ -235,8 +234,8 @@
 ProgramStateRef
 ProgramState::enterStackFrame(const CallEvent &Call,
                               const StackFrameContext *CalleeCtx) const {
-  const StoreRef &NewStore =
-    getStateManager().StoreMgr->enterStackFrame(getStore(), Call, CalleeCtx);
+  const StoreRef &NewStore = getStateManager().StoreMgr->enterStackFrame(
+      this, getStore(), Call, CalleeCtx);
   return makeWithStore(NewStore);
 }
 
Index: clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -264,7 +264,7 @@
       // (which is of type 'void *') to the correct object type.
       SVal AllocV = state->getSVal(CNE, callerCtx);
       AllocV = svalBuilder.evalCast(
-          AllocV, CNE->getType(),
+          state, AllocV, CNE->getType(),
           getContext().getPointerType(getContext().VoidTy));
 
       state = addObjectUnderConstruction(state, CNE, calleeCtx->getParent(),
Index: clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -917,7 +917,7 @@
   if (FD && FD->isReservedGlobalPlacementOperator()) {
     // Non-array placement new should always return the placement location.
     SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx);
-    Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(),
+    Result = svalBuilder.evalCast(State, PlacementLoc, CNE->getType(),
                                   CNE->getPlacementArg(0)->getType());
   }
 
Index: clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -152,11 +152,11 @@
       QualType LTy = getContext().getCanonicalType(LHS->getType());
 
       // Promote LHS.
-      V = svalBuilder.evalCast(V, CLHSTy, LTy);
+      V = svalBuilder.evalCast(state, V, CLHSTy, LTy);
 
       // Compute the result of the operation.
-      SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy),
-                                         B->getType(), CTy);
+      SVal Result = svalBuilder.evalCast(
+          state, evalBinOp(state, Op, V, RightV, CTy), B->getType(), CTy);
 
       // EXPERIMENTAL: "Conjured" symbols.
       // FIXME: Handle structs.
@@ -170,12 +170,12 @@
         LHSVal = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx, LTy,
                                               currBldrCtx->blockCount());
         // However, we need to convert the symbol to the computation type.
-        Result = svalBuilder.evalCast(LHSVal, CTy, LTy);
+        Result = svalBuilder.evalCast(state, LHSVal, CTy, LTy);
       }
       else {
         // The left-hand side may bind to a different value then the
         // computation type.
-        LHSVal = svalBuilder.evalCast(Result, LTy, CTy);
+        LHSVal = svalBuilder.evalCast(state, Result, LTy, CTy);
       }
 
       // In C++, assignment and compound assignment operators return an
@@ -269,7 +269,7 @@
   }
   // Delegate to SValBuilder to process.
   SVal OrigV = state->getSVal(Ex, LCtx);
-  SVal V = svalBuilder.evalCast(OrigV, T, ExTy);
+  SVal V = svalBuilder.evalCast(state, OrigV, T, ExTy);
   // Negate the result if we're treating the boolean as a signed i1
   if (CastE->getCastKind() == CK_BooleanToSignedIntegral)
     V = evalMinus(V);
@@ -734,9 +734,10 @@
       // known to be false, 1 if the value is known to be true and a new symbol
       // when the assumption is unknown.
       nonloc::ConcreteInt Zero(getBasicVals().getValue(0, B->getType()));
-      X = evalBinOp(N->getState(), BO_NE,
-                    svalBuilder.evalCast(RHSVal, B->getType(), RHS->getType()),
-                    Zero, B->getType());
+      X = evalBinOp(
+          N->getState(), BO_NE,
+          svalBuilder.evalCast(state, RHSVal, B->getType(), RHS->getType()),
+          Zero, B->getType());
     }
   }
   Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getLocationContext(), X));
Index: clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1446,7 +1446,8 @@
         IsTemporary = true;
       }
 
-      Optional<SVal> ConstantVal = svalBuilder.getConstantVal(ArgE);
+      Optional<SVal> ConstantVal =
+          svalBuilder.getConstantVal(Pred->getState(), ArgE);
       if (!ConstantVal)
         ConstantVal = UnknownVal();
 
Index: clang/lib/StaticAnalyzer/Core/Environment.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/Environment.cpp
+++ clang/lib/StaticAnalyzer/Core/Environment.cpp
@@ -83,8 +83,8 @@
   return UnknownVal();
 }
 
-SVal Environment::getSVal(const EnvironmentEntry &Entry,
-                          SValBuilder& svalBuilder) const {
+SVal Environment::getSVal(ProgramStateRef State, const EnvironmentEntry &Entry,
+                          SValBuilder &svalBuilder) const {
   const Stmt *S = Entry.getStmt();
   assert(!isa<ObjCForCollectionStmt>(S) &&
          "Use ExprEngine::hasMoreIteration()!");
@@ -118,12 +118,12 @@
   case Stmt::SizeOfPackExprClass:
   case Stmt::PredefinedExprClass:
     // Known constants; defer to SValBuilder.
-    return svalBuilder.getConstantVal(cast<Expr>(S)).getValue();
+    return svalBuilder.getConstantVal(State, cast<Expr>(S)).getValue();
 
   case Stmt::ReturnStmtClass: {
     const auto *RS = cast<ReturnStmt>(S);
     if (const Expr *RE = RS->getRetValue())
-      return getSVal(EnvironmentEntry(RE, LCtx), svalBuilder);
+      return getSVal(State, EnvironmentEntry(RE, LCtx), svalBuilder);
     return UndefinedVal();
   }
 
Index: clang/lib/StaticAnalyzer/Core/CheckerContext.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/CheckerContext.cpp
+++ clang/lib/StaticAnalyzer/Core/CheckerContext.cpp
@@ -104,7 +104,7 @@
     return false;
   ProgramStateManager &Mgr = State->getStateManager();
   if (!LHSVal.getAs<NonLoc>()) {
-    LHSVal = Mgr.getStoreManager().getBinding(State->getStore(),
+    LHSVal = Mgr.getStoreManager().getBinding(State, State->getStore(),
                                               LHSVal.castAs<Loc>());
     if (LHSVal.isUnknownOrUndef() || !LHSVal.getAs<NonLoc>())
       return false;
Index: clang/lib/StaticAnalyzer/Core/CallEvent.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ clang/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -811,7 +811,7 @@
         const CXXMethodDecl *StaticMD = cast<CXXMethodDecl>(getDecl());
         const CXXRecordDecl *StaticClass = StaticMD->getParent();
         QualType StaticTy = Ctx.getPointerType(Ctx.getRecordType(StaticClass));
-        ThisVal = SVB.evalCast(ThisVal, Ty, StaticTy);
+        ThisVal = SVB.evalCast(getState(), ThisVal, Ty, StaticTy);
       }
     }
 
Index: clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
@@ -112,7 +112,8 @@
     auto SizeD = C.getSVal(SizeE).castAs<DefinedSVal>();
     // Convert the array length to size_t.
     NonLoc IndexLength =
-        SVB.evalCast(SizeD, SizeTy, SizeE->getType()).castAs<NonLoc>();
+        SVB.evalCast(C.getState(), SizeD, SizeTy, SizeE->getType())
+            .castAs<NonLoc>();
     // Multiply the array length by the element size.
     SVal Mul = SVB.evalBinOpNN(State, BO_Mul, ArrSize, IndexLength, SizeTy);
     if (auto MulNonLoc = Mul.getAs<NonLoc>())
Index: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -668,7 +668,7 @@
   SVal OtherV = getArgSVal(Call, OtherArg);
   QualType OtherT = Summary.getArgType(OtherArg);
   // Note: we avoid integral promotion for comparison.
-  OtherV = SVB.evalCast(OtherV, T, OtherT);
+  OtherV = SVB.evalCast(C.getState(), OtherV, T, OtherT);
   if (auto CompV = SVB.evalBinOp(State, Op, V, OtherV, CondT)
                        .getAs<DefinedOrUnknownSVal>())
     State = State->assume(*CompV, true);
Index: clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
@@ -212,7 +212,8 @@
 
   if (Optional<loc::MemRegionVal> X = ArgV.getAs<loc::MemRegionVal>()) {
     StoreManager& SM = C.getStoreManager();
-    SymbolRef sym = SM.getBinding(State->getStore(), *X).getAsLocSymbol();
+    SymbolRef sym =
+        SM.getBinding(State, State->getStore(), *X).getAsLocSymbol();
     if (sym)
       return sym;
   }
Index: clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
@@ -248,7 +248,8 @@
     State = setDynamicTypeAndCastInfo(State, MR, CastFromTy, CastToTy,
                                       CastSucceeds);
 
-  SVal V = CastSucceeds ? C.getSValBuilder().evalCast(DV, CastToTy, CastFromTy)
+  SVal V = CastSucceeds ? C.getSValBuilder().evalCast(C.getState(), DV,
+                                                      CastToTy, CastFromTy)
                         : C.getSValBuilder().makeNull();
   C.addTransition(
       State->BindExpr(Call.getOriginExpr(), C.getLocationContext(), V, false),
Index: clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
@@ -241,14 +241,15 @@
   SmallVector<const FieldDecl *, 10> FieldChain;
 
 private:
+  ProgramStateRef State;
   StoreManager &StoreMgr;
   MemRegionManager &MrMgr;
   Store store;
 
 public:
-  FindUninitializedField(StoreManager &storeMgr, MemRegionManager &mrMgr,
-                         Store s)
-      : StoreMgr(storeMgr), MrMgr(mrMgr), store(s) {}
+  FindUninitializedField(ProgramStateRef State, StoreManager &storeMgr,
+                         MemRegionManager &mrMgr, Store s)
+      : State(State), StoreMgr(storeMgr), MrMgr(mrMgr), store(s) {}
 
   bool Find(const TypedValueRegion *R) {
     QualType T = R->getValueType();
@@ -263,7 +264,8 @@
           if (Find(FR))
             return true;
         } else {
-          const SVal &V = StoreMgr.getBinding(store, loc::MemRegionVal(FR));
+          const SVal &V =
+              StoreMgr.getBinding(State, store, loc::MemRegionVal(FR));
           if (V.isUndef())
             return true;
         }
@@ -318,9 +320,9 @@
 
   if (auto LV = V.getAs<nonloc::LazyCompoundVal>()) {
     const LazyCompoundValData *D = LV->getCVData();
-    FindUninitializedField F(C.getState()->getStateManager().getStoreManager(),
-                             C.getSValBuilder().getRegionManager(),
-                             D->getStore());
+    FindUninitializedField F(
+        C.getState(), C.getState()->getStateManager().getStoreManager(),
+        C.getSValBuilder().getRegionManager(), D->getStore());
 
     if (F.Find(D->getRegion())) {
       if (!ChecksEnabled[CK_ArgInitializedness]) {
Index: clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -413,8 +413,8 @@
   NonLoc LastOffset = Offset.castAs<NonLoc>();
 
   // Check that the first buffer is sufficiently long.
-  SVal BufStart =
-      svalBuilder.evalCast(BufVal, PtrTy, Buffer.Expression->getType());
+  SVal BufStart = svalBuilder.evalCast(C.getState(), BufVal, PtrTy,
+                                       Buffer.Expression->getType());
   if (Optional<Loc> BufLoc = BufStart.getAs<Loc>()) {
 
     SVal BufEnd =
@@ -509,8 +509,8 @@
   // Bail out if the cast fails.
   ASTContext &Ctx = svalBuilder.getContext();
   QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
-  SVal FirstStart =
-      svalBuilder.evalCast(*firstLoc, CharPtrTy, First.Expression->getType());
+  SVal FirstStart = svalBuilder.evalCast(C.getState(), *firstLoc, CharPtrTy,
+                                         First.Expression->getType());
   Optional<Loc> FirstStartLoc = FirstStart.getAs<Loc>();
   if (!FirstStartLoc)
     return state;
@@ -899,7 +899,8 @@
   NonLoc LastOffset = Offset.castAs<NonLoc>();
 
   // Check that the first buffer is sufficiently long.
-  SVal BufStart = svalBuilder.evalCast(BufVal, PtrTy, FirstBuf->getType());
+  SVal BufStart =
+      svalBuilder.evalCast(C.getState(), BufVal, PtrTy, FirstBuf->getType());
   Optional<Loc> BufLoc = BufStart.getAs<Loc>();
   if (!BufLoc)
     return true; // cf top comment.
@@ -1068,7 +1069,8 @@
 
     // With the semantic of 'memset()', we should convert the CharVal to
     // unsigned char.
-    CharVal = svalBuilder.evalCast(CharVal, Ctx.UnsignedCharTy, Ctx.IntTy);
+    CharVal = svalBuilder.evalCast(C.getState(), CharVal, Ctx.UnsignedCharTy,
+                                   Ctx.IntTy);
 
     ProgramStateRef StateNullChar, StateNonNullChar;
     std::tie(StateNullChar, StateNonNullChar) =
@@ -1186,8 +1188,8 @@
       SValBuilder &SvalBuilder = C.getSValBuilder();
       ASTContext &Ctx = SvalBuilder.getContext();
       QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
-      SVal DestRegCharVal =
-          SvalBuilder.evalCast(destVal, CharPtrTy, Dest.Expression->getType());
+      SVal DestRegCharVal = SvalBuilder.evalCast(
+          C.getState(), destVal, CharPtrTy, Dest.Expression->getType());
       SVal lastElement = C.getSValBuilder().evalBinOp(
           state, BO_Add, DestRegCharVal, sizeVal, Dest.Expression->getType());
       // If we don't know how much we copied, we can at least
@@ -1601,8 +1603,8 @@
     SVal lenVal = state->getSVal(lenExpr.Expression, LCtx);
 
     // Protect against misdeclared strncpy().
-    lenVal =
-        svalBuilder.evalCast(lenVal, sizeTy, lenExpr.Expression->getType());
+    lenVal = svalBuilder.evalCast(C.getState(), lenVal, sizeTy,
+                                  lenExpr.Expression->getType());
 
     Optional<NonLoc> lenValNL = lenVal.getAs<NonLoc>();
 
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -71,7 +71,8 @@
   ///   expected type of the returned value.  This is used if the value is
   ///   lazily computed.
   /// \return The value bound to the location \c loc.
-  virtual SVal getBinding(Store store, Loc loc, QualType T = QualType()) = 0;
+  virtual SVal getBinding(ProgramStateRef State, Store store, Loc loc,
+                          QualType T = QualType()) = 0;
 
   /// Return the default value bound to a region in a given store. The default
   /// binding is the value of sub-regions that were not initialized separately
@@ -104,7 +105,8 @@
   /// \return A StoreRef object that contains the same
   ///   bindings as \c store with the addition of having the value specified
   ///   by \c val bound to the location given for \c loc.
-  virtual StoreRef Bind(Store store, Loc loc, SVal val) = 0;
+  virtual StoreRef Bind(ProgramStateRef State, Store store, Loc loc,
+                        SVal val) = 0;
 
   /// Return a store with the specified value bound to all sub-regions of the
   /// region. The region must not have previous bindings. If you need to
@@ -146,7 +148,8 @@
     return getLValueFieldOrIvar(D, Base);
   }
 
-  virtual SVal getLValueElement(QualType elementType, NonLoc offset, SVal Base);
+  virtual SVal getLValueElement(ProgramStateRef State, QualType elementType,
+                                NonLoc offset, SVal Base);
 
   /// ArrayToPointer - Used by ExprEngine::VistCast to handle implicit
   ///  conversions between arrays and pointers.
@@ -183,7 +186,8 @@
   ///  casted and 'CastToTy' the result type of the cast.
   const MemRegion *castRegion(const MemRegion *region, QualType CastToTy);
 
-  virtual StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx,
+  virtual StoreRef removeDeadBindings(ProgramStateRef State, Store store,
+                                      const StackFrameContext *LCtx,
                                       SymbolReaper &SymReaper) = 0;
 
   virtual bool includedInBindings(Store store,
@@ -223,19 +227,17 @@
   ///   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,
-                                  const Expr *E, unsigned Count,
-                                  const LocationContext *LCtx,
-                                  const CallEvent *Call,
-                                  InvalidatedSymbols &IS,
-                                  RegionAndSymbolInvalidationTraits &ITraits,
-                                  InvalidatedRegions *InvalidatedTopLevel,
-                                  InvalidatedRegions *Invalidated) = 0;
+  virtual StoreRef
+  invalidateRegions(ProgramStateRef State, Store store, ArrayRef<SVal> Values,
+                    const Expr *E, unsigned Count, const LocationContext *LCtx,
+                    const CallEvent *Call, InvalidatedSymbols &IS,
+                    RegionAndSymbolInvalidationTraits &ITraits,
+                    InvalidatedRegions *InvalidatedTopLevel,
+                    InvalidatedRegions *Invalidated) = 0;
 
   /// enterStackFrame - Let the StoreManager to do something when execution
   /// engine is about to execute into a callee.
-  StoreRef enterStackFrame(Store store,
+  StoreRef enterStackFrame(ProgramStateRef State, Store store,
                            const CallEvent &Call,
                            const StackFrameContext *CalleeCtx);
 
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -72,27 +72,32 @@
   /// The width of the scalar type used for array indices.
   const unsigned ArrayIndexWidth;
 
-  SVal evalCastKind(UndefinedVal V, QualType CastTy, QualType OriginalTy);
-  SVal evalCastKind(UnknownVal V, QualType CastTy, QualType OriginalTy);
-  SVal evalCastKind(Loc V, QualType CastTy, QualType OriginalTy);
-  SVal evalCastKind(NonLoc V, QualType CastTy, QualType OriginalTy);
-  SVal evalCastSubKind(loc::ConcreteInt V, QualType CastTy,
-                       QualType OriginalTy);
-  SVal evalCastSubKind(loc::GotoLabel V, QualType CastTy, QualType OriginalTy);
-  SVal evalCastSubKind(loc::MemRegionVal V, QualType CastTy,
-                       QualType OriginalTy);
-  SVal evalCastSubKind(nonloc::CompoundVal V, QualType CastTy,
-                       QualType OriginalTy);
-  SVal evalCastSubKind(nonloc::ConcreteInt V, QualType CastTy,
-                       QualType OriginalTy);
-  SVal evalCastSubKind(nonloc::LazyCompoundVal V, QualType CastTy,
-                       QualType OriginalTy);
-  SVal evalCastSubKind(nonloc::LocAsInteger V, QualType CastTy,
-                       QualType OriginalTy);
-  SVal evalCastSubKind(nonloc::SymbolVal V, QualType CastTy,
-                       QualType OriginalTy);
-  SVal evalCastSubKind(nonloc::PointerToMember V, QualType CastTy,
+  SVal evalCastKind(ProgramStateRef State, UndefinedVal V, QualType CastTy,
+                    QualType OriginalTy);
+  SVal evalCastKind(ProgramStateRef State, UnknownVal V, QualType CastTy,
+                    QualType OriginalTy);
+  SVal evalCastKind(ProgramStateRef State, Loc V, QualType CastTy,
+                    QualType OriginalTy);
+  SVal evalCastKind(ProgramStateRef State, NonLoc V, QualType CastTy,
+                    QualType OriginalTy);
+  SVal evalCastSubKind(ProgramStateRef State, loc::ConcreteInt V,
+                       QualType CastTy, QualType OriginalTy);
+  SVal evalCastSubKind(ProgramStateRef State, loc::GotoLabel V, QualType CastTy,
                        QualType OriginalTy);
+  SVal evalCastSubKind(ProgramStateRef State, loc::MemRegionVal V,
+                       QualType CastTy, QualType OriginalTy);
+  SVal evalCastSubKind(ProgramStateRef State, nonloc::CompoundVal V,
+                       QualType CastTy, QualType OriginalTy);
+  SVal evalCastSubKind(ProgramStateRef State, nonloc::ConcreteInt V,
+                       QualType CastTy, QualType OriginalTy);
+  SVal evalCastSubKind(ProgramStateRef State, nonloc::LazyCompoundVal V,
+                       QualType CastTy, QualType OriginalTy);
+  SVal evalCastSubKind(ProgramStateRef State, nonloc::LocAsInteger V,
+                       QualType CastTy, QualType OriginalTy);
+  SVal evalCastSubKind(ProgramStateRef State, nonloc::SymbolVal V,
+                       QualType CastTy, QualType OriginalTy);
+  SVal evalCastSubKind(ProgramStateRef State, nonloc::PointerToMember V,
+                       QualType CastTy, QualType OriginalTy);
 
 public:
   SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context,
@@ -116,7 +121,8 @@
              Ty2->isIntegralOrEnumerationType()));
   }
 
-  SVal evalCast(SVal V, QualType CastTy, QualType OriginalTy = QualType{});
+  SVal evalCast(ProgramStateRef State, SVal V, QualType CastTy,
+                QualType OriginalTy = QualType{});
 
   // Handles casts of type CK_IntegralCast.
   SVal evalIntegralCast(ProgramStateRef state, SVal val, QualType castTy,
@@ -259,7 +265,7 @@
   /// manner.
   ///
   /// If \p E is not a constant or cannot be modeled, returns \c None.
-  Optional<SVal> getConstantVal(const Expr *E);
+  Optional<SVal> getConstantVal(ProgramStateRef State, const Expr *E);
 
   NonLoc makeCompoundVal(QualType type, llvm::ImmutableList<SVal> vals) {
     return nonloc::CompoundVal(BasicVals.getCompoundValData(type, vals));
@@ -287,7 +293,7 @@
     return nonloc::ConcreteInt(BasicVals.getValue(idx, ArrayIndexTy));
   }
 
-  SVal convertToArrayIndex(SVal val);
+  SVal convertToArrayIndex(ProgramStateRef State, SVal val);
 
   nonloc::ConcreteInt makeIntVal(const IntegerLiteral* integer) {
     return nonloc::ConcreteInt(
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -756,15 +756,17 @@
   return Base;
 }
 
-inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{
+inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx,
+                                    SVal Base) const {
   if (Optional<NonLoc> N = Idx.getAs<NonLoc>())
-    return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base);
+    return getStateManager().StoreMgr->getLValueElement(this, ElementType, *N,
+                                                        Base);
   return UnknownVal();
 }
 
 inline SVal ProgramState::getSVal(const Stmt *Ex,
                                   const LocationContext *LCtx) const{
-  return Env.getSVal(EnvironmentEntry(Ex, LCtx),
+  return Env.getSVal(this, EnvironmentEntry(Ex, LCtx),
                      *getStateManager().svalBuilder);
 }
 
@@ -782,13 +784,12 @@
 }
 
 inline SVal ProgramState::getRawSVal(Loc LV, QualType T) const {
-  return getStateManager().StoreMgr->getBinding(getStore(), LV, T);
+  return getStateManager().StoreMgr->getBinding(this, getStore(), LV, T);
 }
 
 inline SVal ProgramState::getSVal(const MemRegion* R, QualType T) const {
-  return getStateManager().StoreMgr->getBinding(getStore(),
-                                                loc::MemRegionVal(R),
-                                                T);
+  return getStateManager().StoreMgr->getBinding(this, getStore(),
+                                                loc::MemRegionVal(R), T);
 }
 
 inline BasicValueFactory &ProgramState::getBasicVals() const {
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
@@ -73,7 +73,8 @@
 
   /// Fetches the current binding of the expression in the
   /// Environment.
-  SVal getSVal(const EnvironmentEntry &E, SValBuilder &svalBuilder) const;
+  SVal getSVal(ProgramStateRef State, const EnvironmentEntry &E,
+               SValBuilder &svalBuilder) const;
 
   /// Profile - Profile the contents of an Environment object for use
   ///  in a FoldingSet.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to