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 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)); } }
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)); } }
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); }