@@ -9,6 +9,7 @@ private import DispatchFlow as DispatchFlow
99private import ObjFlow as ObjFlow
1010private import semmle.code.java.dataflow.internal.BaseSSA
1111private import semmle.code.java.controlflow.Guards
12+ private import semmle.code.java.dispatch.internal.Unification
1213
1314/**
1415 * A conservative analysis that returns a single method - if we can establish
@@ -91,69 +92,10 @@ private module Dispatch {
9192 )
9293 }
9394
94- private module Unification_v2 {
95- pragma [ noinline]
96- private predicate unificationTargetLeft ( ParameterizedType t1 , GenericType g ) {
97- qualType ( _, t1 , _) and t1 .getGenericType ( ) = g
98- }
95+ private predicate unificationTargetLeft_v2 ( ParameterizedType t1 ) { qualType ( _, t1 , _) }
9996
100- pragma [ noinline]
101- private predicate unificationTargetRight ( ParameterizedType t2 , GenericType g ) {
102- exists ( viableMethodImpl ( _, _, t2 ) ) and t2 .getGenericType ( ) = g
103- }
104-
105- private predicate unificationTargets ( Type t1 , Type t2 ) {
106- exists ( GenericType g | unificationTargetLeft ( t1 , g ) and unificationTargetRight ( t2 , g ) )
107- or
108- exists ( Array a1 , Array a2 |
109- unificationTargets ( a1 , a2 ) and
110- t1 = a1 .getComponentType ( ) and
111- t2 = a2 .getComponentType ( )
112- )
113- or
114- exists ( ParameterizedType pt1 , ParameterizedType pt2 , int pos |
115- unificationTargets ( pt1 , pt2 ) and
116- not pt1 .getSourceDeclaration ( ) != pt2 .getSourceDeclaration ( ) and
117- t1 = pt1 .getTypeArgument ( pos ) and
118- t2 = pt2 .getTypeArgument ( pos )
119- )
120- }
121-
122- pragma [ noinline]
123- private predicate typeArgsOfUnificationTargets (
124- ParameterizedType t1 , ParameterizedType t2 , int pos , RefType arg1 , RefType arg2
125- ) {
126- unificationTargets ( t1 , t2 ) and
127- arg1 = t1 .getTypeArgument ( pos ) and
128- arg2 = t2 .getTypeArgument ( pos )
129- }
130-
131- predicate failsUnification ( Type t1 , Type t2 ) {
132- unificationTargets ( t1 , t2 ) and
133- (
134- exists ( RefType arg1 , RefType arg2 |
135- typeArgsOfUnificationTargets ( t1 , t2 , _, arg1 , arg2 ) and
136- failsUnification ( arg1 , arg2 )
137- )
138- or
139- failsUnification ( t1 .( Array ) .getComponentType ( ) , t2 .( Array ) .getComponentType ( ) )
140- or
141- not (
142- t1 instanceof Array and t2 instanceof Array
143- or
144- t1 .( PrimitiveType ) = t2 .( PrimitiveType )
145- or
146- t1 .( Class ) .getSourceDeclaration ( ) = t2 .( Class ) .getSourceDeclaration ( )
147- or
148- t1 .( Interface ) .getSourceDeclaration ( ) = t2 .( Interface ) .getSourceDeclaration ( )
149- or
150- t1 instanceof BoundedType and t2 instanceof RefType
151- or
152- t1 instanceof RefType and t2 instanceof BoundedType
153- )
154- )
155- }
156- }
97+ private module Unification_v2 =
98+ MkUnification< unificationTargetLeft_v2 / 1 , unificationTargetRight / 1 > ;
15799
158100 /**
159101 * INTERNAL: Use `viableImpl` instead.
@@ -203,70 +145,15 @@ private module Dispatch {
203145 else result = source .getMethod ( ) .getSourceDeclaration ( )
204146 }
205147
206- private module Unification_v1 {
207- pragma [ noinline]
208- private predicate unificationTargetLeft ( ParameterizedType t1 , GenericType g ) {
209- hasQualifierType ( _, t1 , _) and t1 .getGenericType ( ) = g
210- }
148+ private predicate unificationTargetLeft_v1 ( ParameterizedType t1 ) { hasQualifierType ( _, t1 , _) }
211149
212- pragma [ noinline]
213- private predicate unificationTargetRight ( ParameterizedType t2 , GenericType g ) {
214- exists ( viableMethodImpl ( _, _, t2 ) ) and t2 .getGenericType ( ) = g
215- }
216-
217- private predicate unificationTargets ( Type t1 , Type t2 ) {
218- exists ( GenericType g | unificationTargetLeft ( t1 , g ) and unificationTargetRight ( t2 , g ) )
219- or
220- exists ( Array a1 , Array a2 |
221- unificationTargets ( a1 , a2 ) and
222- t1 = a1 .getComponentType ( ) and
223- t2 = a2 .getComponentType ( )
224- )
225- or
226- exists ( ParameterizedType pt1 , ParameterizedType pt2 , int pos |
227- unificationTargets ( pt1 , pt2 ) and
228- not pt1 .getSourceDeclaration ( ) != pt2 .getSourceDeclaration ( ) and
229- t1 = pt1 .getTypeArgument ( pos ) and
230- t2 = pt2 .getTypeArgument ( pos )
231- )
232- }
233-
234- pragma [ noinline]
235- private predicate typeArgsOfUnificationTargets (
236- ParameterizedType t1 , ParameterizedType t2 , int pos , RefType arg1 , RefType arg2
237- ) {
238- unificationTargets ( t1 , t2 ) and
239- arg1 = t1 .getTypeArgument ( pos ) and
240- arg2 = t2 .getTypeArgument ( pos )
241- }
242-
243- predicate failsUnification ( Type t1 , Type t2 ) {
244- unificationTargets ( t1 , t2 ) and
245- (
246- exists ( RefType arg1 , RefType arg2 |
247- typeArgsOfUnificationTargets ( t1 , t2 , _, arg1 , arg2 ) and
248- failsUnification ( arg1 , arg2 )
249- )
250- or
251- failsUnification ( t1 .( Array ) .getComponentType ( ) , t2 .( Array ) .getComponentType ( ) )
252- or
253- not (
254- t1 instanceof Array and t2 instanceof Array
255- or
256- t1 .( PrimitiveType ) = t2 .( PrimitiveType )
257- or
258- t1 .( Class ) .getSourceDeclaration ( ) = t2 .( Class ) .getSourceDeclaration ( )
259- or
260- t1 .( Interface ) .getSourceDeclaration ( ) = t2 .( Interface ) .getSourceDeclaration ( )
261- or
262- t1 instanceof BoundedType and t2 instanceof RefType
263- or
264- t1 instanceof RefType and t2 instanceof BoundedType
265- )
266- )
267- }
150+ private predicate unificationTargetRight ( ParameterizedType t2 ) {
151+ exists ( viableMethodImpl ( _, _, t2 ) )
268152 }
269153
154+ private module Unification_v1 =
155+ MkUnification< unificationTargetLeft_v1 / 1 , unificationTargetRight / 1 > ;
156+
270157 private RefType getPreciseType ( Expr e ) {
271158 result = e .( FunctionalExpr ) .getConstructedType ( )
272159 or
0 commit comments