void BasicStoreManager::iterBindings(Store store, BindingsHandler& f) {
    BindingsTy B = GetBindings(store);

    for (BindingsTy::iterator I=B.begin(), E=B.end(); I != E; ++I)
        f.HandleBinding(*this, store, I.getKey(), I.getData());

}
Esempio n. 2
0
void CXXInstanceCall::getInitialStackFrameContents(
                                            const StackFrameContext *CalleeCtx,
                                            BindingsTy &Bindings) const {
  AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings);

  // Handle the binding of 'this' in the new stack frame.
  SVal ThisVal = getCXXThisVal();
  if (!ThisVal.isUnknown()) {
    ProgramStateManager &StateMgr = getState()->getStateManager();
    SValBuilder &SVB = StateMgr.getSValBuilder();

    const CXXMethodDecl *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
    Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);

    // If we devirtualized to a different member function, we need to make sure
    // we have the proper layering of CXXBaseObjectRegions.
    if (MD->getCanonicalDecl() != getDecl()->getCanonicalDecl()) {
      ASTContext &Ctx = SVB.getContext();
      const CXXRecordDecl *Class = MD->getParent();
      QualType Ty = Ctx.getPointerType(Ctx.getRecordType(Class));

      // FIXME: CallEvent maybe shouldn't be directly accessing StoreManager.
      bool Failed;
      ThisVal = StateMgr.getStoreManager().evalDynamicCast(ThisVal, Ty, Failed);
      assert(!Failed && "Calling an incorrectly devirtualized method");
    }

    if (!ThisVal.isUnknown())
      Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
  }
}
void BasicStoreManager::print(Store store, llvm::raw_ostream& Out,
                              const char* nl, const char *sep) {

    BindingsTy B = GetBindings(store);
    Out << "Variables:" << nl;

    bool isFirst = true;

    for (BindingsTy::iterator I=B.begin(), E=B.end(); I != E; ++I) {
        if (isFirst)
            isFirst = false;
        else
            Out << nl;

        Out << ' ' << I.getKey() << " : " << I.getData();
    }
}
Esempio n. 4
0
void CXXConstructorCall::getInitialStackFrameContents(
                                             const StackFrameContext *CalleeCtx,
                                             BindingsTy &Bindings) const {
  AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings);

  SVal ThisVal = getCXXThisVal();
  if (!ThisVal.isUnknown()) {
    SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
    const CXXMethodDecl *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
    Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
    Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
  }
}
Store BasicStoreManager::InvalidateRegion(Store store,
        const MemRegion *R,
        const Expr *E,
        unsigned Count,
        InvalidatedSymbols *IS) {
    R = R->StripCasts();

    if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
        return store;

    if (IS) {
        BindingsTy B = GetBindings(store);
        if (BindingsTy::data_type *Val = B.lookup(R)) {
            if (SymbolRef Sym = Val->getAsSymbol())
                IS->insert(Sym);
        }
    }

    QualType T = cast<TypedRegion>(R)->getValueType(R->getContext());
    SVal V = ValMgr.getConjuredSymbolVal(R, E, T, Count);
    return Bind(store, loc::MemRegionVal(R), V);
}
SVal BasicStoreManager::Retrieve(Store store, Loc loc, QualType T) {
    if (isa<UnknownVal>(loc))
        return UnknownVal();

    assert(!isa<UndefinedVal>(loc));

    switch (loc.getSubKind()) {

    case loc::MemRegionKind: {
        const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();

        if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
            return UnknownVal();

        BindingsTy B = GetBindings(store);
        BindingsTy::data_type *Val = B.lookup(R);
        const TypedRegion *TR = cast<TypedRegion>(R);

        if (Val)
            return CastRetrievedVal(*Val, TR, T);

        SVal V = LazyRetrieve(store, TR);
        return V.isUnknownOrUndef() ? V : CastRetrievedVal(V, TR, T);
    }

    case loc::ConcreteIntKind:
        // Some clients may call GetSVal with such an option simply because
        // they are doing a quick scan through their Locs (potentially to
        // invalidate their bindings).  Just return Undefined.
        return UndefinedVal();

    default:
        assert (false && "Invalid Loc.");
        break;
    }

    return UnknownVal();
}
Esempio n. 7
0
void ObjCMethodCall::getInitialStackFrameContents(
                                             const StackFrameContext *CalleeCtx,
                                             BindingsTy &Bindings) const {
  const ObjCMethodDecl *D = cast<ObjCMethodDecl>(CalleeCtx->getDecl());
  SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
  addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
                               D->param_begin(), D->param_end());

  SVal SelfVal = getReceiverSVal();
  if (!SelfVal.isUnknown()) {
    const VarDecl *SelfD = CalleeCtx->getAnalysisDeclContext()->getSelfDecl();
    MemRegionManager &MRMgr = SVB.getRegionManager();
    Loc SelfLoc = SVB.makeLoc(MRMgr.getVarRegion(SelfD, CalleeCtx));
    Bindings.push_back(std::make_pair(SelfLoc, SelfVal));
  }
}
Esempio n. 8
0
void BlockCall::getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
                                             BindingsTy &Bindings) const {
  SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
  ArrayRef<ParmVarDecl*> Params;
  if (isConversionFromLambda()) {
    auto *LambdaOperatorDecl = cast<CXXMethodDecl>(CalleeCtx->getDecl());
    Params = LambdaOperatorDecl->parameters();

    // For blocks converted from a C++ lambda, the callee declaration is the
    // operator() method on the lambda so we bind "this" to
    // the lambda captured by the block.
    const VarRegion *CapturedLambdaRegion = getRegionStoringCapturedLambda();
    SVal ThisVal = loc::MemRegionVal(CapturedLambdaRegion);
    Loc ThisLoc = SVB.getCXXThis(LambdaOperatorDecl, CalleeCtx);
    Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
  } else {
    Params = cast<BlockDecl>(CalleeCtx->getDecl())->parameters();
  }

  addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
                               Params);
}
Store BasicStoreManager::RemoveDeadBindings(Store store, Stmt* Loc,
        SymbolReaper& SymReaper,
        llvm::SmallVectorImpl<const MemRegion*>& RegionRoots)
{
    BindingsTy B = GetBindings(store);
    typedef SVal::symbol_iterator symbol_iterator;

    // Iterate over the variable bindings.
    for (BindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I) {
        if (const VarRegion *VR = dyn_cast<VarRegion>(I.getKey())) {
            if (SymReaper.isLive(Loc, VR))
                RegionRoots.push_back(VR);
            else
                continue;
        }
        else if (isa<ObjCIvarRegion>(I.getKey())) {
            RegionRoots.push_back(I.getKey());
        }
        else
            continue;

        // Mark the bindings in the data as live.
        SVal X = I.getData();
        for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
            SymReaper.markLive(*SI);
    }

    // Scan for live variables and live symbols.
    llvm::SmallPtrSet<const MemRegion*, 10> Marked;

    while (!RegionRoots.empty()) {
        const MemRegion* MR = RegionRoots.back();
        RegionRoots.pop_back();

        while (MR) {
            if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(MR)) {
                SymReaper.markLive(SymR->getSymbol());
                break;
            }
            else if (isa<VarRegion>(MR) || isa<ObjCIvarRegion>(MR)) {
                if (Marked.count(MR))
                    break;

                Marked.insert(MR);
                SVal X = Retrieve(store, loc::MemRegionVal(MR));

                // FIXME: We need to handle symbols nested in region definitions.
                for (symbol_iterator SI=X.symbol_begin(),SE=X.symbol_end(); SI!=SE; ++SI)
                    SymReaper.markLive(*SI);

                if (!isa<loc::MemRegionVal>(X))
                    break;

                const loc::MemRegionVal& LVD = cast<loc::MemRegionVal>(X);
                RegionRoots.push_back(LVD.getRegion());
                break;
            }
            else if (const SubRegion* R = dyn_cast<SubRegion>(MR))
                MR = R->getSuperRegion();
            else
                break;
        }
    }

    // Remove dead variable bindings.
    for (BindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I) {
        const MemRegion* R = I.getKey();

        if (!Marked.count(R)) {
            store = Remove(store, ValMgr.makeLoc(R));
            SVal X = I.getData();

            for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
                SymReaper.maybeDead(*SI);
        }
    }

    return store;
}