Skip to content
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

Merged
merged 4 commits into from
Jun 22, 2020

Conversation

max-schaefer
Copy link
Contributor

When faced with a call x.m() where the type of x is some interface I, getACallee() does the conservative thing and resolves the call to all overriding definitions of m.

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 for x, or perhaps a set of such types, and then resolves m 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 of m we select must belong to a type that implements I. This isn't a trivial condition, since I might inherit m from another interface J, and this way we might be able to exclude some definitions of m in types that implement J but not I.

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.

Max Schaefer added 4 commits June 22, 2020 09:22
The call target must belong to the method set of a type that implements the interface type of the method call receiver, if any.

For example, assume `h` has type `hash.Hash`, then `h.Write(...)` should only be resolved to implementations of `Write` in types implementing `hash.Hash`, not arbitrary other `Writer`s.
@max-schaefer
Copy link
Contributor Author

CodeQL analysis will fail eventually, but that's unrelated to this PR (cf #220), so I'll just go ahead and merge.

@max-schaefer max-schaefer merged commit d8374ad into github:master Jun 22, 2020
ceh pushed a commit to ceh-forks/codeql-go that referenced this pull request Jul 22, 2020
Teach extractor about CodeQL environment variables.
@max-schaefer max-schaefer deleted the refine-virtual-dispatch branch August 28, 2020 06:35
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants