go/callgraph: keep instantiations in DeleteSyntheticNodes

DeleteSyntheticNodes currently removes instantiations of generics from
the call graph. This function is intended to remove synthetic functions
that don't have a counterpart in the source code. Instantiations of
generics do not fit that bill. This also caused problems in govulncheck
where a function call to instantiation was missing from a call stack.

The fix is to keep instantiations and improved the documentation of
DeleteSyntheticNodes.

Change-Id: I32392b7495a8c1a5f6b26f795d46c8f184983e67
Reviewed-on: https://go-review.googlesource.com/c/tools/+/575095
Reviewed-by: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Zvonimir Pavlinovic <zpavlinovic@google.com>
Auto-Submit: Zvonimir Pavlinovic <zpavlinovic@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/go/callgraph/util.go b/go/callgraph/util.go
index 1ab0390..5499320 100644
--- a/go/callgraph/util.go
+++ b/go/callgraph/util.go
@@ -76,9 +76,12 @@
 }
 
 // DeleteSyntheticNodes removes from call graph g all nodes for
-// synthetic functions (except g.Root and package initializers),
-// preserving the topology.  In effect, calls to synthetic wrappers
-// are "inlined".
+// functions that do not correspond to source syntax. For historical
+// reasons, nodes for g.Root and package initializers are always
+// kept.
+//
+// As nodes are removed, edges are created to preserve the
+// reachability relation of the remaining nodes.
 func (g *Graph) DeleteSyntheticNodes() {
 	// Measurements on the standard library and go.tools show that
 	// resulting graph has ~15% fewer nodes and 4-8% fewer edges
@@ -99,7 +102,7 @@
 		}
 	}
 	for fn, cgn := range g.Nodes {
-		if cgn == g.Root || fn.Synthetic == "" || isInit(cgn.Func) {
+		if cgn == g.Root || isInit(cgn.Func) || fn.Syntax() != nil {
 			continue // keep
 		}
 		for _, eIn := range cgn.In {