Skip to content

Commit 19d700c

Browse files
Bryan C. Millsgopherbot
Bryan C. Mills
authored andcommitted
go/ssa/interp: use the actual GOOS and GOARCH to interpret tests
This incidentally uncovered a bug in the `fitsInt` helper function, which was computing the wrong bounds on 32-bit platforms (as if int were 4 bits instead of 4 bytes), which is also fixed. Fixes golang/go#60226 (hopefully). Change-Id: I56afdd3063dce233696f1e7a873dac4ee9ca231f Reviewed-on: https://go-review.googlesource.com/c/tools/+/495255 Reviewed-by: Robert Findley <[email protected]> Auto-Submit: Bryan Mills <[email protected]> Run-TryBot: Bryan Mills <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 9dcd3d5 commit 19d700c

File tree

2 files changed

+51
-77
lines changed

2 files changed

+51
-77
lines changed

go/ssa/interp/interp_test.go

Lines changed: 49 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ import (
2323
"log"
2424
"os"
2525
"path/filepath"
26+
"runtime"
2627
"strings"
2728
"testing"
2829
"time"
30+
"unsafe"
2931

3032
"golang.org/x/tools/go/loader"
3133
"golang.org/x/tools/go/ssa"
@@ -138,13 +140,7 @@ func init() {
138140
}
139141
}
140142

141-
// Specific GOARCH to use for a test case in go.tools/go/ssa/interp/testdata/.
142-
// Defaults to amd64 otherwise.
143-
var testdataArchs = map[string]string{
144-
"width32.go": "386",
145-
}
146-
147-
func run(t *testing.T, input string) bool {
143+
func run(t *testing.T, input string) {
148144
// The recover2 test case is broken on Go 1.14+. See golang/go#34089.
149145
// TODO(matloob): Fix this.
150146
if filepath.Base(input) == "recover2.go" {
@@ -157,16 +153,15 @@ func run(t *testing.T, input string) bool {
157153

158154
ctx := build.Default // copy
159155
ctx.GOROOT = "testdata" // fake goroot
160-
ctx.GOOS = "linux"
161-
ctx.GOARCH = "amd64"
162-
if arch, ok := testdataArchs[filepath.Base(input)]; ok {
163-
ctx.GOARCH = arch
156+
ctx.GOOS = runtime.GOOS
157+
ctx.GOARCH = runtime.GOARCH
158+
if filepath.Base(input) == "width32.go" && unsafe.Sizeof(int(0)) > 4 {
159+
t.Skipf("skipping: width32.go checks behavior for a 32-bit int")
164160
}
165161

166162
conf := loader.Config{Build: &ctx}
167163
if _, err := conf.FromArgs([]string{input}, true); err != nil {
168-
t.Errorf("FromArgs(%s) failed: %s", input, err)
169-
return false
164+
t.Fatalf("FromArgs(%s) failed: %s", input, err)
170165
}
171166

172167
conf.Import("runtime")
@@ -188,8 +183,7 @@ func run(t *testing.T, input string) bool {
188183

189184
iprog, err := conf.Load()
190185
if err != nil {
191-
t.Errorf("conf.Load(%s) failed: %s", input, err)
192-
return false
186+
t.Fatalf("conf.Load(%s) failed: %s", input, err)
193187
}
194188

195189
bmode := ssa.InstantiateGenerics | ssa.SanityCheckFunctions
@@ -205,6 +199,9 @@ func run(t *testing.T, input string) bool {
205199
interp.CapturedOutput = new(bytes.Buffer)
206200

207201
sizes := types.SizesFor("gc", ctx.GOARCH)
202+
if sizes.Sizeof(types.Typ[types.Int]) < 4 {
203+
panic("bogus SizesFor")
204+
}
208205
hint = fmt.Sprintf("To trace execution, run:\n%% go build golang.org/x/tools/cmd/ssadump && ./ssadump -build=C -test -run --interp=T %s\n", input)
209206
var imode interp.Mode // default mode
210207
// imode |= interp.DisableRecover // enable for debugging
@@ -223,17 +220,6 @@ func run(t *testing.T, input string) bool {
223220
if false {
224221
t.Log(input, time.Since(start)) // test profiling
225222
}
226-
227-
return true
228-
}
229-
230-
func printFailures(failures []string) {
231-
if failures != nil {
232-
fmt.Println("The following tests failed:")
233-
for _, f := range failures {
234-
fmt.Printf("\t%s\n", f)
235-
}
236-
}
237223
}
238224

239225
// TestTestdataFiles runs the interpreter on testdata/*.go.
@@ -242,25 +228,20 @@ func TestTestdataFiles(t *testing.T) {
242228
if err != nil {
243229
log.Fatal(err)
244230
}
245-
var failures []string
246231
for _, input := range testdataTests {
247-
if !run(t, filepath.Join(cwd, "testdata", input)) {
248-
failures = append(failures, input)
249-
}
232+
t.Run(input, func(t *testing.T) {
233+
run(t, filepath.Join(cwd, "testdata", input))
234+
})
250235
}
251-
printFailures(failures)
252236
}
253237

254238
// TestGorootTest runs the interpreter on $GOROOT/test/*.go.
255239
func TestGorootTest(t *testing.T) {
256-
var failures []string
257-
258240
for _, input := range gorootTestTests {
259-
if !run(t, filepath.Join(build.Default.GOROOT, "test", input)) {
260-
failures = append(failures, input)
261-
}
241+
t.Run(input, func(t *testing.T) {
242+
run(t, filepath.Join(build.Default.GOROOT, "test", input))
243+
})
262244
}
263-
printFailures(failures)
264245
}
265246

266247
// TestTypeparamTest runs the interpreter on runnable examples
@@ -274,54 +255,47 @@ func TestTypeparamTest(t *testing.T) {
274255
// Skip known failures for the given reason.
275256
// TODO(taking): Address these.
276257
skip := map[string]string{
277-
"chans.go": "interp tests do not support runtime.SetFinalizer",
278-
"issue23536.go": "unknown reason",
279-
"issue376214.go": "unknown issue with variadic cast on bytes",
280-
"issue48042.go": "interp tests do not handle reflect.Value.SetInt",
281-
"issue47716.go": "interp tests do not handle unsafe.Sizeof",
282-
"issue50419.go": "interp tests do not handle dispatch to String() correctly",
283-
"issue51733.go": "interp does not handle unsafe casts",
284-
"ordered.go": "math.NaN() comparisons not being handled correctly",
285-
"orderedmap.go": "interp tests do not support runtime.SetFinalizer",
286-
"stringer.go": "unknown reason",
287-
"issue48317.go": "interp tests do not support encoding/json",
288-
"issue48318.go": "interp tests do not support encoding/json",
289-
"issue58513.go": "interp tests do not support runtime.Caller",
258+
"chans.go": "interp tests do not support runtime.SetFinalizer",
259+
"issue23536.go": "unknown reason",
260+
"issue48042.go": "interp tests do not handle reflect.Value.SetInt",
261+
"issue47716.go": "interp tests do not handle unsafe.Sizeof",
262+
"issue50419.go": "interp tests do not handle dispatch to String() correctly",
263+
"issue51733.go": "interp does not handle unsafe casts",
264+
"ordered.go": "math.NaN() comparisons not being handled correctly",
265+
"orderedmap.go": "interp tests do not support runtime.SetFinalizer",
266+
"stringer.go": "unknown reason",
267+
"issue48317.go": "interp tests do not support encoding/json",
268+
"issue48318.go": "interp tests do not support encoding/json",
269+
"issue58513.go": "interp tests do not support runtime.Caller",
290270
}
291271
// Collect all of the .go files in dir that are runnable.
292272
dir := filepath.Join(build.Default.GOROOT, "test", "typeparam")
293273
list, err := os.ReadDir(dir)
294274
if err != nil {
295275
t.Fatal(err)
296276
}
297-
var inputs []string
298277
for _, entry := range list {
299278
if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".go") {
300279
continue // Consider standalone go files.
301280
}
302-
if reason := skip[entry.Name()]; reason != "" {
303-
t.Logf("skipping %q due to %s.", entry.Name(), reason)
304-
continue
305-
}
306-
input := filepath.Join(dir, entry.Name())
307-
src, err := os.ReadFile(input)
308-
if err != nil {
309-
t.Fatal(err)
310-
}
311-
// Only build test files that can be compiled, or compiled and run.
312-
if bytes.HasPrefix(src, []byte("// run")) && !bytes.HasPrefix(src, []byte("// rundir")) {
313-
inputs = append(inputs, input)
314-
} else {
315-
t.Logf("Not a `// run` file: %s", entry.Name())
316-
}
317-
}
318-
319-
var failures []string
320-
for _, input := range inputs {
321-
t.Log("running", input)
322-
if !run(t, input) {
323-
failures = append(failures, input)
324-
}
281+
t.Run(entry.Name(), func(t *testing.T) {
282+
input := filepath.Join(dir, entry.Name())
283+
src, err := os.ReadFile(input)
284+
if err != nil {
285+
t.Fatal(err)
286+
}
287+
288+
// Only build test files that can be compiled, or compiled and run.
289+
if !bytes.HasPrefix(src, []byte("// run")) || bytes.HasPrefix(src, []byte("// rundir")) {
290+
t.Logf("Not a `// run` file: %s", entry.Name())
291+
return
292+
}
293+
294+
if reason := skip[entry.Name()]; reason != "" {
295+
t.Skipf("skipping: %s", reason)
296+
}
297+
298+
run(t, input)
299+
})
325300
}
326-
printFailures(failures)
327301
}

go/ssa/interp/ops.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ func constValue(c *ssa.Const) value {
9292
func fitsInt(x int64, sizes types.Sizes) bool {
9393
intSize := sizes.Sizeof(types.Typ[types.Int])
9494
if intSize < sizes.Sizeof(types.Typ[types.Int64]) {
95-
maxInt := int64(1)<<(intSize-1) - 1
96-
minInt := -int64(1) << (intSize - 1)
95+
maxInt := int64(1)<<((intSize*8)-1) - 1
96+
minInt := -int64(1) << ((intSize * 8) - 1)
9797
return minInt <= x && x <= maxInt
9898
}
9999
return true

0 commit comments

Comments
 (0)