@@ -7,15 +7,33 @@ private import DataFlowDispatch
77 * A data flow node that occurs as the argument of a call and is passed as-is
88 * to the callable. Instance arguments (`this` pointer) are also included.
99 */
10- class ArgumentNode extends InstructionNode {
10+ class ArgumentNode extends Node {
1111 ArgumentNode ( ) {
12- exists ( CallInstruction call |
13- instr = call .getAnArgument ( )
14- or
15- instr .( ReadSideEffectInstruction ) .getPrimaryInstruction ( ) = call
16- )
12+ // To avoid making this class abstract, we enumerate its values here.
13+ this instanceof PrimaryArgumentNode or
14+ this instanceof SideEffectArgumentNode
15+ }
16+
17+ /**
18+ * Holds if this argument occurs at the given position in the given call.
19+ * The instance argument is considered to have index `-1`.
20+ */
21+ predicate argumentOf ( DataFlowCall call , int pos ) {
22+ this .( PrimaryArgumentNode ) .argumentOf ( call , pos ) or
23+ this .( SideEffectArgumentNode ) .argumentOf ( call , pos )
1724 }
1825
26+ /** Gets the call in which this node is an argument. */
27+ DataFlowCall getCall ( ) { this .argumentOf ( result , _) }
28+ }
29+
30+ /**
31+ * A data flow node that occurs as the argument to a call, or an
32+ * implicit `this` pointer argument.
33+ */
34+ private class PrimaryArgumentNode extends InstructionNode {
35+ PrimaryArgumentNode ( ) { exists ( CallInstruction call | instr = call .getAnArgument ( ) ) }
36+
1937 /**
2038 * Holds if this argument occurs at the given position in the given call.
2139 * The instance argument is considered to have index `-1`.
@@ -24,16 +42,33 @@ class ArgumentNode extends InstructionNode {
2442 instr = call .getPositionalArgument ( pos )
2543 or
2644 instr = call .getThisArgument ( ) and pos = - 1
27- or
28- exists ( ReadSideEffectInstruction read |
29- read = instr and
45+ }
46+ }
47+
48+ /**
49+ * A data flow node representing the read side effect of a call on a
50+ * specific parameter.
51+ */
52+ private class SideEffectArgumentNode extends OperandNode {
53+ override SideEffectOperand op ;
54+ ReadSideEffectInstruction read ;
55+
56+ SideEffectArgumentNode ( ) {
57+ exists ( CallInstruction call |
3058 read .getPrimaryInstruction ( ) = call and
31- pos = getArgumentPosOfSideEffect ( read .getIndex ( ) )
59+ op = read .getSideEffectOperand ( )
3260 )
3361 }
3462
35- /** Gets the call in which this node is an argument. */
36- DataFlowCall getCall ( ) { this .argumentOf ( result , _) }
63+ /**
64+ * Holds if this argument occurs at the given position in the given call.
65+ * See `getArgumentPosOfSideEffect` for a describing of how read side effects
66+ * are assigned an argument position.
67+ */
68+ predicate argumentOf ( DataFlowCall call , int pos ) {
69+ read .getPrimaryInstruction ( ) = call and
70+ pos = getArgumentPosOfSideEffect ( read .getIndex ( ) )
71+ }
3772}
3873
3974private newtype TReturnKind =
0 commit comments