@@ -844,11 +844,13 @@ module InterProceduralPointsTo {
844844 private predicate normal_parameter_points_to ( ParameterDefinition def , PointsToContext context , ObjectInternal value , ControlFlowNode origin ) {
845845 exists ( PointsToContext caller , ControlFlowNode arg |
846846 PointsToInternal:: pointsTo ( arg , caller , value , origin ) and
847- callsite_argument_transfer ( arg , caller , def , context )
847+ named_argument_transfer ( arg , caller , def , context )
848848 )
849849 or
850850 not def .isSelf ( ) and not def .isVarargs ( ) and not def .isKwargs ( ) and
851851 context .isRuntime ( ) and value = ObjectInternal:: unknown ( ) and origin = def .getDefiningNode ( )
852+ or
853+ positional_parameter_points_to ( def , context , value , origin )
852854 }
853855
854856 pragma [ noinline]
@@ -921,15 +923,15 @@ module InterProceduralPointsTo {
921923 exists ( int parameter_offset |
922924 callsite_calls_function ( call , caller , scope , callee , parameter_offset ) and
923925 startOffset = scope .getPositionalParameterCount ( ) - parameter_offset and
924- length = call . getNode ( ) . getPositionalArgumentCount ( ) - startOffset and
926+ length = positional_argument_count ( call , caller ) - startOffset and
925927 length > 0
926928 )
927929 }
928930
929931 predicate varargs_empty_tuple ( Function scope , PointsToContext callee ) {
930932 exists ( CallNode call , PointsToContext caller , int parameter_offset |
931933 callsite_calls_function ( call , caller , scope , callee , parameter_offset ) and
932- scope .getPositionalParameterCount ( ) - parameter_offset >= call . getNode ( ) . getPositionalArgumentCount ( )
934+ scope .getPositionalParameterCount ( ) - parameter_offset >= positional_argument_count ( call , caller )
933935 )
934936 }
935937
@@ -940,16 +942,39 @@ module InterProceduralPointsTo {
940942 p .isKwargs ( ) and value = TUnknownInstance ( ObjectInternal:: builtin ( "dict" ) )
941943 }
942944
943- /** Holds if the `(argument, caller)` pair matches up with `(param, callee)` pair across call. */
944- cached predicate callsite_argument_transfer ( ControlFlowNode argument , PointsToContext caller , ParameterDefinition param , PointsToContext callee ) {
945+ predicate positional_argument_points_to ( CallNode call , int argument , PointsToContext caller , ObjectInternal value , ControlFlowNode origin ) {
946+ PointsToInternal:: pointsTo ( call .getArg ( argument ) , caller , value , origin )
947+ or
948+ exists ( SequenceObjectInternal arg , int pos |
949+ pos = call .getNode ( ) .getPositionalArgumentCount ( ) and
950+ PointsToInternal:: pointsTo ( origin , caller , arg , _) and
951+ value = arg .getItem ( argument - pos ) and
952+ origin = call .getStarArg ( )
953+ )
954+ }
955+
956+ private int positional_argument_count ( CallNode call , PointsToContext caller ) {
957+ result = call .getNode ( ) .getPositionalArgumentCount ( ) and not exists ( call .getStarArg ( ) ) and caller .appliesTo ( call )
958+ or
959+ exists ( SequenceObjectInternal arg , int pos |
960+ pos = call .getNode ( ) .getPositionalArgumentCount ( ) and
961+ PointsToInternal:: pointsTo ( call .getStarArg ( ) , caller , arg , _) and
962+ result = pos + arg .length ( )
963+ )
964+ }
965+
966+ predicate positional_parameter_points_to ( ParameterDefinition def , PointsToContext context , ObjectInternal value , ControlFlowNode origin ) {
967+ exists ( CallNode call , int argument , PointsToContext caller , Function func , int offset |
968+ positional_argument_points_to ( call , argument , caller , value , origin ) and
969+ callsite_calls_function ( call , caller , func , context , offset ) and
970+ def .getParameter ( ) = func .getArg ( argument + offset )
971+ )
972+ }
973+
974+ cached predicate named_argument_transfer ( ControlFlowNode argument , PointsToContext caller , ParameterDefinition param , PointsToContext callee ) {
945975 exists ( CallNode call , Function func , int offset |
946976 callsite_calls_function ( call , caller , func , callee , offset )
947977 |
948- exists ( int n |
949- argument = call .getArg ( n ) and
950- param .getParameter ( ) = func .getArg ( n + offset )
951- )
952- or
953978 exists ( string name |
954979 argument = call .getArgByName ( name ) and
955980 param .getParameter ( ) = func .getArgByName ( name )
0 commit comments