Skip to content

Commit

Permalink
[release-branch.go1.23] cmd/compile: use a non-fragile test for "does…
Browse files Browse the repository at this point in the history
… f contain closure c?"

The old test relied on naming conventions.  The new test
uses an explicit parent pointer chain initialized when the
closures are created (in the same place that the names
used in the older fragile test were assigned).

Fixes #70198.

Change-Id: Ie834103c7096e4505faaff3bed1fc6e918a21211
Reviewed-on: https://go-review.googlesource.com/c/go/+/622656
Reviewed-by: Keith Randall <[email protected]>
Reviewed-by: Keith Randall <[email protected]>
Reviewed-by: Cuong Manh Le <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-on: https://go-review.googlesource.com/c/go/+/625535
Auto-Submit: Dmitri Shuralyov <[email protected]>
  • Loading branch information
dr2chase authored and gopherbot committed Nov 19, 2024
1 parent c390a1c commit 3726f07
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 6 deletions.
11 changes: 6 additions & 5 deletions src/cmd/compile/internal/escape/solve.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,10 @@ func containsClosure(f, c *ir.Func) bool {
return false
}

// Closures within function Foo are named like "Foo.funcN..." or "Foo-rangeN".
// TODO(mdempsky): Better way to recognize this.
fn := f.Sym().Name
cn := c.Sym().Name
return len(cn) > len(fn) && cn[:len(fn)] == fn && (cn[len(fn)] == '.' || cn[len(fn)] == '-')
for p := c.ClosureParent; p != nil; p = p.ClosureParent {
if p == f {
return true
}
}
return false
}
6 changes: 6 additions & 0 deletions src/cmd/compile/internal/ir/func.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ import (
// the generated ODCLFUNC, but there is no
// pointer from the Func back to the OMETHVALUE.
type Func struct {
// if you add or remove a field, don't forget to update sizeof_test.go

miniNode
Body Nodes

Expand All @@ -76,6 +78,9 @@ type Func struct {
// Populated during walk.
Closures []*Func

// Parent of a closure
ClosureParent *Func

// Parents records the parent scope of each scope within a
// function. The root scope (0) has no parent, so the i'th
// scope's parent is stored at Parents[i-1].
Expand Down Expand Up @@ -512,6 +517,7 @@ func NewClosureFunc(fpos, cpos src.XPos, why Op, typ *types.Type, outerfn *Func,

fn.Nname.Defn = fn
pkg.Funcs = append(pkg.Funcs, fn)
fn.ClosureParent = outerfn

return fn
}
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/ir/sizeof_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func TestSizeof(t *testing.T) {
_32bit uintptr // size on 32bit platforms
_64bit uintptr // size on 64bit platforms
}{
{Func{}, 176, 296},
{Func{}, 180, 304},
{Name{}, 96, 168},
}

Expand Down
24 changes: 24 additions & 0 deletions src/cmd/compile/internal/rangefunc/rangefunc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2099,3 +2099,27 @@ func TestTwoLevelReturnCheck(t *testing.T) {
t.Errorf("Expected y=3, got y=%d\n", y)
}
}

func Bug70035(s1, s2, s3 []string) string {
var c1 string
for v1 := range slices.Values(s1) {
var c2 string
for v2 := range slices.Values(s2) {
var c3 string
for v3 := range slices.Values(s3) {
c3 = c3 + v3
}
c2 = c2 + v2 + c3
}
c1 = c1 + v1 + c2
}
return c1
}

func Test70035(t *testing.T) {
got := Bug70035([]string{"1", "2", "3"}, []string{"a", "b", "c"}, []string{"A", "B", "C"})
want := "1aABCbABCcABC2aABCbABCcABC3aABCbABCcABC"
if got != want {
t.Errorf("got %v, want %v", got, want)
}
}

0 comments on commit 3726f07

Please sign in to comment.