1*10e25031STed Kremenek //===- ExprEngineCXX.cpp - ExprEngine support for C++ -----------*- C++ -*-===// 2*10e25031STed Kremenek // 3*10e25031STed Kremenek // The LLVM Compiler Infrastructure 4*10e25031STed Kremenek // 5*10e25031STed Kremenek // This file is distributed under the University of Illinois Open Source 6*10e25031STed Kremenek // License. See LICENSE.TXT for details. 7*10e25031STed Kremenek // 8*10e25031STed Kremenek //===----------------------------------------------------------------------===// 9*10e25031STed Kremenek // 10*10e25031STed Kremenek // This file defines the C++ expression evaluation engine. 11*10e25031STed Kremenek // 12*10e25031STed Kremenek //===----------------------------------------------------------------------===// 13*10e25031STed Kremenek 14*10e25031STed Kremenek #include "clang/StaticAnalyzer/Core/CheckerManager.h" 15*10e25031STed Kremenek #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 16*10e25031STed Kremenek #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 17*10e25031STed Kremenek #include "clang/AST/DeclCXX.h" 18*10e25031STed Kremenek 19*10e25031STed Kremenek using namespace clang; 20*10e25031STed Kremenek using namespace ento; 21*10e25031STed Kremenek 22*10e25031STed Kremenek namespace { 23*10e25031STed Kremenek class CallExprWLItem { 24*10e25031STed Kremenek public: 25*10e25031STed Kremenek CallExpr::const_arg_iterator I; 26*10e25031STed Kremenek ExplodedNode *N; 27*10e25031STed Kremenek 28*10e25031STed Kremenek CallExprWLItem(const CallExpr::const_arg_iterator &i, ExplodedNode *n) 29*10e25031STed Kremenek : I(i), N(n) {} 30*10e25031STed Kremenek }; 31*10e25031STed Kremenek } 32*10e25031STed Kremenek 33*10e25031STed Kremenek void ExprEngine::evalArguments(ConstExprIterator AI, ConstExprIterator AE, 34*10e25031STed Kremenek const FunctionProtoType *FnType, 35*10e25031STed Kremenek ExplodedNode *Pred, ExplodedNodeSet &Dst, 36*10e25031STed Kremenek bool FstArgAsLValue) { 37*10e25031STed Kremenek 38*10e25031STed Kremenek 39*10e25031STed Kremenek SmallVector<CallExprWLItem, 20> WorkList; 40*10e25031STed Kremenek WorkList.reserve(AE - AI); 41*10e25031STed Kremenek WorkList.push_back(CallExprWLItem(AI, Pred)); 42*10e25031STed Kremenek 43*10e25031STed Kremenek while (!WorkList.empty()) { 44*10e25031STed Kremenek CallExprWLItem Item = WorkList.back(); 45*10e25031STed Kremenek WorkList.pop_back(); 46*10e25031STed Kremenek 47*10e25031STed Kremenek if (Item.I == AE) { 48*10e25031STed Kremenek Dst.insert(Item.N); 49*10e25031STed Kremenek continue; 50*10e25031STed Kremenek } 51*10e25031STed Kremenek 52*10e25031STed Kremenek // Evaluate the argument. 53*10e25031STed Kremenek ExplodedNodeSet Tmp; 54*10e25031STed Kremenek if (FstArgAsLValue) { 55*10e25031STed Kremenek FstArgAsLValue = false; 56*10e25031STed Kremenek } 57*10e25031STed Kremenek 58*10e25031STed Kremenek Visit(*Item.I, Item.N, Tmp); 59*10e25031STed Kremenek ++(Item.I); 60*10e25031STed Kremenek for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI != NE; ++NI) 61*10e25031STed Kremenek WorkList.push_back(CallExprWLItem(Item.I, *NI)); 62*10e25031STed Kremenek } 63*10e25031STed Kremenek } 64*10e25031STed Kremenek 65*10e25031STed Kremenek void ExprEngine::evalCallee(const CallExpr *callExpr, 66*10e25031STed Kremenek const ExplodedNodeSet &src, 67*10e25031STed Kremenek ExplodedNodeSet &dest) { 68*10e25031STed Kremenek 69*10e25031STed Kremenek const Expr *callee = 0; 70*10e25031STed Kremenek 71*10e25031STed Kremenek switch (callExpr->getStmtClass()) { 72*10e25031STed Kremenek case Stmt::CXXMemberCallExprClass: { 73*10e25031STed Kremenek // Evaluate the implicit object argument that is the recipient of the 74*10e25031STed Kremenek // call. 75*10e25031STed Kremenek callee = cast<CXXMemberCallExpr>(callExpr)->getImplicitObjectArgument(); 76*10e25031STed Kremenek 77*10e25031STed Kremenek // FIXME: handle member pointers. 78*10e25031STed Kremenek if (!callee) 79*10e25031STed Kremenek return; 80*10e25031STed Kremenek 81*10e25031STed Kremenek break; 82*10e25031STed Kremenek } 83*10e25031STed Kremenek default: { 84*10e25031STed Kremenek callee = callExpr->getCallee()->IgnoreParens(); 85*10e25031STed Kremenek break; 86*10e25031STed Kremenek } 87*10e25031STed Kremenek } 88*10e25031STed Kremenek 89*10e25031STed Kremenek for (ExplodedNodeSet::iterator i = src.begin(), e = src.end(); i != e; ++i) 90*10e25031STed Kremenek Visit(callee, *i, dest); 91*10e25031STed Kremenek } 92*10e25031STed Kremenek 93*10e25031STed Kremenek const CXXThisRegion *ExprEngine::getCXXThisRegion(const CXXRecordDecl *D, 94*10e25031STed Kremenek const StackFrameContext *SFC) { 95*10e25031STed Kremenek const Type *T = D->getTypeForDecl(); 96*10e25031STed Kremenek QualType PT = getContext().getPointerType(QualType(T, 0)); 97*10e25031STed Kremenek return svalBuilder.getRegionManager().getCXXThisRegion(PT, SFC); 98*10e25031STed Kremenek } 99*10e25031STed Kremenek 100*10e25031STed Kremenek const CXXThisRegion *ExprEngine::getCXXThisRegion(const CXXMethodDecl *decl, 101*10e25031STed Kremenek const StackFrameContext *frameCtx) { 102*10e25031STed Kremenek return svalBuilder.getRegionManager(). 103*10e25031STed Kremenek getCXXThisRegion(decl->getThisType(getContext()), frameCtx); 104*10e25031STed Kremenek } 105*10e25031STed Kremenek 106*10e25031STed Kremenek void ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, 107*10e25031STed Kremenek ExplodedNode *Pred, 108*10e25031STed Kremenek ExplodedNodeSet &Dst) { 109*10e25031STed Kremenek ExplodedNodeSet Tmp; 110*10e25031STed Kremenek Visit(ME->GetTemporaryExpr(), Pred, Tmp); 111*10e25031STed Kremenek for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) { 112*10e25031STed Kremenek const ProgramState *state = (*I)->getState(); 113*10e25031STed Kremenek 114*10e25031STed Kremenek // Bind the temporary object to the value of the expression. Then bind 115*10e25031STed Kremenek // the expression to the location of the object. 116*10e25031STed Kremenek SVal V = state->getSVal(ME->GetTemporaryExpr()); 117*10e25031STed Kremenek 118*10e25031STed Kremenek const MemRegion *R = 119*10e25031STed Kremenek svalBuilder.getRegionManager().getCXXTempObjectRegion(ME, 120*10e25031STed Kremenek Pred->getLocationContext()); 121*10e25031STed Kremenek 122*10e25031STed Kremenek state = state->bindLoc(loc::MemRegionVal(R), V); 123*10e25031STed Kremenek MakeNode(Dst, ME, Pred, state->BindExpr(ME, loc::MemRegionVal(R))); 124*10e25031STed Kremenek } 125*10e25031STed Kremenek } 126*10e25031STed Kremenek 127*10e25031STed Kremenek void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, 128*10e25031STed Kremenek const MemRegion *Dest, 129*10e25031STed Kremenek ExplodedNode *Pred, 130*10e25031STed Kremenek ExplodedNodeSet &destNodes) { 131*10e25031STed Kremenek 132*10e25031STed Kremenek const CXXConstructorDecl *CD = E->getConstructor(); 133*10e25031STed Kremenek assert(CD); 134*10e25031STed Kremenek 135*10e25031STed Kremenek #if 0 136*10e25031STed Kremenek if (!(CD->doesThisDeclarationHaveABody() && AMgr.shouldInlineCall())) 137*10e25031STed Kremenek // FIXME: invalidate the object. 138*10e25031STed Kremenek return; 139*10e25031STed Kremenek #endif 140*10e25031STed Kremenek 141*10e25031STed Kremenek // Evaluate other arguments. 142*10e25031STed Kremenek ExplodedNodeSet argsEvaluated; 143*10e25031STed Kremenek const FunctionProtoType *FnType = CD->getType()->getAs<FunctionProtoType>(); 144*10e25031STed Kremenek evalArguments(E->arg_begin(), E->arg_end(), FnType, Pred, argsEvaluated); 145*10e25031STed Kremenek 146*10e25031STed Kremenek #if 0 147*10e25031STed Kremenek // Is the constructor elidable? 148*10e25031STed Kremenek if (E->isElidable()) { 149*10e25031STed Kremenek VisitAggExpr(E->getArg(0), destNodes, Pred, Dst); 150*10e25031STed Kremenek // FIXME: this is here to force propagation if VisitAggExpr doesn't 151*10e25031STed Kremenek if (destNodes.empty()) 152*10e25031STed Kremenek destNodes.Add(Pred); 153*10e25031STed Kremenek return; 154*10e25031STed Kremenek } 155*10e25031STed Kremenek #endif 156*10e25031STed Kremenek 157*10e25031STed Kremenek // Perform the previsit of the constructor. 158*10e25031STed Kremenek ExplodedNodeSet destPreVisit; 159*10e25031STed Kremenek getCheckerManager().runCheckersForPreStmt(destPreVisit, argsEvaluated, E, 160*10e25031STed Kremenek *this); 161*10e25031STed Kremenek 162*10e25031STed Kremenek // Evaluate the constructor. Currently we don't now allow checker-specific 163*10e25031STed Kremenek // implementations of specific constructors (as we do with ordinary 164*10e25031STed Kremenek // function calls. We can re-evaluate this in the future. 165*10e25031STed Kremenek 166*10e25031STed Kremenek #if 0 167*10e25031STed Kremenek // Inlining currently isn't fully implemented. 168*10e25031STed Kremenek 169*10e25031STed Kremenek if (AMgr.shouldInlineCall()) { 170*10e25031STed Kremenek if (!Dest) 171*10e25031STed Kremenek Dest = 172*10e25031STed Kremenek svalBuilder.getRegionManager().getCXXTempObjectRegion(E, 173*10e25031STed Kremenek Pred->getLocationContext()); 174*10e25031STed Kremenek 175*10e25031STed Kremenek // The callee stack frame context used to create the 'this' 176*10e25031STed Kremenek // parameter region. 177*10e25031STed Kremenek const StackFrameContext *SFC = 178*10e25031STed Kremenek AMgr.getStackFrame(CD, Pred->getLocationContext(), 179*10e25031STed Kremenek E, Builder->getBlock(), Builder->getIndex()); 180*10e25031STed Kremenek 181*10e25031STed Kremenek // Create the 'this' region. 182*10e25031STed Kremenek const CXXThisRegion *ThisR = 183*10e25031STed Kremenek getCXXThisRegion(E->getConstructor()->getParent(), SFC); 184*10e25031STed Kremenek 185*10e25031STed Kremenek CallEnter Loc(E, SFC, Pred->getLocationContext()); 186*10e25031STed Kremenek 187*10e25031STed Kremenek 188*10e25031STed Kremenek for (ExplodedNodeSet::iterator NI = argsEvaluated.begin(), 189*10e25031STed Kremenek NE = argsEvaluated.end(); NI != NE; ++NI) { 190*10e25031STed Kremenek const ProgramState *state = (*NI)->getState(); 191*10e25031STed Kremenek // Setup 'this' region, so that the ctor is evaluated on the object pointed 192*10e25031STed Kremenek // by 'Dest'. 193*10e25031STed Kremenek state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest)); 194*10e25031STed Kremenek if (ExplodedNode *N = Builder->generateNode(Loc, state, *NI)) 195*10e25031STed Kremenek destNodes.Add(N); 196*10e25031STed Kremenek } 197*10e25031STed Kremenek } 198*10e25031STed Kremenek #endif 199*10e25031STed Kremenek 200*10e25031STed Kremenek // Default semantics: invalidate all regions passed as arguments. 201*10e25031STed Kremenek SmallVector<const MemRegion*, 10> regionsToInvalidate; 202*10e25031STed Kremenek 203*10e25031STed Kremenek // FIXME: We can have collisions on the conjured symbol if the 204*10e25031STed Kremenek // expression *I also creates conjured symbols. We probably want 205*10e25031STed Kremenek // to identify conjured symbols by an expression pair: the enclosing 206*10e25031STed Kremenek // expression (the context) and the expression itself. This should 207*10e25031STed Kremenek // disambiguate conjured symbols. 208*10e25031STed Kremenek unsigned blockCount = Builder->getCurrentBlockCount(); 209*10e25031STed Kremenek 210*10e25031STed Kremenek // NOTE: Even if RegionsToInvalidate is empty, we must still invalidate 211*10e25031STed Kremenek // global variables. 212*10e25031STed Kremenek ExplodedNodeSet destCall; 213*10e25031STed Kremenek 214*10e25031STed Kremenek for (ExplodedNodeSet::iterator 215*10e25031STed Kremenek i = destPreVisit.begin(), e = destPreVisit.end(); 216*10e25031STed Kremenek i != e; ++i) 217*10e25031STed Kremenek { 218*10e25031STed Kremenek ExplodedNode *Pred = *i; 219*10e25031STed Kremenek const ProgramState *state = Pred->getState(); 220*10e25031STed Kremenek 221*10e25031STed Kremenek // Accumulate list of regions that are invalidated. 222*10e25031STed Kremenek for (CXXConstructExpr::const_arg_iterator 223*10e25031STed Kremenek ai = E->arg_begin(), ae = E->arg_end(); 224*10e25031STed Kremenek ai != ae; ++ai) 225*10e25031STed Kremenek { 226*10e25031STed Kremenek SVal val = state->getSVal(*ai); 227*10e25031STed Kremenek if (const MemRegion *region = val.getAsRegion()) 228*10e25031STed Kremenek regionsToInvalidate.push_back(region); 229*10e25031STed Kremenek } 230*10e25031STed Kremenek 231*10e25031STed Kremenek // Invalidate the regions. 232*10e25031STed Kremenek state = state->invalidateRegions(regionsToInvalidate.data(), 233*10e25031STed Kremenek regionsToInvalidate.data() + 234*10e25031STed Kremenek regionsToInvalidate.size(), 235*10e25031STed Kremenek E, blockCount, 0, 236*10e25031STed Kremenek /* invalidateGlobals = */ true); 237*10e25031STed Kremenek 238*10e25031STed Kremenek Builder->MakeNode(destCall, E, Pred, state); 239*10e25031STed Kremenek } 240*10e25031STed Kremenek 241*10e25031STed Kremenek // Do the post visit. 242*10e25031STed Kremenek getCheckerManager().runCheckersForPostStmt(destNodes, destCall, E, *this); 243*10e25031STed Kremenek } 244*10e25031STed Kremenek 245*10e25031STed Kremenek void ExprEngine::VisitCXXDestructor(const CXXDestructorDecl *DD, 246*10e25031STed Kremenek const MemRegion *Dest, 247*10e25031STed Kremenek const Stmt *S, 248*10e25031STed Kremenek ExplodedNode *Pred, 249*10e25031STed Kremenek ExplodedNodeSet &Dst) { 250*10e25031STed Kremenek if (!(DD->doesThisDeclarationHaveABody() && AMgr.shouldInlineCall())) 251*10e25031STed Kremenek return; 252*10e25031STed Kremenek // Create the context for 'this' region. 253*10e25031STed Kremenek const StackFrameContext *SFC = AMgr.getStackFrame(DD, 254*10e25031STed Kremenek Pred->getLocationContext(), 255*10e25031STed Kremenek S, Builder->getBlock(), 256*10e25031STed Kremenek Builder->getIndex()); 257*10e25031STed Kremenek 258*10e25031STed Kremenek const CXXThisRegion *ThisR = getCXXThisRegion(DD->getParent(), SFC); 259*10e25031STed Kremenek 260*10e25031STed Kremenek CallEnter PP(S, SFC, Pred->getLocationContext()); 261*10e25031STed Kremenek 262*10e25031STed Kremenek const ProgramState *state = Pred->getState(); 263*10e25031STed Kremenek state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest)); 264*10e25031STed Kremenek ExplodedNode *N = Builder->generateNode(PP, state, Pred); 265*10e25031STed Kremenek if (N) 266*10e25031STed Kremenek Dst.Add(N); 267*10e25031STed Kremenek } 268*10e25031STed Kremenek 269*10e25031STed Kremenek void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 270*10e25031STed Kremenek ExplodedNodeSet &Dst) { 271*10e25031STed Kremenek 272*10e25031STed Kremenek unsigned blockCount = Builder->getCurrentBlockCount(); 273*10e25031STed Kremenek DefinedOrUnknownSVal symVal = 274*10e25031STed Kremenek svalBuilder.getConjuredSymbolVal(NULL, CNE, CNE->getType(), blockCount); 275*10e25031STed Kremenek const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion(); 276*10e25031STed Kremenek QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType(); 277*10e25031STed Kremenek const ElementRegion *EleReg = 278*10e25031STed Kremenek getStoreManager().GetElementZeroRegion(NewReg, ObjTy); 279*10e25031STed Kremenek 280*10e25031STed Kremenek if (CNE->isArray()) { 281*10e25031STed Kremenek // FIXME: allocating an array requires simulating the constructors. 282*10e25031STed Kremenek // For now, just return a symbolicated region. 283*10e25031STed Kremenek const ProgramState *state = Pred->getState(); 284*10e25031STed Kremenek state = state->BindExpr(CNE, loc::MemRegionVal(EleReg)); 285*10e25031STed Kremenek MakeNode(Dst, CNE, Pred, state); 286*10e25031STed Kremenek return; 287*10e25031STed Kremenek } 288*10e25031STed Kremenek 289*10e25031STed Kremenek // Evaluate constructor arguments. 290*10e25031STed Kremenek const FunctionProtoType *FnType = NULL; 291*10e25031STed Kremenek const CXXConstructorDecl *CD = CNE->getConstructor(); 292*10e25031STed Kremenek if (CD) 293*10e25031STed Kremenek FnType = CD->getType()->getAs<FunctionProtoType>(); 294*10e25031STed Kremenek ExplodedNodeSet argsEvaluated; 295*10e25031STed Kremenek evalArguments(CNE->constructor_arg_begin(), CNE->constructor_arg_end(), 296*10e25031STed Kremenek FnType, Pred, argsEvaluated); 297*10e25031STed Kremenek 298*10e25031STed Kremenek // Initialize the object region and bind the 'new' expression. 299*10e25031STed Kremenek for (ExplodedNodeSet::iterator I = argsEvaluated.begin(), 300*10e25031STed Kremenek E = argsEvaluated.end(); I != E; ++I) { 301*10e25031STed Kremenek 302*10e25031STed Kremenek const ProgramState *state = (*I)->getState(); 303*10e25031STed Kremenek 304*10e25031STed Kremenek // Accumulate list of regions that are invalidated. 305*10e25031STed Kremenek // FIXME: Eventually we should unify the logic for constructor 306*10e25031STed Kremenek // processing in one place. 307*10e25031STed Kremenek SmallVector<const MemRegion*, 10> regionsToInvalidate; 308*10e25031STed Kremenek for (CXXNewExpr::const_arg_iterator 309*10e25031STed Kremenek ai = CNE->constructor_arg_begin(), ae = CNE->constructor_arg_end(); 310*10e25031STed Kremenek ai != ae; ++ai) 311*10e25031STed Kremenek { 312*10e25031STed Kremenek SVal val = state->getSVal(*ai); 313*10e25031STed Kremenek if (const MemRegion *region = val.getAsRegion()) 314*10e25031STed Kremenek regionsToInvalidate.push_back(region); 315*10e25031STed Kremenek } 316*10e25031STed Kremenek 317*10e25031STed Kremenek if (ObjTy->isRecordType()) { 318*10e25031STed Kremenek regionsToInvalidate.push_back(EleReg); 319*10e25031STed Kremenek // Invalidate the regions. 320*10e25031STed Kremenek state = state->invalidateRegions(regionsToInvalidate.data(), 321*10e25031STed Kremenek regionsToInvalidate.data() + 322*10e25031STed Kremenek regionsToInvalidate.size(), 323*10e25031STed Kremenek CNE, blockCount, 0, 324*10e25031STed Kremenek /* invalidateGlobals = */ true); 325*10e25031STed Kremenek 326*10e25031STed Kremenek } else { 327*10e25031STed Kremenek // Invalidate the regions. 328*10e25031STed Kremenek state = state->invalidateRegions(regionsToInvalidate.data(), 329*10e25031STed Kremenek regionsToInvalidate.data() + 330*10e25031STed Kremenek regionsToInvalidate.size(), 331*10e25031STed Kremenek CNE, blockCount, 0, 332*10e25031STed Kremenek /* invalidateGlobals = */ true); 333*10e25031STed Kremenek 334*10e25031STed Kremenek if (CNE->hasInitializer()) { 335*10e25031STed Kremenek SVal V = state->getSVal(*CNE->constructor_arg_begin()); 336*10e25031STed Kremenek state = state->bindLoc(loc::MemRegionVal(EleReg), V); 337*10e25031STed Kremenek } else { 338*10e25031STed Kremenek // Explicitly set to undefined, because currently we retrieve symbolic 339*10e25031STed Kremenek // value from symbolic region. 340*10e25031STed Kremenek state = state->bindLoc(loc::MemRegionVal(EleReg), UndefinedVal()); 341*10e25031STed Kremenek } 342*10e25031STed Kremenek } 343*10e25031STed Kremenek state = state->BindExpr(CNE, loc::MemRegionVal(EleReg)); 344*10e25031STed Kremenek MakeNode(Dst, CNE, *I, state); 345*10e25031STed Kremenek } 346*10e25031STed Kremenek } 347*10e25031STed Kremenek 348*10e25031STed Kremenek void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, 349*10e25031STed Kremenek ExplodedNode *Pred,ExplodedNodeSet &Dst) { 350*10e25031STed Kremenek // Should do more checking. 351*10e25031STed Kremenek ExplodedNodeSet Argevaluated; 352*10e25031STed Kremenek Visit(CDE->getArgument(), Pred, Argevaluated); 353*10e25031STed Kremenek for (ExplodedNodeSet::iterator I = Argevaluated.begin(), 354*10e25031STed Kremenek E = Argevaluated.end(); I != E; ++I) { 355*10e25031STed Kremenek const ProgramState *state = (*I)->getState(); 356*10e25031STed Kremenek MakeNode(Dst, CDE, *I, state); 357*10e25031STed Kremenek } 358*10e25031STed Kremenek } 359*10e25031STed Kremenek 360*10e25031STed Kremenek void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 361*10e25031STed Kremenek ExplodedNodeSet &Dst) { 362*10e25031STed Kremenek // Get the this object region from StoreManager. 363*10e25031STed Kremenek const MemRegion *R = 364*10e25031STed Kremenek svalBuilder.getRegionManager().getCXXThisRegion( 365*10e25031STed Kremenek getContext().getCanonicalType(TE->getType()), 366*10e25031STed Kremenek Pred->getLocationContext()); 367*10e25031STed Kremenek 368*10e25031STed Kremenek const ProgramState *state = Pred->getState(); 369*10e25031STed Kremenek SVal V = state->getSVal(loc::MemRegionVal(R)); 370*10e25031STed Kremenek MakeNode(Dst, TE, Pred, state->BindExpr(TE, V)); 371*10e25031STed Kremenek } 372