clang  19.0.0git
ProgramState.cpp
Go to the documentation of this file.
1 //= ProgramState.cpp - Path-Sensitive "State" for tracking values --*- C++ -*--=
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements ProgramState and ProgramStateManager.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "clang/Analysis/CFG.h"
21 #include "llvm/Support/raw_ostream.h"
22 #include <optional>
23 
24 using namespace clang;
25 using namespace ento;
26 
27 namespace clang { namespace ento {
28 /// Increments the number of times this state is referenced.
29 
30 void ProgramStateRetain(const ProgramState *state) {
31  ++const_cast<ProgramState*>(state)->refCount;
32 }
33 
34 /// Decrement the number of times this state is referenced.
35 void ProgramStateRelease(const ProgramState *state) {
36  assert(state->refCount > 0);
37  ProgramState *s = const_cast<ProgramState*>(state);
38  if (--s->refCount == 0) {
39  ProgramStateManager &Mgr = s->getStateManager();
40  Mgr.StateSet.RemoveNode(s);
41  s->~ProgramState();
42  Mgr.freeStates.push_back(s);
43  }
44 }
45 }}
46 
48  StoreRef st, GenericDataMap gdm)
49  : stateMgr(mgr),
50  Env(env),
51  store(st.getStore()),
52  GDM(gdm),
53  refCount(0) {
54  stateMgr->getStoreManager().incrementReferenceCount(store);
55 }
56 
58  : stateMgr(RHS.stateMgr), Env(RHS.Env), store(RHS.store), GDM(RHS.GDM),
59  PosteriorlyOverconstrained(RHS.PosteriorlyOverconstrained), refCount(0) {
60  stateMgr->getStoreManager().incrementReferenceCount(store);
61 }
62 
64  if (store)
65  stateMgr->getStoreManager().decrementReferenceCount(store);
66 }
67 
69  return getStateManager().Alloc.identifyKnownAlignedObject<ProgramState>(this);
70 }
71 
73  StoreManagerCreator CreateSMgr,
74  ConstraintManagerCreator CreateCMgr,
75  llvm::BumpPtrAllocator &alloc,
76  ExprEngine *ExprEng)
77  : Eng(ExprEng), EnvMgr(alloc), GDMFactory(alloc),
78  svalBuilder(createSimpleSValBuilder(alloc, Ctx, *this)),
79  CallEventMgr(new CallEventManager(alloc)), Alloc(alloc) {
80  StoreMgr = (*CreateSMgr)(*this);
81  ConstraintMgr = (*CreateCMgr)(*this, ExprEng);
82 }
83 
84 
86  for (GDMContextsTy::iterator I=GDMContexts.begin(), E=GDMContexts.end();
87  I!=E; ++I)
88  I->second.second(I->second.first);
89 }
90 
92  ProgramStateRef state, const StackFrameContext *LCtx,
93  SymbolReaper &SymReaper) {
94 
95  // This code essentially performs a "mark-and-sweep" of the VariableBindings.
96  // The roots are any Block-level exprs and Decls that our liveness algorithm
97  // tells us are live. We then see what Decls they may reference, and keep
98  // those around. This code more than likely can be made faster, and the
99  // frequency of which this method is called should be experimented with
100  // for optimum performance.
101  ProgramState NewState = *state;
102 
103  NewState.Env = EnvMgr.removeDeadBindings(NewState.Env, SymReaper, state);
104 
105  // Clean up the store.
106  StoreRef newStore = StoreMgr->removeDeadBindings(NewState.getStore(), LCtx,
107  SymReaper);
108  NewState.setStore(newStore);
109  SymReaper.setReapedStore(newStore);
110 
111  return getPersistentState(NewState);
112 }
113 
115  SVal V,
116  const LocationContext *LCtx,
117  bool notifyChanges) const {
119  ProgramStateRef newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(),
120  LV, V));
121  const MemRegion *MR = LV.getAsRegion();
122  if (MR && notifyChanges)
123  return Mgr.getOwningEngine().processRegionChange(newState, MR, LCtx);
124 
125  return newState;
126 }
127 
130  const LocationContext *LCtx) const {
132  const MemRegion *R = loc.castAs<loc::MemRegionVal>().getRegion();
133  const StoreRef &newStore = Mgr.StoreMgr->BindDefaultInitial(getStore(), R, V);
134  ProgramStateRef new_state = makeWithStore(newStore);
135  return Mgr.getOwningEngine().processRegionChange(new_state, R, LCtx);
136 }
137 
141  const MemRegion *R = loc.castAs<loc::MemRegionVal>().getRegion();
142  const StoreRef &newStore = Mgr.StoreMgr->BindDefaultZero(getStore(), R);
143  ProgramStateRef new_state = makeWithStore(newStore);
144  return Mgr.getOwningEngine().processRegionChange(new_state, R, LCtx);
145 }
146 
149 
152  const Expr *E, unsigned Count,
153  const LocationContext *LCtx,
154  bool CausedByPointerEscape,
155  InvalidatedSymbols *IS,
156  const CallEvent *Call,
157  RegionAndSymbolInvalidationTraits *ITraits) const {
158  SmallVector<SVal, 8> Values;
159  for (const MemRegion *Reg : Regions)
160  Values.push_back(loc::MemRegionVal(Reg));
161 
162  return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
163  IS, ITraits, Call);
164 }
165 
168  const Expr *E, unsigned Count,
169  const LocationContext *LCtx,
170  bool CausedByPointerEscape,
171  InvalidatedSymbols *IS,
172  const CallEvent *Call,
173  RegionAndSymbolInvalidationTraits *ITraits) const {
174 
175  return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
176  IS, ITraits, Call);
177 }
178 
180 ProgramState::invalidateRegionsImpl(ValueList Values,
181  const Expr *E, unsigned Count,
182  const LocationContext *LCtx,
183  bool CausedByPointerEscape,
184  InvalidatedSymbols *IS,
186  const CallEvent *Call) const {
188  ExprEngine &Eng = Mgr.getOwningEngine();
189 
190  InvalidatedSymbols InvalidatedSyms;
191  if (!IS)
192  IS = &InvalidatedSyms;
193 
195  if (!ITraits)
196  ITraits = &ITraitsLocal;
197 
198  StoreManager::InvalidatedRegions TopLevelInvalidated;
200  const StoreRef &newStore
201  = Mgr.StoreMgr->invalidateRegions(getStore(), Values, E, Count, LCtx, Call,
202  *IS, *ITraits, &TopLevelInvalidated,
203  &Invalidated);
204 
205  ProgramStateRef newState = makeWithStore(newStore);
206 
207  if (CausedByPointerEscape) {
208  newState = Eng.notifyCheckersOfPointerEscape(newState, IS,
209  TopLevelInvalidated,
210  Call,
211  *ITraits);
212  }
213 
214  return Eng.processRegionChanges(newState, IS, TopLevelInvalidated,
215  Invalidated, LCtx, Call);
216 }
217 
219  Store OldStore = getStore();
220  const StoreRef &newStore =
221  getStateManager().StoreMgr->killBinding(OldStore, LV);
222 
223  if (newStore.getStore() == OldStore)
224  return this;
225 
226  return makeWithStore(newStore);
227 }
228 
229 /// SymbolicRegions are expected to be wrapped by an ElementRegion as a
230 /// canonical representation. As a canonical representation, SymbolicRegions
231 /// should be wrapped by ElementRegions before getting a FieldRegion.
232 /// See f8643a9b31c4029942f67d4534c9139b45173504 why.
233 SVal ProgramState::wrapSymbolicRegion(SVal Val) const {
234  const auto *BaseReg = dyn_cast_or_null<SymbolicRegion>(Val.getAsRegion());
235  if (!BaseReg)
236  return Val;
237 
239  QualType ElemTy = BaseReg->getPointeeStaticType();
240  return loc::MemRegionVal{SM.GetElementZeroRegion(BaseReg, ElemTy)};
241 }
242 
245  const StackFrameContext *CalleeCtx) const {
246  const StoreRef &NewStore =
247  getStateManager().StoreMgr->enterStackFrame(getStore(), Call, CalleeCtx);
248  return makeWithStore(NewStore);
249 }
250 
252  const ImplicitParamDecl *SelfDecl = LCtx->getSelfDecl();
253  if (!SelfDecl)
254  return SVal();
255  return getSVal(getRegion(SelfDecl, LCtx));
256 }
257 
259  // We only want to do fetches from regions that we can actually bind
260  // values. For example, SymbolicRegions of type 'id<...>' cannot
261  // have direct bindings (but their can be bindings on their subregions).
262  if (!R->isBoundable())
263  return UnknownVal();
264 
265  if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
266  QualType T = TR->getValueType();
268  return getSVal(R);
269  }
270 
271  return UnknownVal();
272 }
273 
275  SVal V = getRawSVal(location, T);
276 
277  // If 'V' is a symbolic value that is *perfectly* constrained to
278  // be a constant value, use that value instead to lessen the burden
279  // on later analysis stages (so we have less symbolic values to reason
280  // about).
281  // We only go into this branch if we can convert the APSInt value we have
282  // to the type of T, which is not always the case (e.g. for void).
283  if (!T.isNull() && (T->isIntegralOrEnumerationType() || Loc::isLocType(T))) {
284  if (SymbolRef sym = V.getAsSymbol()) {
285  if (const llvm::APSInt *Int = getStateManager()
287  .getSymVal(this, sym)) {
288  // FIXME: Because we don't correctly model (yet) sign-extension
289  // and truncation of symbolic values, we need to convert
290  // the integer value to the correct signedness and bitwidth.
291  //
292  // This shows up in the following:
293  //
294  // char foo();
295  // unsigned x = foo();
296  // if (x == 54)
297  // ...
298  //
299  // The symbolic value stored to 'x' is actually the conjured
300  // symbol for the call to foo(); the type of that symbol is 'char',
301  // not unsigned.
302  const llvm::APSInt &NewV = getBasicVals().Convert(T, *Int);
303 
304  if (V.getAs<Loc>())
305  return loc::ConcreteInt(NewV);
306  else
307  return nonloc::ConcreteInt(NewV);
308  }
309  }
310  }
311 
312  return V;
313 }
314 
316  const LocationContext *LCtx,
317  SVal V, bool Invalidate) const{
318  Environment NewEnv =
319  getStateManager().EnvMgr.bindExpr(Env, EnvironmentEntry(S, LCtx), V,
320  Invalidate);
321  if (NewEnv == Env)
322  return this;
323 
324  ProgramState NewSt = *this;
325  NewSt.Env = NewEnv;
326  return getStateManager().getPersistentState(NewSt);
327 }
328 
329 [[nodiscard]] std::pair<ProgramStateRef, ProgramStateRef>
331  DefinedOrUnknownSVal UpperBound,
332  QualType indexTy) const {
333  if (Idx.isUnknown() || UpperBound.isUnknown())
334  return {this, this};
335 
336  // Build an expression for 0 <= Idx < UpperBound.
337  // This is the same as Idx + MIN < UpperBound + MIN, if overflow is allowed.
338  // FIXME: This should probably be part of SValBuilder.
340  SValBuilder &svalBuilder = SM.getSValBuilder();
341  ASTContext &Ctx = svalBuilder.getContext();
342 
343  // Get the offset: the minimum value of the array index type.
344  BasicValueFactory &BVF = svalBuilder.getBasicValueFactory();
345  if (indexTy.isNull())
346  indexTy = svalBuilder.getArrayIndexType();
347  nonloc::ConcreteInt Min(BVF.getMinValue(indexTy));
348 
349  // Adjust the index.
350  SVal newIdx = svalBuilder.evalBinOpNN(this, BO_Add,
351  Idx.castAs<NonLoc>(), Min, indexTy);
352  if (newIdx.isUnknownOrUndef())
353  return {this, this};
354 
355  // Adjust the upper bound.
356  SVal newBound =
357  svalBuilder.evalBinOpNN(this, BO_Add, UpperBound.castAs<NonLoc>(),
358  Min, indexTy);
359 
360  if (newBound.isUnknownOrUndef())
361  return {this, this};
362 
363  // Build the actual comparison.
364  SVal inBound = svalBuilder.evalBinOpNN(this, BO_LT, newIdx.castAs<NonLoc>(),
365  newBound.castAs<NonLoc>(), Ctx.IntTy);
366  if (inBound.isUnknownOrUndef())
367  return {this, this};
368 
369  // Finally, let the constraint manager take care of it.
370  ConstraintManager &CM = SM.getConstraintManager();
371  return CM.assumeDual(this, inBound.castAs<DefinedSVal>());
372 }
373 
375  DefinedOrUnknownSVal UpperBound,
376  bool Assumption,
377  QualType indexTy) const {
378  std::pair<ProgramStateRef, ProgramStateRef> R =
379  assumeInBoundDual(Idx, UpperBound, indexTy);
380  return Assumption ? R.first : R.second;
381 }
382 
385  if (IsNull.isUnderconstrained())
386  return IsNull;
387  return ConditionTruthVal(!IsNull.getValue());
388 }
389 
391  return stateMgr->getSValBuilder().areEqual(this, Lhs, Rhs);
392 }
393 
395  if (V.isZeroConstant())
396  return true;
397 
398  if (V.isConstant())
399  return false;
400 
401  SymbolRef Sym = V.getAsSymbol(/* IncludeBaseRegion */ true);
402  if (!Sym)
403  return ConditionTruthVal();
404 
405  return getStateManager().ConstraintMgr->isNull(this, Sym);
406 }
407 
409  ProgramState State(this,
410  EnvMgr.getInitialEnvironment(),
411  StoreMgr->getInitialStore(InitLoc),
412  GDMFactory.getEmptyMap());
413 
414  return getPersistentState(State);
415 }
416 
418  ProgramStateRef FromState,
419  ProgramStateRef GDMState) {
420  ProgramState NewState(*FromState);
421  NewState.GDM = GDMState->GDM;
422  return getPersistentState(NewState);
423 }
424 
426 
427  llvm::FoldingSetNodeID ID;
428  State.Profile(ID);
429  void *InsertPos;
430 
431  if (ProgramState *I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
432  return I;
433 
434  ProgramState *newState = nullptr;
435  if (!freeStates.empty()) {
436  newState = freeStates.back();
437  freeStates.pop_back();
438  }
439  else {
440  newState = Alloc.Allocate<ProgramState>();
441  }
442  new (newState) ProgramState(State);
443  StateSet.InsertNode(newState, InsertPos);
444  return newState;
445 }
446 
447 ProgramStateRef ProgramState::makeWithStore(const StoreRef &store) const {
448  ProgramState NewSt(*this);
449  NewSt.setStore(store);
450  return getStateManager().getPersistentState(NewSt);
451 }
452 
453 ProgramStateRef ProgramState::cloneAsPosteriorlyOverconstrained() const {
454  ProgramState NewSt(*this);
455  NewSt.PosteriorlyOverconstrained = true;
456  return getStateManager().getPersistentState(NewSt);
457 }
458 
459 void ProgramState::setStore(const StoreRef &newStore) {
460  Store newStoreStore = newStore.getStore();
461  if (newStoreStore)
462  stateMgr->getStoreManager().incrementReferenceCount(newStoreStore);
463  if (store)
464  stateMgr->getStoreManager().decrementReferenceCount(store);
465  store = newStoreStore;
466 }
467 
469  Base = wrapSymbolicRegion(Base);
470  return getStateManager().StoreMgr->getLValueField(D, Base);
471 }
472 
474  StoreManager &SM = *getStateManager().StoreMgr;
475  Base = wrapSymbolicRegion(Base);
476 
477  // FIXME: This should work with `SM.getLValueField(D->getAnonField(), Base)`,
478  // but that would break some tests. There is probably a bug somewhere that it
479  // would expose.
480  for (const auto *I : D->chain()) {
481  Base = SM.getLValueField(cast<FieldDecl>(I), Base);
482  }
483  return Base;
484 }
485 
486 //===----------------------------------------------------------------------===//
487 // State pretty-printing.
488 //===----------------------------------------------------------------------===//
489 
490 void ProgramState::printJson(raw_ostream &Out, const LocationContext *LCtx,
491  const char *NL, unsigned int Space,
492  bool IsDot) const {
493  Indent(Out, Space, IsDot) << "\"program_state\": {" << NL;
494  ++Space;
495 
497 
498  // Print the store.
499  Mgr.getStoreManager().printJson(Out, getStore(), NL, Space, IsDot);
500 
501  // Print out the environment.
502  Env.printJson(Out, Mgr.getContext(), LCtx, NL, Space, IsDot);
503 
504  // Print out the constraints.
505  Mgr.getConstraintManager().printJson(Out, this, NL, Space, IsDot);
506 
507  // Print out the tracked dynamic types.
508  printDynamicTypeInfoJson(Out, this, NL, Space, IsDot);
509 
510  // Print checker-specific data.
511  Mgr.getOwningEngine().printJson(Out, this, LCtx, NL, Space, IsDot);
512 
513  --Space;
514  Indent(Out, Space, IsDot) << '}';
515 }
516 
517 void ProgramState::printDOT(raw_ostream &Out, const LocationContext *LCtx,
518  unsigned int Space) const {
519  printJson(Out, LCtx, /*NL=*/"\\l", Space, /*IsDot=*/true);
520 }
521 
522 LLVM_DUMP_METHOD void ProgramState::dump() const {
523  printJson(llvm::errs());
524 }
525 
527  return stateMgr->getOwningEngine().getAnalysisManager();
528 }
529 
530 //===----------------------------------------------------------------------===//
531 // Generic Data Map.
532 //===----------------------------------------------------------------------===//
533 
534 void *const* ProgramState::FindGDM(void *K) const {
535  return GDM.lookup(K);
536 }
537 
538 void*
540  void *(*CreateContext)(llvm::BumpPtrAllocator&),
541  void (*DeleteContext)(void*)) {
542 
543  std::pair<void*, void (*)(void*)>& p = GDMContexts[K];
544  if (!p.first) {
545  p.first = CreateContext(Alloc);
546  p.second = DeleteContext;
547  }
548 
549  return p.first;
550 }
551 
553  ProgramState::GenericDataMap M1 = St->getGDM();
554  ProgramState::GenericDataMap M2 = GDMFactory.add(M1, Key, Data);
555 
556  if (M1 == M2)
557  return St;
558 
559  ProgramState NewSt = *St;
560  NewSt.GDM = M2;
561  return getPersistentState(NewSt);
562 }
563 
565  ProgramState::GenericDataMap OldM = state->getGDM();
566  ProgramState::GenericDataMap NewM = GDMFactory.remove(OldM, Key);
567 
568  if (NewM == OldM)
569  return state;
570 
571  ProgramState NewState = *state;
572  NewState.GDM = NewM;
573  return getPersistentState(NewState);
574 }
575 
577  bool wasVisited = !visited.insert(val.getCVData()).second;
578  if (wasVisited)
579  return true;
580 
581  StoreManager &StoreMgr = state->getStateManager().getStoreManager();
582  // FIXME: We don't really want to use getBaseRegion() here because pointer
583  // arithmetic doesn't apply, but scanReachableSymbols only accepts base
584  // regions right now.
585  const MemRegion *R = val.getRegion()->getBaseRegion();
586  return StoreMgr.scanReachableSymbols(val.getStore(), R, *this);
587 }
588 
590  for (SVal V : val)
591  if (!scan(V))
592  return false;
593 
594  return true;
595 }
596 
598  for (SymbolRef SubSym : sym->symbols()) {
599  bool wasVisited = !visited.insert(SubSym).second;
600  if (wasVisited)
601  continue;
602 
603  if (!visitor.VisitSymbol(SubSym))
604  return false;
605  }
606 
607  return true;
608 }
609 
611  if (std::optional<loc::MemRegionVal> X = val.getAs<loc::MemRegionVal>())
612  return scan(X->getRegion());
613 
614  if (std::optional<nonloc::LazyCompoundVal> X =
616  return scan(*X);
617 
618  if (std::optional<nonloc::LocAsInteger> X = val.getAs<nonloc::LocAsInteger>())
619  return scan(X->getLoc());
620 
621  if (SymbolRef Sym = val.getAsSymbol())
622  return scan(Sym);
623 
624  if (std::optional<nonloc::CompoundVal> X = val.getAs<nonloc::CompoundVal>())
625  return scan(*X);
626 
627  return true;
628 }
629 
631  if (isa<MemSpaceRegion>(R))
632  return true;
633 
634  bool wasVisited = !visited.insert(R).second;
635  if (wasVisited)
636  return true;
637 
638  if (!visitor.VisitMemRegion(R))
639  return false;
640 
641  // If this is a symbolic region, visit the symbol for the region.
642  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
643  if (!visitor.VisitSymbol(SR->getSymbol()))
644  return false;
645 
646  // If this is a subregion, also visit the parent regions.
647  if (const SubRegion *SR = dyn_cast<SubRegion>(R)) {
648  const MemRegion *Super = SR->getSuperRegion();
649  if (!scan(Super))
650  return false;
651 
652  // When we reach the topmost region, scan all symbols in it.
653  if (isa<MemSpaceRegion>(Super)) {
654  StoreManager &StoreMgr = state->getStateManager().getStoreManager();
655  if (!StoreMgr.scanReachableSymbols(state->getStore(), SR, *this))
656  return false;
657  }
658  }
659 
660  // Regions captured by a block are also implicitly reachable.
661  if (const BlockDataRegion *BDR = dyn_cast<BlockDataRegion>(R)) {
662  for (auto Var : BDR->referenced_vars()) {
663  if (!scan(Var.getCapturedRegion()))
664  return false;
665  }
666  }
667 
668  return true;
669 }
670 
672  ScanReachableSymbols S(this, visitor);
673  return S.scan(val);
674 }
675 
677  llvm::iterator_range<region_iterator> Reachable,
678  SymbolVisitor &visitor) const {
679  ScanReachableSymbols S(this, visitor);
680  for (const MemRegion *R : Reachable) {
681  if (!S.scan(R))
682  return false;
683  }
684  return true;
685 }
#define V(N, I)
Definition: ASTContext.h:3299
static char ID
Definition: Arena.cpp:183
#define SM(sm)
Definition: Cuda.cpp:83
llvm::APSInt APSInt
const Environment & Env
Definition: HTMLLogger.cpp:148
#define X(type, name)
Definition: Value.h:143
ArrayRef< const MemRegion * > RegionList
ArrayRef< SVal > ValueList
const char * Data
LineState State
__device__ __2f16 float __ockl_bool s
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:185
CanQualType IntTy
Definition: ASTContext.h:1103
This represents one expression.
Definition: Expr.h:110
Represents a member of a struct/union/class.
Definition: Decl.h:3060
Represents a field injected from an anonymous union/struct into the parent scope.
Definition: Decl.h:3344
ArrayRef< NamedDecl * > chain() const
Definition: Decl.h:3366
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
const ImplicitParamDecl * getSelfDecl() const
A (possibly-)qualified type.
Definition: Type.h:940
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1007
It represents a stack frame of the call stack (based on CallEvent).
Stmt - This represents one statement.
Definition: Stmt.h:84
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition: Type.h:8054
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...
const llvm::APSInt & getMinValue(const llvm::APSInt &v)
BlockDataRegion - A region that represents a block instance.
Definition: MemRegion.h:673
Manages the lifetime of CallEvent objects.
Definition: CallEvent.h:1356
Represents an abstract call to a function or method along a particular path.
Definition: CallEvent.h:153
ProgramStatePair assumeDual(ProgramStateRef State, DefinedSVal Cond)
Returns a pair of states (StTrue, StFalse) where the given condition is assumed to be true or false,...
virtual void printJson(raw_ostream &Out, ProgramStateRef State, const char *NL, unsigned int Space, bool IsDot) const =0
An entry in the environment consists of a Stmt and an LocationContext.
Definition: Environment.h:36
Environment bindExpr(Environment Env, const EnvironmentEntry &E, SVal V, bool Invalidate)
Bind a symbolic value to the given environment entry.
Environment removeDeadBindings(Environment Env, SymbolReaper &SymReaper, ProgramStateRef state)
An immutable map from EnvironemntEntries to SVals.
Definition: Environment.h:56
void printJson(raw_ostream &Out, const ASTContext &Ctx, const LocationContext *LCtx=nullptr, const char *NL="\n", unsigned int Space=0, bool IsDot=false) const
ProgramStateRef processRegionChange(ProgramStateRef state, const MemRegion *MR, const LocationContext *LCtx)
Definition: ExprEngine.h:399
void printJson(raw_ostream &Out, ProgramStateRef State, const LocationContext *LCtx, const char *NL, unsigned int Space, bool IsDot) const
printJson - Called by ProgramStateManager to print checker-specific data.
Definition: ExprEngine.cpp:939
ProgramStateRef processRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const LocationContext *LCtx, const CallEvent *Call)
processRegionChanges - Called by ProgramStateManager whenever a change is made to the store.
Definition: ExprEngine.cpp:673
ProgramStateRef notifyCheckersOfPointerEscape(ProgramStateRef State, const InvalidatedSymbols *Invalidated, ArrayRef< const MemRegion * > ExplicitRegions, const CallEvent *Call, RegionAndSymbolInvalidationTraits &ITraits)
Call PointerEscape callback when a value escapes as a result of region invalidation.
AnalysisManager & getAnalysisManager()
Definition: ExprEngine.h:198
static bool isLocType(QualType T)
Definition: SVals.h:259
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:96
virtual bool isBoundable() const
Definition: MemRegion.h:178
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getBaseRegion() const
Definition: MemRegion.cpp:1343
ProgramStateRef removeDeadBindingsFromEnvironmentAndStore(ProgramStateRef St, const StackFrameContext *LCtx, SymbolReaper &SymReaper)
ProgramStateRef removeGDM(ProgramStateRef state, void *Key)
void * FindGDMContext(void *index, void *(*CreateContext)(llvm::BumpPtrAllocator &), void(*DeleteContext)(void *))
ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState, ProgramStateRef GDMState)
ProgramStateRef addGDM(ProgramStateRef St, void *Key, void *Data)
ProgramStateRef getPersistentState(ProgramState &Impl)
ProgramStateRef getInitialState(const LocationContext *InitLoc)
ConstraintManager & getConstraintManager()
Definition: ProgramState.h:582
ProgramStateManager(ASTContext &Ctx, StoreManagerCreator CreateStoreManager, ConstraintManagerCreator CreateConstraintManager, llvm::BumpPtrAllocator &alloc, ExprEngine *expreng)
ProgramState - This class encapsulates:
Definition: ProgramState.h:71
bool scanReachableSymbols(SVal val, SymbolVisitor &visitor) const
Visits the symbols reachable from the given SVal using the provided SymbolVisitor.
Loc getLValue(const CXXBaseSpecifier &BaseSpec, const SubRegion *Super) const
Get the lvalue for a base class object reference.
Definition: ProgramState.h:757
ProgramStateRef bindDefaultZero(SVal loc, const LocationContext *LCtx) const
Performs C++ zero-initialization procedure on the region of memory represented by loc.
llvm::ImmutableMap< void *, void * > GenericDataMap
Definition: ProgramState.h:74
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.
void printJson(raw_ostream &Out, const LocationContext *LCtx=nullptr, const char *NL="\n", unsigned int Space=0, bool IsDot=false) const
ProgramStateRef bindDefaultInitial(SVal loc, SVal V, const LocationContext *LCtx) const
Initializes the region of memory represented by loc with an initial value.
ConstraintManager & getConstraintManager() const
Return the ConstraintManager.
Definition: ProgramState.h:698
SVal getSValAsScalarOrLoc(const Stmt *Ex, const LocationContext *LCtx) const
Definition: ProgramState.h:800
SVal getSelfSVal(const LocationContext *LC) const
Return the value of 'self' if available in the given context.
SVal getRawSVal(Loc LV, QualType T=QualType()) const
Returns the "raw" SVal bound to LV before any value simplfication.
Definition: ProgramState.h:812
ConditionTruthVal isNull(SVal V) const
Check if the given SVal is constrained to zero or is a zero constant.
ProgramStateManager & getStateManager() const
Return the ProgramStateManager associated with this state.
Definition: ProgramState.h:147
ProgramStateRef killBinding(Loc LV) const
ProgramState(ProgramStateManager *mgr, const Environment &env, StoreRef st, GenericDataMap gdm)
This ctor is used when creating the first ProgramState object.
Store getStore() const
Return the store associated with this state.
Definition: ProgramState.h:162
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.
ConditionTruthVal areEqual(SVal Lhs, SVal Rhs) const
void printDOT(raw_ostream &Out, const LocationContext *LCtx=nullptr, unsigned int Space=0) const
ConditionTruthVal isNonNull(SVal V) const
Check if the given SVal is not constrained to zero and is not a zero constant.
ProgramStateRef assumeInBound(DefinedOrUnknownSVal idx, DefinedOrUnknownSVal upperBound, bool assumption, QualType IndexType=QualType()) const
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_ATTRIBUTE_RETURNS_NONNULL const VarRegion * getRegion(const VarDecl *D, const LocationContext *LC) const
Utility method for getting regions.
Definition: ProgramState.h:702
SVal getSVal(const Stmt *S, const LocationContext *LCtx) const
Returns the SVal bound to the statement 'S' in the state's environment.
Definition: ProgramState.h:793
ProgramStateRef bindLoc(Loc location, SVal V, const LocationContext *LCtx, bool notifyChanges=true) const
BasicValueFactory & getBasicVals() const
Definition: ProgramState.h:822
std::pair< ProgramStateRef, ProgramStateRef > assumeInBoundDual(DefinedOrUnknownSVal idx, DefinedOrUnknownSVal upperBound, QualType IndexType=QualType()) const
AnalysisManager & getAnalysisManager() const
void *const * FindGDM(void *K) const
Information about invalidation for a particular region/symbol.
Definition: MemRegion.h:1624
ASTContext & getContext()
Definition: SValBuilder.h:148
BasicValueFactory & getBasicValueFactory()
Definition: SValBuilder.h:161
QualType getArrayIndexType() const
Definition: SValBuilder.h:157
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.
ConditionTruthVal areEqual(ProgramStateRef state, SVal lhs, SVal rhs)
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition: SVals.h:55
bool isUnknownOrUndef() const
Definition: SVals.h:106
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
Definition: SVals.cpp:104
const MemRegion * getAsRegion() const
Definition: SVals.cpp:120
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
Definition: SVals.h:86
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
Definition: SVals.h:82
bool isUnknown() const
Definition: SVals.h:102
A utility class that visits the reachable symbols using a custom SymbolVisitor.
Definition: ProgramState.h:893
bool scan(nonloc::LazyCompoundVal val)
virtual bool scanReachableSymbols(Store S, const MemRegion *R, ScanReachableSymbols &Visitor)=0
Finds the transitive closure of symbols within the given region.
virtual void decrementReferenceCount(Store store)
If the StoreManager supports it, decrement the reference count of the specified Store object.
Definition: Store.h:201
virtual void incrementReferenceCount(Store store)
If the StoreManager supports it, increment the reference count of the specified Store object.
Definition: Store.h:196
virtual void printJson(raw_ostream &Out, Store S, const char *NL, unsigned int Space, bool IsDot) const =0
Store getStore() const
Definition: StoreRef.h:46
SubRegion - A region that subsets another larger region.
Definition: MemRegion.h:441
Symbolic value.
Definition: SymExpr.h:30
llvm::iterator_range< symbol_iterator > symbols() const
Definition: SymExpr.h:87
A class responsible for cleaning up unused symbols.
void setReapedStore(StoreRef st)
Set to the value of the symbolic store after StoreManager::removeDeadBindings has been called.
virtual bool VisitMemRegion(const MemRegion *)
virtual bool VisitSymbol(SymbolRef sym)=0
A visitor method invoked by ProgramStateManager::scanReachableSymbols.
SymbolicRegion - A special, "non-concrete" region.
Definition: MemRegion.h:775
TypedValueRegion - An abstract class representing regions having a typed value.
Definition: MemRegion.h:530
Value representing integer constant.
Definition: SVals.h:297
LLVM_ATTRIBUTE_RETURNS_NONNULL const TypedValueRegion * getRegion() const
Definition: SVals.cpp:194
LLVM_ATTRIBUTE_RETURNS_NONNULL const LazyCompoundValData * getCVData() const
Definition: SVals.h:359
const void * getStore() const
It might return null.
Definition: SVals.cpp:190
std::unique_ptr< StoreManager >(* StoreManagerCreator)(ProgramStateManager &)
Definition: ProgramState.h:44
SValBuilder * createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, ProgramStateManager &stateMgr)
void printDynamicTypeInfoJson(raw_ostream &Out, ProgramStateRef State, const char *NL="\n", unsigned int Space=0, bool IsDot=false)
std::unique_ptr< ConstraintManager >(* ConstraintManagerCreator)(ProgramStateManager &, ExprEngine *)
Definition: ProgramState.h:42
const void * Store
Store - This opaque type encapsulates an immutable mapping from locations to values.
Definition: StoreRef.h:27
void ProgramStateRetain(const ProgramState *state)
Increments the number of times this state is referenced.
void ProgramStateRelease(const ProgramState *state)
Decrement the number of times this state is referenced.
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
Definition: JsonSupport.h:21
long int64_t