@@ -62,17 +62,42 @@ private module Dispatch {
62
62
cached
63
63
Method viableImpl_v3 ( MethodAccess ma ) { result = DispatchFlow:: viableImpl_out ( ma ) }
64
64
65
- private predicate qualType ( VirtualMethodAccess ma , RefType t , boolean exact ) {
66
- exprTypeFlow ( ma .getQualifier ( ) , t , exact )
67
- }
68
-
69
65
/**
70
66
* INTERNAL: Use `viableImpl` instead.
71
67
*
72
68
* Gets a viable implementation of the method called in the given method access.
73
69
*/
74
70
cached
75
71
Method viableImpl_v2 ( MethodAccess ma ) {
72
+ result = viableImpl_v2_cand ( pragma [ only_bind_into ] ( ma ) ) and
73
+ exists ( Method def , RefType t , boolean exact |
74
+ qualUnionType ( pragma [ only_bind_into ] ( ma ) , pragma [ only_bind_into ] ( t ) ,
75
+ pragma [ only_bind_into ] ( exact ) ) and
76
+ def = ma .getMethod ( ) .getSourceDeclaration ( )
77
+ |
78
+ exact = true and result = exactMethodImpl ( def , t .getSourceDeclaration ( ) )
79
+ or
80
+ exact = false and
81
+ exists ( RefType t2 |
82
+ result = viableMethodImpl ( def , t .getSourceDeclaration ( ) , t2 ) and
83
+ not Unification_v2:: failsUnification ( t , t2 )
84
+ )
85
+ )
86
+ or
87
+ result = viableImpl_v2_cand ( ma ) and
88
+ not qualUnionType ( ma , _, _)
89
+ }
90
+
91
+ private predicate qualUnionType ( VirtualMethodAccess ma , RefType t , boolean exact ) {
92
+ exprUnionTypeFlow ( ma .getQualifier ( ) , t , exact )
93
+ }
94
+
95
+ private predicate unificationTargetLeft_v2 ( ParameterizedType t1 ) { qualUnionType ( _, t1 , _) }
96
+
97
+ private module Unification_v2 =
98
+ MkUnification< unificationTargetLeft_v2 / 1 , unificationTargetRight / 1 > ;
99
+
100
+ private Method viableImpl_v2_cand ( MethodAccess ma ) {
76
101
result = viableImpl_v1 ( ma ) and
77
102
(
78
103
exists ( Method def , RefType t , boolean exact |
@@ -84,18 +109,22 @@ private module Dispatch {
84
109
exact = false and
85
110
exists ( RefType t2 |
86
111
result = viableMethodImpl ( def , t .getSourceDeclaration ( ) , t2 ) and
87
- not Unification_v2 :: failsUnification ( t , t2 )
112
+ not Unification_v2_cand :: failsUnification ( t , t2 )
88
113
)
89
114
)
90
115
or
91
116
not qualType ( ma , _, _)
92
117
)
93
118
}
94
119
95
- private predicate unificationTargetLeft_v2 ( ParameterizedType t1 ) { qualType ( _, t1 , _) }
120
+ private predicate qualType ( VirtualMethodAccess ma , RefType t , boolean exact ) {
121
+ exprTypeFlow ( ma .getQualifier ( ) , t , exact )
122
+ }
123
+
124
+ private predicate unificationTargetLeft_v2_cand ( ParameterizedType t1 ) { qualType ( _, t1 , _) }
96
125
97
- private module Unification_v2 =
98
- MkUnification< unificationTargetLeft_v2 / 1 , unificationTargetRight / 1 > ;
126
+ private module Unification_v2_cand =
127
+ MkUnification< unificationTargetLeft_v2_cand / 1 , unificationTargetRight / 1 > ;
99
128
100
129
/**
101
130
* INTERNAL: Use `viableImpl` instead.
@@ -161,9 +190,8 @@ private module Dispatch {
161
190
}
162
191
163
192
private predicate hasQualifierType ( VirtualMethodAccess ma , RefType t , boolean exact ) {
164
- exists ( Expr src | src = variableTrack ( ma .getQualifier ( ) ) |
165
- // If we have a qualifier, then we track it through variable assignments
166
- // and take the type of the assigned value.
193
+ exists ( Expr src | src = ma .getQualifier ( ) |
194
+ // If we have a qualifier, then we take its type.
167
195
exists ( RefType srctype | srctype = getPreciseType ( src ) |
168
196
exists ( BoundedType bd | bd = srctype |
169
197
t = bd .getAnUltimateUpperBoundType ( )
@@ -224,34 +252,7 @@ private module Dispatch {
224
252
225
253
import Dispatch
226
254
227
- private Expr variableTrackStep ( Expr use ) {
228
- exists ( Variable v |
229
- pragma [ only_bind_out ] ( use ) = v .getAnAccess ( ) and
230
- use .getType ( ) instanceof RefType and
231
- not result instanceof NullLiteral and
232
- not v .( LocalVariableDecl ) .getDeclExpr ( ) .hasImplicitInit ( )
233
- |
234
- not v instanceof Parameter and
235
- result = v .getAnAssignedValue ( )
236
- or
237
- exists ( Parameter p | p = v and p .getCallable ( ) .isPrivate ( ) |
238
- result = p .getAnAssignedValue ( ) or
239
- result = p .getAnArgument ( )
240
- )
241
- )
242
- }
243
-
244
- private Expr variableTrackPath ( Expr use ) {
245
- result = variableTrackStep * ( use ) and
246
- not exists ( variableTrackStep ( result ) )
247
- }
248
-
249
255
/**
250
- * Gets an expression by tracking `use` backwards through variable assignments .
256
+ * DEPRECATED: Use `TypeFlow` instead .
251
257
*/
252
- pragma [ inline]
253
- Expr variableTrack ( Expr use ) {
254
- result = variableTrackPath ( use )
255
- or
256
- not exists ( variableTrackPath ( use ) ) and result = use
257
- }
258
+ deprecated Expr variableTrack ( Expr use ) { result = use }
0 commit comments