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
22using namespace clang;
23using namespace ento;
24
25void 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.
39void 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.
92static 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
106const MemRegion *
107ExprEngine::getRegionForConstructedObject(const CXXConstructExpr *CE,
108                                          ExplodedNode *Pred) {
109  const LocationContext *LCtx = Pred->getLocationContext();
110  ProgramStateRef State = Pred->getState();
111
112  // See if we're constructing an existing region by looking at the next
113  // element in the CFG.
114
115  if (auto Elem = findElementDirectlyInitializedByCurrentConstructor()) {
116    if (Optional<CFGStmt> StmtElem = Elem->getAs<CFGStmt>()) {
117      auto *DS = cast<DeclStmt>(StmtElem->getStmt());
118      if (const auto *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) {
119        if (Var->getInit() && Var->getInit()->IgnoreImplicit() == CE) {
120          SVal LValue = State->getLValue(Var, LCtx);
121          QualType Ty = Var->getType();
122          LValue = makeZeroElementRegion(State, LValue, Ty);
123          return LValue.getAsRegion();
124        }
125      }
126    } else if (Optional<CFGInitializer> InitElem = Elem->getAs<CFGInitializer>()) {
127      const CXXCtorInitializer *Init = InitElem->getInitializer();
128      assert(Init->isAnyMemberInitializer());
129      const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
130      Loc ThisPtr =
131      getSValBuilder().getCXXThis(CurCtor, LCtx->getCurrentStackFrame());
132      SVal ThisVal = State->getSVal(ThisPtr);
133
134      const ValueDecl *Field;
135      SVal FieldVal;
136      if (Init->isIndirectMemberInitializer()) {
137        Field = Init->getIndirectMember();
138        FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal);
139      } else {
140        Field = Init->getMember();
141        FieldVal = State->getLValue(Init->getMember(), ThisVal);
142      }
143
144      QualType Ty = Field->getType();
145      FieldVal = makeZeroElementRegion(State, FieldVal, Ty);
146      return FieldVal.getAsRegion();
147    }
148
149    // FIXME: This will eventually need to handle new-expressions as well.
150    // Don't forget to update the pre-constructor initialization code in
151    // ExprEngine::VisitCXXConstructExpr.
152  }
153  // If we couldn't find an existing region to construct into, assume we're
154  // constructing a temporary.
155  MemRegionManager &MRMgr = getSValBuilder().getRegionManager();
156  return MRMgr.getCXXTempObjectRegion(CE, LCtx);
157}
158
159/// Returns true if the initializer for \Elem can be a direct
160/// constructor.
161static bool canHaveDirectConstructor(CFGElement Elem){
162  // DeclStmts and CXXCtorInitializers for fields can be directly constructed.
163
164  if (Optional<CFGStmt> StmtElem = Elem.getAs<CFGStmt>()) {
165    if (isa<DeclStmt>(StmtElem->getStmt())) {
166      return true;
167    }
168  }
169
170  if (Elem.getKind() == CFGElement::Initializer) {
171    return true;
172  }
173
174  return false;
175}
176
177Optional<CFGElement>
178ExprEngine::findElementDirectlyInitializedByCurrentConstructor() {
179  const NodeBuilderContext &CurrBldrCtx = getBuilderContext();
180  // See if we're constructing an existing region by looking at the next
181  // element in the CFG.
182  const CFGBlock *B = CurrBldrCtx.getBlock();
183  assert(isa<CXXConstructExpr>(((*B)[currStmtIdx]).castAs<CFGStmt>().getStmt()));
184  unsigned int NextStmtIdx = currStmtIdx + 1;
185  if (NextStmtIdx >= B->size())
186    return None;
187
188  CFGElement Next = (*B)[NextStmtIdx];
189
190  // Is this a destructor? If so, we might be in the middle of an assignment
191  // to a local or member: look ahead one more element to see what we find.
192  while (Next.getAs<CFGImplicitDtor>() && NextStmtIdx + 1 < B->size()) {
193    ++NextStmtIdx;
194    Next = (*B)[NextStmtIdx];
195  }
196
197  if (canHaveDirectConstructor(Next))
198    return Next;
199
200  return None;
201}
202
203const CXXConstructExpr *
204ExprEngine::findDirectConstructorForCurrentCFGElement() {
205  // Go backward in the CFG to see if the previous element (ignoring
206  // destructors) was a CXXConstructExpr. If so, that constructor
207  // was constructed directly into an existing region.
208  // This process is essentially the inverse of that performed in
209  // findElementDirectlyInitializedByCurrentConstructor().
210  if (currStmtIdx == 0)
211    return nullptr;
212
213  const CFGBlock *B = getBuilderContext().getBlock();
214  assert(canHaveDirectConstructor((*B)[currStmtIdx]));
215
216  unsigned int PreviousStmtIdx = currStmtIdx - 1;
217  CFGElement Previous = (*B)[PreviousStmtIdx];
218
219  while (Previous.getAs<CFGImplicitDtor>() && PreviousStmtIdx > 0) {
220    --PreviousStmtIdx;
221    Previous = (*B)[PreviousStmtIdx];
222  }
223
224  if (Optional<CFGStmt> PrevStmtElem = Previous.getAs<CFGStmt>()) {
225    if (auto *CtorExpr = dyn_cast<CXXConstructExpr>(PrevStmtElem->getStmt())) {
226      return CtorExpr;
227    }
228  }
229
230  return nullptr;
231}
232
233void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
234                                       ExplodedNode *Pred,
235                                       ExplodedNodeSet &destNodes) {
236  const LocationContext *LCtx = Pred->getLocationContext();
237  ProgramStateRef State = Pred->getState();
238
239  const MemRegion *Target = nullptr;
240
241  // FIXME: Handle arrays, which run the same constructor for every element.
242  // For now, we just run the first constructor (which should still invalidate
243  // the entire array).
244
245  switch (CE->getConstructionKind()) {
246  case CXXConstructExpr::CK_Complete: {
247    Target = getRegionForConstructedObject(CE, Pred);
248    break;
249  }
250  case CXXConstructExpr::CK_VirtualBase:
251    // Make sure we are not calling virtual base class initializers twice.
252    // Only the most-derived object should initialize virtual base classes.
253    if (const Stmt *Outer = LCtx->getCurrentStackFrame()->getCallSite()) {
254      const CXXConstructExpr *OuterCtor = dyn_cast<CXXConstructExpr>(Outer);
255      if (OuterCtor) {
256        switch (OuterCtor->getConstructionKind()) {
257        case CXXConstructExpr::CK_NonVirtualBase:
258        case CXXConstructExpr::CK_VirtualBase:
259          // Bail out!
260          destNodes.Add(Pred);
261          return;
262        case CXXConstructExpr::CK_Complete:
263        case CXXConstructExpr::CK_Delegating:
264          break;
265        }
266      }
267    }
268    // FALLTHROUGH
269  case CXXConstructExpr::CK_NonVirtualBase:
270  case CXXConstructExpr::CK_Delegating: {
271    const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
272    Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor,
273                                              LCtx->getCurrentStackFrame());
274    SVal ThisVal = State->getSVal(ThisPtr);
275
276    if (CE->getConstructionKind() == CXXConstructExpr::CK_Delegating) {
277      Target = ThisVal.getAsRegion();
278    } else {
279      // Cast to the base type.
280      bool IsVirtual =
281        (CE->getConstructionKind() == CXXConstructExpr::CK_VirtualBase);
282      SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, CE->getType(),
283                                                         IsVirtual);
284      Target = BaseVal.getAsRegion();
285    }
286    break;
287  }
288  }
289
290  CallEventManager &CEMgr = getStateManager().getCallEventManager();
291  CallEventRef<CXXConstructorCall> Call =
292    CEMgr.getCXXConstructorCall(CE, Target, State, LCtx);
293
294  ExplodedNodeSet DstPreVisit;
295  getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this);
296
297  ExplodedNodeSet PreInitialized;
298  {
299    StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx);
300    if (CE->requiresZeroInitialization()) {
301      // Type of the zero doesn't matter.
302      SVal ZeroVal = svalBuilder.makeZeroVal(getContext().CharTy);
303
304      for (ExplodedNodeSet::iterator I = DstPreVisit.begin(),
305                                     E = DstPreVisit.end();
306           I != E; ++I) {
307        ProgramStateRef State = (*I)->getState();
308        // FIXME: Once we properly handle constructors in new-expressions, we'll
309        // need to invalidate the region before setting a default value, to make
310        // sure there aren't any lingering bindings around. This probably needs
311        // to happen regardless of whether or not the object is zero-initialized
312        // to handle random fields of a placement-initialized object picking up
313        // old bindings. We might only want to do it when we need to, though.
314        // FIXME: This isn't actually correct for arrays -- we need to zero-
315        // initialize the entire array, not just the first element -- but our
316        // handling of arrays everywhere else is weak as well, so this shouldn't
317        // actually make things worse. Placement new makes this tricky as well,
318        // since it's then possible to be initializing one part of a multi-
319        // dimensional array.
320        State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal);
321        Bldr.generateNode(CE, *I, State, /*tag=*/nullptr,
322                          ProgramPoint::PreStmtKind);
323      }
324    }
325  }
326
327  ExplodedNodeSet DstPreCall;
328  getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized,
329                                            *Call, *this);
330
331  ExplodedNodeSet DstEvaluated;
332  StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);
333
334  bool IsArray = isa<ElementRegion>(Target);
335  if (CE->getConstructor()->isTrivial() &&
336      CE->getConstructor()->isCopyOrMoveConstructor() &&
337      !IsArray) {
338    // FIXME: Handle other kinds of trivial constructors as well.
339    for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
340         I != E; ++I)
341      performTrivialCopy(Bldr, *I, *Call);
342
343  } else {
344    for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
345         I != E; ++I)
346      defaultEvalCall(Bldr, *I, *Call);
347  }
348
349  ExplodedNodeSet DstPostCall;
350  getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated,
351                                             *Call, *this);
352  getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this);
353}
354
355void ExprEngine::VisitCXXDestructor(QualType ObjectType,
356                                    const MemRegion *Dest,
357                                    const Stmt *S,
358                                    bool IsBaseDtor,
359                                    ExplodedNode *Pred,
360                                    ExplodedNodeSet &Dst) {
361  const LocationContext *LCtx = Pred->getLocationContext();
362  ProgramStateRef State = Pred->getState();
363
364  // FIXME: We need to run the same destructor on every element of the array.
365  // This workaround will just run the first destructor (which will still
366  // invalidate the entire array).
367  SVal DestVal = UnknownVal();
368  if (Dest)
369    DestVal = loc::MemRegionVal(Dest);
370  DestVal = makeZeroElementRegion(State, DestVal, ObjectType);
371  Dest = DestVal.getAsRegion();
372
373  const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl();
374  assert(RecordDecl && "Only CXXRecordDecls should have destructors");
375  const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor();
376
377  CallEventManager &CEMgr = getStateManager().getCallEventManager();
378  CallEventRef<CXXDestructorCall> Call =
379    CEMgr.getCXXDestructorCall(DtorDecl, S, Dest, IsBaseDtor, State, LCtx);
380
381  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
382                                Call->getSourceRange().getBegin(),
383                                "Error evaluating destructor");
384
385  ExplodedNodeSet DstPreCall;
386  getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
387                                            *Call, *this);
388
389  ExplodedNodeSet DstInvalidated;
390  StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
391  for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
392       I != E; ++I)
393    defaultEvalCall(Bldr, *I, *Call);
394
395  ExplodedNodeSet DstPostCall;
396  getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
397                                             *Call, *this);
398}
399
400void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
401                                          ExplodedNode *Pred,
402                                          ExplodedNodeSet &Dst) {
403  ProgramStateRef State = Pred->getState();
404  const LocationContext *LCtx = Pred->getLocationContext();
405  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
406                                CNE->getStartLoc(),
407                                "Error evaluating New Allocator Call");
408  CallEventManager &CEMgr = getStateManager().getCallEventManager();
409  CallEventRef<CXXAllocatorCall> Call =
410    CEMgr.getCXXAllocatorCall(CNE, State, LCtx);
411
412  ExplodedNodeSet DstPreCall;
413  getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
414                                            *Call, *this);
415
416  ExplodedNodeSet DstInvalidated;
417  StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
418  for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
419       I != E; ++I)
420    defaultEvalCall(Bldr, *I, *Call);
421  getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
422                                             *Call, *this);
423}
424
425
426void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
427                                   ExplodedNodeSet &Dst) {
428  // FIXME: Much of this should eventually migrate to CXXAllocatorCall.
429  // Also, we need to decide how allocators actually work -- they're not
430  // really part of the CXXNewExpr because they happen BEFORE the
431  // CXXConstructExpr subexpression. See PR12014 for some discussion.
432
433  unsigned blockCount = currBldrCtx->blockCount();
434  const LocationContext *LCtx = Pred->getLocationContext();
435  DefinedOrUnknownSVal symVal = UnknownVal();
436  FunctionDecl *FD = CNE->getOperatorNew();
437
438  bool IsStandardGlobalOpNewFunction = false;
439  if (FD && !isa<CXXMethodDecl>(FD) && !FD->isVariadic()) {
440    if (FD->getNumParams() == 2) {
441      QualType T = FD->getParamDecl(1)->getType();
442      if (const IdentifierInfo *II = T.getBaseTypeIdentifier())
443        // NoThrow placement new behaves as a standard new.
444        IsStandardGlobalOpNewFunction = II->getName().equals("nothrow_t");
445    }
446    else
447      // Placement forms are considered non-standard.
448      IsStandardGlobalOpNewFunction = (FD->getNumParams() == 1);
449  }
450
451  // We assume all standard global 'operator new' functions allocate memory in
452  // heap. We realize this is an approximation that might not correctly model
453  // a custom global allocator.
454  if (IsStandardGlobalOpNewFunction)
455    symVal = svalBuilder.getConjuredHeapSymbolVal(CNE, LCtx, blockCount);
456  else
457    symVal = svalBuilder.conjureSymbolVal(nullptr, CNE, LCtx, CNE->getType(),
458                                          blockCount);
459
460  ProgramStateRef State = Pred->getState();
461  CallEventManager &CEMgr = getStateManager().getCallEventManager();
462  CallEventRef<CXXAllocatorCall> Call =
463    CEMgr.getCXXAllocatorCall(CNE, State, LCtx);
464
465  // Invalidate placement args.
466  // FIXME: Once we figure out how we want allocators to work,
467  // we should be using the usual pre-/(default-)eval-/post-call checks here.
468  State = Call->invalidateRegions(blockCount);
469  if (!State)
470    return;
471
472  // If this allocation function is not declared as non-throwing, failures
473  // /must/ be signalled by exceptions, and thus the return value will never be
474  // NULL. -fno-exceptions does not influence this semantics.
475  // FIXME: GCC has a -fcheck-new option, which forces it to consider the case
476  // where new can return NULL. If we end up supporting that option, we can
477  // consider adding a check for it here.
478  // C++11 [basic.stc.dynamic.allocation]p3.
479  if (FD) {
480    QualType Ty = FD->getType();
481    if (const FunctionProtoType *ProtoType = Ty->getAs<FunctionProtoType>())
482      if (!ProtoType->isNothrow(getContext()))
483        State = State->assume(symVal, true);
484  }
485
486  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
487
488  if (CNE->isArray()) {
489    // FIXME: allocating an array requires simulating the constructors.
490    // For now, just return a symbolicated region.
491    const MemRegion *NewReg = symVal.castAs<loc::MemRegionVal>().getRegion();
492    QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
493    const ElementRegion *EleReg =
494      getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
495    State = State->BindExpr(CNE, Pred->getLocationContext(),
496                            loc::MemRegionVal(EleReg));
497    Bldr.generateNode(CNE, Pred, State);
498    return;
499  }
500
501  // FIXME: Once we have proper support for CXXConstructExprs inside
502  // CXXNewExpr, we need to make sure that the constructed object is not
503  // immediately invalidated here. (The placement call should happen before
504  // the constructor call anyway.)
505  SVal Result = symVal;
506  if (FD && FD->isReservedGlobalPlacementOperator()) {
507    // Non-array placement new should always return the placement location.
508    SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx);
509    Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(),
510                                  CNE->getPlacementArg(0)->getType());
511  }
512
513  // Bind the address of the object, then check to see if we cached out.
514  State = State->BindExpr(CNE, LCtx, Result);
515  ExplodedNode *NewN = Bldr.generateNode(CNE, Pred, State);
516  if (!NewN)
517    return;
518
519  // If the type is not a record, we won't have a CXXConstructExpr as an
520  // initializer. Copy the value over.
521  if (const Expr *Init = CNE->getInitializer()) {
522    if (!isa<CXXConstructExpr>(Init)) {
523      assert(Bldr.getResults().size() == 1);
524      Bldr.takeNodes(NewN);
525      evalBind(Dst, CNE, NewN, Result, State->getSVal(Init, LCtx),
526               /*FirstInit=*/IsStandardGlobalOpNewFunction);
527    }
528  }
529}
530
531void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
532                                    ExplodedNode *Pred, ExplodedNodeSet &Dst) {
533  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
534  ProgramStateRef state = Pred->getState();
535  Bldr.generateNode(CDE, Pred, state);
536}
537
538void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS,
539                                   ExplodedNode *Pred,
540                                   ExplodedNodeSet &Dst) {
541  const VarDecl *VD = CS->getExceptionDecl();
542  if (!VD) {
543    Dst.Add(Pred);
544    return;
545  }
546
547  const LocationContext *LCtx = Pred->getLocationContext();
548  SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(),
549                                        currBldrCtx->blockCount());
550  ProgramStateRef state = Pred->getState();
551  state = state->bindLoc(state->getLValue(VD, LCtx), V);
552
553  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
554  Bldr.generateNode(CS, Pred, state);
555}
556
557void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
558                                    ExplodedNodeSet &Dst) {
559  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
560
561  // Get the this object region from StoreManager.
562  const LocationContext *LCtx = Pred->getLocationContext();
563  const MemRegion *R =
564    svalBuilder.getRegionManager().getCXXThisRegion(
565                                  getContext().getCanonicalType(TE->getType()),
566                                                    LCtx);
567
568  ProgramStateRef state = Pred->getState();
569  SVal V = state->getSVal(loc::MemRegionVal(R));
570  Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V));
571}
572
573void ExprEngine::VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred,
574                                 ExplodedNodeSet &Dst) {
575  const LocationContext *LocCtxt = Pred->getLocationContext();
576
577  // Get the region of the lambda itself.
578  const MemRegion *R = svalBuilder.getRegionManager().getCXXTempObjectRegion(
579      LE, LocCtxt);
580  SVal V = loc::MemRegionVal(R);
581
582  ProgramStateRef State = Pred->getState();
583
584  // If we created a new MemRegion for the lambda, we should explicitly bind
585  // the captures.
586  CXXRecordDecl::field_iterator CurField = LE->getLambdaClass()->field_begin();
587  for (LambdaExpr::const_capture_init_iterator i = LE->capture_init_begin(),
588                                               e = LE->capture_init_end();
589       i != e; ++i, ++CurField) {
590    FieldDecl *FieldForCapture = *CurField;
591    SVal FieldLoc = State->getLValue(FieldForCapture, V);
592
593    SVal InitVal;
594    if (!FieldForCapture->hasCapturedVLAType()) {
595      Expr *InitExpr = *i;
596      assert(InitExpr && "Capture missing initialization expression");
597      InitVal = State->getSVal(InitExpr, LocCtxt);
598    } else {
599      // The field stores the length of a captured variable-length array.
600      // These captures don't have initialization expressions; instead we
601      // get the length from the VLAType size expression.
602      Expr *SizeExpr = FieldForCapture->getCapturedVLAType()->getSizeExpr();
603      InitVal = State->getSVal(SizeExpr, LocCtxt);
604    }
605
606    State = State->bindLoc(FieldLoc, InitVal);
607  }
608
609  // Decay the Loc into an RValue, because there might be a
610  // MaterializeTemporaryExpr node above this one which expects the bound value
611  // to be an RValue.
612  SVal LambdaRVal = State->getSVal(R);
613
614  ExplodedNodeSet Tmp;
615  StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
616  // FIXME: is this the right program point kind?
617  Bldr.generateNode(LE, Pred,
618                    State->BindExpr(LE, LocCtxt, LambdaRVal),
619                    nullptr, ProgramPoint::PostLValueKind);
620
621  // FIXME: Move all post/pre visits to ::Visit().
622  getCheckerManager().runCheckersForPostStmt(Dst, Tmp, LE, *this);
623}
624