@@ -561,13 +561,14 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
561561 cc = true
562562 or
563563 // flow out of a callable
564- fwdFlowOut ( _, node , false ) and
564+ fwdFlowOut ( _, _ , node , false ) and
565565 cc = false
566566 or
567567 // flow through a callable
568- exists ( DataFlowCall call |
569- fwdFlowOutFromArg ( call , node ) and
570- fwdFlowIsEntered ( call , cc )
568+ exists ( DataFlowCall call , ReturnKindExtOption kind , ReturnKindExtOption disallowReturnKind |
569+ fwdFlowOutFromArg ( call , kind , node ) and
570+ fwdFlowIsEntered ( call , disallowReturnKind , cc ) and
571+ kind != disallowReturnKind
571572 )
572573 }
573574
@@ -593,11 +594,25 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
593594 )
594595 }
595596
597+ pragma [ nomagic]
598+ private ReturnKindExtOption getDisallowedReturnKind ( ParamNodeEx p ) {
599+ if allowParameterReturnInSelfEx ( p )
600+ then result .isNone ( )
601+ else p .isParameterOf ( _, result .asSome ( ) .( ParamUpdateReturnKind ) .getPosition ( ) )
602+ }
603+
596604 /**
597605 * Holds if an argument to `call` is reached in the flow covered by `fwdFlow`.
598606 */
599607 pragma [ nomagic]
600- private predicate fwdFlowIsEntered ( DataFlowCall call , Cc cc ) { fwdFlowIn ( call , _, cc , _) }
608+ private predicate fwdFlowIsEntered (
609+ DataFlowCall call , ReturnKindExtOption disallowReturnKind , Cc cc
610+ ) {
611+ exists ( ParamNodeEx p |
612+ fwdFlowIn ( call , _, cc , p ) and
613+ disallowReturnKind = getDisallowedReturnKind ( p )
614+ )
615+ }
601616
602617 pragma [ nomagic]
603618 private predicate fwdFlowInReducedViableImplInSomeCallContext (
@@ -618,7 +633,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
618633 pragma [ nomagic]
619634 private DataFlowCallable viableImplInSomeFwdFlowCallContextExt ( DataFlowCall call ) {
620635 exists ( DataFlowCall ctx |
621- fwdFlowIsEntered ( ctx , _) and
636+ fwdFlowIsEntered ( ctx , _, _ ) and
622637 result = viableImplInCallContextExt ( call , ctx )
623638 )
624639 }
@@ -666,17 +681,18 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
666681
667682 // inline to reduce the number of iterations
668683 pragma [ inline]
669- private predicate fwdFlowOut ( DataFlowCall call , NodeEx out , Cc cc ) {
684+ private predicate fwdFlowOut ( DataFlowCall call , ReturnKindExt kind , NodeEx out , Cc cc ) {
670685 exists ( ReturnPosition pos |
671686 fwdFlowReturnPosition ( pos , cc ) and
672687 viableReturnPosOutEx ( call , pos , out ) and
673- not fullBarrier ( out )
688+ not fullBarrier ( out ) and
689+ kind = pos .getKind ( )
674690 )
675691 }
676692
677693 pragma [ nomagic]
678- private predicate fwdFlowOutFromArg ( DataFlowCall call , NodeEx out ) {
679- fwdFlowOut ( call , out , true )
694+ private predicate fwdFlowOutFromArg ( DataFlowCall call , ReturnKindExtOption kind , NodeEx out ) {
695+ fwdFlowOut ( call , kind . asSome ( ) , out , true )
680696 }
681697
682698 private predicate stateStepFwd ( FlowState state1 , FlowState state2 ) {
@@ -750,7 +766,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
750766 )
751767 or
752768 // flow into a callable
753- revFlowIn ( _, node , false ) and
769+ revFlowIn ( _, _ , node , false ) and
754770 toReturn = false
755771 or
756772 // flow out of a callable
@@ -761,9 +777,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
761777 )
762778 or
763779 // flow through a callable
764- exists ( DataFlowCall call |
765- revFlowInToReturn ( call , node ) and
766- revFlowIsReturned ( call , toReturn )
780+ exists ( DataFlowCall call , ReturnKindExtOption kind , ReturnKindExtOption disallowReturnKind |
781+ revFlowIsReturned ( call , kind , toReturn ) and
782+ revFlowInToReturn ( call , disallowReturnKind , node ) and
783+ kind != disallowReturnKind
767784 )
768785 }
769786
@@ -824,16 +841,19 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
824841
825842 // inline to reduce the number of iterations
826843 pragma [ inline]
827- private predicate revFlowIn ( DataFlowCall call , ArgNodeEx arg , boolean toReturn ) {
828- exists ( ParamNodeEx p |
829- revFlow ( p , toReturn ) and
830- viableParamArgNodeCandFwd1 ( call , p , arg )
831- )
844+ private predicate revFlowIn ( DataFlowCall call , ParamNodeEx p , ArgNodeEx arg , boolean toReturn ) {
845+ revFlow ( p , toReturn ) and
846+ viableParamArgNodeCandFwd1 ( call , p , arg )
832847 }
833848
834849 pragma [ nomagic]
835- private predicate revFlowInToReturn ( DataFlowCall call , ArgNodeEx arg ) {
836- revFlowIn ( call , arg , true )
850+ private predicate revFlowInToReturn (
851+ DataFlowCall call , ReturnKindExtOption disallowReturnKind , ArgNodeEx arg
852+ ) {
853+ exists ( ParamNodeEx p |
854+ revFlowIn ( call , p , arg , true ) and
855+ disallowReturnKind = getDisallowedReturnKind ( p )
856+ )
837857 }
838858
839859 /**
@@ -842,10 +862,12 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
842862 * reaching an argument of `call`.
843863 */
844864 pragma [ nomagic]
845- private predicate revFlowIsReturned ( DataFlowCall call , boolean toReturn ) {
865+ private predicate revFlowIsReturned (
866+ DataFlowCall call , ReturnKindExtOption kind , boolean toReturn
867+ ) {
846868 exists ( NodeEx out |
847869 revFlow ( out , toReturn ) and
848- fwdFlowOutFromArg ( call , out )
870+ fwdFlowOutFromArg ( call , kind , out )
849871 )
850872 }
851873
@@ -941,10 +963,14 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
941963
942964 pragma [ nomagic]
943965 predicate callMayFlowThroughRev ( DataFlowCall call ) {
944- exists ( ArgNodeEx arg , boolean toReturn |
945- revFlow ( arg , toReturn ) and
946- revFlowInToReturn ( call , arg ) and
947- revFlowIsReturned ( call , toReturn )
966+ exists (
967+ ArgNodeEx arg , ReturnKindExtOption kind , ReturnKindExtOption disallowReturnKind ,
968+ boolean toReturn
969+ |
970+ revFlow ( arg , pragma [ only_bind_into ] ( toReturn ) ) and
971+ revFlowIsReturned ( call , kind , pragma [ only_bind_into ] ( toReturn ) ) and
972+ revFlowInToReturn ( call , disallowReturnKind , arg ) and
973+ kind != disallowReturnKind
948974 )
949975 }
950976
0 commit comments