mirror of https://github.com/golang/go.git
go/callgraph/vta: remove interprocedural flows for receiver objects
Suppose a call i.Foo(j) and suppose that the initial call graph resolves this call to just a.Foo(x). Here, i is an interface and a is concrete type. VTA then creates flows between j and x. However, it also tries to create flows between i and a. The latter flows are not needed. The flow from i to a will not be registered in the type flow graph as it does not make sense. The flow from a to i would bake in the information from the initial call graph which would defy the purpose of VTA. Note that the flow a -> i doesn't occur in practice as that flow is only created when a and i can alias. Change-Id: Ia4087651c72a14b94d83d07bb5e6d77603842362 Reviewed-on: https://go-review.googlesource.com/c/tools/+/416517 TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Zvonimir Pavlinovic <zpavlinovic@google.com> gopls-CI: kokoro <noreply+kokoro@google.com> Reviewed-by: Tim King <taking@google.com>
This commit is contained in:
parent
6e6f3131ec
commit
7c06b01db6
|
|
@ -586,14 +586,14 @@ func addArgumentFlows(b *builder, c ssa.CallInstruction, f *ssa.Function) {
|
|||
return
|
||||
}
|
||||
cc := c.Common()
|
||||
// When c is an unresolved method call (cc.Method != nil), cc.Value contains
|
||||
// the receiver object rather than cc.Args[0].
|
||||
if cc.Method != nil {
|
||||
b.addInFlowAliasEdges(b.nodeFromVal(f.Params[0]), b.nodeFromVal(cc.Value))
|
||||
}
|
||||
|
||||
offset := 0
|
||||
if cc.Method != nil {
|
||||
// We don't add interprocedural flows for receiver objects.
|
||||
// At a call site, the receiver object is interface while the
|
||||
// callee object is concrete. The flow from interface to
|
||||
// concrete type does not make sense. The flow other way around
|
||||
// would bake in information from the initial call graph.
|
||||
offset = 1
|
||||
}
|
||||
for i, v := range cc.Args {
|
||||
|
|
|
|||
Loading…
Reference in New Issue