]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.23] cmd/compile: use a non-fragile test for "does f contain closu...
authorDavid Chase <drchase@google.com>
Fri, 25 Oct 2024 18:04:22 +0000 (14:04 -0400)
committerGopher Robot <gobot@golang.org>
Tue, 19 Nov 2024 17:52:28 +0000 (17:52 +0000)
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 <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/625535
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>

src/cmd/compile/internal/escape/solve.go
src/cmd/compile/internal/ir/func.go
src/cmd/compile/internal/ir/sizeof_test.go
src/cmd/compile/internal/rangefunc/rangefunc_test.go

index ef17bc48ef234205b1b1bf876fd72750cc963758..32f5a771a34a668cfd96a2f851f2b5082bf969f7 100644 (file)
@@ -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
 }
index d0c8ee359befff39c0059ef4540bc063fcc6e939..4fa9055b4b2c0b519d3c5bc942e8f253994c4fee 100644 (file)
@@ -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].
@@ -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
 }
index 68d2865595b71620c00e6ae2b107f144a5ab6a55..6331cceb4a59b48e54fbd669b598261423f1df26 100644 (file)
@@ -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},
        }
 
index 97ab254395332ac7659dd586b7a1931ccb72867a..e488c3cf377caee0b4a3e38e2ed5aba9670ebe76 100644 (file)
@@ -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)
+       }
+}