22 #include "llvm/Support/raw_ostream.h" 24 using namespace clang;
27 namespace 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 :
llvm::FoldingSetNode(),
59 stateMgr(RHS.stateMgr),
75 llvm::BumpPtrAllocator &alloc,
77 : Eng(SubEng), EnvMgr(alloc), GDMFactory(alloc),
80 StoreMgr = (*CreateSMgr)(*this);
81 ConstraintMgr = (*CreateCMgr)(*
this, SubEng);
86 for (GDMContextsTy::iterator I=GDMContexts.begin(), E=GDMContexts.end();
88 I->second.second(I->second.first);
109 NewState.setStore(newStore);
113 return ConstraintMgr->removeDeadBindings(Result, SymReaper);
119 bool notifyChanges)
const {
121 ProgramStateRef newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(),
135 const StoreRef &newStore = Mgr.StoreMgr->BindDefaultInitial(getStore(), R, V);
146 const StoreRef &newStore = Mgr.StoreMgr->BindDefaultZero(getStore(), R);
158 const Expr *E,
unsigned Count,
160 bool CausedByPointerEscape,
165 for (RegionList::const_iterator I = Regions.begin(),
166 End = Regions.end(); I !=
End; ++I)
169 return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
175 const Expr *E,
unsigned Count,
177 bool CausedByPointerEscape,
182 return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
187 ProgramState::invalidateRegionsImpl(
ValueList Values,
188 const Expr *E,
unsigned Count,
190 bool CausedByPointerEscape,
203 ITraits = &ITraitsLocal;
209 = Mgr.StoreMgr->invalidateRegions(getStore(), Values, E, Count, LCtx, Call,
210 *IS, *ITraits, &TopLevelInvalidated,
215 if (CausedByPointerEscape) {
223 Invalidated, LCtx, Call);
227 Mgr.StoreMgr->invalidateRegions(getStore(), Values, E, Count, LCtx, Call,
228 *IS, *ITraits,
nullptr,
nullptr);
229 return makeWithStore(newStore);
235 Store OldStore = getStore();
237 getStateManager().StoreMgr->killBinding(OldStore, LV);
239 if (newStore.
getStore() == OldStore)
242 return makeWithStore(newStore);
249 getStateManager().StoreMgr->enterStackFrame(getStore(), Call, CalleeCtx);
250 return makeWithStore(NewStore);
270 SVal V = getRawSVal(location, T);
280 if (
const llvm::APSInt *Int = getStateManager()
281 .getConstraintManager()
282 .getSymVal(
this, sym)) {
312 SVal V,
bool Invalidate)
const{
321 return getStateManager().getPersistentState(NewSt);
347 if (newIdx.isUnknownOrUndef())
377 return stateMgr->getSValBuilder().areEqual(
this, Lhs, Rhs);
391 return getStateManager().ConstraintMgr->isNull(
this, Sym);
397 StoreMgr->getInitialStore(InitLoc),
398 GDMFactory.getEmptyMap());
407 NewState.GDM = GDMState->GDM;
413 llvm::FoldingSetNodeID
ID;
417 if (
ProgramState *I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
421 if (!freeStates.empty()) {
422 newState = freeStates.back();
423 freeStates.pop_back();
429 StateSet.InsertNode(newState, InsertPos);
435 NewSt.setStore(store);
436 return getStateManager().getPersistentState(NewSt);
439 void ProgramState::setStore(
const StoreRef &newStore) {
442 stateMgr->getStoreManager().incrementReferenceCount(newStoreStore);
444 stateMgr->getStoreManager().decrementReferenceCount(store);
445 store = newStoreStore;
459 Env.print(Out, NL, Sep, LC);
468 printTaint(Out, NL, Sep);
475 print(Out,
"\\l",
"\\|", LC);
483 const char *NL,
const char *Sep)
const {
487 Out <<
"Tainted symbols:" << NL;
489 for (TaintMapImpl::iterator I = TM.begin(), E = TM.end(); I != E; ++I) {
490 Out << I->first <<
" : " << I->second << NL;
495 printTaint(llvm::errs());
499 return stateMgr->getOwningEngine()->getAnalysisManager();
507 return GDM.lookup(K);
512 void *(*CreateContext)(llvm::BumpPtrAllocator&),
513 void (*DeleteContext)(
void*)) {
515 std::pair<void*, void (*)(void*)>& p = GDMContexts[K];
517 p.first = CreateContext(Alloc);
518 p.second = DeleteContext;
549 bool wasVisited = !visited.insert(val.
getCVData()).second;
573 bool wasVisited = !visited.insert(*SI).second;
577 if (!visitor.VisitSymbol(*SI))
586 return scan(
X->getRegion());
593 return scan(
X->getLoc());
608 if (isa<MemSpaceRegion>(R))
611 bool wasVisited = !visited.insert(R).second;
615 if (!visitor.VisitMemRegion(R))
620 if (!visitor.VisitSymbol(SR->getSymbol()))
624 if (
const SubRegion *SR = dyn_cast<SubRegion>(R)) {
625 const MemRegion *Super = SR->getSuperRegion();
630 if (isa<MemSpaceRegion>(Super)) {
640 E = BDR->referenced_vars_end();
641 for ( ; I != E; ++I) {
658 for ( ; I != E; ++I) {
669 for ( ; I != E; ++I) {
679 if (
const Expr *E = dyn_cast_or_null<Expr>(S))
682 return addTaint(getSVal(S, LCtx), Kind);
689 return addTaint(Sym, Kind);
701 if (
Optional<SVal> binding = getStateManager().StoreMgr->getDefaultBinding(*LCV)) {
702 if (
SymbolRef Sym = binding->getAsSymbol())
703 return addPartialTaint(Sym, LCV->getRegion(),
Kind);
708 return addTaint(R, Kind);
713 if (
const SymbolicRegion *SR = dyn_cast_or_null<SymbolicRegion>(R))
714 return addTaint(SR->getSymbol(),
Kind);
722 while (
const SymbolCast *SC = dyn_cast<SymbolCast>(Sym))
723 Sym = SC->getOperand();
734 if (contains<TaintMap>(ParentSym) && *get<TaintMap>(ParentSym) == Kind)
739 return addTaint(ParentSym, Kind);
743 SavedRegs ? *SavedRegs : stateMgr->TSRFactory.getEmptyMap();
745 Regs = stateMgr->TSRFactory.add(Regs, SubRegion, Kind);
753 if (
const Expr *E = dyn_cast_or_null<Expr>(S))
756 SVal val = getSVal(S, LCtx);
757 return isTainted(val, Kind);
762 return isTainted(Sym, Kind);
764 return isTainted(Reg, Kind);
775 return isTainted(ER->getSuperRegion(), K) || isTainted(ER->getIndex(), K);
778 return isTainted(SR->getSymbol(), K);
780 if (
const SubRegion *ER = dyn_cast<SubRegion>(Reg))
781 return isTainted(ER->getSuperRegion(), K);
793 if (!isa<SymbolData>(*SI))
801 if (
const SymbolDerived *SD = dyn_cast<SymbolDerived>(*SI)) {
803 if (isTainted(SD->getParentSymbol(),
Kind))
810 get<DerivedSymTaint>(SD->getParentSymbol())) {
812 for (
auto I : *Regs) {
825 if (isTainted(SRV->getRegion(),
Kind))
830 if (
const SymbolCast *SC = dyn_cast<SymbolCast>(*SI)) {
831 if (isTainted(SC->getOperand(),
Kind))
virtual ProgramStateRef assume(ProgramStateRef state, DefinedSVal Cond, bool Assumption)=0
LLVM_NODISCARD 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()))
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...
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.
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.
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.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
llvm::ImmutableList< SVal >::iterator iterator
llvm::ImmutableMap< SymbolRef, TaintTagType > TaintMapImpl
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.
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
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.
LLVM_NODISCARD 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.
const VarRegion * getCapturedRegion() 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:
Expr - This represents one expression.
Represents a cast 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.
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()
void print(raw_ostream &Out, const char *nl="\, const char *sep="", const LocationContext *CurrentLC=nullptr) const
ProgramStateRef getInitialState(const LocationContext *InitLoc)
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.
ConditionTruthVal areEqual(SVal Lhs, SVal Rhs) const
llvm::ImmutableMap< const SubRegion *, TaintTagType > TaintedSubRegions
virtual void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep, const LocationContext *LCtx=nullptr)=0
printState - Called by ProgramStateManager to print checker-specific data.
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.
A symbol representing the value stored at a MemRegion.
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
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
LLVM_NODISCARD 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 printDOT(raw_ostream &Out, const LocationContext *CurrentLC=nullptr) const
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...
unsigned TaintTagType
The type of taint, which helps to differentiate between different types of taint. ...
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.
static void Profile(llvm::FoldingSetNodeID &ID, const ProgramState *V)
Profile - Profile the contents of a ProgramState object for use in a FoldingSet.
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
void printDynamicTypeInfo(ProgramStateRef State, raw_ostream &Out, const char *NL, const char *Sep)
bool isUnknownOrUndef() const
ArrayRef< SVal > ValueList
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
Iterator over symbols that the current symbol depends on.