Skip to content

Commit f7d1430

Browse files
author
zeroy
committed
add api in vta
1 parent b1c39aa commit f7d1430

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

go/callgraph/vta/utils.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,16 @@ func calls(f *ssa.Function) []ssa.CallInstruction {
187187
}
188188
return calls
189189
}
190+
191+
// typeAsserts returns the set of type assert instructions in `f`.
192+
func typeAsserts(f *ssa.Function) []*ssa.TypeAssert {
193+
var asserts []*ssa.TypeAssert
194+
for _, bl := range f.Blocks {
195+
for _, instr := range bl.Instrs {
196+
if ta, ok := instr.(*ssa.TypeAssert); ok {
197+
asserts = append(asserts, ta)
198+
}
199+
}
200+
}
201+
return asserts
202+
}

go/callgraph/vta/vta.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ package vta
5959
import (
6060
"go/types"
6161

62+
"maps"
63+
6264
"golang.org/x/tools/go/callgraph"
6365
"golang.org/x/tools/go/ssa"
6466
)
@@ -190,3 +192,37 @@ func (mc methodCache) methods(t types.Type, name string, prog *ssa.Program) []*s
190192
mc[t] = ms
191193
return ms[name]
192194
}
195+
196+
// typeAssertTypes returns a mapping from each type assertion instruction in `f` to the possible types of its input variable.
197+
func typeAssertTypes(f *ssa.Function, typesMap *propTypeMap, cache methodCache) map[*ssa.TypeAssert][]types.Type {
198+
asserts := typeAsserts(f)
199+
result := make(map[*ssa.TypeAssert][]types.Type)
200+
201+
for _, ta := range asserts {
202+
inputVal := ta.X
203+
n := local{val: inputVal}
204+
205+
var possTypes []types.Type
206+
typesMap.propTypes(n)(func(p propType) bool {
207+
possTypes = append(possTypes, p.typ)
208+
return true
209+
})
210+
211+
result[ta] = possTypes
212+
}
213+
214+
return result
215+
}
216+
217+
func GetTypeAsserts(funcs map[*ssa.Function]bool, initial *callgraph.Graph) map[*ssa.TypeAssert][]types.Type {
218+
callees := makeCalleesFunc(funcs, initial)
219+
vtaG, canon := typePropGraph(funcs, callees)
220+
typesMap := propagate(vtaG, canon)
221+
result := make(map[*ssa.TypeAssert][]types.Type)
222+
for f, in := range funcs {
223+
if in {
224+
maps.Copy(result, typeAssertTypes(f, &typesMap, methodCache{}))
225+
}
226+
}
227+
return result
228+
}

0 commit comments

Comments
 (0)