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
}
// 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
// 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].
fn.Nname.Defn = fn
pkg.Funcs = append(pkg.Funcs, fn)
+ fn.ClosureParent = outerfn
return fn
}
_32bit uintptr // size on 32bit platforms
_64bit uintptr // size on 64bit platforms
}{
- {Func{}, 176, 296},
+ {Func{}, 180, 304},
{Name{}, 96, 168},
}
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)
+ }
+}