• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
106 const MemRegion *
getRegionForConstructedObject(const CXXConstructExpr * CE,ExplodedNode * Pred)107 ExprEngine::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.
canHaveDirectConstructor(CFGElement Elem)161 static 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 
177 Optional<CFGElement>
findElementDirectlyInitializedByCurrentConstructor()178 ExprEngine::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 
203 const CXXConstructExpr *
findDirectConstructorForCurrentCFGElement()204 ExprEngine::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 
VisitCXXConstructExpr(const CXXConstructExpr * CE,ExplodedNode * Pred,ExplodedNodeSet & destNodes)233 void 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 
VisitCXXDestructor(QualType ObjectType,const MemRegion * Dest,const Stmt * S,bool IsBaseDtor,ExplodedNode * Pred,ExplodedNodeSet & Dst)355 void 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 
VisitCXXNewAllocatorCall(const CXXNewExpr * CNE,ExplodedNode * Pred,ExplodedNodeSet & Dst)400 void 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 
VisitCXXNewExpr(const CXXNewExpr * CNE,ExplodedNode * Pred,ExplodedNodeSet & Dst)426 void 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 
VisitCXXDeleteExpr(const CXXDeleteExpr * CDE,ExplodedNode * Pred,ExplodedNodeSet & Dst)531 void 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 
VisitCXXCatchStmt(const CXXCatchStmt * CS,ExplodedNode * Pred,ExplodedNodeSet & Dst)538 void 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 
VisitCXXThisExpr(const CXXThisExpr * TE,ExplodedNode * Pred,ExplodedNodeSet & Dst)557 void 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 
VisitLambdaExpr(const LambdaExpr * LE,ExplodedNode * Pred,ExplodedNodeSet & Dst)573 void 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