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);
101 NewState.Env = EnvMgr.removeDeadBindings(NewState.Env, SymReaper, state);
105 StoreMgr->removeDeadBindings(NewState.
getStore(), SF, SymReaper);
106 NewState.setStore(newStore);
113 bool notifyChanges)
const {
119 if (MR && notifyChanges)
168 IS = &InvalidatedSyms;
170 RegionAndSymbolInvalidationTraits ITraitsLocal;
172 ITraits = &ITraitsLocal;
176 const StoreRef &NewStore = Mgr.StoreMgr->invalidateRegions(
177 getStore(), Values, Elem, Count, SF,
Call, *IS, *ITraits,
178 &TopLevelInvalidated, &Invalidated);
182 if (CausedByPointerEscape) {
184 NewState, IS, TopLevelInvalidated,
Call, *ITraits);
188 Invalidated, SF,
Call);
196 if (newStore.
getStore() == OldStore)
199 return makeWithStore(newStore);
205SVal ProgramState::desugarReference(
SVal Val)
const {
206 const auto *TyReg = dyn_cast_or_null<TypedValueRegion>(Val.
getAsRegion());
207 if (!TyReg || !TyReg->getValueType()->isReferenceType())
216SVal ProgramState::wrapSymbolicRegion(
SVal Val)
const {
217 const auto *BaseReg = dyn_cast_or_null<SymbolicRegion>(Val.
getAsRegion());
222 QualType ElemTy = BaseReg->getPointeeStaticType();
229 return makeWithStore(
244 if (!R->isBoundable())
265 if (!T.isNull() && (T->isIntegralOrEnumerationType() ||
Loc::isLocType(T))) {
269 .getSymVal(
this, sym)) {
296 SVal V,
bool Invalidate)
const {
303 NewSt.Env = std::move(NewEnv);
307[[nodiscard]] std::pair<ProgramStateRef, ProgramStateRef>
356 std::pair<ProgramStateRef, ProgramStateRef> R =
358 return Assumption ? R.first : R.second;
363 if (
IsNull.isUnderconstrained())
369 return stateMgr->getSValBuilder().areEqual(
this, Lhs, Rhs);
373 if (
V.isZeroConstant())
387 ProgramState State(
this, EnvMgr.getInitialEnvironment(),
388 StoreMgr->getInitialStore(InitSF),
389 GDMFactory.getEmptyMap());
398 NewState.GDM = GDMState->GDM;
404 llvm::FoldingSetNodeID ID;
408 if (
ProgramState *I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
412 if (!freeStates.empty()) {
413 newState = freeStates.back();
414 freeStates.pop_back();
420 StateSet.InsertNode(newState, InsertPos);
426 NewSt.setStore(store);
442ProgramStateRef ProgramState::cloneAsPosteriorlyOverconstrained()
const {
444 NewSt.PosteriorlyOverconstrained =
true;
448void ProgramState::setStore(
const StoreRef &newStore) {
451 stateMgr->getStoreManager().incrementReferenceCount(newStoreStore);
453 stateMgr->getStoreManager().decrementReferenceCount(store);
454 store = newStoreStore;
471 for (
const auto *I : D->
chain()) {
482 const char *NL,
unsigned int Space,
484 Indent(Out, Space, IsDot) <<
"\"program_state\": {" << NL;
493 Env.printJson(Out, Mgr.
getContext(), SF, NL, Space, IsDot);
505 Indent(Out, Space, IsDot) <<
'}';
509 unsigned int Space)
const {
518 return stateMgr->getOwningEngine().getAnalysisManager();
526 return GDM.lookup(K);
530 const void *K,
void *(*CreateContext)(llvm::BumpPtrAllocator &),
531 void (*DeleteContext)(
void *)) {
533 std::pair<
void*, void (*)(
void*)>& p = GDMContexts[K];
535 p.first = CreateContext(Alloc);
536 p.second = DeleteContext;
569 bool wasVisited = !visited.insert(val.
getCVData()).second;
573 StoreManager &StoreMgr = state->getStateManager().getStoreManager();
591 bool wasVisited = !visited.insert(SubSym).second;
595 if (!visitor.VisitSymbol(SubSym))
604 return scan(
X->getRegion());
606 if (std::optional<nonloc::LazyCompoundVal>
X =
611 return scan(
X->getLoc());
626 bool wasVisited = !visited.insert(R).second;
630 if (!visitor.VisitMemRegion(R))
635 if (!visitor.VisitSymbol(SR->getSymbol()))
639 if (
const SubRegion *SR = dyn_cast<SubRegion>(R)) {
640 const MemRegion *Super = SR->getSuperRegion();
646 StoreManager &StoreMgr = state->getStateManager().getStoreManager();
654 for (
auto Var : BDR->referenced_vars()) {
655 if (!
scan(Var.getCapturedRegion()))
669 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
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.
const ImplicitParamDecl * getSelfDecl() const
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 StackFrame.
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 processRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const StackFrame *SF, const CallEvent *Call)
processRegionChanges - Called by ProgramStateManager whenever a change is made to the store.
void printJson(raw_ostream &Out, ProgramStateRef State, const StackFrame *SF, const char *NL, unsigned int Space, bool IsDot) const
printJson - Called by ProgramStateManager to print checker-specific data.
ProgramStateRef processRegionChange(ProgramStateRef state, const MemRegion *MR, const StackFrame *SF)
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
ExprEngine & getOwningEngine()
ProgramStateRef getInitialState(const StackFrame *InitSF)
void * FindGDMContext(const void *index, void *(*CreateContext)(llvm::BumpPtrAllocator &), void(*DeleteContext)(void *))
friend class ProgramState
ProgramStateRef removeDeadBindingsFromEnvironmentAndStore(ProgramStateRef St, const StackFrame *SF, SymbolReaper &SymReaper)
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)
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.
friend class ProgramStateManager
llvm::ImmutableMap< const void *, void * > GenericDataMap
ProgramStateRef bindDefaultInitial(SVal loc, SVal V, const StackFrame *SF) const
Initializes the region of memory represented by loc with an initial value.
ConstraintManager & getConstraintManager() const
Return the ConstraintManager.
LLVM_ATTRIBUTE_RETURNS_NONNULL const VarRegion * getRegion(const VarDecl *D, const StackFrame *SF) const
Utility method for getting regions.
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.
ProgramStateRef bindLoc(Loc location, SVal V, const StackFrame *SF, bool notifyChanges=true) const
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 StackFrame *SF, SVal V, bool Invalidate=true) const
Create a new state by binding the value V to the expression E in the state's environment.
ProgramStateRef bindDefaultZero(SVal loc, const StackFrame *SF) const
Performs C++ zero-initialization procedure on the region of memory represented by loc.
SVal getSVal(const Expr *E, const StackFrame *SF) const
Returns the SVal bound 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
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
SVal getSValAsScalarOrLoc(const Expr *E, const StackFrame *SF) const
ProgramStateRef invalidateRegions(ArrayRef< const MemRegion * > Regions, ConstCFGElementRef Elem, unsigned BlockCount, const StackFrame *SF, 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.
void printDOT(raw_ostream &Out, const StackFrame *SF=nullptr, unsigned int Space=0) const
SVal getSelfSVal(const StackFrame *SF) const
Return the value of 'self' if available in the given context.
void printJson(raw_ostream &Out, const StackFrame *SF=nullptr, const char *NL="\n", unsigned int Space=0, bool IsDot=false) 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
ProgramStateRef enterStackFrame(const CallEvent &Call, const StackFrame *CalleeSF) const
enterStackFrame - Returns the state for entry to the given stack frame, preserving the current state.
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