Skip to content

Commit 889abb1

Browse files
committed
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 #70035. 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]>
1 parent 6dc99aa commit 889abb1

File tree

4 files changed

+37
-6
lines changed

4 files changed

+37
-6
lines changed

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

+6-5
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

+6
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].
@@ -516,6 +521,7 @@ func NewClosureFunc(fpos, cpos src.XPos, why Op, typ *types.Type, outerfn *Func,
516521

517522
fn.Nname.Defn = fn
518523
pkg.Funcs = append(pkg.Funcs, fn)
524+
fn.ClosureParent = outerfn
519525

520526
return fn
521527
}

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

+1-1
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{}, 180, 304},
23+
{Func{}, 184, 312},
2424
{Name{}, 96, 168},
2525
}
2626

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

+24
Original file line numberDiff line numberDiff line change
@@ -2119,3 +2119,27 @@ func TestTwoLevelReturnCheck(t *testing.T) {
21192119
t.Errorf("Expected y=3, got y=%d\n", y)
21202120
}
21212121
}
2122+
2123+
func Bug70035(s1, s2, s3 []string) string {
2124+
var c1 string
2125+
for v1 := range slices.Values(s1) {
2126+
var c2 string
2127+
for v2 := range slices.Values(s2) {
2128+
var c3 string
2129+
for v3 := range slices.Values(s3) {
2130+
c3 = c3 + v3
2131+
}
2132+
c2 = c2 + v2 + c3
2133+
}
2134+
c1 = c1 + v1 + c2
2135+
}
2136+
return c1
2137+
}
2138+
2139+
func Test70035(t *testing.T) {
2140+
got := Bug70035([]string{"1", "2", "3"}, []string{"a", "b", "c"}, []string{"A", "B", "C"})
2141+
want := "1aABCbABCcABC2aABCbABCcABC3aABCbABCcABC"
2142+
if got != want {
2143+
t.Errorf("got %v, want %v", got, want)
2144+
}
2145+
}

0 commit comments

Comments
 (0)