21 #include "llvm/Support/raw_ostream.h" 23 using namespace clang;
35 assert(state->refCount > 0);
37 if (--s->refCount == 0) {
39 Mgr.StateSet.RemoveNode(s);
41 Mgr.freeStates.push_back(s);
57 :
llvm::FoldingSetNode(),
58 stateMgr(RHS.stateMgr),
78 llvm::BumpPtrAllocator &alloc,
80 : Eng(SubEng), EnvMgr(alloc), GDMFactory(alloc),
83 StoreMgr = (*CreateSMgr)(*this);
84 ConstraintMgr = (*CreateCMgr)(*
this, SubEng);
89 for (GDMContextsTy::iterator I=GDMContexts.begin(), E=GDMContexts.end();
91 I->second.second(I->second.first);
111 NewState.setStore(newStore);
120 bool notifyChanges)
const {
122 ProgramStateRef newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(),
125 if (MR && notifyChanges)
136 const StoreRef &newStore = Mgr.StoreMgr->BindDefaultInitial(getStore(), R, V);
145 const StoreRef &newStore = Mgr.StoreMgr->BindDefaultZero(getStore(), R);
155 const Expr *E,
unsigned Count,
157 bool CausedByPointerEscape,
160 RegionAndSymbolInvalidationTraits *ITraits)
const {
162 for (RegionList::const_iterator I = Regions.begin(),
163 End = Regions.end(); I !=
End; ++I)
164 Values.push_back(loc::MemRegionVal(*I));
166 return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
172 const Expr *E,
unsigned Count,
174 bool CausedByPointerEscape,
177 RegionAndSymbolInvalidationTraits *ITraits)
const {
179 return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
184 ProgramState::invalidateRegionsImpl(
ValueList Values,
185 const Expr *E,
unsigned Count,
187 bool CausedByPointerEscape,
189 RegionAndSymbolInvalidationTraits *ITraits,
192 SubEngine &Eng = Mgr.getOwningEngine();
196 IS = &InvalidatedSyms;
198 RegionAndSymbolInvalidationTraits ITraitsLocal;
200 ITraits = &ITraitsLocal;
204 const StoreRef &newStore
205 = Mgr.StoreMgr->invalidateRegions(getStore(), Values, E, Count, LCtx, Call,
206 *IS, *ITraits, &TopLevelInvalidated,
211 if (CausedByPointerEscape) {
212 newState = Eng.notifyCheckersOfPointerEscape(newState, IS,
218 return Eng.processRegionChanges(newState, IS, TopLevelInvalidated,
219 Invalidated, LCtx, Call);
225 Store OldStore = getStore();
227 getStateManager().StoreMgr->killBinding(OldStore, LV);
229 if (newStore.
getStore() == OldStore)
232 return makeWithStore(newStore);
239 getStateManager().StoreMgr->enterStackFrame(getStore(), Call, CalleeCtx);
240 return makeWithStore(NewStore);
260 SVal V = getRawSVal(location, T);
271 .getConstraintManager()
272 .getSymVal(
this, sym)) {
302 SVal V,
bool Invalidate)
const{
311 return getStateManager().getPersistentState(NewSt);
337 if (newIdx.isUnknownOrUndef())
367 return stateMgr->getSValBuilder().areEqual(
this, Lhs, Rhs);
381 return getStateManager().ConstraintMgr->isNull(
this, Sym);
387 StoreMgr->getInitialStore(InitLoc),
388 GDMFactory.getEmptyMap());
397 NewState.GDM = GDMState->GDM;
403 llvm::FoldingSetNodeID
ID;
407 if (
ProgramState *I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
411 if (!freeStates.empty()) {
412 newState = freeStates.back();
413 freeStates.pop_back();
419 StateSet.InsertNode(newState, InsertPos);
425 NewSt.setStore(store);
426 return getStateManager().getPersistentState(NewSt);
429 void ProgramState::setStore(
const StoreRef &newStore) {
432 stateMgr->getStoreManager().incrementReferenceCount(newStoreStore);
434 stateMgr->getStoreManager().decrementReferenceCount(store);
435 store = newStoreStore;
443 const char *NL,
unsigned int Space,
445 Indent(Out, Space, IsDot) <<
"\"program_state\": {" << NL;
454 Env.printJson(Out, Mgr.
getContext(), LCtx, NL, Space, IsDot);
466 Indent(Out, Space, IsDot) <<
'}';
470 unsigned int Space)
const {
471 printJson(Out, LCtx,
"\\l", Space,
true);
475 printJson(llvm::errs());
479 return stateMgr->getOwningEngine().getAnalysisManager();
487 return GDM.lookup(K);
492 void *(*CreateContext)(llvm::BumpPtrAllocator&),
493 void (*DeleteContext)(
void*)) {
495 std::pair<void*, void (*)(void*)>& p = GDMContexts[K];
497 p.first = CreateContext(Alloc);
498 p.second = DeleteContext;
529 bool wasVisited = !visited.insert(val.
getCVData()).second;
553 bool wasVisited = !visited.insert(*SI).second;
557 if (!visitor.VisitSymbol(*SI))
566 return scan(
X->getRegion());
573 return scan(
X->getLoc());
588 if (isa<MemSpaceRegion>(R))
591 bool wasVisited = !visited.insert(R).second;
595 if (!visitor.VisitMemRegion(R))
600 if (!visitor.VisitSymbol(SR->getSymbol()))
604 if (
const SubRegion *SR = dyn_cast<SubRegion>(R)) {
605 const MemRegion *Super = SR->getSuperRegion();
610 if (isa<MemSpaceRegion>(Super)) {
620 E = BDR->referenced_vars_end();
621 for ( ; I != E; ++I) {
636 llvm::iterator_range<region_iterator> Reachable,
virtual ProgramStateRef assume(ProgramStateRef state, DefinedSVal Cond, bool Assumption)=0
ProgramStateRef addGDM(ProgramStateRef St, void *Key, void *Data)
TypedValueRegion - An abstract class representing regions having a typed value.
ProgramStateRef processRegionChange(ProgramStateRef state, const MemRegion *MR, const LocationContext *LCtx)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
QualType getArrayIndexType() const
A (possibly-)qualified type.
MemRegion - The root abstract class for all memory regions.
bool isUnderconstrained() const
Return true if the constrained is underconstrained and we do not know if the constraint is true of va...
LLVM_NODISCARD 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::DenseSet< SymbolRef > InvalidatedSymbols
Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be placed into a PointerUnion...
SValBuilder * createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, ProgramStateManager &stateMgr)
Stmt - This represents one statement.
BasicValueFactory & getBasicVals()
Manages the lifetime of CallEvent objects.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
ProgramStateRef removeDeadBindingsFromEnvironmentAndStore(ProgramStateRef St, const StackFrameContext *LCtx, SymbolReaper &SymReaper)
Value representing integer constant.
ConditionTruthVal isNonNull(SVal V) const
Check if the given SVal is not constrained to zero and is not a zero constant.
A utility class that visits the reachable symbols using a custom SymbolVisitor.
friend class ProgramState
const void * Store
Store - This opaque type encapsulates an immutable mapping from locations to values.
Store getStore() const
Return the store associated with this state.
LLVM_NODISCARD ProgramStateRef bindDefaultInitial(SVal loc, SVal V, const LocationContext *LCtx) const
Initializes the region of memory represented by loc with an initial value.
virtual void printJson(raw_ostream &Out, Store S, const char *NL, unsigned int Space, bool IsDot) const =0
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
llvm::ImmutableList< SVal >::iterator iterator
std::unique_ptr< StoreManager >(* StoreManagerCreator)(ProgramStateManager &)
symbol_iterator symbol_begin() const
SValBuilder & getSValBuilder()
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
const SymExpr * getAsSymbolicExpression() const
getAsSymbolicExpression - If this Sval wraps a symbolic expression then return that expression...
void setReapedStore(StoreRef st)
Set to the value of the symbolic store after StoreManager::removeDeadBindings has been called...
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...
static bool isLocType(QualType T)
ProgramStateManager & getStateManager() const
Return the ProgramStateManager associated with this state.
BlockDataRegion - A region that represents a block instance.
AnalysisManager & getAnalysisManager() const
bool scanReachableSymbols(SVal val, SymbolVisitor &visitor) const
Visits the symbols reachable from the given SVal using the provided SymbolVisitor.
virtual void decrementReferenceCount(Store store)
If the StoreManager supports it, decrement the reference count of the specified Store object...
const LazyCompoundValData * getCVData() const
virtual void printJson(raw_ostream &Out, ProgramStateRef State, const char *NL, unsigned int Space, bool IsDot) const =0
SmallVector< const MemRegion *, 8 > InvalidatedRegions
SVal getSVal(const Stmt *S, const LocationContext *LCtx) const
Returns the SVal bound to the statement 'S' in the state's environment.
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
const VarRegion * getCapturedRegion() const
void printDOT(raw_ostream &Out, const LocationContext *LCtx=nullptr, unsigned int Space=0) const
void printJson(raw_ostream &Out, const LocationContext *LCtx=nullptr, const char *NL="\, unsigned int Space=0, bool IsDot=false) const
std::unique_ptr< ConstraintManager >(* ConstraintManagerCreator)(ProgramStateManager &, SubEngine *)
LLVM_NODISCARD 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.
llvm::ImmutableMap< void *, void * > GenericDataMap
SymbolicRegion - A special, "non-concrete" region.
ProgramState - This class encapsulates:
This represents one expression.
LLVM_NODISCARD ProgramStateRef bindDefaultZero(SVal loc, const LocationContext *LCtx) const
Performs C++ zero-initialization procedure on the region of memory represented by loc...
StoreManager & getStoreManager()
ConditionTruthVal isNull(SVal V) const
Check if the given SVal is constrained to zero or is a zero constant.
virtual void printJson(raw_ostream &Out, ProgramStateRef State, const LocationContext *LCtx, const char *NL, unsigned int Space, bool IsDot) const =0
printJson - Called by ProgramStateManager to print checker-specific data.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
void *const * FindGDM(void *K) const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
LLVM_NODISCARD ProgramStateRef bindLoc(Loc location, SVal V, const LocationContext *LCtx, bool notifyChanges=true) const
virtual bool isBoundable() const
ProgramStateRef removeGDM(ProgramStateRef state, void *Key)
bool scan(nonloc::LazyCompoundVal val)
Environment getInitialEnvironment()
ProgramStateRef getInitialState(const LocationContext *InitLoc)
const MemRegion * getAsRegion() const
An entry in the environment consists of a Stmt and an LocationContext.
ASTContext & getContext()
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
A class responsible for cleaning up unused symbols.
ConditionTruthVal areEqual(SVal Lhs, SVal Rhs) const
ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState, ProgramStateRef GDMState)
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.
An immutable map from EnvironemntEntries to SVals.
LLVM_NODISCARD 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.
Dataflow Directional Tag Classes.
void ProgramStateRelease(const ProgramState *state)
Decrement the number of times this state is referenced.
ArrayRef< const MemRegion * > RegionList
bool isZeroConstant() const
static symbol_iterator symbol_end()
LLVM_NODISCARD ProgramStateRef killBinding(Loc LV) const
const void * getStore() const
Represents an abstract call to a function or method along a particular path.
virtual bool scanReachableSymbols(Store S, const MemRegion *R, ScanReachableSymbols &Visitor)=0
Finds the transitive closure of symbols within the given region.
ASTContext & getContext()
const llvm::APSInt & getMinValue(const llvm::APSInt &v)
ConstraintManager & getConstraintManager()
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
BasicValueFactory & getBasicValueFactory()
SubRegion - A region that subsets another larger region.
ProgramState(ProgramStateManager *mgr, const Environment &env, StoreRef st, GenericDataMap gdm)
This ctor is used when creating the first ProgramState object.
void ProgramStateRetain(const ProgramState *state)
Increments the number of times this state is referenced.
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
void printDynamicTypeInfoJson(raw_ostream &Out, ProgramStateRef State, const char *NL="\, unsigned int Space=0, bool IsDot=false)
SubEngine & getOwningEngine()
ProgramStateManager(ASTContext &Ctx, StoreManagerCreator CreateStoreManager, ConstraintManagerCreator CreateConstraintManager, llvm::BumpPtrAllocator &alloc, SubEngine *subeng)
const TypedValueRegion * getRegion() const
Environment removeDeadBindings(Environment Env, SymbolReaper &SymReaper, ProgramStateRef state)
void * FindGDMContext(void *index, void *(*CreateContext)(llvm::BumpPtrAllocator &), void(*DeleteContext)(void *))
const MemRegion * getBaseRegion() const
virtual void incrementReferenceCount(Store store)
If the StoreManager supports it, increment the reference count of the specified Store object...
static void Profile(llvm::FoldingSetNodeID &ID, const ProgramState *V)
Profile - Profile the contents of a ProgramState object for use in a FoldingSet.
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
LLVM_NODISCARD ProgramStateRef assumeInBound(DefinedOrUnknownSVal idx, DefinedOrUnknownSVal upperBound, bool assumption, QualType IndexType=QualType()) const
ProgramStateRef getPersistentState(ProgramState &Impl)
SVal getSValAsScalarOrLoc(const Stmt *Ex, const LocationContext *LCtx) const
bool isUnknownOrUndef() const
ArrayRef< SVal > ValueList
Iterator over symbols that the current symbol depends on.