@@ -32,25 +32,34 @@ DataFlow::Node callInput(CallInstruction call, FunctionInput input) {
32
32
}
33
33
34
34
/**
35
- * Gets the instruction that holds the `output` for `call`.
35
+ * Gets the node that represents the output of `call` with kind `output` at
36
+ * indirection index `indirectionIndex`.
36
37
*/
37
- Node callOutput ( CallInstruction call , FunctionOutput output ) {
38
+ private Node callOutputWithIndirectionIndex (
39
+ CallInstruction call , FunctionOutput output , int indirectionIndex
40
+ ) {
38
41
// The return value
39
42
simpleOutNode ( result , call ) and
40
- output .isReturnValue ( )
43
+ output .isReturnValue ( ) and
44
+ indirectionIndex = 0
41
45
or
42
46
// The side effect of a call on the value pointed to by an argument or qualifier
43
- exists ( int index , int indirectionIndex |
47
+ exists ( int index |
44
48
result .( IndirectArgumentOutNode ) .getArgumentIndex ( ) = index and
45
- result .( IndirectArgumentOutNode ) .getIndirectionIndex ( ) = indirectionIndex and
49
+ result .( IndirectArgumentOutNode ) .getIndirectionIndex ( ) = indirectionIndex - 1 and
46
50
result .( IndirectArgumentOutNode ) .getCallInstruction ( ) = call and
47
- output .isParameterDerefOrQualifierObject ( index , indirectionIndex )
51
+ output .isParameterDerefOrQualifierObject ( index , indirectionIndex - 1 )
48
52
)
49
53
or
50
- exists ( int ind |
51
- result = getIndirectReturnOutNode ( call , ind ) and
52
- output .isReturnValueDeref ( ind )
53
- )
54
+ result = getIndirectReturnOutNode ( call , indirectionIndex ) and
55
+ output .isReturnValueDeref ( indirectionIndex )
56
+ }
57
+
58
+ /**
59
+ * Gets the instruction that holds the `output` for `call`.
60
+ */
61
+ Node callOutput ( CallInstruction call , FunctionOutput output ) {
62
+ result = callOutputWithIndirectionIndex ( call , output , _)
54
63
}
55
64
56
65
DataFlow:: Node callInput ( CallInstruction call , FunctionInput input , int d ) {
@@ -76,19 +85,16 @@ private IndirectReturnOutNode getIndirectReturnOutNode(CallInstruction call, int
76
85
*/
77
86
bindingset [ d]
78
87
Node callOutput ( CallInstruction call , FunctionOutput output , int d ) {
79
- exists ( DataFlow:: Node n | n = callOutput ( call , output ) and d > 0 |
88
+ exists ( DataFlow:: Node n , int indirectionIndex |
89
+ n = callOutputWithIndirectionIndex ( call , output , indirectionIndex ) and d > 0
90
+ |
80
91
// The return value
81
- result = getIndirectReturnOutNode ( n . asInstruction ( ) , d )
92
+ result = callOutputWithIndirectionIndex ( call , output , indirectionIndex + d )
82
93
or
94
+ n = callOutputWithIndirectionIndex ( call , output , indirectionIndex ) and
83
95
// If there isn't an indirect out node for the call with indirection `d` then
84
96
// we conflate this with the underlying `CallInstruction`.
85
- not exists ( getIndirectReturnOutNode ( call , d ) ) and
97
+ not exists ( getIndirectReturnOutNode ( call , indirectionIndex + d ) ) and
86
98
n = result
87
- or
88
- // The side effect of a call on the value pointed to by an argument or qualifier
89
- exists ( Operand operand , int indirectionIndex |
90
- Ssa:: outNodeHasAddressAndIndex ( n , operand , indirectionIndex ) and
91
- Ssa:: outNodeHasAddressAndIndex ( result , operand , indirectionIndex + d )
92
- )
93
99
)
94
100
}
0 commit comments