aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/escape/solve.go11
-rw-r--r--src/cmd/compile/internal/ir/func.go6
-rw-r--r--src/cmd/compile/internal/ir/sizeof_test.go2
-rw-r--r--src/cmd/compile/internal/rangefunc/rangefunc_test.go24
4 files changed, 37 insertions, 6 deletions
diff --git a/src/cmd/compile/internal/escape/solve.go b/src/cmd/compile/internal/escape/solve.go
index ef17bc48ef..32f5a771a3 100644
--- a/src/cmd/compile/internal/escape/solve.go
+++ b/src/cmd/compile/internal/escape/solve.go
@@ -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
}
diff --git a/src/cmd/compile/internal/ir/func.go b/src/cmd/compile/internal/ir/func.go
index f9af358ef4..6354da3556 100644
--- a/src/cmd/compile/internal/ir/func.go
+++ b/src/cmd/compile/internal/ir/func.go
@@ -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
@@ -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].
@@ -516,6 +521,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
}
diff --git a/src/cmd/compile/internal/ir/sizeof_test.go b/src/cmd/compile/internal/ir/sizeof_test.go
index 6331cceb4a..ea74296315 100644
--- a/src/cmd/compile/internal/ir/sizeof_test.go
+++ b/src/cmd/compile/internal/ir/sizeof_test.go
@@ -20,7 +20,7 @@ func TestSizeof(t *testing.T) {
_32bit uintptr // size on 32bit platforms
_64bit uintptr // size on 64bit platforms
}{
- {Func{}, 180, 304},
+ {Func{}, 184, 312},
{Name{}, 96, 168},
}
diff --git a/src/cmd/compile/internal/rangefunc/rangefunc_test.go b/src/cmd/compile/internal/rangefunc/rangefunc_test.go
index 1d0bed05c8..acf0ef6e09 100644
--- a/src/cmd/compile/internal/rangefunc/rangefunc_test.go
+++ b/src/cmd/compile/internal/rangefunc/rangefunc_test.go
@@ -2119,3 +2119,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)
+ }
+}