// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Check for invalid cgo pointer passing.
// This looks for code that uses cgo to call C code passing values
// whose types are almost always invalid according to the cgo pointer
// sharing rules.
// Specifically, it warns about attempts to pass a Go chan, map, func,
// or slice to C, either directly, or via a pointer, array, or struct.

package main

import (
	"go/ast"
	"go/token"
	"go/types"
)

func init() {
	register("cgocall",
		"check for types that may not be passed to cgo calls",
		checkCgoCall,
		callExpr)
}

func checkCgoCall(f *File, node ast.Node) {
	x := node.(*ast.CallExpr)

	// We are only looking for calls to functions imported from
	// the "C" package.
	sel, ok := x.Fun.(*ast.SelectorExpr)
	if !ok {
		return
	}
	id, ok := sel.X.(*ast.Ident)
	if !ok || id.Name != "C" {
		return
	}

	// A call to C.CBytes passes a pointer but is always safe.
	if sel.Sel.Name == "CBytes" {
		return
	}

	for _, arg := range x.Args {
		if !typeOKForCgoCall(cgoBaseType(f, arg), make(map[types.Type]bool)) {
			f.Badf(arg.Pos(), "possibly passing Go type with embedded pointer to C")
		}

		// Check for passing the address of a bad type.
		if conv, ok := arg.(*ast.CallExpr); ok && len(conv.Args) == 1 && f.hasBasicType(conv.Fun, types.UnsafePointer) {
			arg = conv.Args[0]
		}
		if u, ok := arg.(*ast.UnaryExpr); ok && u.Op == token.AND {
			if !typeOKForCgoCall(cgoBaseType(f, u.X), make(map[types.Type]bool)) {
				f.Badf(arg.Pos(), "possibly passing Go type with embedded pointer to C")
			}
		}
	}
}

// cgoBaseType tries to look through type conversions involving
// unsafe.Pointer to find the real type. It converts:
//   unsafe.Pointer(x) => x
//   *(*unsafe.Pointer)(unsafe.Pointer(&x)) => x
func cgoBaseType(f *File, arg ast.Expr) types.Type {
	switch arg := arg.(type) {
	case *ast.CallExpr:
		if len(arg.Args) == 1 && f.hasBasicType(arg.Fun, types.UnsafePointer) {
			return cgoBaseType(f, arg.Args[0])
		}
	case *ast.StarExpr:
		call, ok := arg.X.(*ast.CallExpr)
		if !ok || len(call.Args) != 1 {
			break
		}
		// Here arg is *f(v).
		t := f.pkg.types[call.Fun].Type
		if t == nil {
			break
		}
		ptr, ok := t.Underlying().(*types.Pointer)
		if !ok {
			break
		}
		// Here arg is *(*p)(v)
		elem, ok := ptr.Elem().Underlying().(*types.Basic)
		if !ok || elem.Kind() != types.UnsafePointer {
			break
		}
		// Here arg is *(*unsafe.Pointer)(v)
		call, ok = call.Args[0].(*ast.CallExpr)
		if !ok || len(call.Args) != 1 {
			break
		}
		// Here arg is *(*unsafe.Pointer)(f(v))
		if !f.hasBasicType(call.Fun, types.UnsafePointer) {
			break
		}
		// Here arg is *(*unsafe.Pointer)(unsafe.Pointer(v))
		u, ok := call.Args[0].(*ast.UnaryExpr)
		if !ok || u.Op != token.AND {
			break
		}
		// Here arg is *(*unsafe.Pointer)(unsafe.Pointer(&v))
		return cgoBaseType(f, u.X)
	}

	return f.pkg.types[arg].Type
}

// 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. 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(), m)
	case *types.Array:
		return typeOKForCgoCall(t.Elem(), m)
	case *types.Struct:
		for i := 0; i < t.NumFields(); i++ {
			if !typeOKForCgoCall(t.Field(i).Type(), m) {
				return false
			}
		}
	}
	return true
}
