Imports #
"go/types"
"go/types"
"fmt"
"go/ast"
"go/format"
"go/parser"
"go/token"
"go/types"
"log"
"os"
"strconv"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
"go/types"
"go/types"
"fmt"
"go/ast"
"go/format"
"go/parser"
"go/token"
"go/types"
"log"
"os"
"strconv"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
var Analyzer = *ast.UnaryExpr
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.`
const debug = false
type importerFunc func(path string) (*types.Package, error)
func (f importerFunc) Import(path string) (*types.Package, error)
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
func checkCgo(fset *token.FileSet, f *ast.File, info *types.Info, reportf func(token.Pos, string, ...interface{}))
TODO(adonovan): make this a library function or method of Info.
func imported(info *types.Info, spec *ast.ImportSpec) *types.Package
func isUnsafePointer(info *types.Info, e ast.Expr) bool
func run(pass *analysis.Pass) (interface{}, error)
func setGoVersion(tc *types.Config, pkg *types.Package)
func setGoVersion(tc *types.Config, pkg *types.Package)
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)
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
Generated with Arrow