Name: "cftype.localVariable",
In: `package main
+// typedef const void *CFTypeRef;
import "C"
func f() {
`,
Out: `package main
+// typedef const void *CFTypeRef;
import "C"
func f() {
Name: "cftype.globalVariable",
In: `package main
+// typedef const void *CFTypeRef;
import "C"
var x C.CFTypeRef = nil
`,
Out: `package main
+// typedef const void *CFTypeRef;
import "C"
var x C.CFTypeRef = 0
Name: "cftype.EqualArgument",
In: `package main
+// typedef const void *CFTypeRef;
import "C"
var x C.CFTypeRef
`,
Out: `package main
+// typedef const void *CFTypeRef;
import "C"
var x C.CFTypeRef
Name: "cftype.StructField",
In: `package main
+// typedef const void *CFTypeRef;
import "C"
type T struct {
`,
Out: `package main
+// typedef const void *CFTypeRef;
import "C"
type T struct {
Name: "cftype.FunctionArgument",
In: `package main
+// typedef const void *CFTypeRef;
import "C"
func f(x C.CFTypeRef) {
`,
Out: `package main
+// typedef const void *CFTypeRef;
import "C"
func f(x C.CFTypeRef) {
Name: "cftype.ArrayElement",
In: `package main
+// typedef const void *CFTypeRef;
import "C"
var x = [3]C.CFTypeRef{nil, nil, nil}
`,
Out: `package main
+// typedef const void *CFTypeRef;
import "C"
var x = [3]C.CFTypeRef{0, 0, 0}
Name: "cftype.SliceElement",
In: `package main
+// typedef const void *CFTypeRef;
import "C"
var x = []C.CFTypeRef{nil, nil, nil}
`,
Out: `package main
+// typedef const void *CFTypeRef;
import "C"
var x = []C.CFTypeRef{0, 0, 0}
Name: "cftype.MapKey",
In: `package main
+// typedef const void *CFTypeRef;
import "C"
var x = map[C.CFTypeRef]int{nil: 0}
`,
Out: `package main
+// typedef const void *CFTypeRef;
import "C"
var x = map[C.CFTypeRef]int{0: 0}
Name: "cftype.MapValue",
In: `package main
+// typedef const void *CFTypeRef;
import "C"
var x = map[int]C.CFTypeRef{0: nil}
`,
Out: `package main
+// typedef const void *CFTypeRef;
import "C"
var x = map[int]C.CFTypeRef{0: 0}
Name: "cftype.Conversion1",
In: `package main
+// typedef const void *CFTypeRef;
import "C"
var x C.CFTypeRef
`,
Out: `package main
+// typedef const void *CFTypeRef;
import "C"
var x C.CFTypeRef
Name: "cftype.Conversion2",
In: `package main
+// typedef const void *CFTypeRef;
import "C"
var x unsafe.Pointer
`,
Out: `package main
+// typedef const void *CFTypeRef;
import "C"
var x unsafe.Pointer
Name: "egl.localVariable",
In: `package main
+// typedef void *$EGLTYPE;
import "C"
func f() {
`,
Out: `package main
+// typedef void *$EGLTYPE;
import "C"
func f() {
Name: "egl.globalVariable",
In: `package main
+// typedef void *$EGLTYPE;
import "C"
var x C.$EGLTYPE = nil
`,
Out: `package main
+// typedef void *$EGLTYPE;
import "C"
var x C.$EGLTYPE = 0
Name: "egl.EqualArgument",
In: `package main
+// typedef void *$EGLTYPE;
import "C"
var x C.$EGLTYPE
`,
Out: `package main
+// typedef void *$EGLTYPE;
import "C"
var x C.$EGLTYPE
Name: "egl.StructField",
In: `package main
+// typedef void *$EGLTYPE;
import "C"
type T struct {
`,
Out: `package main
+// typedef void *$EGLTYPE;
import "C"
type T struct {
Name: "egl.FunctionArgument",
In: `package main
+// typedef void *$EGLTYPE;
import "C"
func f(x C.$EGLTYPE) {
`,
Out: `package main
+// typedef void *$EGLTYPE;
import "C"
func f(x C.$EGLTYPE) {
Name: "egl.ArrayElement",
In: `package main
+// typedef void *$EGLTYPE;
import "C"
var x = [3]C.$EGLTYPE{nil, nil, nil}
`,
Out: `package main
+// typedef void *$EGLTYPE;
import "C"
var x = [3]C.$EGLTYPE{0, 0, 0}
Name: "egl.SliceElement",
In: `package main
+// typedef void *$EGLTYPE;
import "C"
var x = []C.$EGLTYPE{nil, nil, nil}
`,
Out: `package main
+// typedef void *$EGLTYPE;
import "C"
var x = []C.$EGLTYPE{0, 0, 0}
Name: "egl.MapKey",
In: `package main
+// typedef void *$EGLTYPE;
import "C"
var x = map[C.$EGLTYPE]int{nil: 0}
`,
Out: `package main
+// typedef void *$EGLTYPE;
import "C"
var x = map[C.$EGLTYPE]int{0: 0}
Name: "egl.MapValue",
In: `package main
+// typedef void *$EGLTYPE;
import "C"
var x = map[int]C.$EGLTYPE{0: nil}
`,
Out: `package main
+// typedef void *$EGLTYPE;
import "C"
var x = map[int]C.$EGLTYPE{0: 0}
Name: "jni.localVariable",
In: `package main
+// typedef struct _jobject* jobject;
import "C"
func f() {
`,
Out: `package main
+// typedef struct _jobject* jobject;
import "C"
func f() {
Name: "jni.globalVariable",
In: `package main
+// typedef struct _jobject* jobject;
import "C"
var x C.jobject = nil
`,
Out: `package main
+// typedef struct _jobject* jobject;
import "C"
var x C.jobject = 0
Name: "jni.EqualArgument",
In: `package main
+// typedef struct _jobject* jobject;
import "C"
var x C.jobject
`,
Out: `package main
+// typedef struct _jobject* jobject;
import "C"
var x C.jobject
Name: "jni.StructField",
In: `package main
+// typedef struct _jobject* jobject;
import "C"
type T struct {
`,
Out: `package main
+// typedef struct _jobject* jobject;
import "C"
type T struct {
Name: "jni.FunctionArgument",
In: `package main
+// typedef struct _jobject* jobject;
import "C"
func f(x C.jobject) {
`,
Out: `package main
+// typedef struct _jobject* jobject;
import "C"
func f(x C.jobject) {
Name: "jni.ArrayElement",
In: `package main
+// typedef struct _jobject* jobject;
import "C"
var x = [3]C.jobject{nil, nil, nil}
`,
Out: `package main
+// typedef struct _jobject* jobject;
import "C"
var x = [3]C.jobject{0, 0, 0}
Name: "jni.SliceElement",
In: `package main
+// typedef struct _jobject* jobject;
import "C"
var x = []C.jobject{nil, nil, nil}
`,
Out: `package main
+// typedef struct _jobject* jobject;
import "C"
var x = []C.jobject{0, 0, 0}
Name: "jni.MapKey",
In: `package main
+// typedef struct _jobject* jobject;
import "C"
var x = map[C.jobject]int{nil: 0}
`,
Out: `package main
+// typedef struct _jobject* jobject;
import "C"
var x = map[C.jobject]int{0: 0}
Name: "jni.MapValue",
In: `package main
+// typedef struct _jobject* jobject;
import "C"
var x = map[int]C.jobject{0: nil}
`,
Out: `package main
+// typedef struct _jobject* jobject;
import "C"
var x = map[int]C.jobject{0: 0}
package main
import (
+ "fmt"
"go/ast"
"go/parser"
"internal/diff"
+ "internal/testenv"
"strings"
"testing"
)
+func init() {
+ // If cgo is enabled, enforce that cgo commands invoked by cmd/fix
+ // do not fail during testing.
+ if testenv.HasCGO() {
+ // The reportCgoError hook is global, so we can't set it per-test
+ // if we want to be able to run those tests in parallel.
+ // Instead, simply set it to panic on error: the goroutine dump
+ // from the panic should help us determine which test failed.
+ reportCgoError = func(err error) {
+ panic(fmt.Sprintf("unexpected cgo error: %v", err))
+ }
+ }
+}
+
type testCase struct {
Name string
Fn func(*ast.File) bool
tt := tt
t.Run(tt.Name, func(t *testing.T) {
if tt.Version == 0 {
- t.Parallel()
+ if testing.Verbose() {
+ // Don't run in parallel: cmd/fix sometimes writes directly to stderr,
+ // and since -v prints which test is currently running we want that
+ // information to accurately correlate with the stderr output.
+ } else {
+ t.Parallel()
+ }
} else {
old := goVersion
goVersion = tt.Version
if err != nil {
return err
}
- cmd := exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), "tool", "cgo", "-objdir", dir, "-srcdir", dir, "in.go")
+ goCmd := "go"
+ if goroot := runtime.GOROOT(); goroot != "" {
+ goCmd = filepath.Join(goroot, "bin", "go")
+ }
+ cmd := exec.Command(goCmd, "tool", "cgo", "-objdir", dir, "-srcdir", dir, "in.go")
+ if reportCgoError != nil {
+ // Since cgo command errors will be reported, also forward the error
+ // output from the command for debugging.
+ cmd.Stderr = os.Stderr
+ }
err = cmd.Run()
if err != nil {
return err
return nil
}()
if err != nil {
- fmt.Fprintf(os.Stderr, "go fix: warning: no cgo types: %s\n", err)
+ if reportCgoError == nil {
+ fmt.Fprintf(os.Stderr, "go fix: warning: no cgo types: %s\n", err)
+ } else {
+ reportCgoError(err)
+ }
}
}
return typeof, assign
}
+// reportCgoError, if non-nil, reports a non-nil error from running the "cgo"
+// tool. (Set to a non-nil hook during testing if cgo is expected to work.)
+var reportCgoError func(err error)
+
func makeExprList(a []*ast.Ident) []ast.Expr {
var b []ast.Expr
for _, x := range a {