This repository has been archived by the owner on Jan 5, 2023. It is now read-only.
Refine potential targets for method call through interface #219
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When faced with a call
x.m()
where the type ofx
is some interfaceI
,getACallee()
does the conservative thing and resolves the call to all overriding definitions ofm
.For the data-flow analysis, we try a bit harder: the
viableCallee
predicate checks whether it can by local reasoning determine a concrete (non-interface) type forx
, or perhaps a set of such types, and then resolvesm
on those.This PR adds an orthogonal refinement: even if we can't determine a concrete type for
x
, we can still require that the overriding definition ofm
we select must belong to a type that implementsI
. This isn't a trivial condition, sinceI
might inheritm
from another interfaceJ
, and this way we might be able to exclude some definitions ofm
in types that implementJ
but notI
.Evaluation (internal link) shows no performance change and one alert change. The alert in question had 56 paths; I didn't check all of them, but the ones I did inspect all had a spurious call step of the kind described above in them, so I'm inclined to believe that this was a false positive that is now fixed.
It also fixes a wrong call step observed by @owen-mc, but it does not, by itself, fix the false positive that gave rise to. There is another imprecision involved, which I will fix in a separate PR.
Commit-by-commit review is encouraged. The first commit is not logically related to the rest of the PR, but it's useful for debugging and I've wanted to add it for a while.