// 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. package vulncheck import ( "golang.org/x/tools/go/callgraph" "golang.org/x/tools/go/ssa" ) // forwardSlice computes the transitive closure of functions forward reachable // via calls in cg or referred to in an instruction starting from `sources`. func forwardSlice(sources map[*ssa.Function]bool, cg *callgraph.Graph) map[*ssa.Function]bool { seen := make(map[*ssa.Function]bool) var visit func(f *ssa.Function) visit = func(f *ssa.Function) { if seen[f] { return } seen[f] = true if n := cg.Nodes[f]; n != nil { for _, e := range n.Out { if e.Site != nil { visit(e.Callee.Func) } } } var buf [10]*ssa.Value // avoid alloc in common case for _, b := range f.Blocks { for _, instr := range b.Instrs { for _, op := range instr.Operands(buf[:0]) { if fn, ok := (*op).(*ssa.Function); ok { visit(fn) } } } } } for source := range sources { visit(source) } return seen }