libgo: update to Go 1.12.2

Change-Id: I1db46ccf927572504184bd8cfcfb0ba98a77cfa1
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/170706
Reviewed-by: Than McIntosh <thanm@google.com>
diff --git a/libgo/MERGE b/libgo/MERGE
index d456361..37b7480 100644
--- a/libgo/MERGE
+++ b/libgo/MERGE
@@ -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.
diff --git a/libgo/VERSION b/libgo/VERSION
index f325447..b9c6439 100644
--- a/libgo/VERSION
+++ b/libgo/VERSION
@@ -1 +1 @@
-go1.12.1
+go1.12.2
diff --git a/libgo/go/cmd/go/internal/load/pkg.go b/libgo/go/cmd/go/internal/load/pkg.go
index 543250e..5e511db 100644
--- a/libgo/go/cmd/go/internal/load/pkg.go
+++ b/libgo/go/cmd/go/internal/load/pkg.go
@@ -1184,6 +1184,36 @@
 
 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 @@
 		}
 		_, 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 @@
 			// 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 {
diff --git a/libgo/go/cmd/go/internal/load/test.go b/libgo/go/cmd/go/internal/load/test.go
index c0e0667..7385c4e 100644
--- a/libgo/go/cmd/go/internal/load/test.go
+++ b/libgo/go/cmd/go/internal/load/test.go
@@ -268,17 +268,8 @@
 	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 @@
 	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 @@
 
 		// 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()
 		}
diff --git a/libgo/go/cmd/go/internal/test/test.go b/libgo/go/cmd/go/internal/test/test.go
index 332f312..b72eace 100644
--- a/libgo/go/cmd/go/internal/test/test.go
+++ b/libgo/go/cmd/go/internal/test/test.go
@@ -805,7 +805,7 @@
 	if p.ImportPath == "command-line-arguments" {
 		elem = p.Name
 	} else {
-		_, elem = path.Split(p.ImportPath)
+		elem = load.DefaultExecName(p.ImportPath)
 	}
 	testBinary := elem + ".test"
 
diff --git a/libgo/go/cmd/go/internal/work/build.go b/libgo/go/cmd/go/internal/work/build.go
index 145b875..ed66df2 100644
--- a/libgo/go/cmd/go/internal/work/build.go
+++ b/libgo/go/cmd/go/internal/work/build.go
@@ -10,7 +10,6 @@
 	"go/build"
 	"os"
 	"os/exec"
-	"path"
 	"path/filepath"
 	"runtime"
 	"strings"
@@ -285,7 +284,7 @@
 	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 @@
 	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)
diff --git a/libgo/go/cmd/go/internal/work/exec.go b/libgo/go/cmd/go/internal/work/exec.go
index fc052b3..5302724 100644
--- a/libgo/go/cmd/go/internal/work/exec.go
+++ b/libgo/go/cmd/go/internal/work/exec.go
@@ -214,6 +214,7 @@
 	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 {
diff --git a/libgo/go/cmd/go/testdata/mod/rsc.io_fortune_v2_v2.0.0.txt b/libgo/go/cmd/go/testdata/mod/rsc.io_fortune_v2_v2.0.0.txt
index cfa91f0..3acd637 100644
--- a/libgo/go/cmd/go/testdata/mod/rsc.io_fortune_v2_v2.0.0.txt
+++ b/libgo/go/cmd/go/testdata/mod/rsc.io_fortune_v2_v2.0.0.txt
@@ -13,3 +13,9 @@
 func main() {
 	println(quote.Hello())
 }
+-- fortune_test.go --
+package main
+
+import "testing"
+
+func TestFortuneV2(t *testing.T) {}
diff --git a/libgo/go/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt b/libgo/go/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt
new file mode 100644
index 0000000..ab7cd66
--- /dev/null
+++ b/libgo/go/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt
@@ -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) {}
diff --git a/libgo/go/internal/poll/fd_windows.go b/libgo/go/internal/poll/fd_windows.go
index 19d9a12..f860b82 100644
--- a/libgo/go/internal/poll/fd_windows.go
+++ b/libgo/go/internal/poll/fd_windows.go
@@ -660,6 +660,10 @@
 		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 @@
 		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 {
diff --git a/libgo/go/net/http/httputil/reverseproxy.go b/libgo/go/net/http/httputil/reverseproxy.go
index 4e10bf3..4b165d6 100644
--- a/libgo/go/net/http/httputil/reverseproxy.go
+++ b/libgo/go/net/http/httputil/reverseproxy.go
@@ -389,6 +389,11 @@
 				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
 		}
 	}
diff --git a/libgo/go/net/http/httputil/reverseproxy_test.go b/libgo/go/net/http/httputil/reverseproxy_test.go
index 5edefa0..367ba73 100644
--- a/libgo/go/net/http/httputil/reverseproxy_test.go
+++ b/libgo/go/net/http/httputil/reverseproxy_test.go
@@ -9,6 +9,7 @@
 import (
 	"bufio"
 	"bytes"
+	"context"
 	"errors"
 	"fmt"
 	"io"
@@ -317,6 +318,47 @@
 	}
 }
 
+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"
 
diff --git a/libgo/go/net/lookup.go b/libgo/go/net/lookup.go
index e108893..08e8d01 100644
--- a/libgo/go/net/lookup.go
+++ b/libgo/go/net/lookup.go
@@ -262,8 +262,9 @@
 	// 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 @@
 		// 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() {
diff --git a/libgo/go/net/lookup_test.go b/libgo/go/net/lookup_test.go
index 85bcb2b..28a895e 100644
--- a/libgo/go/net/lookup_test.go
+++ b/libgo/go/net/lookup_test.go
@@ -16,6 +16,7 @@
 	"sort"
 	"strings"
 	"sync"
+	"sync/atomic"
 	"testing"
 	"time"
 )
@@ -253,14 +254,11 @@
 	}
 }
 
-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 @@
 
 	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 @@
 			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 @@
 		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 @@
 	}
 }
 
+// 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())
 
diff --git a/libgo/go/os/path.go b/libgo/go/os/path.go
index 104b7ce..ba43ea3 100644
--- a/libgo/go/os/path.go
+++ b/libgo/go/os/path.go
@@ -62,6 +62,7 @@
 // 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)
 }
diff --git a/libgo/go/os/path_unix.go b/libgo/go/os/path_unix.go
index e55301f..4864989 100644
--- a/libgo/go/os/path_unix.go
+++ b/libgo/go/os/path_unix.go
@@ -51,7 +51,7 @@
 	// Remove leading directory path
 	for i--; i >= 0; i-- {
 		if path[i] == '/' {
-			dirname = path[:i+1]
+			dirname = path[:i]
 			basename = path[i+1:]
 			break
 		}
diff --git a/libgo/go/os/removeall_at.go b/libgo/go/os/removeall_at.go
index 512a891..6fdd7e8 100644
--- a/libgo/go/os/removeall_at.go
+++ b/libgo/go/os/removeall_at.go
@@ -46,13 +46,20 @@
 	}
 	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 @@
 	// 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 @@
 		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 @@
 			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 @@
 	}
 
 	// 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 @@
 	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 @@
 			continue
 		}
 
-		return nil, &PathError{"openat", name, e}
+		return nil, e
 	}
 
 	if !supportsCloseOnExec {
diff --git a/libgo/go/os/removeall_test.go b/libgo/go/os/removeall_test.go
index 21371d8..945a38e 100644
--- a/libgo/go/os/removeall_test.go
+++ b/libgo/go/os/removeall_test.go
@@ -294,7 +294,7 @@
 }
 
 // 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 @@
 		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) {
diff --git a/libgo/go/runtime/runtime-lldb_test.go b/libgo/go/runtime/runtime-lldb_test.go
index fe3a0eb..08d6a34 100644
--- a/libgo/go/runtime/runtime-lldb_test.go
+++ b/libgo/go/runtime/runtime-lldb_test.go
@@ -139,6 +139,7 @@
 	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)
 
diff --git a/libgo/go/syscall/security_windows.go b/libgo/go/syscall/security_windows.go
index ae8b3a1..db80d98 100644
--- a/libgo/go/syscall/security_windows.go
+++ b/libgo/go/syscall/security_windows.go
@@ -290,6 +290,7 @@
 //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