libgo: update to Go 1.12.2

Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/170706

From-SVN: r270214
This commit is contained in:
Ian Lance Taylor 2019-04-08 18:36:25 +00:00
parent 8108dfde82
commit 04862afe9f
21 changed files with 270 additions and 74 deletions

View File

@ -1,4 +1,4 @@
392e9b3da473070f24dbe6c12c282a0e06e73b54
a69f7c05f1880bb90544fb0c3577109cb1d7f3ab
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.

View File

@ -1,4 +1,4 @@
0380c9ad38843d523d9c9804fe300cb7edd7cd3c
ac02fdec7cd16ea8d3de1fc33def9cfabec5170d
The first line of this file holds the git revision number of the
last merge done from the master library sources.

View File

@ -1 +1 @@
go1.12.1
go1.12.2

View File

@ -1184,6 +1184,36 @@ var cgoSyscallExclude = map[string]bool{
var foldPath = make(map[string]string)
// DefaultExecName returns the default executable name
// for a package with the import path importPath.
//
// The default executable name is the last element of the import path.
// In module-aware mode, an additional rule is used. If the last element
// is a vN path element specifying the major version, then the second last
// element of the import path is used instead.
func DefaultExecName(importPath string) string {
_, elem := pathpkg.Split(importPath)
if cfg.ModulesEnabled {
// If this is example.com/mycmd/v2, it's more useful to install it as mycmd than as v2.
// See golang.org/issue/24667.
isVersion := func(v string) bool {
if len(v) < 2 || v[0] != 'v' || v[1] < '1' || '9' < v[1] {
return false
}
for i := 2; i < len(v); i++ {
if c := v[i]; c < '0' || '9' < c {
return false
}
}
return true
}
if isVersion(elem) {
_, elem = pathpkg.Split(pathpkg.Dir(importPath))
}
}
return elem
}
// load populates p using information from bp, err, which should
// be the result of calling build.Context.Import.
func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
@ -1226,7 +1256,7 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
}
_, elem := filepath.Split(p.Dir)
if cfg.ModulesEnabled {
// NOTE(rsc): Using p.ImportPath instead of p.Dir
// NOTE(rsc,dmitshur): Using p.ImportPath instead of p.Dir
// makes sure we install a package in the root of a
// cached module directory as that package name
// not name@v1.2.3.
@ -1235,26 +1265,9 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
// even for non-module-enabled code,
// but I'm not brave enough to change the
// non-module behavior this late in the
// release cycle. Maybe for Go 1.12.
// release cycle. Can be done for Go 1.13.
// See golang.org/issue/26869.
_, elem = pathpkg.Split(p.ImportPath)
// If this is example.com/mycmd/v2, it's more useful to install it as mycmd than as v2.
// See golang.org/issue/24667.
isVersion := func(v string) bool {
if len(v) < 2 || v[0] != 'v' || v[1] < '1' || '9' < v[1] {
return false
}
for i := 2; i < len(v); i++ {
if c := v[i]; c < '0' || '9' < c {
return false
}
}
return true
}
if isVersion(elem) {
_, elem = pathpkg.Split(pathpkg.Dir(p.ImportPath))
}
elem = DefaultExecName(p.ImportPath)
}
full := cfg.BuildContext.GOOS + "_" + cfg.BuildContext.GOARCH + "/" + elem
if cfg.BuildContext.GOOS != base.ToolGOOS || cfg.BuildContext.GOARCH != base.ToolGOARCH {

View File

@ -268,17 +268,8 @@ func GetTestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Pac
pmain.Imports = pmain.Imports[:w]
pmain.Internal.RawImports = str.StringList(pmain.Imports)
if ptest != p {
// We have made modifications to the package p being tested
// and are rebuilding p (as ptest).
// Arrange to rebuild all packages q such that
// the test depends on q and q depends on p.
// This makes sure that q sees the modifications to p.
// Strictly speaking, the rebuild is only necessary if the
// modifications to p change its export metadata, but
// determining that is a bit tricky, so we rebuild always.
recompileForTest(pmain, p, ptest, pxtest)
}
// Replace pmain's transitive dependencies with test copies, as necessary.
recompileForTest(pmain, p, ptest, pxtest)
// Should we apply coverage analysis locally,
// only for this package and only for this test?
@ -325,6 +316,14 @@ Search:
return stk
}
// recompileForTest copies and replaces certain packages in pmain's dependency
// graph. This is necessary for two reasons. First, if ptest is different than
// preal, packages that import the package under test should get ptest instead
// of preal. This is particularly important if pxtest depends on functionality
// exposed in test sources in ptest. Second, if there is a main package
// (other than pmain) anywhere, we need to clear p.Internal.BuildInfo in
// the test copy to prevent link conflicts. This may happen if both -coverpkg
// and the command line patterns include multiple main packages.
func recompileForTest(pmain, preal, ptest, pxtest *Package) {
// The "test copy" of preal is ptest.
// For each package that depends on preal, make a "test copy"
@ -367,7 +366,7 @@ func recompileForTest(pmain, preal, ptest, pxtest *Package) {
// Don't compile build info from a main package. This can happen
// if -coverpkg patterns include main packages, since those packages
// are imported by pmain.
// are imported by pmain. See golang.org/issue/30907.
if p.Internal.BuildInfo != "" && p != pmain {
split()
}

View File

@ -805,7 +805,7 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin
if p.ImportPath == "command-line-arguments" {
elem = p.Name
} else {
_, elem = path.Split(p.ImportPath)
elem = load.DefaultExecName(p.ImportPath)
}
testBinary := elem + ".test"

View File

@ -10,7 +10,6 @@ import (
"go/build"
"os"
"os/exec"
"path"
"path/filepath"
"runtime"
"strings"
@ -285,7 +284,7 @@ func runBuild(cmd *base.Command, args []string) {
pkgs := load.PackagesForBuild(args)
if len(pkgs) == 1 && pkgs[0].Name == "main" && cfg.BuildO == "" {
_, cfg.BuildO = path.Split(pkgs[0].ImportPath)
cfg.BuildO = load.DefaultExecName(pkgs[0].ImportPath)
cfg.BuildO += cfg.ExeSuffix
}
@ -518,7 +517,7 @@ func InstallPackages(patterns []string, pkgs []*load.Package) {
if len(patterns) == 0 && len(pkgs) == 1 && pkgs[0].Name == "main" {
// Compute file 'go build' would have created.
// If it exists and is an executable file, remove it.
_, targ := filepath.Split(pkgs[0].ImportPath)
targ := load.DefaultExecName(pkgs[0].ImportPath)
targ += cfg.ExeSuffix
if filepath.Join(pkgs[0].Dir, targ) != pkgs[0].Target { // maybe $GOBIN is the current directory
fi, err := os.Stat(targ)

View File

@ -214,6 +214,7 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID {
if p.Internal.CoverMode != "" {
fmt.Fprintf(h, "cover %q %q\n", p.Internal.CoverMode, b.toolID("cover"))
}
fmt.Fprintf(h, "modinfo %q\n", p.Internal.BuildInfo)
// Configuration specific to compiler toolchain.
switch cfg.BuildToolchainName {

View File

@ -13,3 +13,9 @@ import "rsc.io/quote"
func main() {
println(quote.Hello())
}
-- fortune_test.go --
package main
import "testing"
func TestFortuneV2(t *testing.T) {}

View File

@ -0,0 +1,43 @@
# This test checks that multiple main packages can be tested
# with -coverpkg=all without duplicate symbol errors.
# Verifies golang.org/issue/30374.
env GO111MODULE=on
[short] skip
go test -coverpkg=all ./...
-- go.mod --
module example.com/cov
-- mainonly/mainonly.go --
package main
func main() {}
-- mainwithtest/mainwithtest.go --
package main
func main() {}
func Foo() {}
-- mainwithtest/mainwithtest_test.go --
package main
import "testing"
func TestFoo(t *testing.T) {
Foo()
}
-- xtest/x.go --
package x
-- xtest/x_test.go --
package x_test
import "testing"
func TestX(t *testing.T) {}

View File

@ -660,6 +660,10 @@ func (fd *FD) Write(buf []byte) (int, error) {
return 0, err
}
defer fd.writeUnlock()
if fd.isFile || fd.isDir || fd.isConsole {
fd.l.Lock()
defer fd.l.Unlock()
}
ntotal := 0
for len(buf) > 0 {
@ -670,8 +674,6 @@ func (fd *FD) Write(buf []byte) (int, error) {
var n int
var err error
if fd.isFile || fd.isDir || fd.isConsole {
fd.l.Lock()
defer fd.l.Unlock()
if fd.isConsole {
n, err = fd.writeConsole(b)
} else {

View File

@ -389,6 +389,11 @@ func (p *ReverseProxy) copyResponse(dst io.Writer, src io.Reader, flushInterval
latency: flushInterval,
}
defer mlw.stop()
// set up initial timer so headers get flushed even if body writes are delayed
mlw.flushPending = true
mlw.t = time.AfterFunc(flushInterval, mlw.delayedFlush)
dst = mlw
}
}

View File

@ -9,6 +9,7 @@ package httputil
import (
"bufio"
"bytes"
"context"
"errors"
"fmt"
"io"
@ -317,6 +318,47 @@ func TestReverseProxyFlushInterval(t *testing.T) {
}
}
func TestReverseProxyFlushIntervalHeaders(t *testing.T) {
const expected = "hi"
stopCh := make(chan struct{})
backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("MyHeader", expected)
w.WriteHeader(200)
w.(http.Flusher).Flush()
<-stopCh
}))
defer backend.Close()
defer close(stopCh)
backendURL, err := url.Parse(backend.URL)
if err != nil {
t.Fatal(err)
}
proxyHandler := NewSingleHostReverseProxy(backendURL)
proxyHandler.FlushInterval = time.Microsecond
frontend := httptest.NewServer(proxyHandler)
defer frontend.Close()
req, _ := http.NewRequest("GET", frontend.URL, nil)
req.Close = true
ctx, cancel := context.WithTimeout(req.Context(), 10*time.Second)
defer cancel()
req = req.WithContext(ctx)
res, err := frontend.Client().Do(req)
if err != nil {
t.Fatalf("Get: %v", err)
}
defer res.Body.Close()
if res.Header.Get("MyHeader") != expected {
t.Errorf("got header %q; expected %q", res.Header.Get("MyHeader"), expected)
}
}
func TestReverseProxyCancelation(t *testing.T) {
const backendResponse = "I am the backend"

View File

@ -262,8 +262,9 @@ func (r *Resolver) lookupIPAddr(ctx context.Context, network, host string) ([]IP
// only the values in context. See Issue 28600.
lookupGroupCtx, lookupGroupCancel := context.WithCancel(withUnexpiredValuesPreserved(ctx))
lookupKey := network + "\000" + host
dnsWaitGroup.Add(1)
ch, called := r.getLookupGroup().DoChan(host, func() (interface{}, error) {
ch, called := r.getLookupGroup().DoChan(lookupKey, func() (interface{}, error) {
defer dnsWaitGroup.Done()
return testHookLookupIP(lookupGroupCtx, resolverFunc, network, host)
})
@ -280,7 +281,7 @@ func (r *Resolver) lookupIPAddr(ctx context.Context, network, host string) ([]IP
// let the lookup continue uncanceled, and let later
// lookups with the same key share the result.
// See issues 8602, 20703, 22724.
if r.getLookupGroup().ForgetUnshared(host) {
if r.getLookupGroup().ForgetUnshared(lookupKey) {
lookupGroupCancel()
} else {
go func() {

View File

@ -16,6 +16,7 @@ import (
"sort"
"strings"
"sync"
"sync/atomic"
"testing"
"time"
)
@ -253,14 +254,11 @@ func TestLookupGmailTXT(t *testing.T) {
}
}
var lookupGooglePublicDNSAddrTests = []struct {
addr, name string
}{
{"8.8.8.8", ".google.com."},
{"8.8.4.4", ".google.com."},
{"2001:4860:4860::8888", ".google.com."},
{"2001:4860:4860::8844", ".google.com."},
var lookupGooglePublicDNSAddrTests = []string{
"8.8.8.8",
"8.8.4.4",
"2001:4860:4860::8888",
"2001:4860:4860::8844",
}
func TestLookupGooglePublicDNSAddr(t *testing.T) {
@ -272,8 +270,8 @@ func TestLookupGooglePublicDNSAddr(t *testing.T) {
defer dnsWaitGroup.Wait()
for _, tt := range lookupGooglePublicDNSAddrTests {
names, err := LookupAddr(tt.addr)
for _, ip := range lookupGooglePublicDNSAddrTests {
names, err := LookupAddr(ip)
if err != nil {
t.Fatal(err)
}
@ -281,8 +279,8 @@ func TestLookupGooglePublicDNSAddr(t *testing.T) {
t.Error("got no record")
}
for _, name := range names {
if !strings.HasSuffix(name, tt.name) {
t.Errorf("got %s; want a record containing %s", name, tt.name)
if !strings.HasSuffix(name, ".google.com.") && !strings.HasSuffix(name, ".google.") {
t.Errorf("got %q; want a record ending in .google.com. or .google.", name)
}
}
}
@ -658,8 +656,8 @@ func testDots(t *testing.T, mode string) {
t.Errorf("LookupAddr(8.8.8.8): %v (mode=%v)", err, mode)
} else {
for _, name := range names {
if !strings.HasSuffix(name, ".google.com.") {
t.Errorf("LookupAddr(8.8.8.8) = %v, want names ending in .google.com. with trailing dot (mode=%v)", names, mode)
if !strings.HasSuffix(name, ".google.com.") && !strings.HasSuffix(name, ".google.") {
t.Errorf("LookupAddr(8.8.8.8) = %v, want names ending in .google.com or .google with trailing dot (mode=%v)", names, mode)
break
}
}
@ -1096,6 +1094,69 @@ func TestLookupIPAddrPreservesContextValues(t *testing.T) {
}
}
// Issue 30521: The lookup group should call the resolver for each network.
func TestLookupIPAddrConcurrentCallsForNetworks(t *testing.T) {
origTestHookLookupIP := testHookLookupIP
defer func() { testHookLookupIP = origTestHookLookupIP }()
queries := [][]string{
{"udp", "golang.org"},
{"udp4", "golang.org"},
{"udp6", "golang.org"},
{"udp", "golang.org"},
{"udp", "golang.org"},
}
results := map[[2]string][]IPAddr{
{"udp", "golang.org"}: {
{IP: IPv4(127, 0, 0, 1)},
{IP: IPv6loopback},
},
{"udp4", "golang.org"}: {
{IP: IPv4(127, 0, 0, 1)},
},
{"udp6", "golang.org"}: {
{IP: IPv6loopback},
},
}
calls := int32(0)
waitCh := make(chan struct{})
testHookLookupIP = func(ctx context.Context, fn func(context.Context, string, string) ([]IPAddr, error), network, host string) ([]IPAddr, error) {
// We'll block until this is called one time for each different
// expected result. This will ensure that the lookup group would wait
// for the existing call if it was to be reused.
if atomic.AddInt32(&calls, 1) == int32(len(results)) {
close(waitCh)
}
select {
case <-waitCh:
case <-ctx.Done():
return nil, ctx.Err()
}
return results[[2]string{network, host}], nil
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
wg := sync.WaitGroup{}
for _, q := range queries {
network := q[0]
host := q[1]
wg.Add(1)
go func() {
defer wg.Done()
gotIPs, err := DefaultResolver.lookupIPAddr(ctx, network, host)
if err != nil {
t.Errorf("lookupIPAddr(%v, %v): unexpected error: %v", network, host, err)
}
wantIPs := results[[2]string{network, host}]
if !reflect.DeepEqual(gotIPs, wantIPs) {
t.Errorf("lookupIPAddr(%v, %v): mismatched IPAddr results\n\tGot: %v\n\tWant: %v", network, host, gotIPs, wantIPs)
}
}()
}
wg.Wait()
}
func TestWithUnexpiredValuesPreserved(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())

View File

@ -62,6 +62,7 @@ func MkdirAll(path string, perm FileMode) error {
// It removes everything it can but returns the first error
// it encounters. If the path does not exist, RemoveAll
// returns nil (no error).
// If there is an error, it will be of type *PathError.
func RemoveAll(path string) error {
return removeAll(path)
}

View File

@ -51,7 +51,7 @@ func splitPath(path string) (string, string) {
// Remove leading directory path
for i--; i >= 0; i-- {
if path[i] == '/' {
dirname = path[:i+1]
dirname = path[:i]
basename = path[i+1:]
break
}

View File

@ -46,13 +46,20 @@ func removeAll(path string) error {
}
defer parent.Close()
return removeAllFrom(parent, base)
if err := removeAllFrom(parent, base); err != nil {
if pathErr, ok := err.(*PathError); ok {
pathErr.Path = parentDir + string(PathSeparator) + pathErr.Path
err = pathErr
}
return err
}
return nil
}
func removeAllFrom(parent *File, path string) error {
func removeAllFrom(parent *File, base string) error {
parentFd := int(parent.Fd())
// Simple case: if Unlink (aka remove) works, we're done.
err := unix.Unlinkat(parentFd, path, 0)
err := unix.Unlinkat(parentFd, base, 0)
if err == nil || IsNotExist(err) {
return nil
}
@ -64,21 +71,21 @@ func removeAllFrom(parent *File, path string) error {
// whose contents need to be removed.
// Otherwise just return the error.
if err != syscall.EISDIR && err != syscall.EPERM && err != syscall.EACCES {
return err
return &PathError{"unlinkat", base, err}
}
// Is this a directory we need to recurse into?
var statInfo syscall.Stat_t
statErr := unix.Fstatat(parentFd, path, &statInfo, unix.AT_SYMLINK_NOFOLLOW)
statErr := unix.Fstatat(parentFd, base, &statInfo, unix.AT_SYMLINK_NOFOLLOW)
if statErr != nil {
if IsNotExist(statErr) {
return nil
}
return statErr
return &PathError{"fstatat", base, statErr}
}
if statInfo.Mode&syscall.S_IFMT != syscall.S_IFDIR {
// Not a directory; return the error from the Remove.
return err
// Not a directory; return the error from the unix.Unlinkat.
return &PathError{"unlinkat", base, err}
}
// Remove the directory's entries.
@ -87,12 +94,12 @@ func removeAllFrom(parent *File, path string) error {
const request = 1024
// Open the directory to recurse into
file, err := openFdAt(parentFd, path)
file, err := openFdAt(parentFd, base)
if err != nil {
if IsNotExist(err) {
return nil
}
recurseErr = err
recurseErr = &PathError{"openfdat", base, err}
break
}
@ -103,12 +110,15 @@ func removeAllFrom(parent *File, path string) error {
if IsNotExist(readErr) {
return nil
}
return readErr
return &PathError{"readdirnames", base, readErr}
}
for _, name := range names {
err := removeAllFrom(file, name)
if err != nil {
if pathErr, ok := err.(*PathError); ok {
pathErr.Path = base + string(PathSeparator) + pathErr.Path
}
recurseErr = err
}
}
@ -127,7 +137,7 @@ func removeAllFrom(parent *File, path string) error {
}
// Remove the directory itself.
unlinkError := unix.Unlinkat(parentFd, path, unix.AT_REMOVEDIR)
unlinkError := unix.Unlinkat(parentFd, base, unix.AT_REMOVEDIR)
if unlinkError == nil || IsNotExist(unlinkError) {
return nil
}
@ -135,7 +145,7 @@ func removeAllFrom(parent *File, path string) error {
if recurseErr != nil {
return recurseErr
}
return unlinkError
return &PathError{"unlinkat", base, unlinkError}
}
// openFdAt opens path relative to the directory in fd.
@ -157,7 +167,7 @@ func openFdAt(dirfd int, name string) (*File, error) {
continue
}
return nil, &PathError{"openat", name, e}
return nil, e
}
if !supportsCloseOnExec {

View File

@ -294,7 +294,7 @@ func TestRemoveReadOnlyDir(t *testing.T) {
}
// Issue #29983.
func TestRemoveAllButReadOnly(t *testing.T) {
func TestRemoveAllButReadOnlyAndPathError(t *testing.T) {
switch runtime.GOOS {
case "nacl", "js", "windows":
t.Skipf("skipping test on %s", runtime.GOOS)
@ -355,10 +355,21 @@ func TestRemoveAllButReadOnly(t *testing.T) {
defer Chmod(d, 0777)
}
if err := RemoveAll(tempDir); err == nil {
err = RemoveAll(tempDir)
if err == nil {
t.Fatal("RemoveAll succeeded unexpectedly")
}
// The error should be of type *PathError.
// see issue 30491 for details.
if pathErr, ok := err.(*PathError); ok {
if g, w := pathErr.Path, filepath.Join(tempDir, "b", "y"); g != w {
t.Errorf("got %q, expected pathErr.path %q", g, w)
}
} else {
t.Errorf("got %T, expected *os.PathError", err)
}
for _, dir := range dirs {
_, err := Stat(filepath.Join(tempDir, dir))
if inReadonly(dir) {

View File

@ -139,6 +139,7 @@ func TestLldbPython(t *testing.T) {
if final := os.Getenv("GOROOT_FINAL"); final != "" && runtime.GOROOT() != final {
t.Skip("gdb test can fail with GOROOT_FINAL pending")
}
testenv.SkipFlaky(t, 31188)
checkLldbPython(t)

View File

@ -290,6 +290,7 @@ type Tokenprimarygroup struct {
//sys OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
//sys GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
//sys GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
//sys getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemDirectoryW
// An access token contains the security information for a logon session.
// The system creates an access token when a user logs on, and every