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.insert(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.
131 const Expr *E, ProgramStateRef State, unsigned NumVisitedCaller,
132 const LocationContext *LCtx, const ConstructionContext *CC,
133 EvalCallOptions &CallOpts, unsigned Idx) {
134
136 MemRegionManager &MRMgr = SVB.getRegionManager();
137 ASTContext &ACtx = SVB.getContext();
138
139 // Compute the target region by exploring the construction context.
140 if (CC) {
141 switch (CC->getKind()) {
144 const auto *DSCC = cast<VariableConstructionContext>(CC);
145 const auto *DS = DSCC->getDeclStmt();
146 const auto *Var = cast<VarDecl>(DS->getSingleDecl());
147 QualType Ty = Var->getType();
148 return makeElementRegion(State, State->getLValue(Var, LCtx), Ty,
149 CallOpts.IsArrayCtorOrDtor, Idx);
150 }
154 const auto *Init = ICC->getCXXCtorInitializer();
155 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
156 Loc ThisPtr = SVB.getCXXThis(CurCtor, LCtx->getStackFrame());
157 SVal ThisVal = State->getSVal(ThisPtr);
158 if (Init->isBaseInitializer()) {
159 const auto *ThisReg = cast<SubRegion>(ThisVal.getAsRegion());
160 const CXXRecordDecl *BaseClass =
161 Init->getBaseClass()->getAsCXXRecordDecl();
162 const auto *BaseReg =
163 MRMgr.getCXXBaseObjectRegion(BaseClass, ThisReg,
164 Init->isBaseVirtual());
165 return SVB.makeLoc(BaseReg);
166 }
167 if (Init->isDelegatingInitializer())
168 return ThisVal;
169
170 const ValueDecl *Field;
171 SVal FieldVal;
172 if (Init->isIndirectMemberInitializer()) {
173 Field = Init->getIndirectMember();
174 FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal);
175 } else {
176 Field = Init->getMember();
177 FieldVal = State->getLValue(Init->getMember(), ThisVal);
178 }
179
180 QualType Ty = Field->getType();
181 return makeElementRegion(State, FieldVal, Ty, CallOpts.IsArrayCtorOrDtor,
182 Idx);
183 }
185 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
186 const auto *NECC = cast<NewAllocatedObjectConstructionContext>(CC);
187 const auto *NE = NECC->getCXXNewExpr();
188 SVal V = *getObjectUnderConstruction(State, NE, LCtx);
189 if (const SubRegion *MR =
190 dyn_cast_or_null<SubRegion>(V.getAsRegion())) {
191 if (NE->isArray()) {
192 CallOpts.IsArrayCtorOrDtor = true;
193
194 auto Ty = NE->getType()->getPointeeType();
195 while (const auto *AT = getContext().getAsArrayType(Ty))
196 Ty = AT->getElementType();
197
198 auto R = MRMgr.getElementRegion(Ty, svalBuilder.makeArrayIndex(Idx),
199 MR, SVB.getContext());
200
201 return loc::MemRegionVal(R);
202 }
203 return V;
204 }
205 // TODO: Detect when the allocator returns a null pointer.
206 // Constructor shall not be called in this case.
207 }
208 break;
209 }
212 // The temporary is to be managed by the parent stack frame.
213 // So build it in the parent stack frame if we're not in the
214 // top frame of the analysis.
215 const StackFrame *SF = LCtx->getStackFrame();
216 if (const LocationContext *CallerLCtx = SF->getParent()) {
217 auto RTC = (*SF->getCallSiteBlock())[SF->getIndex()]
218 .getAs<CFGCXXRecordTypedCall>();
219 if (!RTC) {
220 // We were unable to find the correct construction context for the
221 // call in the parent stack frame. This is equivalent to not being
222 // able to find construction context at all.
223 break;
224 }
225
226 unsigned NVCaller = getNumVisited(CallerLCtx, SF->getCallSiteBlock());
228 SF->getCallSite(), State, NVCaller, CallerLCtx,
229 RTC->getConstructionContext(), CallOpts);
230 } else {
231 // We are on the top frame of the analysis. We do not know where is the
232 // object returned to. Conjure a symbolic region for the return value.
233 // TODO: We probably need a new MemRegion kind to represent the storage
234 // of that SymbolicRegion, so that we could produce a fancy symbol
235 // instead of an anonymous conjured symbol.
236 // TODO: Do we need to track the region to avoid having it dead
237 // too early? It does die too early, at least in C++17, but because
238 // putting anything into a SymbolicRegion causes an immediate escape,
239 // it doesn't cause any leak false positives.
240 const auto *RCC = cast<ReturnedValueConstructionContext>(CC);
241 // Make sure that this doesn't coincide with any other symbol
242 // conjured for the returned expression.
243 static const int TopLevelSymRegionTag = 0;
244 const Expr *RetE = RCC->getReturnStmt()->getRetValue();
245 assert(RetE && "Void returns should not have a construction context");
246 QualType ReturnTy = RetE->getType();
247 QualType RegionTy = ACtx.getPointerType(ReturnTy);
248 return SVB.conjureSymbolVal(&TopLevelSymRegionTag, getCFGElementRef(),
249 SF, RegionTy, getNumVisitedCurrent());
250 }
251 llvm_unreachable("Unhandled return value construction context!");
252 }
254 assert(AMgr.getAnalyzerOptions().ShouldElideConstructors);
256
257 // Support pre-C++17 copy elision. We'll have the elidable copy
258 // constructor in the AST and in the CFG, but we'll skip it
259 // and construct directly into the final object. This call
260 // also sets the CallOpts flags for us.
261 // If the elided copy/move constructor is not supported, there's still
262 // benefit in trying to model the non-elided constructor.
263 // Stash our state before trying to elide, as it'll get overwritten.
264 ProgramStateRef PreElideState = State;
265 EvalCallOptions PreElideCallOpts = CallOpts;
266
268 TCC->getConstructorAfterElision(), State, NumVisitedCaller, LCtx,
269 TCC->getConstructionContextAfterElision(), CallOpts);
270
271 // FIXME: This definition of "copy elision has not failed" is unreliable.
272 // It doesn't indicate that the constructor will actually be inlined
273 // later; this is still up to evalCall() to decide.
275 return V;
276
277 // Copy elision failed. Revert the changes and proceed as if we have
278 // a simple temporary.
279 CallOpts = PreElideCallOpts;
281 [[fallthrough]];
282 }
284 const auto *TCC = cast<TemporaryObjectConstructionContext>(CC);
285 const MaterializeTemporaryExpr *MTE = TCC->getMaterializedTemporaryExpr();
286
287 CallOpts.IsTemporaryCtorOrDtor = true;
288 if (MTE) {
289 if (const ValueDecl *VD = MTE->getExtendingDecl()) {
291 assert(SD != SD_FullExpression);
292 if (!VD->getType()->isReferenceType()) {
293 // We're lifetime-extended by a surrounding aggregate.
294 // Automatic destructors aren't quite working in this case
295 // on the CFG side. We should warn the caller about that.
296 // FIXME: Is there a better way to retrieve this information from
297 // the MaterializeTemporaryExpr?
299 }
300
301 if (SD == SD_Static || SD == SD_Thread)
302 return loc::MemRegionVal(
303 MRMgr.getCXXStaticLifetimeExtendedObjectRegion(E, VD));
304
305 return loc::MemRegionVal(
306 MRMgr.getCXXLifetimeExtendedObjectRegion(E, VD, LCtx));
307 }
308 assert(MTE->getStorageDuration() == SD_FullExpression);
309 }
310
311 return loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
312 }
314 CallOpts.IsTemporaryCtorOrDtor = true;
315
316 const auto *LCC = cast<LambdaCaptureConstructionContext>(CC);
317
319 MRMgr.getCXXTempObjectRegion(LCC->getInitializer(), LCtx));
320
321 const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E);
322 if (getIndexOfElementToConstruct(State, CE, LCtx)) {
323 CallOpts.IsArrayCtorOrDtor = true;
324 Base = State->getLValue(E->getType(), svalBuilder.makeArrayIndex(Idx),
325 Base);
326 }
327
328 return Base;
329 }
331 // Arguments are technically temporaries.
332 CallOpts.IsTemporaryCtorOrDtor = true;
333
334 const auto *ACC = cast<ArgumentConstructionContext>(CC);
335 const Expr *E = ACC->getCallLikeExpr();
336 unsigned Idx = ACC->getIndex();
337
339 auto getArgLoc = [&](CallEventRef<> Caller) -> std::optional<SVal> {
340 const LocationContext *FutureSFC =
341 Caller->getCalleeStackFrame(NumVisitedCaller);
342 // Return early if we are unable to reliably foresee
343 // the future stack frame.
344 if (!FutureSFC)
345 return std::nullopt;
346
347 // This should be equivalent to Caller->getDecl() for now, but
348 // FutureSFC->getDecl() is likely to support better stuff (like
349 // virtual functions) earlier.
350 const Decl *CalleeD = FutureSFC->getDecl();
351
352 // FIXME: Support for variadic arguments is not implemented here yet.
353 if (CallEvent::isVariadic(CalleeD))
354 return std::nullopt;
355
356 // Operator arguments do not correspond to operator parameters
357 // because this-argument is implemented as a normal argument in
358 // operator call expressions but not in operator declarations.
359 const TypedValueRegion *TVR = Caller->getParameterLocation(
360 *Caller->getAdjustedParameterIndex(Idx), NumVisitedCaller);
361 if (!TVR)
362 return std::nullopt;
363
364 return loc::MemRegionVal(TVR);
365 };
366
367 if (const auto *CE = dyn_cast<CallExpr>(E)) {
368 CallEventRef<> Caller =
369 CEMgr.getSimpleCall(CE, State, LCtx, getCFGElementRef());
370 if (std::optional<SVal> V = getArgLoc(Caller))
371 return *V;
372 else
373 break;
374 } else if (const auto *CCE = dyn_cast<CXXConstructExpr>(E)) {
375 // Don't bother figuring out the target region for the future
376 // constructor because we won't need it.
378 CCE, /*Target=*/nullptr, State, LCtx, getCFGElementRef());
379 if (std::optional<SVal> V = getArgLoc(Caller))
380 return *V;
381 else
382 break;
383 } else if (const auto *ME = dyn_cast<ObjCMessageExpr>(E)) {
384 CallEventRef<> Caller =
385 CEMgr.getObjCMethodCall(ME, State, LCtx, getCFGElementRef());
386 if (std::optional<SVal> V = getArgLoc(Caller))
387 return *V;
388 else
389 break;
390 }
391 }
392 } // switch (CC->getKind())
393 }
394
395 // If we couldn't find an existing region to construct into, assume we're
396 // constructing a temporary. Notify the caller of our failure.
398 return loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
399}
400
402 SVal V, const Expr *E, ProgramStateRef State, const LocationContext *LCtx,
403 const ConstructionContext *CC, const EvalCallOptions &CallOpts) {
405 // Sounds like we failed to find the target region and therefore
406 // copy elision failed. There's nothing we can do about it here.
407 return State;
408 }
409
410 // See if we're constructing an existing region by looking at the
411 // current construction context.
412 assert(CC && "Computed target region without construction context?");
413 switch (CC->getKind()) {
416 const auto *DSCC = cast<VariableConstructionContext>(CC);
417 return addObjectUnderConstruction(State, DSCC->getDeclStmt(), LCtx, V);
418 }
422 const auto *Init = ICC->getCXXCtorInitializer();
423 // Base and delegating initializers handled above
424 assert(Init->isAnyMemberInitializer() &&
425 "Base and delegating initializers should have been handled by"
426 "computeObjectUnderConstruction()");
427 return addObjectUnderConstruction(State, Init, LCtx, V);
428 }
430 return State;
431 }
434 const StackFrame *SF = LCtx->getStackFrame();
435 const LocationContext *CallerLCtx = SF->getParent();
436 if (!CallerLCtx) {
437 // No extra work is necessary in top frame.
438 return State;
439 }
440
441 auto RTC = (*SF->getCallSiteBlock())[SF->getIndex()]
442 .getAs<CFGCXXRecordTypedCall>();
443 assert(RTC && "Could not have had a target region without it");
444
446 V, SF->getCallSite(), State, CallerLCtx,
447 RTC->getConstructionContext(), CallOpts);
448 }
450 assert(AMgr.getAnalyzerOptions().ShouldElideConstructors);
454 V, TCC->getConstructorAfterElision(), State, LCtx,
455 TCC->getConstructionContextAfterElision(), CallOpts);
456
457 // Remember that we've elided the constructor.
458 State = addObjectUnderConstruction(
459 State, TCC->getConstructorAfterElision(), LCtx, V);
460
461 // Remember that we've elided the destructor.
462 if (const auto *BTE = TCC->getCXXBindTemporaryExpr())
463 State = elideDestructor(State, BTE, LCtx);
464
465 // Instead of materialization, shamelessly return
466 // the final object destination.
467 if (const auto *MTE = TCC->getMaterializedTemporaryExpr())
468 State = addObjectUnderConstruction(State, MTE, LCtx, V);
469
470 return State;
471 }
472 // If we decided not to elide the constructor, proceed as if
473 // it's a simple temporary.
474 [[fallthrough]];
475 }
477 const auto *TCC = cast<TemporaryObjectConstructionContext>(CC);
478 if (const auto *BTE = TCC->getCXXBindTemporaryExpr())
479 State = addObjectUnderConstruction(State, BTE, LCtx, V);
480
481 if (const auto *MTE = TCC->getMaterializedTemporaryExpr())
482 State = addObjectUnderConstruction(State, MTE, LCtx, V);
483
484 return State;
485 }
487 const auto *LCC = cast<LambdaCaptureConstructionContext>(CC);
488
489 // If we capture and array, we want to store the super region, not a
490 // sub-region.
491 if (const auto *EL = dyn_cast_or_null<ElementRegion>(V.getAsRegion()))
492 V = loc::MemRegionVal(EL->getSuperRegion());
493
494 return addObjectUnderConstruction(
495 State, {LCC->getLambdaExpr(), LCC->getIndex()}, LCtx, V);
496 }
498 const auto *ACC = cast<ArgumentConstructionContext>(CC);
499 if (const auto *BTE = ACC->getCXXBindTemporaryExpr())
500 State = addObjectUnderConstruction(State, BTE, LCtx, V);
501
502 return addObjectUnderConstruction(
503 State, {ACC->getCallLikeExpr(), ACC->getIndex()}, LCtx, V);
504 }
505 }
506 llvm_unreachable("Unhandled construction context!");
507}
508
509static ProgramStateRef
511 const ArrayInitLoopExpr *AILE,
512 const LocationContext *LCtx, NonLoc Idx) {
514 MemRegionManager &MRMgr = SVB.getRegionManager();
515 ASTContext &Ctx = SVB.getContext();
516
517 // HACK: There is no way we can put the index of the array element into the
518 // CFG unless we unroll the loop, so we manually select and bind the required
519 // parameter to the environment.
520 const Expr *SourceArray = AILE->getCommonExpr()->getSourceExpr();
521 const auto *Ctor =
523
524 const auto *SourceArrayRegion =
525 cast<SubRegion>(State->getSVal(SourceArray, LCtx).getAsRegion());
527 MRMgr.getElementRegion(Ctor->getType(), Idx, SourceArrayRegion, Ctx);
528
529 return State->BindExpr(Ctor->getArg(0), LCtx,
531}
532
533void ExprEngine::handleConstructor(const Expr *E,
534 ExplodedNode *Pred,
535 ExplodedNodeSet &destNodes) {
536 const auto *CE = dyn_cast<CXXConstructExpr>(E);
537 const auto *CIE = dyn_cast<CXXInheritedCtorInitExpr>(E);
538 assert(CE || CIE);
539
540 const LocationContext *LCtx = Pred->getLocationContext();
541 ProgramStateRef State = Pred->getState();
542
543 SVal Target = UnknownVal();
544
545 if (CE) {
546 if (std::optional<SVal> ElidedTarget =
547 getObjectUnderConstruction(State, CE, LCtx)) {
548 // We've previously modeled an elidable constructor by pretending that
549 // it in fact constructs into the correct target. This constructor can
550 // therefore be skipped.
551 Target = *ElidedTarget;
552 NodeBuilder Bldr(Pred, destNodes, *currBldrCtx);
553 State = finishObjectConstruction(State, CE, LCtx);
554 if (auto L = Target.getAs<Loc>())
555 State = State->BindExpr(CE, LCtx, State->getSVal(*L, CE->getType()));
556 Bldr.generateNode(CE, Pred, State);
557 return;
558 }
559 }
560
561 EvalCallOptions CallOpts;
562 auto C = getCurrentCFGElement().getAs<CFGConstructor>();
563 assert(C || getCurrentCFGElement().getAs<CFGStmt>());
564 const ConstructionContext *CC = C ? C->getConstructionContext() : nullptr;
565
566 const CXXConstructionKind CK =
567 CE ? CE->getConstructionKind() : CIE->getConstructionKind();
568 switch (CK) {
570 // Inherited constructors are always base class constructors.
571 assert(CE && !CIE && "A complete constructor is inherited?!");
572
573 // If the ctor is part of an ArrayInitLoopExpr, we want to handle it
574 // differently.
575 auto *AILE = CC ? CC->getArrayInitLoop() : nullptr;
576
577 unsigned Idx = 0;
578 if (CE->getType()->isArrayType() || AILE) {
579
580 auto isZeroSizeArray = [&] {
581 uint64_t Size = 1;
582
583 if (const auto *CAT = dyn_cast<ConstantArrayType>(CE->getType()))
585 else if (AILE)
587
588 return Size == 0;
589 };
590
591 // No element construction will happen in a 0 size array.
592 if (isZeroSizeArray()) {
593 NodeBuilder Bldr(Pred, destNodes, *currBldrCtx);
594 static SimpleProgramPointTag T{"ExprEngine",
595 "Skipping 0 size array construction"};
596 Bldr.generateNode(CE, Pred, State, &T);
597 return;
598 }
599
600 Idx = getIndexOfElementToConstruct(State, CE, LCtx).value_or(0u);
601 State = setIndexOfElementToConstruct(State, CE, LCtx, Idx + 1);
602 }
603
604 if (AILE) {
605 // Only set this once even though we loop through it multiple times.
606 if (!getPendingInitLoop(State, CE, LCtx))
607 State = setPendingInitLoop(
608 State, CE, LCtx,
609 getContext().getArrayInitLoopExprElementCount(AILE));
610
612 State, AILE, LCtx, svalBuilder.makeArrayIndex(Idx));
613 }
614
615 // The target region is found from construction context.
616 std::tie(State, Target) = handleConstructionContext(
617 CE, State, currBldrCtx, LCtx, CC, CallOpts, Idx);
618 break;
619 }
621 // Make sure we are not calling virtual base class initializers twice.
622 // Only the most-derived object should initialize virtual base classes.
623 const auto *OuterCtor = dyn_cast_or_null<CXXConstructExpr>(
624 LCtx->getStackFrame()->getCallSite());
625 assert(
626 (!OuterCtor ||
627 OuterCtor->getConstructionKind() == CXXConstructionKind::Complete ||
628 OuterCtor->getConstructionKind() == CXXConstructionKind::Delegating) &&
629 ("This virtual base should have already been initialized by "
630 "the most derived class!"));
631 (void)OuterCtor;
632 [[fallthrough]];
633 }
635 // In C++17, classes with non-virtual bases may be aggregates, so they would
636 // be initialized as aggregates without a constructor call, so we may have
637 // a base class constructed directly into an initializer list without
638 // having the derived-class constructor call on the previous stack frame.
639 // Initializer lists may be nested into more initializer lists that
640 // correspond to surrounding aggregate initializations.
641 // FIXME: For now this code essentially bails out. We need to find the
642 // correct target region and set it.
643 // FIXME: Instead of relying on the ParentMap, we should have the
644 // trigger-statement (InitListExpr or CXXParenListInitExpr in this case)
645 // passed down from CFG or otherwise always available during construction.
646 if (isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(
647 LCtx->getParentMap().getParent(E))) {
648 MemRegionManager &MRMgr = getSValBuilder().getRegionManager();
649 Target = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
651 break;
652 }
653 [[fallthrough]];
655 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
656 Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor,
657 LCtx->getStackFrame());
658 SVal ThisVal = State->getSVal(ThisPtr);
659
661 Target = ThisVal;
662 } else {
663 // Cast to the base type.
664 bool IsVirtual = (CK == CXXConstructionKind::VirtualBase);
665 SVal BaseVal =
666 getStoreManager().evalDerivedToBase(ThisVal, E->getType(), IsVirtual);
667 Target = BaseVal;
668 }
669 break;
670 }
671 }
672
673 if (State != Pred->getState()) {
674 static SimpleProgramPointTag T("ExprEngine",
675 "Prepare for object construction");
676 ExplodedNodeSet DstPrepare;
677 NodeBuilder BldrPrepare(Pred, DstPrepare, *currBldrCtx);
678 Pred =
679 BldrPrepare.generateNode(E, Pred, State, &T, ProgramPoint::PreStmtKind);
680 if (!Pred)
681 return;
682 }
683
684 const MemRegion *TargetRegion = Target.getAsRegion();
685 CallEventManager &CEMgr = getStateManager().getCallEventManager();
686 CallEventRef<> Call =
687 CIE ? (CallEventRef<>)CEMgr.getCXXInheritedConstructorCall(
688 CIE, TargetRegion, State, LCtx, getCFGElementRef())
689 : (CallEventRef<>)CEMgr.getCXXConstructorCall(
690 CE, TargetRegion, State, LCtx, getCFGElementRef());
691
692 ExplodedNodeSet DstPreVisit;
693 getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, E, *this);
694
695 ExplodedNodeSet PreInitialized;
696 if (CE) {
697 // FIXME: Is it possible and/or useful to do this before PreStmt?
698 NodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx);
699 for (ExplodedNode *N : DstPreVisit) {
700 ProgramStateRef State = N->getState();
701 if (CE->requiresZeroInitialization()) {
702 // FIXME: Once we properly handle constructors in new-expressions, we'll
703 // need to invalidate the region before setting a default value, to make
704 // sure there aren't any lingering bindings around. This probably needs
705 // to happen regardless of whether or not the object is zero-initialized
706 // to handle random fields of a placement-initialized object picking up
707 // old bindings. We might only want to do it when we need to, though.
708 // FIXME: This isn't actually correct for arrays -- we need to zero-
709 // initialize the entire array, not just the first element -- but our
710 // handling of arrays everywhere else is weak as well, so this shouldn't
711 // actually make things worse. Placement new makes this tricky as well,
712 // since it's then possible to be initializing one part of a multi-
713 // dimensional array.
714 const CXXRecordDecl *TargetHeldRecord =
715 dyn_cast_or_null<CXXRecordDecl>(CE->getType()->getAsRecordDecl());
716
717 if (!TargetHeldRecord || !TargetHeldRecord->isEmpty())
718 State = State->bindDefaultZero(Target, LCtx);
719 }
720
721 Bldr.generateNode(CE, N, State, /*tag=*/nullptr,
723 }
724 } else {
725 PreInitialized = DstPreVisit;
726 }
727
728 ExplodedNodeSet DstPreCall;
729 getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized,
730 *Call, *this);
731
732 ExplodedNodeSet DstEvaluated;
733
734 if (CE && CE->getConstructor()->isTrivial() &&
735 CE->getConstructor()->isCopyOrMoveConstructor() &&
736 !CallOpts.IsArrayCtorOrDtor) {
737 NodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);
738 // FIXME: Handle other kinds of trivial constructors as well.
739 for (ExplodedNode *N : DstPreCall)
740 performTrivialCopy(Bldr, N, *Call);
741
742 } else {
743 for (ExplodedNode *N : DstPreCall)
744 getCheckerManager().runCheckersForEvalCall(DstEvaluated, N, *Call, *this,
745 CallOpts);
746 }
747
748 // If the CFG was constructed without elements for temporary destructors
749 // and the just-called constructor created a temporary object then
750 // stop exploration if the temporary object has a noreturn constructor.
751 // This can lose coverage because the destructor, if it were present
752 // in the CFG, would be called at the end of the full expression or
753 // later (for life-time extended temporaries) -- but avoids infeasible
754 // paths when no-return temporary destructors are used for assertions.
755 ExplodedNodeSet DstEvaluatedPostProcessed;
756 NodeBuilder Bldr(DstEvaluated, DstEvaluatedPostProcessed, *currBldrCtx);
757 const AnalysisDeclContext *ADC = LCtx->getAnalysisDeclContext();
759 if (llvm::isa_and_nonnull<CXXTempObjectRegion,
760 CXXLifetimeExtendedObjectRegion>(TargetRegion) &&
762 ->getParent()
763 ->isAnyDestructorNoReturn()) {
764
765 // If we've inlined the constructor, then DstEvaluated would be empty.
766 // In this case we still want a sink, which could be implemented
767 // in processCallExit. But we don't have that implemented at the moment,
768 // so if you hit this assertion, see if you can avoid inlining
769 // the respective constructor when analyzer-config cfg-temporary-dtors
770 // is set to false.
771 // Otherwise there's nothing wrong with inlining such constructor.
772 assert(!DstEvaluated.empty() &&
773 "We should not have inlined this constructor!");
774
775 for (ExplodedNode *N : DstEvaluated) {
776 Bldr.generateSink(E, N, N->getState());
777 }
778
779 // There is no need to run the PostCall and PostStmt checker
780 // callbacks because we just generated sinks on all nodes in th
781 // frontier.
782 return;
783 }
784 }
785
786 ExplodedNodeSet DstPostArgumentCleanup;
787 for (ExplodedNode *I : DstEvaluatedPostProcessed)
788 finishArgumentConstruction(DstPostArgumentCleanup, I, *Call);
789
790 // If there were other constructors called for object-type arguments
791 // of this constructor, clean them up.
792 ExplodedNodeSet DstPostCall;
794 DstPostArgumentCleanup,
795 *Call, *this);
796 getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, E, *this);
797}
798
800 ExplodedNode *Pred,
801 ExplodedNodeSet &Dst) {
802 handleConstructor(CE, Pred, Dst);
803}
804
806 const CXXInheritedCtorInitExpr *CE, ExplodedNode *Pred,
807 ExplodedNodeSet &Dst) {
808 handleConstructor(CE, Pred, Dst);
809}
810
812 const MemRegion *Dest,
813 const Stmt *S,
814 bool IsBaseDtor,
815 ExplodedNode *Pred,
816 ExplodedNodeSet &Dst,
817 EvalCallOptions &CallOpts) {
818 assert(S && "A destructor without a trigger!");
819 const LocationContext *LCtx = Pred->getLocationContext();
820 ProgramStateRef State = Pred->getState();
821
822 const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl();
823 assert(RecordDecl && "Only CXXRecordDecls should have destructors");
824 const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor();
825 // FIXME: There should always be a Decl, otherwise the destructor call
826 // shouldn't have been added to the CFG in the first place.
827 if (!DtorDecl) {
828 // Skip the invalid destructor. We cannot simply return because
829 // it would interrupt the analysis instead.
830 static SimpleProgramPointTag T("ExprEngine", "SkipInvalidDestructor");
831 // FIXME: PostImplicitCall with a null decl may crash elsewhere anyway.
832 PostImplicitCall PP(/*Decl=*/nullptr, S->getEndLoc(), LCtx,
833 getCFGElementRef(), &T);
834 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
835 Bldr.generateNode(PP, Pred->getState(), Pred);
836 return;
837 }
838
839 if (!Dest) {
840 // We're trying to destroy something that is not a region. This may happen
841 // for a variety of reasons (unknown target region, concrete integer instead
842 // of target region, etc.). The current code makes an attempt to recover.
843 // FIXME: We probably don't really need to recover when we're dealing
844 // with concrete integers specifically.
846 if (const Expr *E = dyn_cast_or_null<Expr>(S)) {
847 Dest = MRMgr.getCXXTempObjectRegion(E, Pred->getLocationContext());
848 } else {
849 static SimpleProgramPointTag T("ExprEngine", "SkipInvalidDestructor");
850 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
851 Bldr.generateSink(Pred->getLocation().withTag(&T),
852 Pred->getState(), Pred);
853 return;
854 }
855 }
856
859 DtorDecl, S, Dest, IsBaseDtor, State, LCtx, getCFGElementRef());
860
861 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
862 Call->getSourceRange().getBegin(),
863 "Error evaluating destructor");
864
865 ExplodedNodeSet DstPreCall;
866 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
867 *Call, *this);
868
869 ExplodedNodeSet DstInvalidated;
870 NodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
871 for (ExplodedNode *N : DstPreCall)
872 defaultEvalCall(Bldr, N, *Call, CallOpts);
873
874 getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
875 *Call, *this);
876}
877
879 ExplodedNode *Pred,
880 ExplodedNodeSet &Dst) {
881 ProgramStateRef State = Pred->getState();
882 const LocationContext *LCtx = Pred->getLocationContext();
883 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
884 CNE->getBeginLoc(),
885 "Error evaluating New Allocator Call");
888 CEMgr.getCXXAllocatorCall(CNE, State, LCtx, getCFGElementRef());
889
890 ExplodedNodeSet DstPreCall;
891 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
892 *Call, *this);
893
894 ExplodedNodeSet DstPostCall;
895 NodeBuilder CallBldr(DstPreCall, DstPostCall, *currBldrCtx);
896 for (ExplodedNode *I : DstPreCall) {
897 // Operator new calls (CXXNewExpr) are intentionally not eval-called,
898 // because it does not make sense to eval-call user-provided functions.
899 // 1) If the new operator can be inlined, then don't prevent it from
900 // inlining by having an eval-call of that operator.
901 // 2) If it can't be inlined, then the default conservative modeling
902 // is what we want anyway.
903 // So the best is to not allow eval-calling CXXNewExprs from checkers.
904 // Checkers can provide their pre/post-call callbacks if needed.
905 defaultEvalCall(CallBldr, I, *Call);
906 }
907 // If the call is inlined, DstPostCall will be empty and we bail out now.
908
909 // Store return value of operator new() for future use, until the actual
910 // CXXNewExpr gets processed.
911 ExplodedNodeSet DstPostValue;
912 NodeBuilder ValueBldr(DstPostCall, DstPostValue, *currBldrCtx);
913 for (ExplodedNode *I : DstPostCall) {
914 // FIXME: Because CNE serves as the "call site" for the allocator (due to
915 // lack of a better expression in the AST), the conjured return value symbol
916 // is going to be of the same type (C++ object pointer type). Technically
917 // this is not correct because the operator new's prototype always says that
918 // it returns a 'void *'. So we should change the type of the symbol,
919 // and then evaluate the cast over the symbolic pointer from 'void *' to
920 // the object pointer type. But without changing the symbol's type it
921 // is breaking too much to evaluate the no-op symbolic cast over it, so we
922 // skip it for now.
923 ProgramStateRef State = I->getState();
924 SVal RetVal = State->getSVal(CNE, LCtx);
925 // [basic.stc.dynamic.allocation] (on the return value of an allocation
926 // function):
927 // "The order, contiguity, and initial value of storage allocated by
928 // successive calls to an allocation function are unspecified."
929 State = State->bindDefaultInitial(RetVal, UndefinedVal{}, LCtx);
930
931 // If this allocation function is not declared as non-throwing, failures
932 // /must/ be signalled by exceptions, and thus the return value will never
933 // be NULL. -fno-exceptions does not influence this semantics.
934 // FIXME: GCC has a -fcheck-new option, which forces it to consider the case
935 // where new can return NULL. If we end up supporting that option, we can
936 // consider adding a check for it here.
937 // C++11 [basic.stc.dynamic.allocation]p3.
938 if (const FunctionDecl *FD = CNE->getOperatorNew()) {
939 QualType Ty = FD->getType();
940 if (const auto *ProtoType = Ty->getAs<FunctionProtoType>())
941 if (!ProtoType->isNothrow())
942 State = State->assume(RetVal.castAs<DefinedOrUnknownSVal>(), true);
943 }
944
945 ValueBldr.generateNode(
946 CNE, I, addObjectUnderConstruction(State, CNE, LCtx, RetVal));
947 }
948
949 ExplodedNodeSet DstPostPostCallCallback;
950 getCheckerManager().runCheckersForPostCall(DstPostPostCallCallback,
951 DstPostValue, *Call, *this);
952 for (ExplodedNode *I : DstPostPostCallCallback) {
954 }
955}
956
958 ExplodedNodeSet &Dst) {
959 // FIXME: Much of this should eventually migrate to CXXAllocatorCall.
960 // Also, we need to decide how allocators actually work -- they're not
961 // really part of the CXXNewExpr because they happen BEFORE the
962 // CXXConstructExpr subexpression. See PR12014 for some discussion.
963
964 unsigned blockCount = getNumVisitedCurrent();
965 const LocationContext *LCtx = Pred->getLocationContext();
966 SVal symVal = UnknownVal();
967 FunctionDecl *FD = CNE->getOperatorNew();
968
969 bool IsStandardGlobalOpNewFunction =
971
972 ProgramStateRef State = Pred->getState();
973
974 // Retrieve the stored operator new() return value.
975 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
976 symVal = *getObjectUnderConstruction(State, CNE, LCtx);
977 State = finishObjectConstruction(State, CNE, LCtx);
978 }
979
980 // We assume all standard global 'operator new' functions allocate memory in
981 // heap. We realize this is an approximation that might not correctly model
982 // a custom global allocator.
983 if (symVal.isUnknown()) {
984 if (IsStandardGlobalOpNewFunction)
985 symVal = svalBuilder.getConjuredHeapSymbolVal(getCFGElementRef(), LCtx,
986 CNE->getType(), blockCount);
987 else
988 symVal = svalBuilder.conjureSymbolVal(
989 /*symbolTag=*/nullptr, getCFGElementRef(), LCtx, blockCount);
990 }
991
994 CEMgr.getCXXAllocatorCall(CNE, State, LCtx, getCFGElementRef());
995
996 if (!AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
997 // Invalidate placement args.
998 // FIXME: Once we figure out how we want allocators to work,
999 // we should be using the usual pre-/(default-)eval-/post-call checkers
1000 // here.
1001 State = Call->invalidateRegions(blockCount, State);
1002 if (!State)
1003 return;
1004
1005 // If this allocation function is not declared as non-throwing, failures
1006 // /must/ be signalled by exceptions, and thus the return value will never
1007 // be NULL. -fno-exceptions does not influence this semantics.
1008 // FIXME: GCC has a -fcheck-new option, which forces it to consider the case
1009 // where new can return NULL. If we end up supporting that option, we can
1010 // consider adding a check for it here.
1011 // C++11 [basic.stc.dynamic.allocation]p3.
1012 if (const auto *ProtoType = FD->getType()->getAs<FunctionProtoType>())
1013 if (!ProtoType->isNothrow())
1014 if (auto dSymVal = symVal.getAs<DefinedOrUnknownSVal>())
1015 State = State->assume(*dSymVal, true);
1016 }
1017
1018 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
1019
1020 SVal Result = symVal;
1021
1022 if (CNE->isArray()) {
1023
1024 if (const auto *NewReg = cast_or_null<SubRegion>(symVal.getAsRegion())) {
1025 // If each element is initialized by their default constructor, the field
1026 // values are properly placed inside the required region, however if an
1027 // initializer list is used, this doesn't happen automatically.
1028 auto *Init = CNE->getInitializer();
1029 bool isInitList =
1030 isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(Init);
1031
1032 QualType ObjTy =
1033 isInitList ? Init->getType() : CNE->getType()->getPointeeType();
1034 const ElementRegion *EleReg =
1035 MRMgr.getElementRegion(ObjTy, svalBuilder.makeArrayIndex(0), NewReg,
1036 svalBuilder.getContext());
1037 Result = loc::MemRegionVal(EleReg);
1038
1039 // If the array is list initialized, we bind the initializer list to the
1040 // memory region here, otherwise we would lose it.
1041 if (isInitList) {
1042 Bldr.takeNodes(Pred);
1043 Pred = Bldr.generateNode(CNE, Pred, State);
1044
1045 SVal V = State->getSVal(Init, LCtx);
1046 ExplodedNodeSet evaluated;
1047 evalBind(evaluated, CNE, Pred, Result, V, true);
1048
1049 Bldr.takeNodes(Pred);
1050 Bldr.addNodes(evaluated);
1051
1052 Pred = *evaluated.begin();
1053 State = Pred->getState();
1054 }
1055 }
1056
1057 State = State->BindExpr(CNE, Pred->getLocationContext(), Result);
1058 Bldr.generateNode(CNE, Pred, State);
1059 return;
1060 }
1061
1062 // FIXME: Once we have proper support for CXXConstructExprs inside
1063 // CXXNewExpr, we need to make sure that the constructed object is not
1064 // immediately invalidated here. (The placement call should happen before
1065 // the constructor call anyway.)
1067 // Non-array placement new should always return the placement location.
1068 SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx);
1069 Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(),
1070 CNE->getPlacementArg(0)->getType());
1071 }
1072
1073 // Bind the address of the object, then check to see if we cached out.
1074 State = State->BindExpr(CNE, LCtx, Result);
1075 ExplodedNode *NewN = Bldr.generateNode(CNE, Pred, State);
1076 if (!NewN)
1077 return;
1078
1079 // If the type is not a record, we won't have a CXXConstructExpr as an
1080 // initializer. Copy the value over.
1081 if (const Expr *Init = CNE->getInitializer()) {
1083 assert(Bldr.getResults().size() == 1);
1084 Bldr.takeNodes(NewN);
1085 evalBind(Dst, CNE, NewN, Result, State->getSVal(Init, LCtx),
1086 /*FirstInit=*/IsStandardGlobalOpNewFunction);
1087 }
1088 }
1089}
1090
1092 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
1093
1096 CDE, Pred->getState(), Pred->getLocationContext(), getCFGElementRef());
1097
1098 ExplodedNodeSet DstPreCall;
1099 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, *Call, *this);
1100 ExplodedNodeSet DstPostCall;
1101
1102 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
1103 NodeBuilder Bldr(DstPreCall, DstPostCall, *currBldrCtx);
1104 for (ExplodedNode *I : DstPreCall) {
1105 // Intentionally either inline or conservative eval-call the operator
1106 // delete, but avoid triggering an eval-call event for checkers.
1107 // As detailed at handling CXXNewExprs, in short, because it does not
1108 // really make sense to eval-call user-provided functions.
1109 defaultEvalCall(Bldr, I, *Call);
1110 }
1111 } else {
1112 DstPostCall = std::move(DstPreCall);
1113 }
1114 getCheckerManager().runCheckersForPostCall(Dst, DstPostCall, *Call, *this);
1115}
1116
1118 ExplodedNodeSet &Dst) {
1119 const VarDecl *VD = CS->getExceptionDecl();
1120 if (!VD) {
1121 Dst.insert(Pred);
1122 return;
1123 }
1124
1125 const LocationContext *LCtx = Pred->getLocationContext();
1126 SVal V = svalBuilder.conjureSymbolVal(getCFGElementRef(), LCtx, VD->getType(),
1128 ProgramStateRef state = Pred->getState();
1129 state = state->bindLoc(state->getLValue(VD, LCtx), V, LCtx);
1130
1131 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
1132 Bldr.generateNode(CS, Pred, state);
1133}
1134
1136 ExplodedNodeSet &Dst) {
1137 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
1138
1139 // Get the this object region from StoreManager.
1140 const LocationContext *LCtx = Pred->getLocationContext();
1141 const MemRegion *R =
1142 svalBuilder.getRegionManager().getCXXThisRegion(
1143 getContext().getCanonicalType(TE->getType()),
1144 LCtx);
1145
1146 ProgramStateRef state = Pred->getState();
1147 SVal V = state->getSVal(loc::MemRegionVal(R));
1148 Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V));
1149}
1150
1152 ExplodedNodeSet &Dst) {
1153 const LocationContext *LocCtxt = Pred->getLocationContext();
1154
1155 // Get the region of the lambda itself.
1156 const MemRegion *R = svalBuilder.getRegionManager().getCXXTempObjectRegion(
1157 LE, LocCtxt);
1159
1160 ProgramStateRef State = Pred->getState();
1161
1162 // If we created a new MemRegion for the lambda, we should explicitly bind
1163 // the captures.
1164 for (auto const [Idx, FieldForCapture, InitExpr] :
1165 llvm::zip(llvm::seq<unsigned>(0, -1), LE->getLambdaClass()->fields(),
1166 LE->capture_inits())) {
1167 SVal FieldLoc = State->getLValue(FieldForCapture, V);
1168
1169 SVal InitVal;
1170 if (!FieldForCapture->hasCapturedVLAType()) {
1171 assert(InitExpr && "Capture missing initialization expression");
1172
1173 // Capturing a 0 length array is a no-op, so we ignore it to get a more
1174 // accurate analysis. If it's not ignored, it would set the default
1175 // binding of the lambda to 'Unknown', which can lead to falsely detecting
1176 // 'Uninitialized' values as 'Unknown' and not reporting a warning.
1177 const auto FTy = FieldForCapture->getType();
1178 if (FTy->isConstantArrayType() &&
1179 getContext().getConstantArrayElementCount(
1180 getContext().getAsConstantArrayType(FTy)) == 0)
1181 continue;
1182
1183 // With C++17 copy elision the InitExpr can be anything, so instead of
1184 // pattern matching all cases, we simple check if the current field is
1185 // under construction or not, regardless what it's InitExpr is.
1186 if (const auto OUC =
1187 getObjectUnderConstruction(State, {LE, Idx}, LocCtxt)) {
1188 InitVal = State->getSVal(OUC->getAsRegion());
1189
1190 State = finishObjectConstruction(State, {LE, Idx}, LocCtxt);
1191 } else
1192 InitVal = State->getSVal(InitExpr, LocCtxt);
1193
1194 } else {
1195
1196 assert(!getObjectUnderConstruction(State, {LE, Idx}, LocCtxt) &&
1197 "VLA capture by value is a compile time error!");
1198
1199 // The field stores the length of a captured variable-length array.
1200 // These captures don't have initialization expressions; instead we
1201 // get the length from the VLAType size expression.
1202 Expr *SizeExpr = FieldForCapture->getCapturedVLAType()->getSizeExpr();
1203 InitVal = State->getSVal(SizeExpr, LocCtxt);
1204 }
1205
1206 State = State->bindLoc(FieldLoc, InitVal, LocCtxt);
1207 }
1208
1209 // Decay the Loc into an RValue, because there might be a
1210 // MaterializeTemporaryExpr node above this one which expects the bound value
1211 // to be an RValue.
1212 SVal LambdaRVal = State->getSVal(R);
1213
1214 ExplodedNodeSet Tmp;
1215 NodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
1216 // FIXME: is this the right program point kind?
1217 Bldr.generateNode(LE, Pred,
1218 State->BindExpr(LE, LocCtxt, LambdaRVal),
1220
1221 // FIXME: Move all post/pre visits to ::Visit().
1222 getCheckerManager().runCheckersForPostStmt(Dst, Tmp, LE, *this);
1223}
1224
1226 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
1227 ExplodedNodeSet CheckerPreStmt;
1228 getCheckerManager().runCheckersForPreStmt(CheckerPreStmt, Pred, A, *this);
1229
1230 ExplodedNodeSet EvalSet;
1231 NodeBuilder Bldr(CheckerPreStmt, EvalSet, *currBldrCtx);
1232
1233 for (const auto *Attr : getSpecificAttrs<CXXAssumeAttr>(A->getAttrs())) {
1234 for (ExplodedNode *N : CheckerPreStmt) {
1235 Visit(Attr->getAssumption()->IgnoreParens(), N, EvalSet);
1236 }
1237 }
1238
1239 getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, A, *this);
1240}
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:227
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:5969
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Definition Expr.h:5984
Attr - This represents one attribute.
Definition Attr.h:46
Represents an attribute applied to a statement.
Definition Stmt.h:2209
ArrayRef< const Attr * > getAttrs() const
Definition Stmt.h:2241
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:1552
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition ExprCXX.h:2630
Represents a C++ destructor within a class.
Definition DeclCXX.h:2882
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition ExprCXX.h:1755
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2132
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition ExprCXX.h:2359
bool isArray() const
Definition ExprCXX.h:2468
Expr * getPlacementArg(unsigned I)
Definition ExprCXX.h:2507
SourceLocation getBeginLoc() const
Definition ExprCXX.h:2610
FunctionDecl * getOperatorNew() const
Definition ExprCXX.h:2463
Expr * getInitializer()
The initializer of this new-expression.
Definition ExprCXX.h:2537
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:1158
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:2122
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:2018
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:2612
bool isReservedGlobalPlacementOperator() const
Determines whether this operator new or delete is one of the reserved global placement operators: voi...
Definition Decl.cpp:3398
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5362
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition ExprCXX.h:1972
const Decl * getDecl() const
const ParentMap & getParentMap() const
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
const LocationContext * getParent() const
It might return null.
const StackFrame * getStackFrame() const
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition ExprCXX.h:4920
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Definition ExprCXX.h:4945
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
Definition ExprCXX.h:4937
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
Definition ExprCXX.h:4970
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:4343
It represents a stack frame of the call stack (based on CallEvent).
unsigned getIndex() const
const Expr * 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:789
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9266
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:924
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:1466
CallEventRef< CXXDeallocatorCall > getCXXDeallocatorCall(const CXXDeleteExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1482
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:1444
CallEventRef< CXXAllocatorCall > getCXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1475
CallEventRef< CXXConstructorCall > getCXXConstructorCall(const CXXConstructExpr *E, const MemRegion *Target, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1451
CallEventRef< CXXInheritedConstructorCall > getCXXInheritedConstructorCall(const CXXInheritedCtorInitExpr *E, const MemRegion *Target, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1458
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 function calls (including methods, constructors, destructors etc.
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 function calls (including methods, constructors, destructors etc.
ElementRegion is used to represent both array elements and casts.
Definition MemRegion.h:1232
ExplodedNodeSet is a set of ExplodedNode * elements with the invariant that its elements cannot be nu...
void insert(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:480
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:819
void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, ExplodedNodeSet &Dst, EvalCallOptions &Options)
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:770
unsigned getNumVisited(const LocationContext *LC, const CFGBlock *Block) const
Definition ExprEngine.h:296
SVal computeObjectUnderConstruction(const Expr *E, ProgramStateRef State, unsigned NumVisitedCaller, 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)
Retrieves 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:215
StoreManager & getStoreManager()
Definition ExprEngine.h:483
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:292
CheckerManager & getCheckerManager() const
Definition ExprEngine.h:224
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)
unsigned getNumVisitedCurrent() const
Definition ExprEngine.h:302
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:228
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)
Retrieves 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
This is the simplest builder which generates nodes in the ExplodedGraph.
Definition CoreEngine.h:267
void takeNodes(const ExplodedNodeSet &S)
Definition CoreEngine.h:332
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:302
void addNodes(const ExplodedNodeSet &S)
Definition CoreEngine.h:338
const ExplodedNodeSet & getResults() const
Definition CoreEngine.h:328
CallEventManager & getCallEventManager()
MemRegionManager & getRegionManager()
ProgramStateManager & getStateManager()
NonLoc makeArrayIndex(uint64_t idx)
ASTContext & getContext()
loc::MemRegionVal makeLoc(SymbolRef sym)
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, ConstCFGElementRef elem, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique 'name'.
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrame *SF)
Return a memory region for the 'this' object reference.
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:1544
StorageDuration
The storage duration for an object (per C++ [basic.stc]).
Definition Specifiers.h:340
@ SD_Thread
Thread storage duration.
Definition Specifiers.h:343
@ SD_Static
Static storage duration.
Definition Specifiers.h:344
@ SD_FullExpression
Full-expression storage duration (for temporaries).
Definition Specifiers.h:341
@ 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 if a call should be inlined during evalCall().
Definition ExprEngine.h:94
bool IsTemporaryLifetimeExtendedViaAggregate
This call is a constructor for a temporary that is lifetime-extended by binding it to a reference-typ...
Definition ExprEngine.h:109
bool IsTemporaryCtorOrDtor
This call is a constructor or a destructor of a temporary value.
Definition ExprEngine.h:104
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:101
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:116
bool IsCtorOrDtorWithImproperlyModeledTargetRegion
This call is a constructor or a destructor for which we do not currently compute the this-region corr...
Definition ExprEngine.h:97