@@ -871,6 +871,36 @@ final class TuplePositionContent extends Content, TTuplePositionContent {
871871 override Location getLocation ( ) { result instanceof EmptyLocation }
872872}
873873
874+ /**
875+ * A content for the index of an argument to at function call.
876+ *
877+ * Used by the model generator to create flow summaries for higher-order
878+ * functions.
879+ */
880+ final class FunctionCallArgumentContent extends Content , TFunctionCallArgumentContent {
881+ private int pos ;
882+
883+ FunctionCallArgumentContent ( ) { this = TFunctionCallArgumentContent ( pos ) }
884+
885+ int getPosition ( ) { result = pos }
886+
887+ override string toString ( ) { result = "function argument at " + pos }
888+
889+ override Location getLocation ( ) { result instanceof EmptyLocation }
890+ }
891+
892+ /**
893+ * A content for the return value of function call.
894+ *
895+ * Used by the model generator to create flow summaries for higher-order
896+ * functions.
897+ */
898+ final class FunctionCallReturnContent extends Content , TFunctionCallReturnContent {
899+ override string toString ( ) { result = "function return" }
900+
901+ override Location getLocation ( ) { result instanceof EmptyLocation }
902+ }
903+
874904/** Holds if `access` indexes a tuple at an index corresponding to `c`. */
875905private predicate fieldTuplePositionContent ( FieldExprCfgNode access , TuplePositionContent c ) {
876906 access .getNameRef ( ) .getText ( ) .toInt ( ) = c .getPosition ( )
@@ -1192,6 +1222,13 @@ module RustDataFlow implements InputSig<Location> {
11921222 node2 .asExpr ( ) = deref
11931223 )
11941224 or
1225+ // Read from function return
1226+ exists ( DataFlowCall call |
1227+ lambdaCall ( call , _, node1 ) and
1228+ call = node2 .( OutNode ) .getCall ( TNormalReturnKind ( ) ) and
1229+ c instanceof FunctionCallReturnContent
1230+ )
1231+ or
11951232 VariableCapture:: readStep ( node1 , c , node2 )
11961233 )
11971234 or
@@ -1273,6 +1310,13 @@ module RustDataFlow implements InputSig<Location> {
12731310 node2 .asExpr ( ) = ref
12741311 )
12751312 or
1313+ // Store in function argument
1314+ exists ( DataFlowCall call , int i |
1315+ isArgumentNode ( node1 , call , TPositionalParameterPosition ( i ) ) and
1316+ lambdaCall ( call , _, node2 .( PostUpdateNode ) .getPreUpdateNode ( ) ) and
1317+ c .( FunctionCallArgumentContent ) .getPosition ( ) = i
1318+ )
1319+ or
12761320 VariableCapture:: storeStep ( node1 , c , node2 )
12771321 }
12781322
@@ -1615,6 +1659,10 @@ private module Cached {
16151659 TStructFieldContent ( Struct s , string field ) {
16161660 field = s .getFieldList ( ) .( RecordFieldList ) .getAField ( ) .getName ( ) .getText ( )
16171661 } or
1662+ TFunctionCallReturnContent ( ) or
1663+ TFunctionCallArgumentContent ( int pos ) {
1664+ pos in [ 0 .. any ( CallExpr c ) .getArgList ( ) .getNumberOfArgs ( ) - 1 ]
1665+ } or
16181666 TCapturedVariableContent ( VariableCapture:: CapturedVariable v ) or
16191667 TReferenceContent ( )
16201668
0 commit comments