@@ -551,15 +551,17 @@ void transferCallReturningOptional(const CallExpr *E,
551551 setHasValue (*Loc, State.Env .makeAtomicBoolValue (), State.Env );
552552}
553553
554- void handleConstMemberCall (const CallExpr *CE,
554+ bool handleConstMemberCall (const CallExpr *CE,
555555 dataflow::RecordStorageLocation *RecordLoc,
556556 const MatchFinder::MatchResult &Result,
557557 LatticeTransferState &State) {
558+ if (RecordLoc == nullptr ) return false ;
559+
558560 // If the const method returns an optional or reference to an optional.
559- if (RecordLoc != nullptr && isSupportedOptionalType (CE->getType ())) {
561+ if (isSupportedOptionalType (CE->getType ())) {
560562 const FunctionDecl *DirectCallee = CE->getDirectCallee ();
561563 if (DirectCallee == nullptr )
562- return ;
564+ return false ;
563565 StorageLocation &Loc =
564566 State.Lattice .getOrCreateConstMethodReturnStorageLocation (
565567 *RecordLoc, DirectCallee, State.Env , [&](StorageLocation &Loc) {
@@ -577,57 +579,65 @@ void handleConstMemberCall(const CallExpr *CE,
577579 auto &ResultLoc = State.Env .getResultObjectLocation (*CE);
578580 copyRecord (cast<RecordStorageLocation>(Loc), ResultLoc, State.Env );
579581 }
580- return ;
582+ return true ;
581583 }
582584
585+ bool IsBooleanOrPointer = CE->getType ()->isBooleanType () ||
586+ CE->getType ()->isPointerType ();
587+
583588 // Cache if the const method returns a reference
584- if (RecordLoc != nullptr && CE->isGLValue ()) {
589+ if (CE->isGLValue ()) {
585590 const FunctionDecl *DirectCallee = CE->getDirectCallee ();
586591 if (DirectCallee == nullptr )
587- return ;
592+ return false ;
588593
589594 StorageLocation &Loc =
590595 State.Lattice .getOrCreateConstMethodReturnStorageLocation (
591596 *RecordLoc, DirectCallee, State.Env , [&](StorageLocation &Loc) {
592- // no-op
597+ if (IsBooleanOrPointer) {
598+ State.Env .setValue (Loc, *State.Env .createValue (CE->getType ()));
599+ }
593600 });
594601
595602 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.
603606 Value *Val = State.Lattice .getOrCreateConstMethodReturnValue (*RecordLoc, CE,
604607 State.Env );
605608 if (Val == nullptr )
606- return ;
609+ return false ;
607610 State.Env .setValue (*CE, *Val);
608- return ;
611+ return true ;
609612 }
610613
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 ;
616615}
617616
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+ }
623628}
624629
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) {
628633 auto *RecordLoc = cast_or_null<dataflow::RecordStorageLocation>(
629634 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+ }
631641}
632642
633643void handleNonConstMemberCall (const CallExpr *CE,
0 commit comments