@@ -551,15 +551,17 @@ void transferCallReturningOptional(const CallExpr *E,
551
551
setHasValue (*Loc, State.Env .makeAtomicBoolValue (), State.Env );
552
552
}
553
553
554
- void handleConstMemberCall (const CallExpr *CE,
554
+ bool handleConstMemberCall (const CallExpr *CE,
555
555
dataflow::RecordStorageLocation *RecordLoc,
556
556
const MatchFinder::MatchResult &Result,
557
557
LatticeTransferState &State) {
558
+ if (RecordLoc == nullptr ) return false ;
559
+
558
560
// If the const method returns an optional or reference to an optional.
559
- if (RecordLoc != nullptr && isSupportedOptionalType (CE->getType ())) {
561
+ if (isSupportedOptionalType (CE->getType ())) {
560
562
const FunctionDecl *DirectCallee = CE->getDirectCallee ();
561
563
if (DirectCallee == nullptr )
562
- return ;
564
+ return false ;
563
565
StorageLocation &Loc =
564
566
State.Lattice .getOrCreateConstMethodReturnStorageLocation (
565
567
*RecordLoc, DirectCallee, State.Env , [&](StorageLocation &Loc) {
@@ -577,57 +579,65 @@ void handleConstMemberCall(const CallExpr *CE,
577
579
auto &ResultLoc = State.Env .getResultObjectLocation (*CE);
578
580
copyRecord (cast<RecordStorageLocation>(Loc), ResultLoc, State.Env );
579
581
}
580
- return ;
582
+ return true ;
581
583
}
582
584
585
+ bool IsBooleanOrPointer = CE->getType ()->isBooleanType () ||
586
+ CE->getType ()->isPointerType ();
587
+
583
588
// Cache if the const method returns a reference
584
- if (RecordLoc != nullptr && CE->isGLValue ()) {
589
+ if (CE->isGLValue ()) {
585
590
const FunctionDecl *DirectCallee = CE->getDirectCallee ();
586
591
if (DirectCallee == nullptr )
587
- return ;
592
+ return false ;
588
593
589
594
StorageLocation &Loc =
590
595
State.Lattice .getOrCreateConstMethodReturnStorageLocation (
591
596
*RecordLoc, DirectCallee, State.Env , [&](StorageLocation &Loc) {
592
- // no-op
597
+ if (IsBooleanOrPointer) {
598
+ State.Env .setValue (Loc, *State.Env .createValue (CE->getType ()));
599
+ }
593
600
});
594
601
595
602
State.Env .setStorageLocation (*CE, Loc);
596
- return ;
597
- }
598
-
599
- // Cache if the const method returns a boolean or pointer type.
600
- // We may decide to cache other return types in the future.
601
- if (RecordLoc != nullptr &&
602
- (CE->getType ()->isBooleanType () || CE->getType ()->isPointerType ())) {
603
+ return true ;
604
+ } else if (IsBooleanOrPointer) {
605
+ // Cache if the const method returns a boolean or pointer type.
603
606
Value *Val = State.Lattice .getOrCreateConstMethodReturnValue (*RecordLoc, CE,
604
607
State.Env );
605
608
if (Val == nullptr )
606
- return ;
609
+ return false ;
607
610
State.Env .setValue (*CE, *Val);
608
- return ;
611
+ return true ;
609
612
}
610
613
611
- // Perform default handling if the call returns an optional
612
- // but wasn't handled above (if RecordLoc is nullptr).
613
- if (isSupportedOptionalType (CE->getType ())) {
614
- transferCallReturningOptional (CE, Result, State);
615
- }
614
+ return false ;
616
615
}
617
616
618
- void transferValue_ConstMemberCall (const CXXMemberCallExpr *MCE,
619
- const MatchFinder::MatchResult &Result,
620
- LatticeTransferState &State) {
621
- handleConstMemberCall (
622
- MCE, dataflow::getImplicitObjectLocation (*MCE, State.Env ), Result, State);
617
+ void transferConstMemberCall (const CXXMemberCallExpr *MCE,
618
+ const MatchFinder::MatchResult &Result,
619
+ LatticeTransferState &State) {
620
+ if (!handleConstMemberCall (
621
+ MCE, dataflow::getImplicitObjectLocation (*MCE, State.Env ), Result,
622
+ State)) {
623
+ // Perform default handling if the call returns an optional,
624
+ // but wasn't handled.
625
+ if (isSupportedOptionalType (MCE->getType ()))
626
+ transferCallReturningOptional (MCE, Result, State);
627
+ }
623
628
}
624
629
625
- void transferValue_ConstMemberOperatorCall (
626
- const CXXOperatorCallExpr *OCE, const MatchFinder::MatchResult &Result,
627
- LatticeTransferState &State) {
630
+ void transferConstMemberOperatorCall ( const CXXOperatorCallExpr *OCE,
631
+ const MatchFinder::MatchResult &Result,
632
+ LatticeTransferState &State) {
628
633
auto *RecordLoc = cast_or_null<dataflow::RecordStorageLocation>(
629
634
State.Env .getStorageLocation (*OCE->getArg (0 )));
630
- handleConstMemberCall (OCE, RecordLoc, Result, State);
635
+ if (!handleConstMemberCall (OCE, RecordLoc, Result, State)) {
636
+ // Perform default handling if the call returns an optional,
637
+ // but wasn't handled.
638
+ if (isSupportedOptionalType (OCE->getType ()))
639
+ transferCallReturningOptional (OCE, Result, State);
640
+ }
631
641
}
632
642
633
643
void handleNonConstMemberCall (const CallExpr *CE,
0 commit comments