@@ -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 disallow |
569+ fwdFlowOutFromArg ( call , kind , node ) and
570+ fwdFlowIsEntered ( call , disallow , cc ) and
571+ kind != disallow
571572 )
572573 }
573574
@@ -597,7 +598,13 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
597598 * Holds if an argument to `call` is reached in the flow covered by `fwdFlow`.
598599 */
599600 pragma [ nomagic]
600- private predicate fwdFlowIsEntered ( DataFlowCall call , Cc cc ) { fwdFlowIn ( call , _, cc , _) }
601+ private predicate fwdFlowIsEntered ( DataFlowCall call , ReturnKindExtOption disallow , Cc cc ) {
602+ exists ( ParamNodeEx p | fwdFlowIn ( call , _, cc , p ) |
603+ if allowParameterReturnInSelfEx ( p )
604+ then disallow .isNone ( )
605+ else p .isParameterOf ( _, disallow .asSome ( ) .( ParamUpdateReturnKind ) .getPosition ( ) )
606+ )
607+ }
601608
602609 pragma [ nomagic]
603610 private predicate fwdFlowInReducedViableImplInSomeCallContext (
@@ -618,7 +625,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
618625 pragma [ nomagic]
619626 private DataFlowCallable viableImplInSomeFwdFlowCallContextExt ( DataFlowCall call ) {
620627 exists ( DataFlowCall ctx |
621- fwdFlowIsEntered ( ctx , _) and
628+ fwdFlowIsEntered ( ctx , _, _ ) and
622629 result = viableImplInCallContextExt ( call , ctx )
623630 )
624631 }
@@ -666,17 +673,18 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
666673
667674 // inline to reduce the number of iterations
668675 pragma [ inline]
669- private predicate fwdFlowOut ( DataFlowCall call , NodeEx out , Cc cc ) {
670- exists ( ReturnPosition pos |
671- fwdFlowReturnPosition ( pos , cc ) and
672- viableReturnPosOutEx ( call , pos , out ) and
673- not fullBarrier ( out )
674- )
676+ private predicate fwdFlowOut ( DataFlowCall call , ReturnPosition pos , NodeEx out , Cc cc ) {
677+ fwdFlowReturnPosition ( pos , cc ) and
678+ viableReturnPosOutEx ( call , pos , out ) and
679+ not fullBarrier ( out )
675680 }
676681
677682 pragma [ nomagic]
678- private predicate fwdFlowOutFromArg ( DataFlowCall call , NodeEx out ) {
679- fwdFlowOut ( call , out , true )
683+ private predicate fwdFlowOutFromArg ( DataFlowCall call , ReturnKindExtOption kind , NodeEx out ) {
684+ exists ( ReturnPosition pos |
685+ fwdFlowOut ( call , pos , out , true ) and
686+ kind .asSome ( ) = pos .getKind ( )
687+ )
680688 }
681689
682690 private predicate stateStepFwd ( FlowState state1 , FlowState state2 ) {
@@ -750,7 +758,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
750758 )
751759 or
752760 // flow into a callable
753- revFlowIn ( _, node , false ) and
761+ revFlowIn ( _, _ , node , false ) and
754762 toReturn = false
755763 or
756764 // flow out of a callable
@@ -761,9 +769,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
761769 )
762770 or
763771 // flow through a callable
764- exists ( DataFlowCall call |
765- revFlowInToReturn ( call , node ) and
766- revFlowIsReturned ( call , toReturn )
772+ exists ( DataFlowCall call , ReturnKindExtOption kind , ReturnKindExtOption disallow |
773+ revFlowIsReturned ( call , kind , toReturn ) and
774+ revFlowInToReturn ( call , disallow , node ) and
775+ kind != disallow
767776 )
768777 }
769778
@@ -824,16 +833,20 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
824833
825834 // inline to reduce the number of iterations
826835 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- )
836+ private predicate revFlowIn ( DataFlowCall call , ParamNodeEx p , ArgNodeEx arg , boolean toReturn ) {
837+ revFlow ( p , toReturn ) and
838+ viableParamArgNodeCandFwd1 ( call , p , arg )
832839 }
833840
834841 pragma [ nomagic]
835- private predicate revFlowInToReturn ( DataFlowCall call , ArgNodeEx arg ) {
836- revFlowIn ( call , arg , true )
842+ private predicate revFlowInToReturn (
843+ DataFlowCall call , ReturnKindExtOption disallow , ArgNodeEx arg
844+ ) {
845+ exists ( ParamNodeEx p | revFlowIn ( call , p , arg , true ) |
846+ if allowParameterReturnInSelfEx ( p )
847+ then disallow .isNone ( )
848+ else p .isParameterOf ( _, disallow .asSome ( ) .( ParamUpdateReturnKind ) .getPosition ( ) )
849+ )
837850 }
838851
839852 /**
@@ -842,10 +855,12 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
842855 * reaching an argument of `call`.
843856 */
844857 pragma [ nomagic]
845- private predicate revFlowIsReturned ( DataFlowCall call , boolean toReturn ) {
858+ private predicate revFlowIsReturned (
859+ DataFlowCall call , ReturnKindExtOption kind , boolean toReturn
860+ ) {
846861 exists ( NodeEx out |
847862 revFlow ( out , toReturn ) and
848- fwdFlowOutFromArg ( call , out )
863+ fwdFlowOutFromArg ( call , kind , out )
849864 )
850865 }
851866
@@ -947,10 +962,13 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
947962
948963 pragma [ nomagic]
949964 predicate callMayFlowThroughRev ( DataFlowCall call ) {
950- exists ( ArgNodeEx arg , boolean toReturn |
965+ exists (
966+ ArgNodeEx arg , ReturnKindExtOption kind , ReturnKindExtOption disallow , boolean toReturn
967+ |
951968 revFlow ( arg , toReturn ) and
952- revFlowInToReturn ( call , arg ) and
953- revFlowIsReturned ( call , toReturn )
969+ revFlowIsReturned ( call , pragma [ only_bind_into ] ( kind ) , toReturn ) and
970+ revFlowInToReturn ( call , pragma [ only_bind_into ] ( disallow ) , arg ) and
971+ kind != disallow
954972 )
955973 }
956974
0 commit comments