@@ -72,6 +72,7 @@ private module Internal {
72
72
not mc .isLateBound ( )
73
73
} or
74
74
TDispatchAccessorCall ( AccessorCall ac ) or
75
+ TDispatchOperatorCall ( OperatorCall oc ) { not oc .isLateBound ( ) } or
75
76
TDispatchReflectionCall ( MethodCall mc , string name , Expr object , Expr qualifier , int args ) {
76
77
isReflectionCall ( mc , name , object , qualifier , args )
77
78
} or
@@ -90,8 +91,6 @@ private module Internal {
90
91
or
91
92
c instanceof ConstructorInitializer
92
93
or
93
- c = any ( OperatorCall oc | not oc .isLateBound ( ) )
94
- or
95
94
c instanceof LocalFunctionCall
96
95
}
97
96
@@ -113,12 +112,12 @@ private module Internal {
113
112
}
114
113
115
114
cached
116
- predicate mayBenefitFromCallContext ( DispatchMethodOrAccessorCall dc ) {
115
+ predicate mayBenefitFromCallContext ( DispatchOverridableCall dc ) {
117
116
dc .mayBenefitFromCallContext ( _, _)
118
117
}
119
118
120
119
cached
121
- RuntimeCallable getADynamicTargetInCallContext ( DispatchMethodOrAccessorCall dc , DispatchCall ctx ) {
120
+ RuntimeCallable getADynamicTargetInCallContext ( DispatchOverridableCall dc , DispatchCall ctx ) {
122
121
result = dc .getADynamicTargetInCallContext ( ctx )
123
122
}
124
123
}
@@ -214,6 +213,9 @@ private module Internal {
214
213
/** Gets the qualifier of this call, if any. */
215
214
abstract Expr getQualifier ( ) ;
216
215
216
+ /** Gets the qualifier or another expression that can be used for typing purposes, if any. */
217
+ Expr getSyntheticQualifier ( ) { result = this .getQualifier ( ) }
218
+
217
219
/** Gets a static (compile-time) target of this call. */
218
220
abstract Callable getAStaticTarget ( ) ;
219
221
@@ -241,7 +243,7 @@ private module Internal {
241
243
private predicate hasCallable0 ( Gvn:: GvnType t , OverridableCallable c , OverridableCallable source ) {
242
244
c .getUnboundDeclaration ( ) = source and
243
245
any ( ValueOrRefType t0 | Gvn:: getGlobalValueNumber ( t0 ) = t ) .hasCallable ( c ) and
244
- source = any ( DispatchMethodOrAccessorCall call ) .getAStaticTargetExt ( )
246
+ source = any ( DispatchOverridableCall call ) .getAStaticTargetExt ( )
245
247
}
246
248
247
249
pragma [ noinline]
@@ -250,7 +252,7 @@ private module Internal {
250
252
hasOverrider ( t , c )
251
253
}
252
254
253
- abstract private class DispatchMethodOrAccessorCall extends DispatchCallImpl {
255
+ abstract private class DispatchOverridableCall extends DispatchCallImpl {
254
256
pragma [ noinline]
255
257
OverridableCallable getAStaticTargetExt ( ) {
256
258
exists ( OverridableCallable target | this .getAStaticTarget ( ) = target |
@@ -261,13 +263,15 @@ private module Internal {
261
263
}
262
264
263
265
pragma [ nomagic]
264
- predicate hasQualifierTypeInherited ( Type t ) { t = getAPossibleType ( this .getQualifier ( ) , _) }
266
+ predicate hasQualifierTypeInherited ( Type t ) {
267
+ t = getAPossibleType ( this .getSyntheticQualifier ( ) , _)
268
+ }
265
269
266
270
pragma [ noinline]
267
271
private predicate hasSubsumedQualifierType ( Gvn:: GvnType t ) {
268
272
hasOverrider ( t , _) and
269
273
exists ( Type t0 |
270
- t0 = getAPossibleType ( this .getQualifier ( ) , false ) and
274
+ t0 = getAPossibleType ( this .getSyntheticQualifier ( ) , false ) and
271
275
not t0 instanceof TypeParameter
272
276
|
273
277
t = Gvn:: getGlobalValueNumber ( t0 )
@@ -280,12 +284,12 @@ private module Internal {
280
284
private predicate hasConstrainedTypeParameterQualifierType (
281
285
Unification:: ConstrainedTypeParameter tp
282
286
) {
283
- tp = getAPossibleType ( this .getQualifier ( ) , false )
287
+ tp = getAPossibleType ( this .getSyntheticQualifier ( ) , false )
284
288
}
285
289
286
290
pragma [ noinline]
287
291
private predicate hasUnconstrainedTypeParameterQualifierType ( ) {
288
- getAPossibleType ( this .getQualifier ( ) , false ) instanceof
292
+ getAPossibleType ( this .getSyntheticQualifier ( ) , false ) instanceof
289
293
Unification:: UnconstrainedTypeParameter
290
294
}
291
295
@@ -313,7 +317,7 @@ private module Internal {
313
317
|
314
318
pdef = def .getDefinition ( ) and
315
319
p = pdef .getTarget ( ) and
316
- this .getQualifier ( ) = def .getARead ( ) and
320
+ this .getSyntheticQualifier ( ) = def .getARead ( ) and
317
321
p .getPosition ( ) = i and
318
322
c .getAParameter ( ) = p and
319
323
not p .isParams ( )
@@ -446,7 +450,7 @@ private module Internal {
446
450
447
451
pragma [ noinline]
448
452
NonConstructedOverridableCallable getAViableOverrider0 ( ) {
449
- getAPossibleType ( this .getQualifier ( ) , false ) instanceof TypeParameter and
453
+ getAPossibleType ( this .getSyntheticQualifier ( ) , false ) instanceof TypeParameter and
450
454
result .getAConstructingCallableOrSelf ( ) = this .getAStaticTargetExt ( )
451
455
}
452
456
@@ -497,9 +501,10 @@ private module Internal {
497
501
result = c .getAnOverrider ( t )
498
502
)
499
503
or
500
- exists ( NonConstructedOverridableCallable c |
504
+ exists ( NonConstructedOverridableCallable c , NonConstructedOverridableCallable mid |
501
505
c = this .getAViableOverrider0 ( ) and
502
- result = c .getAnOverrider ( _)
506
+ c = mid .getUnboundDeclaration ( ) and
507
+ result = mid .getAnOverrider ( _)
503
508
|
504
509
this .hasUnconstrainedTypeParameterQualifierType ( )
505
510
or
@@ -774,7 +779,7 @@ private module Internal {
774
779
* The set of viable targets is determined by taking virtual dispatch
775
780
* into account.
776
781
*/
777
- private class DispatchMethodCall extends DispatchMethodOrAccessorCall , TDispatchMethodCall {
782
+ private class DispatchMethodCall extends DispatchOverridableCall , TDispatchMethodCall {
778
783
override MethodCall getCall ( ) { this = TDispatchMethodCall ( result ) }
779
784
780
785
override Expr getArgument ( int i ) {
@@ -789,13 +794,35 @@ private module Internal {
789
794
override Method getAStaticTarget ( ) { result = this .getCall ( ) .getTarget ( ) }
790
795
}
791
796
797
+ /**
798
+ * An ordinary operator call.
799
+ *
800
+ * The set of viable targets is determined by taking virtual dispatch
801
+ * into account.
802
+ */
803
+ private class DispatchOperatorCall extends DispatchOverridableCall , TDispatchOperatorCall {
804
+ override OperatorCall getCall ( ) { this = TDispatchOperatorCall ( result ) }
805
+
806
+ override Expr getArgument ( int i ) { result = this .getCall ( ) .getArgument ( i ) }
807
+
808
+ /**
809
+ * Gets the first child expression of an operator call, which can be considered the qualifier
810
+ * expression for the dispatch call use-cases.
811
+ */
812
+ override Expr getSyntheticQualifier ( ) { result = this .getCall ( ) .getChildExpr ( 0 ) }
813
+
814
+ override Expr getQualifier ( ) { none ( ) }
815
+
816
+ override Operator getAStaticTarget ( ) { result = this .getCall ( ) .getTarget ( ) }
817
+ }
818
+
792
819
/**
793
820
* A call to an accessor.
794
821
*
795
822
* The set of viable targets is determined by taking virtual dispatch
796
823
* into account.
797
824
*/
798
- private class DispatchAccessorCall extends DispatchMethodOrAccessorCall , TDispatchAccessorCall {
825
+ private class DispatchAccessorCall extends DispatchOverridableCall , TDispatchAccessorCall {
799
826
override AccessorCall getCall ( ) { this = TDispatchAccessorCall ( result ) }
800
827
801
828
override Expr getArgument ( int i ) { result = this .getCall ( ) .getArgument ( i ) }
@@ -805,7 +832,7 @@ private module Internal {
805
832
override Accessor getAStaticTarget ( ) { result = this .getCall ( ) .getTarget ( ) }
806
833
807
834
override RuntimeAccessor getADynamicTarget ( ) {
808
- result = DispatchMethodOrAccessorCall .super .getADynamicTarget ( ) and
835
+ result = DispatchOverridableCall .super .getADynamicTarget ( ) and
809
836
// Calls to accessors may have `dynamic` expression arguments,
810
837
// so we need to check that the types match
811
838
forall ( Type argumentType , int i | this .hasDynamicArg ( i , argumentType ) |
@@ -829,7 +856,7 @@ private module Internal {
829
856
830
857
pragma [ nomagic]
831
858
private predicate hasQualifierType ( Type qualifierType , boolean isExactType ) {
832
- exists ( Type t | t = getAPossibleType ( this .getQualifier ( ) , isExactType ) |
859
+ exists ( Type t | t = getAPossibleType ( this .getSyntheticQualifier ( ) , isExactType ) |
833
860
qualifierType = t and
834
861
not t instanceof TypeParameter
835
862
or
0 commit comments