@@ -557,17 +557,18 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
557557 )
558558 or
559559 // flow into a callable
560- fwdFlowIn ( _, _ , _, node ) and
560+ fwdFlowInParam ( _, node , _) and
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,30 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
593594 )
594595 }
595596
597+ pragma [ nomagic]
598+ private predicate fwdFlowInParam ( DataFlowCall call , ParamNodeEx p , Cc cc ) {
599+ fwdFlowIn ( call , _, cc , p )
600+ }
601+
602+ pragma [ nomagic]
603+ private ReturnKindExtOption getDisallowedReturnKind ( ParamNodeEx p ) {
604+ if allowParameterReturnInSelfEx ( p )
605+ then result .isNone ( )
606+ else p .isParameterOf ( _, result .asSome ( ) .( ParamUpdateReturnKind ) .getPosition ( ) )
607+ }
608+
596609 /**
597610 * Holds if an argument to `call` is reached in the flow covered by `fwdFlow`.
598611 */
599612 pragma [ nomagic]
600- private predicate fwdFlowIsEntered ( DataFlowCall call , Cc cc ) { fwdFlowIn ( call , _, cc , _) }
613+ private predicate fwdFlowIsEntered (
614+ DataFlowCall call , ReturnKindExtOption disallowReturnKind , Cc cc
615+ ) {
616+ exists ( ParamNodeEx p |
617+ fwdFlowInParam ( call , p , cc ) and
618+ disallowReturnKind = getDisallowedReturnKind ( p )
619+ )
620+ }
601621
602622 pragma [ nomagic]
603623 private predicate fwdFlowInReducedViableImplInSomeCallContext (
@@ -618,7 +638,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
618638 pragma [ nomagic]
619639 private DataFlowCallable viableImplInSomeFwdFlowCallContextExt ( DataFlowCall call ) {
620640 exists ( DataFlowCall ctx |
621- fwdFlowIsEntered ( ctx , _) and
641+ fwdFlowIsEntered ( ctx , _, _ ) and
622642 result = viableImplInCallContextExt ( call , ctx )
623643 )
624644 }
@@ -666,17 +686,18 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
666686
667687 // inline to reduce the number of iterations
668688 pragma [ inline]
669- private predicate fwdFlowOut ( DataFlowCall call , NodeEx out , Cc cc ) {
689+ private predicate fwdFlowOut ( DataFlowCall call , ReturnKindExt kind , NodeEx out , Cc cc ) {
670690 exists ( ReturnPosition pos |
671691 fwdFlowReturnPosition ( pos , cc ) and
672692 viableReturnPosOutEx ( call , pos , out ) and
673- not fullBarrier ( out )
693+ not fullBarrier ( out ) and
694+ kind = pos .getKind ( )
674695 )
675696 }
676697
677698 pragma [ nomagic]
678- private predicate fwdFlowOutFromArg ( DataFlowCall call , NodeEx out ) {
679- fwdFlowOut ( call , out , true )
699+ private predicate fwdFlowOutFromArg ( DataFlowCall call , ReturnKindExtOption kind , NodeEx out ) {
700+ fwdFlowOut ( call , kind . asSome ( ) , out , true )
680701 }
681702
682703 private predicate stateStepFwd ( FlowState state1 , FlowState state2 ) {
@@ -750,7 +771,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
750771 )
751772 or
752773 // flow into a callable
753- revFlowIn ( _, node , false ) and
774+ revFlowIn ( _, _ , node , false ) and
754775 toReturn = false
755776 or
756777 // flow out of a callable
@@ -761,9 +782,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
761782 )
762783 or
763784 // flow through a callable
764- exists ( DataFlowCall call |
765- revFlowInToReturn ( call , node ) and
766- revFlowIsReturned ( call , toReturn )
785+ exists ( DataFlowCall call , ReturnKindExtOption kind , ReturnKindExtOption disallowReturnKind |
786+ revFlowIsReturned ( call , kind , toReturn ) and
787+ revFlowInToReturn ( call , disallowReturnKind , node ) and
788+ kind != disallowReturnKind
767789 )
768790 }
769791
@@ -824,16 +846,19 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
824846
825847 // inline to reduce the number of iterations
826848 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- )
849+ private predicate revFlowIn ( DataFlowCall call , ParamNodeEx p , ArgNodeEx arg , boolean toReturn ) {
850+ revFlow ( p , toReturn ) and
851+ viableParamArgNodeCandFwd1 ( call , p , arg )
832852 }
833853
834854 pragma [ nomagic]
835- private predicate revFlowInToReturn ( DataFlowCall call , ArgNodeEx arg ) {
836- revFlowIn ( call , arg , true )
855+ private predicate revFlowInToReturn (
856+ DataFlowCall call , ReturnKindExtOption disallowReturnKind , ArgNodeEx arg
857+ ) {
858+ exists ( ParamNodeEx p |
859+ revFlowIn ( call , p , arg , true ) and
860+ disallowReturnKind = getDisallowedReturnKind ( p )
861+ )
837862 }
838863
839864 /**
@@ -842,10 +867,12 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
842867 * reaching an argument of `call`.
843868 */
844869 pragma [ nomagic]
845- private predicate revFlowIsReturned ( DataFlowCall call , boolean toReturn ) {
870+ private predicate revFlowIsReturned (
871+ DataFlowCall call , ReturnKindExtOption kind , boolean toReturn
872+ ) {
846873 exists ( NodeEx out |
847874 revFlow ( out , toReturn ) and
848- fwdFlowOutFromArg ( call , out )
875+ fwdFlowOutFromArg ( call , kind , out )
849876 )
850877 }
851878
@@ -947,10 +974,14 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
947974
948975 pragma [ nomagic]
949976 predicate callMayFlowThroughRev ( DataFlowCall call ) {
950- exists ( ArgNodeEx arg , boolean toReturn |
951- revFlow ( arg , toReturn ) and
952- revFlowInToReturn ( call , arg ) and
953- revFlowIsReturned ( call , toReturn )
977+ exists (
978+ ArgNodeEx arg , ReturnKindExtOption kind , ReturnKindExtOption disallowReturnKind ,
979+ boolean toReturn
980+ |
981+ revFlow ( arg , pragma [ only_bind_into ] ( toReturn ) ) and
982+ revFlowIsReturned ( call , kind , pragma [ only_bind_into ] ( toReturn ) ) and
983+ revFlowInToReturn ( call , disallowReturnKind , arg ) and
984+ kind != disallowReturnKind
954985 )
955986 }
956987
0 commit comments