22 #include "llvm/Support/raw_ostream.h" 24 using namespace clang;
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),
79 llvm::BumpPtrAllocator &alloc,
81 : Eng(SubEng), EnvMgr(alloc), GDMFactory(alloc),
84 StoreMgr = (*CreateSMgr)(*this);
85 ConstraintMgr = (*CreateCMgr)(*
this, SubEng);
90 for (GDMContextsTy::iterator I=GDMContexts.begin(), E=GDMContexts.end();
92 I->second.second(I->second.first);
113 NewState.setStore(newStore);
117 return ConstraintMgr->removeDeadBindings(Result, SymReaper);
123 bool notifyChanges)
const {
125 ProgramStateRef newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(),
128 if (MR && notifyChanges)
139 const StoreRef &newStore = Mgr.StoreMgr->BindDefaultInitial(getStore(), R, V);
148 const StoreRef &newStore = Mgr.StoreMgr->BindDefaultZero(getStore(), R);
158 const Expr *E,
unsigned Count,
160 bool CausedByPointerEscape,
163 RegionAndSymbolInvalidationTraits *ITraits)
const {
165 for (RegionList::const_iterator I = Regions.begin(),
166 End = Regions.end(); I !=
End; ++I)
167 Values.push_back(loc::MemRegionVal(*I));
169 return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
175 const Expr *E,
unsigned Count,
177 bool CausedByPointerEscape,
180 RegionAndSymbolInvalidationTraits *ITraits)
const {
182 return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
187 ProgramState::invalidateRegionsImpl(
ValueList Values,
188 const Expr *E,
unsigned Count,
190 bool CausedByPointerEscape,
192 RegionAndSymbolInvalidationTraits *ITraits,
195 SubEngine &Eng = Mgr.getOwningEngine();
199 IS = &InvalidatedSyms;
201 RegionAndSymbolInvalidationTraits ITraitsLocal;
203 ITraits = &ITraitsLocal;
207 const StoreRef &newStore
208 = Mgr.StoreMgr->invalidateRegions(getStore(), Values, E, Count, LCtx, Call,
209 *IS, *ITraits, &TopLevelInvalidated,
214 if (CausedByPointerEscape) {
215 newState = Eng.notifyCheckersOfPointerEscape(newState, IS,
221 return Eng.processRegionChanges(newState, IS, TopLevelInvalidated,
222 Invalidated, LCtx, Call);
228 Store OldStore = getStore();
230 getStateManager().StoreMgr->killBinding(OldStore, LV);
232 if (newStore.
getStore() == OldStore)
235 return makeWithStore(newStore);
242 getStateManager().StoreMgr->enterStackFrame(getStore(), Call, CalleeCtx);
243 return makeWithStore(NewStore);
263 SVal V = getRawSVal(location, T);
273 if (
const llvm::APSInt *Int = getStateManager()
274 .getConstraintManager()
275 .getSymVal(
this, sym)) {
305 SVal V,
bool Invalidate)
const{
314 return getStateManager().getPersistentState(NewSt);
340 if (newIdx.isUnknownOrUndef())
370 return stateMgr->getSValBuilder().areEqual(
this, Lhs, Rhs);
384 return getStateManager().ConstraintMgr->isNull(
this, Sym);
390 StoreMgr->getInitialStore(InitLoc),
391 GDMFactory.getEmptyMap());
400 NewState.GDM = GDMState->GDM;
406 llvm::FoldingSetNodeID
ID;
410 if (
ProgramState *I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
414 if (!freeStates.empty()) {
415 newState = freeStates.back();
416 freeStates.pop_back();
422 StateSet.InsertNode(newState, InsertPos);
428 NewSt.setStore(store);
429 return getStateManager().getPersistentState(NewSt);
432 void ProgramState::setStore(
const StoreRef &newStore) {
435 stateMgr->getStoreManager().incrementReferenceCount(newStoreStore);
437 stateMgr->getStoreManager().decrementReferenceCount(store);
438 store = newStoreStore;
446 const char *NL,
const char *Sep,
450 const ASTContext &Context = getStateManager().getContext();
454 Env.print(Out, NL, Sep, Context, LC);
471 print(Out,
"\\l",
"\\|", LC);
479 const char *NL)
const {
483 Out <<
"Tainted symbols:" << NL;
485 for (TaintMapImpl::iterator I = TM.begin(), E = TM.end(); I != E; ++I) {
486 Out << I->first <<
" : " << I->second << NL;
491 printTaint(llvm::errs());
495 return stateMgr->getOwningEngine().getAnalysisManager();
503 return GDM.lookup(K);
508 void *(*CreateContext)(llvm::BumpPtrAllocator&),
509 void (*DeleteContext)(
void*)) {
511 std::pair<void*, void (*)(void*)>& p = GDMContexts[K];
513 p.first = CreateContext(Alloc);
514 p.second = DeleteContext;
545 bool wasVisited = !visited.insert(val.
getCVData()).second;
569 bool wasVisited = !visited.insert(*SI).second;
573 if (!visitor.VisitSymbol(*SI))
582 return scan(
X->getRegion());
589 return scan(
X->getLoc());
604 if (isa<MemSpaceRegion>(R))
607 bool wasVisited = !visited.insert(R).second;
611 if (!visitor.VisitMemRegion(R))
616 if (!visitor.VisitSymbol(SR->getSymbol()))
620 if (
const SubRegion *SR = dyn_cast<SubRegion>(R)) {
621 const MemRegion *Super = SR->getSuperRegion();
626 if (isa<MemSpaceRegion>(Super)) {
636 E = BDR->referenced_vars_end();
637 for ( ; I != E; ++I) {
652 llvm::iterator_range<region_iterator> Reachable,
665 if (
const Expr *E = dyn_cast_or_null<Expr>(S))
668 return addTaint(getSVal(S, LCtx), Kind);
675 return addTaint(Sym, Kind);
687 if (
Optional<SVal> binding = getStateManager().StoreMgr->getDefaultBinding(*LCV)) {
688 if (
SymbolRef Sym = binding->getAsSymbol())
689 return addPartialTaint(Sym, LCV->getRegion(),
Kind);
694 return addTaint(R, Kind);
699 if (
const SymbolicRegion *SR = dyn_cast_or_null<SymbolicRegion>(R))
700 return addTaint(SR->getSymbol(),
Kind);
708 while (
const SymbolCast *SC = dyn_cast<SymbolCast>(Sym))
709 Sym = SC->getOperand();
720 if (contains<TaintMap>(ParentSym) && *get<TaintMap>(ParentSym) == Kind)
725 return addTaint(ParentSym, Kind);
729 SavedRegs ? *SavedRegs : stateMgr->TSRFactory.getEmptyMap();
731 Regs = stateMgr->TSRFactory.add(Regs, SubRegion, Kind);
739 if (
const Expr *E = dyn_cast_or_null<Expr>(S))
742 SVal val = getSVal(S, LCtx);
743 return isTainted(val, Kind);
748 return isTainted(Sym, Kind);
750 return isTainted(Reg, Kind);
761 return isTainted(ER->getSuperRegion(), K) || isTainted(ER->getIndex(), K);
764 return isTainted(SR->getSymbol(), K);
766 if (
const SubRegion *ER = dyn_cast<SubRegion>(Reg))
767 return isTainted(ER->getSuperRegion(), K);
779 if (!isa<SymbolData>(*SI))
787 if (
const SymbolDerived *SD = dyn_cast<SymbolDerived>(*SI)) {
789 if (isTainted(SD->getParentSymbol(),
Kind))
796 get<DerivedSymTaint>(SD->getParentSymbol())) {
798 for (
auto I : *Regs) {
811 if (isTainted(SRV->getRegion(),
Kind))
816 if (
const SymbolCast *SC = dyn_cast<SymbolCast>(*SI)) {
817 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...
llvm::DenseSet< SymbolRef > InvalidatedSymbols
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.
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.
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 &)
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.
bool isTainted(const Stmt *S, const LocationContext *LCtx, TaintTagType Kind=TaintTagGeneric) const
Check if the statement is tainted in the current 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 print(Store store, raw_ostream &Out, const char *nl)=0
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.
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.
virtual void print(ProgramStateRef state, raw_ostream &Out, const char *nl, const char *sep)=0
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.
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:
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...
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()
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...
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
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
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
void printTaint(raw_ostream &Out, const char *nl="\) const
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 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. ...
ElementRegion 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.