20#include "llvm/Support/raw_ostream.h"
35 assert(state->refCount > 0);
37 if (--
s->refCount == 0) {
39 Mgr.StateSet.RemoveNode(
s);
41 Mgr.freeStates.push_back(
s);
53 stateMgr->getStoreManager().incrementReferenceCount(store);
57 : stateMgr(RHS.stateMgr), Env(RHS.Env), store(RHS.store), GDM(RHS.GDM),
58 PosteriorlyOverconstrained(RHS.PosteriorlyOverconstrained), refCount(0) {
59 stateMgr->getStoreManager().incrementReferenceCount(store);
64 stateMgr->getStoreManager().decrementReferenceCount(store);
74 llvm::BumpPtrAllocator &alloc,
76 : Eng(ExprEng), EnvMgr(alloc), GDMFactory(alloc),
79 StoreMgr = (*CreateSMgr)(*this);
80 ConstraintMgr = (*CreateCMgr)(*
this, ExprEng);
85 for (GDMContextsTy::iterator I=GDMContexts.begin(), E=GDMContexts.end();
87 I->second.second(I->second.first);
102 NewState.Env = EnvMgr.removeDeadBindings(NewState.Env, SymReaper, state);
107 NewState.setStore(newStore);
116 bool notifyChanges)
const {
122 if (MR && notifyChanges)
165 const LocationContext *LCtx,
bool CausedByPointerEscape,
174 IS = &InvalidatedSyms;
176 RegionAndSymbolInvalidationTraits ITraitsLocal;
178 ITraits = &ITraitsLocal;
182 const StoreRef &NewStore = Mgr.StoreMgr->invalidateRegions(
183 getStore(), Values, Elem, Count, LCtx,
Call, *IS, *ITraits,
184 &TopLevelInvalidated, &Invalidated);
188 if (CausedByPointerEscape) {
190 NewState, IS, TopLevelInvalidated,
Call, *ITraits);
194 Invalidated, LCtx,
Call);
202 if (newStore.
getStore() == OldStore)
205 return makeWithStore(newStore);
211SVal ProgramState::desugarReference(
SVal Val)
const {
212 const auto *TyReg = dyn_cast_or_null<TypedValueRegion>(Val.
getAsRegion());
213 if (!TyReg || !TyReg->getValueType()->isReferenceType())
222SVal ProgramState::wrapSymbolicRegion(
SVal Val)
const {
223 const auto *BaseReg = dyn_cast_or_null<SymbolicRegion>(Val.
getAsRegion());
228 QualType ElemTy = BaseReg->getPointeeStaticType();
235 return makeWithStore(
250 if (!R->isBoundable())
271 if (!T.isNull() && (T->isIntegralOrEnumerationType() ||
Loc::isLocType(T))) {
275 .getSymVal(
this, sym)) {
303 bool Invalidate)
const {
310 NewSt.Env = std::move(NewEnv);
314[[nodiscard]] std::pair<ProgramStateRef, ProgramStateRef>
363 std::pair<ProgramStateRef, ProgramStateRef> R =
365 return Assumption ? R.first : R.second;
370 if (
IsNull.isUnderconstrained())
376 return stateMgr->getSValBuilder().areEqual(
this, Lhs, Rhs);
380 if (
V.isZeroConstant())
395 EnvMgr.getInitialEnvironment(),
396 StoreMgr->getInitialStore(InitLoc),
397 GDMFactory.getEmptyMap());
406 NewState.GDM = GDMState->GDM;
412 llvm::FoldingSetNodeID ID;
416 if (
ProgramState *I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
420 if (!freeStates.empty()) {
421 newState = freeStates.back();
422 freeStates.pop_back();
428 StateSet.InsertNode(newState, InsertPos);
434 NewSt.setStore(store);
450ProgramStateRef ProgramState::cloneAsPosteriorlyOverconstrained()
const {
452 NewSt.PosteriorlyOverconstrained =
true;
456void ProgramState::setStore(
const StoreRef &newStore) {
459 stateMgr->getStoreManager().incrementReferenceCount(newStoreStore);
461 stateMgr->getStoreManager().decrementReferenceCount(store);
462 store = newStoreStore;
479 for (
const auto *I : D->
chain()) {
490 const char *NL,
unsigned int Space,
492 Indent(Out, Space, IsDot) <<
"\"program_state\": {" << NL;
501 Env.printJson(Out, Mgr.
getContext(), LCtx, NL, Space, IsDot);
513 Indent(Out, Space, IsDot) <<
'}';
517 unsigned int Space)
const {
518 printJson(Out, LCtx,
"\\l", Space,
true);
526 return stateMgr->getOwningEngine().getAnalysisManager();
534 return GDM.lookup(K);
538 const void *K,
void *(*CreateContext)(llvm::BumpPtrAllocator &),
539 void (*DeleteContext)(
void *)) {
541 std::pair<
void*, void (*)(
void*)>& p = GDMContexts[K];
543 p.first = CreateContext(Alloc);
544 p.second = DeleteContext;
577 bool wasVisited = !visited.insert(val.
getCVData()).second;
581 StoreManager &StoreMgr = state->getStateManager().getStoreManager();
599 bool wasVisited = !visited.insert(SubSym).second;
603 if (!visitor.VisitSymbol(SubSym))
612 return scan(
X->getRegion());
614 if (std::optional<nonloc::LazyCompoundVal>
X =
619 return scan(
X->getLoc());
634 bool wasVisited = !visited.insert(R).second;
638 if (!visitor.VisitMemRegion(R))
643 if (!visitor.VisitSymbol(SR->getSymbol()))
647 if (
const SubRegion *SR = dyn_cast<SubRegion>(R)) {
648 const MemRegion *Super = SR->getSuperRegion();
654 StoreManager &StoreMgr = state->getStateManager().getStoreManager();
662 for (
auto Var : BDR->referenced_vars()) {
663 if (!
scan(Var.getCapturedRegion()))
677 llvm::iterator_range<region_iterator> Reachable,
ArrayRef< const MemRegion * > RegionList
ArrayRef< SVal > ValueList
__device__ __2f16 float __ockl_bool s
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
This represents one expression.
Represents a member of a struct/union/class.
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
const ImplicitParamDecl * getSelfDecl() const
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
It represents a stack frame of the call stack (based on CallEvent).
A safe wrapper around APSInt objects allocated and owned by BasicValueFactory.
APSIntPtr getMinValue(const llvm::APSInt &v)
APSIntPtr Convert(const llvm::APSInt &To, const llvm::APSInt &From)
Convert - Create a new persistent APSInt with the same value as 'From' but with the bitwidth and sign...
BlockDataRegion - A region that represents a block instance.
Manages the lifetime of CallEvent objects.
Represents an abstract call to a function or method along a particular path.
ProgramStatePair assumeDual(ProgramStateRef State, DefinedSVal Cond)
Returns a pair of states (StTrue, StFalse) where the given condition is assumed to be true or false,...
virtual void printJson(raw_ostream &Out, ProgramStateRef State, const char *NL, unsigned int Space, bool IsDot) const =0
An entry in the environment consists of a Stmt and an LocationContext.
Environment bindExpr(Environment Env, const EnvironmentEntry &E, SVal V, bool Invalidate)
Bind a symbolic value to the given environment entry.
An immutable map from EnvironmentEntries to SVals.
ProgramStateRef processRegionChange(ProgramStateRef state, const MemRegion *MR, const LocationContext *LCtx)
void printJson(raw_ostream &Out, ProgramStateRef State, const LocationContext *LCtx, const char *NL, unsigned int Space, bool IsDot) const
printJson - Called by ProgramStateManager to print checker-specific data.
ProgramStateRef processRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const LocationContext *LCtx, const CallEvent *Call)
processRegionChanges - Called by ProgramStateManager whenever a change is made to the store.
ProgramStateRef notifyCheckersOfPointerEscape(ProgramStateRef State, const InvalidatedSymbols *Invalidated, ArrayRef< const MemRegion * > ExplicitRegions, const CallEvent *Call, RegionAndSymbolInvalidationTraits &ITraits)
Call PointerEscape callback when a value escapes as a result of region invalidation.
ProgramStateRef escapeValues(ProgramStateRef State, ArrayRef< SVal > Vs, PointerEscapeKind K, const CallEvent *Call=nullptr) const
A simple wrapper when you only need to notify checkers of pointer-escape of some values.
static bool isLocType(QualType T)
MemRegion - The root abstract class for all memory regions.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getBaseRegion() const
ProgramStateRef removeDeadBindingsFromEnvironmentAndStore(ProgramStateRef St, const StackFrameContext *LCtx, SymbolReaper &SymReaper)
ExprEngine & getOwningEngine()
void * FindGDMContext(const void *index, void *(*CreateContext)(llvm::BumpPtrAllocator &), void(*DeleteContext)(void *))
friend class ProgramState
ASTContext & getContext()
ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState, ProgramStateRef GDMState)
ProgramStateRef removeGDM(ProgramStateRef state, const void *Key)
ProgramStateRef addGDM(ProgramStateRef St, const void *Key, void *Data)
ProgramStateRef getPersistentState(ProgramState &Impl)
ProgramStateRef getInitialState(const LocationContext *InitLoc)
StoreManager & getStoreManager()
ProgramStateManager(ASTContext &Ctx, StoreManagerCreator CreateStoreManager, ConstraintManagerCreator CreateConstraintManager, llvm::BumpPtrAllocator &alloc, ExprEngine *expreng)
ConstraintManager & getConstraintManager()
ProgramState - This class encapsulates:
bool scanReachableSymbols(SVal val, SymbolVisitor &visitor) const
Visits the symbols reachable from the given SVal using the provided SymbolVisitor.
Loc getLValue(const CXXBaseSpecifier &BaseSpec, const SubRegion *Super) const
Get the lvalue for a base class object reference.
ProgramStateRef bindDefaultZero(SVal loc, const LocationContext *LCtx) const
Performs C++ zero-initialization procedure on the region of memory represented by loc.
friend class ProgramStateManager
llvm::ImmutableMap< const void *, void * > GenericDataMap
void printJson(raw_ostream &Out, const LocationContext *LCtx=nullptr, const char *NL="\n", unsigned int Space=0, bool IsDot=false) const
ProgramStateRef bindDefaultInitial(SVal loc, SVal V, const LocationContext *LCtx) const
Initializes the region of memory represented by loc with an initial value.
ConstraintManager & getConstraintManager() const
Return the ConstraintManager.
SVal getSValAsScalarOrLoc(const Stmt *Ex, const LocationContext *LCtx) const
SVal getSelfSVal(const LocationContext *LC) const
Return the value of 'self' if available in the given context.
SVal getRawSVal(Loc LV, QualType T=QualType()) const
Returns the "raw" SVal bound to LV before any value simplification.
ConditionTruthVal isNull(SVal V) const
Check if the given SVal is constrained to zero or is a zero constant.
ProgramStateManager & getStateManager() const
Return the ProgramStateManager associated with this state.
ProgramStateRef killBinding(Loc LV) const
ProgramState(ProgramStateManager *mgr, const Environment &env, StoreRef st, GenericDataMap gdm)
This ctor is used when creating the first ProgramState object.
ProgramStateRef BindExpr(const Expr *E, const LocationContext *LCtx, SVal V, bool Invalidate=true) const
Create a new state by binding the value V to the expression E in the state's environment.
Store getStore() const
Return the store associated with this state.
ConditionTruthVal areEqual(SVal Lhs, SVal Rhs) const
void printDOT(raw_ostream &Out, const LocationContext *LCtx=nullptr, unsigned int Space=0) const
ConditionTruthVal isNonNull(SVal V) const
Check if the given SVal is not constrained to zero and is not a zero constant.
ProgramStateRef assumeInBound(DefinedOrUnknownSVal idx, DefinedOrUnknownSVal upperBound, bool assumption, QualType IndexType=QualType()) const
ProgramStateRef enterStackFrame(const CallEvent &Call, const StackFrameContext *CalleeCtx) const
enterStackFrame - Returns the state for entry to the given stack frame, preserving the current state.
LLVM_ATTRIBUTE_RETURNS_NONNULL const VarRegion * getRegion(const VarDecl *D, const LocationContext *LC) const
Utility method for getting regions.
SVal getSVal(const Stmt *S, const LocationContext *LCtx) const
Returns the SVal bound to the statement 'S' in the state's environment.
ProgramStateRef invalidateRegions(ArrayRef< const MemRegion * > Regions, ConstCFGElementRef Elem, unsigned BlockCount, const LocationContext *LCtx, bool CausesPointerEscape, InvalidatedSymbols *IS=nullptr, const CallEvent *Call=nullptr, RegionAndSymbolInvalidationTraits *ITraits=nullptr) const
Returns the state with bindings for the given regions cleared from the store.
ProgramStateRef bindLoc(Loc location, SVal V, const LocationContext *LCtx, bool notifyChanges=true) const
friend class ConstraintManager
BasicValueFactory & getBasicVals() const
std::pair< ProgramStateRef, ProgramStateRef > assumeInBoundDual(DefinedOrUnknownSVal idx, DefinedOrUnknownSVal upperBound, QualType IndexType=QualType()) const
void *const * FindGDM(const void *K) const
AnalysisManager & getAnalysisManager() const
Information about invalidation for a particular region/symbol.
BasicValueFactory & getBasicValueFactory()
ASTContext & getContext()
QualType getArrayIndexType() const
virtual SVal evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op, NonLoc lhs, NonLoc rhs, QualType resultTy)=0
Create a new value which represents a binary expression with two non- location operands.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
bool isUnknownOrUndef() const
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
const MemRegion * getAsRegion() const
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
A utility class that visits the reachable symbols using a custom SymbolVisitor.
bool scan(nonloc::LazyCompoundVal val)
virtual bool scanReachableSymbols(Store S, const MemRegion *R, ScanReachableSymbols &Visitor)=0
Finds the transitive closure of symbols within the given region.
SmallVector< const MemRegion *, 8 > InvalidatedRegions
virtual void printJson(raw_ostream &Out, Store S, const char *NL, unsigned int Space, bool IsDot) const =0
SubRegion - A region that subsets another larger region.
llvm::iterator_range< symbol_iterator > symbols() const
A class responsible for cleaning up unused symbols.
void setReapedStore(StoreRef st)
Set to the value of the symbolic store after StoreManager::removeDeadBindings has been called.
SymbolicRegion - A special, "non-concrete" region.
TypedValueRegion - An abstract class representing regions having a typed value.
The simplest example of a concrete compound value is nonloc::CompoundVal, which represents a concrete...
Value representing integer constant.
While nonloc::CompoundVal covers a few simple use cases, nonloc::LazyCompoundVal is a more performant...
LLVM_ATTRIBUTE_RETURNS_NONNULL const LazyCompoundValData * getCVData() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const TypedValueRegion * getRegion() const
This function itself is immaterial.
const void * getStore() const
It might return null.
@ PSK_EscapeOnBind
A pointer escapes due to binding its value to a location that the analyzer cannot track.
SValBuilder * createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, ProgramStateManager &stateMgr)
llvm::DenseSet< SymbolRef > InvalidatedSymbols
void printDynamicTypeInfoJson(raw_ostream &Out, ProgramStateRef State, const char *NL="\n", unsigned int Space=0, bool IsDot=false)
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
const SymExpr * SymbolRef
std::unique_ptr< ConstraintManager >(* ConstraintManagerCreator)(ProgramStateManager &, ExprEngine *)
std::unique_ptr< StoreManager >(* StoreManagerCreator)(ProgramStateManager &)
void ProgramStateRetain(const ProgramState *state)
Increments the number of times this state is referenced.
void ProgramStateRelease(const ProgramState *state)
Decrement the number of times this state is referenced.
const void * Store
Store - This opaque type encapsulates an immutable mapping from locations to values.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
CFGBlock::ConstCFGElementRef ConstCFGElementRef
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
U cast(CodeGen::Address addr)
llvm::SmallVector< SVal, 0 > FailedToBindValues