aboutsummaryrefslogtreecommitdiff
path: root/go/ssa/builder_test.go
diff options
context:
space:
mode:
authorTim King <taking@google.com>2022-05-11 14:12:33 -0700
committerTim King <taking@google.com>2022-05-16 16:39:03 +0000
commit1e55371df567127a49b447aa65b92cb04ad99138 (patch)
tree97b41ae80e9ca145bc77566669d2c9aaec0b433d /go/ssa/builder_test.go
parent29d48d6d9d17e86ff120ff4ac25270233728b12b (diff)
downloadgolang-x-tools-1e55371df567127a49b447aa65b92cb04ad99138.tar.gz
go/ssa: fix *SelectorExpr within *IndexExpr handling
When a *IndexExpr or *IndexListExpr expr is over a *SelectorExpr and expr denotes an instantiation, build expr as the *SelectorExpr. Fixes golang/go#52834 Change-Id: I9a69ac28a6e8fb0ee9eb45db8675872b75d69a0f Reviewed-on: https://go-review.googlesource.com/c/tools/+/405555 gopls-CI: kokoro <noreply+kokoro@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Tim King <taking@google.com> Reviewed-by: Zvonimir Pavlinovic <zpavlinovic@google.com> Reviewed-by: Alan Donovan <adonovan@google.com>
Diffstat (limited to 'go/ssa/builder_test.go')
-rw-r--r--go/ssa/builder_test.go54
1 files changed, 54 insertions, 0 deletions
diff --git a/go/ssa/builder_test.go b/go/ssa/builder_test.go
index 6b9c79803..ba9aaf768 100644
--- a/go/ssa/builder_test.go
+++ b/go/ssa/builder_test.go
@@ -20,6 +20,7 @@ import (
"strings"
"testing"
+ "golang.org/x/tools/go/buildutil"
"golang.org/x/tools/go/loader"
"golang.org/x/tools/go/ssa"
"golang.org/x/tools/go/ssa/ssautil"
@@ -823,3 +824,56 @@ func sliceMax(s []int) []int { return s[a():b():c()] }
})
}
}
+
+// TestGenericFunctionSelector ensures generic functions from other packages can be selected.
+func TestGenericFunctionSelector(t *testing.T) {
+ if !typeparams.Enabled {
+ t.Skip("TestGenericFunctionSelector uses type parameters.")
+ }
+
+ pkgs := map[string]map[string]string{
+ "main": {"m.go": `package main; import "a"; func main() { a.F[int](); a.G[int,string](); a.H(0) }`},
+ "a": {"a.go": `package a; func F[T any](){}; func G[S, T any](){}; func H[T any](a T){} `},
+ }
+
+ for _, mode := range []ssa.BuilderMode{
+ ssa.SanityCheckFunctions,
+ ssa.SanityCheckFunctions | ssa.InstantiateGenerics,
+ } {
+ conf := loader.Config{
+ Build: buildutil.FakeContext(pkgs),
+ }
+ conf.Import("main")
+
+ lprog, err := conf.Load()
+ if err != nil {
+ t.Errorf("Load failed: %s", err)
+ }
+ if lprog == nil {
+ t.Fatalf("Load returned nil *Program")
+ }
+ // Create and build SSA
+ prog := ssautil.CreateProgram(lprog, mode)
+ p := prog.Package(lprog.Package("main").Pkg)
+ p.Build()
+
+ var callees []string // callees of the CallInstruction.String() in main().
+ for _, b := range p.Func("main").Blocks {
+ for _, i := range b.Instrs {
+ if call, ok := i.(ssa.CallInstruction); ok {
+ if callee := call.Common().StaticCallee(); call != nil {
+ callees = append(callees, callee.String())
+ } else {
+ t.Errorf("CallInstruction without StaticCallee() %q", call)
+ }
+ }
+ }
+ }
+ sort.Strings(callees) // ignore the order in the code.
+
+ want := "[a.F[[int]] a.G[[int string]] a.H[[int]]]"
+ if got := fmt.Sprint(callees); got != want {
+ t.Errorf("Expected main() to contain calls %v. got %v", want, got)
+ }
+ }
+}