@@ -72,6 +72,7 @@ private module Internal {
7272 not mc .isLateBound ( )
7373 } or
7474 TDispatchAccessorCall ( AccessorCall ac ) or
75+ TDispatchOperatorCall ( OperatorCall oc ) { not oc .isLateBound ( ) } or
7576 TDispatchReflectionCall ( MethodCall mc , string name , Expr object , Expr qualifier , int args ) {
7677 isReflectionCall ( mc , name , object , qualifier , args )
7778 } or
@@ -90,8 +91,6 @@ private module Internal {
9091 or
9192 c instanceof ConstructorInitializer
9293 or
93- c = any ( OperatorCall oc | not oc .isLateBound ( ) )
94- or
9594 c instanceof LocalFunctionCall
9695 }
9796
@@ -113,12 +112,12 @@ private module Internal {
113112 }
114113
115114 cached
116- predicate mayBenefitFromCallContext ( DispatchMethodOrAccessorCall dc ) {
115+ predicate mayBenefitFromCallContext ( DispatchOverridableCall dc ) {
117116 dc .mayBenefitFromCallContext ( _, _)
118117 }
119118
120119 cached
121- RuntimeCallable getADynamicTargetInCallContext ( DispatchMethodOrAccessorCall dc , DispatchCall ctx ) {
120+ RuntimeCallable getADynamicTargetInCallContext ( DispatchOverridableCall dc , DispatchCall ctx ) {
122121 result = dc .getADynamicTargetInCallContext ( ctx )
123122 }
124123 }
@@ -214,6 +213,9 @@ private module Internal {
214213 /** Gets the qualifier of this call, if any. */
215214 abstract Expr getQualifier ( ) ;
216215
216+ /** Gets the qualifier or another expression that can be used for typing purposes, if any. */
217+ Expr getSyntheticQualifier ( ) { result = this .getQualifier ( ) }
218+
217219 /** Gets a static (compile-time) target of this call. */
218220 abstract Callable getAStaticTarget ( ) ;
219221
@@ -241,7 +243,7 @@ private module Internal {
241243 private predicate hasCallable0 ( Gvn:: GvnType t , OverridableCallable c , OverridableCallable source ) {
242244 c .getUnboundDeclaration ( ) = source and
243245 any ( ValueOrRefType t0 | Gvn:: getGlobalValueNumber ( t0 ) = t ) .hasCallable ( c ) and
244- source = any ( DispatchMethodOrAccessorCall call ) .getAStaticTargetExt ( )
246+ source = any ( DispatchOverridableCall call ) .getAStaticTargetExt ( )
245247 }
246248
247249 pragma [ noinline]
@@ -250,7 +252,7 @@ private module Internal {
250252 hasOverrider ( t , c )
251253 }
252254
253- abstract private class DispatchMethodOrAccessorCall extends DispatchCallImpl {
255+ abstract private class DispatchOverridableCall extends DispatchCallImpl {
254256 pragma [ noinline]
255257 OverridableCallable getAStaticTargetExt ( ) {
256258 exists ( OverridableCallable target | this .getAStaticTarget ( ) = target |
@@ -261,13 +263,15 @@ private module Internal {
261263 }
262264
263265 pragma [ nomagic]
264- predicate hasQualifierTypeInherited ( Type t ) { t = getAPossibleType ( this .getQualifier ( ) , _) }
266+ predicate hasQualifierTypeInherited ( Type t ) {
267+ t = getAPossibleType ( this .getSyntheticQualifier ( ) , _)
268+ }
265269
266270 pragma [ noinline]
267271 private predicate hasSubsumedQualifierType ( Gvn:: GvnType t ) {
268272 hasOverrider ( t , _) and
269273 exists ( Type t0 |
270- t0 = getAPossibleType ( this .getQualifier ( ) , false ) and
274+ t0 = getAPossibleType ( this .getSyntheticQualifier ( ) , false ) and
271275 not t0 instanceof TypeParameter
272276 |
273277 t = Gvn:: getGlobalValueNumber ( t0 )
@@ -280,12 +284,12 @@ private module Internal {
280284 private predicate hasConstrainedTypeParameterQualifierType (
281285 Unification:: ConstrainedTypeParameter tp
282286 ) {
283- tp = getAPossibleType ( this .getQualifier ( ) , false )
287+ tp = getAPossibleType ( this .getSyntheticQualifier ( ) , false )
284288 }
285289
286290 pragma [ noinline]
287291 private predicate hasUnconstrainedTypeParameterQualifierType ( ) {
288- getAPossibleType ( this .getQualifier ( ) , false ) instanceof
292+ getAPossibleType ( this .getSyntheticQualifier ( ) , false ) instanceof
289293 Unification:: UnconstrainedTypeParameter
290294 }
291295
@@ -313,7 +317,7 @@ private module Internal {
313317 |
314318 pdef = def .getDefinition ( ) and
315319 p = pdef .getTarget ( ) and
316- this .getQualifier ( ) = def .getARead ( ) and
320+ this .getSyntheticQualifier ( ) = def .getARead ( ) and
317321 p .getPosition ( ) = i and
318322 c .getAParameter ( ) = p and
319323 not p .isParams ( )
@@ -446,7 +450,7 @@ private module Internal {
446450
447451 pragma [ noinline]
448452 NonConstructedOverridableCallable getAViableOverrider0 ( ) {
449- getAPossibleType ( this .getQualifier ( ) , false ) instanceof TypeParameter and
453+ getAPossibleType ( this .getSyntheticQualifier ( ) , false ) instanceof TypeParameter and
450454 result .getAConstructingCallableOrSelf ( ) = this .getAStaticTargetExt ( )
451455 }
452456
@@ -497,9 +501,10 @@ private module Internal {
497501 result = c .getAnOverrider ( t )
498502 )
499503 or
500- exists ( NonConstructedOverridableCallable c |
504+ exists ( NonConstructedOverridableCallable c , NonConstructedOverridableCallable mid |
501505 c = this .getAViableOverrider0 ( ) and
502- result = c .getAnOverrider ( _)
506+ c = mid .getUnboundDeclaration ( ) and
507+ result = mid .getAnOverrider ( _)
503508 |
504509 this .hasUnconstrainedTypeParameterQualifierType ( )
505510 or
@@ -774,7 +779,7 @@ private module Internal {
774779 * The set of viable targets is determined by taking virtual dispatch
775780 * into account.
776781 */
777- private class DispatchMethodCall extends DispatchMethodOrAccessorCall , TDispatchMethodCall {
782+ private class DispatchMethodCall extends DispatchOverridableCall , TDispatchMethodCall {
778783 override MethodCall getCall ( ) { this = TDispatchMethodCall ( result ) }
779784
780785 override Expr getArgument ( int i ) {
@@ -789,13 +794,35 @@ private module Internal {
789794 override Method getAStaticTarget ( ) { result = this .getCall ( ) .getTarget ( ) }
790795 }
791796
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+
792819 /**
793820 * A call to an accessor.
794821 *
795822 * The set of viable targets is determined by taking virtual dispatch
796823 * into account.
797824 */
798- private class DispatchAccessorCall extends DispatchMethodOrAccessorCall , TDispatchAccessorCall {
825+ private class DispatchAccessorCall extends DispatchOverridableCall , TDispatchAccessorCall {
799826 override AccessorCall getCall ( ) { this = TDispatchAccessorCall ( result ) }
800827
801828 override Expr getArgument ( int i ) { result = this .getCall ( ) .getArgument ( i ) }
@@ -805,7 +832,7 @@ private module Internal {
805832 override Accessor getAStaticTarget ( ) { result = this .getCall ( ) .getTarget ( ) }
806833
807834 override RuntimeAccessor getADynamicTarget ( ) {
808- result = DispatchMethodOrAccessorCall .super .getADynamicTarget ( ) and
835+ result = DispatchOverridableCall .super .getADynamicTarget ( ) and
809836 // Calls to accessors may have `dynamic` expression arguments,
810837 // so we need to check that the types match
811838 forall ( Type argumentType , int i | this .hasDynamicArg ( i , argumentType ) |
@@ -829,7 +856,7 @@ private module Internal {
829856
830857 pragma [ nomagic]
831858 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 ) |
833860 qualifierType = t and
834861 not t instanceof TypeParameter
835862 or
0 commit comments