110e25031STed Kremenek //===- ExprEngineCXX.cpp - ExprEngine support for C++ -----------*- C++ -*-===//
210e25031STed Kremenek //
310e25031STed Kremenek //                     The LLVM Compiler Infrastructure
410e25031STed Kremenek //
510e25031STed Kremenek // This file is distributed under the University of Illinois Open Source
610e25031STed Kremenek // License. See LICENSE.TXT for details.
710e25031STed Kremenek //
810e25031STed Kremenek //===----------------------------------------------------------------------===//
910e25031STed Kremenek //
1010e25031STed Kremenek //  This file defines the C++ expression evaluation engine.
1110e25031STed Kremenek //
1210e25031STed Kremenek //===----------------------------------------------------------------------===//
1310e25031STed Kremenek 
1410e25031STed Kremenek #include "clang/StaticAnalyzer/Core/CheckerManager.h"
1510e25031STed Kremenek #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
1610e25031STed Kremenek #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
17087611edSJordy Rose #include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
1810e25031STed Kremenek #include "clang/AST/DeclCXX.h"
1910e25031STed Kremenek 
2010e25031STed Kremenek using namespace clang;
2110e25031STed Kremenek using namespace ento;
2210e25031STed Kremenek 
2310e25031STed Kremenek namespace {
2410e25031STed Kremenek class CallExprWLItem {
2510e25031STed Kremenek public:
2610e25031STed Kremenek   CallExpr::const_arg_iterator I;
2710e25031STed Kremenek   ExplodedNode *N;
2810e25031STed Kremenek 
2910e25031STed Kremenek   CallExprWLItem(const CallExpr::const_arg_iterator &i, ExplodedNode *n)
3010e25031STed Kremenek     : I(i), N(n) {}
3110e25031STed Kremenek };
3210e25031STed Kremenek }
3310e25031STed Kremenek 
3410e25031STed Kremenek void ExprEngine::evalArguments(ConstExprIterator AI, ConstExprIterator AE,
3510e25031STed Kremenek                                  const FunctionProtoType *FnType,
3610e25031STed Kremenek                                  ExplodedNode *Pred, ExplodedNodeSet &Dst,
3710e25031STed Kremenek                                  bool FstArgAsLValue) {
3810e25031STed Kremenek 
3910e25031STed Kremenek 
4010e25031STed Kremenek   SmallVector<CallExprWLItem, 20> WorkList;
4110e25031STed Kremenek   WorkList.reserve(AE - AI);
4210e25031STed Kremenek   WorkList.push_back(CallExprWLItem(AI, Pred));
4310e25031STed Kremenek 
4410e25031STed Kremenek   while (!WorkList.empty()) {
4510e25031STed Kremenek     CallExprWLItem Item = WorkList.back();
4610e25031STed Kremenek     WorkList.pop_back();
4710e25031STed Kremenek 
4810e25031STed Kremenek     if (Item.I == AE) {
4910e25031STed Kremenek       Dst.insert(Item.N);
5010e25031STed Kremenek       continue;
5110e25031STed Kremenek     }
5210e25031STed Kremenek 
5310e25031STed Kremenek     // Evaluate the argument.
5410e25031STed Kremenek     ExplodedNodeSet Tmp;
5510e25031STed Kremenek     if (FstArgAsLValue) {
5610e25031STed Kremenek       FstArgAsLValue = false;
5710e25031STed Kremenek     }
5810e25031STed Kremenek 
5910e25031STed Kremenek     Visit(*Item.I, Item.N, Tmp);
6010e25031STed Kremenek     ++(Item.I);
6110e25031STed Kremenek     for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI != NE; ++NI)
6210e25031STed Kremenek       WorkList.push_back(CallExprWLItem(Item.I, *NI));
6310e25031STed Kremenek   }
6410e25031STed Kremenek }
6510e25031STed Kremenek 
6610e25031STed Kremenek void ExprEngine::evalCallee(const CallExpr *callExpr,
6710e25031STed Kremenek                             const ExplodedNodeSet &src,
6810e25031STed Kremenek                             ExplodedNodeSet &dest) {
6910e25031STed Kremenek 
7010e25031STed Kremenek   const Expr *callee = 0;
7110e25031STed Kremenek 
7210e25031STed Kremenek   switch (callExpr->getStmtClass()) {
7310e25031STed Kremenek     case Stmt::CXXMemberCallExprClass: {
7410e25031STed Kremenek       // Evaluate the implicit object argument that is the recipient of the
7510e25031STed Kremenek       // call.
7610e25031STed Kremenek       callee = cast<CXXMemberCallExpr>(callExpr)->getImplicitObjectArgument();
7710e25031STed Kremenek 
7810e25031STed Kremenek       // FIXME: handle member pointers.
7910e25031STed Kremenek       if (!callee)
8010e25031STed Kremenek         return;
8110e25031STed Kremenek 
8210e25031STed Kremenek       break;
8310e25031STed Kremenek     }
8410e25031STed Kremenek     default: {
8510e25031STed Kremenek       callee = callExpr->getCallee()->IgnoreParens();
8610e25031STed Kremenek       break;
8710e25031STed Kremenek     }
8810e25031STed Kremenek   }
8910e25031STed Kremenek 
9010e25031STed Kremenek   for (ExplodedNodeSet::iterator i = src.begin(), e = src.end(); i != e; ++i)
9110e25031STed Kremenek     Visit(callee, *i, dest);
9210e25031STed Kremenek }
9310e25031STed Kremenek 
9410e25031STed Kremenek const CXXThisRegion *ExprEngine::getCXXThisRegion(const CXXRecordDecl *D,
9510e25031STed Kremenek                                                  const StackFrameContext *SFC) {
9610e25031STed Kremenek   const Type *T = D->getTypeForDecl();
9710e25031STed Kremenek   QualType PT = getContext().getPointerType(QualType(T, 0));
9810e25031STed Kremenek   return svalBuilder.getRegionManager().getCXXThisRegion(PT, SFC);
9910e25031STed Kremenek }
10010e25031STed Kremenek 
10110e25031STed Kremenek const CXXThisRegion *ExprEngine::getCXXThisRegion(const CXXMethodDecl *decl,
10210e25031STed Kremenek                                             const StackFrameContext *frameCtx) {
10310e25031STed Kremenek   return svalBuilder.getRegionManager().
10410e25031STed Kremenek                     getCXXThisRegion(decl->getThisType(getContext()), frameCtx);
10510e25031STed Kremenek }
10610e25031STed Kremenek 
10710e25031STed Kremenek void ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
10810e25031STed Kremenek                                           ExplodedNode *Pred,
10910e25031STed Kremenek                                           ExplodedNodeSet &Dst) {
110e4e5712cSAnna Zaks   StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
1112a14c695STed Kremenek   const Expr *tempExpr = ME->GetTemporaryExpr()->IgnoreParens();
11249b1e38eSTed Kremenek   ProgramStateRef state = Pred->getState();
113632e3b7eSTed Kremenek   const LocationContext *LCtx = Pred->getLocationContext();
11410e25031STed Kremenek 
11510e25031STed Kremenek   // Bind the temporary object to the value of the expression. Then bind
11610e25031STed Kremenek   // the expression to the location of the object.
117632e3b7eSTed Kremenek   SVal V = state->getSVal(tempExpr, Pred->getLocationContext());
11810e25031STed Kremenek 
11910e25031STed Kremenek   const MemRegion *R =
120632e3b7eSTed Kremenek     svalBuilder.getRegionManager().getCXXTempObjectRegion(ME, LCtx);
12110e25031STed Kremenek 
12210e25031STed Kremenek   state = state->bindLoc(loc::MemRegionVal(R), V);
123632e3b7eSTed Kremenek   Bldr.generateNode(ME, Pred, state->BindExpr(ME, LCtx, loc::MemRegionVal(R)));
12410e25031STed Kremenek }
12510e25031STed Kremenek 
126*11764ab4SBenjamin Kramer void ExprEngine::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *expr,
127*11764ab4SBenjamin Kramer                                              ExplodedNode *Pred,
128*11764ab4SBenjamin Kramer                                              ExplodedNodeSet &Dst) {
129*11764ab4SBenjamin Kramer   VisitCXXConstructExpr(expr, 0, Pred, Dst);
130*11764ab4SBenjamin Kramer }
131*11764ab4SBenjamin Kramer 
13210e25031STed Kremenek void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E,
13310e25031STed Kremenek                                        const MemRegion *Dest,
13410e25031STed Kremenek                                        ExplodedNode *Pred,
13510e25031STed Kremenek                                        ExplodedNodeSet &destNodes) {
13610e25031STed Kremenek 
13710e25031STed Kremenek   const CXXConstructorDecl *CD = E->getConstructor();
13810e25031STed Kremenek   assert(CD);
13910e25031STed Kremenek 
14010e25031STed Kremenek #if 0
14110e25031STed Kremenek   if (!(CD->doesThisDeclarationHaveABody() && AMgr.shouldInlineCall()))
14210e25031STed Kremenek     // FIXME: invalidate the object.
14310e25031STed Kremenek     return;
14410e25031STed Kremenek #endif
14510e25031STed Kremenek 
14610e25031STed Kremenek   // Evaluate other arguments.
14710e25031STed Kremenek   ExplodedNodeSet argsEvaluated;
14810e25031STed Kremenek   const FunctionProtoType *FnType = CD->getType()->getAs<FunctionProtoType>();
14910e25031STed Kremenek   evalArguments(E->arg_begin(), E->arg_end(), FnType, Pred, argsEvaluated);
15010e25031STed Kremenek 
15110e25031STed Kremenek #if 0
15210e25031STed Kremenek   // Is the constructor elidable?
15310e25031STed Kremenek   if (E->isElidable()) {
15410e25031STed Kremenek     VisitAggExpr(E->getArg(0), destNodes, Pred, Dst);
15510e25031STed Kremenek     // FIXME: this is here to force propagation if VisitAggExpr doesn't
15610e25031STed Kremenek     if (destNodes.empty())
15710e25031STed Kremenek       destNodes.Add(Pred);
15810e25031STed Kremenek     return;
15910e25031STed Kremenek   }
16010e25031STed Kremenek #endif
16110e25031STed Kremenek 
16210e25031STed Kremenek   // Perform the previsit of the constructor.
16310e25031STed Kremenek   ExplodedNodeSet destPreVisit;
16410e25031STed Kremenek   getCheckerManager().runCheckersForPreStmt(destPreVisit, argsEvaluated, E,
16510e25031STed Kremenek                                             *this);
16610e25031STed Kremenek 
16710e25031STed Kremenek   // Evaluate the constructor.  Currently we don't now allow checker-specific
16810e25031STed Kremenek   // implementations of specific constructors (as we do with ordinary
16910e25031STed Kremenek   // function calls.  We can re-evaluate this in the future.
17010e25031STed Kremenek 
17110e25031STed Kremenek #if 0
17210e25031STed Kremenek   // Inlining currently isn't fully implemented.
17310e25031STed Kremenek 
17410e25031STed Kremenek   if (AMgr.shouldInlineCall()) {
17510e25031STed Kremenek     if (!Dest)
17610e25031STed Kremenek       Dest =
17710e25031STed Kremenek         svalBuilder.getRegionManager().getCXXTempObjectRegion(E,
17810e25031STed Kremenek                                                   Pred->getLocationContext());
17910e25031STed Kremenek 
18010e25031STed Kremenek     // The callee stack frame context used to create the 'this'
18110e25031STed Kremenek     // parameter region.
18210e25031STed Kremenek     const StackFrameContext *SFC =
18310e25031STed Kremenek       AMgr.getStackFrame(CD, Pred->getLocationContext(),
184e594034fSAnna Zaks                          E, currentBuilderContext->getBlock(),
185e594034fSAnna Zaks                          currentStmtIdx);
18610e25031STed Kremenek 
18710e25031STed Kremenek     // Create the 'this' region.
18810e25031STed Kremenek     const CXXThisRegion *ThisR =
18910e25031STed Kremenek       getCXXThisRegion(E->getConstructor()->getParent(), SFC);
19010e25031STed Kremenek 
19110e25031STed Kremenek     CallEnter Loc(E, SFC, Pred->getLocationContext());
19210e25031STed Kremenek 
193e4e5712cSAnna Zaks     StmtNodeBuilder Bldr(argsEvaluated, destNodes, *currentBuilderContext);
19410e25031STed Kremenek     for (ExplodedNodeSet::iterator NI = argsEvaluated.begin(),
19510e25031STed Kremenek                                   NE = argsEvaluated.end(); NI != NE; ++NI) {
19649b1e38eSTed Kremenek       ProgramStateRef state = (*NI)->getState();
19710e25031STed Kremenek       // Setup 'this' region, so that the ctor is evaluated on the object pointed
19810e25031STed Kremenek       // by 'Dest'.
19910e25031STed Kremenek       state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest));
200e594034fSAnna Zaks       Bldr.generateNode(Loc, *NI, state);
20110e25031STed Kremenek     }
20210e25031STed Kremenek   }
20310e25031STed Kremenek #endif
20410e25031STed Kremenek 
20510e25031STed Kremenek   // Default semantics: invalidate all regions passed as arguments.
20610e25031STed Kremenek   ExplodedNodeSet destCall;
207e594034fSAnna Zaks   {
208e4e5712cSAnna Zaks     StmtNodeBuilder Bldr(destPreVisit, destCall, *currentBuilderContext);
20910e25031STed Kremenek     for (ExplodedNodeSet::iterator
21010e25031STed Kremenek         i = destPreVisit.begin(), e = destPreVisit.end();
21110e25031STed Kremenek         i != e; ++i)
21210e25031STed Kremenek     {
21310e25031STed Kremenek       ExplodedNode *Pred = *i;
214d188d66eSJordy Rose       const LocationContext *LC = Pred->getLocationContext();
21549b1e38eSTed Kremenek       ProgramStateRef state = Pred->getState();
21610e25031STed Kremenek 
217632e3b7eSTed Kremenek       state = invalidateArguments(state, CallOrObjCMessage(E, state, LC), LC);
218e594034fSAnna Zaks       Bldr.generateNode(E, Pred, state);
21910e25031STed Kremenek     }
220e594034fSAnna Zaks   }
22110e25031STed Kremenek   // Do the post visit.
22210e25031STed Kremenek   getCheckerManager().runCheckersForPostStmt(destNodes, destCall, E, *this);
22310e25031STed Kremenek }
22410e25031STed Kremenek 
22510e25031STed Kremenek void ExprEngine::VisitCXXDestructor(const CXXDestructorDecl *DD,
22610e25031STed Kremenek                                       const MemRegion *Dest,
22710e25031STed Kremenek                                       const Stmt *S,
22810e25031STed Kremenek                                       ExplodedNode *Pred,
22910e25031STed Kremenek                                       ExplodedNodeSet &Dst) {
230e4e5712cSAnna Zaks   StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
23110e25031STed Kremenek   if (!(DD->doesThisDeclarationHaveABody() && AMgr.shouldInlineCall()))
23210e25031STed Kremenek     return;
233142adc49STed Kremenek 
23410e25031STed Kremenek   // Create the context for 'this' region.
235142adc49STed Kremenek   const StackFrameContext *SFC =
23681ce1c8aSTed Kremenek     AnalysisDeclContexts.getContext(DD)->
237142adc49STed Kremenek       getStackFrame(Pred->getLocationContext(), S,
238e594034fSAnna Zaks       currentBuilderContext->getBlock(), currentStmtIdx);
23910e25031STed Kremenek 
24010e25031STed Kremenek   const CXXThisRegion *ThisR = getCXXThisRegion(DD->getParent(), SFC);
24110e25031STed Kremenek 
24210e25031STed Kremenek   CallEnter PP(S, SFC, Pred->getLocationContext());
24310e25031STed Kremenek 
24449b1e38eSTed Kremenek   ProgramStateRef state = Pred->getState();
24510e25031STed Kremenek   state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest));
246e594034fSAnna Zaks   Bldr.generateNode(PP, Pred, state);
24710e25031STed Kremenek }
24810e25031STed Kremenek 
24910e25031STed Kremenek void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
25010e25031STed Kremenek                                    ExplodedNodeSet &Dst) {
251e4e5712cSAnna Zaks   StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
25210e25031STed Kremenek 
253e594034fSAnna Zaks   unsigned blockCount = currentBuilderContext->getCurrentBlockCount();
25410e25031STed Kremenek   DefinedOrUnknownSVal symVal =
25510e25031STed Kremenek     svalBuilder.getConjuredSymbolVal(NULL, CNE, CNE->getType(), blockCount);
25610e25031STed Kremenek   const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion();
25710e25031STed Kremenek   QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
25810e25031STed Kremenek   const ElementRegion *EleReg =
25910e25031STed Kremenek     getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
26010e25031STed Kremenek 
26110e25031STed Kremenek   if (CNE->isArray()) {
26210e25031STed Kremenek     // FIXME: allocating an array requires simulating the constructors.
26310e25031STed Kremenek     // For now, just return a symbolicated region.
26449b1e38eSTed Kremenek     ProgramStateRef state = Pred->getState();
265632e3b7eSTed Kremenek     state = state->BindExpr(CNE, Pred->getLocationContext(),
266632e3b7eSTed Kremenek                             loc::MemRegionVal(EleReg));
267e594034fSAnna Zaks     Bldr.generateNode(CNE, Pred, state);
26810e25031STed Kremenek     return;
26910e25031STed Kremenek   }
27010e25031STed Kremenek 
27110e25031STed Kremenek   // Evaluate constructor arguments.
27210e25031STed Kremenek   const FunctionProtoType *FnType = NULL;
27310e25031STed Kremenek   const CXXConstructorDecl *CD = CNE->getConstructor();
27410e25031STed Kremenek   if (CD)
27510e25031STed Kremenek     FnType = CD->getType()->getAs<FunctionProtoType>();
27610e25031STed Kremenek   ExplodedNodeSet argsEvaluated;
277e594034fSAnna Zaks   Bldr.takeNodes(Pred);
27810e25031STed Kremenek   evalArguments(CNE->constructor_arg_begin(), CNE->constructor_arg_end(),
27910e25031STed Kremenek                 FnType, Pred, argsEvaluated);
280e594034fSAnna Zaks   Bldr.addNodes(argsEvaluated);
28110e25031STed Kremenek 
28210e25031STed Kremenek   // Initialize the object region and bind the 'new' expression.
28310e25031STed Kremenek   for (ExplodedNodeSet::iterator I = argsEvaluated.begin(),
28410e25031STed Kremenek                                  E = argsEvaluated.end(); I != E; ++I) {
28510e25031STed Kremenek 
28649b1e38eSTed Kremenek     ProgramStateRef state = (*I)->getState();
28710e25031STed Kremenek 
28810e25031STed Kremenek     // Accumulate list of regions that are invalidated.
28910e25031STed Kremenek     // FIXME: Eventually we should unify the logic for constructor
29010e25031STed Kremenek     // processing in one place.
29110e25031STed Kremenek     SmallVector<const MemRegion*, 10> regionsToInvalidate;
29210e25031STed Kremenek     for (CXXNewExpr::const_arg_iterator
29310e25031STed Kremenek           ai = CNE->constructor_arg_begin(), ae = CNE->constructor_arg_end();
29410e25031STed Kremenek           ai != ae; ++ai)
29510e25031STed Kremenek     {
296632e3b7eSTed Kremenek       SVal val = state->getSVal(*ai, (*I)->getLocationContext());
29710e25031STed Kremenek       if (const MemRegion *region = val.getAsRegion())
29810e25031STed Kremenek         regionsToInvalidate.push_back(region);
29910e25031STed Kremenek     }
30010e25031STed Kremenek 
30110e25031STed Kremenek     if (ObjTy->isRecordType()) {
30210e25031STed Kremenek       regionsToInvalidate.push_back(EleReg);
30310e25031STed Kremenek       // Invalidate the regions.
3048158ef0dSAnna Zaks       // TODO: Pass the call to new information as the last argument, to limit
3058158ef0dSAnna Zaks       // the globals which will get invalidated.
3061fad6631SJordy Rose       state = state->invalidateRegions(regionsToInvalidate,
3078158ef0dSAnna Zaks                                        CNE, blockCount, 0, 0);
30810e25031STed Kremenek 
30910e25031STed Kremenek     } else {
31010e25031STed Kremenek       // Invalidate the regions.
3118158ef0dSAnna Zaks       // TODO: Pass the call to new information as the last argument, to limit
3128158ef0dSAnna Zaks       // the globals which will get invalidated.
3131fad6631SJordy Rose       state = state->invalidateRegions(regionsToInvalidate,
3148158ef0dSAnna Zaks                                        CNE, blockCount, 0, 0);
31510e25031STed Kremenek 
31610e25031STed Kremenek       if (CNE->hasInitializer()) {
317632e3b7eSTed Kremenek         SVal V = state->getSVal(*CNE->constructor_arg_begin(),
318632e3b7eSTed Kremenek                                 (*I)->getLocationContext());
31910e25031STed Kremenek         state = state->bindLoc(loc::MemRegionVal(EleReg), V);
32010e25031STed Kremenek       } else {
32110e25031STed Kremenek         // Explicitly set to undefined, because currently we retrieve symbolic
32210e25031STed Kremenek         // value from symbolic region.
32310e25031STed Kremenek         state = state->bindLoc(loc::MemRegionVal(EleReg), UndefinedVal());
32410e25031STed Kremenek       }
32510e25031STed Kremenek     }
326632e3b7eSTed Kremenek     state = state->BindExpr(CNE, (*I)->getLocationContext(),
327632e3b7eSTed Kremenek                             loc::MemRegionVal(EleReg));
328e594034fSAnna Zaks     Bldr.generateNode(CNE, *I, state);
32910e25031STed Kremenek   }
33010e25031STed Kremenek }
33110e25031STed Kremenek 
33210e25031STed Kremenek void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
33310e25031STed Kremenek                                     ExplodedNode *Pred, ExplodedNodeSet &Dst) {
33410e25031STed Kremenek   // Should do more checking.
33510e25031STed Kremenek   ExplodedNodeSet Argevaluated;
33610e25031STed Kremenek   Visit(CDE->getArgument(), Pred, Argevaluated);
337e4e5712cSAnna Zaks   StmtNodeBuilder Bldr(Argevaluated, Dst, *currentBuilderContext);
33810e25031STed Kremenek   for (ExplodedNodeSet::iterator I = Argevaluated.begin(),
33910e25031STed Kremenek                                  E = Argevaluated.end(); I != E; ++I) {
34049b1e38eSTed Kremenek     ProgramStateRef state = (*I)->getState();
341e594034fSAnna Zaks     Bldr.generateNode(CDE, *I, state);
34210e25031STed Kremenek   }
34310e25031STed Kremenek }
34410e25031STed Kremenek 
34510e25031STed Kremenek void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
34610e25031STed Kremenek                                     ExplodedNodeSet &Dst) {
347e4e5712cSAnna Zaks   StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
348e594034fSAnna Zaks 
34910e25031STed Kremenek   // Get the this object region from StoreManager.
350632e3b7eSTed Kremenek   const LocationContext *LCtx = Pred->getLocationContext();
35110e25031STed Kremenek   const MemRegion *R =
35210e25031STed Kremenek     svalBuilder.getRegionManager().getCXXThisRegion(
35310e25031STed Kremenek                                   getContext().getCanonicalType(TE->getType()),
354632e3b7eSTed Kremenek                                                     LCtx);
35510e25031STed Kremenek 
35649b1e38eSTed Kremenek   ProgramStateRef state = Pred->getState();
35710e25031STed Kremenek   SVal V = state->getSVal(loc::MemRegionVal(R));
358632e3b7eSTed Kremenek   Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V));
35910e25031STed Kremenek }
360