Bumping k8s dependencies to 1.13

This commit is contained in:
Cheng Xing
2018-11-16 14:08:25 -08:00
parent 305407125c
commit b4c0b68ec7
8002 changed files with 884099 additions and 276228 deletions

View File

@@ -32,7 +32,7 @@ package ssa
import (
"fmt"
"go/ast"
exact "go/constant"
"go/constant"
"go/token"
"go/types"
"os"
@@ -63,7 +63,7 @@ var (
// SSA Value constants.
vZero = intConst(0)
vOne = intConst(1)
vTrue = NewConst(exact.MakeBool(true), tBool)
vTrue = NewConst(constant.MakeBool(true), tBool)
)
// builder holds state associated with the package currently being built.
@@ -131,11 +131,11 @@ func (b *builder) logicalBinop(fn *Function, e *ast.BinaryExpr) Value {
switch e.Op {
case token.LAND:
b.cond(fn, e.X, rhs, done)
short = NewConst(exact.MakeBool(false), t)
short = NewConst(constant.MakeBool(false), t)
case token.LOR:
b.cond(fn, e.X, done, rhs)
short = NewConst(exact.MakeBool(true), t)
short = NewConst(constant.MakeBool(true), t)
}
// Is rhs unreachable?
@@ -969,10 +969,10 @@ func (b *builder) setCall(fn *Function, e *ast.CallExpr, c *CallCommon) {
c.Args = b.emitCallArgs(fn, sig, e, c.Args)
}
// assignOp emits to fn code to perform loc += incr or loc -= incr.
func (b *builder) assignOp(fn *Function, loc lvalue, incr Value, op token.Token) {
// assignOp emits to fn code to perform loc <op>= val.
func (b *builder) assignOp(fn *Function, loc lvalue, val Value, op token.Token, pos token.Pos) {
oldv := loc.load(fn)
loc.store(fn, emitArith(fn, op, oldv, emitConv(fn, incr, oldv.Type()), loc.typ(), token.NoPos))
loc.store(fn, emitArith(fn, op, oldv, emitConv(fn, val, oldv.Type()), loc.typ(), pos))
}
// localValueSpec emits to fn code to define all of the vars in the
@@ -1998,7 +1998,7 @@ start:
op = token.SUB
}
loc := b.addr(fn, s.X, false)
b.assignOp(fn, loc, NewConst(exact.MakeInt64(1), loc.typ()), op)
b.assignOp(fn, loc, NewConst(constant.MakeInt64(1), loc.typ()), op, s.Pos())
case *ast.AssignStmt:
switch s.Tok {
@@ -2007,7 +2007,7 @@ start:
default: // +=, etc.
op := s.Tok + token.ADD - token.ADD_ASSIGN
b.assignOp(fn, b.addr(fn, s.Lhs[0], false), b.expr(fn, s.Rhs[0]), op)
b.assignOp(fn, b.addr(fn, s.Lhs[0], false), b.expr(fn, s.Rhs[0]), op, s.Pos())
}
case *ast.GoStmt:

View File

@@ -8,7 +8,7 @@ package ssa
import (
"fmt"
exact "go/constant"
"go/constant"
"go/token"
"go/types"
"strconv"
@@ -17,14 +17,14 @@ import (
// NewConst returns a new constant of the specified value and type.
// val must be valid according to the specification of Const.Value.
//
func NewConst(val exact.Value, typ types.Type) *Const {
func NewConst(val constant.Value, typ types.Type) *Const {
return &Const{typ, val}
}
// intConst returns an 'int' constant that evaluates to i.
// (i is an int64 in case the host is narrower than the target.)
func intConst(i int64) *Const {
return NewConst(exact.MakeInt64(i), tInt)
return NewConst(constant.MakeInt64(i), tInt)
}
// nilConst returns a nil constant of the specified type, which may
@@ -36,7 +36,7 @@ func nilConst(typ types.Type) *Const {
// stringConst returns a 'string' constant that evaluates to s.
func stringConst(s string) *Const {
return NewConst(exact.MakeString(s), tString)
return NewConst(constant.MakeString(s), tString)
}
// zeroConst returns a new "zero" constant of the specified type,
@@ -48,11 +48,11 @@ func zeroConst(t types.Type) *Const {
case *types.Basic:
switch {
case t.Info()&types.IsBoolean != 0:
return NewConst(exact.MakeBool(false), t)
return NewConst(constant.MakeBool(false), t)
case t.Info()&types.IsNumeric != 0:
return NewConst(exact.MakeInt64(0), t)
return NewConst(constant.MakeInt64(0), t)
case t.Info()&types.IsString != 0:
return NewConst(exact.MakeString(""), t)
return NewConst(constant.MakeString(""), t)
case t.Kind() == types.UnsafePointer:
fallthrough
case t.Kind() == types.UntypedNil:
@@ -74,8 +74,8 @@ func (c *Const) RelString(from *types.Package) string {
var s string
if c.Value == nil {
s = "nil"
} else if c.Value.Kind() == exact.String {
s = exact.StringVal(c.Value)
} else if c.Value.Kind() == constant.String {
s = constant.StringVal(c.Value)
const max = 20
// TODO(adonovan): don't cut a rune in half.
if len(s) > max {
@@ -121,14 +121,14 @@ func (c *Const) IsNil() bool {
// a signed 64-bit integer.
//
func (c *Const) Int64() int64 {
switch x := exact.ToInt(c.Value); x.Kind() {
case exact.Int:
if i, ok := exact.Int64Val(x); ok {
switch x := constant.ToInt(c.Value); x.Kind() {
case constant.Int:
if i, ok := constant.Int64Val(x); ok {
return i
}
return 0
case exact.Float:
f, _ := exact.Float64Val(x)
case constant.Float:
f, _ := constant.Float64Val(x)
return int64(f)
}
panic(fmt.Sprintf("unexpected constant value: %T", c.Value))
@@ -138,14 +138,14 @@ func (c *Const) Int64() int64 {
// an unsigned 64-bit integer.
//
func (c *Const) Uint64() uint64 {
switch x := exact.ToInt(c.Value); x.Kind() {
case exact.Int:
if u, ok := exact.Uint64Val(x); ok {
switch x := constant.ToInt(c.Value); x.Kind() {
case constant.Int:
if u, ok := constant.Uint64Val(x); ok {
return u
}
return 0
case exact.Float:
f, _ := exact.Float64Val(x)
case constant.Float:
f, _ := constant.Float64Val(x)
return uint64(f)
}
panic(fmt.Sprintf("unexpected constant value: %T", c.Value))
@@ -155,7 +155,7 @@ func (c *Const) Uint64() uint64 {
// a float64.
//
func (c *Const) Float64() float64 {
f, _ := exact.Float64Val(c.Value)
f, _ := constant.Float64Val(c.Value)
return f
}
@@ -163,7 +163,7 @@ func (c *Const) Float64() float64 {
// fit a complex128.
//
func (c *Const) Complex128() complex128 {
re, _ := exact.Float64Val(exact.Real(c.Value))
im, _ := exact.Float64Val(exact.Imag(c.Value))
re, _ := constant.Float64Val(constant.Real(c.Value))
im, _ := constant.Float64Val(constant.Imag(c.Value))
return complex(re, im)
}

View File

@@ -251,12 +251,19 @@ func (prog *Program) AllPackages() []*Package {
return pkgs
}
// ImportedPackage returns the importable SSA Package whose import
// path is path, or nil if no such SSA package has been created.
// ImportedPackage returns the importable Package whose PkgPath
// is path, or nil if no such Package has been created.
//
// Not all packages are importable. For example, no import
// declaration can resolve to the x_test package created by 'go test'
// or the ad-hoc main package created 'go build foo.go'.
// A parameter to CreatePackage determines whether a package should be
// considered importable. For example, no import declaration can resolve
// to the ad-hoc main package created by 'go build foo.go'.
//
// TODO(adonovan): rethink this function and the "importable" concept;
// most packages are importable. This function assumes that all
// types.Package.Path values are unique within the ssa.Program, which is
// false---yet this function remains very convenient.
// Clients should use (*Program).Package instead where possible.
// SSA doesn't really need a string-keyed map of packages.
//
func (prog *Program) ImportedPackage(path string) *Package {
return prog.imported[path]

View File

@@ -23,11 +23,13 @@
// such as multi-way branch can be reconstructed as needed; see
// ssautil.Switches() for an example.
//
// To construct an SSA-form program, call ssautil.CreateProgram on a
// loader.Program, a set of type-checked packages created from
// parsed Go source files. The resulting ssa.Program contains all the
// packages and their members, but SSA code is not created for
// function bodies until a subsequent call to (*Package).Build.
// The simplest way to create the SSA representation of a package is
// to load typed syntax trees using golang.org/x/tools/go/packages, then
// invoke the ssautil.Packages helper function. See ExampleLoadPackages
// and ExampleWholeProgram for examples.
// The resulting ssa.Program contains all the packages and their
// members, but SSA code is not created for function bodies until a
// subsequent call to (*Package).Build or (*Program).Build.
//
// The builder initially builds a naive SSA form in which all local
// variables are addresses of stack locations with explicit loads and

View File

@@ -11,9 +11,10 @@ import (
"go/parser"
"go/token"
"go/types"
"log"
"os"
"golang.org/x/tools/go/loader"
"golang.org/x/tools/go/packages"
"golang.org/x/tools/go/ssa"
"golang.org/x/tools/go/ssa/ssautil"
)
@@ -48,7 +49,7 @@ func main() {
// with similar functionality. It is located at
// golang.org/x/tools/cmd/ssadump.
//
func ExampleBuildPackage() {
func Example_buildPackage() {
// Parse the source files.
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "hello.go", hello, parser.ParseComments)
@@ -113,26 +114,51 @@ func ExampleBuildPackage() {
// return
}
// This program shows how to load a main package (cmd/cover) and all its
// dependencies from source, using the loader, and then build SSA code
// for the entire program. This is what you'd typically use for a
// whole-program analysis.
//
func ExampleLoadProgram() {
// Load cmd/cover and its dependencies.
var conf loader.Config
conf.Import("cmd/cover")
lprog, err := conf.Load()
// This example builds SSA code for a set of packages using the
// x/tools/go/packages API. This is what you would typically use for a
// analysis capable of operating on a single package.
func Example_loadPackages() {
// Load, parse, and type-check the initial packages.
cfg := &packages.Config{Mode: packages.LoadSyntax}
initial, err := packages.Load(cfg, "fmt", "net/http")
if err != nil {
fmt.Print(err) // type error in some package
return
log.Fatal(err)
}
// Create SSA-form program representation.
prog := ssautil.CreateProgram(lprog, ssa.SanityCheckFunctions)
// Stop if any package had errors.
// This step is optional; without it, the next step
// will create SSA for only a subset of packages.
if packages.PrintErrors(initial) > 0 {
log.Fatalf("packages contain errors")
}
// Build SSA code for the entire cmd/cover program.
prog.Build()
// Create SSA packages for all well-typed packages.
prog, pkgs := ssautil.Packages(initial, ssa.PrintPackages)
_ = prog
// Output:
// Build SSA code for the well-typed initial packages.
for _, p := range pkgs {
if p != nil {
p.Build()
}
}
}
// This example builds SSA code for a set of packages plus all their dependencies,
// using the x/tools/go/packages API.
// This is what you'd typically use for a whole-program analysis.
func Example_loadWholeProgram() {
// Load, parse, and type-check the whole program.
cfg := packages.Config{Mode: packages.LoadAllSyntax}
initial, err := packages.Load(&cfg, "fmt", "net/http")
if err != nil {
log.Fatal(err)
}
// Create SSA packages for well-typed packages and their dependencies.
prog, pkgs := ssautil.AllPackages(initial, ssa.PrintPackages)
_ = pkgs
// Build SSA code for the whole program.
prog.Build()
}

View File

@@ -103,8 +103,8 @@ var gorootTestTests = []string{
"floatcmp.go",
"crlf.go", // doesn't actually assert anything (runoutput)
// Slow tests follow.
"bom.go", // ~1.7s
"gc1.go", // ~1.7s
"bom.go", // ~1.7s
"gc1.go", // ~1.7s
"cmplxdivide.go cmplxdivide1.go", // ~2.4s
// Working, but not worth enabling:
@@ -156,6 +156,7 @@ var testdataTests = []string{
type successPredicate func(exitcode int, output string) error
func run(t *testing.T, dir, input string, success successPredicate) bool {
t.Skip("golang.org/issue/27292")
if runtime.GOOS == "darwin" {
t.Skip("skipping on darwin until golang.org/issue/23166 is fixed")
}
@@ -192,7 +193,7 @@ func run(t *testing.T, dir, input string, success successPredicate) bool {
interp.CapturedOutput = nil
}()
hint = fmt.Sprintf("To dump SSA representation, run:\n%% go build golang.org/x/tools/cmd/ssadump && ./ssadump -test -build=CFP %s\n", input)
hint = fmt.Sprintf("To dump SSA representation, run:\n%% go build golang.org/x/tools/cmd/ssadump && ./ssadump -test -build=CFP %s\n", strings.Join(inputs, " "))
iprog, err := conf.Load()
if err != nil {
@@ -227,7 +228,7 @@ func run(t *testing.T, dir, input string, success successPredicate) bool {
var out bytes.Buffer
interp.CapturedOutput = &out
hint = fmt.Sprintf("To trace execution, run:\n%% go build golang.org/x/tools/cmd/ssadump && ./ssadump -build=C -test -run --interp=T %s\n", input)
hint = fmt.Sprintf("To trace execution, run:\n%% go build golang.org/x/tools/cmd/ssadump && ./ssadump -build=C -test -run --interp=T %s\n", strings.Join(inputs, " "))
exitCode := interp.Interpret(mainPkg, 0, &types.StdSizes{WordSize: 8, MaxAlign: 8}, inputs[0], []string{})
// The definition of success varies with each file.

View File

@@ -7,7 +7,7 @@ package interp
import (
"bytes"
"fmt"
exact "go/constant"
"go/constant"
"go/token"
"go/types"
"strings"
@@ -40,7 +40,7 @@ func constValue(c *ssa.Const) value {
// TODO(adonovan): eliminate untyped constants from SSA form.
switch t.Kind() {
case types.Bool, types.UntypedBool:
return exact.BoolVal(c.Value)
return constant.BoolVal(c.Value)
case types.Int, types.UntypedInt:
// Assume sizeof(int) is same on host and target.
return int(c.Int64())
@@ -75,8 +75,8 @@ func constValue(c *ssa.Const) value {
case types.Complex128, types.UntypedComplex:
return c.Complex128()
case types.String, types.UntypedString:
if c.Value.Kind() == exact.String {
return exact.StringVal(c.Value)
if c.Value.Kind() == constant.String {
return constant.StringVal(c.Value)
}
return string(rune(c.Int64()))
}

View File

@@ -5,7 +5,9 @@ package main
import "fmt"
// Map literals.
func init() {
// TODO(adonovan): we can no longer print maps
// until the interpreter supports (reflect.Value).MapRange.
func _() {
type M map[int]int
m1 := []*M{{1: 1}, &M{2: 2}}
want := "map[1:1] map[2:2]"

View File

@@ -23,14 +23,14 @@ import (
//
func (prog *Program) MethodValue(sel *types.Selection) *Function {
if sel.Kind() != types.MethodVal {
panic(fmt.Sprintf("Method(%s) kind != MethodVal", sel))
panic(fmt.Sprintf("MethodValue(%s) kind != MethodVal", sel))
}
T := sel.Recv()
if isInterface(T) {
return nil // abstract method
}
if prog.mode&LogSource != 0 {
defer logStack("Method %s %v", T, sel)()
defer logStack("MethodValue %s %v", T, sel)()
}
prog.methodsMu.Lock()

View File

@@ -408,8 +408,8 @@ func (s *sanity) checkFunction(fn *Function) bool {
s.errorf("nil Prog")
}
fn.String() // must not crash
fn.RelString(fn.pkg()) // must not crash
_ = fn.String() // must not crash
_ = fn.RelString(fn.pkg()) // must not crash
// All functions have a package, except delegates (which are
// shared across packages, or duplicated as weak symbols in a
@@ -446,6 +446,17 @@ func (s *sanity) checkFunction(fn *Function) bool {
if p.Parent() != fn {
s.errorf("Param %s at index %d has wrong parent", p.Name(), i)
}
// Check common suffix of Signature and Params match type.
if sig := fn.Signature; sig != nil {
j := i - len(fn.Params) + sig.Params().Len() // index within sig.Params
if j < 0 {
continue
}
if !types.Identical(p.Type(), sig.Params().At(j).Type()) {
s.errorf("Param %s at index %d has wrong type (%s, versus %s in Signature)", p.Name(), i, p.Type(), sig.Params().At(j).Type())
}
}
s.checkReferrerList(p)
}
for i, fv := range fn.FreeVars {
@@ -488,7 +499,7 @@ func sanityCheckPackage(pkg *Package) {
if pkg.Pkg == nil {
panic(fmt.Sprintf("Package %s has no Object", pkg))
}
pkg.String() // must not crash
_ = pkg.String() // must not crash
for name, mem := range pkg.Members {
if name != mem.Name() {

View File

@@ -9,7 +9,7 @@ package ssa_test
import (
"fmt"
"go/ast"
exact "go/constant"
"go/constant"
"go/parser"
"go/token"
"go/types"
@@ -144,7 +144,7 @@ func checkConstValue(t *testing.T, prog *ssa.Program, obj *types.Const) {
return
}
if obj.Name() != "nil" {
if !exact.Compare(c.Value, token.EQL, obj.Val()) {
if !constant.Compare(c.Value, token.EQL, obj.Val()) {
t.Errorf("ConstValue(%s).Value (%s) != %s",
obj, c.Value, obj.Val())
return

View File

@@ -10,7 +10,7 @@ package ssa
import (
"fmt"
"go/ast"
exact "go/constant"
"go/constant"
"go/token"
"go/types"
"sync"
@@ -404,9 +404,8 @@ type Parameter struct {
// All source-level constant expressions are represented by a Const
// of the same type and value.
//
// Value holds the exact value of the constant, independent of its
// Type(), using the same representation as package go/exact uses for
// constants, or nil for a typed nil value.
// Value holds the value of the constant, independent of its Type(),
// using go/constant representation, or nil for a typed nil value.
//
// Pos() returns token.NoPos.
//
@@ -417,7 +416,7 @@ type Parameter struct {
//
type Const struct {
typ types.Type
Value exact.Value
Value constant.Value
}
// A Global is a named Value holding the address of a package-level
@@ -655,10 +654,10 @@ type ChangeInterface struct {
// value of a concrete type.
//
// Use Program.MethodSets.MethodSet(X.Type()) to find the method-set
// of X, and Program.Method(m) to find the implementation of a method.
// of X, and Program.MethodValue(m) to find the implementation of a method.
//
// To construct the zero value of an interface type T, use:
// NewConst(exact.MakeNil(), T, pos)
// NewConst(constant.MakeNil(), T, pos)
//
// Pos() returns the ast.CallExpr.Lparen, if the instruction arose
// from an explicit conversion in the source.

View File

@@ -12,9 +12,86 @@ import (
"go/types"
"golang.org/x/tools/go/loader"
"golang.org/x/tools/go/packages"
"golang.org/x/tools/go/ssa"
)
// Packages creates an SSA program for a set of packages.
//
// The packages must have been loaded from source syntax using the
// golang.org/x/tools/go/packages.Load function in LoadSyntax or
// LoadAllSyntax mode.
//
// Packages creates an SSA package for each well-typed package in the
// initial list, plus all their dependencies. The resulting list of
// packages corresponds to the list of initial packages, and may contain
// a nil if SSA code could not be constructed for the corresponding initial
// package due to type errors.
//
// Code for bodies of functions is not built until Build is called on
// the resulting Program. SSA code is constructed only for the initial
// packages with well-typed syntax trees.
//
// The mode parameter controls diagnostics and checking during SSA construction.
//
func Packages(initial []*packages.Package, mode ssa.BuilderMode) (*ssa.Program, []*ssa.Package) {
return doPackages(initial, mode, false)
}
// AllPackages creates an SSA program for a set of packages plus all
// their dependencies.
//
// The packages must have been loaded from source syntax using the
// golang.org/x/tools/go/packages.Load function in LoadAllSyntax mode.
//
// AllPackages creates an SSA package for each well-typed package in the
// initial list, plus all their dependencies. The resulting list of
// packages corresponds to the list of intial packages, and may contain
// a nil if SSA code could not be constructed for the corresponding
// initial package due to type errors.
//
// Code for bodies of functions is not built until Build is called on
// the resulting Program. SSA code is constructed for all packages with
// well-typed syntax trees.
//
// The mode parameter controls diagnostics and checking during SSA construction.
//
func AllPackages(initial []*packages.Package, mode ssa.BuilderMode) (*ssa.Program, []*ssa.Package) {
return doPackages(initial, mode, true)
}
func doPackages(initial []*packages.Package, mode ssa.BuilderMode, deps bool) (*ssa.Program, []*ssa.Package) {
var fset *token.FileSet
if len(initial) > 0 {
fset = initial[0].Fset
}
prog := ssa.NewProgram(fset, mode)
isInitial := make(map[*packages.Package]bool, len(initial))
for _, p := range initial {
isInitial[p] = true
}
ssamap := make(map[*packages.Package]*ssa.Package)
packages.Visit(initial, nil, func(p *packages.Package) {
if p.Types != nil && !p.IllTyped {
var files []*ast.File
if deps || isInitial[p] {
files = p.Syntax
}
ssamap[p] = prog.CreatePackage(p.Types, files, p.TypesInfo, true)
}
})
var ssapkgs []*ssa.Package
for _, p := range initial {
ssapkgs = append(ssapkgs, ssamap[p]) // may be nil
}
return prog, ssapkgs
}
// CreateProgram returns a new program in SSA form, given a program
// loaded from source. An SSA package is created for each transitively
// error-free package of lprog.
@@ -22,7 +99,10 @@ import (
// Code for bodies of functions is not built until Build is called
// on the result.
//
// mode controls diagnostics and checking during SSA construction.
// The mode parameter controls diagnostics and checking during SSA construction.
//
// Deprecated: use golang.org/x/tools/go/packages and the Packages
// function instead; see ssa.ExampleLoadPackages.
//
func CreateProgram(lprog *loader.Program, mode ssa.BuilderMode) *ssa.Program {
prog := ssa.NewProgram(lprog.Fset, mode)

View File

@@ -5,14 +5,17 @@
package ssautil_test
import (
"bytes"
"go/ast"
"go/importer"
"go/parser"
"go/token"
"go/types"
"os"
"strings"
"testing"
"golang.org/x/tools/go/packages"
"golang.org/x/tools/go/ssa/ssautil"
)
@@ -49,6 +52,45 @@ func TestBuildPackage(t *testing.T) {
}
}
func TestPackages(t *testing.T) {
cfg := &packages.Config{Mode: packages.LoadSyntax}
initial, err := packages.Load(cfg, "bytes")
if err != nil {
t.Fatal(err)
}
if packages.PrintErrors(initial) > 0 {
t.Fatal("there were errors")
}
prog, pkgs := ssautil.Packages(initial, 0)
bytesNewBuffer := pkgs[0].Func("NewBuffer")
bytesNewBuffer.Pkg.Build()
// We'll dump the SSA of bytes.NewBuffer because it is small and stable.
out := new(bytes.Buffer)
bytesNewBuffer.WriteTo(out)
// For determinism, sanitize the location.
location := prog.Fset.Position(bytesNewBuffer.Pos()).String()
got := strings.Replace(out.String(), location, "$GOROOT/src/bytes/buffer.go:1", -1)
want := `
# Name: bytes.NewBuffer
# Package: bytes
# Location: $GOROOT/src/bytes/buffer.go:1
func NewBuffer(buf []byte) *Buffer:
0: entry P:0 S:0
t0 = new Buffer (complit) *Buffer
t1 = &t0.buf [#0] *[]byte
*t1 = buf
return t0
`[1:]
if got != want {
t.Errorf("bytes.NewBuffer SSA = <<%s>>, want <<%s>>", got, want)
}
}
func TestBuildPackage_MissingImport(t *testing.T) {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "bad.go", `package bad; import "missing"`, 0)
@@ -62,3 +104,17 @@ func TestBuildPackage_MissingImport(t *testing.T) {
t.Fatal("BuildPackage succeeded unexpectedly")
}
}
func TestIssue28106(t *testing.T) {
// In go1.10, go/packages loads all packages from source, not
// export data, but does not type check function bodies of
// imported packages. This test ensures that we do not attempt
// to run the SSA builder on functions without type information.
cfg := &packages.Config{Mode: packages.LoadSyntax}
pkgs, err := packages.Load(cfg, "runtime")
if err != nil {
t.Fatal(err)
}
prog, _ := ssautil.Packages(pkgs, 0)
prog.Build() // no crash
}

View File

@@ -8,8 +8,8 @@ package ssa
// tests of the supplied packages.
// It is closely coupled to $GOROOT/src/cmd/go/test.go and $GOROOT/src/testing.
//
// TODO(adonovan): this file no longer needs to live in the ssa package.
// Move it to ssautil.
// TODO(adonovan): throws this all away now that x/tools/go/packages
// provides access to the actual synthetic test main files.
import (
"bytes"
@@ -26,6 +26,8 @@ import (
// FindTests returns the Test, Benchmark, and Example functions
// (as defined by "go test") defined in the specified package,
// and its TestMain function, if any.
//
// Deprecated: use x/tools/go/packages to access synthetic testmain packages.
func FindTests(pkg *Package) (tests, benchmarks, examples []*Function, main *Function) {
prog := pkg.Prog
@@ -109,6 +111,8 @@ func isTest(name, prefix string) bool {
//
// Subsequent calls to prog.AllPackages include the new package.
// The package pkg must belong to the program prog.
//
// Deprecated: use x/tools/go/packages to access synthetic testmain packages.
func (prog *Program) CreateTestMainPackage(pkg *Package) *Package {
if pkg.Prog != prog {
log.Fatal("Package does not belong to Program")

View File

@@ -141,13 +141,9 @@ func makeWrapper(prog *Program, sel *types.Selection) *Function {
// start is the index of the first regular parameter to use.
//
func createParams(fn *Function, start int) {
var last *Parameter
tparams := fn.Signature.Params()
for i, n := start, tparams.Len(); i < n; i++ {
last = fn.addParamObj(tparams.At(i))
}
if fn.Signature.Variadic() {
last.typ = types.NewSlice(last.typ)
fn.addParamObj(tparams.At(i))
}
}