summaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/compile/internal/loopvar/loopvar.go20
-rw-r--r--src/cmd/compile/internal/loopvar/loopvar_test.go11
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 a015672c2d..e5fedd2fce 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 d48b5ada7f..03e6eec437 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)