1 //===- ExprEngineCXX.cpp - ExprEngine support for C++ -----------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the C++ expression evaluation engine.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
15 #include "clang/AST/DeclCXX.h"
16 #include "clang/AST/StmtCXX.h"
17 #include "clang/Basic/PrettyStackTrace.h"
18 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
19 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
20 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
21
22 using namespace clang;
23 using namespace ento;
24
CreateCXXTemporaryObject(const MaterializeTemporaryExpr * ME,ExplodedNode * Pred,ExplodedNodeSet & Dst)25 void ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
26 ExplodedNode *Pred,
27 ExplodedNodeSet &Dst) {
28 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
29 const Expr *tempExpr = ME->GetTemporaryExpr()->IgnoreParens();
30 ProgramStateRef state = Pred->getState();
31 const LocationContext *LCtx = Pred->getLocationContext();
32
33 state = createTemporaryRegionIfNeeded(state, LCtx, tempExpr, ME);
34 Bldr.generateNode(ME, Pred, state);
35 }
36
37 // FIXME: This is the sort of code that should eventually live in a Core
38 // checker rather than as a special case in ExprEngine.
performTrivialCopy(NodeBuilder & Bldr,ExplodedNode * Pred,const CallEvent & Call)39 void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
40 const CallEvent &Call) {
41 SVal ThisVal;
42 bool AlwaysReturnsLValue;
43 if (const CXXConstructorCall *Ctor = dyn_cast<CXXConstructorCall>(&Call)) {
44 assert(Ctor->getDecl()->isTrivial());
45 assert(Ctor->getDecl()->isCopyOrMoveConstructor());
46 ThisVal = Ctor->getCXXThisVal();
47 AlwaysReturnsLValue = false;
48 } else {
49 assert(cast<CXXMethodDecl>(Call.getDecl())->isTrivial());
50 assert(cast<CXXMethodDecl>(Call.getDecl())->getOverloadedOperator() ==
51 OO_Equal);
52 ThisVal = cast<CXXInstanceCall>(Call).getCXXThisVal();
53 AlwaysReturnsLValue = true;
54 }
55
56 const LocationContext *LCtx = Pred->getLocationContext();
57
58 ExplodedNodeSet Dst;
59 Bldr.takeNodes(Pred);
60
61 SVal V = Call.getArgSVal(0);
62
63 // If the value being copied is not unknown, load from its location to get
64 // an aggregate rvalue.
65 if (Optional<Loc> L = V.getAs<Loc>())
66 V = Pred->getState()->getSVal(*L);
67 else
68 assert(V.isUnknown());
69
70 const Expr *CallExpr = Call.getOriginExpr();
71 evalBind(Dst, CallExpr, Pred, ThisVal, V, true);
72
73 PostStmt PS(CallExpr, LCtx);
74 for (ExplodedNodeSet::iterator I = Dst.begin(), E = Dst.end();
75 I != E; ++I) {
76 ProgramStateRef State = (*I)->getState();
77 if (AlwaysReturnsLValue)
78 State = State->BindExpr(CallExpr, LCtx, ThisVal);
79 else
80 State = bindReturnValue(Call, LCtx, State);
81 Bldr.generateNode(PS, State, *I);
82 }
83 }
84
85
86 /// Returns a region representing the first element of a (possibly
87 /// multi-dimensional) array.
88 ///
89 /// On return, \p Ty will be set to the base type of the array.
90 ///
91 /// If the type is not an array type at all, the original value is returned.
makeZeroElementRegion(ProgramStateRef State,SVal LValue,QualType & Ty)92 static SVal makeZeroElementRegion(ProgramStateRef State, SVal LValue,
93 QualType &Ty) {
94 SValBuilder &SVB = State->getStateManager().getSValBuilder();
95 ASTContext &Ctx = SVB.getContext();
96
97 while (const ArrayType *AT = Ctx.getAsArrayType(Ty)) {
98 Ty = AT->getElementType();
99 LValue = State->getLValue(Ty, SVB.makeZeroArrayIndex(), LValue);
100 }
101
102 return LValue;
103 }
104
105
getRegionForConstructedObject(const CXXConstructExpr * CE,ExplodedNode * Pred,ExprEngine & Eng,unsigned int CurrStmtIdx)106 static const MemRegion *getRegionForConstructedObject(
107 const CXXConstructExpr *CE, ExplodedNode *Pred, ExprEngine &Eng,
108 unsigned int CurrStmtIdx) {
109 const LocationContext *LCtx = Pred->getLocationContext();
110 ProgramStateRef State = Pred->getState();
111 const NodeBuilderContext &CurrBldrCtx = Eng.getBuilderContext();
112
113 // See if we're constructing an existing region by looking at the next
114 // element in the CFG.
115 const CFGBlock *B = CurrBldrCtx.getBlock();
116 unsigned int NextStmtIdx = CurrStmtIdx + 1;
117 if (NextStmtIdx < B->size()) {
118 CFGElement Next = (*B)[NextStmtIdx];
119
120 // Is this a destructor? If so, we might be in the middle of an assignment
121 // to a local or member: look ahead one more element to see what we find.
122 while (Next.getAs<CFGImplicitDtor>() && NextStmtIdx + 1 < B->size()) {
123 ++NextStmtIdx;
124 Next = (*B)[NextStmtIdx];
125 }
126
127 // Is this a constructor for a local variable?
128 if (Optional<CFGStmt> StmtElem = Next.getAs<CFGStmt>()) {
129 if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) {
130 if (const VarDecl *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) {
131 if (Var->getInit() && Var->getInit()->IgnoreImplicit() == CE) {
132 SVal LValue = State->getLValue(Var, LCtx);
133 QualType Ty = Var->getType();
134 LValue = makeZeroElementRegion(State, LValue, Ty);
135 return LValue.getAsRegion();
136 }
137 }
138 }
139 }
140
141 // Is this a constructor for a member?
142 if (Optional<CFGInitializer> InitElem = Next.getAs<CFGInitializer>()) {
143 const CXXCtorInitializer *Init = InitElem->getInitializer();
144 assert(Init->isAnyMemberInitializer());
145
146 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
147 Loc ThisPtr = Eng.getSValBuilder().getCXXThis(CurCtor,
148 LCtx->getCurrentStackFrame());
149 SVal ThisVal = State->getSVal(ThisPtr);
150
151 const ValueDecl *Field;
152 SVal FieldVal;
153 if (Init->isIndirectMemberInitializer()) {
154 Field = Init->getIndirectMember();
155 FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal);
156 } else {
157 Field = Init->getMember();
158 FieldVal = State->getLValue(Init->getMember(), ThisVal);
159 }
160
161 QualType Ty = Field->getType();
162 FieldVal = makeZeroElementRegion(State, FieldVal, Ty);
163 return FieldVal.getAsRegion();
164 }
165
166 // FIXME: This will eventually need to handle new-expressions as well.
167 // Don't forget to update the pre-constructor initialization code in
168 // ExprEngine::VisitCXXConstructExpr.
169 }
170
171 // If we couldn't find an existing region to construct into, assume we're
172 // constructing a temporary.
173 MemRegionManager &MRMgr = Eng.getSValBuilder().getRegionManager();
174 return MRMgr.getCXXTempObjectRegion(CE, LCtx);
175 }
176
VisitCXXConstructExpr(const CXXConstructExpr * CE,ExplodedNode * Pred,ExplodedNodeSet & destNodes)177 void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
178 ExplodedNode *Pred,
179 ExplodedNodeSet &destNodes) {
180 const LocationContext *LCtx = Pred->getLocationContext();
181 ProgramStateRef State = Pred->getState();
182
183 const MemRegion *Target = nullptr;
184
185 // FIXME: Handle arrays, which run the same constructor for every element.
186 // For now, we just run the first constructor (which should still invalidate
187 // the entire array).
188
189 switch (CE->getConstructionKind()) {
190 case CXXConstructExpr::CK_Complete: {
191 Target = getRegionForConstructedObject(CE, Pred, *this, currStmtIdx);
192 break;
193 }
194 case CXXConstructExpr::CK_VirtualBase:
195 // Make sure we are not calling virtual base class initializers twice.
196 // Only the most-derived object should initialize virtual base classes.
197 if (const Stmt *Outer = LCtx->getCurrentStackFrame()->getCallSite()) {
198 const CXXConstructExpr *OuterCtor = dyn_cast<CXXConstructExpr>(Outer);
199 if (OuterCtor) {
200 switch (OuterCtor->getConstructionKind()) {
201 case CXXConstructExpr::CK_NonVirtualBase:
202 case CXXConstructExpr::CK_VirtualBase:
203 // Bail out!
204 destNodes.Add(Pred);
205 return;
206 case CXXConstructExpr::CK_Complete:
207 case CXXConstructExpr::CK_Delegating:
208 break;
209 }
210 }
211 }
212 // FALLTHROUGH
213 case CXXConstructExpr::CK_NonVirtualBase:
214 case CXXConstructExpr::CK_Delegating: {
215 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
216 Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor,
217 LCtx->getCurrentStackFrame());
218 SVal ThisVal = State->getSVal(ThisPtr);
219
220 if (CE->getConstructionKind() == CXXConstructExpr::CK_Delegating) {
221 Target = ThisVal.getAsRegion();
222 } else {
223 // Cast to the base type.
224 bool IsVirtual =
225 (CE->getConstructionKind() == CXXConstructExpr::CK_VirtualBase);
226 SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, CE->getType(),
227 IsVirtual);
228 Target = BaseVal.getAsRegion();
229 }
230 break;
231 }
232 }
233
234 CallEventManager &CEMgr = getStateManager().getCallEventManager();
235 CallEventRef<CXXConstructorCall> Call =
236 CEMgr.getCXXConstructorCall(CE, Target, State, LCtx);
237
238 ExplodedNodeSet DstPreVisit;
239 getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this);
240
241 ExplodedNodeSet PreInitialized;
242 {
243 StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx);
244 if (CE->requiresZeroInitialization()) {
245 // Type of the zero doesn't matter.
246 SVal ZeroVal = svalBuilder.makeZeroVal(getContext().CharTy);
247
248 for (ExplodedNodeSet::iterator I = DstPreVisit.begin(),
249 E = DstPreVisit.end();
250 I != E; ++I) {
251 ProgramStateRef State = (*I)->getState();
252 // FIXME: Once we properly handle constructors in new-expressions, we'll
253 // need to invalidate the region before setting a default value, to make
254 // sure there aren't any lingering bindings around. This probably needs
255 // to happen regardless of whether or not the object is zero-initialized
256 // to handle random fields of a placement-initialized object picking up
257 // old bindings. We might only want to do it when we need to, though.
258 // FIXME: This isn't actually correct for arrays -- we need to zero-
259 // initialize the entire array, not just the first element -- but our
260 // handling of arrays everywhere else is weak as well, so this shouldn't
261 // actually make things worse. Placement new makes this tricky as well,
262 // since it's then possible to be initializing one part of a multi-
263 // dimensional array.
264 State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal);
265 Bldr.generateNode(CE, *I, State, /*tag=*/nullptr,
266 ProgramPoint::PreStmtKind);
267 }
268 }
269 }
270
271 ExplodedNodeSet DstPreCall;
272 getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized,
273 *Call, *this);
274
275 ExplodedNodeSet DstEvaluated;
276 StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);
277
278 bool IsArray = isa<ElementRegion>(Target);
279 if (CE->getConstructor()->isTrivial() &&
280 CE->getConstructor()->isCopyOrMoveConstructor() &&
281 !IsArray) {
282 // FIXME: Handle other kinds of trivial constructors as well.
283 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
284 I != E; ++I)
285 performTrivialCopy(Bldr, *I, *Call);
286
287 } else {
288 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
289 I != E; ++I)
290 defaultEvalCall(Bldr, *I, *Call);
291 }
292
293 ExplodedNodeSet DstPostCall;
294 getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated,
295 *Call, *this);
296 getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this);
297 }
298
VisitCXXDestructor(QualType ObjectType,const MemRegion * Dest,const Stmt * S,bool IsBaseDtor,ExplodedNode * Pred,ExplodedNodeSet & Dst)299 void ExprEngine::VisitCXXDestructor(QualType ObjectType,
300 const MemRegion *Dest,
301 const Stmt *S,
302 bool IsBaseDtor,
303 ExplodedNode *Pred,
304 ExplodedNodeSet &Dst) {
305 const LocationContext *LCtx = Pred->getLocationContext();
306 ProgramStateRef State = Pred->getState();
307
308 // FIXME: We need to run the same destructor on every element of the array.
309 // This workaround will just run the first destructor (which will still
310 // invalidate the entire array).
311 SVal DestVal = UnknownVal();
312 if (Dest)
313 DestVal = loc::MemRegionVal(Dest);
314 DestVal = makeZeroElementRegion(State, DestVal, ObjectType);
315 Dest = DestVal.getAsRegion();
316
317 const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl();
318 assert(RecordDecl && "Only CXXRecordDecls should have destructors");
319 const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor();
320
321 CallEventManager &CEMgr = getStateManager().getCallEventManager();
322 CallEventRef<CXXDestructorCall> Call =
323 CEMgr.getCXXDestructorCall(DtorDecl, S, Dest, IsBaseDtor, State, LCtx);
324
325 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
326 Call->getSourceRange().getBegin(),
327 "Error evaluating destructor");
328
329 ExplodedNodeSet DstPreCall;
330 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
331 *Call, *this);
332
333 ExplodedNodeSet DstInvalidated;
334 StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
335 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
336 I != E; ++I)
337 defaultEvalCall(Bldr, *I, *Call);
338
339 ExplodedNodeSet DstPostCall;
340 getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
341 *Call, *this);
342 }
343
VisitCXXNewAllocatorCall(const CXXNewExpr * CNE,ExplodedNode * Pred,ExplodedNodeSet & Dst)344 void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
345 ExplodedNode *Pred,
346 ExplodedNodeSet &Dst) {
347 ProgramStateRef State = Pred->getState();
348 const LocationContext *LCtx = Pred->getLocationContext();
349 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
350 CNE->getStartLoc(),
351 "Error evaluating New Allocator Call");
352 CallEventManager &CEMgr = getStateManager().getCallEventManager();
353 CallEventRef<CXXAllocatorCall> Call =
354 CEMgr.getCXXAllocatorCall(CNE, State, LCtx);
355
356 ExplodedNodeSet DstPreCall;
357 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
358 *Call, *this);
359
360 ExplodedNodeSet DstInvalidated;
361 StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
362 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
363 I != E; ++I)
364 defaultEvalCall(Bldr, *I, *Call);
365 getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
366 *Call, *this);
367 }
368
369
VisitCXXNewExpr(const CXXNewExpr * CNE,ExplodedNode * Pred,ExplodedNodeSet & Dst)370 void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
371 ExplodedNodeSet &Dst) {
372 // FIXME: Much of this should eventually migrate to CXXAllocatorCall.
373 // Also, we need to decide how allocators actually work -- they're not
374 // really part of the CXXNewExpr because they happen BEFORE the
375 // CXXConstructExpr subexpression. See PR12014 for some discussion.
376
377 unsigned blockCount = currBldrCtx->blockCount();
378 const LocationContext *LCtx = Pred->getLocationContext();
379 DefinedOrUnknownSVal symVal = UnknownVal();
380 FunctionDecl *FD = CNE->getOperatorNew();
381
382 bool IsStandardGlobalOpNewFunction = false;
383 if (FD && !isa<CXXMethodDecl>(FD) && !FD->isVariadic()) {
384 if (FD->getNumParams() == 2) {
385 QualType T = FD->getParamDecl(1)->getType();
386 if (const IdentifierInfo *II = T.getBaseTypeIdentifier())
387 // NoThrow placement new behaves as a standard new.
388 IsStandardGlobalOpNewFunction = II->getName().equals("nothrow_t");
389 }
390 else
391 // Placement forms are considered non-standard.
392 IsStandardGlobalOpNewFunction = (FD->getNumParams() == 1);
393 }
394
395 // We assume all standard global 'operator new' functions allocate memory in
396 // heap. We realize this is an approximation that might not correctly model
397 // a custom global allocator.
398 if (IsStandardGlobalOpNewFunction)
399 symVal = svalBuilder.getConjuredHeapSymbolVal(CNE, LCtx, blockCount);
400 else
401 symVal = svalBuilder.conjureSymbolVal(nullptr, CNE, LCtx, CNE->getType(),
402 blockCount);
403
404 ProgramStateRef State = Pred->getState();
405 CallEventManager &CEMgr = getStateManager().getCallEventManager();
406 CallEventRef<CXXAllocatorCall> Call =
407 CEMgr.getCXXAllocatorCall(CNE, State, LCtx);
408
409 // Invalidate placement args.
410 // FIXME: Once we figure out how we want allocators to work,
411 // we should be using the usual pre-/(default-)eval-/post-call checks here.
412 State = Call->invalidateRegions(blockCount);
413 if (!State)
414 return;
415
416 // If this allocation function is not declared as non-throwing, failures
417 // /must/ be signalled by exceptions, and thus the return value will never be
418 // NULL. -fno-exceptions does not influence this semantics.
419 // FIXME: GCC has a -fcheck-new option, which forces it to consider the case
420 // where new can return NULL. If we end up supporting that option, we can
421 // consider adding a check for it here.
422 // C++11 [basic.stc.dynamic.allocation]p3.
423 if (FD) {
424 QualType Ty = FD->getType();
425 if (const FunctionProtoType *ProtoType = Ty->getAs<FunctionProtoType>())
426 if (!ProtoType->isNothrow(getContext()))
427 State = State->assume(symVal, true);
428 }
429
430 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
431
432 if (CNE->isArray()) {
433 // FIXME: allocating an array requires simulating the constructors.
434 // For now, just return a symbolicated region.
435 const MemRegion *NewReg = symVal.castAs<loc::MemRegionVal>().getRegion();
436 QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
437 const ElementRegion *EleReg =
438 getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
439 State = State->BindExpr(CNE, Pred->getLocationContext(),
440 loc::MemRegionVal(EleReg));
441 Bldr.generateNode(CNE, Pred, State);
442 return;
443 }
444
445 // FIXME: Once we have proper support for CXXConstructExprs inside
446 // CXXNewExpr, we need to make sure that the constructed object is not
447 // immediately invalidated here. (The placement call should happen before
448 // the constructor call anyway.)
449 SVal Result = symVal;
450 if (FD && FD->isReservedGlobalPlacementOperator()) {
451 // Non-array placement new should always return the placement location.
452 SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx);
453 Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(),
454 CNE->getPlacementArg(0)->getType());
455 }
456
457 // Bind the address of the object, then check to see if we cached out.
458 State = State->BindExpr(CNE, LCtx, Result);
459 ExplodedNode *NewN = Bldr.generateNode(CNE, Pred, State);
460 if (!NewN)
461 return;
462
463 // If the type is not a record, we won't have a CXXConstructExpr as an
464 // initializer. Copy the value over.
465 if (const Expr *Init = CNE->getInitializer()) {
466 if (!isa<CXXConstructExpr>(Init)) {
467 assert(Bldr.getResults().size() == 1);
468 Bldr.takeNodes(NewN);
469 evalBind(Dst, CNE, NewN, Result, State->getSVal(Init, LCtx),
470 /*FirstInit=*/IsStandardGlobalOpNewFunction);
471 }
472 }
473 }
474
VisitCXXDeleteExpr(const CXXDeleteExpr * CDE,ExplodedNode * Pred,ExplodedNodeSet & Dst)475 void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
476 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
477 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
478 ProgramStateRef state = Pred->getState();
479 Bldr.generateNode(CDE, Pred, state);
480 }
481
VisitCXXCatchStmt(const CXXCatchStmt * CS,ExplodedNode * Pred,ExplodedNodeSet & Dst)482 void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS,
483 ExplodedNode *Pred,
484 ExplodedNodeSet &Dst) {
485 const VarDecl *VD = CS->getExceptionDecl();
486 if (!VD) {
487 Dst.Add(Pred);
488 return;
489 }
490
491 const LocationContext *LCtx = Pred->getLocationContext();
492 SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(),
493 currBldrCtx->blockCount());
494 ProgramStateRef state = Pred->getState();
495 state = state->bindLoc(state->getLValue(VD, LCtx), V);
496
497 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
498 Bldr.generateNode(CS, Pred, state);
499 }
500
VisitCXXThisExpr(const CXXThisExpr * TE,ExplodedNode * Pred,ExplodedNodeSet & Dst)501 void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
502 ExplodedNodeSet &Dst) {
503 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
504
505 // Get the this object region from StoreManager.
506 const LocationContext *LCtx = Pred->getLocationContext();
507 const MemRegion *R =
508 svalBuilder.getRegionManager().getCXXThisRegion(
509 getContext().getCanonicalType(TE->getType()),
510 LCtx);
511
512 ProgramStateRef state = Pred->getState();
513 SVal V = state->getSVal(loc::MemRegionVal(R));
514 Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V));
515 }
516