go/callgraph/vta: fix call site computation bug

VTA was not considering call edges, while setting up interprocedural
type flow, that involve synthetic functions. This can lead to missed
call graph edges. This CL makes sure all callees given by the initial
callgraph are considered.

Change-Id: I61070a80af60c05493b6bece354d768ba18a9f3e
Reviewed-on: https://go-review.googlesource.com/c/tools/+/348729
Run-TryBot: Zvonimir Pavlinovic <zpavlinovic@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Tim King <taking@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Zvonimir Pavlinovic <zpavlinovic@google.com>
diff --git a/go/callgraph/vta/testdata/callgraph_fields.go b/go/callgraph/vta/testdata/callgraph_fields.go
new file mode 100644
index 0000000..00aa649
--- /dev/null
+++ b/go/callgraph/vta/testdata/callgraph_fields.go
@@ -0,0 +1,91 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// go:build ignore
+
+package testdata
+
+type I interface {
+	Foo()
+}
+
+type A struct {
+	I
+}
+
+func (a *A) Do() {
+	a.Foo()
+}
+
+type B struct{}
+
+func (b B) Foo() {}
+
+func NewA(b B) *A {
+	return &A{I: &b}
+}
+
+func Baz(b B) {
+	a := NewA(b)
+	a.Do()
+}
+
+// Relevant SSA:
+// func Baz(b B):
+//        t0 = local B (b)
+//        *t0 = b
+//        t1 = *t0
+//        t2 = NewA(t1)
+//        t3 = (*A).Do(t2)
+//        return
+//
+// func (a *A) Do():
+//        t0 = &a.I [#0]
+//        t1 = *t0
+//        t2 = invoke t1.Foo()
+//        return
+//
+// Name: (testdata.A).Foo
+// Synthetic: wrapper for func (testdata.I).Foo()
+// Location: testdata/callgraph_fields.go:10:2
+// func (arg0 testdata.A) Foo():
+//	  t0 = local testdata.A ()
+//        *t0 = arg0
+//        t1 = &t0.I [#0]
+//        t2 = *t1
+//        t3 = invoke t2.Foo()
+//        return
+//
+// Name: (*testdata.A).Foo
+// Synthetic: wrapper for func (testdata.I).Foo()
+// Location: testdata/callgraph_fields.go:10:2
+// func (arg0 *testdata.A) Foo():
+//        t0 = &arg0.I [#0]
+//        t1 = *t0
+//        t2 = invoke t1.Foo()
+//        return
+//
+// func (b B) Foo():
+//        t0 = local B (b)
+//        *t0 = b
+//        return
+//
+// func (b *testdata.B) Foo():
+//        t0 = ssa:wrapnilchk(b, "testdata.B":string, "Foo":string)
+//        t1 = *t0
+//        t2 = (testdata.B).Foo(t1)
+//        return
+//
+// func NewA(b B) *A:
+//        t0 = new B (b)
+//        *t0 = b
+//        t1 = new A (complit)
+//        t2 = &t1.I [#0]
+//        t3 = make I <- *B (t0)
+//        *t2 = t3
+//        return t1
+
+// WANT:
+// Baz: (*A).Do(t2) -> A.Do; NewA(t1) -> NewA
+// A.Do: invoke t1.Foo() -> B.Foo
diff --git a/go/callgraph/vta/testdata/dynamic_calls.go b/go/callgraph/vta/testdata/dynamic_calls.go
index fa4270b..b8c14b2 100644
--- a/go/callgraph/vta/testdata/dynamic_calls.go
+++ b/go/callgraph/vta/testdata/dynamic_calls.go
@@ -37,7 +37,13 @@
 //   t4 = h()
 //   return t4
 
+// Local(t2) has seemingly duplicates of successors. This
+// happens in stringification of type propagation graph.
+// Due to CHA, we analyze A.foo and *A.foo as well as B.foo
+// and *B.foo, which have similar bodies and hence similar
+// type flow that gets merged together during stringification.
+
 // WANT:
-// Local(t2) -> Local(ai), Local(bi)
+// Local(t2) -> Local(ai), Local(ai), Local(bi), Local(bi)
 // Constant(testdata.I) -> Local(t4)
 // Local(t1) -> Local(t2)
diff --git a/go/callgraph/vta/utils.go b/go/callgraph/vta/utils.go
index 69361ab..cabc93b 100644
--- a/go/callgraph/vta/utils.go
+++ b/go/callgraph/vta/utils.go
@@ -114,10 +114,8 @@
 	}
 
 	for _, edge := range node.Out {
-		callee := edge.Callee.Func
-		// Skip synthetic functions wrapped around source functions.
-		if edge.Site == c && callee.Synthetic == "" {
-			matches = append(matches, callee)
+		if edge.Site == c {
+			matches = append(matches, edge.Callee.Func)
 		}
 	}
 	return matches
diff --git a/go/callgraph/vta/vta_test.go b/go/callgraph/vta/vta_test.go
index 87b27cb..b0d2de7 100644
--- a/go/callgraph/vta/vta_test.go
+++ b/go/callgraph/vta/vta_test.go
@@ -19,6 +19,7 @@
 		"testdata/callgraph_interfaces.go",
 		"testdata/callgraph_pointers.go",
 		"testdata/callgraph_collections.go",
+		"testdata/callgraph_fields.go",
 	} {
 		t.Run(file, func(t *testing.T) {
 			prog, want, err := testProg(file)