From a297bfd9847df3a44ed5943003c8e4acf197b066 Mon Sep 17 00:00:00 2001 From: Alan Donovan Date: Wed, 31 Jan 2024 17:04:03 -0500 Subject: [PATCH] go/callgraph/rta: audit for types.Alias safety Updates golang/go#65294 Change-Id: I90fe0cc3ab5a6171e112e2eb0e452efb172d9980 Reviewed-on: https://go-review.googlesource.com/c/tools/+/559937 Reviewed-by: Zvonimir Pavlinovic LUCI-TryBot-Result: Go LUCI --- go/callgraph/rta/rta.go | 9 ++++++++- go/callgraph/rta/rta_test.go | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/go/callgraph/rta/rta.go b/go/callgraph/rta/rta.go index d0ae0fccf57..72b383dabe7 100644 --- a/go/callgraph/rta/rta.go +++ b/go/callgraph/rta/rta.go @@ -45,6 +45,7 @@ import ( "golang.org/x/tools/go/callgraph" "golang.org/x/tools/go/ssa" "golang.org/x/tools/go/types/typeutil" + "golang.org/x/tools/internal/aliases" "golang.org/x/tools/internal/compat" ) @@ -416,6 +417,9 @@ func (r *rta) implementations(I *types.Interface) []types.Type { // dynamic type of some interface or reflect.Value. // Adapted from needMethods in go/ssa/builder.go func (r *rta) addRuntimeType(T types.Type, skip bool) { + // Never record aliases. + T = aliases.Unalias(T) + if prev, ok := r.result.RuntimeTypes.At(T).(bool); ok { if skip && !prev { r.result.RuntimeTypes.Set(T, skip) @@ -457,7 +461,7 @@ func (r *rta) addRuntimeType(T types.Type, skip bool) { case *types.Named: n = T case *types.Pointer: - n, _ = T.Elem().(*types.Named) + n, _ = aliases.Unalias(T.Elem()).(*types.Named) } if n != nil { owner := n.Obj().Pkg() @@ -476,6 +480,9 @@ func (r *rta) addRuntimeType(T types.Type, skip bool) { } switch t := T.(type) { + case *aliases.Alias: + panic("unreachable") + case *types.Basic: // nop diff --git a/go/callgraph/rta/rta_test.go b/go/callgraph/rta/rta_test.go index a855dd6d369..8552dc7b13c 100644 --- a/go/callgraph/rta/rta_test.go +++ b/go/callgraph/rta/rta_test.go @@ -23,6 +23,7 @@ import ( "golang.org/x/tools/go/loader" "golang.org/x/tools/go/ssa" "golang.org/x/tools/go/ssa/ssautil" + "golang.org/x/tools/internal/aliases" ) // TestRTA runs RTA on each testdata/*.go file and compares the @@ -200,7 +201,7 @@ func check(t *testing.T, f *ast.File, pkg *ssa.Package, res *rta.Result) { got := make(stringset) res.RuntimeTypes.Iterate(func(key types.Type, value interface{}) { if !value.(bool) { // accessible to reflection - typ := types.TypeString(key, types.RelativeTo(pkg.Pkg)) + typ := types.TypeString(aliases.Unalias(key), types.RelativeTo(pkg.Pkg)) got[typ] = true } })