21#include "llvm/Support/raw_ostream.h"
27namespace clang {
namespace ento {
36 assert(state->refCount > 0);
38 if (--
s->refCount == 0) {
40 Mgr.StateSet.RemoveNode(
s);
42 Mgr.freeStates.push_back(
s);
58 : stateMgr(RHS.stateMgr),
Env(RHS.
Env), store(RHS.store), GDM(RHS.GDM),
59 PosteriorlyOverconstrained(RHS.PosteriorlyOverconstrained), refCount(0) {
75 llvm::BumpPtrAllocator &alloc,
77 : Eng(ExprEng), EnvMgr(alloc), GDMFactory(alloc),
80 StoreMgr = (*CreateSMgr)(*this);
81 ConstraintMgr = (*CreateCMgr)(*
this, ExprEng);
86 for (GDMContextsTy::iterator I=GDMContexts.begin(), E=GDMContexts.end();
88 I->second.second(I->second.first);
108 NewState.setStore(newStore);
117 bool notifyChanges)
const {
122 if (MR && notifyChanges)
152 const Expr *E,
unsigned Count,
154 bool CausedByPointerEscape,
162 return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
168 const Expr *E,
unsigned Count,
170 bool CausedByPointerEscape,
175 return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
180ProgramState::invalidateRegionsImpl(
ValueList Values,
181 const Expr *E,
unsigned Count,
183 bool CausedByPointerEscape,
192 IS = &InvalidatedSyms;
196 ITraits = &ITraitsLocal;
201 = Mgr.StoreMgr->invalidateRegions(
getStore(), Values, E, Count, LCtx,
Call,
202 *IS, *ITraits, &TopLevelInvalidated,
207 if (CausedByPointerEscape) {
215 Invalidated, LCtx,
Call);
223 if (newStore.
getStore() == OldStore)
226 return makeWithStore(newStore);
233SVal ProgramState::wrapSymbolicRegion(
SVal Val)
const {
234 const auto *BaseReg = dyn_cast_or_null<SymbolicRegion>(Val.
getAsRegion());
239 QualType ElemTy = BaseReg->getPointeeStaticType();
248 return makeWithStore(NewStore);
287 .getSymVal(
this, sym)) {
317 SVal V,
bool Invalidate)
const{
329[[nodiscard]] std::pair<ProgramStateRef, ProgramStateRef>
378 std::pair<ProgramStateRef, ProgramStateRef> R =
380 return Assumption ? R.first : R.second;
385 if (
IsNull.isUnderconstrained())
395 if (
V.isZeroConstant())
411 StoreMgr->getInitialStore(InitLoc),
412 GDMFactory.getEmptyMap());
421 NewState.GDM = GDMState->GDM;
427 llvm::FoldingSetNodeID ID;
431 if (
ProgramState *I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
435 if (!freeStates.empty()) {
436 newState = freeStates.back();
437 freeStates.pop_back();
443 StateSet.InsertNode(newState, InsertPos);
449 NewSt.setStore(store);
453ProgramStateRef ProgramState::cloneAsPosteriorlyOverconstrained()
const {
455 NewSt.PosteriorlyOverconstrained =
true;
459void ProgramState::setStore(
const StoreRef &newStore) {
465 store = newStoreStore;
480 for (
const auto *I : D->
chain()) {
481 Base =
SM.getLValueField(cast<FieldDecl>(I),
Base);
491 const char *NL,
unsigned int Space,
493 Indent(Out, Space, IsDot) <<
"\"program_state\": {" << NL;
514 Indent(Out, Space, IsDot) <<
'}';
518 unsigned int Space)
const {
519 printJson(Out, LCtx,
"\\l", Space,
true);
535 return GDM.lookup(K);
540 void *(*CreateContext)(llvm::BumpPtrAllocator&),
541 void (*DeleteContext)(
void*)) {
543 std::pair<
void*, void (*)(
void*)>& p = GDMContexts[K];
545 p.first = CreateContext(Alloc);
546 p.second = DeleteContext;
577 bool wasVisited = !visited.insert(val.
getCVData()).second;
581 StoreManager &StoreMgr = state->getStateManager().getStoreManager();
599 bool wasVisited = !visited.insert(SubSym).second;
612 return scan(
X->getRegion());
614 if (std::optional<nonloc::LazyCompoundVal>
X =
619 return scan(
X->getLoc());
631 if (isa<MemSpaceRegion>(R))
634 bool wasVisited = !visited.insert(R).second;
647 if (
const SubRegion *SR = dyn_cast<SubRegion>(R)) {
648 const MemRegion *Super = SR->getSuperRegion();
653 if (isa<MemSpaceRegion>(Super)) {
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).
Stmt - This represents one statement.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
const llvm::APSInt & 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...
const llvm::APSInt & getMinValue(const llvm::APSInt &v)
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 getInitialEnvironment()
Environment bindExpr(Environment Env, const EnvironmentEntry &E, SVal V, bool Invalidate)
Bind a symbolic value to the given environment entry.
Environment removeDeadBindings(Environment Env, SymbolReaper &SymReaper, ProgramStateRef state)
An immutable map from EnvironemntEntries to SVals.
void printJson(raw_ostream &Out, const ASTContext &Ctx, const LocationContext *LCtx=nullptr, const char *NL="\n", unsigned int Space=0, bool IsDot=false) const
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.
AnalysisManager & getAnalysisManager()
static bool isLocType(QualType T)
MemRegion - The root abstract class for all memory regions.
virtual bool isBoundable() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getBaseRegion() const
SValBuilder & getSValBuilder()
ProgramStateRef removeDeadBindingsFromEnvironmentAndStore(ProgramStateRef St, const StackFrameContext *LCtx, SymbolReaper &SymReaper)
ExprEngine & getOwningEngine()
ProgramStateRef removeGDM(ProgramStateRef state, void *Key)
void * FindGDMContext(void *index, void *(*CreateContext)(llvm::BumpPtrAllocator &), void(*DeleteContext)(void *))
friend class ProgramState
ASTContext & getContext()
ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState, ProgramStateRef GDMState)
ProgramStateRef addGDM(ProgramStateRef St, 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.
llvm::ImmutableMap< void *, void * > GenericDataMap
ProgramStateRef BindExpr(const Stmt *S, const LocationContext *LCtx, SVal V, bool Invalidate=true) const
Create a new state by binding the value 'V' to the statement 'S' in the state's environment.
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 simplfication.
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.
Store getStore() const
Return the store associated with this state.
ProgramStateRef invalidateRegions(ArrayRef< const MemRegion * > Regions, const Expr *E, 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.
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 bindLoc(Loc location, SVal V, const LocationContext *LCtx, bool notifyChanges=true) const
BasicValueFactory & getBasicVals() const
std::pair< ProgramStateRef, ProgramStateRef > assumeInBoundDual(DefinedOrUnknownSVal idx, DefinedOrUnknownSVal upperBound, QualType IndexType=QualType()) const
AnalysisManager & getAnalysisManager() const
void *const * FindGDM(void *K) 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.
ConditionTruthVal areEqual(ProgramStateRef state, SVal lhs, SVal rhs)
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.
virtual void decrementReferenceCount(Store store)
If the StoreManager supports it, decrement the reference count of the specified Store object.
virtual void incrementReferenceCount(Store store)
If the StoreManager supports it, increment the reference count of the specified Store object.
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.
virtual bool VisitMemRegion(const MemRegion *)
virtual bool VisitSymbol(SymbolRef sym)=0
A visitor method invoked by ProgramStateManager::scanReachableSymbols.
SymbolicRegion - A special, "non-concrete" region.
TypedValueRegion - An abstract class representing regions having a typed value.
Value representing integer constant.
LLVM_ATTRIBUTE_RETURNS_NONNULL const LazyCompoundValData * getCVData() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const TypedValueRegion * getRegion() const
const void * getStore() const
It might return null.
SValBuilder * createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, ProgramStateManager &stateMgr)
void printDynamicTypeInfoJson(raw_ostream &Out, ProgramStateRef State, const char *NL="\n", unsigned int Space=0, bool IsDot=false)
std::unique_ptr< ConstraintManager >(* ConstraintManagerCreator)(ProgramStateManager &, ExprEngine *)
std::unique_ptr< StoreManager >(* StoreManagerCreator)(ProgramStateManager &)
const void * Store
Store - This opaque type encapsulates an immutable mapping from locations to values.
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.
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T