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);
117 bool notifyChanges)
const {
119 ProgramStateRef newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(),
133 const StoreRef &newStore = Mgr.StoreMgr->BindDefault(getStore(), R, V);
145 const Expr *E,
unsigned Count,
147 bool CausedByPointerEscape,
152 for (RegionList::const_iterator I = Regions.begin(),
153 End = Regions.end(); I !=
End; ++I)
156 return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
162 const Expr *E,
unsigned Count,
164 bool CausedByPointerEscape,
169 return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
174 ProgramState::invalidateRegionsImpl(
ValueList Values,
175 const Expr *E,
unsigned Count,
177 bool CausedByPointerEscape,
190 ITraits = &ITraitsLocal;
196 = Mgr.StoreMgr->invalidateRegions(getStore(), Values, E, Count, LCtx, Call,
197 *IS, *ITraits, &TopLevelInvalidated,
202 if (CausedByPointerEscape) {
210 Invalidated, LCtx, Call);
214 Mgr.StoreMgr->invalidateRegions(getStore(), Values, E, Count, LCtx, Call,
215 *IS, *ITraits,
nullptr,
nullptr);
216 return makeWithStore(newStore);
222 Store OldStore = getStore();
224 getStateManager().StoreMgr->killBinding(OldStore, LV);
226 if (newStore.
getStore() == OldStore)
229 return makeWithStore(newStore);
236 getStateManager().StoreMgr->enterStackFrame(getStore(), Call, CalleeCtx);
237 return makeWithStore(NewStore);
257 SVal V = getRawSVal(cast<Loc>(location), T);
267 if (
const llvm::APSInt *Int = getStateManager()
268 .getConstraintManager()
269 .getSymVal(
this, sym)) {
299 SVal V,
bool Invalidate)
const{
308 return getStateManager().getPersistentState(NewSt);
368 return getStateManager().ConstraintMgr->isNull(
this, Sym);
374 StoreMgr->getInitialStore(InitLoc),
375 GDMFactory.getEmptyMap());
384 NewState.GDM = GDMState->GDM;
390 llvm::FoldingSetNodeID
ID;
394 if (
ProgramState *I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
398 if (!freeStates.empty()) {
399 newState = freeStates.back();
400 freeStates.pop_back();
406 StateSet.InsertNode(newState, InsertPos);
412 NewSt.setStore(store);
413 return getStateManager().getPersistentState(NewSt);
416 void ProgramState::setStore(
const StoreRef &newStore) {
419 stateMgr->getStoreManager().incrementReferenceCount(newStoreStore);
421 stateMgr->getStoreManager().decrementReferenceCount(store);
422 store = newStoreStore;
430 const char *NL,
const char *Sep)
const {
436 Env.print(Out, NL, Sep);
446 print(Out,
"\\l",
"\\|");
454 const char *NL,
const char *Sep)
const {
458 Out <<
"Tainted Symbols:" << NL;
460 for (TaintMapImpl::iterator I = TM.begin(), E = TM.end(); I != E; ++I) {
461 Out << I->first <<
" : " << I->second << NL;
466 printTaint(llvm::errs());
474 return GDM.lookup(K);
479 void *(*CreateContext)(llvm::BumpPtrAllocator&),
480 void (*DeleteContext)(
void*)) {
482 std::pair<void*, void (*)(void*)>& p = GDMContexts[K];
484 p.first = CreateContext(Alloc);
485 p.second = DeleteContext;
516 bool wasVisited = !visited.insert(val.
getCVData()).second;
540 bool wasVisited = !visited.insert(*SI).second;
544 if (!visitor.VisitSymbol(*SI))
553 return scan(
X->getRegion());
560 return scan(
X->getLoc());
575 if (isa<MemSpaceRegion>(R))
578 bool wasVisited = !visited.insert(R).second;
582 if (!visitor.VisitMemRegion(R))
587 if (!visitor.VisitSymbol(SR->getSymbol()))
591 if (
const SubRegion *SR = dyn_cast<SubRegion>(R)) {
592 const MemRegion *Super = SR->getSuperRegion();
597 if (isa<MemSpaceRegion>(Super)) {
607 E = BDR->referenced_vars_end();
608 for ( ; I != E; ++I) {
625 for ( ; I != E; ++I) {
636 for ( ; I != E; ++I) {
646 if (
const Expr *E = dyn_cast_or_null<Expr>(S))
649 return addTaint(getSVal(S, LCtx), Kind);
656 return addTaint(Sym, Kind);
668 if (
Optional<SVal> binding = getStateManager().StoreMgr->getDefaultBinding(*LCV)) {
669 if (
SymbolRef Sym = binding->getAsSymbol())
670 return addPartialTaint(Sym, LCV->getRegion(),
Kind);
675 return addTaint(R, Kind);
680 if (
const SymbolicRegion *SR = dyn_cast_or_null<SymbolicRegion>(R))
681 return addTaint(SR->getSymbol(),
Kind);
689 while (
const SymbolCast *SC = dyn_cast<SymbolCast>(Sym))
690 Sym = SC->getOperand();
701 if (contains<TaintMap>(ParentSym) && *get<TaintMap>(ParentSym) == Kind)
706 return addTaint(ParentSym, Kind);
710 SavedRegs ? *SavedRegs : stateMgr->TSRFactory.getEmptyMap();
712 Regs = stateMgr->TSRFactory.add(Regs, SubRegion, Kind);
720 if (
const Expr *E = dyn_cast_or_null<Expr>(S))
723 SVal val = getSVal(S, LCtx);
724 return isTainted(val, Kind);
729 return isTainted(Sym, Kind);
731 return isTainted(Reg, Kind);
742 return isTainted(ER->getSuperRegion(), K) || isTainted(ER->getIndex(), K);
745 return isTainted(SR->getSymbol(), K);
747 if (
const SubRegion *ER = dyn_cast<SubRegion>(Reg))
748 return isTainted(ER->getSuperRegion(), K);
760 if (!isa<SymbolData>(*SI))
768 if (
const SymbolDerived *SD = dyn_cast<SymbolDerived>(*SI)) {
770 if (isTainted(SD->getParentSymbol(),
Kind))
777 get<DerivedSymTaint>(SD->getParentSymbol())) {
779 for (
auto I : *Regs) {
784 if (Kind == I.second &&
793 if (isTainted(SRV->getRegion(),
Kind))
798 if (
const SymbolCast *SC = dyn_cast<SymbolCast>(*SI)) {
799 if (isTainted(SC->getOperand(),
Kind))
virtual ProgramStateRef assume(ProgramStateRef state, DefinedSVal Cond, bool Assumption)=0
ProgramStateRef addPartialTaint(SymbolRef ParentSym, const SubRegion *SubRegion, TaintTagType Kind=TaintTagGeneric) const
Create a new state in a which a sub-region of a given symbol is tainted.
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()))
A (possibly-)qualified type.
MemRegion - The root abstract class for all memory regions.
ProgramStateRef enterStackFrame(const CallEvent &Call, const StackFrameContext *CalleeCtx) const
enterStackFrame - Returns the state for entry to the given stack frame, preserving the current state...
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
SValBuilder * createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, ProgramStateManager &stateMgr)
Stmt - This represents one statement.
Information about invalidation for a particular region/symbol.
BasicValueFactory & getBasicVals()
Manages the lifetime of CallEvent objects.
const void * Store
Store - This opaque type encapsulates an immutable mapping from locations to values.
bool isTainted(const Stmt *S, const LocationContext *LCtx, TaintTagType Kind=TaintTagGeneric) const
Check if the statement is tainted in the current state.
Value representing integer constant.
A utility class that visits the reachable symbols using a custom SymbolVisitor.
friend class ProgramState
void print(raw_ostream &Out, const char *nl="\, const char *sep="") const
ProgramStateRef removeDeadBindings(ProgramStateRef St, const StackFrameContext *LCtx, SymbolReaper &SymReaper)
Store getStore() const
Return the store associated with this state.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
std::unique_ptr< StoreManager >(* StoreManagerCreator)(ProgramStateManager &)
SubEngine * getOwningEngine()
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.
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
A symbol representing the value of a MemRegion whose parent region has symbolic value.
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
virtual void print(ProgramStateRef state, raw_ostream &Out, const char *nl, const char *sep)=0
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
void printDOT(raw_ostream &Out) const
const VarRegion * getCapturedRegion() const
llvm::ImmutableList< SVal >::iterator iterator
std::unique_ptr< ConstraintManager >(* ConstraintManagerCreator)(ProgramStateManager &, SubEngine *)
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.
SymbolicRegion - A special, "non-concrete" region.
unsigned TaintTagType
The type of taint, which helps to differentiate between different types of taint. ...
ProgramState - This class encapsulates:
Expr - This represents one expression.
const FunctionProtoType * T
Represents a cast expression.
StoreManager & getStoreManager()
ConditionTruthVal isNull(SVal V) const
Check if the given SVal is constrained to zero or is a zero constant.
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...
virtual bool isBoundable() const
ProgramStateRef removeGDM(ProgramStateRef state, void *Key)
bool scan(nonloc::LazyCompoundVal val)
Environment getInitialEnvironment()
ProgramStateRef getInitialState(const LocationContext *InitLoc)
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.
const MemRegion * getAsRegion() const
bool isSubRegionOf(const MemRegion *R) const override
Check if the region is a subregion of the given region.
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...
virtual ProgramStateRef processRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion *> ExplicitRegions, ArrayRef< const MemRegion *> Regions, const LocationContext *LCtx, const CallEvent *Call)=0
processRegionChanges - Called by ProgramStateManager whenever a change is made to the store...
A class responsible for cleaning up unused symbols.
ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState, ProgramStateRef GDMState)
ProgramStateRef bindDefault(SVal loc, SVal V, const LocationContext *LCtx) 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.
An immutable map from EnvironemntEntries to SVals.
A symbol representing the value stored at a MemRegion.
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()
ProgramStateRef killBinding(Loc LV) const
const void * getStore() const
void printTaint(raw_ostream &Out, const char *nl="\, const char *sep="") const
virtual void print(Store store, raw_ostream &Out, const char *nl, const char *sep)=0
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.
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.
const SymExpr * getAsSymExpr() const
ProgramStateRef addTaint(const Stmt *S, const LocationContext *LCtx, TaintTagType Kind=TaintTagGeneric) const
Create a new state in which the statement is marked as tainted.
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
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...
virtual ProgramStateRef notifyCheckersOfPointerEscape(ProgramStateRef State, const InvalidatedSymbols *Invalidated, ArrayRef< const MemRegion *> ExplicitRegions, ArrayRef< const MemRegion *> Regions, const CallEvent *Call, RegionAndSymbolInvalidationTraits &HTraits)=0
ElementRegin is used to represent both array elements and casts.
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)
Profile - Profile the contents of a ProgramState object for use in a FoldingSet.
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
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
Iterator over symbols that the current symbol depends on.