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. 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 N = Idx.getAs()) - 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/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 getConstantVal(const Expr *E); + Optional getConstantVal(ProgramStateRef State, const Expr *E); NonLoc makeCompoundVal(QualType type, llvm::ImmutableList 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/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 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 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/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(); // 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 BufLoc = BufStart.getAs()) { 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 FirstStartLoc = FirstStart.getAs(); if (!FirstStartLoc) return state; @@ -899,7 +899,8 @@ NonLoc LastOffset = Offset.castAs(); // 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 BufLoc = BufStart.getAs(); 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 lenValNL = lenVal.getAs(); Index: clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -241,14 +241,15 @@ SmallVector 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()) { 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/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/MacOSKeychainAPIChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp @@ -212,7 +212,8 @@ if (Optional X = ArgV.getAs()) { 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/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()) State = State->assume(*CompV, true); 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(); // Convert the array length to size_t. NonLoc IndexLength = - SVB.evalCast(SizeD, SizeTy, SizeE->getType()).castAs(); + SVB.evalCast(C.getState(), SizeD, SizeTy, SizeE->getType()) + .castAs(); // Multiply the array length by the element size. SVal Mul = SVB.evalBinOpNN(State, BO_Mul, ArrSize, IndexLength, SizeTy); if (auto MulNonLoc = Mul.getAs()) 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(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/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()) { - LHSVal = Mgr.getStoreManager().getBinding(State->getStore(), + LHSVal = Mgr.getStoreManager().getBinding(State, State->getStore(), LHSVal.castAs()); if (LHSVal.isUnknownOrUndef() || !LHSVal.getAs()) return false; 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(S) && "Use ExprEngine::hasMoreIteration()!"); @@ -118,12 +118,12 @@ case Stmt::SizeOfPackExprClass: case Stmt::PredefinedExprClass: // Known constants; defer to SValBuilder. - return svalBuilder.getConstantVal(cast(S)).getValue(); + return svalBuilder.getConstantVal(State, cast(S)).getValue(); case Stmt::ReturnStmtClass: { const auto *RS = cast(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/ExprEngine.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1447,7 +1447,8 @@ IsTemporary = true; } - Optional ConstantVal = svalBuilder.getConstantVal(ArgE); + Optional ConstantVal = + svalBuilder.getConstantVal(Pred->getState(), ArgE); if (!ConstantVal) ConstantVal = UnknownVal(); 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/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/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/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/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 Values, - const Expr *E, unsigned Count, - const LocationContext *LCtx, - const CallEvent *Call, - InvalidatedSymbols &IS, + StoreRef invalidateRegions(ProgramStateRef State, Store store, + ArrayRef 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 tryBindSmallStruct(RegionBindingsConstRef B, + Optional 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 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(this)->AddToWorkList(R); } - void RunWorkList() { + void RunWorkList(ProgramStateRef State) { while (!WL.empty()) { WorkListElement E = WL.pop_back_val(); const MemRegion *BaseR = E; - static_cast(this)->VisitCluster(BaseR, getCluster(BaseR)); + static_cast(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(this)->VisitCluster(BaseR, C); + void VisitCluster(ProgramStateRef State, const MemRegion *BaseR, + const ClusterBindings *C, bool Flag) { + static_cast(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 L = V.getAs()) { if (const MemRegion *LR = L->getAsRegion()) AddToWorkList(LR); @@ -1323,16 +1332,11 @@ } } -StoreRef -RegionStoreManager::invalidateRegions(Store store, - ArrayRef 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 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() && "location unknown"); assert(!L.getAs() && "location undefined"); @@ -1479,7 +1485,7 @@ return UnknownVal(); if (const FieldRegion* FR = dyn_cast(R)) - return svalBuilder.evalCast(getBindingForField(B, FR), T); + return svalBuilder.evalCast(State, getBindingForField(State, B, FR), T); if (const ElementRegion* ER = dyn_cast(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(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(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 &V = B.getDirectBinding(R)) return *V; @@ -1684,7 +1691,8 @@ return svalBuilder.makeZeroVal(R->getElementType()); if (const Expr *ElemInit = InitList->getInit(i)) - if (Optional V = svalBuilder.getConstantVal(ElemInit)) + if (Optional 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 &V = B.getDirectBinding(R)) @@ -1744,7 +1753,7 @@ QualType Ty = FD->getType(); if (Ty.isConstQualified()) if (const Expr *Init = FD->getInClassInitializer()) - if (Optional V = svalBuilder.getConstantVal(Init)) + if (Optional 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(Init)) { if (Index < InitList->getNumInits()) { if (const Expr *FieldInit = InitList->getInit(Index)) - if (Optional V = svalBuilder.getConstantVal(FieldInit)) + if (Optional 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 @@ -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(LazyBindingRegion)) - Result = getBindingForElement(LazyBinding, ER); + Result = getBindingForElement(State, LazyBinding, ER); else - Result = getBindingForField(LazyBinding, + Result = getBindingForField(State, LazyBinding, cast(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 V = svalBuilder.getConstantVal(Init)) + if (Optional 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 V = svalBuilder.getConstantVal(Init)) + if (Optional 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()) return B; @@ -2132,11 +2144,11 @@ if (const TypedValueRegion* TR = dyn_cast(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(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 MRV = Init.getAs()) { - 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(); // 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 -RegionStoreManager::tryBindSmallStruct(RegionBindingsConstRef B, - const TypedValueRegion *R, - const RecordDecl *RD, - nonloc::LazyCompoundVal LCV) { +Optional RegionStoreManager::tryBindSmallStruct( + ProgramStateRef State, RegionBindingsConstRef B, const TypedValueRegion *R, + const RecordDecl *RD, nonloc::LazyCompoundVal LCV) { FieldVector Fields; if (const CXXRecordDecl *Class = dyn_cast(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 LCV = V.getAs()) { - if (Optional NewB = tryBindSmallStruct(B, R, RD, *LCV)) + if (Optional 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::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/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 SValBuilder::getConstantVal(const Expr *E) { +Optional 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 Val = getConstantVal(SE); + Optional 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,65 +565,73 @@ default: llvm_unreachable("Unknown SVal kind"); case SVal::UndefinedValKind: - return evalCastKind(V.castAs(), CastTy, OriginalTy); + return evalCastKind(State, V.castAs(), CastTy, OriginalTy); case SVal::UnknownValKind: - return evalCastKind(V.castAs(), CastTy, OriginalTy); + return evalCastKind(State, V.castAs(), CastTy, OriginalTy); case SVal::LocKind: - return evalCastKind(V.castAs(), CastTy, OriginalTy); + return evalCastKind(State, V.castAs(), CastTy, OriginalTy); case SVal::NonLocKind: - return evalCastKind(V.castAs(), CastTy, OriginalTy); + return evalCastKind(State, V.castAs(), CastTy, OriginalTy); } llvm_unreachable("Unknown SVal kind"); } -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(), CastTy, OriginalTy); + return evalCastSubKind(State, V.castAs(), CastTy, + OriginalTy); case loc::GotoLabelKind: - return evalCastSubKind(V.castAs(), CastTy, OriginalTy); + return evalCastSubKind(State, V.castAs(), CastTy, + OriginalTy); case loc::MemRegionValKind: - return evalCastSubKind(V.castAs(), CastTy, OriginalTy); + return evalCastSubKind(State, V.castAs(), 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(), CastTy, OriginalTy); + return evalCastSubKind(State, V.castAs(), CastTy, + OriginalTy); case nonloc::ConcreteIntKind: - return evalCastSubKind(V.castAs(), CastTy, OriginalTy); + return evalCastSubKind(State, V.castAs(), CastTy, + OriginalTy); case nonloc::LazyCompoundValKind: - return evalCastSubKind(V.castAs(), CastTy, + return evalCastSubKind(State, V.castAs(), CastTy, OriginalTy); case nonloc::LocAsIntegerKind: - return evalCastSubKind(V.castAs(), CastTy, + return evalCastSubKind(State, V.castAs(), CastTy, OriginalTy); case nonloc::SymbolValKind: - return evalCastSubKind(V.castAs(), CastTy, OriginalTy); + return evalCastSubKind(State, V.castAs(), CastTy, + OriginalTy); case nonloc::PointerToMemberKind: - return evalCastSubKind(V.castAs(), CastTy, + return evalCastSubKind(State, V.castAs(), 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); @@ -642,8 +651,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. @@ -675,8 +684,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(); @@ -797,14 +806,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); @@ -827,20 +836,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()) { @@ -854,7 +863,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() || @@ -868,7 +877,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; } @@ -894,8 +903,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. @@ -929,7 +938,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/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(); + Cond = SVB.evalCast(State, *LV, SVB.getContext().BoolTy, T) + .castAs(); } return assume(State, Cond.castAs(), Assumption); 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 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 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().evalBinOp(BasicVals, op, *rInt); if (Optional Result = ResultVal.getAs()) - return evalCast(*Result, resultTy); + return evalCast(state, *Result, resultTy); assert(!ResultVal.getAs() && "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 l = evalCast(state, lhs, boolType).castAs(); NonLoc r = makeTruthVal(false, boolType).castAs(); return evalBinOpNN(state, op, l, r, resultTy); } @@ -901,7 +902,7 @@ Optional LeftIndex = LeftIndexVal.getAs(); if (!LeftIndex) return UnknownVal(); - LeftIndexVal = evalCast(*LeftIndex, ArrayIndexTy); + LeftIndexVal = evalCast(state, *LeftIndex, ArrayIndexTy); LeftIndex = LeftIndexVal.getAs(); if (!LeftIndex) return UnknownVal(); @@ -911,7 +912,7 @@ Optional RightIndex = RightIndexVal.getAs(); if (!RightIndex) return UnknownVal(); - RightIndexVal = evalCast(*RightIndex, ArrayIndexTy); + RightIndexVal = evalCast(state, *RightIndex, ArrayIndexTy); RightIndex = RightIndexVal.getAs(); 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(); + rhs = convertToArrayIndex(state, rhs).castAs(); 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/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(), I.second); + Store = Bind(State, Store.getStore(), I.first.castAs(), 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(BaseRegion); // Convert the offset to the appropriate size and signedness. - Offset = svalBuilder.convertToArrayIndex(Offset).castAs(); + Offset = svalBuilder.convertToArrayIndex(State, Offset).castAs(); if (!ElemR) { // If the base region is not an ElementRegion, create one. Index: clang/unittests/StaticAnalyzer/StoreTest.cpp =================================================================== --- clang/unittests/StaticAnalyzer/StoreTest.cpp +++ clang/unittests/StaticAnalyzer/StoreTest.cpp @@ -69,13 +69,13 @@ SVal NarrowZero = Builder.makeZeroVal(ASTCtxt.CharTy); // Bind(Zero) - Store StX0 = SManager.Bind(StInit, LX0, Zero).getStore(); - EXPECT_EQ(Zero, SManager.getBinding(StX0, LX0, ASTCtxt.IntTy)); + Store StX0 = SManager.Bind(nullptr, StInit, LX0, Zero).getStore(); + EXPECT_EQ(Zero, SManager.getBinding(nullptr, StX0, LX0, ASTCtxt.IntTy)); // BindDefaultInitial(Zero) Store StY0 = SManager.BindDefaultInitial(StInit, LY0.getAsRegion(), Zero).getStore(); - EXPECT_EQ(Zero, SManager.getBinding(StY0, LY0, ASTCtxt.IntTy)); + EXPECT_EQ(Zero, SManager.getBinding(nullptr, StY0, LY0, ASTCtxt.IntTy)); EXPECT_EQ(Zero, *SManager.getDefaultBinding(StY0, LY0.getAsRegion())); // BindDefaultZero() @@ -83,17 +83,17 @@ // BindDefaultZero wipes the region with '0 S8b', not with out Zero. // Direct load, however, does give us back the object of the type // that we specify for loading. - EXPECT_EQ(Zero, SManager.getBinding(StZ0, LZ0, ASTCtxt.IntTy)); + EXPECT_EQ(Zero, SManager.getBinding(nullptr, StZ0, LZ0, ASTCtxt.IntTy)); EXPECT_EQ(NarrowZero, *SManager.getDefaultBinding(StZ0, LZ0.getAsRegion())); // Bind(One) - Store StX1 = SManager.Bind(StInit, LX1, One).getStore(); - EXPECT_EQ(One, SManager.getBinding(StX1, LX1, ASTCtxt.IntTy)); + Store StX1 = SManager.Bind(nullptr, StInit, LX1, One).getStore(); + EXPECT_EQ(One, SManager.getBinding(nullptr, StX1, LX1, ASTCtxt.IntTy)); // BindDefaultInitial(One) Store StY1 = SManager.BindDefaultInitial(StInit, LY1.getAsRegion(), One).getStore(); - EXPECT_EQ(One, SManager.getBinding(StY1, LY1, ASTCtxt.IntTy)); + EXPECT_EQ(One, SManager.getBinding(nullptr, StY1, LY1, ASTCtxt.IntTy)); EXPECT_EQ(One, *SManager.getDefaultBinding(StY1, LY1.getAsRegion())); } @@ -134,10 +134,10 @@ Store StInit = SManager.getInitialStore(SFC).getStore(); // Let's bind constant 1 to 'test[0]' SVal One = Builder.makeIntVal(1, Int); - Store StX = SManager.Bind(StInit, ZeroElement, One).getStore(); + Store StX = SManager.Bind(nullptr, StInit, ZeroElement, One).getStore(); // And make sure that we can read this binding back as it was - EXPECT_EQ(One, SManager.getBinding(StX, ZeroElement, Int)); + EXPECT_EQ(One, SManager.getBinding(nullptr, StX, ZeroElement, Int)); } public: