Skip to content

Commit

Permalink
go/callgraph/vta: add basic tests for range-over-func
Browse files Browse the repository at this point in the history
The tests check the callees at the call to yield and type flow out of
the range-over-func iterator. If needed, a test for defer will be added
in a follow-up CL.

Change-Id: Ic9208ac0824a36fb50879730e8ec9398b9b6e284
Reviewed-on: https://go-review.googlesource.com/c/tools/+/611395
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Tim King <taking@google.com>
  • Loading branch information
zpavlinovic committed Sep 6, 2024
1 parent 2c7aaab commit 075ae7d
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 9 deletions.
96 changes: 96 additions & 0 deletions go/callgraph/vta/testdata/src/callgraph_range_over_func.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright 2024 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.

// go:build ignore

package testdata

type I interface {
Foo()
}

type A struct{}

func (a A) Foo() {}

type B struct{}

func (b B) Foo() {}

type C struct{}

func (c C) Foo() {} // Test that this is not called.

type iset []I

func (i iset) All() func(func(I) bool) {
return func(yield func(I) bool) {
for _, v := range i {
if !yield(v) {
return
}
}
}
}

var x = iset([]I{A{}, B{}})

func X() {
for i := range x.All() {
i.Foo()
}
}

func Y() I {
for i := range x.All() {
return i
}
return nil
}

func Bar() {
X()
y := Y()
y.Foo()
}

// Relevant SSA:
//func X$1(I) bool:
// t0 = *jump$1
// t1 = t0 == 0:int
// if t1 goto 1 else 2
//1:
// *jump$1 = -1:int
// t2 = invoke arg0.Foo()
// *jump$1 = 0:int
// return true:bool
//2:
// t3 = make interface{} <- string ("yield function ca...":string) interface{}
// panic t3
//
//func All$1(yield func(I) bool):
// t0 = *i
// t1 = len(t0)
// jump 1
//1:
// t2 = phi [0: -1:int, 2: t3] #rangeindex
// t3 = t2 + 1:int
// t4 = t3 < t1
// if t4 goto 2 else 3
//2:
// t5 = &t0[t3]
// t6 = *t5
// t7 = yield(t6)
// if t7 goto 1 else 4
//
//func Bar():
// t0 = X()
// t1 = Y()
// t2 = invoke t1.Foo()
// return

// WANT:
// Bar: X() -> X; Y() -> Y; invoke t1.Foo() -> A.Foo, B.Foo
// X$1: invoke arg0.Foo() -> A.Foo, B.Foo
// All$1: yield(t6) -> X$1, Y$1
20 changes: 11 additions & 9 deletions go/callgraph/vta/vta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:debug gotypesalias=1

package vta

import (
Expand All @@ -15,7 +17,7 @@ import (
"golang.org/x/tools/go/callgraph/cha"
"golang.org/x/tools/go/ssa"
"golang.org/x/tools/go/ssa/ssautil"
"golang.org/x/tools/internal/aliases"
"golang.org/x/tools/internal/testenv"
)

func TestVTACallGraph(t *testing.T) {
Expand All @@ -27,7 +29,7 @@ func TestVTACallGraph(t *testing.T) {
cmp.Diff(got, want)) // to aid debugging
}

for _, file := range []string{
files := []string{
"testdata/src/callgraph_static.go",
"testdata/src/callgraph_ho.go",
"testdata/src/callgraph_interfaces.go",
Expand All @@ -38,14 +40,14 @@ func TestVTACallGraph(t *testing.T) {
"testdata/src/callgraph_recursive_types.go",
"testdata/src/callgraph_issue_57756.go",
"testdata/src/callgraph_comma_maps.go",
"testdata/src/callgraph_type_aliases.go",
} {
t.Run(file, func(t *testing.T) {
// https://github.com/golang/go/issues/68799
if !aliases.Enabled() && file == "testdata/src/callgraph_type_aliases.go" {
t.Skip("callgraph_type_aliases.go requires gotypesalias=1")
}
"testdata/src/callgraph_type_aliases.go", // https://github.com/golang/go/issues/68799
}
if testenv.Go1Point() >= 23 {
files = append(files, "testdata/src/callgraph_range_over_func.go")
}

for _, file := range files {
t.Run(file, func(t *testing.T) {
prog, want, err := testProg(file, ssa.BuilderMode(0))
if err != nil {
t.Fatalf("couldn't load test file '%s': %s", file, err)
Expand Down

0 comments on commit 075ae7d

Please sign in to comment.