clang 23.0.0git
ExprEngineCXX.cpp
Go to the documentation of this file.
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
15#include "clang/AST/DeclCXX.h"
16#include "clang/AST/ParentMap.h"
17#include "clang/AST/StmtCXX.h"
25#include "llvm/ADT/STLExtras.h"
26#include "llvm/ADT/Sequence.h"
27#include "llvm/Support/Casting.h"
28#include <optional>
29
30using namespace clang;
31using namespace ento;
32
34 ExplodedNode *Pred,
35 ExplodedNodeSet &Dst) {
36 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
37 const Expr *tempExpr = ME->getSubExpr()->IgnoreParens();
38 ProgramStateRef state = Pred->getState();
39 const LocationContext *LCtx = Pred->getLocationContext();
40
41 state = createTemporaryRegionIfNeeded(state, LCtx, tempExpr, ME);
42 Bldr.generateNode(ME, Pred, state);
43}
44
45// FIXME: This is the sort of code that should eventually live in a Core
46// checker rather than as a special case in ExprEngine.
47void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
48 const CallEvent &Call) {
49 SVal ThisVal;
50 bool AlwaysReturnsLValue;
51 [[maybe_unused]] const CXXRecordDecl *ThisRD = nullptr;
52 if (const CXXConstructorCall *Ctor = dyn_cast<CXXConstructorCall>(&Call)) {
53 assert(Ctor->getDecl()->isTrivial());
54 assert(Ctor->getDecl()->isCopyOrMoveConstructor());
55 ThisVal = Ctor->getCXXThisVal();
56 ThisRD = Ctor->getDecl()->getParent();
57 AlwaysReturnsLValue = false;
58 } else {
59 assert(cast<CXXMethodDecl>(Call.getDecl())->isTrivial());
60 assert(cast<CXXMethodDecl>(Call.getDecl())->getOverloadedOperator() ==
61 OO_Equal);
62 ThisVal = cast<CXXInstanceCall>(Call).getCXXThisVal();
63 ThisRD = cast<CXXMethodDecl>(Call.getDecl())->getParent();
64 AlwaysReturnsLValue = true;
65 }
66
67 const LocationContext *LCtx = Pred->getLocationContext();
68 const Expr *CallExpr = Call.getOriginExpr();
69
71 Bldr.takeNodes(Pred);
72
73 assert(ThisRD);
74
75 if (!ThisRD->isEmpty()) {
76 SVal V = Call.getArgSVal(0);
77 const Expr *VExpr = Call.getArgExpr(0);
78
79 // If the value being copied is not unknown, load from its location to get
80 // an aggregate rvalue.
81 if (std::optional<Loc> L = V.getAs<Loc>())
82 V = Pred->getState()->getSVal(*L);
83 else
84 assert(V.isUnknownOrUndef());
85
87 evalLocation(Tmp, CallExpr, VExpr, Pred, Pred->getState(), V,
88 /*isLoad=*/true);
89 for (ExplodedNode *N : Tmp)
90 evalBind(Dst, CallExpr, N, ThisVal, V, !AlwaysReturnsLValue);
91 } else {
92 // We can't copy empty classes because of empty base class optimization.
93 // In that case, copying the empty base class subobject would overwrite the
94 // object that it overlaps with - so let's not do that.
95 // See issue-157467.cpp for an example.
96 Dst.Add(Pred);
97 }
98
99 PostStmt PS(CallExpr, LCtx);
100 for (ExplodedNode *N : Dst) {
101 ProgramStateRef State = N->getState();
102 if (AlwaysReturnsLValue)
103 State = State->BindExpr(CallExpr, LCtx, ThisVal);
104 else
105 State = bindReturnValue(Call, LCtx, State);
106 Bldr.generateNode(PS, State, N);
107 }
108}
109
110SVal ExprEngine::makeElementRegion(ProgramStateRef State, SVal LValue,
111 QualType &Ty, bool &IsArray, unsigned Idx) {
112 SValBuilder &SVB = State->getStateManager().getSValBuilder();
113 ASTContext &Ctx = SVB.getContext();
114
115 if (const ArrayType *AT = Ctx.getAsArrayType(Ty)) {
116 while (AT) {
117 Ty = AT->getElementType();
118 AT = dyn_cast<ArrayType>(AT->getElementType());
119 }
120 LValue = State->getLValue(Ty, SVB.makeArrayIndex(Idx), LValue);
121 IsArray = true;
122 }
123
124 return LValue;
125}
126
127// In case when the prvalue is returned from the function (kind is one of
128// SimpleReturnedValueKind, CXX17ElidedCopyReturnedValueKind), then
129// it's materialization happens in context of the caller.
130// We pass BldrCtx explicitly, as currBldrCtx always refers to callee's context.
132 const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx,
133 const LocationContext *LCtx, const ConstructionContext *CC,
134 EvalCallOptions &CallOpts, unsigned Idx) {
135
137 MemRegionManager &MRMgr = SVB.getRegionManager();
138 ASTContext &ACtx = SVB.getContext();
139
140 // Compute the target region by exploring the construction context.
141 if (CC) {
142 switch (CC->getKind()) {
145 const auto *DSCC = cast<VariableConstructionContext>(CC);
146 const auto *DS = DSCC->getDeclStmt();
147 const auto *Var = cast<VarDecl>(DS->getSingleDecl());
148 QualType Ty = Var->getType();
149 return makeElementRegion(State, State->getLValue(Var, LCtx), Ty,
150 CallOpts.IsArrayCtorOrDtor, Idx);
151 }
155 const auto *Init = ICC->getCXXCtorInitializer();
156 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
157 Loc ThisPtr = SVB.getCXXThis(CurCtor, LCtx->getStackFrame());
158 SVal ThisVal = State->getSVal(ThisPtr);
159 if (Init->isBaseInitializer()) {
160 const auto *ThisReg = cast<SubRegion>(ThisVal.getAsRegion());
161 const CXXRecordDecl *BaseClass =
162 Init->getBaseClass()->getAsCXXRecordDecl();
163 const auto *BaseReg =
164 MRMgr.getCXXBaseObjectRegion(BaseClass, ThisReg,
165 Init->isBaseVirtual());
166 return SVB.makeLoc(BaseReg);
167 }
168 if (Init->isDelegatingInitializer())
169 return ThisVal;
170
171 const ValueDecl *Field;
172 SVal FieldVal;
173 if (Init->isIndirectMemberInitializer()) {
174 Field = Init->getIndirectMember();
175 FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal);
176 } else {
177 Field = Init->getMember();
178 FieldVal = State->getLValue(Init->getMember(), ThisVal);
179 }
180
181 QualType Ty = Field->getType();
182 return makeElementRegion(State, FieldVal, Ty, CallOpts.IsArrayCtorOrDtor,
183 Idx);
184 }
186 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
187 const auto *NECC = cast<NewAllocatedObjectConstructionContext>(CC);
188 const auto *NE = NECC->getCXXNewExpr();
189 SVal V = *getObjectUnderConstruction(State, NE, LCtx);
190 if (const SubRegion *MR =
191 dyn_cast_or_null<SubRegion>(V.getAsRegion())) {
192 if (NE->isArray()) {
193 CallOpts.IsArrayCtorOrDtor = true;
194
195 auto Ty = NE->getType()->getPointeeType();
196 while (const auto *AT = getContext().getAsArrayType(Ty))
197 Ty = AT->getElementType();
198
199 auto R = MRMgr.getElementRegion(Ty, svalBuilder.makeArrayIndex(Idx),
200 MR, SVB.getContext());
201
202 return loc::MemRegionVal(R);
203 }
204 return V;
205 }
206 // TODO: Detect when the allocator returns a null pointer.
207 // Constructor shall not be called in this case.
208 }
209 break;
210 }
213 // The temporary is to be managed by the parent stack frame.
214 // So build it in the parent stack frame if we're not in the
215 // top frame of the analysis.
216 const StackFrameContext *SFC = LCtx->getStackFrame();
217 if (const LocationContext *CallerLCtx = SFC->getParent()) {
218 auto RTC = (*SFC->getCallSiteBlock())[SFC->getIndex()]
219 .getAs<CFGCXXRecordTypedCall>();
220 if (!RTC) {
221 // We were unable to find the correct construction context for the
222 // call in the parent stack frame. This is equivalent to not being
223 // able to find construction context at all.
224 break;
225 }
226 if (isa<BlockInvocationContext>(CallerLCtx)) {
227 // Unwrap block invocation contexts. They're mostly part of
228 // the current stack frame.
229 CallerLCtx = CallerLCtx->getParent();
230 assert(!isa<BlockInvocationContext>(CallerLCtx));
231 }
232
233 NodeBuilderContext CallerBldrCtx(getCoreEngine(),
234 SFC->getCallSiteBlock(), CallerLCtx);
236 cast<Expr>(SFC->getCallSite()), State, &CallerBldrCtx, CallerLCtx,
237 RTC->getConstructionContext(), CallOpts);
238 } else {
239 // We are on the top frame of the analysis. We do not know where is the
240 // object returned to. Conjure a symbolic region for the return value.
241 // TODO: We probably need a new MemRegion kind to represent the storage
242 // of that SymbolicRegion, so that we could produce a fancy symbol
243 // instead of an anonymous conjured symbol.
244 // TODO: Do we need to track the region to avoid having it dead
245 // too early? It does die too early, at least in C++17, but because
246 // putting anything into a SymbolicRegion causes an immediate escape,
247 // it doesn't cause any leak false positives.
248 const auto *RCC = cast<ReturnedValueConstructionContext>(CC);
249 // Make sure that this doesn't coincide with any other symbol
250 // conjured for the returned expression.
251 static const int TopLevelSymRegionTag = 0;
252 const Expr *RetE = RCC->getReturnStmt()->getRetValue();
253 assert(RetE && "Void returns should not have a construction context");
254 QualType ReturnTy = RetE->getType();
255 QualType RegionTy = ACtx.getPointerType(ReturnTy);
256 return SVB.conjureSymbolVal(&TopLevelSymRegionTag, getCFGElementRef(),
257 SFC, RegionTy, currBldrCtx->blockCount());
258 }
259 llvm_unreachable("Unhandled return value construction context!");
260 }
262 assert(AMgr.getAnalyzerOptions().ShouldElideConstructors);
264
265 // Support pre-C++17 copy elision. We'll have the elidable copy
266 // constructor in the AST and in the CFG, but we'll skip it
267 // and construct directly into the final object. This call
268 // also sets the CallOpts flags for us.
269 // If the elided copy/move constructor is not supported, there's still
270 // benefit in trying to model the non-elided constructor.
271 // Stash our state before trying to elide, as it'll get overwritten.
272 ProgramStateRef PreElideState = State;
273 EvalCallOptions PreElideCallOpts = CallOpts;
274
276 TCC->getConstructorAfterElision(), State, BldrCtx, LCtx,
277 TCC->getConstructionContextAfterElision(), CallOpts);
278
279 // FIXME: This definition of "copy elision has not failed" is unreliable.
280 // It doesn't indicate that the constructor will actually be inlined
281 // later; this is still up to evalCall() to decide.
283 return V;
284
285 // Copy elision failed. Revert the changes and proceed as if we have
286 // a simple temporary.
287 CallOpts = PreElideCallOpts;
289 [[fallthrough]];
290 }
292 const auto *TCC = cast<TemporaryObjectConstructionContext>(CC);
293 const MaterializeTemporaryExpr *MTE = TCC->getMaterializedTemporaryExpr();
294
295 CallOpts.IsTemporaryCtorOrDtor = true;
296 if (MTE) {
297 if (const ValueDecl *VD = MTE->getExtendingDecl()) {
299 assert(SD != SD_FullExpression);
300 if (!VD->getType()->isReferenceType()) {
301 // We're lifetime-extended by a surrounding aggregate.
302 // Automatic destructors aren't quite working in this case
303 // on the CFG side. We should warn the caller about that.
304 // FIXME: Is there a better way to retrieve this information from
305 // the MaterializeTemporaryExpr?
307 }
308
309 if (SD == SD_Static || SD == SD_Thread)
310 return loc::MemRegionVal(
311 MRMgr.getCXXStaticLifetimeExtendedObjectRegion(E, VD));
312
313 return loc::MemRegionVal(
314 MRMgr.getCXXLifetimeExtendedObjectRegion(E, VD, LCtx));
315 }
316 assert(MTE->getStorageDuration() == SD_FullExpression);
317 }
318
319 return loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
320 }
322 CallOpts.IsTemporaryCtorOrDtor = true;
323
324 const auto *LCC = cast<LambdaCaptureConstructionContext>(CC);
325
327 MRMgr.getCXXTempObjectRegion(LCC->getInitializer(), LCtx));
328
329 const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E);
330 if (getIndexOfElementToConstruct(State, CE, LCtx)) {
331 CallOpts.IsArrayCtorOrDtor = true;
332 Base = State->getLValue(E->getType(), svalBuilder.makeArrayIndex(Idx),
333 Base);
334 }
335
336 return Base;
337 }
339 // Arguments are technically temporaries.
340 CallOpts.IsTemporaryCtorOrDtor = true;
341
342 const auto *ACC = cast<ArgumentConstructionContext>(CC);
343 const Expr *E = ACC->getCallLikeExpr();
344 unsigned Idx = ACC->getIndex();
345
347 auto getArgLoc = [&](CallEventRef<> Caller) -> std::optional<SVal> {
348 const LocationContext *FutureSFC =
349 Caller->getCalleeStackFrame(BldrCtx->blockCount());
350 // Return early if we are unable to reliably foresee
351 // the future stack frame.
352 if (!FutureSFC)
353 return std::nullopt;
354
355 // This should be equivalent to Caller->getDecl() for now, but
356 // FutureSFC->getDecl() is likely to support better stuff (like
357 // virtual functions) earlier.
358 const Decl *CalleeD = FutureSFC->getDecl();
359
360 // FIXME: Support for variadic arguments is not implemented here yet.
361 if (CallEvent::isVariadic(CalleeD))
362 return std::nullopt;
363
364 // Operator arguments do not correspond to operator parameters
365 // because this-argument is implemented as a normal argument in
366 // operator call expressions but not in operator declarations.
367 const TypedValueRegion *TVR = Caller->getParameterLocation(
368 *Caller->getAdjustedParameterIndex(Idx), BldrCtx->blockCount());
369 if (!TVR)
370 return std::nullopt;
371
372 return loc::MemRegionVal(TVR);
373 };
374
375 if (const auto *CE = dyn_cast<CallExpr>(E)) {
376 CallEventRef<> Caller =
377 CEMgr.getSimpleCall(CE, State, LCtx, getCFGElementRef());
378 if (std::optional<SVal> V = getArgLoc(Caller))
379 return *V;
380 else
381 break;
382 } else if (const auto *CCE = dyn_cast<CXXConstructExpr>(E)) {
383 // Don't bother figuring out the target region for the future
384 // constructor because we won't need it.
386 CCE, /*Target=*/nullptr, State, LCtx, getCFGElementRef());
387 if (std::optional<SVal> V = getArgLoc(Caller))
388 return *V;
389 else
390 break;
391 } else if (const auto *ME = dyn_cast<ObjCMessageExpr>(E)) {
392 CallEventRef<> Caller =
393 CEMgr.getObjCMethodCall(ME, State, LCtx, getCFGElementRef());
394 if (std::optional<SVal> V = getArgLoc(Caller))
395 return *V;
396 else
397 break;
398 }
399 }
400 } // switch (CC->getKind())
401 }
402
403 // If we couldn't find an existing region to construct into, assume we're
404 // constructing a temporary. Notify the caller of our failure.
406 return loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
407}
408
410 SVal V, const Expr *E, ProgramStateRef State, const LocationContext *LCtx,
411 const ConstructionContext *CC, const EvalCallOptions &CallOpts) {
413 // Sounds like we failed to find the target region and therefore
414 // copy elision failed. There's nothing we can do about it here.
415 return State;
416 }
417
418 // See if we're constructing an existing region by looking at the
419 // current construction context.
420 assert(CC && "Computed target region without construction context?");
421 switch (CC->getKind()) {
424 const auto *DSCC = cast<VariableConstructionContext>(CC);
425 return addObjectUnderConstruction(State, DSCC->getDeclStmt(), LCtx, V);
426 }
430 const auto *Init = ICC->getCXXCtorInitializer();
431 // Base and delegating initializers handled above
432 assert(Init->isAnyMemberInitializer() &&
433 "Base and delegating initializers should have been handled by"
434 "computeObjectUnderConstruction()");
435 return addObjectUnderConstruction(State, Init, LCtx, V);
436 }
438 return State;
439 }
442 const StackFrameContext *SFC = LCtx->getStackFrame();
443 const LocationContext *CallerLCtx = SFC->getParent();
444 if (!CallerLCtx) {
445 // No extra work is necessary in top frame.
446 return State;
447 }
448
449 auto RTC = (*SFC->getCallSiteBlock())[SFC->getIndex()]
450 .getAs<CFGCXXRecordTypedCall>();
451 assert(RTC && "Could not have had a target region without it");
452 if (isa<BlockInvocationContext>(CallerLCtx)) {
453 // Unwrap block invocation contexts. They're mostly part of
454 // the current stack frame.
455 CallerLCtx = CallerLCtx->getParent();
456 assert(!isa<BlockInvocationContext>(CallerLCtx));
457 }
458
460 cast<Expr>(SFC->getCallSite()), State, CallerLCtx,
461 RTC->getConstructionContext(), CallOpts);
462 }
464 assert(AMgr.getAnalyzerOptions().ShouldElideConstructors);
468 V, TCC->getConstructorAfterElision(), State, LCtx,
469 TCC->getConstructionContextAfterElision(), CallOpts);
470
471 // Remember that we've elided the constructor.
472 State = addObjectUnderConstruction(
473 State, TCC->getConstructorAfterElision(), LCtx, V);
474
475 // Remember that we've elided the destructor.
476 if (const auto *BTE = TCC->getCXXBindTemporaryExpr())
477 State = elideDestructor(State, BTE, LCtx);
478
479 // Instead of materialization, shamelessly return
480 // the final object destination.
481 if (const auto *MTE = TCC->getMaterializedTemporaryExpr())
482 State = addObjectUnderConstruction(State, MTE, LCtx, V);
483
484 return State;
485 }
486 // If we decided not to elide the constructor, proceed as if
487 // it's a simple temporary.
488 [[fallthrough]];
489 }
491 const auto *TCC = cast<TemporaryObjectConstructionContext>(CC);
492 if (const auto *BTE = TCC->getCXXBindTemporaryExpr())
493 State = addObjectUnderConstruction(State, BTE, LCtx, V);
494
495 if (const auto *MTE = TCC->getMaterializedTemporaryExpr())
496 State = addObjectUnderConstruction(State, MTE, LCtx, V);
497
498 return State;
499 }
501 const auto *LCC = cast<LambdaCaptureConstructionContext>(CC);
502
503 // If we capture and array, we want to store the super region, not a
504 // sub-region.
505 if (const auto *EL = dyn_cast_or_null<ElementRegion>(V.getAsRegion()))
506 V = loc::MemRegionVal(EL->getSuperRegion());
507
508 return addObjectUnderConstruction(
509 State, {LCC->getLambdaExpr(), LCC->getIndex()}, LCtx, V);
510 }
512 const auto *ACC = cast<ArgumentConstructionContext>(CC);
513 if (const auto *BTE = ACC->getCXXBindTemporaryExpr())
514 State = addObjectUnderConstruction(State, BTE, LCtx, V);
515
516 return addObjectUnderConstruction(
517 State, {ACC->getCallLikeExpr(), ACC->getIndex()}, LCtx, V);
518 }
519 }
520 llvm_unreachable("Unhandled construction context!");
521}
522
523static ProgramStateRef
525 const ArrayInitLoopExpr *AILE,
526 const LocationContext *LCtx, NonLoc Idx) {
528 MemRegionManager &MRMgr = SVB.getRegionManager();
529 ASTContext &Ctx = SVB.getContext();
530
531 // HACK: There is no way we can put the index of the array element into the
532 // CFG unless we unroll the loop, so we manually select and bind the required
533 // parameter to the environment.
534 const Expr *SourceArray = AILE->getCommonExpr()->getSourceExpr();
535 const auto *Ctor =
537
538 const auto *SourceArrayRegion =
539 cast<SubRegion>(State->getSVal(SourceArray, LCtx).getAsRegion());
541 MRMgr.getElementRegion(Ctor->getType(), Idx, SourceArrayRegion, Ctx);
542
543 return State->BindExpr(Ctor->getArg(0), LCtx,
545}
546
547void ExprEngine::handleConstructor(const Expr *E,
548 ExplodedNode *Pred,
549 ExplodedNodeSet &destNodes) {
550 const auto *CE = dyn_cast<CXXConstructExpr>(E);
551 const auto *CIE = dyn_cast<CXXInheritedCtorInitExpr>(E);
552 assert(CE || CIE);
553
554 const LocationContext *LCtx = Pred->getLocationContext();
555 ProgramStateRef State = Pred->getState();
556
557 SVal Target = UnknownVal();
558
559 if (CE) {
560 if (std::optional<SVal> ElidedTarget =
561 getObjectUnderConstruction(State, CE, LCtx)) {
562 // We've previously modeled an elidable constructor by pretending that
563 // it in fact constructs into the correct target. This constructor can
564 // therefore be skipped.
565 Target = *ElidedTarget;
566 NodeBuilder Bldr(Pred, destNodes, *currBldrCtx);
567 State = finishObjectConstruction(State, CE, LCtx);
568 if (auto L = Target.getAs<Loc>())
569 State = State->BindExpr(CE, LCtx, State->getSVal(*L, CE->getType()));
570 Bldr.generateNode(CE, Pred, State);
571 return;
572 }
573 }
574
575 EvalCallOptions CallOpts;
576 auto C = getCurrentCFGElement().getAs<CFGConstructor>();
577 assert(C || getCurrentCFGElement().getAs<CFGStmt>());
578 const ConstructionContext *CC = C ? C->getConstructionContext() : nullptr;
579
580 const CXXConstructionKind CK =
581 CE ? CE->getConstructionKind() : CIE->getConstructionKind();
582 switch (CK) {
584 // Inherited constructors are always base class constructors.
585 assert(CE && !CIE && "A complete constructor is inherited?!");
586
587 // If the ctor is part of an ArrayInitLoopExpr, we want to handle it
588 // differently.
589 auto *AILE = CC ? CC->getArrayInitLoop() : nullptr;
590
591 unsigned Idx = 0;
592 if (CE->getType()->isArrayType() || AILE) {
593
594 auto isZeroSizeArray = [&] {
595 uint64_t Size = 1;
596
597 if (const auto *CAT = dyn_cast<ConstantArrayType>(CE->getType()))
599 else if (AILE)
601
602 return Size == 0;
603 };
604
605 // No element construction will happen in a 0 size array.
606 if (isZeroSizeArray()) {
607 NodeBuilder Bldr(Pred, destNodes, *currBldrCtx);
608 static SimpleProgramPointTag T{"ExprEngine",
609 "Skipping 0 size array construction"};
610 Bldr.generateNode(CE, Pred, State, &T);
611 return;
612 }
613
614 Idx = getIndexOfElementToConstruct(State, CE, LCtx).value_or(0u);
615 State = setIndexOfElementToConstruct(State, CE, LCtx, Idx + 1);
616 }
617
618 if (AILE) {
619 // Only set this once even though we loop through it multiple times.
620 if (!getPendingInitLoop(State, CE, LCtx))
621 State = setPendingInitLoop(
622 State, CE, LCtx,
623 getContext().getArrayInitLoopExprElementCount(AILE));
624
626 State, AILE, LCtx, svalBuilder.makeArrayIndex(Idx));
627 }
628
629 // The target region is found from construction context.
630 std::tie(State, Target) = handleConstructionContext(
631 CE, State, currBldrCtx, LCtx, CC, CallOpts, Idx);
632 break;
633 }
635 // Make sure we are not calling virtual base class initializers twice.
636 // Only the most-derived object should initialize virtual base classes.
637 const auto *OuterCtor = dyn_cast_or_null<CXXConstructExpr>(
638 LCtx->getStackFrame()->getCallSite());
639 assert(
640 (!OuterCtor ||
641 OuterCtor->getConstructionKind() == CXXConstructionKind::Complete ||
642 OuterCtor->getConstructionKind() == CXXConstructionKind::Delegating) &&
643 ("This virtual base should have already been initialized by "
644 "the most derived class!"));
645 (void)OuterCtor;
646 [[fallthrough]];
647 }
649 // In C++17, classes with non-virtual bases may be aggregates, so they would
650 // be initialized as aggregates without a constructor call, so we may have
651 // a base class constructed directly into an initializer list without
652 // having the derived-class constructor call on the previous stack frame.
653 // Initializer lists may be nested into more initializer lists that
654 // correspond to surrounding aggregate initializations.
655 // FIXME: For now this code essentially bails out. We need to find the
656 // correct target region and set it.
657 // FIXME: Instead of relying on the ParentMap, we should have the
658 // trigger-statement (InitListExpr or CXXParenListInitExpr in this case)
659 // passed down from CFG or otherwise always available during construction.
660 if (isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(
661 LCtx->getParentMap().getParent(E))) {
662 MemRegionManager &MRMgr = getSValBuilder().getRegionManager();
663 Target = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
665 break;
666 }
667 [[fallthrough]];
669 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
670 Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor,
671 LCtx->getStackFrame());
672 SVal ThisVal = State->getSVal(ThisPtr);
673
675 Target = ThisVal;
676 } else {
677 // Cast to the base type.
678 bool IsVirtual = (CK == CXXConstructionKind::VirtualBase);
679 SVal BaseVal =
680 getStoreManager().evalDerivedToBase(ThisVal, E->getType(), IsVirtual);
681 Target = BaseVal;
682 }
683 break;
684 }
685 }
686
687 if (State != Pred->getState()) {
688 static SimpleProgramPointTag T("ExprEngine",
689 "Prepare for object construction");
690 ExplodedNodeSet DstPrepare;
691 NodeBuilder BldrPrepare(Pred, DstPrepare, *currBldrCtx);
692 Pred =
693 BldrPrepare.generateNode(E, Pred, State, &T, ProgramPoint::PreStmtKind);
694 if (!Pred)
695 return;
696 }
697
698 const MemRegion *TargetRegion = Target.getAsRegion();
699 CallEventManager &CEMgr = getStateManager().getCallEventManager();
700 CallEventRef<> Call =
701 CIE ? (CallEventRef<>)CEMgr.getCXXInheritedConstructorCall(
702 CIE, TargetRegion, State, LCtx, getCFGElementRef())
703 : (CallEventRef<>)CEMgr.getCXXConstructorCall(
704 CE, TargetRegion, State, LCtx, getCFGElementRef());
705
706 ExplodedNodeSet DstPreVisit;
707 getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, E, *this);
708
709 ExplodedNodeSet PreInitialized;
710 if (CE) {
711 // FIXME: Is it possible and/or useful to do this before PreStmt?
712 NodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx);
713 for (ExplodedNode *N : DstPreVisit) {
714 ProgramStateRef State = N->getState();
715 if (CE->requiresZeroInitialization()) {
716 // FIXME: Once we properly handle constructors in new-expressions, we'll
717 // need to invalidate the region before setting a default value, to make
718 // sure there aren't any lingering bindings around. This probably needs
719 // to happen regardless of whether or not the object is zero-initialized
720 // to handle random fields of a placement-initialized object picking up
721 // old bindings. We might only want to do it when we need to, though.
722 // FIXME: This isn't actually correct for arrays -- we need to zero-
723 // initialize the entire array, not just the first element -- but our
724 // handling of arrays everywhere else is weak as well, so this shouldn't
725 // actually make things worse. Placement new makes this tricky as well,
726 // since it's then possible to be initializing one part of a multi-
727 // dimensional array.
728 const CXXRecordDecl *TargetHeldRecord =
729 dyn_cast_or_null<CXXRecordDecl>(CE->getType()->getAsRecordDecl());
730
731 if (!TargetHeldRecord || !TargetHeldRecord->isEmpty())
732 State = State->bindDefaultZero(Target, LCtx);
733 }
734
735 Bldr.generateNode(CE, N, State, /*tag=*/nullptr,
737 }
738 } else {
739 PreInitialized = DstPreVisit;
740 }
741
742 ExplodedNodeSet DstPreCall;
743 getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized,
744 *Call, *this);
745
746 ExplodedNodeSet DstEvaluated;
747
748 if (CE && CE->getConstructor()->isTrivial() &&
749 CE->getConstructor()->isCopyOrMoveConstructor() &&
750 !CallOpts.IsArrayCtorOrDtor) {
751 NodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);
752 // FIXME: Handle other kinds of trivial constructors as well.
753 for (ExplodedNode *N : DstPreCall)
754 performTrivialCopy(Bldr, N, *Call);
755
756 } else {
757 for (ExplodedNode *N : DstPreCall)
758 getCheckerManager().runCheckersForEvalCall(DstEvaluated, N, *Call, *this,
759 CallOpts);
760 }
761
762 // If the CFG was constructed without elements for temporary destructors
763 // and the just-called constructor created a temporary object then
764 // stop exploration if the temporary object has a noreturn constructor.
765 // This can lose coverage because the destructor, if it were present
766 // in the CFG, would be called at the end of the full expression or
767 // later (for life-time extended temporaries) -- but avoids infeasible
768 // paths when no-return temporary destructors are used for assertions.
769 ExplodedNodeSet DstEvaluatedPostProcessed;
770 NodeBuilder Bldr(DstEvaluated, DstEvaluatedPostProcessed, *currBldrCtx);
771 const AnalysisDeclContext *ADC = LCtx->getAnalysisDeclContext();
773 if (llvm::isa_and_nonnull<CXXTempObjectRegion,
774 CXXLifetimeExtendedObjectRegion>(TargetRegion) &&
776 ->getParent()
777 ->isAnyDestructorNoReturn()) {
778
779 // If we've inlined the constructor, then DstEvaluated would be empty.
780 // In this case we still want a sink, which could be implemented
781 // in processCallExit. But we don't have that implemented at the moment,
782 // so if you hit this assertion, see if you can avoid inlining
783 // the respective constructor when analyzer-config cfg-temporary-dtors
784 // is set to false.
785 // Otherwise there's nothing wrong with inlining such constructor.
786 assert(!DstEvaluated.empty() &&
787 "We should not have inlined this constructor!");
788
789 for (ExplodedNode *N : DstEvaluated) {
790 Bldr.generateSink(E, N, N->getState());
791 }
792
793 // There is no need to run the PostCall and PostStmt checker
794 // callbacks because we just generated sinks on all nodes in th
795 // frontier.
796 return;
797 }
798 }
799
800 ExplodedNodeSet DstPostArgumentCleanup;
801 for (ExplodedNode *I : DstEvaluatedPostProcessed)
802 finishArgumentConstruction(DstPostArgumentCleanup, I, *Call);
803
804 // If there were other constructors called for object-type arguments
805 // of this constructor, clean them up.
806 ExplodedNodeSet DstPostCall;
808 DstPostArgumentCleanup,
809 *Call, *this);
810 getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, E, *this);
811}
812
814 ExplodedNode *Pred,
815 ExplodedNodeSet &Dst) {
816 handleConstructor(CE, Pred, Dst);
817}
818
820 const CXXInheritedCtorInitExpr *CE, ExplodedNode *Pred,
821 ExplodedNodeSet &Dst) {
822 handleConstructor(CE, Pred, Dst);
823}
824
826 const MemRegion *Dest,
827 const Stmt *S,
828 bool IsBaseDtor,
829 ExplodedNode *Pred,
830 ExplodedNodeSet &Dst,
831 EvalCallOptions &CallOpts) {
832 assert(S && "A destructor without a trigger!");
833 const LocationContext *LCtx = Pred->getLocationContext();
834 ProgramStateRef State = Pred->getState();
835
836 const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl();
837 assert(RecordDecl && "Only CXXRecordDecls should have destructors");
838 const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor();
839 // FIXME: There should always be a Decl, otherwise the destructor call
840 // shouldn't have been added to the CFG in the first place.
841 if (!DtorDecl) {
842 // Skip the invalid destructor. We cannot simply return because
843 // it would interrupt the analysis instead.
844 static SimpleProgramPointTag T("ExprEngine", "SkipInvalidDestructor");
845 // FIXME: PostImplicitCall with a null decl may crash elsewhere anyway.
846 PostImplicitCall PP(/*Decl=*/nullptr, S->getEndLoc(), LCtx,
847 getCFGElementRef(), &T);
848 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
849 Bldr.generateNode(PP, Pred->getState(), Pred);
850 return;
851 }
852
853 if (!Dest) {
854 // We're trying to destroy something that is not a region. This may happen
855 // for a variety of reasons (unknown target region, concrete integer instead
856 // of target region, etc.). The current code makes an attempt to recover.
857 // FIXME: We probably don't really need to recover when we're dealing
858 // with concrete integers specifically.
860 if (const Expr *E = dyn_cast_or_null<Expr>(S)) {
861 Dest = MRMgr.getCXXTempObjectRegion(E, Pred->getLocationContext());
862 } else {
863 static SimpleProgramPointTag T("ExprEngine", "SkipInvalidDestructor");
864 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
865 Bldr.generateSink(Pred->getLocation().withTag(&T),
866 Pred->getState(), Pred);
867 return;
868 }
869 }
870
873 DtorDecl, S, Dest, IsBaseDtor, State, LCtx, getCFGElementRef());
874
875 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
876 Call->getSourceRange().getBegin(),
877 "Error evaluating destructor");
878
879 ExplodedNodeSet DstPreCall;
880 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
881 *Call, *this);
882
883 ExplodedNodeSet DstInvalidated;
884 NodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
885 for (ExplodedNode *N : DstPreCall)
886 defaultEvalCall(Bldr, N, *Call, CallOpts);
887
888 getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
889 *Call, *this);
890}
891
893 ExplodedNode *Pred,
894 ExplodedNodeSet &Dst) {
895 ProgramStateRef State = Pred->getState();
896 const LocationContext *LCtx = Pred->getLocationContext();
897 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
898 CNE->getBeginLoc(),
899 "Error evaluating New Allocator Call");
902 CEMgr.getCXXAllocatorCall(CNE, State, LCtx, getCFGElementRef());
903
904 ExplodedNodeSet DstPreCall;
905 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
906 *Call, *this);
907
908 ExplodedNodeSet DstPostCall;
909 NodeBuilder CallBldr(DstPreCall, DstPostCall, *currBldrCtx);
910 for (ExplodedNode *I : DstPreCall) {
911 // Operator new calls (CXXNewExpr) are intentionally not eval-called,
912 // because it does not make sense to eval-call user-provided functions.
913 // 1) If the new operator can be inlined, then don't prevent it from
914 // inlining by having an eval-call of that operator.
915 // 2) If it can't be inlined, then the default conservative modeling
916 // is what we want anyway.
917 // So the best is to not allow eval-calling CXXNewExprs from checkers.
918 // Checkers can provide their pre/post-call callbacks if needed.
919 defaultEvalCall(CallBldr, I, *Call);
920 }
921 // If the call is inlined, DstPostCall will be empty and we bail out now.
922
923 // Store return value of operator new() for future use, until the actual
924 // CXXNewExpr gets processed.
925 ExplodedNodeSet DstPostValue;
926 NodeBuilder ValueBldr(DstPostCall, DstPostValue, *currBldrCtx);
927 for (ExplodedNode *I : DstPostCall) {
928 // FIXME: Because CNE serves as the "call site" for the allocator (due to
929 // lack of a better expression in the AST), the conjured return value symbol
930 // is going to be of the same type (C++ object pointer type). Technically
931 // this is not correct because the operator new's prototype always says that
932 // it returns a 'void *'. So we should change the type of the symbol,
933 // and then evaluate the cast over the symbolic pointer from 'void *' to
934 // the object pointer type. But without changing the symbol's type it
935 // is breaking too much to evaluate the no-op symbolic cast over it, so we
936 // skip it for now.
937 ProgramStateRef State = I->getState();
938 SVal RetVal = State->getSVal(CNE, LCtx);
939 // [basic.stc.dynamic.allocation] (on the return value of an allocation
940 // function):
941 // "The order, contiguity, and initial value of storage allocated by
942 // successive calls to an allocation function are unspecified."
943 State = State->bindDefaultInitial(RetVal, UndefinedVal{}, LCtx);
944
945 // If this allocation function is not declared as non-throwing, failures
946 // /must/ be signalled by exceptions, and thus the return value will never
947 // be NULL. -fno-exceptions does not influence this semantics.
948 // FIXME: GCC has a -fcheck-new option, which forces it to consider the case
949 // where new can return NULL. If we end up supporting that option, we can
950 // consider adding a check for it here.
951 // C++11 [basic.stc.dynamic.allocation]p3.
952 if (const FunctionDecl *FD = CNE->getOperatorNew()) {
953 QualType Ty = FD->getType();
954 if (const auto *ProtoType = Ty->getAs<FunctionProtoType>())
955 if (!ProtoType->isNothrow())
956 State = State->assume(RetVal.castAs<DefinedOrUnknownSVal>(), true);
957 }
958
959 ValueBldr.generateNode(
960 CNE, I, addObjectUnderConstruction(State, CNE, LCtx, RetVal));
961 }
962
963 ExplodedNodeSet DstPostPostCallCallback;
964 getCheckerManager().runCheckersForPostCall(DstPostPostCallCallback,
965 DstPostValue, *Call, *this);
966 for (ExplodedNode *I : DstPostPostCallCallback) {
968 }
969}
970
972 ExplodedNodeSet &Dst) {
973 // FIXME: Much of this should eventually migrate to CXXAllocatorCall.
974 // Also, we need to decide how allocators actually work -- they're not
975 // really part of the CXXNewExpr because they happen BEFORE the
976 // CXXConstructExpr subexpression. See PR12014 for some discussion.
977
978 unsigned blockCount = currBldrCtx->blockCount();
979 const LocationContext *LCtx = Pred->getLocationContext();
980 SVal symVal = UnknownVal();
981 FunctionDecl *FD = CNE->getOperatorNew();
982
983 bool IsStandardGlobalOpNewFunction =
985
986 ProgramStateRef State = Pred->getState();
987
988 // Retrieve the stored operator new() return value.
989 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
990 symVal = *getObjectUnderConstruction(State, CNE, LCtx);
991 State = finishObjectConstruction(State, CNE, LCtx);
992 }
993
994 // We assume all standard global 'operator new' functions allocate memory in
995 // heap. We realize this is an approximation that might not correctly model
996 // a custom global allocator.
997 if (symVal.isUnknown()) {
998 if (IsStandardGlobalOpNewFunction)
999 symVal = svalBuilder.getConjuredHeapSymbolVal(getCFGElementRef(), LCtx,
1000 CNE->getType(), blockCount);
1001 else
1002 symVal = svalBuilder.conjureSymbolVal(
1003 /*symbolTag=*/nullptr, getCFGElementRef(), LCtx, blockCount);
1004 }
1005
1008 CEMgr.getCXXAllocatorCall(CNE, State, LCtx, getCFGElementRef());
1009
1010 if (!AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
1011 // Invalidate placement args.
1012 // FIXME: Once we figure out how we want allocators to work,
1013 // we should be using the usual pre-/(default-)eval-/post-call checkers
1014 // here.
1015 State = Call->invalidateRegions(blockCount, State);
1016 if (!State)
1017 return;
1018
1019 // If this allocation function is not declared as non-throwing, failures
1020 // /must/ be signalled by exceptions, and thus the return value will never
1021 // be NULL. -fno-exceptions does not influence this semantics.
1022 // FIXME: GCC has a -fcheck-new option, which forces it to consider the case
1023 // where new can return NULL. If we end up supporting that option, we can
1024 // consider adding a check for it here.
1025 // C++11 [basic.stc.dynamic.allocation]p3.
1026 if (const auto *ProtoType = FD->getType()->getAs<FunctionProtoType>())
1027 if (!ProtoType->isNothrow())
1028 if (auto dSymVal = symVal.getAs<DefinedOrUnknownSVal>())
1029 State = State->assume(*dSymVal, true);
1030 }
1031
1032 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
1033
1034 SVal Result = symVal;
1035
1036 if (CNE->isArray()) {
1037
1038 if (const auto *NewReg = cast_or_null<SubRegion>(symVal.getAsRegion())) {
1039 // If each element is initialized by their default constructor, the field
1040 // values are properly placed inside the required region, however if an
1041 // initializer list is used, this doesn't happen automatically.
1042 auto *Init = CNE->getInitializer();
1043 bool isInitList =
1044 isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(Init);
1045
1046 QualType ObjTy =
1047 isInitList ? Init->getType() : CNE->getType()->getPointeeType();
1048 const ElementRegion *EleReg =
1049 MRMgr.getElementRegion(ObjTy, svalBuilder.makeArrayIndex(0), NewReg,
1050 svalBuilder.getContext());
1051 Result = loc::MemRegionVal(EleReg);
1052
1053 // If the array is list initialized, we bind the initializer list to the
1054 // memory region here, otherwise we would lose it.
1055 if (isInitList) {
1056 Bldr.takeNodes(Pred);
1057 Pred = Bldr.generateNode(CNE, Pred, State);
1058
1059 SVal V = State->getSVal(Init, LCtx);
1060 ExplodedNodeSet evaluated;
1061 evalBind(evaluated, CNE, Pred, Result, V, true);
1062
1063 Bldr.takeNodes(Pred);
1064 Bldr.addNodes(evaluated);
1065
1066 Pred = *evaluated.begin();
1067 State = Pred->getState();
1068 }
1069 }
1070
1071 State = State->BindExpr(CNE, Pred->getLocationContext(), Result);
1072 Bldr.generateNode(CNE, Pred, State);
1073 return;
1074 }
1075
1076 // FIXME: Once we have proper support for CXXConstructExprs inside
1077 // CXXNewExpr, we need to make sure that the constructed object is not
1078 // immediately invalidated here. (The placement call should happen before
1079 // the constructor call anyway.)
1081 // Non-array placement new should always return the placement location.
1082 SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx);
1083 Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(),
1084 CNE->getPlacementArg(0)->getType());
1085 }
1086
1087 // Bind the address of the object, then check to see if we cached out.
1088 State = State->BindExpr(CNE, LCtx, Result);
1089 ExplodedNode *NewN = Bldr.generateNode(CNE, Pred, State);
1090 if (!NewN)
1091 return;
1092
1093 // If the type is not a record, we won't have a CXXConstructExpr as an
1094 // initializer. Copy the value over.
1095 if (const Expr *Init = CNE->getInitializer()) {
1097 assert(Bldr.getResults().size() == 1);
1098 Bldr.takeNodes(NewN);
1099 evalBind(Dst, CNE, NewN, Result, State->getSVal(Init, LCtx),
1100 /*FirstInit=*/IsStandardGlobalOpNewFunction);
1101 }
1102 }
1103}
1104
1106 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
1107
1110 CDE, Pred->getState(), Pred->getLocationContext(), getCFGElementRef());
1111
1112 ExplodedNodeSet DstPreCall;
1113 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, *Call, *this);
1114 ExplodedNodeSet DstPostCall;
1115
1116 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
1117 NodeBuilder Bldr(DstPreCall, DstPostCall, *currBldrCtx);
1118 for (ExplodedNode *I : DstPreCall) {
1119 // Intentionally either inline or conservative eval-call the operator
1120 // delete, but avoid triggering an eval-call event for checkers.
1121 // As detailed at handling CXXNewExprs, in short, because it does not
1122 // really make sense to eval-call user-provided functions.
1123 defaultEvalCall(Bldr, I, *Call);
1124 }
1125 } else {
1126 DstPostCall = std::move(DstPreCall);
1127 }
1128 getCheckerManager().runCheckersForPostCall(Dst, DstPostCall, *Call, *this);
1129}
1130
1132 ExplodedNodeSet &Dst) {
1133 const VarDecl *VD = CS->getExceptionDecl();
1134 if (!VD) {
1135 Dst.Add(Pred);
1136 return;
1137 }
1138
1139 const LocationContext *LCtx = Pred->getLocationContext();
1140 SVal V = svalBuilder.conjureSymbolVal(getCFGElementRef(), LCtx, VD->getType(),
1141 currBldrCtx->blockCount());
1142 ProgramStateRef state = Pred->getState();
1143 state = state->bindLoc(state->getLValue(VD, LCtx), V, LCtx);
1144
1145 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
1146 Bldr.generateNode(CS, Pred, state);
1147}
1148
1150 ExplodedNodeSet &Dst) {
1151 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
1152
1153 // Get the this object region from StoreManager.
1154 const LocationContext *LCtx = Pred->getLocationContext();
1155 const MemRegion *R =
1156 svalBuilder.getRegionManager().getCXXThisRegion(
1157 getContext().getCanonicalType(TE->getType()),
1158 LCtx);
1159
1160 ProgramStateRef state = Pred->getState();
1161 SVal V = state->getSVal(loc::MemRegionVal(R));
1162 Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V));
1163}
1164
1166 ExplodedNodeSet &Dst) {
1167 const LocationContext *LocCtxt = Pred->getLocationContext();
1168
1169 // Get the region of the lambda itself.
1170 const MemRegion *R = svalBuilder.getRegionManager().getCXXTempObjectRegion(
1171 LE, LocCtxt);
1173
1174 ProgramStateRef State = Pred->getState();
1175
1176 // If we created a new MemRegion for the lambda, we should explicitly bind
1177 // the captures.
1178 for (auto const [Idx, FieldForCapture, InitExpr] :
1179 llvm::zip(llvm::seq<unsigned>(0, -1), LE->getLambdaClass()->fields(),
1180 LE->capture_inits())) {
1181 SVal FieldLoc = State->getLValue(FieldForCapture, V);
1182
1183 SVal InitVal;
1184 if (!FieldForCapture->hasCapturedVLAType()) {
1185 assert(InitExpr && "Capture missing initialization expression");
1186
1187 // Capturing a 0 length array is a no-op, so we ignore it to get a more
1188 // accurate analysis. If it's not ignored, it would set the default
1189 // binding of the lambda to 'Unknown', which can lead to falsely detecting
1190 // 'Uninitialized' values as 'Unknown' and not reporting a warning.
1191 const auto FTy = FieldForCapture->getType();
1192 if (FTy->isConstantArrayType() &&
1193 getContext().getConstantArrayElementCount(
1194 getContext().getAsConstantArrayType(FTy)) == 0)
1195 continue;
1196
1197 // With C++17 copy elision the InitExpr can be anything, so instead of
1198 // pattern matching all cases, we simple check if the current field is
1199 // under construction or not, regardless what it's InitExpr is.
1200 if (const auto OUC =
1201 getObjectUnderConstruction(State, {LE, Idx}, LocCtxt)) {
1202 InitVal = State->getSVal(OUC->getAsRegion());
1203
1204 State = finishObjectConstruction(State, {LE, Idx}, LocCtxt);
1205 } else
1206 InitVal = State->getSVal(InitExpr, LocCtxt);
1207
1208 } else {
1209
1210 assert(!getObjectUnderConstruction(State, {LE, Idx}, LocCtxt) &&
1211 "VLA capture by value is a compile time error!");
1212
1213 // The field stores the length of a captured variable-length array.
1214 // These captures don't have initialization expressions; instead we
1215 // get the length from the VLAType size expression.
1216 Expr *SizeExpr = FieldForCapture->getCapturedVLAType()->getSizeExpr();
1217 InitVal = State->getSVal(SizeExpr, LocCtxt);
1218 }
1219
1220 State = State->bindLoc(FieldLoc, InitVal, LocCtxt);
1221 }
1222
1223 // Decay the Loc into an RValue, because there might be a
1224 // MaterializeTemporaryExpr node above this one which expects the bound value
1225 // to be an RValue.
1226 SVal LambdaRVal = State->getSVal(R);
1227
1228 ExplodedNodeSet Tmp;
1229 NodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
1230 // FIXME: is this the right program point kind?
1231 Bldr.generateNode(LE, Pred,
1232 State->BindExpr(LE, LocCtxt, LambdaRVal),
1234
1235 // FIXME: Move all post/pre visits to ::Visit().
1236 getCheckerManager().runCheckersForPostStmt(Dst, Tmp, LE, *this);
1237}
1238
1240 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
1241 ExplodedNodeSet CheckerPreStmt;
1242 getCheckerManager().runCheckersForPreStmt(CheckerPreStmt, Pred, A, *this);
1243
1244 ExplodedNodeSet EvalSet;
1245 NodeBuilder Bldr(CheckerPreStmt, EvalSet, *currBldrCtx);
1246
1247 for (const auto *Attr : getSpecificAttrs<CXXAssumeAttr>(A->getAttrs())) {
1248 for (ExplodedNode *N : CheckerPreStmt) {
1249 Visit(Attr->getAssumption()->IgnoreParens(), N, EvalSet);
1250 }
1251 }
1252
1253 getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, A, *this);
1254}
Defines the clang::ASTContext interface.
#define V(N, I)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static ProgramStateRef bindRequiredArrayElementToEnvironment(ProgramStateRef State, const ArrayInitLoopExpr *AILE, const LocationContext *LCtx, NonLoc Idx)
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:226
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const
Return number of constant array elements.
uint64_t getArrayInitLoopExprElementCount(const ArrayInitLoopExpr *AILE) const
Return number of elements initialized in an ArrayInitLoopExpr.
CFG::BuildOptions & getCFGBuildOptions()
Represents a loop initializing the elements of an array.
Definition Expr.h:5971
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Definition Expr.h:5986
Attr - This represents one attribute.
Definition Attr.h:46
Represents an attribute applied to a statement.
Definition Stmt.h:2195
ArrayRef< const Attr * > getAttrs() const
Definition Stmt.h:2227
Represents a function call that returns a C++ object by value.
Definition CFG.h:187
std::optional< T > getAs() const
Convert to the specified CFGElement type, returning std::nullopt if this CFGElement is not of the des...
Definition CFG.h:110
CXXCatchStmt - This represents a C++ catch block.
Definition StmtCXX.h:28
VarDecl * getExceptionDecl() const
Definition StmtCXX.h:49
Represents a call to a C++ constructor.
Definition ExprCXX.h:1549
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition ExprCXX.h:2627
Represents a C++ destructor within a class.
Definition DeclCXX.h:2876
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition ExprCXX.h:1752
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2136
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition ExprCXX.h:2356
bool isArray() const
Definition ExprCXX.h:2465
Expr * getPlacementArg(unsigned I)
Definition ExprCXX.h:2504
SourceLocation getBeginLoc() const
Definition ExprCXX.h:2607
FunctionDecl * getOperatorNew() const
Definition ExprCXX.h:2460
Expr * getInitializer()
The initializer of this new-expression.
Definition ExprCXX.h:2534
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
Definition DeclCXX.h:1186
Represents the this expression in C++.
Definition ExprCXX.h:1155
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2946
ConstructionContext's subclasses describe different ways of constructing an object in C++.
virtual const ArrayInitLoopExpr * getArrayInitLoop() const
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2109
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
This represents one expression.
Definition Expr.h:112
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3086
QualType getType() const
Definition Expr.h:144
Represents a function declaration or definition.
Definition Decl.h:2000
bool isReplaceableGlobalAllocationFunction(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
Definition Decl.h:2594
bool isReservedGlobalPlacementOperator() const
Determines whether this operator new or delete is one of the reserved global placement operators: voi...
Definition Decl.cpp:3404
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5315
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition ExprCXX.h:1969
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
const Decl * getDecl() const
const ParentMap & getParentMap() const
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
const LocationContext * getParent() const
It might return null.
const StackFrameContext * getStackFrame() const
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition ExprCXX.h:4921
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Definition ExprCXX.h:4946
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
Definition ExprCXX.h:4938
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
Definition ExprCXX.h:4971
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition Expr.h:1231
Stmt * getParent(Stmt *) const
Represents a program point just after an implicit call event.
If a crash happens while one of these objects are live, the message is printed out along with the spe...
ProgramPoint withTag(const ProgramPointTag *tag) const
Create a new ProgramPoint object that is the same as the original except for using the specified tag ...
A (possibly-)qualified type.
Definition TypeBase.h:937
Represents a struct/union/class.
Definition Decl.h:4327
It represents a stack frame of the call stack (based on CallEvent).
const Stmt * getCallSite() const
const CFGBlock * getCallSiteBlock() const
Stmt - This represents one statement.
Definition Stmt.h:86
SourceLocation getEndLoc() const LLVM_READONLY
Definition Stmt.cpp:367
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition Type.h:26
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:753
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9218
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
QualType getType() const
Definition Decl.h:723
Represents a variable declaration or definition.
Definition Decl.h:926
Represents a call to a C++ constructor.
Definition CallEvent.h:997
Manages the lifetime of CallEvent objects.
Definition CallEvent.h:1374
CallEventRef< CXXDestructorCall > getCXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger, const MemRegion *Target, bool IsBase, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1467
CallEventRef< CXXDeallocatorCall > getCXXDeallocatorCall(const CXXDeleteExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1483
CallEventRef getSimpleCall(const CallExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
CallEventRef< ObjCMethodCall > getObjCMethodCall(const ObjCMessageExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1445
CallEventRef< CXXAllocatorCall > getCXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1476
CallEventRef< CXXConstructorCall > getCXXConstructorCall(const CXXConstructExpr *E, const MemRegion *Target, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1452
CallEventRef< CXXInheritedConstructorCall > getCXXInheritedConstructorCall(const CXXInheritedCtorInitExpr *E, const MemRegion *Target, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1459
Represents an abstract call to a function or method along a particular path.
Definition CallEvent.h:153
static bool isVariadic(const Decl *D)
Returns true if the given decl is known to be variadic.
void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng)
Run checkers for pre-visiting obj-c messages.
void runCheckersForEvalCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &CE, ExprEngine &Eng, const EvalCallOptions &CallOpts)
Run checkers for evaluating a call.
void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting Stmts.
void runCheckersForNewAllocator(const CXXAllocatorCall &Call, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng, bool wasInlined=false)
Run checkers between C++ operator new and constructor calls.
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting obj-c messages.
ElementRegion is used to represent both array elements and casts.
Definition MemRegion.h:1227
void Add(ExplodedNode *N)
const ProgramStateRef & getState() const
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
const LocationContext * getLocationContext() const
ProgramStateManager & getStateManager()
Definition ExprEngine.h:419
std::pair< ProgramStateRef, SVal > handleConstructionContext(const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx, const LocationContext *LCtx, const ConstructionContext *CC, EvalCallOptions &CallOpts, unsigned Idx=0)
A convenient wrapper around computeObjectUnderConstruction and updateObjectsUnderConstruction.
Definition ExprEngine.h:760
void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, ExplodedNodeSet &Dst, EvalCallOptions &Options)
const CoreEngine & getCoreEngine() const
Definition ExprEngine.h:450
void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLambdaExpr - Transfer function logic for LambdaExprs.
static std::optional< SVal > getObjectUnderConstruction(ProgramStateRef State, const ConstructionContextItem &Item, const LocationContext *LC)
By looking at a certain item that may be potentially part of an object's ConstructionContext,...
CFGElement getCurrentCFGElement()
Return the CFG element corresponding to the worklist element that is currently being processed by Exp...
Definition ExprEngine.h:709
SVal computeObjectUnderConstruction(const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx, const LocationContext *LCtx, const ConstructionContext *CC, EvalCallOptions &CallOpts, unsigned Idx=0)
Find location of the object that is being constructed by a given constructor.
static std::optional< unsigned > getIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E, const LocationContext *LCtx)
Retreives which element is being constructed in a non-POD type array.
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
Definition ExprEngine.h:195
StoreManager & getStoreManager()
Definition ExprEngine.h:422
void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Create a C++ temporary object for an rvalue.
ConstCFGElementRef getCFGElementRef() const
Definition ExprEngine.h:229
CheckerManager & getCheckerManager() const
Definition ExprEngine.h:204
ProgramStateRef bindReturnValue(const CallEvent &Call, const LocationContext *LCtx, ProgramStateRef State)
Create a new state in which the call return value is binded to the call origin expression.
void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Visit - Transfer function logic for all statements.
void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred, const CallEvent &Call, const EvalCallOptions &CallOpts={})
Default implementation of call evaluation.
void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
SValBuilder & getSValBuilder()
Definition ExprEngine.h:208
ProgramStateRef updateObjectsUnderConstruction(SVal V, const Expr *E, ProgramStateRef State, const LocationContext *LCtx, const ConstructionContext *CC, const EvalCallOptions &CallOpts)
Update the program state with all the path-sensitive information that's necessary to perform construc...
void VisitAttributedStmt(const AttributedStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitAttributedStmt - Transfer function logic for AttributedStmt.
static std::optional< unsigned > getPendingInitLoop(ProgramStateRef State, const CXXConstructExpr *E, const LocationContext *LCtx)
Retreives the size of the array in the pending ArrayInitLoopExpr.
const ElementRegion * getElementRegion(QualType elementType, NonLoc Idx, const SubRegion *superRegion, const ASTContext &Ctx)
getElementRegion - Retrieve the memory region associated with the associated element type,...
MemRegion - The root abstract class for all memory regions.
Definition MemRegion.h:98
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path.
Definition CoreEngine.h:219
This is the simplest builder which generates nodes in the ExplodedGraph.
Definition CoreEngine.h:246
void takeNodes(const ExplodedNodeSet &S)
Definition CoreEngine.h:312
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred, bool MarkAsSink=false)
Generates a node in the ExplodedGraph.
ExplodedNode * generateSink(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a sink in the ExplodedGraph.
Definition CoreEngine.h:281
void addNodes(const ExplodedNodeSet &S)
Definition CoreEngine.h:318
const ExplodedNodeSet & getResults() const
Definition CoreEngine.h:307
CallEventManager & getCallEventManager()
MemRegionManager & getRegionManager()
ProgramStateManager & getStateManager()
NonLoc makeArrayIndex(uint64_t idx)
ASTContext & getContext()
loc::MemRegionVal makeLoc(SymbolRef sym)
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrameContext *SFC)
Return a memory region for the 'this' object reference.
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, ConstCFGElementRef elem, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique 'name'.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition SVals.h:56
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
Definition SVals.h:87
const MemRegion * getAsRegion() const
Definition SVals.cpp:119
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
Definition SVals.h:83
bool isUnknown() const
Definition SVals.h:105
SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)
Evaluates a chain of derived-to-base casts through the path specified in Cast.
Definition Store.cpp:254
SubRegion - A region that subsets another larger region.
Definition MemRegion.h:474
TypedValueRegion - An abstract class representing regions having a typed value.
Definition MemRegion.h:563
Definition ARM.cpp:1102
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
CXXConstructionKind
Definition ExprCXX.h:1541
StorageDuration
The storage duration for an object (per C++ [basic.stc]).
Definition Specifiers.h:339
@ SD_Thread
Thread storage duration.
Definition Specifiers.h:342
@ SD_Static
Static storage duration.
Definition Specifiers.h:343
@ SD_FullExpression
Full-expression storage duration (for temporaries).
Definition Specifiers.h:340
@ Result
The result type of a method or function.
Definition TypeBase.h:905
auto getSpecificAttrs(const Container &container)
U cast(CodeGen::Address addr)
Definition Address.h:327
Expr * extractElementInitializerFromNestedAILE(const ArrayInitLoopExpr *AILE)
Definition CFG.cpp:1460
unsigned long uint64_t
Hints for figuring out of a call should be inlined during evalCall().
Definition ExprEngine.h:96
bool IsTemporaryLifetimeExtendedViaAggregate
This call is a constructor for a temporary that is lifetime-extended by binding it to a reference-typ...
Definition ExprEngine.h:111
bool IsTemporaryCtorOrDtor
This call is a constructor or a destructor of a temporary value.
Definition ExprEngine.h:106
bool IsArrayCtorOrDtor
This call is a constructor or a destructor for a single element within an array, a part of array cons...
Definition ExprEngine.h:103
bool IsElidableCtorThatHasNotBeenElided
This call is a pre-C++17 elidable constructor that we failed to elide because we failed to compute th...
Definition ExprEngine.h:118
bool IsCtorOrDtorWithImproperlyModeledTargetRegion
This call is a constructor or a destructor for which we do not currently compute the this-region corr...
Definition ExprEngine.h:99