Skip to content

Commit 3726f07

Browse files
dr2chasegopherbot
authored andcommitted
[release-branch.go1.23] cmd/compile: use a non-fragile test for "does 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]>
1 parent c390a1c commit 3726f07

File tree

4 files changed

+37
-6
lines changed

4 files changed

+37
-6
lines changed

src/cmd/compile/internal/escape/solve.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,10 @@ func containsClosure(f, c *ir.Func) bool {
318318
return false
319319
}
320320

321-
// Closures within function Foo are named like "Foo.funcN..." or "Foo-rangeN".
322-
// TODO(mdempsky): Better way to recognize this.
323-
fn := f.Sym().Name
324-
cn := c.Sym().Name
325-
return len(cn) > len(fn) && cn[:len(fn)] == fn && (cn[len(fn)] == '.' || cn[len(fn)] == '-')
321+
for p := c.ClosureParent; p != nil; p = p.ClosureParent {
322+
if p == f {
323+
return true
324+
}
325+
}
326+
return false
326327
}

src/cmd/compile/internal/ir/func.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ import (
5151
// the generated ODCLFUNC, but there is no
5252
// pointer from the Func back to the OMETHVALUE.
5353
type Func struct {
54+
// if you add or remove a field, don't forget to update sizeof_test.go
55+
5456
miniNode
5557
Body Nodes
5658

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

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

513518
fn.Nname.Defn = fn
514519
pkg.Funcs = append(pkg.Funcs, fn)
520+
fn.ClosureParent = outerfn
515521

516522
return fn
517523
}

src/cmd/compile/internal/ir/sizeof_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func TestSizeof(t *testing.T) {
2020
_32bit uintptr // size on 32bit platforms
2121
_64bit uintptr // size on 64bit platforms
2222
}{
23-
{Func{}, 176, 296},
23+
{Func{}, 180, 304},
2424
{Name{}, 96, 168},
2525
}
2626

src/cmd/compile/internal/rangefunc/rangefunc_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2099,3 +2099,27 @@ func TestTwoLevelReturnCheck(t *testing.T) {
20992099
t.Errorf("Expected y=3, got y=%d\n", y)
21002100
}
21012101
}
2102+
2103+
func Bug70035(s1, s2, s3 []string) string {
2104+
var c1 string
2105+
for v1 := range slices.Values(s1) {
2106+
var c2 string
2107+
for v2 := range slices.Values(s2) {
2108+
var c3 string
2109+
for v3 := range slices.Values(s3) {
2110+
c3 = c3 + v3
2111+
}
2112+
c2 = c2 + v2 + c3
2113+
}
2114+
c1 = c1 + v1 + c2
2115+
}
2116+
return c1
2117+
}
2118+
2119+
func Test70035(t *testing.T) {
2120+
got := Bug70035([]string{"1", "2", "3"}, []string{"a", "b", "c"}, []string{"A", "B", "C"})
2121+
want := "1aABCbABCcABC2aABCbABCcABC3aABCbABCcABC"
2122+
if got != want {
2123+
t.Errorf("got %v, want %v", got, want)
2124+
}
2125+
}

0 commit comments

Comments
 (0)