aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/loopvar/loopvar_test.go
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2023-07-05 16:21:19 -0400
committerDavid Chase <drchase@google.com>2023-08-08 21:20:26 +0000
commitfe1daf2e439ec1d650ea1193f10f52525f83f8a7 (patch)
tree4db784376b586aa2a60b2ed79fde7889c557273b /src/cmd/compile/internal/loopvar/loopvar_test.go
parent6d8d88a70716bd35708748ba4e0110bdcd9520f3 (diff)
downloadgo-fe1daf2e439ec1d650ea1193f10f52525f83f8a7.tar.xz
cmd/compile: use new for loop semantics for Go 1.22+ compilations
This includes version-dependent support for GOEXPERIMENT and -d=loopvar, -d=loopvarhash, to allow testing/porting of old code. Includes tests of downgrade (1.22 -> 1.21) and upgrade (1.21 -> 1.22) based on //go:build lines (while running a 1.22 build/compiler). Change-Id: Idd3be61a2b46acec33c7e7edac0924158cc726b4 Reviewed-on: https://go-review.googlesource.com/c/go/+/508819 Run-TryBot: David Chase <drchase@google.com> Reviewed-by: Russ Cox <rsc@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/loopvar/loopvar_test.go')
-rw-r--r--src/cmd/compile/internal/loopvar/loopvar_test.go133
1 files changed, 126 insertions, 7 deletions
diff --git a/src/cmd/compile/internal/loopvar/loopvar_test.go b/src/cmd/compile/internal/loopvar/loopvar_test.go
index 03e6eec437..c8e11dbd07 100644
--- a/src/cmd/compile/internal/loopvar/loopvar_test.go
+++ b/src/cmd/compile/internal/loopvar/loopvar_test.go
@@ -51,7 +51,7 @@ var cases = []testcase{
}
// TestLoopVar checks that the GOEXPERIMENT and debug flags behave as expected.
-func TestLoopVar(t *testing.T) {
+func TestLoopVarGo1_21(t *testing.T) {
switch runtime.GOOS {
case "linux", "darwin":
default:
@@ -71,7 +71,7 @@ func TestLoopVar(t *testing.T) {
for i, tc := range cases {
for _, f := range tc.files {
source := f
- cmd := testenv.Command(t, gocmd, "build", "-o", output, "-gcflags=-d=loopvar="+tc.lvFlag, source)
+ cmd := testenv.Command(t, gocmd, "build", "-o", output, "-gcflags=-lang=go1.21 -d=loopvar="+tc.lvFlag, source)
cmd.Env = append(cmd.Env, "GOEXPERIMENT=loopvar", "HOME="+tmpdir)
cmd.Dir = "testdata"
t.Logf("File %s loopvar=%s expect '%s' exit code %d", f, tc.lvFlag, tc.buildExpect, tc.expectRC)
@@ -103,7 +103,7 @@ func TestLoopVar(t *testing.T) {
}
}
-func TestLoopVarInlines(t *testing.T) {
+func TestLoopVarInlinesGo1_21(t *testing.T) {
switch runtime.GOOS {
case "linux", "darwin":
default:
@@ -125,7 +125,7 @@ func TestLoopVarInlines(t *testing.T) {
// This disables the loopvar change, except for the specified package.
// The effect should follow the package, even though everything (except "c")
// is inlined.
- cmd := testenv.Command(t, gocmd, "run", "-gcflags="+pkg+"=-d=loopvar=1", root)
+ cmd := testenv.Command(t, gocmd, "run", "-gcflags="+root+"/...=-lang=go1.21", "-gcflags="+pkg+"=-d=loopvar=1", root)
cmd.Env = append(cmd.Env, "GOEXPERIMENT=noloopvar", "HOME="+tmpdir)
cmd.Dir = filepath.Join("testdata", "inlines")
@@ -166,6 +166,7 @@ func countMatches(s, re string) int {
}
func TestLoopVarHashes(t *testing.T) {
+ // This behavior does not depend on Go version (1.21 or greater)
switch runtime.GOOS {
case "linux", "darwin":
default:
@@ -187,7 +188,7 @@ func TestLoopVarHashes(t *testing.T) {
// This disables the loopvar change, except for the specified hash pattern.
// -trimpath is necessary so we get the same answer no matter where the
// Go repository is checked out. This is not normally a concern since people
- // do not rely on the meaning of specific hashes.
+ // do not normally rely on the meaning of specific hashes.
cmd := testenv.Command(t, gocmd, "run", "-trimpath", root)
cmd.Env = append(cmd.Env, "GOCOMPILEDEBUG=loopvarhash="+hash, "HOME="+tmpdir)
cmd.Dir = filepath.Join("testdata", "inlines")
@@ -225,7 +226,8 @@ func TestLoopVarHashes(t *testing.T) {
}
}
-func TestLoopVarOpt(t *testing.T) {
+// TestLoopVarVersionEnableFlag checks for loopvar transformation enabled by command line flag (1.22).
+func TestLoopVarVersionEnableFlag(t *testing.T) {
switch runtime.GOOS {
case "linux", "darwin":
default:
@@ -240,7 +242,8 @@ func TestLoopVarOpt(t *testing.T) {
testenv.MustHaveGoBuild(t)
gocmd := testenv.GoToolPath(t)
- cmd := testenv.Command(t, gocmd, "run", "-gcflags=-d=loopvar=2", "opt.go")
+ // loopvar=3 logs info but does not change loopvarness
+ cmd := testenv.Command(t, gocmd, "run", "-gcflags=-lang=go1.22 -d=loopvar=3", "opt.go")
cmd.Dir = filepath.Join("testdata")
b, err := cmd.CombinedOutput()
@@ -260,5 +263,121 @@ func TestLoopVarOpt(t *testing.T) {
if err != nil {
t.Errorf("err=%v != nil", err)
}
+}
+
+// TestLoopVarVersionEnableGoBuild checks for loopvar transformation enabled by go:build version (1.22).
+func TestLoopVarVersionEnableGoBuild(t *testing.T) {
+ switch runtime.GOOS {
+ case "linux", "darwin":
+ default:
+ t.Skipf("Slow test, usually avoid it, os=%s not linux or darwin", runtime.GOOS)
+ }
+ switch runtime.GOARCH {
+ case "amd64", "arm64":
+ default:
+ t.Skipf("Slow test, usually avoid it, arch=%s not amd64 or arm64", runtime.GOARCH)
+ }
+
+ testenv.MustHaveGoBuild(t)
+ gocmd := testenv.GoToolPath(t)
+
+ // loopvar=3 logs info but does not change loopvarness
+ cmd := testenv.Command(t, gocmd, "run", "-gcflags=-lang=go1.21 -d=loopvar=3", "opt-122.go")
+ cmd.Dir = filepath.Join("testdata")
+
+ b, err := cmd.CombinedOutput()
+ m := string(b)
+
+ t.Logf(m)
+
+ yCount := strings.Count(m, "opt-122.go:18:6: loop variable private now per-iteration, heap-allocated (loop inlined into ./opt-122.go:32)")
+ nCount := strings.Count(m, "shared")
+
+ if yCount != 1 {
+ t.Errorf("yCount=%d != 1", yCount)
+ }
+ if nCount > 0 {
+ t.Errorf("nCount=%d > 0", nCount)
+ }
+ if err != nil {
+ t.Errorf("err=%v != nil", err)
+ }
+}
+
+// TestLoopVarVersionDisableFlag checks for loopvar transformation DISABLED by command line version (1.21).
+func TestLoopVarVersionDisableFlag(t *testing.T) {
+ switch runtime.GOOS {
+ case "linux", "darwin":
+ default:
+ t.Skipf("Slow test, usually avoid it, os=%s not linux or darwin", runtime.GOOS)
+ }
+ switch runtime.GOARCH {
+ case "amd64", "arm64":
+ default:
+ t.Skipf("Slow test, usually avoid it, arch=%s not amd64 or arm64", runtime.GOARCH)
+ }
+ testenv.MustHaveGoBuild(t)
+ gocmd := testenv.GoToolPath(t)
+
+ // loopvar=3 logs info but does not change loopvarness
+ cmd := testenv.Command(t, gocmd, "run", "-gcflags=-lang=go1.21 -d=loopvar=3", "opt.go")
+ cmd.Dir = filepath.Join("testdata")
+
+ b, err := cmd.CombinedOutput()
+ m := string(b)
+
+ t.Logf(m) // expect error
+
+ yCount := strings.Count(m, "opt.go:16:6: loop variable private now per-iteration, heap-allocated (loop inlined into ./opt.go:30)")
+ nCount := strings.Count(m, "shared")
+
+ if yCount != 0 {
+ t.Errorf("yCount=%d != 0", yCount)
+ }
+ if nCount > 0 {
+ t.Errorf("nCount=%d > 0", nCount)
+ }
+ if err == nil { // expect error
+ t.Errorf("err=%v == nil", err)
+ }
+}
+
+// TestLoopVarVersionDisableGoBuild checks for loopvar transformation DISABLED by go:build version (1.21).
+func TestLoopVarVersionDisableGoBuild(t *testing.T) {
+ switch runtime.GOOS {
+ case "linux", "darwin":
+ default:
+ t.Skipf("Slow test, usually avoid it, os=%s not linux or darwin", runtime.GOOS)
+ }
+ switch runtime.GOARCH {
+ case "amd64", "arm64":
+ default:
+ t.Skipf("Slow test, usually avoid it, arch=%s not amd64 or arm64", runtime.GOARCH)
+ }
+
+ testenv.MustHaveGoBuild(t)
+ gocmd := testenv.GoToolPath(t)
+
+ // loopvar=3 logs info but does not change loopvarness
+ cmd := testenv.Command(t, gocmd, "run", "-gcflags=-lang=go1.22 -d=loopvar=3", "opt-121.go")
+ cmd.Dir = filepath.Join("testdata")
+
+ b, err := cmd.CombinedOutput()
+ m := string(b)
+
+ t.Logf(m) // expect error
+
+ yCount := strings.Count(m, "opt-121.go:18:6: loop variable private now per-iteration, heap-allocated (loop inlined into ./opt-121.go:32)")
+ nCount := strings.Count(m, "shared")
+
+ if yCount != 0 {
+ t.Errorf("yCount=%d != 0", yCount)
+ }
+ if nCount > 0 {
+ t.Errorf("nCount=%d > 0", nCount)
+ }
+ if err == nil { // expect error
+ t.Errorf("err=%v == nil", err)
+ }
}