// 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.

// Package cgocall defines an Analyzer that detects some violations of
// the cgo pointer passing rules.
package cgocall

import (
	"fmt"
	"go/ast"
	"go/format"
	"go/parser"
	"go/token"
	"go/types"
	"log"
	"os"
	"runtime"
	"strconv"

	"golang.org/x/tools/go/analysis"
	"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
)

const debug = false

const Doc = `detect some violations of the cgo pointer passing rules

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.`

var Analyzer = &analysis.Analyzer{
	Name:             "cgocall",
	Doc:              Doc,
	RunDespiteErrors: true,
	Run:              run,
}

func run(pass *analysis.Pass) (interface{}, error) {
	if runtime.Compiler != "gccgo" && !analysisutil.Imports(pass.Pkg, "runtime/cgo") {
		return nil, nil // doesn't use cgo
	}

	cgofiles, info, err := typeCheckCgoSourceFiles(pass.Fset, pass.Pkg, pass.Files, pass.TypesInfo, pass.TypesSizes)
	if err != nil {
		return nil, err
	}
	for _, f := range cgofiles {
		checkCgo(pass.Fset, f, info, pass.Reportf)
	}
	return nil, nil
}

func checkCgo(fset *token.FileSet, f *ast.File, info *types.Info, reportf func(token.Pos, string, ...interface{})) {
	ast.Inspect(f, func(n ast.Node) bool {
		call, ok := n.(*ast.CallExpr)
		if !ok {
			return true
		}

		// Is this a C.f() call?
		var name string
		if sel, ok := analysisutil.Unparen(call.Fun).(*ast.SelectorExpr); ok {
			if id, ok := sel.X.(*ast.Ident); ok && id.Name == "C" {
				name = sel.Sel.Name
			}
		}
		if name == "" {
			return true // not a call we need to check
		}

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

		if debug {
			log.Printf("%s: call to C.%s", fset.Position(call.Lparen), name)
		}

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

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

// typeCheckCgoSourceFiles returns type-checked syntax trees for the raw
// cgo files of a package (those that import "C"). Such files are not
// Go, so there may be gaps in type information around C.f references.
//
// This checker was initially written in vet to inspect raw cgo source
// files using partial type information. However, Analyzers in the new
// analysis API are presented with the type-checked, "cooked" Go ASTs
// resulting from cgo-processing files, so we must choose between
// working with the cooked file generated by cgo (which was tried but
// proved fragile) or locating the raw cgo file (e.g. from //line
// directives) and working with that, as we now do.
//
// Specifically, we must type-check the raw cgo source files (or at
// least the subtrees needed for this analyzer) in an environment that
// simulates the rest of the already type-checked package.
//
// For example, for each raw cgo source file in the original package,
// such as this one:
//
// 	package p
// 	import "C"
//	import "fmt"
//	type T int
//	const k = 3
//	var x, y = fmt.Println()
//	func f() { ... }
//	func g() { ... C.malloc(k) ... }
//	func (T) f(int) string { ... }
//
// we synthesize a new ast.File, shown below, that dot-imports the
// original "cooked" package using a special name ("·this·"), so that all
// references to package members resolve correctly. (References to
// unexported names cause an "unexported" error, which we ignore.)
//
// To avoid shadowing names imported from the cooked package,
// package-level declarations in the new source file are modified so
// that they do not declare any names.
// (The cgocall analysis is concerned with uses, not declarations.)
// Specifically, type declarations are discarded;
// all names in each var and const declaration are blanked out;
// each method is turned into a regular function by turning
// the receiver into the first parameter;
// and all functions are renamed to "_".
//
// 	package p
// 	import . "·this·" // declares T, k, x, y, f, g, T.f
// 	import "C"
//	import "fmt"
//	const _ = 3
//	var _, _ = fmt.Println()
//	func _() { ... }
//	func _() { ... C.malloc(k) ... }
//	func _(T, int) string { ... }
//
// In this way, the raw function bodies and const/var initializer
// expressions are preserved but refer to the "cooked" objects imported
// from "·this·", and none of the transformed package-level declarations
// actually declares anything. In the example above, the reference to k
// in the argument of the call to C.malloc resolves to "·this·".k, which
// has an accurate type.
//
// This approach could in principle be generalized to more complex
// analyses on raw cgo files. One could synthesize a "C" package so that
// C.f would resolve to "·this·"._C_func_f, for example. But we have
// limited ourselves here to preserving function bodies and initializer
// expressions since that is all that the cgocall analyzer needs.
//
func typeCheckCgoSourceFiles(fset *token.FileSet, pkg *types.Package, files []*ast.File, info *types.Info, sizes types.Sizes) ([]*ast.File, *types.Info, error) {
	const thispkg = "·this·"

	// Which files are cgo files?
	var cgoFiles []*ast.File
	importMap := map[string]*types.Package{thispkg: pkg}
	for _, raw := range files {
		// If f is a cgo-generated file, Position reports
		// the original file, honoring //line directives.
		filename := fset.Position(raw.Pos()).Filename
		f, err := parser.ParseFile(fset, filename, nil, parser.Mode(0))
		if err != nil {
			return nil, nil, fmt.Errorf("can't parse raw cgo file: %v", err)
		}
		found := false
		for _, spec := range f.Imports {
			if spec.Path.Value == `"C"` {
				found = true
				break
			}
		}
		if !found {
			continue // not a cgo file
		}

		// Record the original import map.
		for _, spec := range raw.Imports {
			path, _ := strconv.Unquote(spec.Path.Value)
			importMap[path] = imported(info, spec)
		}

		// Add special dot-import declaration:
		//    import . "·this·"
		var decls []ast.Decl
		decls = append(decls, &ast.GenDecl{
			Tok: token.IMPORT,
			Specs: []ast.Spec{
				&ast.ImportSpec{
					Name: &ast.Ident{Name: "."},
					Path: &ast.BasicLit{
						Kind:  token.STRING,
						Value: strconv.Quote(thispkg),
					},
				},
			},
		})

		// Transform declarations from the raw cgo file.
		for _, decl := range f.Decls {
			switch decl := decl.(type) {
			case *ast.GenDecl:
				switch decl.Tok {
				case token.TYPE:
					// Discard type declarations.
					continue
				case token.IMPORT:
					// Keep imports.
				case token.VAR, token.CONST:
					// Blank the declared var/const names.
					for _, spec := range decl.Specs {
						spec := spec.(*ast.ValueSpec)
						for i := range spec.Names {
							spec.Names[i].Name = "_"
						}
					}
				}
			case *ast.FuncDecl:
				// Blank the declared func name.
				decl.Name.Name = "_"

				// Turn a method receiver:  func (T) f(P) R {...}
				// into regular parameter:  func _(T, P) R {...}
				if decl.Recv != nil {
					var params []*ast.Field
					params = append(params, decl.Recv.List...)
					params = append(params, decl.Type.Params.List...)
					decl.Type.Params.List = params
					decl.Recv = nil
				}
			}
			decls = append(decls, decl)
		}
		f.Decls = decls
		if debug {
			format.Node(os.Stderr, fset, f) // debugging
		}
		cgoFiles = append(cgoFiles, f)
	}
	if cgoFiles == nil {
		return nil, nil, nil // nothing to do (can't happen?)
	}

	// Type-check the synthetic files.
	tc := &types.Config{
		FakeImportC: true,
		Importer: importerFunc(func(path string) (*types.Package, error) {
			return importMap[path], nil
		}),
		Sizes: sizes,
		Error: func(error) {}, // ignore errors (e.g. unused import)
	}

	// It's tempting to record the new types in the
	// existing pass.TypesInfo, but we don't own it.
	altInfo := &types.Info{
		Types: make(map[ast.Expr]types.TypeAndValue),
	}
	tc.Check(pkg.Path(), fset, cgoFiles, altInfo)

	return cgoFiles, altInfo, nil
}

// 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(info *types.Info, arg ast.Expr) types.Type {
	switch arg := arg.(type) {
	case *ast.CallExpr:
		if len(arg.Args) == 1 && isUnsafePointer(info, arg.Fun) {
			return cgoBaseType(info, 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 := info.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 !isUnsafePointer(info, call.Fun) {
			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(info, u.X)
	}

	return info.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
}

func isUnsafePointer(info *types.Info, e ast.Expr) bool {
	t := info.Types[e].Type
	return t != nil && t.Underlying() == types.Typ[types.UnsafePointer]
}

type importerFunc func(path string) (*types.Package, error)

func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) }

// TODO(adonovan): make this a library function or method of Info.
func imported(info *types.Info, spec *ast.ImportSpec) *types.Package {
	obj, ok := info.Implicits[spec]
	if !ok {
		obj = info.Defs[spec.Name] // renaming import
	}
	return obj.(*types.PkgName).Imported()
}
