From b3d1cce3eb26a08420d803df872721bfd370e3ed Mon Sep 17 00:00:00 2001 From: David Chase Date: Wed, 10 May 2023 19:29:18 -0400 Subject: [PATCH] cmd/compile: add more information to the bisect-verbose report running on cmd/compile/internal/testdata/inlines now shows: ``` --- change set #1 (enabling changes causes failure) b/b.go:16:6: loop variable i now per-iteration (loop inlined into b/b.go:10) b/b.go:16:6: loop variable i now per-iteration ./b/b.go:16:6: loop variable b.i now per-iteration (loop inlined into a/a.go:18) ./b/b.go:16:6: loop variable b.i now per-iteration (loop inlined into ./main.go:37) ./b/b.go:16:6: loop variable b.i now per-iteration (loop inlined into ./main.go:38) --- ``` and ``` --- change set #2 (enabling changes causes failure) ./main.go:27:6: loop variable i now per-iteration ./main.go:27:6: loop variable i now per-iteration (loop inlined into ./main.go:35) --- ``` Still unsure about the utility of mentioning the inlined occurrence, but better than mysteriously repeating the line over and over again. Change-Id: I357f5d419ab4928fa316f4612eec3b75e7f8ac34 Reviewed-on: https://go-review.googlesource.com/c/go/+/494296 TryBot-Result: Gopher Robot Reviewed-by: Matthew Dempsky Run-TryBot: David Chase --- src/cmd/compile/internal/loopvar/loopvar.go | 20 +++++++++++++++++-- .../compile/internal/loopvar/loopvar_test.go | 11 +++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/cmd/compile/internal/loopvar/loopvar.go b/src/cmd/compile/internal/loopvar/loopvar.go index a015672c2d4..e5fedd2fcea 100644 --- a/src/cmd/compile/internal/loopvar/loopvar.go +++ b/src/cmd/compile/internal/loopvar/loopvar.go @@ -48,6 +48,16 @@ func ForCapture(fn *ir.Func) []VarAndLoop { // if a loop variable is transformed it is appended to this slice for later logging var transformed []VarAndLoop + describe := func(n *ir.Name) string { + pos := n.Pos() + inner := base.Ctxt.InnermostPos(pos) + outer := base.Ctxt.OutermostPos(pos) + if inner == outer { + return fmt.Sprintf("loop variable %v now per-iteration", n) + } + return fmt.Sprintf("loop variable %v now per-iteration (loop inlined into %s:%d)", n, outer.Filename(), outer.Line()) + } + forCapture := func() { seq := 1 @@ -91,7 +101,10 @@ func ForCapture(fn *ir.Func) []VarAndLoop { // subject to hash-variable debugging. maybeReplaceVar := func(k ir.Node, x *ir.RangeStmt) ir.Node { if n, ok := k.(*ir.Name); ok && possiblyLeaked[n] { - if base.LoopVarHash.MatchPos(n.Pos(), nil) { + desc := func() string { + return describe(n) + } + if base.LoopVarHash.MatchPos(n.Pos(), desc) { // Rename the loop key, prefix body with assignment from loop key transformed = append(transformed, VarAndLoop{n, x, lastPos}) tk := typecheck.Temp(n.Type()) @@ -198,8 +211,11 @@ func ForCapture(fn *ir.Func) []VarAndLoop { // Collect the leaking variables for the much-more-complex transformation. forAllDefInInit(x, func(z ir.Node) { if n, ok := z.(*ir.Name); ok && possiblyLeaked[n] { + desc := func() string { + return describe(n) + } // Hash on n.Pos() for most precise failure location. - if base.LoopVarHash.MatchPos(n.Pos(), nil) { + if base.LoopVarHash.MatchPos(n.Pos(), desc) { leaked = append(leaked, n) } } diff --git a/src/cmd/compile/internal/loopvar/loopvar_test.go b/src/cmd/compile/internal/loopvar/loopvar_test.go index d48b5ada7f9..03e6eec4373 100644 --- a/src/cmd/compile/internal/loopvar/loopvar_test.go +++ b/src/cmd/compile/internal/loopvar/loopvar_test.go @@ -8,6 +8,7 @@ import ( "internal/testenv" "os/exec" "path/filepath" + "regexp" "runtime" "strings" "testing" @@ -159,6 +160,11 @@ func TestLoopVarInlines(t *testing.T) { } } +func countMatches(s, re string) int { + slice := regexp.MustCompile(re).FindAllString(s, -1) + return len(slice) +} + func TestLoopVarHashes(t *testing.T) { switch runtime.GOOS { case "linux", "darwin": @@ -195,7 +201,7 @@ func TestLoopVarHashes(t *testing.T) { m := f(arg) t.Logf(m) - mCount := strings.Count(m, "loopvarhash triggered cmd/compile/internal/loopvar/testdata/inlines/main.go:27:6 001100110110110010100100") + mCount := countMatches(m, "loopvarhash triggered cmd/compile/internal/loopvar/testdata/inlines/main.go:27:6: .* 001100110110110010100100") otherCount := strings.Count(m, "loopvarhash") if mCount < 1 { t.Errorf("%s: did not see triggered main.go:27:6", arg) @@ -203,8 +209,7 @@ func TestLoopVarHashes(t *testing.T) { if mCount != otherCount { t.Errorf("%s: too many matches", arg) } - - mCount = strings.Count(m, "cmd/compile/internal/loopvar/testdata/inlines/main.go:27:6 [bisect-match 0x7802e115b9336ca4]") + mCount = countMatches(m, "cmd/compile/internal/loopvar/testdata/inlines/main.go:27:6: .* \\[bisect-match 0x7802e115b9336ca4\\]") otherCount = strings.Count(m, "[bisect-match ") if mCount < 1 { t.Errorf("%s: did not see bisect-match for main.go:27:6", arg)