@@ -2,17 +2,25 @@ private import java
2
2
private import DataFlowPrivate
3
3
private import DataFlowUtil
4
4
private import semmle.code.java.dataflow.InstanceAccess
5
- import semmle.code.java.dispatch.VirtualDispatch
5
+ private import semmle.code.java.dataflow.FlowSummary
6
+ private import semmle.code.java.dispatch.VirtualDispatch as VirtualDispatch
6
7
7
8
private module DispatchImpl {
9
+ /** Gets a viable implementation of the target of the given `Call`. */
10
+ Callable viableCallable ( Call c ) {
11
+ result = VirtualDispatch:: viableCallable ( c )
12
+ or
13
+ result .( SummarizedCallable ) = c .getCallee ( ) .getSourceDeclaration ( )
14
+ }
15
+
8
16
/**
9
17
* Holds if the set of viable implementations that can be called by `ma`
10
18
* might be improved by knowing the call context. This is the case if the
11
19
* qualifier is the `i`th parameter of the enclosing callable `c`.
12
20
*/
13
21
private predicate mayBenefitFromCallContext ( MethodAccess ma , Callable c , int i ) {
14
22
exists ( Parameter p |
15
- 2 <= strictcount ( viableImpl ( ma ) ) and
23
+ 2 <= strictcount ( VirtualDispatch :: viableImpl ( ma ) ) and
16
24
ma .getQualifier ( ) .( VarAccess ) .getVariable ( ) = p and
17
25
p .getPosition ( ) = i and
18
26
c .getAParameter ( ) = p and
@@ -21,7 +29,7 @@ private module DispatchImpl {
21
29
)
22
30
or
23
31
exists ( OwnInstanceAccess ia |
24
- 2 <= strictcount ( viableImpl ( ma ) ) and
32
+ 2 <= strictcount ( VirtualDispatch :: viableImpl ( ma ) ) and
25
33
( ia .isExplicit ( ma .getQualifier ( ) ) or ia .isImplicitMethodQualifier ( ma ) ) and
26
34
i = - 1 and
27
35
c = ma .getEnclosingCallable ( )
@@ -60,7 +68,7 @@ private module DispatchImpl {
60
68
or
61
69
ctx .getArgument ( i ) = arg
62
70
|
63
- src = variableTrack ( arg ) and
71
+ src = VirtualDispatch :: variableTrack ( arg ) and
64
72
srctype = getPreciseType ( src ) and
65
73
if src instanceof ClassInstanceExpr then exact = true else exact = false
66
74
)
@@ -93,18 +101,18 @@ private module DispatchImpl {
93
101
* restricted to those `ma`s for which a context might make a difference.
94
102
*/
95
103
Method viableImplInCallContext ( MethodAccess ma , Call ctx ) {
96
- result = viableImpl ( ma ) and
104
+ result = VirtualDispatch :: viableImpl ( ma ) and
97
105
exists ( int i , Callable c , Method def , RefType t , boolean exact |
98
106
mayBenefitFromCallContext ( ma , c , i ) and
99
107
c = viableCallable ( ctx ) and
100
108
contextArgHasType ( ctx , i , t , exact ) and
101
109
ma .getMethod ( ) = def
102
110
|
103
- exact = true and result = exactMethodImpl ( def , t .getSourceDeclaration ( ) )
111
+ exact = true and result = VirtualDispatch :: exactMethodImpl ( def , t .getSourceDeclaration ( ) )
104
112
or
105
113
exact = false and
106
114
exists ( RefType t2 |
107
- result = viableMethodImpl ( def , t .getSourceDeclaration ( ) , t2 ) and
115
+ result = VirtualDispatch :: viableMethodImpl ( def , t .getSourceDeclaration ( ) , t2 ) and
108
116
not failsUnification ( t , t2 )
109
117
)
110
118
)
@@ -117,7 +125,7 @@ private module DispatchImpl {
117
125
118
126
pragma [ noinline]
119
127
private predicate unificationTargetRight ( ParameterizedType t2 , GenericType g ) {
120
- exists ( viableMethodImpl ( _, _, t2 ) ) and t2 .getGenericType ( ) = g
128
+ exists ( VirtualDispatch :: viableMethodImpl ( _, _, t2 ) ) and t2 .getGenericType ( ) = g
121
129
}
122
130
123
131
private predicate unificationTargets ( Type t1 , Type t2 ) {
0 commit comments