Commit 04862afe by Ian Lance Taylor

libgo: update to Go 1.12.2

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

From-SVN: r270214
parent 8108dfde
392e9b3da473070f24dbe6c12c282a0e06e73b54
a69f7c05f1880bb90544fb0c3577109cb1d7f3ab
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
0380c9ad38843d523d9c9804fe300cb7edd7cd3c
ac02fdec7cd16ea8d3de1fc33def9cfabec5170d
The first line of this file holds the git revision number of the
last merge done from the master library sources.
......@@ -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 {
......
......@@ -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()
}
......
......@@ -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"
......
......@@ -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)
......
......@@ -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 {
......
......@@ -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) {}
# 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) {}
......@@ -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 {
......
......@@ -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
}
}
......
......@@ -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"
......
......@@ -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() {
......
......@@ -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())
......
......@@ -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)
}
......
......@@ -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
}
......
......@@ -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 {
......
......@@ -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) {
......
......@@ -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)
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment