diff options
| author | David Chase <drchase@google.com> | 2023-07-05 16:21:19 -0400 |
|---|---|---|
| committer | David Chase <drchase@google.com> | 2023-08-08 21:20:26 +0000 |
| commit | fe1daf2e439ec1d650ea1193f10f52525f83f8a7 (patch) | |
| tree | 4db784376b586aa2a60b2ed79fde7889c557273b /src/cmd/compile/internal/loopvar/loopvar_test.go | |
| parent | 6d8d88a70716bd35708748ba4e0110bdcd9520f3 (diff) | |
| download | go-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.go | 133 |
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) + } } |
