1//===- ExprEngineCXX.cpp - ExprEngine support for C++ -----------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the C++ expression evaluation engine.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
14#include "clang/Analysis/ConstructionContext.h"
15#include "clang/AST/DeclCXX.h"
16#include "clang/AST/StmtCXX.h"
17#include "clang/AST/ParentMap.h"
18#include "clang/Basic/PrettyStackTrace.h"
19#include "clang/StaticAnalyzer/Core/CheckerManager.h"
20#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
21#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
22
23using namespace clang;
24using namespace ento;
25
26void ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
27 ExplodedNode *Pred,
28 ExplodedNodeSet &Dst) {
29 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
30 const Expr *tempExpr = ME->getSubExpr()->IgnoreParens();
31 ProgramStateRef state = Pred->getState();
32 const LocationContext *LCtx = Pred->getLocationContext();
33
34 state = createTemporaryRegionIfNeeded(state, LCtx, tempExpr, ME);
35 Bldr.generateNode(ME, Pred, state);
36}
37
38// FIXME: This is the sort of code that should eventually live in a Core
39// checker rather than as a special case in ExprEngine.
40void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
41 const CallEvent &Call) {
42 SVal ThisVal;
43 bool AlwaysReturnsLValue;
44 const CXXRecordDecl *ThisRD = nullptr;
45 if (const CXXConstructorCall *Ctor = dyn_cast<CXXConstructorCall>(&Call)) {
46 assert(Ctor->getDecl()->isTrivial());
47 assert(Ctor->getDecl()->isCopyOrMoveConstructor());
48 ThisVal = Ctor->getCXXThisVal();
49 ThisRD = Ctor->getDecl()->getParent();
50 AlwaysReturnsLValue = false;
51 } else {
52 assert(cast<CXXMethodDecl>(Call.getDecl())->isTrivial());
53 assert(cast<CXXMethodDecl>(Call.getDecl())->getOverloadedOperator() ==
54 OO_Equal);
55 ThisVal = cast<CXXInstanceCall>(Call).getCXXThisVal();
56 ThisRD = cast<CXXMethodDecl>(Call.getDecl())->getParent();
57 AlwaysReturnsLValue = true;
58 }
59
60 assert(ThisRD);
61 if (ThisRD->isEmpty()) {
62 // Do nothing for empty classes. Otherwise it'd retrieve an UnknownVal
63 // and bind it and RegionStore would think that the actual value
64 // in this region at this offset is unknown.
65 return;
66 }
67
68 const LocationContext *LCtx = Pred->getLocationContext();
69
70 ExplodedNodeSet Dst;
71 Bldr.takeNodes(Pred);
72
73 SVal V = Call.getArgSVal(0);
74
75 // If the value being copied is not unknown, load from its location to get
76 // an aggregate rvalue.
77 if (Optional<Loc> L = V.getAs<Loc>())
78 V = Pred->getState()->getSVal(*L);
79 else
80 assert(V.isUnknownOrUndef());
81
82 const Expr *CallExpr = Call.getOriginExpr();
83 evalBind(Dst, CallExpr, Pred, ThisVal, V, true);
84
85 PostStmt PS(CallExpr, LCtx);
86 for (ExplodedNodeSet::iterator I = Dst.begin(), E = Dst.end();
87 I != E; ++I) {
88 ProgramStateRef State = (*I)->getState();
89 if (AlwaysReturnsLValue)
90 State = State->BindExpr(CallExpr, LCtx, ThisVal);
91 else
92 State = bindReturnValue(Call, LCtx, State);
93 Bldr.generateNode(PS, State, *I);
94 }
95}
96
97SVal ExprEngine::makeElementRegion(ProgramStateRef State, SVal LValue,
98 QualType &Ty, bool &IsArray, unsigned Idx) {
99 SValBuilder &SVB = State->getStateManager().getSValBuilder();
100 ASTContext &Ctx = SVB.getContext();
101
102 if (const ArrayType *AT = Ctx.getAsArrayType(Ty)) {
103 while (AT) {
104 Ty = AT->getElementType();
105 AT = dyn_cast<ArrayType>(AT->getElementType());
106 }
107 LValue = State->getLValue(Ty, SVB.makeArrayIndex(Idx), LValue);
108 IsArray = true;
109 }
110
111 return LValue;
112}
113
114SVal ExprEngine::computeObjectUnderConstruction(
115 const Expr *E, ProgramStateRef State, const LocationContext *LCtx,
116 const ConstructionContext *CC, EvalCallOptions &CallOpts, unsigned Idx) {
117 SValBuilder &SVB = getSValBuilder();
118 MemRegionManager &MRMgr = SVB.getRegionManager();
119 ASTContext &ACtx = SVB.getContext();
120
121 // Compute the target region by exploring the construction context.
122 if (CC) {
123 switch (CC->getKind()) {
124 case ConstructionContext::CXX17ElidedCopyVariableKind:
125 case ConstructionContext::SimpleVariableKind: {
126 const auto *DSCC = cast<VariableConstructionContext>(CC);
127 const auto *DS = DSCC->getDeclStmt();
128 const auto *Var = cast<VarDecl>(DS->getSingleDecl());
129 QualType Ty = Var->getType();
130 return makeElementRegion(State, State->getLValue(Var, LCtx), Ty,
131 CallOpts.IsArrayCtorOrDtor, Idx);
132 }
133 case ConstructionContext::CXX17ElidedCopyConstructorInitializerKind:
134 case ConstructionContext::SimpleConstructorInitializerKind: {
135 const auto *ICC = cast<ConstructorInitializerConstructionContext>(CC);
136 const auto *Init = ICC->getCXXCtorInitializer();
137 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
138 Loc ThisPtr = SVB.getCXXThis(CurCtor, LCtx->getStackFrame());
139 SVal ThisVal = State->getSVal(ThisPtr);
140 if (Init->isBaseInitializer()) {
141 const auto *ThisReg = cast<SubRegion>(ThisVal.getAsRegion());
142 const CXXRecordDecl *BaseClass =
143 Init->getBaseClass()->getAsCXXRecordDecl();
144 const auto *BaseReg =
145 MRMgr.getCXXBaseObjectRegion(BaseClass, ThisReg,
146 Init->isBaseVirtual());
147 return SVB.makeLoc(BaseReg);
148 }
149 if (Init->isDelegatingInitializer())
150 return ThisVal;
151
152 const ValueDecl *Field;
153 SVal FieldVal;
154 if (Init->isIndirectMemberInitializer()) {
155 Field = Init->getIndirectMember();
156 FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal);
157 } else {
158 Field = Init->getMember();
159 FieldVal = State->getLValue(Init->getMember(), ThisVal);
160 }
161
162 QualType Ty = Field->getType();
163 return makeElementRegion(State, FieldVal, Ty, CallOpts.IsArrayCtorOrDtor,
164 Idx);
165 }
166 case ConstructionContext::NewAllocatedObjectKind: {
167 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
168 const auto *NECC = cast<NewAllocatedObjectConstructionContext>(CC);
169 const auto *NE = NECC->getCXXNewExpr();
170 SVal V = *getObjectUnderConstruction(State, NE, LCtx);
171 if (const SubRegion *MR =
172 dyn_cast_or_null<SubRegion>(V.getAsRegion())) {
173 if (NE->isArray()) {
174 // TODO: In fact, we need to call the constructor for every
175 // allocated element, not just the first one!
176 CallOpts.IsArrayCtorOrDtor = true;
177
178 auto R = MRMgr.getElementRegion(NE->getType()->getPointeeType(),
179 svalBuilder.makeArrayIndex(Idx), MR,
180 SVB.getContext());
181
182 return loc::MemRegionVal(R);
183 }
184 return V;
185 }
186 // TODO: Detect when the allocator returns a null pointer.
187 // Constructor shall not be called in this case.
188 }
189 break;
190 }
191 case ConstructionContext::SimpleReturnedValueKind:
192 case ConstructionContext::CXX17ElidedCopyReturnedValueKind: {
193 // The temporary is to be managed by the parent stack frame.
194 // So build it in the parent stack frame if we're not in the
195 // top frame of the analysis.
196 const StackFrameContext *SFC = LCtx->getStackFrame();
197 if (const LocationContext *CallerLCtx = SFC->getParent()) {
198 auto RTC = (*SFC->getCallSiteBlock())[SFC->getIndex()]
199 .getAs<CFGCXXRecordTypedCall>();
200 if (!RTC) {
201 // We were unable to find the correct construction context for the
202 // call in the parent stack frame. This is equivalent to not being
203 // able to find construction context at all.
204 break;
205 }
206 if (isa<BlockInvocationContext>(CallerLCtx)) {
207 // Unwrap block invocation contexts. They're mostly part of
208 // the current stack frame.
209 CallerLCtx = CallerLCtx->getParent();
210 assert(!isa<BlockInvocationContext>(CallerLCtx));
211 }
212 return computeObjectUnderConstruction(
213 cast<Expr>(SFC->getCallSite()), State, CallerLCtx,
214 RTC->getConstructionContext(), CallOpts);
215 } else {
216 // We are on the top frame of the analysis. We do not know where is the
217 // object returned to. Conjure a symbolic region for the return value.
218 // TODO: We probably need a new MemRegion kind to represent the storage
219 // of that SymbolicRegion, so that we cound produce a fancy symbol
220 // instead of an anonymous conjured symbol.
221 // TODO: Do we need to track the region to avoid having it dead
222 // too early? It does die too early, at least in C++17, but because
223 // putting anything into a SymbolicRegion causes an immediate escape,
224 // it doesn't cause any leak false positives.
225 const auto *RCC = cast<ReturnedValueConstructionContext>(CC);
226 // Make sure that this doesn't coincide with any other symbol
227 // conjured for the returned expression.
228 static const int TopLevelSymRegionTag = 0;
229 const Expr *RetE = RCC->getReturnStmt()->getRetValue();
230 assert(RetE && "Void returns should not have a construction context");
231 QualType ReturnTy = RetE->getType();
232 QualType RegionTy = ACtx.getPointerType(ReturnTy);
233 return SVB.conjureSymbolVal(&TopLevelSymRegionTag, RetE, SFC, RegionTy,
234 currBldrCtx->blockCount());
235 }
236 llvm_unreachable("Unhandled return value construction context!");
237 }
238 case ConstructionContext::ElidedTemporaryObjectKind: {
239 assert(AMgr.getAnalyzerOptions().ShouldElideConstructors);
240 const auto *TCC = cast<ElidedTemporaryObjectConstructionContext>(CC);
241
242 // Support pre-C++17 copy elision. We'll have the elidable copy
243 // constructor in the AST and in the CFG, but we'll skip it
244 // and construct directly into the final object. This call
245 // also sets the CallOpts flags for us.
246 // If the elided copy/move constructor is not supported, there's still
247 // benefit in trying to model the non-elided constructor.
248 // Stash our state before trying to elide, as it'll get overwritten.
249 ProgramStateRef PreElideState = State;
250 EvalCallOptions PreElideCallOpts = CallOpts;
251
252 SVal V = computeObjectUnderConstruction(
253 TCC->getConstructorAfterElision(), State, LCtx,
254 TCC->getConstructionContextAfterElision(), CallOpts);
255
256 // FIXME: This definition of "copy elision has not failed" is unreliable.
257 // It doesn't indicate that the constructor will actually be inlined
258 // later; this is still up to evalCall() to decide.
259 if (!CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion)
260 return V;
261
262 // Copy elision failed. Revert the changes and proceed as if we have
263 // a simple temporary.
264 CallOpts = PreElideCallOpts;
265 CallOpts.IsElidableCtorThatHasNotBeenElided = true;
266 [[fallthrough]];
267 }
268 case ConstructionContext::SimpleTemporaryObjectKind: {
269 const auto *TCC = cast<TemporaryObjectConstructionContext>(CC);
270 const MaterializeTemporaryExpr *MTE = TCC->getMaterializedTemporaryExpr();
271
272 CallOpts.IsTemporaryCtorOrDtor = true;
273 if (MTE) {
274 if (const ValueDecl *VD = MTE->getExtendingDecl()) {
275 assert(MTE->getStorageDuration() != SD_FullExpression);
276 if (!VD->getType()->isReferenceType()) {
277 // We're lifetime-extended by a surrounding aggregate.
278 // Automatic destructors aren't quite working in this case
279 // on the CFG side. We should warn the caller about that.
280 // FIXME: Is there a better way to retrieve this information from
281 // the MaterializeTemporaryExpr?
282 CallOpts.IsTemporaryLifetimeExtendedViaAggregate = true;
283 }
284 }
285
286 if (MTE->getStorageDuration() == SD_Static ||
287 MTE->getStorageDuration() == SD_Thread)
288 return loc::MemRegionVal(MRMgr.getCXXStaticTempObjectRegion(E));
289 }
290
291 return loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
292 }
293 case ConstructionContext::LambdaCaptureKind: {
294 CallOpts.IsTemporaryCtorOrDtor = true;
295
296 const auto *LCC = cast<LambdaCaptureConstructionContext>(CC);
297
298 SVal Base = loc::MemRegionVal(
299 MRMgr.getCXXTempObjectRegion(LCC->getInitializer(), LCtx));
300
301 const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E);
302 if (getIndexOfElementToConstruct(State, CE, LCtx)) {
303 CallOpts.IsArrayCtorOrDtor = true;
304 Base = State->getLValue(E->getType(), svalBuilder.makeArrayIndex(Idx),
305 Base);
306 }
307
308 return Base;
309 }
310 case ConstructionContext::ArgumentKind: {
311 // Arguments are technically temporaries.
312 CallOpts.IsTemporaryCtorOrDtor = true;
313
314 const auto *ACC = cast<ArgumentConstructionContext>(CC);
315 const Expr *E = ACC->getCallLikeExpr();
316 unsigned Idx = ACC->getIndex();
317
318 CallEventManager &CEMgr = getStateManager().getCallEventManager();
319 auto getArgLoc = [&](CallEventRef<> Caller) -> Optional<SVal> {
320 const LocationContext *FutureSFC =
321 Caller->getCalleeStackFrame(currBldrCtx->blockCount());
322 // Return early if we are unable to reliably foresee
323 // the future stack frame.
324 if (!FutureSFC)
325 return None;
326
327 // This should be equivalent to Caller->getDecl() for now, but
328 // FutureSFC->getDecl() is likely to support better stuff (like
329 // virtual functions) earlier.
330 const Decl *CalleeD = FutureSFC->getDecl();
331
332 // FIXME: Support for variadic arguments is not implemented here yet.
333 if (CallEvent::isVariadic(CalleeD))
334 return None;
335
336 // Operator arguments do not correspond to operator parameters
337 // because this-argument is implemented as a normal argument in
338 // operator call expressions but not in operator declarations.
339 const TypedValueRegion *TVR = Caller->getParameterLocation(
340 *Caller->getAdjustedParameterIndex(Idx), currBldrCtx->blockCount());
341 if (!TVR)
342 return None;
343
344 return loc::MemRegionVal(TVR);
345 };
346
347 if (const auto *CE = dyn_cast<CallExpr>(E)) {
348 CallEventRef<> Caller = CEMgr.getSimpleCall(CE, State, LCtx);
349 if (Optional<SVal> V = getArgLoc(Caller))
350 return *V;
351 else
352 break;
353 } else if (const auto *CCE = dyn_cast<CXXConstructExpr>(E)) {
354 // Don't bother figuring out the target region for the future
355 // constructor because we won't need it.
356 CallEventRef<> Caller =
357 CEMgr.getCXXConstructorCall(CCE, /*Target=*/nullptr, State, LCtx);
358 if (Optional<SVal> V = getArgLoc(Caller))
359 return *V;
360 else
361 break;
362 } else if (const auto *ME = dyn_cast<ObjCMessageExpr>(E)) {
363 CallEventRef<> Caller = CEMgr.getObjCMethodCall(ME, State, LCtx);
364 if (Optional<SVal> V = getArgLoc(Caller))
365 return *V;
366 else
367 break;
368 }
369 }
370 } // switch (CC->getKind())
371 }
372
373 // If we couldn't find an existing region to construct into, assume we're
374 // constructing a temporary. Notify the caller of our failure.
375 CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true;
376 return loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
377}
378
379ProgramStateRef ExprEngine::updateObjectsUnderConstruction(
380 SVal V, const Expr *E, ProgramStateRef State, const LocationContext *LCtx,
381 const ConstructionContext *CC, const EvalCallOptions &CallOpts) {
382 if (CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion) {
383 // Sounds like we failed to find the target region and therefore
384 // copy elision failed. There's nothing we can do about it here.
385 return State;
386 }
387
388 // See if we're constructing an existing region by looking at the
389 // current construction context.
390 assert(CC && "Computed target region without construction context?");
391 switch (CC->getKind()) {
392 case ConstructionContext::CXX17ElidedCopyVariableKind:
393 case ConstructionContext::SimpleVariableKind: {
394 const auto *DSCC = cast<VariableConstructionContext>(CC);
395 return addObjectUnderConstruction(State, DSCC->getDeclStmt(), LCtx, V);
396 }
397 case ConstructionContext::CXX17ElidedCopyConstructorInitializerKind:
398 case ConstructionContext::SimpleConstructorInitializerKind: {
399 const auto *ICC = cast<ConstructorInitializerConstructionContext>(CC);
400 const auto *Init = ICC->getCXXCtorInitializer();
401 // Base and delegating initializers handled above
402 assert(Init->isAnyMemberInitializer() &&
403 "Base and delegating initializers should have been handled by"
404 "computeObjectUnderConstruction()");
405 return addObjectUnderConstruction(State, Init, LCtx, V);
406 }
407 case ConstructionContext::NewAllocatedObjectKind: {
408 return State;
409 }
410 case ConstructionContext::SimpleReturnedValueKind:
411 case ConstructionContext::CXX17ElidedCopyReturnedValueKind: {
412 const StackFrameContext *SFC = LCtx->getStackFrame();
413 const LocationContext *CallerLCtx = SFC->getParent();
414 if (!CallerLCtx) {
415 // No extra work is necessary in top frame.
416 return State;
417 }
418
419 auto RTC = (*SFC->getCallSiteBlock())[SFC->getIndex()]
420 .getAs<CFGCXXRecordTypedCall>();
421 assert(RTC && "Could not have had a target region without it");
422 if (isa<BlockInvocationContext>(CallerLCtx)) {
423 // Unwrap block invocation contexts. They're mostly part of
424 // the current stack frame.
425 CallerLCtx = CallerLCtx->getParent();
426 assert(!isa<BlockInvocationContext>(CallerLCtx));
427 }
428
429 return updateObjectsUnderConstruction(V,
430 cast<Expr>(SFC->getCallSite()), State, CallerLCtx,
431 RTC->getConstructionContext(), CallOpts);
432 }
433 case ConstructionContext::ElidedTemporaryObjectKind: {
434 assert(AMgr.getAnalyzerOptions().ShouldElideConstructors);
435 if (!CallOpts.IsElidableCtorThatHasNotBeenElided) {
436 const auto *TCC = cast<ElidedTemporaryObjectConstructionContext>(CC);
437 State = updateObjectsUnderConstruction(
438 V, TCC->getConstructorAfterElision(), State, LCtx,
439 TCC->getConstructionContextAfterElision(), CallOpts);
440
441 // Remember that we've elided the constructor.
442 State = addObjectUnderConstruction(
443 State, TCC->getConstructorAfterElision(), LCtx, V);
444
445 // Remember that we've elided the destructor.
446 if (const auto *BTE = TCC->getCXXBindTemporaryExpr())
447 State = elideDestructor(State, BTE, LCtx);
448
449 // Instead of materialization, shamelessly return
450 // the final object destination.
451 if (const auto *MTE = TCC->getMaterializedTemporaryExpr())
452 State = addObjectUnderConstruction(State, MTE, LCtx, V);
453
454 return State;
455 }
456 // If we decided not to elide the constructor, proceed as if
457 // it's a simple temporary.
458 [[fallthrough]];
459 }
460 case ConstructionContext::SimpleTemporaryObjectKind: {
461 const auto *TCC = cast<TemporaryObjectConstructionContext>(CC);
462 if (const auto *BTE = TCC->getCXXBindTemporaryExpr())
463 State = addObjectUnderConstruction(State, BTE, LCtx, V);
464
465 if (const auto *MTE = TCC->getMaterializedTemporaryExpr())
466 State = addObjectUnderConstruction(State, MTE, LCtx, V);
467
468 return State;
469 }
470 case ConstructionContext::LambdaCaptureKind: {
471 const auto *LCC = cast<LambdaCaptureConstructionContext>(CC);
472
473 // If we capture and array, we want to store the super region, not a
474 // sub-region.
475 if (const auto *EL = dyn_cast_or_null<ElementRegion>(V.getAsRegion()))
476 V = loc::MemRegionVal(EL->getSuperRegion());
477
478 return addObjectUnderConstruction(
479 State, {LCC->getLambdaExpr(), LCC->getIndex()}, LCtx, V);
480 }
481 case ConstructionContext::ArgumentKind: {
482 const auto *ACC = cast<ArgumentConstructionContext>(CC);
483 if (const auto *BTE = ACC->getCXXBindTemporaryExpr())
484 State = addObjectUnderConstruction(State, BTE, LCtx, V);
485
486 return addObjectUnderConstruction(
487 State, {ACC->getCallLikeExpr(), ACC->getIndex()}, LCtx, V);
488 }
489 }
490 llvm_unreachable("Unhandled construction context!");
491}
492
493static ProgramStateRef
494bindRequiredArrayElementToEnvironment(ProgramStateRef State,
495 const ArrayInitLoopExpr *AILE,
496 const LocationContext *LCtx, SVal Idx) {
497 // The ctor in this case is guaranteed to be a copy ctor, otherwise we hit a
498 // compile time error.
499 //
500 // -ArrayInitLoopExpr <-- we're here
501 // |-OpaqueValueExpr
502 // | `-DeclRefExpr <-- match this
503 // `-CXXConstructExpr
504 // `-ImplicitCastExpr
505 // `-ArraySubscriptExpr
506 // |-ImplicitCastExpr
507 // | `-OpaqueValueExpr
508 // | `-DeclRefExpr
509 // `-ArrayInitIndexExpr
510 //
511 // The resulting expression might look like the one below in an implicit
512 // copy/move ctor.
513 //
514 // ArrayInitLoopExpr <-- we're here
515 // |-OpaqueValueExpr
516 // | `-MemberExpr <-- match this
517 // | (`-CXXStaticCastExpr) <-- move ctor only
518 // | `-DeclRefExpr
519 // `-CXXConstructExpr
520 // `-ArraySubscriptExpr
521 // |-ImplicitCastExpr
522 // | `-OpaqueValueExpr
523 // | `-MemberExpr
524 // | `-DeclRefExpr
525 // `-ArrayInitIndexExpr
526 //
527 // HACK: There is no way we can put the index of the array element into the
528 // CFG unless we unroll the loop, so we manually select and bind the required
529 // parameter to the environment.
530 const auto *CE = cast<CXXConstructExpr>(AILE->getSubExpr());
531 const auto *OVESrc = AILE->getCommonExpr()->getSourceExpr();
532
533 SVal Base = UnknownVal();
534 if (const auto *ME = dyn_cast<MemberExpr>(OVESrc))
535 Base = State->getSVal(ME, LCtx);
536 else if (const auto *DRE = cast<DeclRefExpr>(OVESrc))
537 Base = State->getLValue(cast<VarDecl>(DRE->getDecl()), LCtx);
538 else
539 llvm_unreachable("ArrayInitLoopExpr contains unexpected source expression");
540
541 SVal NthElem = State->getLValue(CE->getType(), Idx, Base);
542
543 return State->BindExpr(CE->getArg(0), LCtx, NthElem);
544}
545
546void ExprEngine::handleConstructor(const Expr *E,
547 ExplodedNode *Pred,
548 ExplodedNodeSet &destNodes) {
549 const auto *CE = dyn_cast<CXXConstructExpr>(E);
550 const auto *CIE = dyn_cast<CXXInheritedCtorInitExpr>(E);
551 assert(CE || CIE);
552
553 const LocationContext *LCtx = Pred->getLocationContext();
554 ProgramStateRef State = Pred->getState();
555
556 SVal Target = UnknownVal();
557
558 if (CE) {
559 if (Optional<SVal> ElidedTarget =
560 getObjectUnderConstruction(State, CE, LCtx)) {
561 // We've previously modeled an elidable constructor by pretending that it
562 // in fact constructs into the correct target. This constructor can
563 // therefore be skipped.
564 Target = *ElidedTarget;
565 StmtNodeBuilder Bldr(Pred, destNodes, *currBldrCtx);
566 State = finishObjectConstruction(State, CE, LCtx);
567 if (auto L = Target.getAs<Loc>())
568 State = State->BindExpr(CE, LCtx, State->getSVal(*L, CE->getType()));
569 Bldr.generateNode(CE, Pred, State);
570 return;
571 }
572 }
573
574 EvalCallOptions CallOpts;
575 auto C = getCurrentCFGElement().getAs<CFGConstructor>();
576 assert(C || getCurrentCFGElement().getAs<CFGStmt>());
577 const ConstructionContext *CC = C ? C->getConstructionContext() : nullptr;
578
579 const CXXConstructExpr::ConstructionKind CK =
580 CE ? CE->getConstructionKind() : CIE->getConstructionKind();
581 switch (CK) {
582 case CXXConstructExpr::CK_Complete: {
583 // Inherited constructors are always base class constructors.
584 assert(CE && !CIE && "A complete constructor is inherited?!");
585
586 // If the ctor is part of an ArrayInitLoopExpr, we want to handle it
587 // differently.
588 auto *AILE = CC ? CC->getArrayInitLoop() : nullptr;
589
590 unsigned Idx = 0;
591 if (CE->getType()->isArrayType() || AILE) {
592 Idx = getIndexOfElementToConstruct(State, CE, LCtx).value_or(0u);
593 State = setIndexOfElementToConstruct(State, CE, LCtx, Idx + 1);
594 }
595
596 if (AILE) {
597 // Only set this once even though we loop through it multiple times.
598 if (!getPendingInitLoop(State, CE, LCtx))
599 State = setPendingInitLoop(State, CE, LCtx,
600 AILE->getArraySize().getLimitedValue());
601
602 State = bindRequiredArrayElementToEnvironment(
603 State, AILE, LCtx, svalBuilder.makeArrayIndex(Idx));
604 }
605
606 // The target region is found from construction context.
607 std::tie(State, Target) =
608 handleConstructionContext(CE, State, LCtx, CC, CallOpts, Idx);
609 break;
610 }
611 case CXXConstructExpr::CK_VirtualBase: {
612 // Make sure we are not calling virtual base class initializers twice.
613 // Only the most-derived object should initialize virtual base classes.
614 const auto *OuterCtor = dyn_cast_or_null<CXXConstructExpr>(
615 LCtx->getStackFrame()->getCallSite());
616 assert(
617 (!OuterCtor ||
618 OuterCtor->getConstructionKind() == CXXConstructExpr::CK_Complete ||
619 OuterCtor->getConstructionKind() == CXXConstructExpr::CK_Delegating) &&
620 ("This virtual base should have already been initialized by "
621 "the most derived class!"));
622 (void)OuterCtor;
623 [[fallthrough]];
624 }
625 case CXXConstructExpr::CK_NonVirtualBase:
626 // In C++17, classes with non-virtual bases may be aggregates, so they would
627 // be initialized as aggregates without a constructor call, so we may have
628 // a base class constructed directly into an initializer list without
629 // having the derived-class constructor call on the previous stack frame.
630 // Initializer lists may be nested into more initializer lists that
631 // correspond to surrounding aggregate initializations.
632 // FIXME: For now this code essentially bails out. We need to find the
633 // correct target region and set it.
634 // FIXME: Instead of relying on the ParentMap, we should have the
635 // trigger-statement (InitListExpr in this case) passed down from CFG or
636 // otherwise always available during construction.
637 if (isa_and_nonnull<InitListExpr>(LCtx->getParentMap().getParent(E))) {
638 MemRegionManager &MRMgr = getSValBuilder().getRegionManager();
639 Target = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
640 CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true;
641 break;
642 }
643 [[fallthrough]];
644 case CXXConstructExpr::CK_Delegating: {
645 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
646 Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor,
647 LCtx->getStackFrame());
648 SVal ThisVal = State->getSVal(ThisPtr);
649
650 if (CK == CXXConstructExpr::CK_Delegating) {
651 Target = ThisVal;
652 } else {
653 // Cast to the base type.
654 bool IsVirtual = (CK == CXXConstructExpr::CK_VirtualBase);
655 SVal BaseVal =
656 getStoreManager().evalDerivedToBase(ThisVal, E->getType(), IsVirtual);
657 Target = BaseVal;
658 }
659 break;
660 }
661 }
662
663 if (State != Pred->getState()) {
664 static SimpleProgramPointTag T("ExprEngine",
665 "Prepare for object construction");
666 ExplodedNodeSet DstPrepare;
667 StmtNodeBuilder BldrPrepare(Pred, DstPrepare, *currBldrCtx);
668 BldrPrepare.generateNode(E, Pred, State, &T, ProgramPoint::PreStmtKind);
669 assert(DstPrepare.size() <= 1);
670 if (DstPrepare.size() == 0)
671 return;
672 Pred = *BldrPrepare.begin();
673 }
674
675 const MemRegion *TargetRegion = Target.getAsRegion();
676 CallEventManager &CEMgr = getStateManager().getCallEventManager();
677 CallEventRef<> Call =
678 CIE ? (CallEventRef<>)CEMgr.getCXXInheritedConstructorCall(
679 CIE, TargetRegion, State, LCtx)
680 : (CallEventRef<>)CEMgr.getCXXConstructorCall(
681 CE, TargetRegion, State, LCtx);
682
683 ExplodedNodeSet DstPreVisit;
684 getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, E, *this);
685
686 ExplodedNodeSet PreInitialized;
687 if (CE) {
688 // FIXME: Is it possible and/or useful to do this before PreStmt?
689 StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx);
690 for (ExplodedNodeSet::iterator I = DstPreVisit.begin(),
691 E = DstPreVisit.end();
692 I != E; ++I) {
693 ProgramStateRef State = (*I)->getState();
694 if (CE->requiresZeroInitialization()) {
695 // FIXME: Once we properly handle constructors in new-expressions, we'll
696 // need to invalidate the region before setting a default value, to make
697 // sure there aren't any lingering bindings around. This probably needs
698 // to happen regardless of whether or not the object is zero-initialized
699 // to handle random fields of a placement-initialized object picking up
700 // old bindings. We might only want to do it when we need to, though.
701 // FIXME: This isn't actually correct for arrays -- we need to zero-
702 // initialize the entire array, not just the first element -- but our
703 // handling of arrays everywhere else is weak as well, so this shouldn't
704 // actually make things worse. Placement new makes this tricky as well,
705 // since it's then possible to be initializing one part of a multi-
706 // dimensional array.
707 State = State->bindDefaultZero(Target, LCtx);
708 }
709
710 Bldr.generateNode(CE, *I, State, /*tag=*/nullptr,
711 ProgramPoint::PreStmtKind);
712 }
713 } else {
714 PreInitialized = DstPreVisit;
715 }
716
717 ExplodedNodeSet DstPreCall;
718 getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized,
719 *Call, *this);
720
721 ExplodedNodeSet DstEvaluated;
722
723 if (CE && CE->getConstructor()->isTrivial() &&
724 CE->getConstructor()->isCopyOrMoveConstructor() &&
725 !CallOpts.IsArrayCtorOrDtor) {
726 StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);
727 // FIXME: Handle other kinds of trivial constructors as well.
728 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
729 I != E; ++I)
730 performTrivialCopy(Bldr, *I, *Call);
731
732 } else {
733 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
734 I != E; ++I)
735 getCheckerManager().runCheckersForEvalCall(DstEvaluated, *I, *Call, *this,
736 CallOpts);
737 }
738
739 // If the CFG was constructed without elements for temporary destructors
740 // and the just-called constructor created a temporary object then
741 // stop exploration if the temporary object has a noreturn constructor.
742 // This can lose coverage because the destructor, if it were present
743 // in the CFG, would be called at the end of the full expression or
744 // later (for life-time extended temporaries) -- but avoids infeasible
745 // paths when no-return temporary destructors are used for assertions.
746 ExplodedNodeSet DstEvaluatedPostProcessed;
747 StmtNodeBuilder Bldr(DstEvaluated, DstEvaluatedPostProcessed, *currBldrCtx);
748 const AnalysisDeclContext *ADC = LCtx->getAnalysisDeclContext();
749 if (!ADC->getCFGBuildOptions().AddTemporaryDtors) {
750 if (llvm::isa_and_nonnull<CXXTempObjectRegion>(TargetRegion) &&
751 cast<CXXConstructorDecl>(Call->getDecl())
752 ->getParent()
753 ->isAnyDestructorNoReturn()) {
754
755 // If we've inlined the constructor, then DstEvaluated would be empty.
756 // In this case we still want a sink, which could be implemented
757 // in processCallExit. But we don't have that implemented at the moment,
758 // so if you hit this assertion, see if you can avoid inlining
759 // the respective constructor when analyzer-config cfg-temporary-dtors
760 // is set to false.
761 // Otherwise there's nothing wrong with inlining such constructor.
762 assert(!DstEvaluated.empty() &&
763 "We should not have inlined this constructor!");
764
765 for (ExplodedNode *N : DstEvaluated) {
766 Bldr.generateSink(E, N, N->getState());
767 }
768
769 // There is no need to run the PostCall and PostStmt checker
770 // callbacks because we just generated sinks on all nodes in th
771 // frontier.
772 return;
773 }
774 }
775
776 ExplodedNodeSet DstPostArgumentCleanup;
777 for (ExplodedNode *I : DstEvaluatedPostProcessed)
778 finishArgumentConstruction(DstPostArgumentCleanup, I, *Call);
779
780 // If there were other constructors called for object-type arguments
781 // of this constructor, clean them up.
782 ExplodedNodeSet DstPostCall;
783 getCheckerManager().runCheckersForPostCall(DstPostCall,
784 DstPostArgumentCleanup,
785 *Call, *this);
786 getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, E, *this);
787}
788
789void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
790 ExplodedNode *Pred,
791 ExplodedNodeSet &Dst) {
792 handleConstructor(CE, Pred, Dst);
793}
794
795void ExprEngine::VisitCXXInheritedCtorInitExpr(
796 const CXXInheritedCtorInitExpr *CE, ExplodedNode *Pred,
797 ExplodedNodeSet &Dst) {
798 handleConstructor(CE, Pred, Dst);
799}
800
801void ExprEngine::VisitCXXDestructor(QualType ObjectType,
802 const MemRegion *Dest,
803 const Stmt *S,
804 bool IsBaseDtor,
805 ExplodedNode *Pred,
806 ExplodedNodeSet &Dst,
807 EvalCallOptions &CallOpts) {
808 assert(S && "A destructor without a trigger!");
809 const LocationContext *LCtx = Pred->getLocationContext();
810 ProgramStateRef State = Pred->getState();
811
812 const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl();
813 assert(RecordDecl && "Only CXXRecordDecls should have destructors");
814 const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor();
815 // FIXME: There should always be a Decl, otherwise the destructor call
816 // shouldn't have been added to the CFG in the first place.
817 if (!DtorDecl) {
818 // Skip the invalid destructor. We cannot simply return because
819 // it would interrupt the analysis instead.
820 static SimpleProgramPointTag T("ExprEngine", "SkipInvalidDestructor");
821 // FIXME: PostImplicitCall with a null decl may crash elsewhere anyway.
822 PostImplicitCall PP(/*Decl=*/nullptr, S->getEndLoc(), LCtx, &T);
823 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
824 Bldr.generateNode(PP, Pred->getState(), Pred);
825 return;
826 }
827
828 if (!Dest) {
829 // We're trying to destroy something that is not a region. This may happen
830 // for a variety of reasons (unknown target region, concrete integer instead
831 // of target region, etc.). The current code makes an attempt to recover.
832 // FIXME: We probably don't really need to recover when we're dealing
833 // with concrete integers specifically.
834 CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true;
835 if (const Expr *E = dyn_cast_or_null<Expr>(S)) {
836 Dest = MRMgr.getCXXTempObjectRegion(E, Pred->getLocationContext());
837 } else {
838 static SimpleProgramPointTag T("ExprEngine", "SkipInvalidDestructor");
839 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
840 Bldr.generateSink(Pred->getLocation().withTag(&T),
841 Pred->getState(), Pred);
842 return;
843 }
844 }
845
846 CallEventManager &CEMgr = getStateManager().getCallEventManager();
847 CallEventRef<CXXDestructorCall> Call =
848 CEMgr.getCXXDestructorCall(DtorDecl, S, Dest, IsBaseDtor, State, LCtx);
849
850 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
851 Call->getSourceRange().getBegin(),
852 "Error evaluating destructor");
853
854 ExplodedNodeSet DstPreCall;
855 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
856 *Call, *this);
857
858 ExplodedNodeSet DstInvalidated;
859 StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
860 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
861 I != E; ++I)
862 defaultEvalCall(Bldr, *I, *Call, CallOpts);
863
864 getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
865 *Call, *this);
866}
867
868void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
869 ExplodedNode *Pred,
870 ExplodedNodeSet &Dst) {
871 ProgramStateRef State = Pred->getState();
872 const LocationContext *LCtx = Pred->getLocationContext();
873 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
874 CNE->getBeginLoc(),
875 "Error evaluating New Allocator Call");
876 CallEventManager &CEMgr = getStateManager().getCallEventManager();
877 CallEventRef<CXXAllocatorCall> Call =
878 CEMgr.getCXXAllocatorCall(CNE, State, LCtx);
879
880 ExplodedNodeSet DstPreCall;
881 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
882 *Call, *this);
883
884 ExplodedNodeSet DstPostCall;
885 StmtNodeBuilder CallBldr(DstPreCall, DstPostCall, *currBldrCtx);
886 for (ExplodedNode *I : DstPreCall) {
887 // FIXME: Provide evalCall for checkers?
888 defaultEvalCall(CallBldr, I, *Call);
889 }
890 // If the call is inlined, DstPostCall will be empty and we bail out now.
891
892 // Store return value of operator new() for future use, until the actual
893 // CXXNewExpr gets processed.
894 ExplodedNodeSet DstPostValue;
895 StmtNodeBuilder ValueBldr(DstPostCall, DstPostValue, *currBldrCtx);
896 for (ExplodedNode *I : DstPostCall) {
897 // FIXME: Because CNE serves as the "call site" for the allocator (due to
898 // lack of a better expression in the AST), the conjured return value symbol
899 // is going to be of the same type (C++ object pointer type). Technically
900 // this is not correct because the operator new's prototype always says that
901 // it returns a 'void *'. So we should change the type of the symbol,
902 // and then evaluate the cast over the symbolic pointer from 'void *' to
903 // the object pointer type. But without changing the symbol's type it
904 // is breaking too much to evaluate the no-op symbolic cast over it, so we
905 // skip it for now.
906 ProgramStateRef State = I->getState();
907 SVal RetVal = State->getSVal(CNE, LCtx);
908
909 // If this allocation function is not declared as non-throwing, failures
910 // /must/ be signalled by exceptions, and thus the return value will never
911 // be NULL. -fno-exceptions does not influence this semantics.
912 // FIXME: GCC has a -fcheck-new option, which forces it to consider the case
913 // where new can return NULL. If we end up supporting that option, we can
914 // consider adding a check for it here.
915 // C++11 [basic.stc.dynamic.allocation]p3.
916 if (const FunctionDecl *FD = CNE->getOperatorNew()) {
917 QualType Ty = FD->getType();
918 if (const auto *ProtoType = Ty->getAs<FunctionProtoType>())
919 if (!ProtoType->isNothrow())
920 State = State->assume(RetVal.castAs<DefinedOrUnknownSVal>(), true);
921 }
922
923 ValueBldr.generateNode(
924 CNE, I, addObjectUnderConstruction(State, CNE, LCtx, RetVal));
925 }
926
927 ExplodedNodeSet DstPostPostCallCallback;
928 getCheckerManager().runCheckersForPostCall(DstPostPostCallCallback,
929 DstPostValue, *Call, *this);
930 for (ExplodedNode *I : DstPostPostCallCallback) {
931 getCheckerManager().runCheckersForNewAllocator(*Call, Dst, I, *this);
932 }
933}
934
935void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
936 ExplodedNodeSet &Dst) {
937 // FIXME: Much of this should eventually migrate to CXXAllocatorCall.
938 // Also, we need to decide how allocators actually work -- they're not
939 // really part of the CXXNewExpr because they happen BEFORE the
940 // CXXConstructExpr subexpression. See PR12014 for some discussion.
941
942 unsigned blockCount = currBldrCtx->blockCount();
943 const LocationContext *LCtx = Pred->getLocationContext();
944 SVal symVal = UnknownVal();
945 FunctionDecl *FD = CNE->getOperatorNew();
946
947 bool IsStandardGlobalOpNewFunction =
948 FD->isReplaceableGlobalAllocationFunction();
949
950 ProgramStateRef State = Pred->getState();
951
952 // Retrieve the stored operator new() return value.
953 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
954 symVal = *getObjectUnderConstruction(State, CNE, LCtx);
955 State = finishObjectConstruction(State, CNE, LCtx);
956 }
957
958 // We assume all standard global 'operator new' functions allocate memory in
959 // heap. We realize this is an approximation that might not correctly model
960 // a custom global allocator.
961 if (symVal.isUnknown()) {
962 if (IsStandardGlobalOpNewFunction)
963 symVal = svalBuilder.getConjuredHeapSymbolVal(CNE, LCtx, blockCount);
964 else
965 symVal = svalBuilder.conjureSymbolVal(nullptr, CNE, LCtx, CNE->getType(),
966 blockCount);
967 }
968
969 CallEventManager &CEMgr = getStateManager().getCallEventManager();
970 CallEventRef<CXXAllocatorCall> Call =
971 CEMgr.getCXXAllocatorCall(CNE, State, LCtx);
972
973 if (!AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
974 // Invalidate placement args.
975 // FIXME: Once we figure out how we want allocators to work,
976 // we should be using the usual pre-/(default-)eval-/post-call checkers
977 // here.
978 State = Call->invalidateRegions(blockCount);
979 if (!State)
980 return;
981
982 // If this allocation function is not declared as non-throwing, failures
983 // /must/ be signalled by exceptions, and thus the return value will never
984 // be NULL. -fno-exceptions does not influence this semantics.
985 // FIXME: GCC has a -fcheck-new option, which forces it to consider the case
986 // where new can return NULL. If we end up supporting that option, we can
987 // consider adding a check for it here.
988 // C++11 [basic.stc.dynamic.allocation]p3.
989 if (const auto *ProtoType = FD->getType()->getAs<FunctionProtoType>())
990 if (!ProtoType->isNothrow())
991 if (auto dSymVal = symVal.getAs<DefinedOrUnknownSVal>())
992 State = State->assume(*dSymVal, true);
993 }
994
995 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
996
997 SVal Result = symVal;
998
999 if (CNE->isArray()) {
1000
1001 if (const auto *NewReg = cast_or_null<SubRegion>(symVal.getAsRegion())) {
1002 // If each element is initialized by their default constructor, the field
1003 // values are properly placed inside the required region, however if an
1004 // initializer list is used, this doesn't happen automatically.
1005 auto *Init = CNE->getInitializer();
1006 bool isInitList = isa_and_nonnull<InitListExpr>(Init);
1007
1008 QualType ObjTy =
1009 isInitList ? Init->getType() : CNE->getType()->getPointeeType();
1010 const ElementRegion *EleReg =
1011 MRMgr.getElementRegion(ObjTy, svalBuilder.makeArrayIndex(0), NewReg,
1012 svalBuilder.getContext());
1013 Result = loc::MemRegionVal(EleReg);
1014
1015 // If the array is list initialized, we bind the initializer list to the
1016 // memory region here, otherwise we would lose it.
1017 if (isInitList) {
1018 Bldr.takeNodes(Pred);
1019 Pred = Bldr.generateNode(CNE, Pred, State);
1020
1021 SVal V = State->getSVal(Init, LCtx);
1022 ExplodedNodeSet evaluated;
1023 evalBind(evaluated, CNE, Pred, Result, V, true);
1024
1025 Bldr.takeNodes(Pred);
1026 Bldr.addNodes(evaluated);
1027
1028 Pred = *evaluated.begin();
1029 State = Pred->getState();
1030 }
1031 }
1032
1033 State = State->BindExpr(CNE, Pred->getLocationContext(), Result);
1034 Bldr.generateNode(CNE, Pred, State);
1035 return;
1036 }
1037
1038 // FIXME: Once we have proper support for CXXConstructExprs inside
1039 // CXXNewExpr, we need to make sure that the constructed object is not
1040 // immediately invalidated here. (The placement call should happen before
1041 // the constructor call anyway.)
1042 if (FD->isReservedGlobalPlacementOperator()) {
1043 // Non-array placement new should always return the placement location.
1044 SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx);
1045 Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(),
1046 CNE->getPlacementArg(0)->getType());
1047 }
1048
1049 // Bind the address of the object, then check to see if we cached out.
1050 State = State->BindExpr(CNE, LCtx, Result);
1051 ExplodedNode *NewN = Bldr.generateNode(CNE, Pred, State);
1052 if (!NewN)
1053 return;
1054
1055 // If the type is not a record, we won't have a CXXConstructExpr as an
1056 // initializer. Copy the value over.
1057 if (const Expr *Init = CNE->getInitializer()) {
1058 if (!isa<CXXConstructExpr>(Init)) {
1059 assert(Bldr.getResults().size() == 1);
1060 Bldr.takeNodes(NewN);
1061 evalBind(Dst, CNE, NewN, Result, State->getSVal(Init, LCtx),
1062 /*FirstInit=*/IsStandardGlobalOpNewFunction);
1063 }
1064 }
1065}
1066
1067void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
1068 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
1069
1070 CallEventManager &CEMgr = getStateManager().getCallEventManager();
1071 CallEventRef<CXXDeallocatorCall> Call = CEMgr.getCXXDeallocatorCall(
1072 CDE, Pred->getState(), Pred->getLocationContext());
1073
1074 ExplodedNodeSet DstPreCall;
1075 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, *Call, *this);
1076 ExplodedNodeSet DstPostCall;
1077
1078 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
1079 StmtNodeBuilder Bldr(DstPreCall, DstPostCall, *currBldrCtx);
1080 for (ExplodedNode *I : DstPreCall) {
1081 defaultEvalCall(Bldr, I, *Call);
1082 }
1083 } else {
1084 DstPostCall = DstPreCall;
1085 }
1086 getCheckerManager().runCheckersForPostCall(Dst, DstPostCall, *Call, *this);
1087}
1088
1089void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred,
1090 ExplodedNodeSet &Dst) {
1091 const VarDecl *VD = CS->getExceptionDecl();
1092 if (!VD) {
1093 Dst.Add(Pred);
1094 return;
1095 }
1096
1097 const LocationContext *LCtx = Pred->getLocationContext();
1098 SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(),
1099 currBldrCtx->blockCount());
1100 ProgramStateRef state = Pred->getState();
1101 state = state->bindLoc(state->getLValue(VD, LCtx), V, LCtx);
1102
1103 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
1104 Bldr.generateNode(CS, Pred, state);
1105}
1106
1107void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
1108 ExplodedNodeSet &Dst) {
1109 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
1110
1111 // Get the this object region from StoreManager.
1112 const LocationContext *LCtx = Pred->getLocationContext();
1113 const MemRegion *R =
1114 svalBuilder.getRegionManager().getCXXThisRegion(
1115 getContext().getCanonicalType(TE->getType()),
1116 LCtx);
1117
1118 ProgramStateRef state = Pred->getState();
1119 SVal V = state->getSVal(loc::MemRegionVal(R));
1120 Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V));
1121}
1122
1123void ExprEngine::VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred,
1124 ExplodedNodeSet &Dst) {
1125 const LocationContext *LocCtxt = Pred->getLocationContext();
1126
1127 // Get the region of the lambda itself.
1128 const MemRegion *R = svalBuilder.getRegionManager().getCXXTempObjectRegion(
1129 LE, LocCtxt);
1130 SVal V = loc::MemRegionVal(R);
1131
1132 ProgramStateRef State = Pred->getState();
1133
1134 // If we created a new MemRegion for the lambda, we should explicitly bind
1135 // the captures.
1136 unsigned Idx = 0;
1137 CXXRecordDecl::field_iterator CurField = LE->getLambdaClass()->field_begin();
1138 for (LambdaExpr::const_capture_init_iterator i = LE->capture_init_begin(),
1139 e = LE->capture_init_end();
1140 i != e; ++i, ++CurField, ++Idx) {
1141 FieldDecl *FieldForCapture = *CurField;
1142 SVal FieldLoc = State->getLValue(FieldForCapture, V);
1143
1144 SVal InitVal;
1145 if (!FieldForCapture->hasCapturedVLAType()) {
1146 const Expr *InitExpr = *i;
1147
1148 assert(InitExpr && "Capture missing initialization expression");
1149
1150 if (const auto AILE = dyn_cast<ArrayInitLoopExpr>(InitExpr)) {
1151 // If the AILE initializes a POD array, we need to keep it as the
1152 // InitExpr.
1153 if (dyn_cast<CXXConstructExpr>(AILE->getSubExpr()))
1154 InitExpr = AILE->getSubExpr();
1155 }
1156
1157 // With C++17 copy elision this can happen.
1158 if (const auto *FC = dyn_cast<CXXFunctionalCastExpr>(InitExpr))
1159 InitExpr = FC->getSubExpr();
1160
1161 assert(InitExpr &&
1162 "Extracted capture initialization expression is missing");
1163
1164 if (dyn_cast<CXXConstructExpr>(InitExpr)) {
1165 InitVal = *getObjectUnderConstruction(State, {LE, Idx}, LocCtxt);
1166 InitVal = State->getSVal(InitVal.getAsRegion());
1167
1168 State = finishObjectConstruction(State, {LE, Idx}, LocCtxt);
1169 } else
1170 InitVal = State->getSVal(InitExpr, LocCtxt);
1171
1172 } else {
1173
1174 assert(!getObjectUnderConstruction(State, {LE, Idx}, LocCtxt) &&
1175 "VLA capture by value is a compile time error!");
1176
1177 // The field stores the length of a captured variable-length array.
1178 // These captures don't have initialization expressions; instead we
1179 // get the length from the VLAType size expression.
1180 Expr *SizeExpr = FieldForCapture->getCapturedVLAType()->getSizeExpr();
1181 InitVal = State->getSVal(SizeExpr, LocCtxt);
1182 }
1183
1184 State = State->bindLoc(FieldLoc, InitVal, LocCtxt);
1185 }
1186
1187 // Decay the Loc into an RValue, because there might be a
1188 // MaterializeTemporaryExpr node above this one which expects the bound value
1189 // to be an RValue.
1190 SVal LambdaRVal = State->getSVal(R);
1191
1192 ExplodedNodeSet Tmp;
1193 StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
1194 // FIXME: is this the right program point kind?
1195 Bldr.generateNode(LE, Pred,
1196 State->BindExpr(LE, LocCtxt, LambdaRVal),
1197 nullptr, ProgramPoint::PostLValueKind);
1198
1199 // FIXME: Move all post/pre visits to ::Visit().
1200 getCheckerManager().runCheckersForPostStmt(Dst, Tmp, LE, *this);
1201}
1202

source code of clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp