@@ -69,14 +69,19 @@ void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
6969
7070 assert (ThisRD);
7171 SVal V = Call.getArgSVal (0 );
72+ const Expr *VExpr = Call.getArgExpr (0 );
7273
7374 // If the value being copied is not unknown, load from its location to get
7475 // an aggregate rvalue.
7576 if (std::optional<Loc> L = V.getAs <Loc>())
7677 V = Pred->getState ()->getSVal (*L);
7778 else
7879 assert (V.isUnknownOrUndef ());
79- evalBind (Dst, CallExpr, Pred, ThisVal, V, true );
80+
81+ ExplodedNodeSet Tmp;
82+ evalLocation (Tmp, CallExpr, VExpr, Pred, Pred->getState (), V, true );
83+ for (ExplodedNode *N : Tmp)
84+ evalBind (Dst, CallExpr, N, ThisVal, V, true );
8085
8186 PostStmt PS (CallExpr, LCtx);
8287 for (ExplodedNode *N : Dst) {
@@ -141,10 +146,9 @@ SVal ExprEngine::computeObjectUnderConstruction(
141146 if (Init->isBaseInitializer ()) {
142147 const auto *ThisReg = cast<SubRegion>(ThisVal.getAsRegion ());
143148 const CXXRecordDecl *BaseClass =
144- Init->getBaseClass ()->getAsCXXRecordDecl ();
145- const auto *BaseReg =
146- MRMgr.getCXXBaseObjectRegion (BaseClass, ThisReg,
147- Init->isBaseVirtual ());
149+ Init->getBaseClass ()->getAsCXXRecordDecl ();
150+ const auto *BaseReg = MRMgr.getCXXBaseObjectRegion (
151+ BaseClass, ThisReg, Init->isBaseVirtual ());
148152 return SVB.makeLoc (BaseReg);
149153 }
150154 if (Init->isDelegatingInitializer ())
@@ -183,7 +187,7 @@ SVal ExprEngine::computeObjectUnderConstruction(
183187
184188 return loc::MemRegionVal (R);
185189 }
186- return V;
190+ return V;
187191 }
188192 // TODO: Detect when the allocator returns a null pointer.
189193 // Constructor shall not be called in this case.
@@ -405,99 +409,99 @@ ProgramStateRef ExprEngine::updateObjectsUnderConstruction(
405409 case ConstructionContext::SimpleVariableKind: {
406410 const auto *DSCC = cast<VariableConstructionContext>(CC);
407411 return addObjectUnderConstruction (State, DSCC->getDeclStmt (), LCtx, V);
408- }
409- case ConstructionContext::CXX17ElidedCopyConstructorInitializerKind:
410- case ConstructionContext::SimpleConstructorInitializerKind: {
411- const auto *ICC = cast<ConstructorInitializerConstructionContext>(CC);
412- const auto *Init = ICC->getCXXCtorInitializer ();
413- // Base and delegating initializers handled above
414- assert (Init->isAnyMemberInitializer () &&
415- " Base and delegating initializers should have been handled by"
416- " computeObjectUnderConstruction()" );
417- return addObjectUnderConstruction (State, Init, LCtx, V);
418- }
419- case ConstructionContext::NewAllocatedObjectKind: {
412+ }
413+ case ConstructionContext::CXX17ElidedCopyConstructorInitializerKind:
414+ case ConstructionContext::SimpleConstructorInitializerKind: {
415+ const auto *ICC = cast<ConstructorInitializerConstructionContext>(CC);
416+ const auto *Init = ICC->getCXXCtorInitializer ();
417+ // Base and delegating initializers handled above
418+ assert (Init->isAnyMemberInitializer () &&
419+ " Base and delegating initializers should have been handled by"
420+ " computeObjectUnderConstruction()" );
421+ return addObjectUnderConstruction (State, Init, LCtx, V);
422+ }
423+ case ConstructionContext::NewAllocatedObjectKind: {
424+ return State;
425+ }
426+ case ConstructionContext::SimpleReturnedValueKind:
427+ case ConstructionContext::CXX17ElidedCopyReturnedValueKind: {
428+ const StackFrameContext *SFC = LCtx->getStackFrame ();
429+ const LocationContext *CallerLCtx = SFC->getParent ();
430+ if (!CallerLCtx) {
431+ // No extra work is necessary in top frame.
420432 return State;
421433 }
422- case ConstructionContext::SimpleReturnedValueKind:
423- case ConstructionContext::CXX17ElidedCopyReturnedValueKind: {
424- const StackFrameContext *SFC = LCtx->getStackFrame ();
425- const LocationContext *CallerLCtx = SFC->getParent ();
426- if (!CallerLCtx) {
427- // No extra work is necessary in top frame.
428- return State;
429- }
430434
431- auto RTC = (*SFC->getCallSiteBlock ())[SFC->getIndex ()]
432- .getAs <CFGCXXRecordTypedCall>();
433- assert (RTC && " Could not have had a target region without it" );
434- if (isa<BlockInvocationContext>(CallerLCtx)) {
435- // Unwrap block invocation contexts. They're mostly part of
436- // the current stack frame.
437- CallerLCtx = CallerLCtx->getParent ();
438- assert (!isa<BlockInvocationContext>(CallerLCtx));
439- }
440-
441- return updateObjectsUnderConstruction (V,
442- cast<Expr>(SFC->getCallSite ()), State, CallerLCtx,
443- RTC->getConstructionContext (), CallOpts);
444- }
445- case ConstructionContext::ElidedTemporaryObjectKind: {
446- assert (AMgr.getAnalyzerOptions ().ShouldElideConstructors );
447- if (!CallOpts.IsElidableCtorThatHasNotBeenElided ) {
448- const auto *TCC = cast<ElidedTemporaryObjectConstructionContext>(CC);
449- State = updateObjectsUnderConstruction (
450- V, TCC->getConstructorAfterElision (), State, LCtx,
451- TCC->getConstructionContextAfterElision (), CallOpts);
452-
453- // Remember that we've elided the constructor.
454- State = addObjectUnderConstruction (
455- State, TCC->getConstructorAfterElision (), LCtx, V);
456-
457- // Remember that we've elided the destructor.
458- if (const auto *BTE = TCC->getCXXBindTemporaryExpr ())
459- State = elideDestructor (State, BTE, LCtx);
460-
461- // Instead of materialization, shamelessly return
462- // the final object destination.
463- if (const auto *MTE = TCC->getMaterializedTemporaryExpr ())
464- State = addObjectUnderConstruction (State, MTE, LCtx, V);
465-
466- return State;
467- }
468- // If we decided not to elide the constructor, proceed as if
469- // it's a simple temporary.
470- [[fallthrough]];
435+ auto RTC = (*SFC->getCallSiteBlock ())[SFC->getIndex ()]
436+ .getAs <CFGCXXRecordTypedCall>();
437+ assert (RTC && " Could not have had a target region without it" );
438+ if (isa<BlockInvocationContext>(CallerLCtx)) {
439+ // Unwrap block invocation contexts. They're mostly part of
440+ // the current stack frame.
441+ CallerLCtx = CallerLCtx->getParent ();
442+ assert (!isa<BlockInvocationContext>(CallerLCtx));
471443 }
472- case ConstructionContext::SimpleTemporaryObjectKind: {
473- const auto *TCC = cast<TemporaryObjectConstructionContext>(CC);
444+
445+ return updateObjectsUnderConstruction (
446+ V, cast<Expr>(SFC->getCallSite ()), State, CallerLCtx,
447+ RTC->getConstructionContext (), CallOpts);
448+ }
449+ case ConstructionContext::ElidedTemporaryObjectKind: {
450+ assert (AMgr.getAnalyzerOptions ().ShouldElideConstructors );
451+ if (!CallOpts.IsElidableCtorThatHasNotBeenElided ) {
452+ const auto *TCC = cast<ElidedTemporaryObjectConstructionContext>(CC);
453+ State = updateObjectsUnderConstruction (
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.
474462 if (const auto *BTE = TCC->getCXXBindTemporaryExpr ())
475- State = addObjectUnderConstruction (State, BTE, LCtx, V );
463+ State = elideDestructor (State, BTE, LCtx);
476464
465+ // Instead of materialization, shamelessly return
466+ // the final object destination.
477467 if (const auto *MTE = TCC->getMaterializedTemporaryExpr ())
478468 State = addObjectUnderConstruction (State, MTE, LCtx, V);
479469
480470 return State;
481471 }
482- case ConstructionContext::LambdaCaptureKind: {
483- const auto *LCC = cast<LambdaCaptureConstructionContext>(CC);
472+ // If we decided not to elide the constructor, proceed as if
473+ // it's a simple temporary.
474+ [[fallthrough]];
475+ }
476+ case ConstructionContext::SimpleTemporaryObjectKind: {
477+ const auto *TCC = cast<TemporaryObjectConstructionContext>(CC);
478+ if (const auto *BTE = TCC->getCXXBindTemporaryExpr ())
479+ State = addObjectUnderConstruction (State, BTE, LCtx, V);
484480
485- // If we capture and array, we want to store the super region, not a
486- // sub-region.
487- if (const auto *EL = dyn_cast_or_null<ElementRegion>(V.getAsRegion ()))
488- V = loc::MemRegionVal (EL->getSuperRegion ());
481+ if (const auto *MTE = TCC->getMaterializedTemporaryExpr ())
482+ State = addObjectUnderConstruction (State, MTE, LCtx, V);
489483
490- return addObjectUnderConstruction (
491- State, {LCC->getLambdaExpr (), LCC->getIndex ()}, LCtx, V);
492- }
493- case ConstructionContext::ArgumentKind: {
494- const auto *ACC = cast<ArgumentConstructionContext>(CC);
495- if (const auto *BTE = ACC->getCXXBindTemporaryExpr ())
496- State = addObjectUnderConstruction (State, BTE, LCtx, V);
484+ return State;
485+ }
486+ case ConstructionContext::LambdaCaptureKind: {
487+ const auto *LCC = cast<LambdaCaptureConstructionContext>(CC);
497488
498- return addObjectUnderConstruction (
499- State, {ACC->getCallLikeExpr (), ACC->getIndex ()}, LCtx, V);
500- }
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+ }
497+ case ConstructionContext::ArgumentKind: {
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+ }
501505 }
502506 llvm_unreachable (" Unhandled construction context!" );
503507}
@@ -526,8 +530,7 @@ bindRequiredArrayElementToEnvironment(ProgramStateRef State,
526530 loc::MemRegionVal (ElementRegion));
527531}
528532
529- void ExprEngine::handleConstructor (const Expr *E,
530- ExplodedNode *Pred,
533+ void ExprEngine::handleConstructor (const Expr *E, ExplodedNode *Pred,
531534 ExplodedNodeSet &destNodes) {
532535 const auto *CE = dyn_cast<CXXConstructExpr>(E);
533536 const auto *CIE = dyn_cast<CXXInheritedCtorInitExpr>(E);
@@ -541,16 +544,16 @@ void ExprEngine::handleConstructor(const Expr *E,
541544 if (CE) {
542545 if (std::optional<SVal> ElidedTarget =
543546 getObjectUnderConstruction (State, CE, LCtx)) {
544- // We've previously modeled an elidable constructor by pretending that
545- // it in fact constructs into the correct target. This constructor can
546- // therefore be skipped.
547- Target = *ElidedTarget;
548- StmtNodeBuilder Bldr (Pred, destNodes, *currBldrCtx);
549- State = finishObjectConstruction (State, CE, LCtx);
550- if (auto L = Target.getAs <Loc>())
551- State = State->BindExpr (CE, LCtx, State->getSVal (*L, CE->getType ()));
552- Bldr.generateNode (CE, Pred, State);
553- return ;
547+ // We've previously modeled an elidable constructor by pretending that
548+ // it in fact constructs into the correct target. This constructor can
549+ // therefore be skipped.
550+ Target = *ElidedTarget;
551+ StmtNodeBuilder Bldr (Pred, destNodes, *currBldrCtx);
552+ State = finishObjectConstruction (State, CE, LCtx);
553+ if (auto L = Target.getAs <Loc>())
554+ State = State->BindExpr (CE, LCtx, State->getSVal (*L, CE->getType ()));
555+ Bldr.generateNode (CE, Pred, State);
556+ return ;
554557 }
555558 }
556559
@@ -648,8 +651,7 @@ void ExprEngine::handleConstructor(const Expr *E,
648651 [[fallthrough]];
649652 case CXXConstructionKind::Delegating: {
650653 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl ());
651- Loc ThisPtr = getSValBuilder ().getCXXThis (CurCtor,
652- LCtx->getStackFrame ());
654+ Loc ThisPtr = getSValBuilder ().getCXXThis (CurCtor, LCtx->getStackFrame ());
653655 SVal ThisVal = State->getSVal (ThisPtr);
654656
655657 if (CK == CXXConstructionKind::Delegating) {
@@ -718,8 +720,8 @@ void ExprEngine::handleConstructor(const Expr *E,
718720 }
719721
720722 ExplodedNodeSet DstPreCall;
721- getCheckerManager ().runCheckersForPreCall (DstPreCall, PreInitialized,
722- *Call, * this );
723+ getCheckerManager ().runCheckersForPreCall (DstPreCall, PreInitialized, *Call,
724+ *this );
723725
724726 ExplodedNodeSet DstEvaluated;
725727
@@ -782,9 +784,8 @@ void ExprEngine::handleConstructor(const Expr *E,
782784 // If there were other constructors called for object-type arguments
783785 // of this constructor, clean them up.
784786 ExplodedNodeSet DstPostCall;
785- getCheckerManager ().runCheckersForPostCall (DstPostCall,
786- DstPostArgumentCleanup,
787- *Call, *this );
787+ getCheckerManager ().runCheckersForPostCall (
788+ DstPostCall, DstPostArgumentCleanup, *Call, *this );
788789 getCheckerManager ().runCheckersForPostStmt (destNodes, DstPostCall, E, *this );
789790}
790791
@@ -800,12 +801,9 @@ void ExprEngine::VisitCXXInheritedCtorInitExpr(
800801 handleConstructor (CE, Pred, Dst);
801802}
802803
803- void ExprEngine::VisitCXXDestructor (QualType ObjectType,
804- const MemRegion *Dest,
805- const Stmt *S,
806- bool IsBaseDtor,
807- ExplodedNode *Pred,
808- ExplodedNodeSet &Dst,
804+ void ExprEngine::VisitCXXDestructor (QualType ObjectType, const MemRegion *Dest,
805+ const Stmt *S, bool IsBaseDtor,
806+ ExplodedNode *Pred, ExplodedNodeSet &Dst,
809807 EvalCallOptions &CallOpts) {
810808 assert (S && " A destructor without a trigger!" );
811809 const LocationContext *LCtx = Pred->getLocationContext ();
@@ -840,8 +838,8 @@ void ExprEngine::VisitCXXDestructor(QualType ObjectType,
840838 } else {
841839 static SimpleProgramPointTag T (" ExprEngine" , " SkipInvalidDestructor" );
842840 NodeBuilder Bldr (Pred, Dst, *currBldrCtx);
843- Bldr.generateSink (Pred->getLocation ().withTag (&T),
844- Pred-> getState (), Pred );
841+ Bldr.generateSink (Pred->getLocation ().withTag (&T), Pred-> getState (),
842+ Pred);
845843 return ;
846844 }
847845 }
@@ -855,16 +853,14 @@ void ExprEngine::VisitCXXDestructor(QualType ObjectType,
855853 " Error evaluating destructor" );
856854
857855 ExplodedNodeSet DstPreCall;
858- getCheckerManager ().runCheckersForPreCall (DstPreCall, Pred,
859- *Call, *this );
856+ getCheckerManager ().runCheckersForPreCall (DstPreCall, Pred, *Call, *this );
860857
861858 ExplodedNodeSet DstInvalidated;
862859 StmtNodeBuilder Bldr (DstPreCall, DstInvalidated, *currBldrCtx);
863860 for (ExplodedNode *N : DstPreCall)
864861 defaultEvalCall (Bldr, N, *Call, CallOpts);
865862
866- getCheckerManager ().runCheckersForPostCall (Dst, DstInvalidated,
867- *Call, *this );
863+ getCheckerManager ().runCheckersForPostCall (Dst, DstInvalidated, *Call, *this );
868864}
869865
870866void ExprEngine::VisitCXXNewAllocatorCall (const CXXNewExpr *CNE,
@@ -880,8 +876,7 @@ void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
880876 CEMgr.getCXXAllocatorCall (CNE, State, LCtx, getCFGElementRef ());
881877
882878 ExplodedNodeSet DstPreCall;
883- getCheckerManager ().runCheckersForPreCall (DstPreCall, Pred,
884- *Call, *this );
879+ getCheckerManager ().runCheckersForPreCall (DstPreCall, Pred, *Call, *this );
885880
886881 ExplodedNodeSet DstPostCall;
887882 StmtNodeBuilder CallBldr (DstPreCall, DstPostCall, *currBldrCtx);
@@ -940,7 +935,7 @@ void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
940935}
941936
942937void ExprEngine::VisitCXXNewExpr (const CXXNewExpr *CNE, ExplodedNode *Pred,
943- ExplodedNodeSet &Dst) {
938+ ExplodedNodeSet &Dst) {
944939 // FIXME: Much of this should eventually migrate to CXXAllocatorCall.
945940 // Also, we need to decide how allocators actually work -- they're not
946941 // really part of the CXXNewExpr because they happen BEFORE the
@@ -1112,15 +1107,13 @@ void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred,
11121107}
11131108
11141109void ExprEngine::VisitCXXThisExpr (const CXXThisExpr *TE, ExplodedNode *Pred,
1115- ExplodedNodeSet &Dst) {
1110+ ExplodedNodeSet &Dst) {
11161111 StmtNodeBuilder Bldr (Pred, Dst, *currBldrCtx);
11171112
11181113 // Get the this object region from StoreManager.
11191114 const LocationContext *LCtx = Pred->getLocationContext ();
1120- const MemRegion *R =
1121- svalBuilder.getRegionManager ().getCXXThisRegion (
1122- getContext ().getCanonicalType (TE->getType ()),
1123- LCtx);
1115+ const MemRegion *R = svalBuilder.getRegionManager ().getCXXThisRegion (
1116+ getContext ().getCanonicalType (TE->getType ()), LCtx);
11241117
11251118 ProgramStateRef state = Pred->getState ();
11261119 SVal V = state->getSVal (loc::MemRegionVal (R));
@@ -1132,8 +1125,8 @@ void ExprEngine::VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred,
11321125 const LocationContext *LocCtxt = Pred->getLocationContext ();
11331126
11341127 // Get the region of the lambda itself.
1135- const MemRegion *R = svalBuilder. getRegionManager (). getCXXTempObjectRegion (
1136- LE, LocCtxt);
1128+ const MemRegion *R =
1129+ svalBuilder. getRegionManager (). getCXXTempObjectRegion ( LE, LocCtxt);
11371130 SVal V = loc::MemRegionVal (R);
11381131
11391132 ProgramStateRef State = Pred->getState ();
@@ -1193,9 +1186,8 @@ void ExprEngine::VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred,
11931186 ExplodedNodeSet Tmp;
11941187 StmtNodeBuilder Bldr (Pred, Tmp, *currBldrCtx);
11951188 // FIXME: is this the right program point kind?
1196- Bldr.generateNode (LE, Pred,
1197- State->BindExpr (LE, LocCtxt, LambdaRVal),
1198- nullptr , ProgramPoint::PostLValueKind);
1189+ Bldr.generateNode (LE, Pred, State->BindExpr (LE, LocCtxt, LambdaRVal), nullptr ,
1190+ ProgramPoint::PostLValueKind);
11991191
12001192 // FIXME: Move all post/pre visits to ::Visit().
12011193 getCheckerManager ().runCheckersForPostStmt (Dst, Tmp, LE, *this );
0 commit comments