clang 22.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 StmtNodeBuilder 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 StmtNodeBuilder 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 StmtNodeBuilder 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 StmtNodeBuilder BldrPrepare(Pred, DstPrepare, *currBldrCtx);
692 BldrPrepare.generateNode(E, Pred, State, &T, ProgramPoint::PreStmtKind);
693 assert(DstPrepare.size() <= 1);
694 if (DstPrepare.size() == 0)
695 return;
696 Pred = *BldrPrepare.begin();
697 }
698
699 const MemRegion *TargetRegion = Target.getAsRegion();
700 CallEventManager &CEMgr = getStateManager().getCallEventManager();
701 CallEventRef<> Call =
702 CIE ? (CallEventRef<>)CEMgr.getCXXInheritedConstructorCall(
703 CIE, TargetRegion, State, LCtx, getCFGElementRef())
704 : (CallEventRef<>)CEMgr.getCXXConstructorCall(
705 CE, TargetRegion, State, LCtx, getCFGElementRef());
706
707 ExplodedNodeSet DstPreVisit;
708 getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, E, *this);
709
710 ExplodedNodeSet PreInitialized;
711 if (CE) {
712 // FIXME: Is it possible and/or useful to do this before PreStmt?
713 StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx);
714 for (ExplodedNode *N : DstPreVisit) {
715 ProgramStateRef State = N->getState();
716 if (CE->requiresZeroInitialization()) {
717 // FIXME: Once we properly handle constructors in new-expressions, we'll
718 // need to invalidate the region before setting a default value, to make
719 // sure there aren't any lingering bindings around. This probably needs
720 // to happen regardless of whether or not the object is zero-initialized
721 // to handle random fields of a placement-initialized object picking up
722 // old bindings. We might only want to do it when we need to, though.
723 // FIXME: This isn't actually correct for arrays -- we need to zero-
724 // initialize the entire array, not just the first element -- but our
725 // handling of arrays everywhere else is weak as well, so this shouldn't
726 // actually make things worse. Placement new makes this tricky as well,
727 // since it's then possible to be initializing one part of a multi-
728 // dimensional array.
729 const CXXRecordDecl *TargetHeldRecord =
730 dyn_cast_or_null<CXXRecordDecl>(CE->getType()->getAsRecordDecl());
731
732 if (!TargetHeldRecord || !TargetHeldRecord->isEmpty())
733 State = State->bindDefaultZero(Target, LCtx);
734 }
735
736 Bldr.generateNode(CE, N, State, /*tag=*/nullptr,
738 }
739 } else {
740 PreInitialized = DstPreVisit;
741 }
742
743 ExplodedNodeSet DstPreCall;
744 getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized,
745 *Call, *this);
746
747 ExplodedNodeSet DstEvaluated;
748
749 if (CE && CE->getConstructor()->isTrivial() &&
750 CE->getConstructor()->isCopyOrMoveConstructor() &&
751 !CallOpts.IsArrayCtorOrDtor) {
752 StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);
753 // FIXME: Handle other kinds of trivial constructors as well.
754 for (ExplodedNode *N : DstPreCall)
755 performTrivialCopy(Bldr, N, *Call);
756
757 } else {
758 for (ExplodedNode *N : DstPreCall)
759 getCheckerManager().runCheckersForEvalCall(DstEvaluated, N, *Call, *this,
760 CallOpts);
761 }
762
763 // If the CFG was constructed without elements for temporary destructors
764 // and the just-called constructor created a temporary object then
765 // stop exploration if the temporary object has a noreturn constructor.
766 // This can lose coverage because the destructor, if it were present
767 // in the CFG, would be called at the end of the full expression or
768 // later (for life-time extended temporaries) -- but avoids infeasible
769 // paths when no-return temporary destructors are used for assertions.
770 ExplodedNodeSet DstEvaluatedPostProcessed;
771 StmtNodeBuilder Bldr(DstEvaluated, DstEvaluatedPostProcessed, *currBldrCtx);
772 const AnalysisDeclContext *ADC = LCtx->getAnalysisDeclContext();
774 if (llvm::isa_and_nonnull<CXXTempObjectRegion,
775 CXXLifetimeExtendedObjectRegion>(TargetRegion) &&
777 ->getParent()
778 ->isAnyDestructorNoReturn()) {
779
780 // If we've inlined the constructor, then DstEvaluated would be empty.
781 // In this case we still want a sink, which could be implemented
782 // in processCallExit. But we don't have that implemented at the moment,
783 // so if you hit this assertion, see if you can avoid inlining
784 // the respective constructor when analyzer-config cfg-temporary-dtors
785 // is set to false.
786 // Otherwise there's nothing wrong with inlining such constructor.
787 assert(!DstEvaluated.empty() &&
788 "We should not have inlined this constructor!");
789
790 for (ExplodedNode *N : DstEvaluated) {
791 Bldr.generateSink(E, N, N->getState());
792 }
793
794 // There is no need to run the PostCall and PostStmt checker
795 // callbacks because we just generated sinks on all nodes in th
796 // frontier.
797 return;
798 }
799 }
800
801 ExplodedNodeSet DstPostArgumentCleanup;
802 for (ExplodedNode *I : DstEvaluatedPostProcessed)
803 finishArgumentConstruction(DstPostArgumentCleanup, I, *Call);
804
805 // If there were other constructors called for object-type arguments
806 // of this constructor, clean them up.
807 ExplodedNodeSet DstPostCall;
809 DstPostArgumentCleanup,
810 *Call, *this);
811 getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, E, *this);
812}
813
815 ExplodedNode *Pred,
816 ExplodedNodeSet &Dst) {
817 handleConstructor(CE, Pred, Dst);
818}
819
821 const CXXInheritedCtorInitExpr *CE, ExplodedNode *Pred,
822 ExplodedNodeSet &Dst) {
823 handleConstructor(CE, Pred, Dst);
824}
825
827 const MemRegion *Dest,
828 const Stmt *S,
829 bool IsBaseDtor,
830 ExplodedNode *Pred,
831 ExplodedNodeSet &Dst,
832 EvalCallOptions &CallOpts) {
833 assert(S && "A destructor without a trigger!");
834 const LocationContext *LCtx = Pred->getLocationContext();
835 ProgramStateRef State = Pred->getState();
836
837 const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl();
838 assert(RecordDecl && "Only CXXRecordDecls should have destructors");
839 const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor();
840 // FIXME: There should always be a Decl, otherwise the destructor call
841 // shouldn't have been added to the CFG in the first place.
842 if (!DtorDecl) {
843 // Skip the invalid destructor. We cannot simply return because
844 // it would interrupt the analysis instead.
845 static SimpleProgramPointTag T("ExprEngine", "SkipInvalidDestructor");
846 // FIXME: PostImplicitCall with a null decl may crash elsewhere anyway.
847 PostImplicitCall PP(/*Decl=*/nullptr, S->getEndLoc(), LCtx,
848 getCFGElementRef(), &T);
849 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
850 Bldr.generateNode(PP, Pred->getState(), Pred);
851 return;
852 }
853
854 if (!Dest) {
855 // We're trying to destroy something that is not a region. This may happen
856 // for a variety of reasons (unknown target region, concrete integer instead
857 // of target region, etc.). The current code makes an attempt to recover.
858 // FIXME: We probably don't really need to recover when we're dealing
859 // with concrete integers specifically.
861 if (const Expr *E = dyn_cast_or_null<Expr>(S)) {
862 Dest = MRMgr.getCXXTempObjectRegion(E, Pred->getLocationContext());
863 } else {
864 static SimpleProgramPointTag T("ExprEngine", "SkipInvalidDestructor");
865 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
866 Bldr.generateSink(Pred->getLocation().withTag(&T),
867 Pred->getState(), Pred);
868 return;
869 }
870 }
871
874 DtorDecl, S, Dest, IsBaseDtor, State, LCtx, getCFGElementRef());
875
876 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
877 Call->getSourceRange().getBegin(),
878 "Error evaluating destructor");
879
880 ExplodedNodeSet DstPreCall;
881 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
882 *Call, *this);
883
884 ExplodedNodeSet DstInvalidated;
885 StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
886 for (ExplodedNode *N : DstPreCall)
887 defaultEvalCall(Bldr, N, *Call, CallOpts);
888
889 getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
890 *Call, *this);
891}
892
894 ExplodedNode *Pred,
895 ExplodedNodeSet &Dst) {
896 ProgramStateRef State = Pred->getState();
897 const LocationContext *LCtx = Pred->getLocationContext();
898 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
899 CNE->getBeginLoc(),
900 "Error evaluating New Allocator Call");
903 CEMgr.getCXXAllocatorCall(CNE, State, LCtx, getCFGElementRef());
904
905 ExplodedNodeSet DstPreCall;
906 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
907 *Call, *this);
908
909 ExplodedNodeSet DstPostCall;
910 StmtNodeBuilder CallBldr(DstPreCall, DstPostCall, *currBldrCtx);
911 for (ExplodedNode *I : DstPreCall) {
912 // FIXME: Provide evalCall for checkers?
913 defaultEvalCall(CallBldr, I, *Call);
914 }
915 // If the call is inlined, DstPostCall will be empty and we bail out now.
916
917 // Store return value of operator new() for future use, until the actual
918 // CXXNewExpr gets processed.
919 ExplodedNodeSet DstPostValue;
920 StmtNodeBuilder ValueBldr(DstPostCall, DstPostValue, *currBldrCtx);
921 for (ExplodedNode *I : DstPostCall) {
922 // FIXME: Because CNE serves as the "call site" for the allocator (due to
923 // lack of a better expression in the AST), the conjured return value symbol
924 // is going to be of the same type (C++ object pointer type). Technically
925 // this is not correct because the operator new's prototype always says that
926 // it returns a 'void *'. So we should change the type of the symbol,
927 // and then evaluate the cast over the symbolic pointer from 'void *' to
928 // the object pointer type. But without changing the symbol's type it
929 // is breaking too much to evaluate the no-op symbolic cast over it, so we
930 // skip it for now.
931 ProgramStateRef State = I->getState();
932 SVal RetVal = State->getSVal(CNE, LCtx);
933 // [basic.stc.dynamic.allocation] (on the return value of an allocation
934 // function):
935 // "The order, contiguity, and initial value of storage allocated by
936 // successive calls to an allocation function are unspecified."
937 State = State->bindDefaultInitial(RetVal, UndefinedVal{}, LCtx);
938
939 // If this allocation function is not declared as non-throwing, failures
940 // /must/ be signalled by exceptions, and thus the return value will never
941 // be NULL. -fno-exceptions does not influence this semantics.
942 // FIXME: GCC has a -fcheck-new option, which forces it to consider the case
943 // where new can return NULL. If we end up supporting that option, we can
944 // consider adding a check for it here.
945 // C++11 [basic.stc.dynamic.allocation]p3.
946 if (const FunctionDecl *FD = CNE->getOperatorNew()) {
947 QualType Ty = FD->getType();
948 if (const auto *ProtoType = Ty->getAs<FunctionProtoType>())
949 if (!ProtoType->isNothrow())
950 State = State->assume(RetVal.castAs<DefinedOrUnknownSVal>(), true);
951 }
952
953 ValueBldr.generateNode(
954 CNE, I, addObjectUnderConstruction(State, CNE, LCtx, RetVal));
955 }
956
957 ExplodedNodeSet DstPostPostCallCallback;
958 getCheckerManager().runCheckersForPostCall(DstPostPostCallCallback,
959 DstPostValue, *Call, *this);
960 for (ExplodedNode *I : DstPostPostCallCallback) {
962 }
963}
964
966 ExplodedNodeSet &Dst) {
967 // FIXME: Much of this should eventually migrate to CXXAllocatorCall.
968 // Also, we need to decide how allocators actually work -- they're not
969 // really part of the CXXNewExpr because they happen BEFORE the
970 // CXXConstructExpr subexpression. See PR12014 for some discussion.
971
972 unsigned blockCount = currBldrCtx->blockCount();
973 const LocationContext *LCtx = Pred->getLocationContext();
974 SVal symVal = UnknownVal();
975 FunctionDecl *FD = CNE->getOperatorNew();
976
977 bool IsStandardGlobalOpNewFunction =
979
980 ProgramStateRef State = Pred->getState();
981
982 // Retrieve the stored operator new() return value.
983 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
984 symVal = *getObjectUnderConstruction(State, CNE, LCtx);
985 State = finishObjectConstruction(State, CNE, LCtx);
986 }
987
988 // We assume all standard global 'operator new' functions allocate memory in
989 // heap. We realize this is an approximation that might not correctly model
990 // a custom global allocator.
991 if (symVal.isUnknown()) {
992 if (IsStandardGlobalOpNewFunction)
993 symVal = svalBuilder.getConjuredHeapSymbolVal(getCFGElementRef(), LCtx,
994 CNE->getType(), blockCount);
995 else
996 symVal = svalBuilder.conjureSymbolVal(
997 /*symbolTag=*/nullptr, getCFGElementRef(), LCtx, blockCount);
998 }
999
1002 CEMgr.getCXXAllocatorCall(CNE, State, LCtx, getCFGElementRef());
1003
1004 if (!AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
1005 // Invalidate placement args.
1006 // FIXME: Once we figure out how we want allocators to work,
1007 // we should be using the usual pre-/(default-)eval-/post-call checkers
1008 // here.
1009 State = Call->invalidateRegions(blockCount);
1010 if (!State)
1011 return;
1012
1013 // If this allocation function is not declared as non-throwing, failures
1014 // /must/ be signalled by exceptions, and thus the return value will never
1015 // be NULL. -fno-exceptions does not influence this semantics.
1016 // FIXME: GCC has a -fcheck-new option, which forces it to consider the case
1017 // where new can return NULL. If we end up supporting that option, we can
1018 // consider adding a check for it here.
1019 // C++11 [basic.stc.dynamic.allocation]p3.
1020 if (const auto *ProtoType = FD->getType()->getAs<FunctionProtoType>())
1021 if (!ProtoType->isNothrow())
1022 if (auto dSymVal = symVal.getAs<DefinedOrUnknownSVal>())
1023 State = State->assume(*dSymVal, true);
1024 }
1025
1026 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
1027
1028 SVal Result = symVal;
1029
1030 if (CNE->isArray()) {
1031
1032 if (const auto *NewReg = cast_or_null<SubRegion>(symVal.getAsRegion())) {
1033 // If each element is initialized by their default constructor, the field
1034 // values are properly placed inside the required region, however if an
1035 // initializer list is used, this doesn't happen automatically.
1036 auto *Init = CNE->getInitializer();
1037 bool isInitList =
1038 isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(Init);
1039
1040 QualType ObjTy =
1041 isInitList ? Init->getType() : CNE->getType()->getPointeeType();
1042 const ElementRegion *EleReg =
1043 MRMgr.getElementRegion(ObjTy, svalBuilder.makeArrayIndex(0), NewReg,
1044 svalBuilder.getContext());
1045 Result = loc::MemRegionVal(EleReg);
1046
1047 // If the array is list initialized, we bind the initializer list to the
1048 // memory region here, otherwise we would lose it.
1049 if (isInitList) {
1050 Bldr.takeNodes(Pred);
1051 Pred = Bldr.generateNode(CNE, Pred, State);
1052
1053 SVal V = State->getSVal(Init, LCtx);
1054 ExplodedNodeSet evaluated;
1055 evalBind(evaluated, CNE, Pred, Result, V, true);
1056
1057 Bldr.takeNodes(Pred);
1058 Bldr.addNodes(evaluated);
1059
1060 Pred = *evaluated.begin();
1061 State = Pred->getState();
1062 }
1063 }
1064
1065 State = State->BindExpr(CNE, Pred->getLocationContext(), Result);
1066 Bldr.generateNode(CNE, Pred, State);
1067 return;
1068 }
1069
1070 // FIXME: Once we have proper support for CXXConstructExprs inside
1071 // CXXNewExpr, we need to make sure that the constructed object is not
1072 // immediately invalidated here. (The placement call should happen before
1073 // the constructor call anyway.)
1075 // Non-array placement new should always return the placement location.
1076 SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx);
1077 Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(),
1078 CNE->getPlacementArg(0)->getType());
1079 }
1080
1081 // Bind the address of the object, then check to see if we cached out.
1082 State = State->BindExpr(CNE, LCtx, Result);
1083 ExplodedNode *NewN = Bldr.generateNode(CNE, Pred, State);
1084 if (!NewN)
1085 return;
1086
1087 // If the type is not a record, we won't have a CXXConstructExpr as an
1088 // initializer. Copy the value over.
1089 if (const Expr *Init = CNE->getInitializer()) {
1091 assert(Bldr.getResults().size() == 1);
1092 Bldr.takeNodes(NewN);
1093 evalBind(Dst, CNE, NewN, Result, State->getSVal(Init, LCtx),
1094 /*FirstInit=*/IsStandardGlobalOpNewFunction);
1095 }
1096 }
1097}
1098
1100 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
1101
1104 CDE, Pred->getState(), Pred->getLocationContext(), getCFGElementRef());
1105
1106 ExplodedNodeSet DstPreCall;
1107 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, *Call, *this);
1108 ExplodedNodeSet DstPostCall;
1109
1110 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
1111 StmtNodeBuilder Bldr(DstPreCall, DstPostCall, *currBldrCtx);
1112 for (ExplodedNode *I : DstPreCall) {
1113 defaultEvalCall(Bldr, I, *Call);
1114 }
1115 } else {
1116 DstPostCall = DstPreCall;
1117 }
1118 getCheckerManager().runCheckersForPostCall(Dst, DstPostCall, *Call, *this);
1119}
1120
1122 ExplodedNodeSet &Dst) {
1123 const VarDecl *VD = CS->getExceptionDecl();
1124 if (!VD) {
1125 Dst.Add(Pred);
1126 return;
1127 }
1128
1129 const LocationContext *LCtx = Pred->getLocationContext();
1130 SVal V = svalBuilder.conjureSymbolVal(getCFGElementRef(), LCtx, VD->getType(),
1131 currBldrCtx->blockCount());
1132 ProgramStateRef state = Pred->getState();
1133 state = state->bindLoc(state->getLValue(VD, LCtx), V, LCtx);
1134
1135 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
1136 Bldr.generateNode(CS, Pred, state);
1137}
1138
1140 ExplodedNodeSet &Dst) {
1141 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
1142
1143 // Get the this object region from StoreManager.
1144 const LocationContext *LCtx = Pred->getLocationContext();
1145 const MemRegion *R =
1146 svalBuilder.getRegionManager().getCXXThisRegion(
1147 getContext().getCanonicalType(TE->getType()),
1148 LCtx);
1149
1150 ProgramStateRef state = Pred->getState();
1151 SVal V = state->getSVal(loc::MemRegionVal(R));
1152 Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V));
1153}
1154
1156 ExplodedNodeSet &Dst) {
1157 const LocationContext *LocCtxt = Pred->getLocationContext();
1158
1159 // Get the region of the lambda itself.
1160 const MemRegion *R = svalBuilder.getRegionManager().getCXXTempObjectRegion(
1161 LE, LocCtxt);
1163
1164 ProgramStateRef State = Pred->getState();
1165
1166 // If we created a new MemRegion for the lambda, we should explicitly bind
1167 // the captures.
1168 for (auto const [Idx, FieldForCapture, InitExpr] :
1169 llvm::zip(llvm::seq<unsigned>(0, -1), LE->getLambdaClass()->fields(),
1170 LE->capture_inits())) {
1171 SVal FieldLoc = State->getLValue(FieldForCapture, V);
1172
1173 SVal InitVal;
1174 if (!FieldForCapture->hasCapturedVLAType()) {
1175 assert(InitExpr && "Capture missing initialization expression");
1176
1177 // Capturing a 0 length array is a no-op, so we ignore it to get a more
1178 // accurate analysis. If it's not ignored, it would set the default
1179 // binding of the lambda to 'Unknown', which can lead to falsely detecting
1180 // 'Uninitialized' values as 'Unknown' and not reporting a warning.
1181 const auto FTy = FieldForCapture->getType();
1182 if (FTy->isConstantArrayType() &&
1183 getContext().getConstantArrayElementCount(
1184 getContext().getAsConstantArrayType(FTy)) == 0)
1185 continue;
1186
1187 // With C++17 copy elision the InitExpr can be anything, so instead of
1188 // pattern matching all cases, we simple check if the current field is
1189 // under construction or not, regardless what it's InitExpr is.
1190 if (const auto OUC =
1191 getObjectUnderConstruction(State, {LE, Idx}, LocCtxt)) {
1192 InitVal = State->getSVal(OUC->getAsRegion());
1193
1194 State = finishObjectConstruction(State, {LE, Idx}, LocCtxt);
1195 } else
1196 InitVal = State->getSVal(InitExpr, LocCtxt);
1197
1198 } else {
1199
1200 assert(!getObjectUnderConstruction(State, {LE, Idx}, LocCtxt) &&
1201 "VLA capture by value is a compile time error!");
1202
1203 // The field stores the length of a captured variable-length array.
1204 // These captures don't have initialization expressions; instead we
1205 // get the length from the VLAType size expression.
1206 Expr *SizeExpr = FieldForCapture->getCapturedVLAType()->getSizeExpr();
1207 InitVal = State->getSVal(SizeExpr, LocCtxt);
1208 }
1209
1210 State = State->bindLoc(FieldLoc, InitVal, LocCtxt);
1211 }
1212
1213 // Decay the Loc into an RValue, because there might be a
1214 // MaterializeTemporaryExpr node above this one which expects the bound value
1215 // to be an RValue.
1216 SVal LambdaRVal = State->getSVal(R);
1217
1218 ExplodedNodeSet Tmp;
1219 StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
1220 // FIXME: is this the right program point kind?
1221 Bldr.generateNode(LE, Pred,
1222 State->BindExpr(LE, LocCtxt, LambdaRVal),
1224
1225 // FIXME: Move all post/pre visits to ::Visit().
1226 getCheckerManager().runCheckersForPostStmt(Dst, Tmp, LE, *this);
1227}
1228
1230 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
1231 ExplodedNodeSet CheckerPreStmt;
1232 getCheckerManager().runCheckersForPreStmt(CheckerPreStmt, Pred, A, *this);
1233
1234 ExplodedNodeSet EvalSet;
1235 StmtNodeBuilder Bldr(CheckerPreStmt, EvalSet, *currBldrCtx);
1236
1237 for (const auto *Attr : getSpecificAttrs<CXXAssumeAttr>(A->getAttrs())) {
1238 for (ExplodedNode *N : CheckerPreStmt) {
1239 Visit(Attr->getAssumption()->IgnoreParens(), N, EvalSet);
1240 }
1241 }
1242
1243 getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, A, *this);
1244}
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:188
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:5904
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Definition Expr.h:5919
Attr - This represents one attribute.
Definition Attr.h:44
Represents an attribute applied to a statement.
Definition Stmt.h:2203
ArrayRef< const Attr * > getAttrs() const
Definition Stmt.h:2235
Represents a function call that returns a C++ object by value.
Definition CFG.h:186
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:109
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:2620
Represents a C++ destructor within a class.
Definition DeclCXX.h:2869
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition ExprCXX.h:1753
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2129
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition ExprCXX.h:2349
bool isArray() const
Definition ExprCXX.h:2458
Expr * getPlacementArg(unsigned I)
Definition ExprCXX.h:2497
SourceLocation getBeginLoc() const
Definition ExprCXX.h:2600
FunctionDecl * getOperatorNew() const
Definition ExprCXX.h:2453
Expr * getInitializer()
The initializer of this new-expression.
Definition ExprCXX.h:2527
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:2879
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:3069
QualType getType() const
Definition Expr.h:144
Represents a function declaration or definition.
Definition Decl.h:1999
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:2593
bool isReservedGlobalPlacementOperator() const
Determines whether this operator new or delete is one of the reserved global placement operators: voi...
Definition Decl.cpp:3391
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5264
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition ExprCXX.h:1970
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:4914
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Definition ExprCXX.h:4939
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
Definition ExprCXX.h:4931
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
Definition ExprCXX.h:4964
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition Expr.h:1230
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:4309
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:85
SourceLocation getEndLoc() const LLVM_READONLY
Definition Stmt.cpp:358
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:752
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9101
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:711
QualType getType() const
Definition Decl.h:722
Represents a variable declaration or definition.
Definition Decl.h:925
Represents a call to a C++ constructor.
Definition CallEvent.h:986
Manages the lifetime of CallEvent objects.
Definition CallEvent.h:1363
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:1456
CallEventRef< CXXDeallocatorCall > getCXXDeallocatorCall(const CXXDeleteExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1472
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:1434
CallEventRef< CXXAllocatorCall > getCXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1465
CallEventRef< CXXConstructorCall > getCXXConstructorCall(const CXXConstructExpr *E, const MemRegion *Target, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1441
CallEventRef< CXXInheritedConstructorCall > getCXXInheritedConstructorCall(const CXXInheritedCtorInitExpr *E, const MemRegion *Target, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1448
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:421
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:763
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:452
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:712
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:196
StoreManager & getStoreManager()
Definition ExprEngine.h:424
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:232
CheckerManager & getCheckerManager() const
Definition ExprEngine.h:205
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:209
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:224
This is the simplest builder which generates nodes in the ExplodedGraph.
Definition CoreEngine.h:240
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a node in the ExplodedGraph.
Definition CoreEngine.h:293
void takeNodes(const ExplodedNodeSet &S)
Definition CoreEngine.h:335
ExplodedNode * generateSink(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a sink in the ExplodedGraph.
Definition CoreEngine.h:306
void addNodes(const ExplodedNodeSet &S)
Definition CoreEngine.h:341
const ExplodedNodeSet & getResults()
Definition CoreEngine.h:312
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
This builder class is useful for generating nodes that resulted from visiting a statement.
Definition CoreEngine.h:384
ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
Definition CoreEngine.h:413
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:1134
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
const FunctionProtoType * T
auto getSpecificAttrs(const Container &container)
U cast(CodeGen::Address addr)
Definition Address.h:327
Expr * extractElementInitializerFromNestedAILE(const ArrayInitLoopExpr *AILE)
Definition CFG.cpp:1448
unsigned long uint64_t
Hints for figuring out of a call should be inlined during evalCall().
Definition ExprEngine.h:97
bool IsTemporaryLifetimeExtendedViaAggregate
This call is a constructor for a temporary that is lifetime-extended by binding it to a reference-typ...
Definition ExprEngine.h:112
bool IsTemporaryCtorOrDtor
This call is a constructor or a destructor of a temporary value.
Definition ExprEngine.h:107
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:104
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:119
bool IsCtorOrDtorWithImproperlyModeledTargetRegion
This call is a constructor or a destructor for which we do not currently compute the this-region corr...
Definition ExprEngine.h:100