type val … func (v val) String() string { … } func (v val) Name() string { … } func (v val) Type() types.Type { … } func (v val) Parent() *ssa.Function { … } func (v val) Referrers() *[]ssa.Instruction { … } func (v val) Pos() token.Pos { … } // newLocal creates a new local node with ssa.Value // named `name` and type `t`. func newLocal(name string, t types.Type) local { … } // newNamedType creates a bogus type named `name`. func newNamedType(name string) *types.Named { … } // sccString is a utility for stringifying `nodeToScc`. Every // scc is represented as a string where string representation // of scc nodes are sorted and concatenated using `;`. func sccString(sccs [][]idx, g *vtaGraph) []string { … } // nodeToTypeString is testing utility for stringifying results // of type propagation: propTypeMap `pMap` is converted to a map // from node strings to a string consisting of type stringifications // concatenated with `;`. We stringify reachable type information // that also has an accompanying function by the function name. func nodeToTypeString(pMap propTypeMap) map[string]string { … } // sccEqual compares two sets of SCC stringifications. func sccEqual(sccs1 []string, sccs2 []string) bool { … } // isRevTopSorted checks if sccs of `g` are sorted in reverse // topological order: // // for every edge x -> y in g, nodeToScc[x] > nodeToScc[y] func isRevTopSorted(g *vtaGraph, idxToScc []int) bool { … } func sccMapsConsistent(sccs [][]idx, idxToSccID []int) bool { … } // setName sets name of the function `f` to `name` // using reflection since setting the name otherwise // is only possible within the ssa package. func setName(f *ssa.Function, name string) { … } // testSuite produces a named set of graphs as follows, where // parentheses contain node types and F nodes stand for function // nodes whose content is function named F: // // no-cycles: // t0 (A) -> t1 (B) -> t2 (C) // // trivial-cycle: // <-------- <-------- // | | | | // t0 (A) -> t1 (B) -> // // circle-cycle: // t0 (A) -> t1 (A) -> t2 (B) // | | // <-------------------- // // fully-connected: // t0 (A) <-> t1 (B) // \ / // t2(C) // // subsumed-scc: // t0 (A) -> t1 (B) -> t2(B) -> t3 (A) // | | | | // | <--------- | // <----------------------------- // // more-realistic: // <-------- // | | // t0 (A) --> // ----------> // | | // t1 (A) -> t2 (B) -> F1 -> F2 -> F3 -> F4 // | | | | // <------- <------------ func testSuite() map[string]*vtaGraph { … } func TestSCC(t *testing.T) { … } func TestPropagation(t *testing.T) { … } func testLastIndex[S ~[]E, E comparable](t *testing.T, s S, e E, want int) { … } func TestLastIndex(t *testing.T) { … }