@@ -51,7 +51,7 @@ var cases = []testcase{
51
51
}
52
52
53
53
// TestLoopVar checks that the GOEXPERIMENT and debug flags behave as expected.
54
- func TestLoopVar (t * testing.T ) {
54
+ func TestLoopVarGo1_21 (t * testing.T ) {
55
55
switch runtime .GOOS {
56
56
case "linux" , "darwin" :
57
57
default :
@@ -71,7 +71,7 @@ func TestLoopVar(t *testing.T) {
71
71
for i , tc := range cases {
72
72
for _ , f := range tc .files {
73
73
source := f
74
- cmd := testenv .Command (t , gocmd , "build" , "-o" , output , "-gcflags=-d=loopvar=" + tc .lvFlag , source )
74
+ cmd := testenv .Command (t , gocmd , "build" , "-o" , output , "-gcflags=-lang=go1.21 - d=loopvar=" + tc .lvFlag , source )
75
75
cmd .Env = append (cmd .Env , "GOEXPERIMENT=loopvar" , "HOME=" + tmpdir )
76
76
cmd .Dir = "testdata"
77
77
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) {
103
103
}
104
104
}
105
105
106
- func TestLoopVarInlines (t * testing.T ) {
106
+ func TestLoopVarInlinesGo1_21 (t * testing.T ) {
107
107
switch runtime .GOOS {
108
108
case "linux" , "darwin" :
109
109
default :
@@ -125,7 +125,7 @@ func TestLoopVarInlines(t *testing.T) {
125
125
// This disables the loopvar change, except for the specified package.
126
126
// The effect should follow the package, even though everything (except "c")
127
127
// is inlined.
128
- cmd := testenv .Command (t , gocmd , "run" , "-gcflags=" + pkg + "=-d=loopvar=1" , root )
128
+ cmd := testenv .Command (t , gocmd , "run" , "-gcflags=" + root + "/...=-lang=go1.21" , "-gcflags=" + pkg + "=-d=loopvar=1" , root )
129
129
cmd .Env = append (cmd .Env , "GOEXPERIMENT=noloopvar" , "HOME=" + tmpdir )
130
130
cmd .Dir = filepath .Join ("testdata" , "inlines" )
131
131
@@ -166,6 +166,7 @@ func countMatches(s, re string) int {
166
166
}
167
167
168
168
func TestLoopVarHashes (t * testing.T ) {
169
+ // This behavior does not depend on Go version (1.21 or greater)
169
170
switch runtime .GOOS {
170
171
case "linux" , "darwin" :
171
172
default :
@@ -187,7 +188,7 @@ func TestLoopVarHashes(t *testing.T) {
187
188
// This disables the loopvar change, except for the specified hash pattern.
188
189
// -trimpath is necessary so we get the same answer no matter where the
189
190
// Go repository is checked out. This is not normally a concern since people
190
- // do not rely on the meaning of specific hashes.
191
+ // do not normally rely on the meaning of specific hashes.
191
192
cmd := testenv .Command (t , gocmd , "run" , "-trimpath" , root )
192
193
cmd .Env = append (cmd .Env , "GOCOMPILEDEBUG=loopvarhash=" + hash , "HOME=" + tmpdir )
193
194
cmd .Dir = filepath .Join ("testdata" , "inlines" )
@@ -225,7 +226,8 @@ func TestLoopVarHashes(t *testing.T) {
225
226
}
226
227
}
227
228
228
- func TestLoopVarOpt (t * testing.T ) {
229
+ // TestLoopVarVersionEnableFlag checks for loopvar transformation enabled by command line flag (1.22).
230
+ func TestLoopVarVersionEnableFlag (t * testing.T ) {
229
231
switch runtime .GOOS {
230
232
case "linux" , "darwin" :
231
233
default :
@@ -240,7 +242,8 @@ func TestLoopVarOpt(t *testing.T) {
240
242
testenv .MustHaveGoBuild (t )
241
243
gocmd := testenv .GoToolPath (t )
242
244
243
- cmd := testenv .Command (t , gocmd , "run" , "-gcflags=-d=loopvar=2" , "opt.go" )
245
+ // loopvar=3 logs info but does not change loopvarness
246
+ cmd := testenv .Command (t , gocmd , "run" , "-gcflags=-lang=go1.22 -d=loopvar=3" , "opt.go" )
244
247
cmd .Dir = filepath .Join ("testdata" )
245
248
246
249
b , err := cmd .CombinedOutput ()
@@ -260,5 +263,121 @@ func TestLoopVarOpt(t *testing.T) {
260
263
if err != nil {
261
264
t .Errorf ("err=%v != nil" , err )
262
265
}
266
+ }
267
+
268
+ // TestLoopVarVersionEnableGoBuild checks for loopvar transformation enabled by go:build version (1.22).
269
+ func TestLoopVarVersionEnableGoBuild (t * testing.T ) {
270
+ switch runtime .GOOS {
271
+ case "linux" , "darwin" :
272
+ default :
273
+ t .Skipf ("Slow test, usually avoid it, os=%s not linux or darwin" , runtime .GOOS )
274
+ }
275
+ switch runtime .GOARCH {
276
+ case "amd64" , "arm64" :
277
+ default :
278
+ t .Skipf ("Slow test, usually avoid it, arch=%s not amd64 or arm64" , runtime .GOARCH )
279
+ }
280
+
281
+ testenv .MustHaveGoBuild (t )
282
+ gocmd := testenv .GoToolPath (t )
283
+
284
+ // loopvar=3 logs info but does not change loopvarness
285
+ cmd := testenv .Command (t , gocmd , "run" , "-gcflags=-lang=go1.21 -d=loopvar=3" , "opt-122.go" )
286
+ cmd .Dir = filepath .Join ("testdata" )
287
+
288
+ b , err := cmd .CombinedOutput ()
289
+ m := string (b )
290
+
291
+ t .Logf (m )
292
+
293
+ yCount := strings .Count (m , "opt-122.go:18:6: loop variable private now per-iteration, heap-allocated (loop inlined into ./opt-122.go:32)" )
294
+ nCount := strings .Count (m , "shared" )
295
+
296
+ if yCount != 1 {
297
+ t .Errorf ("yCount=%d != 1" , yCount )
298
+ }
299
+ if nCount > 0 {
300
+ t .Errorf ("nCount=%d > 0" , nCount )
301
+ }
302
+ if err != nil {
303
+ t .Errorf ("err=%v != nil" , err )
304
+ }
305
+ }
306
+
307
+ // TestLoopVarVersionDisableFlag checks for loopvar transformation DISABLED by command line version (1.21).
308
+ func TestLoopVarVersionDisableFlag (t * testing.T ) {
309
+ switch runtime .GOOS {
310
+ case "linux" , "darwin" :
311
+ default :
312
+ t .Skipf ("Slow test, usually avoid it, os=%s not linux or darwin" , runtime .GOOS )
313
+ }
314
+ switch runtime .GOARCH {
315
+ case "amd64" , "arm64" :
316
+ default :
317
+ t .Skipf ("Slow test, usually avoid it, arch=%s not amd64 or arm64" , runtime .GOARCH )
318
+ }
263
319
320
+ testenv .MustHaveGoBuild (t )
321
+ gocmd := testenv .GoToolPath (t )
322
+
323
+ // loopvar=3 logs info but does not change loopvarness
324
+ cmd := testenv .Command (t , gocmd , "run" , "-gcflags=-lang=go1.21 -d=loopvar=3" , "opt.go" )
325
+ cmd .Dir = filepath .Join ("testdata" )
326
+
327
+ b , err := cmd .CombinedOutput ()
328
+ m := string (b )
329
+
330
+ t .Logf (m ) // expect error
331
+
332
+ yCount := strings .Count (m , "opt.go:16:6: loop variable private now per-iteration, heap-allocated (loop inlined into ./opt.go:30)" )
333
+ nCount := strings .Count (m , "shared" )
334
+
335
+ if yCount != 0 {
336
+ t .Errorf ("yCount=%d != 0" , yCount )
337
+ }
338
+ if nCount > 0 {
339
+ t .Errorf ("nCount=%d > 0" , nCount )
340
+ }
341
+ if err == nil { // expect error
342
+ t .Errorf ("err=%v == nil" , err )
343
+ }
344
+ }
345
+
346
+ // TestLoopVarVersionDisableGoBuild checks for loopvar transformation DISABLED by go:build version (1.21).
347
+ func TestLoopVarVersionDisableGoBuild (t * testing.T ) {
348
+ switch runtime .GOOS {
349
+ case "linux" , "darwin" :
350
+ default :
351
+ t .Skipf ("Slow test, usually avoid it, os=%s not linux or darwin" , runtime .GOOS )
352
+ }
353
+ switch runtime .GOARCH {
354
+ case "amd64" , "arm64" :
355
+ default :
356
+ t .Skipf ("Slow test, usually avoid it, arch=%s not amd64 or arm64" , runtime .GOARCH )
357
+ }
358
+
359
+ testenv .MustHaveGoBuild (t )
360
+ gocmd := testenv .GoToolPath (t )
361
+
362
+ // loopvar=3 logs info but does not change loopvarness
363
+ cmd := testenv .Command (t , gocmd , "run" , "-gcflags=-lang=go1.22 -d=loopvar=3" , "opt-121.go" )
364
+ cmd .Dir = filepath .Join ("testdata" )
365
+
366
+ b , err := cmd .CombinedOutput ()
367
+ m := string (b )
368
+
369
+ t .Logf (m ) // expect error
370
+
371
+ yCount := strings .Count (m , "opt-121.go:18:6: loop variable private now per-iteration, heap-allocated (loop inlined into ./opt-121.go:32)" )
372
+ nCount := strings .Count (m , "shared" )
373
+
374
+ if yCount != 0 {
375
+ t .Errorf ("yCount=%d != 0" , yCount )
376
+ }
377
+ if nCount > 0 {
378
+ t .Errorf ("nCount=%d > 0" , nCount )
379
+ }
380
+ if err == nil { // expect error
381
+ t .Errorf ("err=%v == nil" , err )
382
+ }
264
383
}
0 commit comments