@@ -608,6 +608,16 @@ private module ParameterNodes {
608608}
609609import ParameterNodes
610610
611+ /** A data flow node that represents a call argument. */
612+ abstract class ArgumentNode extends Node {
613+ /** Holds if this argument occurs at the given position in the given call. */
614+ cached
615+ abstract predicate argumentOf ( DataFlowCall call , int pos ) ;
616+
617+ /** Gets the call in which this node is an argument. */
618+ final DataFlowCall getCall ( ) { this .argumentOf ( result , _) }
619+ }
620+
611621private module ArgumentNodes {
612622 class DelegateArgumentConfiguration extends ControlFlowReachabilityConfiguration {
613623 DelegateArgumentConfiguration ( ) { this = "DelegateArgumentConfiguration" }
@@ -625,9 +635,9 @@ private module ArgumentNodes {
625635 }
626636
627637 /**
628- * Holds if `arg` is an argument of the call `call` , which resolves to a
629- * library callable that is known to forward `arg` into the `i`th parameter
630- * of a supplied delegate `delegate`.
638+ * Holds if `arg` is an argument of a call, which resolves to a library callable
639+ * that is known to forward `arg` into the `i`th parameter of a supplied
640+ * delegate `delegate`.
631641 *
632642 * For example, in
633643 *
@@ -638,9 +648,9 @@ private module ArgumentNodes {
638648 * `arg = x`, `i = 0`, `call = x.Select(Foo)`, and `delegate = Foo`.
639649 */
640650 private predicate flowIntoCallableLibraryCall (
641- DataFlowCall call , Node arg , ImplicitDelegateDataFlowCall delegate , int i
651+ ExplicitArgumentNode arg , ImplicitDelegateDataFlowCall delegate , int i
642652 ) {
643- exists ( int j , boolean preservesValue |
653+ exists ( DataFlowCall call , int j , boolean preservesValue |
644654 preservesValue = true and i = j
645655 or
646656 preservesValue = false and i = j + delegate .getNumberOfDelegateParameters ( )
@@ -678,43 +688,34 @@ private module ArgumentNodes {
678688 }
679689 }
680690
681- /** A data flow node that represents a call argument. */
682- abstract class ArgumentNode extends Node {
683- /** Holds if this argument occurs at the given position in the given call. */
684- cached
685- abstract predicate argumentOf ( DataFlowCall call , int pos ) ;
686-
687- /** Gets the call in which this node is an argument. */
688- final DataFlowCall getCall ( ) { this .argumentOf ( result , _) }
689- }
690-
691691 /** A data flow node that represents an explicit call argument. */
692692 private class ExplicitArgumentNode extends ArgumentNode {
693- private DataFlowCall c ;
694-
695- private int i ;
696-
697693 ExplicitArgumentNode ( ) {
698- exists ( ArgumentConfiguration x , Expr call , Argument arg |
699- arg = this .asExpr ( ) and
700- call = c .getExpr ( ) and
701- arg .isArgumentOf ( call , i ) and
702- x .hasExprPath ( _, this .getControlFlowNode ( ) , _, c .getControlFlowNode ( ) )
703- )
694+ this .asExpr ( ) instanceof Argument
704695 or
705- exists ( CIL:: Call call , CIL:: Expr arg |
706- arg = this .asExpr ( ) and
707- call = c .getExpr ( ) and
708- arg = call .getArgument ( i )
709- )
696+ this .asExpr ( ) = any ( CIL:: Call call ) .getAnArgument ( )
697+ or
698+ libraryFlowDelegateCallIn ( _, _, this .asExpr ( ) , _, _, _)
710699 or
711- flowIntoCallableLibraryCall ( _, this , c , i )
700+ this . ( ImplicitDelegateOutNode ) . isArgumentOf ( _, _ )
712701 }
713702
714703 override predicate argumentOf ( DataFlowCall call , int pos ) {
715704 Stages:: DataFlowStage:: forceCachingInSameStage ( ) and
716- call = c and
717- pos = i
705+ exists ( ArgumentConfiguration x , Expr c , Argument arg |
706+ arg = this .asExpr ( ) and
707+ c = call .getExpr ( ) and
708+ arg .isArgumentOf ( c , pos ) and
709+ x .hasExprPath ( _, this .getControlFlowNode ( ) , _, call .getControlFlowNode ( ) )
710+ )
711+ or
712+ exists ( CIL:: Call c , CIL:: Expr arg |
713+ arg = this .asExpr ( ) and
714+ c = call .getExpr ( ) and
715+ arg = c .getArgument ( pos )
716+ )
717+ or
718+ flowIntoCallableLibraryCall ( this , call , pos )
718719 }
719720 }
720721
@@ -849,13 +850,13 @@ private module ArgumentNodes {
849850}
850851import ArgumentNodes
851852
852- private module ReturnNodes {
853- /** A data flow node that represents a value returned by a callable. */
854- abstract class ReturnNode extends Node {
855- /** Gets the kind of this return node. */
856- abstract ReturnKind getKind ( ) ;
857- }
853+ /** A data flow node that represents a value returned by a callable. */
854+ abstract class ReturnNode extends Node {
855+ /** Gets the kind of this return node. */
856+ abstract ReturnKind getKind ( ) ;
857+ }
858858
859+ private module ReturnNodes {
859860 /**
860861 * A data flow node that represents an expression returned by a callable,
861862 * either using a (`yield`) `return` statement or an expression body (`=>`).
@@ -962,14 +963,14 @@ private module ReturnNodes {
962963}
963964import ReturnNodes
964965
965- private module OutNodes {
966- /** A data flow node that represents the output of a call. */
967- abstract class OutNode extends Node {
968- /** Gets the underlying call. */
969- cached
970- abstract DataFlowCall getCall ( ) ;
971- }
966+ /** A data flow node that represents the output of a call. */
967+ abstract class OutNode extends Node {
968+ /** Gets the underlying call. */
969+ cached
970+ abstract DataFlowCall getCall ( ) ;
971+ }
972972
973+ private module OutNodes {
973974 private DataFlowCall csharpCall ( Expr e , ControlFlow:: Node cfn ) {
974975 e = any ( DispatchCall dc | result = TNonDelegateCall ( cfn , dc ) ) .getCall ( ) or
975976 result = TExplicitDelegateCall ( cfn , e )
0 commit comments