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