ProgramState.cpp revision 256281
133965Sjdp//= ProgramState.cpp - Path-Sensitive "State" for tracking values --*- C++ -*--=
233965Sjdp//
333965Sjdp//                     The LLVM Compiler Infrastructure
433965Sjdp//
533965Sjdp// This file is distributed under the University of Illinois Open Source
633965Sjdp// License. See LICENSE.TXT for details.
733965Sjdp//
833965Sjdp//===----------------------------------------------------------------------===//
933965Sjdp//
1033965Sjdp//  This file implements ProgramState and ProgramStateManager.
1133965Sjdp//
1233965Sjdp//===----------------------------------------------------------------------===//
1333965Sjdp
1433965Sjdp#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
1533965Sjdp#include "clang/Analysis/CFG.h"
1633965Sjdp#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
1733965Sjdp#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
1833965Sjdp#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
1933965Sjdp#include "clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h"
2033965Sjdp#include "llvm/Support/raw_ostream.h"
2133965Sjdp
2233965Sjdpusing namespace clang;
2333965Sjdpusing namespace ento;
2433965Sjdp
2533965Sjdpnamespace clang { namespace  ento {
2633965Sjdp/// Increments the number of times this state is referenced.
2733965Sjdp
2833965Sjdpvoid ProgramStateRetain(const ProgramState *state) {
2933965Sjdp  ++const_cast<ProgramState*>(state)->refCount;
3033965Sjdp}
3133965Sjdp
3233965Sjdp/// Decrement the number of times this state is referenced.
3333965Sjdpvoid ProgramStateRelease(const ProgramState *state) {
3433965Sjdp  assert(state->refCount > 0);
3533965Sjdp  ProgramState *s = const_cast<ProgramState*>(state);
3633965Sjdp  if (--s->refCount == 0) {
3733965Sjdp    ProgramStateManager &Mgr = s->getStateManager();
3833965Sjdp    Mgr.StateSet.RemoveNode(s);
3933965Sjdp    s->~ProgramState();
4033965Sjdp    Mgr.freeStates.push_back(s);
4133965Sjdp  }
4233965Sjdp}
4333965Sjdp}}
4433965Sjdp
4533965SjdpProgramState::ProgramState(ProgramStateManager *mgr, const Environment& env,
4633965Sjdp                 StoreRef st, GenericDataMap gdm)
4733965Sjdp  : stateMgr(mgr),
4833965Sjdp    Env(env),
4933965Sjdp    store(st.getStore()),
5033965Sjdp    GDM(gdm),
5133965Sjdp    refCount(0) {
5233965Sjdp  stateMgr->getStoreManager().incrementReferenceCount(store);
5333965Sjdp}
5433965Sjdp
5533965SjdpProgramState::ProgramState(const ProgramState &RHS)
5633965Sjdp    : llvm::FoldingSetNode(),
5733965Sjdp      stateMgr(RHS.stateMgr),
5833965Sjdp      Env(RHS.Env),
5933965Sjdp      store(RHS.store),
6033965Sjdp      GDM(RHS.GDM),
6133965Sjdp      refCount(0) {
6233965Sjdp  stateMgr->getStoreManager().incrementReferenceCount(store);
6333965Sjdp}
6433965Sjdp
6533965SjdpProgramState::~ProgramState() {
6633965Sjdp  if (store)
6733965Sjdp    stateMgr->getStoreManager().decrementReferenceCount(store);
6833965Sjdp}
6933965Sjdp
7033965SjdpProgramStateManager::ProgramStateManager(ASTContext &Ctx,
7133965Sjdp                                         StoreManagerCreator CreateSMgr,
7233965Sjdp                                         ConstraintManagerCreator CreateCMgr,
7333965Sjdp                                         llvm::BumpPtrAllocator &alloc,
7433965Sjdp                                         SubEngine *SubEng)
7533965Sjdp  : Eng(SubEng), EnvMgr(alloc), GDMFactory(alloc),
7633965Sjdp    svalBuilder(createSimpleSValBuilder(alloc, Ctx, *this)),
7733965Sjdp    CallEventMgr(new CallEventManager(alloc)), Alloc(alloc) {
7833965Sjdp  StoreMgr.reset((*CreateSMgr)(*this));
7933965Sjdp  ConstraintMgr.reset((*CreateCMgr)(*this, SubEng));
8033965Sjdp}
8133965Sjdp
8233965Sjdp
8333965SjdpProgramStateManager::~ProgramStateManager() {
8433965Sjdp  for (GDMContextsTy::iterator I=GDMContexts.begin(), E=GDMContexts.end();
8533965Sjdp       I!=E; ++I)
8633965Sjdp    I->second.second(I->second.first);
8733965Sjdp}
8833965Sjdp
8933965SjdpProgramStateRef
9033965SjdpProgramStateManager::removeDeadBindings(ProgramStateRef state,
9133965Sjdp                                   const StackFrameContext *LCtx,
9233965Sjdp                                   SymbolReaper& SymReaper) {
9333965Sjdp
9433965Sjdp  // This code essentially performs a "mark-and-sweep" of the VariableBindings.
9533965Sjdp  // The roots are any Block-level exprs and Decls that our liveness algorithm
9633965Sjdp  // tells us are live.  We then see what Decls they may reference, and keep
9733965Sjdp  // those around.  This code more than likely can be made faster, and the
9833965Sjdp  // frequency of which this method is called should be experimented with
9933965Sjdp  // for optimum performance.
10033965Sjdp  ProgramState NewState = *state;
10133965Sjdp
10233965Sjdp  NewState.Env = EnvMgr.removeDeadBindings(NewState.Env, SymReaper, state);
10333965Sjdp
10433965Sjdp  // Clean up the store.
10533965Sjdp  StoreRef newStore = StoreMgr->removeDeadBindings(NewState.getStore(), LCtx,
10633965Sjdp                                                   SymReaper);
10733965Sjdp  NewState.setStore(newStore);
10833965Sjdp  SymReaper.setReapedStore(newStore);
10933965Sjdp
11033965Sjdp  ProgramStateRef Result = getPersistentState(NewState);
11133965Sjdp  return ConstraintMgr->removeDeadBindings(Result, SymReaper);
11233965Sjdp}
11333965Sjdp
11433965SjdpProgramStateRef ProgramState::bindLoc(Loc LV, SVal V, bool notifyChanges) const {
11533965Sjdp  ProgramStateManager &Mgr = getStateManager();
11633965Sjdp  ProgramStateRef newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(),
11733965Sjdp                                                             LV, V));
11833965Sjdp  const MemRegion *MR = LV.getAsRegion();
11933965Sjdp  if (MR && Mgr.getOwningEngine() && notifyChanges)
12033965Sjdp    return Mgr.getOwningEngine()->processRegionChange(newState, MR);
12133965Sjdp
12233965Sjdp  return newState;
12333965Sjdp}
12433965Sjdp
12533965SjdpProgramStateRef ProgramState::bindDefault(SVal loc, SVal V) const {
12633965Sjdp  ProgramStateManager &Mgr = getStateManager();
12733965Sjdp  const MemRegion *R = loc.castAs<loc::MemRegionVal>().getRegion();
12833965Sjdp  const StoreRef &newStore = Mgr.StoreMgr->BindDefault(getStore(), R, V);
12933965Sjdp  ProgramStateRef new_state = makeWithStore(newStore);
13033965Sjdp  return Mgr.getOwningEngine() ?
13133965Sjdp           Mgr.getOwningEngine()->processRegionChange(new_state, R) :
13233965Sjdp           new_state;
13333965Sjdp}
13433965Sjdp
13533965Sjdptypedef ArrayRef<const MemRegion *> RegionList;
13633965Sjdptypedef ArrayRef<SVal> ValueList;
13733965Sjdp
13833965SjdpProgramStateRef
13933965SjdpProgramState::invalidateRegions(RegionList Regions,
14033965Sjdp                                const Expr *E, unsigned Count,
14133965Sjdp                                const LocationContext *LCtx,
14233965Sjdp                                bool CausedByPointerEscape,
14333965Sjdp                                InvalidatedSymbols *IS,
14433965Sjdp                                const CallEvent *Call,
14533965Sjdp                                RegionList ConstRegions) const {
14633965Sjdp  SmallVector<SVal, 8> Values;
14733965Sjdp  for (RegionList::const_iterator I = Regions.begin(),
14833965Sjdp                                  End = Regions.end(); I != End; ++I)
14933965Sjdp    Values.push_back(loc::MemRegionVal(*I));
15033965Sjdp
15133965Sjdp  SmallVector<SVal, 8> ConstValues;
15233965Sjdp  for (RegionList::const_iterator I = ConstRegions.begin(),
15333965Sjdp                                  End = ConstRegions.end(); I != End; ++I)
15433965Sjdp    ConstValues.push_back(loc::MemRegionVal(*I));
15533965Sjdp
15633965Sjdp  if (!IS) {
15733965Sjdp    InvalidatedSymbols invalidated;
15833965Sjdp    return invalidateRegionsImpl(Values, E, Count, LCtx,
15933965Sjdp                                 CausedByPointerEscape,
16033965Sjdp                                 invalidated, Call, ConstValues);
16133965Sjdp  }
16233965Sjdp  return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
16333965Sjdp                               *IS, Call, ConstValues);
16433965Sjdp}
16533965Sjdp
16633965SjdpProgramStateRef
16733965SjdpProgramState::invalidateRegions(ValueList Values,
16833965Sjdp                                const Expr *E, unsigned Count,
16933965Sjdp                                const LocationContext *LCtx,
17033965Sjdp                                bool CausedByPointerEscape,
17133965Sjdp                                InvalidatedSymbols *IS,
17233965Sjdp                                const CallEvent *Call,
17333965Sjdp                                ValueList ConstValues) const {
17433965Sjdp  if (!IS) {
17533965Sjdp    InvalidatedSymbols invalidated;
17633965Sjdp    return invalidateRegionsImpl(Values, E, Count, LCtx,
17733965Sjdp                                 CausedByPointerEscape,
17833965Sjdp                                 invalidated, Call, ConstValues);
17933965Sjdp  }
18033965Sjdp  return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
18133965Sjdp                               *IS, Call, ConstValues);
18233965Sjdp}
18333965Sjdp
18433965SjdpProgramStateRef
18533965SjdpProgramState::invalidateRegionsImpl(ValueList Values,
18633965Sjdp                                    const Expr *E, unsigned Count,
18733965Sjdp                                    const LocationContext *LCtx,
18833965Sjdp                                    bool CausedByPointerEscape,
18933965Sjdp                                    InvalidatedSymbols &IS,
19033965Sjdp                                    const CallEvent *Call,
19133965Sjdp                                    ValueList ConstValues) const {
19233965Sjdp  ProgramStateManager &Mgr = getStateManager();
19333965Sjdp  SubEngine* Eng = Mgr.getOwningEngine();
19433965Sjdp  InvalidatedSymbols ConstIS;
19533965Sjdp
19633965Sjdp  if (Eng) {
19733965Sjdp    StoreManager::InvalidatedRegions TopLevelInvalidated;
19833965Sjdp    StoreManager::InvalidatedRegions TopLevelConstInvalidated;
19933965Sjdp    StoreManager::InvalidatedRegions Invalidated;
20033965Sjdp    const StoreRef &newStore
20133965Sjdp    = Mgr.StoreMgr->invalidateRegions(getStore(), Values, ConstValues,
20233965Sjdp                                      E, Count, LCtx, Call,
20333965Sjdp                                      IS, ConstIS,
20433965Sjdp                                      &TopLevelInvalidated,
20533965Sjdp                                      &TopLevelConstInvalidated,
20633965Sjdp                                      &Invalidated);
20733965Sjdp
20833965Sjdp    ProgramStateRef newState = makeWithStore(newStore);
20933965Sjdp
21033965Sjdp    if (CausedByPointerEscape) {
21133965Sjdp      newState = Eng->notifyCheckersOfPointerEscape(newState, &IS,
21233965Sjdp                                                    TopLevelInvalidated,
21333965Sjdp                                                    Invalidated, Call);
21433965Sjdp      if (!ConstValues.empty()) {
21533965Sjdp        StoreManager::InvalidatedRegions Empty;
21633965Sjdp        newState = Eng->notifyCheckersOfPointerEscape(newState, &ConstIS,
21733965Sjdp                                                      TopLevelConstInvalidated,
21833965Sjdp                                                      Empty, Call,
21933965Sjdp                                                      true);
22033965Sjdp      }
22133965Sjdp    }
22233965Sjdp
22333965Sjdp    return Eng->processRegionChanges(newState, &IS,
22433965Sjdp                                     TopLevelInvalidated, Invalidated,
22533965Sjdp                                     Call);
22633965Sjdp  }
22733965Sjdp
22833965Sjdp  const StoreRef &newStore =
22933965Sjdp  Mgr.StoreMgr->invalidateRegions(getStore(), Values, ConstValues,
23033965Sjdp                                  E, Count, LCtx, Call,
23133965Sjdp                                  IS, ConstIS, NULL, NULL, NULL);
23233965Sjdp  return makeWithStore(newStore);
23333965Sjdp}
23433965Sjdp
23533965SjdpProgramStateRef ProgramState::killBinding(Loc LV) const {
23633965Sjdp  assert(!LV.getAs<loc::MemRegionVal>() && "Use invalidateRegion instead.");
23733965Sjdp
23833965Sjdp  Store OldStore = getStore();
23933965Sjdp  const StoreRef &newStore =
24033965Sjdp    getStateManager().StoreMgr->killBinding(OldStore, LV);
24133965Sjdp
24233965Sjdp  if (newStore.getStore() == OldStore)
24333965Sjdp    return this;
24433965Sjdp
24533965Sjdp  return makeWithStore(newStore);
24633965Sjdp}
24733965Sjdp
24833965SjdpProgramStateRef
24933965SjdpProgramState::enterStackFrame(const CallEvent &Call,
25033965Sjdp                              const StackFrameContext *CalleeCtx) const {
25133965Sjdp  const StoreRef &NewStore =
25233965Sjdp    getStateManager().StoreMgr->enterStackFrame(getStore(), Call, CalleeCtx);
25333965Sjdp  return makeWithStore(NewStore);
25433965Sjdp}
25533965Sjdp
25633965SjdpSVal ProgramState::getSValAsScalarOrLoc(const MemRegion *R) const {
25733965Sjdp  // We only want to do fetches from regions that we can actually bind
25833965Sjdp  // values.  For example, SymbolicRegions of type 'id<...>' cannot
25933965Sjdp  // have direct bindings (but their can be bindings on their subregions).
26033965Sjdp  if (!R->isBoundable())
26133965Sjdp    return UnknownVal();
26233965Sjdp
26333965Sjdp  if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
26433965Sjdp    QualType T = TR->getValueType();
26533965Sjdp    if (Loc::isLocType(T) || T->isIntegralOrEnumerationType())
26633965Sjdp      return getSVal(R);
26733965Sjdp  }
26833965Sjdp
26933965Sjdp  return UnknownVal();
27033965Sjdp}
27133965Sjdp
27233965SjdpSVal ProgramState::getSVal(Loc location, QualType T) const {
27333965Sjdp  SVal V = getRawSVal(cast<Loc>(location), T);
27433965Sjdp
27533965Sjdp  // If 'V' is a symbolic value that is *perfectly* constrained to
27633965Sjdp  // be a constant value, use that value instead to lessen the burden
27733965Sjdp  // on later analysis stages (so we have less symbolic values to reason
27833965Sjdp  // about).
27933965Sjdp  if (!T.isNull()) {
28033965Sjdp    if (SymbolRef sym = V.getAsSymbol()) {
28133965Sjdp      if (const llvm::APSInt *Int = getStateManager()
28233965Sjdp                                    .getConstraintManager()
28333965Sjdp                                    .getSymVal(this, sym)) {
28433965Sjdp        // FIXME: Because we don't correctly model (yet) sign-extension
28533965Sjdp        // and truncation of symbolic values, we need to convert
28633965Sjdp        // the integer value to the correct signedness and bitwidth.
28733965Sjdp        //
28833965Sjdp        // This shows up in the following:
28933965Sjdp        //
29033965Sjdp        //   char foo();
29133965Sjdp        //   unsigned x = foo();
29233965Sjdp        //   if (x == 54)
29333965Sjdp        //     ...
29433965Sjdp        //
29533965Sjdp        //  The symbolic value stored to 'x' is actually the conjured
29633965Sjdp        //  symbol for the call to foo(); the type of that symbol is 'char',
29733965Sjdp        //  not unsigned.
29833965Sjdp        const llvm::APSInt &NewV = getBasicVals().Convert(T, *Int);
29933965Sjdp
30033965Sjdp        if (V.getAs<Loc>())
30133965Sjdp          return loc::ConcreteInt(NewV);
30233965Sjdp        else
30333965Sjdp          return nonloc::ConcreteInt(NewV);
30433965Sjdp      }
30533965Sjdp    }
30633965Sjdp  }
30733965Sjdp
30833965Sjdp  return V;
30933965Sjdp}
31033965Sjdp
31133965SjdpProgramStateRef ProgramState::BindExpr(const Stmt *S,
31233965Sjdp                                           const LocationContext *LCtx,
31333965Sjdp                                           SVal V, bool Invalidate) const{
31433965Sjdp  Environment NewEnv =
31533965Sjdp    getStateManager().EnvMgr.bindExpr(Env, EnvironmentEntry(S, LCtx), V,
31633965Sjdp                                      Invalidate);
31733965Sjdp  if (NewEnv == Env)
31833965Sjdp    return this;
31933965Sjdp
32033965Sjdp  ProgramState NewSt = *this;
32133965Sjdp  NewSt.Env = NewEnv;
32233965Sjdp  return getStateManager().getPersistentState(NewSt);
32333965Sjdp}
32433965Sjdp
32533965SjdpProgramStateRef ProgramState::assumeInBound(DefinedOrUnknownSVal Idx,
32633965Sjdp                                      DefinedOrUnknownSVal UpperBound,
32733965Sjdp                                      bool Assumption,
32833965Sjdp                                      QualType indexTy) const {
32933965Sjdp  if (Idx.isUnknown() || UpperBound.isUnknown())
33033965Sjdp    return this;
33133965Sjdp
33233965Sjdp  // Build an expression for 0 <= Idx < UpperBound.
33333965Sjdp  // This is the same as Idx + MIN < UpperBound + MIN, if overflow is allowed.
33433965Sjdp  // FIXME: This should probably be part of SValBuilder.
33533965Sjdp  ProgramStateManager &SM = getStateManager();
33633965Sjdp  SValBuilder &svalBuilder = SM.getSValBuilder();
33733965Sjdp  ASTContext &Ctx = svalBuilder.getContext();
33833965Sjdp
33933965Sjdp  // Get the offset: the minimum value of the array index type.
34033965Sjdp  BasicValueFactory &BVF = svalBuilder.getBasicValueFactory();
34133965Sjdp  // FIXME: This should be using ValueManager::ArrayindexTy...somehow.
34233965Sjdp  if (indexTy.isNull())
34333965Sjdp    indexTy = Ctx.IntTy;
34433965Sjdp  nonloc::ConcreteInt Min(BVF.getMinValue(indexTy));
34533965Sjdp
34633965Sjdp  // Adjust the index.
34733965Sjdp  SVal newIdx = svalBuilder.evalBinOpNN(this, BO_Add,
34833965Sjdp                                        Idx.castAs<NonLoc>(), Min, indexTy);
34933965Sjdp  if (newIdx.isUnknownOrUndef())
35033965Sjdp    return this;
35133965Sjdp
35233965Sjdp  // Adjust the upper bound.
35333965Sjdp  SVal newBound =
35433965Sjdp    svalBuilder.evalBinOpNN(this, BO_Add, UpperBound.castAs<NonLoc>(),
35533965Sjdp                            Min, indexTy);
35633965Sjdp
35733965Sjdp  if (newBound.isUnknownOrUndef())
35833965Sjdp    return this;
35933965Sjdp
36033965Sjdp  // Build the actual comparison.
36133965Sjdp  SVal inBound = svalBuilder.evalBinOpNN(this, BO_LT, newIdx.castAs<NonLoc>(),
36233965Sjdp                                         newBound.castAs<NonLoc>(), Ctx.IntTy);
36333965Sjdp  if (inBound.isUnknownOrUndef())
36433965Sjdp    return this;
36533965Sjdp
36633965Sjdp  // Finally, let the constraint manager take care of it.
36733965Sjdp  ConstraintManager &CM = SM.getConstraintManager();
36833965Sjdp  return CM.assume(this, inBound.castAs<DefinedSVal>(), Assumption);
36933965Sjdp}
37033965Sjdp
37133965SjdpConditionTruthVal ProgramState::isNull(SVal V) const {
37233965Sjdp  if (V.isZeroConstant())
37333965Sjdp    return true;
37433965Sjdp
37533965Sjdp  if (V.isConstant())
37633965Sjdp    return false;
37733965Sjdp
37833965Sjdp  SymbolRef Sym = V.getAsSymbol(/* IncludeBaseRegion */ true);
37933965Sjdp  if (!Sym)
38033965Sjdp    return ConditionTruthVal();
38133965Sjdp
38233965Sjdp  return getStateManager().ConstraintMgr->isNull(this, Sym);
38333965Sjdp}
38433965Sjdp
38533965SjdpProgramStateRef ProgramStateManager::getInitialState(const LocationContext *InitLoc) {
38633965Sjdp  ProgramState State(this,
38733965Sjdp                EnvMgr.getInitialEnvironment(),
38833965Sjdp                StoreMgr->getInitialStore(InitLoc),
38933965Sjdp                GDMFactory.getEmptyMap());
39033965Sjdp
39133965Sjdp  return getPersistentState(State);
39233965Sjdp}
39333965Sjdp
39433965SjdpProgramStateRef ProgramStateManager::getPersistentStateWithGDM(
39533965Sjdp                                                     ProgramStateRef FromState,
39633965Sjdp                                                     ProgramStateRef GDMState) {
39733965Sjdp  ProgramState NewState(*FromState);
39833965Sjdp  NewState.GDM = GDMState->GDM;
39933965Sjdp  return getPersistentState(NewState);
40033965Sjdp}
40133965Sjdp
40233965SjdpProgramStateRef ProgramStateManager::getPersistentState(ProgramState &State) {
40333965Sjdp
40433965Sjdp  llvm::FoldingSetNodeID ID;
40533965Sjdp  State.Profile(ID);
40633965Sjdp  void *InsertPos;
40733965Sjdp
40833965Sjdp  if (ProgramState *I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
40933965Sjdp    return I;
41033965Sjdp
41133965Sjdp  ProgramState *newState = 0;
41233965Sjdp  if (!freeStates.empty()) {
41333965Sjdp    newState = freeStates.back();
41433965Sjdp    freeStates.pop_back();
41533965Sjdp  }
41633965Sjdp  else {
41733965Sjdp    newState = (ProgramState*) Alloc.Allocate<ProgramState>();
41833965Sjdp  }
41933965Sjdp  new (newState) ProgramState(State);
42033965Sjdp  StateSet.InsertNode(newState, InsertPos);
42133965Sjdp  return newState;
42233965Sjdp}
42333965Sjdp
42433965SjdpProgramStateRef ProgramState::makeWithStore(const StoreRef &store) const {
42533965Sjdp  ProgramState NewSt(*this);
42633965Sjdp  NewSt.setStore(store);
42733965Sjdp  return getStateManager().getPersistentState(NewSt);
42833965Sjdp}
42933965Sjdp
43033965Sjdpvoid ProgramState::setStore(const StoreRef &newStore) {
43133965Sjdp  Store newStoreStore = newStore.getStore();
43233965Sjdp  if (newStoreStore)
43333965Sjdp    stateMgr->getStoreManager().incrementReferenceCount(newStoreStore);
43433965Sjdp  if (store)
43533965Sjdp    stateMgr->getStoreManager().decrementReferenceCount(store);
43633965Sjdp  store = newStoreStore;
43733965Sjdp}
43833965Sjdp
43933965Sjdp//===----------------------------------------------------------------------===//
44033965Sjdp//  State pretty-printing.
44133965Sjdp//===----------------------------------------------------------------------===//
44233965Sjdp
44333965Sjdpvoid ProgramState::print(raw_ostream &Out,
44433965Sjdp                         const char *NL, const char *Sep) const {
44533965Sjdp  // Print the store.
44633965Sjdp  ProgramStateManager &Mgr = getStateManager();
44733965Sjdp  Mgr.getStoreManager().print(getStore(), Out, NL, Sep);
44833965Sjdp
44933965Sjdp  // Print out the environment.
45033965Sjdp  Env.print(Out, NL, Sep);
45133965Sjdp
45233965Sjdp  // Print out the constraints.
45333965Sjdp  Mgr.getConstraintManager().print(this, Out, NL, Sep);
45433965Sjdp
45533965Sjdp  // Print checker-specific data.
45633965Sjdp  Mgr.getOwningEngine()->printState(Out, this, NL, Sep);
45733965Sjdp}
45833965Sjdp
45933965Sjdpvoid ProgramState::printDOT(raw_ostream &Out) const {
46033965Sjdp  print(Out, "\\l", "\\|");
46133965Sjdp}
46233965Sjdp
46333965Sjdpvoid ProgramState::dump() const {
46433965Sjdp  print(llvm::errs());
46533965Sjdp}
46633965Sjdp
46733965Sjdpvoid ProgramState::printTaint(raw_ostream &Out,
46833965Sjdp                              const char *NL, const char *Sep) const {
46933965Sjdp  TaintMapImpl TM = get<TaintMap>();
47033965Sjdp
47133965Sjdp  if (!TM.isEmpty())
47233965Sjdp    Out <<"Tainted Symbols:" << NL;
47333965Sjdp
47433965Sjdp  for (TaintMapImpl::iterator I = TM.begin(), E = TM.end(); I != E; ++I) {
47533965Sjdp    Out << I->first << " : " << I->second << NL;
47633965Sjdp  }
47733965Sjdp}
47833965Sjdp
47933965Sjdpvoid ProgramState::dumpTaint() const {
48033965Sjdp  printTaint(llvm::errs());
48133965Sjdp}
48233965Sjdp
48333965Sjdp//===----------------------------------------------------------------------===//
48433965Sjdp// Generic Data Map.
48533965Sjdp//===----------------------------------------------------------------------===//
48633965Sjdp
48733965Sjdpvoid *const* ProgramState::FindGDM(void *K) const {
48833965Sjdp  return GDM.lookup(K);
48933965Sjdp}
49033965Sjdp
49133965Sjdpvoid*
49233965SjdpProgramStateManager::FindGDMContext(void *K,
49333965Sjdp                               void *(*CreateContext)(llvm::BumpPtrAllocator&),
49433965Sjdp                               void (*DeleteContext)(void*)) {
49533965Sjdp
49633965Sjdp  std::pair<void*, void (*)(void*)>& p = GDMContexts[K];
49733965Sjdp  if (!p.first) {
49833965Sjdp    p.first = CreateContext(Alloc);
49933965Sjdp    p.second = DeleteContext;
50033965Sjdp  }
50133965Sjdp
50233965Sjdp  return p.first;
50333965Sjdp}
50433965Sjdp
50533965SjdpProgramStateRef ProgramStateManager::addGDM(ProgramStateRef St, void *Key, void *Data){
50633965Sjdp  ProgramState::GenericDataMap M1 = St->getGDM();
50733965Sjdp  ProgramState::GenericDataMap M2 = GDMFactory.add(M1, Key, Data);
50833965Sjdp
50933965Sjdp  if (M1 == M2)
51033965Sjdp    return St;
51133965Sjdp
51233965Sjdp  ProgramState NewSt = *St;
51333965Sjdp  NewSt.GDM = M2;
51433965Sjdp  return getPersistentState(NewSt);
51533965Sjdp}
51633965Sjdp
51733965SjdpProgramStateRef ProgramStateManager::removeGDM(ProgramStateRef state, void *Key) {
51833965Sjdp  ProgramState::GenericDataMap OldM = state->getGDM();
51933965Sjdp  ProgramState::GenericDataMap NewM = GDMFactory.remove(OldM, Key);
52033965Sjdp
52133965Sjdp  if (NewM == OldM)
52233965Sjdp    return state;
52333965Sjdp
52433965Sjdp  ProgramState NewState = *state;
52533965Sjdp  NewState.GDM = NewM;
52633965Sjdp  return getPersistentState(NewState);
52733965Sjdp}
52833965Sjdp
52933965Sjdpbool ScanReachableSymbols::scan(nonloc::CompoundVal val) {
53033965Sjdp  for (nonloc::CompoundVal::iterator I=val.begin(), E=val.end(); I!=E; ++I)
53133965Sjdp    if (!scan(*I))
53233965Sjdp      return false;
53333965Sjdp
53433965Sjdp  return true;
53533965Sjdp}
53633965Sjdp
53733965Sjdpbool ScanReachableSymbols::scan(const SymExpr *sym) {
53833965Sjdp  unsigned &isVisited = visited[sym];
53933965Sjdp  if (isVisited)
54033965Sjdp    return true;
54133965Sjdp  isVisited = 1;
54233965Sjdp
54333965Sjdp  if (!visitor.VisitSymbol(sym))
54433965Sjdp    return false;
54533965Sjdp
54633965Sjdp  // TODO: should be rewritten using SymExpr::symbol_iterator.
54733965Sjdp  switch (sym->getKind()) {
54833965Sjdp    case SymExpr::RegionValueKind:
54933965Sjdp    case SymExpr::ConjuredKind:
55033965Sjdp    case SymExpr::DerivedKind:
55133965Sjdp    case SymExpr::ExtentKind:
55233965Sjdp    case SymExpr::MetadataKind:
55333965Sjdp      break;
55433965Sjdp    case SymExpr::CastSymbolKind:
55533965Sjdp      return scan(cast<SymbolCast>(sym)->getOperand());
55633965Sjdp    case SymExpr::SymIntKind:
55733965Sjdp      return scan(cast<SymIntExpr>(sym)->getLHS());
55833965Sjdp    case SymExpr::IntSymKind:
55933965Sjdp      return scan(cast<IntSymExpr>(sym)->getRHS());
56033965Sjdp    case SymExpr::SymSymKind: {
56133965Sjdp      const SymSymExpr *x = cast<SymSymExpr>(sym);
56233965Sjdp      return scan(x->getLHS()) && scan(x->getRHS());
56333965Sjdp    }
56433965Sjdp  }
56533965Sjdp  return true;
56633965Sjdp}
56733965Sjdp
56833965Sjdpbool ScanReachableSymbols::scan(SVal val) {
56933965Sjdp  if (Optional<loc::MemRegionVal> X = val.getAs<loc::MemRegionVal>())
57033965Sjdp    return scan(X->getRegion());
57133965Sjdp
57233965Sjdp  if (Optional<nonloc::LazyCompoundVal> X =
57333965Sjdp          val.getAs<nonloc::LazyCompoundVal>()) {
57433965Sjdp    StoreManager &StoreMgr = state->getStateManager().getStoreManager();
57533965Sjdp    // FIXME: We don't really want to use getBaseRegion() here because pointer
57633965Sjdp    // arithmetic doesn't apply, but scanReachableSymbols only accepts base
57733965Sjdp    // regions right now.
57833965Sjdp    if (!StoreMgr.scanReachableSymbols(X->getStore(),
57933965Sjdp                                       X->getRegion()->getBaseRegion(),
58033965Sjdp                                       *this))
58133965Sjdp      return false;
58233965Sjdp  }
58333965Sjdp
58433965Sjdp  if (Optional<nonloc::LocAsInteger> X = val.getAs<nonloc::LocAsInteger>())
58533965Sjdp    return scan(X->getLoc());
58633965Sjdp
58733965Sjdp  if (SymbolRef Sym = val.getAsSymbol())
58833965Sjdp    return scan(Sym);
58933965Sjdp
59033965Sjdp  if (const SymExpr *Sym = val.getAsSymbolicExpression())
59133965Sjdp    return scan(Sym);
59233965Sjdp
59333965Sjdp  if (Optional<nonloc::CompoundVal> X = val.getAs<nonloc::CompoundVal>())
59433965Sjdp    return scan(*X);
59533965Sjdp
59633965Sjdp  return true;
59733965Sjdp}
59833965Sjdp
59933965Sjdpbool ScanReachableSymbols::scan(const MemRegion *R) {
60033965Sjdp  if (isa<MemSpaceRegion>(R))
60133965Sjdp    return true;
60233965Sjdp
60333965Sjdp  unsigned &isVisited = visited[R];
60433965Sjdp  if (isVisited)
60533965Sjdp    return true;
60633965Sjdp  isVisited = 1;
60733965Sjdp
60833965Sjdp
60933965Sjdp  if (!visitor.VisitMemRegion(R))
61033965Sjdp    return false;
61133965Sjdp
61233965Sjdp  // If this is a symbolic region, visit the symbol for the region.
61333965Sjdp  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
61433965Sjdp    if (!visitor.VisitSymbol(SR->getSymbol()))
61533965Sjdp      return false;
61633965Sjdp
61733965Sjdp  // If this is a subregion, also visit the parent regions.
61833965Sjdp  if (const SubRegion *SR = dyn_cast<SubRegion>(R)) {
61933965Sjdp    const MemRegion *Super = SR->getSuperRegion();
62033965Sjdp    if (!scan(Super))
62133965Sjdp      return false;
62233965Sjdp
62333965Sjdp    // When we reach the topmost region, scan all symbols in it.
62433965Sjdp    if (isa<MemSpaceRegion>(Super)) {
62533965Sjdp      StoreManager &StoreMgr = state->getStateManager().getStoreManager();
62633965Sjdp      if (!StoreMgr.scanReachableSymbols(state->getStore(), SR, *this))
62733965Sjdp        return false;
62833965Sjdp    }
62933965Sjdp  }
63033965Sjdp
63133965Sjdp  // Regions captured by a block are also implicitly reachable.
63233965Sjdp  if (const BlockDataRegion *BDR = dyn_cast<BlockDataRegion>(R)) {
63333965Sjdp    BlockDataRegion::referenced_vars_iterator I = BDR->referenced_vars_begin(),
63433965Sjdp                                              E = BDR->referenced_vars_end();
63533965Sjdp    for ( ; I != E; ++I) {
63633965Sjdp      if (!scan(I.getCapturedRegion()))
63733965Sjdp        return false;
63833965Sjdp    }
63933965Sjdp  }
64033965Sjdp
64133965Sjdp  return true;
64233965Sjdp}
64333965Sjdp
64433965Sjdpbool ProgramState::scanReachableSymbols(SVal val, SymbolVisitor& visitor) const {
64533965Sjdp  ScanReachableSymbols S(this, visitor);
64633965Sjdp  return S.scan(val);
64733965Sjdp}
64833965Sjdp
64933965Sjdpbool ProgramState::scanReachableSymbols(const SVal *I, const SVal *E,
65033965Sjdp                                   SymbolVisitor &visitor) const {
65133965Sjdp  ScanReachableSymbols S(this, visitor);
65233965Sjdp  for ( ; I != E; ++I) {
65333965Sjdp    if (!S.scan(*I))
65433965Sjdp      return false;
65533965Sjdp  }
65633965Sjdp  return true;
65733965Sjdp}
65833965Sjdp
65933965Sjdpbool ProgramState::scanReachableSymbols(const MemRegion * const *I,
66033965Sjdp                                   const MemRegion * const *E,
66133965Sjdp                                   SymbolVisitor &visitor) const {
66233965Sjdp  ScanReachableSymbols S(this, visitor);
66333965Sjdp  for ( ; I != E; ++I) {
66433965Sjdp    if (!S.scan(*I))
66533965Sjdp      return false;
66633965Sjdp  }
66733965Sjdp  return true;
66833965Sjdp}
66933965Sjdp
67033965SjdpProgramStateRef ProgramState::addTaint(const Stmt *S,
67133965Sjdp                                           const LocationContext *LCtx,
67233965Sjdp                                           TaintTagType Kind) const {
67333965Sjdp  if (const Expr *E = dyn_cast_or_null<Expr>(S))
67433965Sjdp    S = E->IgnoreParens();
67533965Sjdp
67633965Sjdp  SymbolRef Sym = getSVal(S, LCtx).getAsSymbol();
67733965Sjdp  if (Sym)
67833965Sjdp    return addTaint(Sym, Kind);
67933965Sjdp
68033965Sjdp  const MemRegion *R = getSVal(S, LCtx).getAsRegion();
68133965Sjdp  addTaint(R, Kind);
68233965Sjdp
68333965Sjdp  // Cannot add taint, so just return the state.
68433965Sjdp  return this;
68533965Sjdp}
68633965Sjdp
68733965SjdpProgramStateRef ProgramState::addTaint(const MemRegion *R,
68833965Sjdp                                           TaintTagType Kind) const {
68933965Sjdp  if (const SymbolicRegion *SR = dyn_cast_or_null<SymbolicRegion>(R))
69033965Sjdp    return addTaint(SR->getSymbol(), Kind);
69133965Sjdp  return this;
69233965Sjdp}
69333965Sjdp
69433965SjdpProgramStateRef ProgramState::addTaint(SymbolRef Sym,
69533965Sjdp                                           TaintTagType Kind) const {
69633965Sjdp  // If this is a symbol cast, remove the cast before adding the taint. Taint
69733965Sjdp  // is cast agnostic.
69833965Sjdp  while (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym))
69933965Sjdp    Sym = SC->getOperand();
70033965Sjdp
70133965Sjdp  ProgramStateRef NewState = set<TaintMap>(Sym, Kind);
70233965Sjdp  assert(NewState);
70333965Sjdp  return NewState;
70433965Sjdp}
70533965Sjdp
70633965Sjdpbool ProgramState::isTainted(const Stmt *S, const LocationContext *LCtx,
70733965Sjdp                             TaintTagType Kind) const {
70833965Sjdp  if (const Expr *E = dyn_cast_or_null<Expr>(S))
70933965Sjdp    S = E->IgnoreParens();
71033965Sjdp
71133965Sjdp  SVal val = getSVal(S, LCtx);
71233965Sjdp  return isTainted(val, Kind);
71333965Sjdp}
71433965Sjdp
71533965Sjdpbool ProgramState::isTainted(SVal V, TaintTagType Kind) const {
71633965Sjdp  if (const SymExpr *Sym = V.getAsSymExpr())
71733965Sjdp    return isTainted(Sym, Kind);
71833965Sjdp  if (const MemRegion *Reg = V.getAsRegion())
71933965Sjdp    return isTainted(Reg, Kind);
72033965Sjdp  return false;
72133965Sjdp}
72233965Sjdp
72333965Sjdpbool ProgramState::isTainted(const MemRegion *Reg, TaintTagType K) const {
72433965Sjdp  if (!Reg)
72533965Sjdp    return false;
72633965Sjdp
72733965Sjdp  // Element region (array element) is tainted if either the base or the offset
72833965Sjdp  // are tainted.
72933965Sjdp  if (const ElementRegion *ER = dyn_cast<ElementRegion>(Reg))
73033965Sjdp    return isTainted(ER->getSuperRegion(), K) || isTainted(ER->getIndex(), K);
73133965Sjdp
73233965Sjdp  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(Reg))
73333965Sjdp    return isTainted(SR->getSymbol(), K);
73433965Sjdp
73533965Sjdp  if (const SubRegion *ER = dyn_cast<SubRegion>(Reg))
73633965Sjdp    return isTainted(ER->getSuperRegion(), K);
73733965Sjdp
73833965Sjdp  return false;
73933965Sjdp}
74033965Sjdp
74133965Sjdpbool ProgramState::isTainted(SymbolRef Sym, TaintTagType Kind) const {
74233965Sjdp  if (!Sym)
74333965Sjdp    return false;
74433965Sjdp
74533965Sjdp  // Traverse all the symbols this symbol depends on to see if any are tainted.
74633965Sjdp  bool Tainted = false;
74733965Sjdp  for (SymExpr::symbol_iterator SI = Sym->symbol_begin(), SE =Sym->symbol_end();
74833965Sjdp       SI != SE; ++SI) {
74933965Sjdp    if (!isa<SymbolData>(*SI))
75033965Sjdp      continue;
75133965Sjdp
75233965Sjdp    const TaintTagType *Tag = get<TaintMap>(*SI);
75333965Sjdp    Tainted = (Tag && *Tag == Kind);
75433965Sjdp
75533965Sjdp    // If this is a SymbolDerived with a tainted parent, it's also tainted.
75633965Sjdp    if (const SymbolDerived *SD = dyn_cast<SymbolDerived>(*SI))
75733965Sjdp      Tainted = Tainted || isTainted(SD->getParentSymbol(), Kind);
75833965Sjdp
75933965Sjdp    // If memory region is tainted, data is also tainted.
76033965Sjdp    if (const SymbolRegionValue *SRV = dyn_cast<SymbolRegionValue>(*SI))
76133965Sjdp      Tainted = Tainted || isTainted(SRV->getRegion(), Kind);
76233965Sjdp
76333965Sjdp    // If If this is a SymbolCast from a tainted value, it's also tainted.
76433965Sjdp    if (const SymbolCast *SC = dyn_cast<SymbolCast>(*SI))
76533965Sjdp      Tainted = Tainted || isTainted(SC->getOperand(), Kind);
76633965Sjdp
76733965Sjdp    if (Tainted)
76833965Sjdp      return true;
76933965Sjdp  }
77033965Sjdp
77133965Sjdp  return Tainted;
77233965Sjdp}
77333965Sjdp
77433965Sjdp/// The GDM component containing the dynamic type info. This is a map from a
77533965Sjdp/// symbol to its most likely type.
77633965SjdpREGISTER_TRAIT_WITH_PROGRAMSTATE(DynamicTypeMap,
77733965Sjdp                                 CLANG_ENTO_PROGRAMSTATE_MAP(const MemRegion *,
77833965Sjdp                                                             DynamicTypeInfo))
77933965Sjdp
78033965SjdpDynamicTypeInfo ProgramState::getDynamicTypeInfo(const MemRegion *Reg) const {
78133965Sjdp  Reg = Reg->StripCasts();
78233965Sjdp
78333965Sjdp  // Look up the dynamic type in the GDM.
78433965Sjdp  const DynamicTypeInfo *GDMType = get<DynamicTypeMap>(Reg);
78533965Sjdp  if (GDMType)
78633965Sjdp    return *GDMType;
78733965Sjdp
78833965Sjdp  // Otherwise, fall back to what we know about the region.
78933965Sjdp  if (const TypedRegion *TR = dyn_cast<TypedRegion>(Reg))
79033965Sjdp    return DynamicTypeInfo(TR->getLocationType(), /*CanBeSubclass=*/false);
79133965Sjdp
79233965Sjdp  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(Reg)) {
79333965Sjdp    SymbolRef Sym = SR->getSymbol();
79433965Sjdp    return DynamicTypeInfo(Sym->getType());
79533965Sjdp  }
79633965Sjdp
79733965Sjdp  return DynamicTypeInfo();
79833965Sjdp}
79933965Sjdp
80033965SjdpProgramStateRef ProgramState::setDynamicTypeInfo(const MemRegion *Reg,
80133965Sjdp                                                 DynamicTypeInfo NewTy) const {
80233965Sjdp  Reg = Reg->StripCasts();
80333965Sjdp  ProgramStateRef NewState = set<DynamicTypeMap>(Reg, NewTy);
80433965Sjdp  assert(NewState);
80533965Sjdp  return NewState;
80633965Sjdp}
80733965Sjdp