diff options
Diffstat (limited to 'src/cmd/vet/cgo.go')
-rw-r--r-- | src/cmd/vet/cgo.go | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/src/cmd/vet/cgo.go b/src/cmd/vet/cgo.go index d233e9a960..984911c489 100644 --- a/src/cmd/vet/cgo.go +++ b/src/cmd/vet/cgo.go @@ -44,7 +44,7 @@ func checkCgoCall(f *File, node ast.Node) { } for _, arg := range x.Args { - if !typeOKForCgoCall(cgoBaseType(f, arg)) { + if !typeOKForCgoCall(cgoBaseType(f, arg), make(map[types.Type]bool)) { f.Badf(arg.Pos(), "possibly passing Go type with embedded pointer to C") } @@ -53,7 +53,7 @@ func checkCgoCall(f *File, node ast.Node) { arg = conv.Args[0] } if u, ok := arg.(*ast.UnaryExpr); ok && u.Op == token.AND { - if !typeOKForCgoCall(cgoBaseType(f, u.X)) { + if !typeOKForCgoCall(cgoBaseType(f, u.X), make(map[types.Type]bool)) { f.Badf(arg.Pos(), "possibly passing Go type with embedded pointer to C") } } @@ -110,23 +110,24 @@ func cgoBaseType(f *File, arg ast.Expr) types.Type { return f.pkg.types[arg].Type } -// typeOKForCgoCall returns true if the type of arg is OK to pass to a +// typeOKForCgoCall reports whether the type of arg is OK to pass to a // C function using cgo. This is not true for Go types with embedded -// pointers. -func typeOKForCgoCall(t types.Type) bool { - if t == nil { +// pointers. m is used to avoid infinite recursion on recursive types. +func typeOKForCgoCall(t types.Type, m map[types.Type]bool) bool { + if t == nil || m[t] { return true } + m[t] = true switch t := t.Underlying().(type) { case *types.Chan, *types.Map, *types.Signature, *types.Slice: return false case *types.Pointer: - return typeOKForCgoCall(t.Elem()) + return typeOKForCgoCall(t.Elem(), m) case *types.Array: - return typeOKForCgoCall(t.Elem()) + return typeOKForCgoCall(t.Elem(), m) case *types.Struct: for i := 0; i < t.NumFields(); i++ { - if !typeOKForCgoCall(t.Field(i).Type()) { + if !typeOKForCgoCall(t.Field(i).Type(), m) { return false } } |