20 #include "llvm/Support/raw_ostream.h"
22 using namespace clang;
25 namespace clang {
namespace ento {
34 assert(state->refCount > 0);
36 if (--s->refCount == 0) {
38 Mgr.StateSet.RemoveNode(s);
40 Mgr.freeStates.push_back(s);
56 : llvm::FoldingSetNode(),
57 stateMgr(RHS.stateMgr),
73 llvm::BumpPtrAllocator &alloc,
75 : Eng(SubEng), EnvMgr(alloc), GDMFactory(alloc),
78 StoreMgr = (*CreateSMgr)(*this);
79 ConstraintMgr = (*CreateCMgr)(*
this, SubEng);
84 for (GDMContextsTy::iterator I=GDMContexts.begin(), E=GDMContexts.end();
86 I->second.second(I->second.first);
107 NewState.setStore(newStore);
111 return ConstraintMgr->removeDeadBindings(Result, SymReaper);
142 bool CausedByPointerEscape,
147 for (RegionList::const_iterator I = Regions.begin(),
148 End = Regions.end(); I !=
End; ++I)
151 return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
159 bool CausedByPointerEscape,
164 return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
169 ProgramState::invalidateRegionsImpl(
ValueList Values,
172 bool CausedByPointerEscape,
185 ITraits = &ITraitsLocal;
191 = Mgr.StoreMgr->invalidateRegions(
getStore(), Values, E, Count, LCtx, Call,
192 *IS, *ITraits, &TopLevelInvalidated,
197 if (CausedByPointerEscape) {
209 Mgr.StoreMgr->invalidateRegions(
getStore(), Values, E, Count, LCtx, Call,
210 *IS, *ITraits,
nullptr,
nullptr);
211 return makeWithStore(newStore);
221 if (newStore.
getStore() == OldStore)
224 return makeWithStore(newStore);
232 return makeWithStore(NewStore);
292 SVal V,
bool Invalidate)
const{
367 StoreMgr->getInitialStore(InitLoc),
368 GDMFactory.getEmptyMap());
377 NewState.GDM = GDMState->GDM;
383 llvm::FoldingSetNodeID
ID;
387 if (
ProgramState *I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
391 if (!freeStates.empty()) {
392 newState = freeStates.back();
393 freeStates.pop_back();
399 StateSet.InsertNode(newState, InsertPos);
405 NewSt.setStore(store);
409 void ProgramState::setStore(
const StoreRef &newStore) {
415 store = newStoreStore;
423 const char *NL,
const char *Sep)
const {
429 Env.
print(Out, NL, Sep);
439 print(Out,
"\\l",
"\\|");
447 const char *NL,
const char *Sep)
const {
451 Out <<
"Tainted Symbols:" << NL;
453 for (TaintMapImpl::iterator I = TM.begin(), E = TM.end(); I != E; ++I) {
454 Out << I->first <<
" : " << I->second << NL;
467 return GDM.lookup(K);
472 void *(*CreateContext)(llvm::BumpPtrAllocator&),
473 void (*DeleteContext)(
void*)) {
475 std::pair<void*, void (*)(void*)>&
p = GDMContexts[K];
477 p.first = CreateContext(Alloc);
478 p.second = DeleteContext;
509 bool wasVisited = !visited.insert(val.
getCVData()).second;
513 StoreManager &StoreMgr = state->getStateManager().getStoreManager();
530 bool wasVisited = !visited.insert(sym).second;
546 return scan(cast<SymbolCast>(sym)->getOperand());
548 return scan(cast<SymIntExpr>(sym)->getLHS());
550 return scan(cast<IntSymExpr>(sym)->getRHS());
561 return scan(
X->getRegion());
568 return scan(
X->getLoc());
583 if (isa<MemSpaceRegion>(R))
586 bool wasVisited = !visited.insert(R).second;
599 if (
const SubRegion *SR = dyn_cast<SubRegion>(R)) {
600 const MemRegion *Super = SR->getSuperRegion();
605 if (isa<MemSpaceRegion>(Super)) {
606 StoreManager &StoreMgr = state->getStateManager().getStoreManager();
615 E = BDR->referenced_vars_end();
616 for ( ; I != E; ++I) {
633 for ( ; I != E; ++I) {
644 for ( ; I != E; ++I) {
654 if (
const Expr *E = dyn_cast_or_null<Expr>(S))
670 if (
const SymbolicRegion *SR = dyn_cast_or_null<SymbolicRegion>(R))
679 while (
const SymbolCast *SC = dyn_cast<SymbolCast>(Sym))
680 Sym = SC->getOperand();
689 if (
const Expr *E = dyn_cast_or_null<Expr>(S))
716 if (
const SubRegion *ER = dyn_cast<SubRegion>(Reg))
717 return isTainted(ER->getSuperRegion(), K);
727 bool Tainted =
false;
730 if (!isa<SymbolData>(*SI))
734 Tainted = (Tag && *Tag ==
Kind);
745 if (
const SymbolCast *SC = dyn_cast<SymbolCast>(*SI))
762 Reg = Reg->StripCasts();
770 if (
const TypedRegion *TR = dyn_cast<TypedRegion>(Reg))
virtual ProgramStateRef assume(ProgramStateRef state, DefinedSVal Cond, bool Assumption)=0
ProgramStateRef addGDM(ProgramStateRef St, void *Key, void *Data)
const SymExpr * getAsSymExpr() const
ProgramStateManager & getStateManager() const
Return the ProgramStateManager associated with this state.
ProgramStateRef enterStackFrame(const CallEvent &Call, const StackFrameContext *CalleeCtx) const
TypedValueRegion - An abstract class representing regions having a typed value.
MemRegion - The root abstract class for all memory regions.
void print(raw_ostream &Out, const char *NL, const char *Sep) const
SValBuilder * createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, ProgramStateManager &stateMgr)
Information about invalidation for a particular region/symbol.
SVal getRawSVal(Loc LV, QualType T=QualType()) const
Returns the "raw" SVal bound to LV before any value simplfication.
ProgramStateRef addTaint(const Stmt *S, const LocationContext *LCtx, TaintTagType Kind=TaintTagGeneric) const
Create a new state in which the statement is marked as tainted.
virtual bool isBoundable() const
Manages the lifetime of CallEvent objects.
Value representing integer constant.
const SymExpr * getRHS() const
friend class ProgramState
std::unique_ptr< ConstraintManager >(* ConstraintManagerCreator)(ProgramStateManager &, SubEngine *)
const MemRegion * getBaseRegion() const
ProgramStateRef removeDeadBindings(ProgramStateRef St, const StackFrameContext *LCtx, SymbolReaper &SymReaper)
bool isZeroConstant() const
bool isTainted(const Stmt *S, const LocationContext *LCtx, TaintTagType Kind=TaintTagGeneric) const
Check if the statement is tainted in the current state.
Symbolic value. These values used to capture symbolic execution of the program.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SubEngine * getOwningEngine()
Environment bindExpr(Environment Env, const EnvironmentEntry &E, SVal V, bool Invalidate)
Bind a symbolic value to the given environment entry.
SValBuilder & getSValBuilder()
void setReapedStore(StoreRef st)
Set to the value of the symbolic store after StoreManager::removeDeadBindings has been called...
const SymExpr * getLHS() const
const llvm::APSInt & Convert(const llvm::APSInt &To, const llvm::APSInt &From)
static bool isLocType(QualType T)
void *const * FindGDM(void *K) const
bool isUnknownOrUndef() const
virtual void decrementReferenceCount(Store store)
SVal getSValAsScalarOrLoc(const Stmt *Ex, const LocationContext *LCtx) const
virtual QualType getType() const =0
virtual void print(ProgramStateRef state, raw_ostream &Out, const char *nl, const char *sep)=0
llvm::ImmutableList< SVal >::iterator iterator
const MemRegion * StripCasts(bool StripBaseCasts=true) const
ID
Defines the set of possible language-specific address spaces.
virtual ProgramStateRef processRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const CallEvent *Call)=0
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.
Stores the currently inferred strictest bound on the runtime type of a region in a given state along ...
ProgramStateRef setDynamicTypeInfo(const MemRegion *Reg, DynamicTypeInfo NewTy) const
Set dynamic type information of the region; return the new state.
const VarRegion * getCapturedRegion() const
SVal getSVal(const Stmt *S, const LocationContext *LCtx) const
Returns the SVal bound to the statement 'S' in the state's environment.
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
Represents a cast expression.
ProgramStateRef bindLoc(Loc location, SVal V, bool notifyChanges=true) const
StoreManager & getStoreManager()
The result type of a method or function.
const LazyCompoundValData * getCVData() const
ProgramStateRef BindExpr(const Stmt *S, const LocationContext *LCtx, SVal V, bool Invalidate=true) const
ProgramStateRef removeGDM(ProgramStateRef state, void *Key)
virtual bool VisitMemRegion(const MemRegion *region)
bool scan(nonloc::LazyCompoundVal val)
Environment getInitialEnvironment()
#define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type)
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
ProgramStateRef getInitialState(const LocationContext *InitLoc)
ProgramStateRef assumeInBound(DefinedOrUnknownSVal idx, DefinedOrUnknownSVal upperBound, bool assumption, QualType IndexType=QualType()) const
ProgramStateRef processRegionChange(ProgramStateRef state, const MemRegion *MR)
ASTContext & getContext()
#define CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value)
A class responsible for cleaning up unused symbols.
const VarRegion * getRegion(const VarDecl *D, const LocationContext *LC) const
Utility method for getting regions.
ConditionTruthVal isNull(SVal V) const
Check if the given SVal is constrained to zero or is a zero constant.
void printDOT(raw_ostream &Out) const
ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState, ProgramStateRef GDMState)
virtual SVal evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op, NonLoc lhs, NonLoc rhs, QualType resultTy)=0
REGISTER_TRAIT_WITH_PROGRAMSTATE(DynamicTypeMap, CLANG_ENTO_PROGRAMSTATE_MAP(const MemRegion *, DynamicTypeInfo)) DynamicTypeInfo ProgramState const DynamicTypeInfo GDMType)
An immutable map from EnvironemntEntries to SVals.
A symbol representing the value stored at a MemRegion.
virtual bool VisitSymbol(SymbolRef sym)=0
A visitor method invoked by ProgramStateManager::scanReachableSymbols.
void ProgramStateRelease(const ProgramState *state)
Decrement the number of times this state is referenced.
ArrayRef< const MemRegion * > RegionList
static __inline__ uint32_t volatile uint32_t * p
static symbol_iterator symbol_end()
const MemRegion * getAsRegion() const
virtual void print(Store store, raw_ostream &Out, const char *nl, const char *sep)=0
ProgramStateRef killBinding(Loc LV) 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
const llvm::APSInt & getMinValue(const llvm::APSInt &v)
ConstraintManager & getConstraintManager()
BasicValueFactory & getBasicValueFactory()
const TypedValueRegion * getRegion() const
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.
ProgramStateRef bindDefault(SVal loc, SVal V) const
ProgramStateManager(ASTContext &Ctx, StoreManagerCreator CreateStoreManager, ConstraintManagerCreator CreateConstraintManager, llvm::BumpPtrAllocator &alloc, SubEngine *subeng)
void print(raw_ostream &Out, const char *nl="\n", const char *sep="") const
Environment removeDeadBindings(Environment Env, SymbolReaper &SymReaper, ProgramStateRef state)
void * FindGDMContext(void *index, void *(*CreateContext)(llvm::BumpPtrAllocator &), void(*DeleteContext)(void *))
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef. Otherwise, return 0.
virtual void incrementReferenceCount(Store store)
symbol_iterator symbol_begin() const
ElementRegin is used to represent both array elements and casts.
virtual ProgramStateRef notifyCheckersOfPointerEscape(ProgramStateRef State, const InvalidatedSymbols *Invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const CallEvent *Call, RegionAndSymbolInvalidationTraits &HTraits)=0
virtual void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep)=0
printState - Called by ProgramStateManager to print checker-specific data.
static void Profile(llvm::FoldingSetNodeID &ID, const ProgramState *V)
virtual const llvm::APSInt * getSymVal(ProgramStateRef state, SymbolRef sym) const
If a symbol is perfectly constrained to a constant, attempt to return the concrete value...
const SymExpr * getAsSymbolicExpression() const
ProgramStateRef getPersistentState(ProgramState &Impl)
BasicValueFactory & getBasicVals() const
bool isNull() const
isNull - Return true if this QualType doesn't point to a type yet.
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
void printTaint(raw_ostream &Out, const char *nl="\n", const char *sep="") const
Represents a symbolic expression like 'x' + 'y'.
TypedRegion - An abstract class representing regions that are typed.
ArrayRef< SVal > ValueList
Expr * IgnoreParens() LLVM_READONLY
bool scanReachableSymbols(SVal val, SymbolVisitor &visitor) const
Visits the symbols reachable from the given SVal using the provided SymbolVisitor.
std::unique_ptr< StoreManager >(* StoreManagerCreator)(ProgramStateManager &)
Iterator over symbols that the current symbol depends on.
const void * getStore() const