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);
112 NewState.setStore(newStore);
116 return ConstraintMgr->removeDeadBindings(Result, SymReaper);
122 bool notifyChanges)
const {
124 ProgramStateRef newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(),
127 if (MR && notifyChanges)
138 const StoreRef &newStore = Mgr.StoreMgr->BindDefaultInitial(getStore(), R, V);
147 const StoreRef &newStore = Mgr.StoreMgr->BindDefaultZero(getStore(), R);
157 const Expr *E,
unsigned Count,
159 bool CausedByPointerEscape,
162 RegionAndSymbolInvalidationTraits *ITraits)
const {
164 for (RegionList::const_iterator I = Regions.begin(),
165 End = Regions.end(); I !=
End; ++I)
166 Values.push_back(loc::MemRegionVal(*I));
168 return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
174 const Expr *E,
unsigned Count,
176 bool CausedByPointerEscape,
179 RegionAndSymbolInvalidationTraits *ITraits)
const {
181 return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
186 ProgramState::invalidateRegionsImpl(
ValueList Values,
187 const Expr *E,
unsigned Count,
189 bool CausedByPointerEscape,
191 RegionAndSymbolInvalidationTraits *ITraits,
194 SubEngine &Eng = Mgr.getOwningEngine();
198 IS = &InvalidatedSyms;
200 RegionAndSymbolInvalidationTraits ITraitsLocal;
202 ITraits = &ITraitsLocal;
206 const StoreRef &newStore
207 = Mgr.StoreMgr->invalidateRegions(getStore(), Values, E, Count, LCtx, Call,
208 *IS, *ITraits, &TopLevelInvalidated,
213 if (CausedByPointerEscape) {
214 newState = Eng.notifyCheckersOfPointerEscape(newState, IS,
220 return Eng.processRegionChanges(newState, IS, TopLevelInvalidated,
221 Invalidated, LCtx, Call);
227 Store OldStore = getStore();
229 getStateManager().StoreMgr->killBinding(OldStore, LV);
231 if (newStore.
getStore() == OldStore)
234 return makeWithStore(newStore);
241 getStateManager().StoreMgr->enterStackFrame(getStore(), Call, CalleeCtx);
242 return makeWithStore(NewStore);
262 SVal V = getRawSVal(location, T);
272 if (
const llvm::APSInt *Int = getStateManager()
273 .getConstraintManager()
274 .getSymVal(
this, sym)) {
304 SVal V,
bool Invalidate)
const{
313 return getStateManager().getPersistentState(NewSt);
339 if (newIdx.isUnknownOrUndef())
369 return stateMgr->getSValBuilder().areEqual(
this, Lhs, Rhs);
383 return getStateManager().ConstraintMgr->isNull(
this, Sym);
389 StoreMgr->getInitialStore(InitLoc),
390 GDMFactory.getEmptyMap());
399 NewState.GDM = GDMState->GDM;
405 llvm::FoldingSetNodeID
ID;
409 if (
ProgramState *I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
413 if (!freeStates.empty()) {
414 newState = freeStates.back();
415 freeStates.pop_back();
421 StateSet.InsertNode(newState, InsertPos);
427 NewSt.setStore(store);
428 return getStateManager().getPersistentState(NewSt);
431 void ProgramState::setStore(
const StoreRef &newStore) {
434 stateMgr->getStoreManager().incrementReferenceCount(newStoreStore);
436 stateMgr->getStoreManager().decrementReferenceCount(store);
437 store = newStoreStore;
445 const char *NL,
unsigned int Space,
447 Indent(Out, Space, IsDot) <<
"\"program_state\": {" << NL;
456 Env.printJson(Out, Mgr.
getContext(), LCtx, NL, Space, IsDot);
468 Indent(Out, Space, IsDot) <<
'}';
472 unsigned int Space)
const {
473 printJson(Out, LCtx,
"\\l", Space,
true);
477 printJson(llvm::errs());
481 return stateMgr->getOwningEngine().getAnalysisManager();
489 return GDM.lookup(K);
494 void *(*CreateContext)(llvm::BumpPtrAllocator&),
495 void (*DeleteContext)(
void*)) {
497 std::pair<void*, void (*)(void*)>&
p = GDMContexts[K];
499 p.first = CreateContext(Alloc);
500 p.second = DeleteContext;
531 bool wasVisited = !visited.insert(val.
getCVData()).second;
555 bool wasVisited = !visited.insert(*SI).second;
559 if (!visitor.VisitSymbol(*SI))
568 return scan(
X->getRegion());
575 return scan(
X->getLoc());
590 if (isa<MemSpaceRegion>(R))
593 bool wasVisited = !visited.insert(R).second;
597 if (!visitor.VisitMemRegion(R))
602 if (!visitor.VisitSymbol(SR->getSymbol()))
606 if (
const SubRegion *SR = dyn_cast<SubRegion>(R)) {
607 const MemRegion *Super = SR->getSuperRegion();
612 if (isa<MemSpaceRegion>(Super)) {
622 E = BDR->referenced_vars_end();
623 for ( ; I != E; ++I) {
638 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
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.
ProgramStateRef removeDeadBindings(ProgramStateRef St, const StackFrameContext *LCtx, SymbolReaper &SymReaper)
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.