This patch updates libgo to the Go 1.16.2 release.  Bootstrapped and
ran Go testsuite on x86_64-pc-linux-gnu.  Committed to mainline.

Ian
d5eae60451faeea9d87ae3815f7e4db0e6e182ed
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index e5756c6662c..c0bfa1ff78a 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-2f281eb24ef256a2d3bb9fc1a7ef964d82b40182
+10b00ad87303d37c68b2d54dd25d655bd316946e
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/MERGE b/libgo/MERGE
index 183b0245ee2..a52dceb182f 100644
--- a/libgo/MERGE
+++ b/libgo/MERGE
@@ -1,4 +1,4 @@
-f21be2fdc6f1becdbed1592ea0b245cdeedc5ac8
+3979fb9af9ccfc0b7ccb613dcf256b18c2c295f0
 
 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 4befab24bc9..d0b0a900460 100644
--- a/libgo/VERSION
+++ b/libgo/VERSION
@@ -1 +1 @@
-go1.16
+go1.16.2
diff --git a/libgo/go/archive/zip/reader.go b/libgo/go/archive/zip/reader.go
index 8b4e77875fb..c288ad965bc 100644
--- a/libgo/go/archive/zip/reader.go
+++ b/libgo/go/archive/zip/reader.go
@@ -664,7 +664,7 @@ func toValidName(name string) string {
        if strings.HasPrefix(p, "/") {
                p = p[len("/"):]
        }
-       for strings.HasPrefix(name, "../") {
+       for strings.HasPrefix(p, "../") {
                p = p[len("../"):]
        }
        return p
diff --git a/libgo/go/archive/zip/reader_test.go 
b/libgo/go/archive/zip/reader_test.go
index 34e96f7da43..5faf1f49b51 100644
--- a/libgo/go/archive/zip/reader_test.go
+++ b/libgo/go/archive/zip/reader_test.go
@@ -1081,3 +1081,38 @@ func TestFS(t *testing.T) {
                t.Fatal(err)
        }
 }
+
+func TestCVE202127919(t *testing.T) {
+       // Archive containing only the file "../test.txt"
+       data := []byte{
+               0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x00,
+               0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x2e, 0x2e,
+               0x2f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x78,
+               0x74, 0x0a, 0xc9, 0xc8, 0x2c, 0x56, 0xc8, 0x2c,
+               0x56, 0x48, 0x54, 0x28, 0x49, 0x2d, 0x2e, 0x51,
+               0x28, 0x49, 0xad, 0x28, 0x51, 0x48, 0xcb, 0xcc,
+               0x49, 0xd5, 0xe3, 0x02, 0x04, 0x00, 0x00, 0xff,
+               0xff, 0x50, 0x4b, 0x07, 0x08, 0xc0, 0xd7, 0xed,
+               0xc3, 0x20, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00,
+               0x00, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00, 0x14,
+               0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0xc0, 0xd7, 0xed, 0xc3, 0x20, 0x00, 0x00,
+               0x00, 0x1a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e,
+               0x2e, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74,
+               0x78, 0x74, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00,
+               0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x39, 0x00,
+               0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00,
+       }
+       r, err := NewReader(bytes.NewReader([]byte(data)), int64(len(data)))
+       if err != nil {
+               t.Fatalf("Error reading the archive: %v", err)
+       }
+       _, err = r.Open("test.txt")
+       if err != nil {
+               t.Errorf("Error reading file: %v", err)
+       }
+}
diff --git a/libgo/go/cmd/go.mod b/libgo/go/cmd/go.mod
index 235e28f64f3..35582f3975f 100644
--- a/libgo/go/cmd/go.mod
+++ b/libgo/go/cmd/go.mod
@@ -6,7 +6,7 @@ require (
        github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2
        golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff
        golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
-       golang.org/x/mod v0.4.1
+       golang.org/x/mod v0.4.2-0.20210302225053-d515b24adc21
        golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect
        golang.org/x/tools v0.0.0-20210107193943-4ed967dd8eff
 )
diff --git a/libgo/go/cmd/go/internal/get/get.go 
b/libgo/go/cmd/go/internal/get/get.go
index 38ff3823f22..329a2f5eda4 100644
--- a/libgo/go/cmd/go/internal/get/get.go
+++ b/libgo/go/cmd/go/internal/get/get.go
@@ -431,7 +431,7 @@ func downloadPackage(p *load.Package) error {
                }
                importPrefix = importPrefix[:slash]
        }
-       if err := module.CheckImportPath(importPrefix); err != nil {
+       if err := checkImportPath(importPrefix); err != nil {
                return fmt.Errorf("%s: invalid import path: %v", p.ImportPath, 
err)
        }
        security := web.SecureOnly
@@ -591,3 +591,31 @@ func selectTag(goVersion string, tags []string) (match 
string) {
        }
        return ""
 }
+
+// checkImportPath is like module.CheckImportPath, but it forbids leading dots
+// in path elements. This can lead to 'go get' creating .git and other VCS
+// directories in places we might run VCS tools later.
+func checkImportPath(path string) error {
+       if err := module.CheckImportPath(path); err != nil {
+               return err
+       }
+       checkElem := func(elem string) error {
+               if elem[0] == '.' {
+                       return fmt.Errorf("malformed import path %q: leading 
dot in path element", path)
+               }
+               return nil
+       }
+       elemStart := 0
+       for i, r := range path {
+               if r == '/' {
+                       if err := checkElem(path[elemStart:]); err != nil {
+                               return err
+                       }
+                       elemStart = i + 1
+               }
+       }
+       if err := checkElem(path[elemStart:]); err != nil {
+               return err
+       }
+       return nil
+}
diff --git a/libgo/go/cmd/go/internal/modcmd/tidy.go 
b/libgo/go/cmd/go/internal/modcmd/tidy.go
index 3b83d87a8eb..8bc9ed50bed 100644
--- a/libgo/go/cmd/go/internal/modcmd/tidy.go
+++ b/libgo/go/cmd/go/internal/modcmd/tidy.go
@@ -62,10 +62,11 @@ func runTidy(ctx context.Context, cmd *base.Command, args 
[]string) {
        modload.RootMode = modload.NeedRoot
 
        modload.LoadPackages(ctx, modload.PackageOpts{
-               Tags:                  imports.AnyTags(),
-               ResolveMissingImports: true,
-               LoadTests:             true,
-               AllowErrors:           tidyE,
+               Tags:                     imports.AnyTags(),
+               ResolveMissingImports:    true,
+               LoadTests:                true,
+               AllowErrors:              tidyE,
+               SilenceMissingStdImports: true,
        }, "all")
 
        modload.TidyBuildList()
diff --git a/libgo/go/cmd/go/internal/modcmd/vendor.go 
b/libgo/go/cmd/go/internal/modcmd/vendor.go
index d3ed9e00e22..ac1fb7720aa 100644
--- a/libgo/go/cmd/go/internal/modcmd/vendor.go
+++ b/libgo/go/cmd/go/internal/modcmd/vendor.go
@@ -64,10 +64,11 @@ func runVendor(ctx context.Context, cmd *base.Command, args 
[]string) {
        modload.RootMode = modload.NeedRoot
 
        loadOpts := modload.PackageOpts{
-               Tags:                  imports.AnyTags(),
-               ResolveMissingImports: true,
-               UseVendorAll:          true,
-               AllowErrors:           vendorE,
+               Tags:                     imports.AnyTags(),
+               ResolveMissingImports:    true,
+               UseVendorAll:             true,
+               AllowErrors:              vendorE,
+               SilenceMissingStdImports: true,
        }
        _, pkgs := modload.LoadPackages(ctx, loadOpts, "all")
 
diff --git a/libgo/go/cmd/go/internal/modget/get.go 
b/libgo/go/cmd/go/internal/modget/get.go
index dccacd3d1ee..5a98408a325 100644
--- a/libgo/go/cmd/go/internal/modget/get.go
+++ b/libgo/go/cmd/go/internal/modget/get.go
@@ -1514,7 +1514,7 @@ func (r *resolver) checkPackagesAndRetractions(ctx 
context.Context, pkgPatterns
                }
        }
        if retractPath != "" {
-               fmt.Fprintf(os.Stderr, "go: to switch to the latest unretracted 
version, run:\n\tgo get %s@latest", retractPath)
+               fmt.Fprintf(os.Stderr, "go: to switch to the latest unretracted 
version, run:\n\tgo get %s@latest\n", retractPath)
        }
 }
 
diff --git a/libgo/go/cmd/go/internal/modget/query.go 
b/libgo/go/cmd/go/internal/modget/query.go
index d8364c8c0d3..1a5a60f7eb9 100644
--- a/libgo/go/cmd/go/internal/modget/query.go
+++ b/libgo/go/cmd/go/internal/modget/query.go
@@ -186,7 +186,7 @@ func (q *query) validate() error {
        if q.pattern == "all" {
                // If there is no main module, "all" is not meaningful.
                if !modload.HasModRoot() {
-                       return fmt.Errorf(`cannot match "all": working 
directory is not part of a module`)
+                       return fmt.Errorf(`cannot match "all": %v`, 
modload.ErrNoModRoot)
                }
                if !versionOkForMainModule(q.version) {
                        // TODO(bcmills): "all@none" seems like a totally 
reasonable way to
diff --git a/libgo/go/cmd/go/internal/modload/import.go 
b/libgo/go/cmd/go/internal/modload/import.go
index 182429aee41..995641c9f1f 100644
--- a/libgo/go/cmd/go/internal/modload/import.go
+++ b/libgo/go/cmd/go/internal/modload/import.go
@@ -51,7 +51,7 @@ func (e *ImportMissingError) Error() string {
                if e.isStd {
                        return fmt.Sprintf("package %s is not in GOROOT (%s)", 
e.Path, filepath.Join(cfg.GOROOT, "src", e.Path))
                }
-               if e.QueryErr != nil {
+               if e.QueryErr != nil && e.QueryErr != ErrNoModRoot {
                        return fmt.Sprintf("cannot find module providing 
package %s: %v", e.Path, e.QueryErr)
                }
                if cfg.BuildMod == "mod" || (cfg.BuildMod == "readonly" && 
allowMissingModuleImports) {
@@ -66,13 +66,11 @@ func (e *ImportMissingError) Error() string {
                        return fmt.Sprintf("module %s provides package %s and 
is replaced but not required; to add it:\n\tgo get %s", e.replaced.Path, 
e.Path, suggestArg)
                }
 
-               suggestion := ""
-               if !HasModRoot() {
-                       suggestion = ": working directory is not part of a 
module"
-               } else {
-                       suggestion = fmt.Sprintf("; to add it:\n\tgo get %s", 
e.Path)
+               message := fmt.Sprintf("no required module provides package 
%s", e.Path)
+               if e.QueryErr != nil {
+                       return fmt.Sprintf("%s: %v", message, e.QueryErr)
                }
-               return fmt.Sprintf("no required module provides package %s%s", 
e.Path, suggestion)
+               return fmt.Sprintf("%s; to add it:\n\tgo get %s", message, 
e.Path)
        }
 
        if e.newMissingVersion != "" {
@@ -318,7 +316,11 @@ func importFromBuildList(ctx context.Context, path string, 
buildList []module.Ve
                return mods[0], dirs[0], nil
        }
 
-       return module.Version{}, "", &ImportMissingError{Path: path, isStd: 
pathIsStd}
+       var queryErr error
+       if !HasModRoot() {
+               queryErr = ErrNoModRoot
+       }
+       return module.Version{}, "", &ImportMissingError{Path: path, QueryErr: 
queryErr, isStd: pathIsStd}
 }
 
 // queryImport attempts to locate a module that can be added to the current
diff --git a/libgo/go/cmd/go/internal/modload/init.go 
b/libgo/go/cmd/go/internal/modload/init.go
index bc8d17e0a5f..8ec1c8681a9 100644
--- a/libgo/go/cmd/go/internal/modload/init.go
+++ b/libgo/go/cmd/go/internal/modload/init.go
@@ -177,7 +177,7 @@ func Init() {
                                base.Fatalf("go: cannot find main module, but 
-modfile was set.\n\t-modfile cannot be used to set the module root directory.")
                        }
                        if RootMode == NeedRoot {
-                               base.Fatalf("go: cannot find main module; see 
'go help modules'")
+                               base.Fatalf("go: %v", ErrNoModRoot)
                        }
                        if !mustUseModules {
                                // GO111MODULE is 'auto', and we can't find a 
module root.
@@ -338,9 +338,11 @@ func die() {
                }
                base.Fatalf("go: cannot find main module, but found %s in 
%s\n\tto create a module there, run:\n\t%sgo mod init", name, dir, cdCmd)
        }
-       base.Fatalf("go: cannot find main module; see 'go help modules'")
+       base.Fatalf("go: %v", ErrNoModRoot)
 }
 
+var ErrNoModRoot = errors.New("go.mod file not found in current directory or 
any parent directory; see 'go help modules'")
+
 // LoadModFile sets Target and, if there is a main module, parses the initial
 // build list from its go.mod file.
 //
@@ -539,9 +541,10 @@ func fixVersion(ctx context.Context, fixed *bool) 
modfile.VersionFixer {
                        }
                }
                if vers != "" && module.CanonicalVersion(vers) == vers {
-                       if err := module.CheckPathMajor(vers, pathMajor); err 
== nil {
-                               return vers, nil
+                       if err := module.CheckPathMajor(vers, pathMajor); err 
!= nil {
+                               return "", 
module.VersionError(module.Version{Path: path, Version: vers}, err)
                        }
+                       return vers, nil
                }
 
                info, err := Query(ctx, path, vers, "", nil)
diff --git a/libgo/go/cmd/go/internal/modload/list.go 
b/libgo/go/cmd/go/internal/modload/list.go
index 3491f941cd3..7b1aa7fd413 100644
--- a/libgo/go/cmd/go/internal/modload/list.go
+++ b/libgo/go/cmd/go/internal/modload/list.go
@@ -73,7 +73,7 @@ func listModules(ctx context.Context, args []string, 
listVersions, listRetracted
                        base.Fatalf("go: cannot use relative path %s to specify 
module", arg)
                }
                if !HasModRoot() && (arg == "all" || strings.Contains(arg, 
"...")) {
-                       base.Fatalf("go: cannot match %q: working directory is 
not part of a module", arg)
+                       base.Fatalf("go: cannot match %q: %v", arg, 
ErrNoModRoot)
                }
                if i := strings.Index(arg, "@"); i >= 0 {
                        path := arg[:i]
diff --git a/libgo/go/cmd/go/internal/modload/load.go 
b/libgo/go/cmd/go/internal/modload/load.go
index 6d87acc6d3b..154fc3c6f0a 100644
--- a/libgo/go/cmd/go/internal/modload/load.go
+++ b/libgo/go/cmd/go/internal/modload/load.go
@@ -170,6 +170,12 @@ type PackageOpts struct {
        // that occur while loading packages. SilenceErrors implies AllowErrors.
        SilenceErrors bool
 
+       // SilenceMissingStdImports indicates that LoadPackages should not print
+       // errors or terminate the process if an imported package is missing, 
and the
+       // import path looks like it might be in the standard library (perhaps 
in a
+       // future version).
+       SilenceMissingStdImports bool
+
        // SilenceUnmatchedWarnings suppresses the warnings normally emitted for
        // patterns that did not match any packages.
        SilenceUnmatchedWarnings bool
@@ -287,8 +293,13 @@ func LoadPackages(ctx context.Context, opts PackageOpts, 
patterns ...string) (ma
                                        sumErr.importerIsTest = importer.testOf 
!= nil
                                }
                        }
+                       silence := opts.SilenceErrors
+                       if stdErr := (*ImportMissingError)(nil); 
errors.As(pkg.err, &stdErr) &&
+                               stdErr.isStd && opts.SilenceMissingStdImports {
+                               silence = true
+                       }
 
-                       if !opts.SilenceErrors {
+                       if !silence {
                                if opts.AllowErrors {
                                        fmt.Fprintf(os.Stderr, "%s: %v\n", 
pkg.stackText(), pkg.err)
                                } else {
diff --git a/libgo/go/cmd/go/internal/run/run.go 
b/libgo/go/cmd/go/internal/run/run.go
index 99578b244c8..666b1a0e560 100644
--- a/libgo/go/cmd/go/internal/run/run.go
+++ b/libgo/go/cmd/go/internal/run/run.go
@@ -96,28 +96,12 @@ func runRun(ctx context.Context, cmd *base.Command, args 
[]string) {
                base.Fatalf("go run: no go files listed")
        }
        cmdArgs := args[i:]
-       if p.Error != nil {
-               base.Fatalf("%s", p.Error)
-       }
+       load.CheckPackageErrors([]*load.Package{p})
 
-       p.Internal.OmitDebug = true
-       if len(p.DepsErrors) > 0 {
-               // Since these are errors in dependencies,
-               // the same error might show up multiple times,
-               // once in each package that depends on it.
-               // Only print each once.
-               printed := map[*load.PackageError]bool{}
-               for _, err := range p.DepsErrors {
-                       if !printed[err] {
-                               printed[err] = true
-                               base.Errorf("%s", err)
-                       }
-               }
-       }
-       base.ExitIfErrors()
        if p.Name != "main" {
                base.Fatalf("go run: cannot run non-main package")
        }
+       p.Internal.OmitDebug = true
        p.Target = "" // must build - not up to date
        if p.Internal.CmdlineFiles {
                //set executable name if go file is given as cmd-argument
diff --git a/libgo/go/cmd/go/testdata/script/mod_convert_dep.txt 
b/libgo/go/cmd/go/testdata/script/mod_convert_dep.txt
index ad22aca5be8..875a836fd27 100644
--- a/libgo/go/cmd/go/testdata/script/mod_convert_dep.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_convert_dep.txt
@@ -18,7 +18,7 @@ stdout '^m$'
 # Test that we ignore directories when trying to find alternate config files.
 cd $WORK/gopkgdir/x
 ! go list .
-stderr 'cannot find main module'
+stderr '^go: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 ! stderr 'Gopkg.lock'
 
 -- $WORK/test/Gopkg.lock --
diff --git a/libgo/go/cmd/go/testdata/script/mod_edit.txt 
b/libgo/go/cmd/go/testdata/script/mod_edit.txt
index d7e681e8313..9da69306dac 100644
--- a/libgo/go/cmd/go/testdata/script/mod_edit.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_edit.txt
@@ -16,9 +16,9 @@ cmpenv go.mod $WORK/go.mod.init
 cmpenv go.mod $WORK/go.mod.init
 
 # go mod edits
-go mod edit -droprequire=x.1 -require=x.1@v1.0.0 -require=x.2@v1.1.0 
-droprequire=x.2 -exclude='x.1 @ v1.2.0' -exclude=x.1@v1.2.1 
-replace=x.1@v1.3.0=y.1@v1.4.0 -replace='x.1@v1.4.0 = ../z' -retract=v1.6.0 
-retract=[v1.1.0,v1.2.0] -retract=[v1.3.0,v1.4.0] -retract=v1.0.0
+go mod edit -droprequire=x.1 -require=x.1@v1.0.0 -require=x.2@v1.1.0 
-droprequire=x.2 -exclude='x.1 @ v1.2.0' -exclude=x.1@v1.2.1 
-exclude=x.1@v2.0.0+incompatible -replace=x.1@v1.3.0=y.1@v1.4.0 
-replace='x.1@v1.4.0 = ../z' -retract=v1.6.0 -retract=[v1.1.0,v1.2.0] 
-retract=[v1.3.0,v1.4.0] -retract=v1.0.0
 cmpenv go.mod $WORK/go.mod.edit1
-go mod edit -droprequire=x.1 -dropexclude=x.1@v1.2.1 -dropreplace=x.1@v1.3.0 
-require=x.3@v1.99.0 -dropretract=v1.0.0 -dropretract=[v1.1.0,v1.2.0]
+go mod edit -droprequire=x.1 -dropexclude=x.1@v1.2.1 
-dropexclude=x.1@v2.0.0+incompatible -dropreplace=x.1@v1.3.0 
-require=x.3@v1.99.0 -dropretract=v1.0.0 -dropretract=[v1.1.0,v1.2.0]
 cmpenv go.mod $WORK/go.mod.edit2
 
 # -exclude and -retract reject invalid versions.
@@ -27,6 +27,17 @@ stderr '^go mod: -exclude=example.com/m@bad: version "bad" 
invalid: must be of t
 ! go mod edit -retract=bad
 stderr '^go mod: -retract=bad: version "bad" invalid: must be of the form 
v1.2.3$'
 
+! go mod edit -exclude=example.com/m@v2.0.0
+stderr '^go mod: -exclude=example.com/m@v2\.0\.0: version "v2\.0\.0" invalid: 
should be v2\.0\.0\+incompatible \(or module example\.com/m/v2\)$'
+
+! go mod edit -exclude=example.com/m/v2@v1.0.0
+stderr '^go mod: -exclude=example.com/m/v2@v1\.0\.0: version "v1\.0\.0" 
invalid: should be v2, not v1$'
+
+! go mod edit -exclude=gopkg.in/example.v1@v2.0.0
+stderr '^go mod: -exclude=gopkg\.in/example\.v1@v2\.0\.0: version "v2\.0\.0" 
invalid: should be v1, not v2$'
+
+cmpenv go.mod $WORK/go.mod.edit2
+
 # go mod edit -json
 go mod edit -json
 cmpenv stdout $WORK/go.mod.json
@@ -88,6 +99,7 @@ require x.1 v1.0.0
 exclude (
        x.1 v1.2.0
        x.1 v1.2.1
+       x.1 v2.0.0+incompatible
 )
 
 replace (
diff --git a/libgo/go/cmd/go/testdata/script/mod_find.txt 
b/libgo/go/cmd/go/testdata/script/mod_find.txt
index 9468acfd33d..1e01973ff41 100644
--- a/libgo/go/cmd/go/testdata/script/mod_find.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_find.txt
@@ -49,7 +49,7 @@ rm go.mod
 # Test that we ignore directories when trying to find go.mod.
 cd $WORK/gomoddir
 ! go list .
-stderr 'cannot find main module'
+stderr '^go: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 
 [!symlink] stop
 
diff --git a/libgo/go/cmd/go/testdata/script/mod_outside.txt 
b/libgo/go/cmd/go/testdata/script/mod_outside.txt
index 8f01b5d2426..565589268ee 100644
--- a/libgo/go/cmd/go/testdata/script/mod_outside.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_outside.txt
@@ -12,13 +12,13 @@ stdout 'NUL|/dev/null'
 # 'go list' without arguments implicitly operates on the current directory,
 # which is not in a module.
 ! go list
-stderr 'cannot find main module'
+stderr '^go: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 go list -m
 stdout '^command-line-arguments$'
 # 'go list' in the working directory should fail even if there is a a 'package
 # main' present: without a main module, we do not know its package path.
 ! go list ./needmod
-stderr 'cannot find main module'
+stderr '^go: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 
 # 'go list all' lists the transitive import graph of the main module,
 # which is empty if there is no main module.
@@ -41,7 +41,7 @@ stdout 'command-line-arguments'
 
 # 'go list' on a package from a module should fail.
 ! go list example.com/printversion
-stderr '^no required module provides package example.com/printversion: working 
directory is not part of a module$'
+stderr '^no required module provides package example.com/printversion: go.mod 
file not found in current directory or any parent directory; see ''go help 
modules''$'
 
 
 # 'go list -m' with an explicit version should resolve that version.
@@ -54,19 +54,19 @@ stdout 'v1.0.0\s+v1.0.1\s+v1.1.0'
 
 # 'go list -m all' should fail. "all" is not meaningful outside of a module.
 ! go list -m all
-stderr 'go: cannot match "all": working directory is not part of a module'
+stderr 'go: cannot match "all": go.mod file not found in current directory or 
any parent directory; see ''go help modules''$'
 
 # 'go list -m <mods> all' should also fail.
 ! go list -m example.com/printversion@v1.0.0 all
-stderr 'go: cannot match "all": working directory is not part of a module'
+stderr 'go: cannot match "all": go.mod file not found in current directory or 
any parent directory; see ''go help modules''$'
 ! stdout 'example.com/version'
 
 # 'go list -m' with wildcards should fail. Wildcards match modules in the
 # build list, so they aren't meaningful outside a module.
 ! go list -m ...
-stderr 'go: cannot match "...": working directory is not part of a module'
+stderr 'go: cannot match "...": go.mod file not found in current directory or 
any parent directory; see ''go help modules''$'
 ! go list -m rsc.io/quote/...
-stderr 'go: cannot match "rsc.io/quote/...": working directory is not part of 
a module'
+stderr 'go: cannot match "rsc.io/quote/...": go.mod file not found in current 
directory or any parent directory; see ''go help modules''$'
 
 
 # 'go clean' should skip the current directory if it isn't in a module.
@@ -76,20 +76,20 @@ go clean -n
 
 # 'go mod graph' should fail, since there's no module graph.
 ! go mod graph
-stderr 'cannot find main module'
+stderr '^go: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 
 # 'go mod why' should fail, since there is no main module to depend on 
anything.
 ! go mod why -m example.com/version
-stderr 'cannot find main module'
+stderr '^go: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 
 # 'go mod edit', 'go mod tidy', and 'go mod fmt' should fail:
 # there is no go.mod file to edit.
 ! go mod tidy
-stderr 'cannot find main module'
+stderr '^go: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 ! go mod edit -fmt
-stderr 'cannot find main module'
+stderr '^go: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 ! go mod edit -require example.com/version@v1.0.0
-stderr 'cannot find main module'
+stderr '^go: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 
 
 # 'go mod download' without arguments should report an error.
@@ -104,33 +104,33 @@ exists 
$GOPATH/pkg/mod/cache/download/example.com/printversion/@v/v1.0.0.zip
 
 # 'go mod download all' should fail. "all" is not meaningful outside of a 
module.
 ! go mod download all
-stderr 'go: cannot match "all": working directory is not part of a module'
+stderr 'go: cannot match "all": go.mod file not found in current directory or 
any parent directory; see ''go help modules''$'
 
 
 # 'go mod vendor' should fail: it starts by clearing the existing vendor
 # directory, and we don't know where that is.
 ! go mod vendor
-stderr 'cannot find main module'
+stderr '^go: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 
 
 # 'go mod verify' should fail: we have no modules to verify.
 ! go mod verify
-stderr 'cannot find main module'
+stderr '^go: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 
 
 # 'go get' without arguments implicitly operates on the main module, and thus
 # should fail.
 ! go get
-stderr 'cannot find main module'
+stderr '^go: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 ! go get -u
-stderr 'cannot find main module'
+stderr '^go: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 ! go get -u ./needmod
-stderr 'cannot find main module'
+stderr '^go: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 
 # 'go get -u all' upgrades the transitive import graph of the main module,
 # which is empty.
 ! go get -u all
-stderr 'go get: cannot match "all": working directory is not part of a module'
+stderr '^go get: cannot match "all": go.mod file not found in current 
directory or any parent directory; see ''go help modules''$'
 
 # 'go get' should check the proposed module graph for consistency,
 # even though we won't write it anywhere.
@@ -147,16 +147,16 @@ exists $GOPATH/pkg/mod/example.com/version@v1.0.0
 # 'go build' without arguments implicitly operates on the current directory, 
and should fail.
 cd needmod
 ! go build
-stderr 'cannot find main module'
+stderr '^go: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 cd ..
 
 # 'go build' of a non-module directory should fail too.
 ! go build ./needmod
-stderr 'cannot find main module'
+stderr '^go: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 
 # 'go build' of source files should fail if they import anything outside std.
 ! go build -n ./needmod/needmod.go
-stderr '^needmod[/\\]needmod.go:10:2: no required module provides package 
example.com/version: working directory is not part of a module$'
+stderr '^needmod[/\\]needmod.go:10:2: no required module provides package 
example.com/version: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 
 # 'go build' of source files should succeed if they do not import anything 
outside std.
 go build -n -o ignore ./stdonly/stdonly.go
@@ -179,7 +179,7 @@ go doc fmt
 
 # 'go doc' should fail for a package path outside a module.
 ! go doc example.com/version
-stderr 'doc: no required module provides package example.com/version: working 
directory is not part of a module'
+stderr 'doc: no required module provides package example.com/version: go.mod 
file not found in current directory or any parent directory; see ''go help 
modules''$'
 
 # 'go install' with a version should succeed if all constraints are met.
 # See mod_install_pkg_version.
@@ -194,7 +194,7 @@ stderr '^go install: version is required when current 
directory is not in a modu
 # 'go install' should fail if a source file imports a package that must be
 # resolved to a module.
 ! go install ./needmod/needmod.go
-stderr 'needmod[/\\]needmod.go:10:2: no required module provides package 
example.com/version: working directory is not part of a module'
+stderr 'needmod[/\\]needmod.go:10:2: no required module provides package 
example.com/version: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 
 # 'go install' should succeed with a package in GOROOT.
 go install cmd/addr2line
@@ -206,12 +206,12 @@ stderr 'can only use path@version syntax with'
 
 # 'go run' should fail if a package argument must be resolved to a module.
 ! go run example.com/printversion
-stderr '^no required module provides package example.com/printversion: working 
directory is not part of a module$'
+stderr '^no required module provides package example.com/printversion: go.mod 
file not found in current directory or any parent directory; see ''go help 
modules''$'
 
 # 'go run' should fail if a source file imports a package that must be
 # resolved to a module.
 ! go run ./needmod/needmod.go
-stderr '^needmod[/\\]needmod.go:10:2: no required module provides package 
example.com/version: working directory is not part of a module$'
+stderr '^needmod[/\\]needmod.go:10:2: no required module provides package 
example.com/version: go.mod file not found in current directory or any parent 
directory; see ''go help modules''$'
 
 
 # 'go fmt' should be able to format files outside of a module.
diff --git a/libgo/go/cmd/go/testdata/script/mod_tidy_error.txt 
b/libgo/go/cmd/go/testdata/script/mod_tidy_error.txt
index b6c24ceaf75..395537b1a71 100644
--- a/libgo/go/cmd/go/testdata/script/mod_tidy_error.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_tidy_error.txt
@@ -4,12 +4,12 @@ env GO111MODULE=on
 # 'go mod tidy' and 'go mod vendor' should not hide loading errors.
 
 ! go mod tidy
-stderr '^issue27063 imports\n\tnonexist: package nonexist is not in GOROOT 
\(.*\)'
+! stderr 'package nonexist is not in GOROOT'
 stderr '^issue27063 imports\n\tnonexist.example.com: cannot find module 
providing package nonexist.example.com'
 stderr '^issue27063 imports\n\tissue27063/other 
imports\n\tother.example.com/nonexist: cannot find module providing package 
other.example.com/nonexist'
 
 ! go mod vendor
-stderr '^issue27063 imports\n\tnonexist: package nonexist is not in GOROOT 
\(.*\)'
+! stderr 'package nonexist is not in GOROOT'
 stderr '^issue27063 imports\n\tnonexist.example.com: cannot find module 
providing package nonexist.example.com'
 stderr '^issue27063 imports\n\tissue27063/other 
imports\n\tother.example.com/nonexist: cannot find module providing package 
other.example.com/nonexist'
 
diff --git a/libgo/go/cmd/vendor/modules.txt b/libgo/go/cmd/vendor/modules.txt
index e033984956b..10842768a88 100644
--- a/libgo/go/cmd/vendor/modules.txt
+++ b/libgo/go/cmd/vendor/modules.txt
@@ -28,7 +28,7 @@ golang.org/x/arch/x86/x86asm
 golang.org/x/crypto/ed25519
 golang.org/x/crypto/ed25519/internal/edwards25519
 golang.org/x/crypto/ssh/terminal
-# golang.org/x/mod v0.4.1
+# golang.org/x/mod v0.4.2-0.20210302225053-d515b24adc21
 ## explicit
 golang.org/x/mod/internal/lazyregexp
 golang.org/x/mod/modfile
diff --git a/libgo/go/encoding/xml/xml.go b/libgo/go/encoding/xml/xml.go
index adaf4daf198..6f9594d7ba7 100644
--- a/libgo/go/encoding/xml/xml.go
+++ b/libgo/go/encoding/xml/xml.go
@@ -271,7 +271,7 @@ func NewTokenDecoder(t TokenReader) *Decoder {
 // it will return an error.
 //
 // Token implements XML name spaces as described by
-// https://www.w3.org/TR/REC-xml-names/.  Each of the
+// https://www.w3.org/TR/REC-xml-names/. Each of the
 // Name structures contained in the Token has the Space
 // set to the URL identifying its name space when known.
 // If Token encounters an unrecognized name space prefix,
@@ -285,16 +285,17 @@ func (d *Decoder) Token() (Token, error) {
        if d.nextToken != nil {
                t = d.nextToken
                d.nextToken = nil
-       } else if t, err = d.rawToken(); err != nil {
-               switch {
-               case err == io.EOF && d.t != nil:
-                       err = nil
-               case err == io.EOF && d.stk != nil && d.stk.kind != stkEOF:
-                       err = d.syntaxError("unexpected EOF")
+       } else {
+               if t, err = d.rawToken(); t == nil && err != nil {
+                       if err == io.EOF && d.stk != nil && d.stk.kind != 
stkEOF {
+                               err = d.syntaxError("unexpected EOF")
+                       }
+                       return nil, err
                }
-               return t, err
+               // We still have a token to process, so clear any
+               // errors (e.g. EOF) and proceed.
+               err = nil
        }
-
        if !d.Strict {
                if t1, ok := d.autoClose(t); ok {
                        d.nextToken = t
diff --git a/libgo/go/encoding/xml/xml_test.go 
b/libgo/go/encoding/xml/xml_test.go
index efddca43e91..5672ebb375f 100644
--- a/libgo/go/encoding/xml/xml_test.go
+++ b/libgo/go/encoding/xml/xml_test.go
@@ -33,30 +33,90 @@ func (t *toks) Token() (Token, error) {
 
 func TestDecodeEOF(t *testing.T) {
        start := StartElement{Name: Name{Local: "test"}}
-       t.Run("EarlyEOF", func(t *testing.T) {
-               d := NewTokenDecoder(&toks{earlyEOF: true, t: []Token{
-                       start,
-                       start.End(),
-               }})
-               err := d.Decode(&struct {
-                       XMLName Name `xml:"test"`
-               }{})
-               if err != nil {
-                       t.Error(err)
+       tests := []struct {
+               name   string
+               tokens []Token
+               ok     bool
+       }{
+               {
+                       name: "OK",
+                       tokens: []Token{
+                               start,
+                               start.End(),
+                       },
+                       ok: true,
+               },
+               {
+                       name: "Malformed",
+                       tokens: []Token{
+                               start,
+                               StartElement{Name: Name{Local: "bad"}},
+                               start.End(),
+                       },
+                       ok: false,
+               },
+       }
+       for _, tc := range tests {
+               for _, eof := range []bool{true, false} {
+                       name := fmt.Sprintf("%s/earlyEOF=%v", tc.name, eof)
+                       t.Run(name, func(t *testing.T) {
+                               d := NewTokenDecoder(&toks{
+                                       earlyEOF: eof,
+                                       t:        tc.tokens,
+                               })
+                               err := d.Decode(&struct {
+                                       XMLName Name `xml:"test"`
+                               }{})
+                               if tc.ok && err != nil {
+                                       t.Fatalf("d.Decode: expected nil error, 
got %v", err)
+                               }
+                               if _, ok := err.(*SyntaxError); !tc.ok && !ok {
+                                       t.Errorf("d.Decode: expected syntax 
error, got %v", err)
+                               }
+                       })
                }
-       })
-       t.Run("LateEOF", func(t *testing.T) {
-               d := NewTokenDecoder(&toks{t: []Token{
-                       start,
-                       start.End(),
-               }})
-               err := d.Decode(&struct {
-                       XMLName Name `xml:"test"`
-               }{})
-               if err != nil {
-                       t.Error(err)
+       }
+}
+
+type toksNil struct {
+       returnEOF bool
+       t         []Token
+}
+
+func (t *toksNil) Token() (Token, error) {
+       if len(t.t) == 0 {
+               if !t.returnEOF {
+                       // Return nil, nil before returning an EOF. It's legal, 
but
+                       // discouraged.
+                       t.returnEOF = true
+                       return nil, nil
                }
-       })
+               return nil, io.EOF
+       }
+       var tok Token
+       tok, t.t = t.t[0], t.t[1:]
+       return tok, nil
+}
+
+func TestDecodeNilToken(t *testing.T) {
+       for _, strict := range []bool{true, false} {
+               name := fmt.Sprintf("Strict=%v", strict)
+               t.Run(name, func(t *testing.T) {
+                       start := StartElement{Name: Name{Local: "test"}}
+                       bad := StartElement{Name: Name{Local: "bad"}}
+                       d := NewTokenDecoder(&toksNil{
+                               // Malformed
+                               t: []Token{start, bad, start.End()},
+                       })
+                       d.Strict = strict
+                       err := d.Decode(&struct {
+                               XMLName Name `xml:"test"`
+                       }{})
+                       if _, ok := err.(*SyntaxError); !ok {
+                               t.Errorf("d.Decode: expected syntax error, got 
%v", err)
+                       }
+               })
+       }
 }
 
 const testInput = `
diff --git a/libgo/go/go/build/build_test.go b/libgo/go/go/build/build_test.go
index 490c212642c..1c0dc4692c9 100644
--- a/libgo/go/go/build/build_test.go
+++ b/libgo/go/go/build/build_test.go
@@ -614,7 +614,7 @@ func TestImportPackageOutsideModule(t *testing.T) {
        ctxt.GOPATH = gopath
        ctxt.Dir = filepath.Join(gopath, "src/example.com/p")
 
-       want := "working directory is not part of a module"
+       want := "go.mod file not found in current directory or any parent 
directory"
        if _, err := ctxt.Import("example.com/p", gopath, FindOnly); err == nil 
{
                t.Fatal("importing package when no go.mod is present succeeded 
unexpectedly")
        } else if errStr := err.Error(); !strings.Contains(errStr, want) {
diff --git a/libgo/go/golang.org/x/mod/modfile/rule.go 
b/libgo/go/golang.org/x/mod/modfile/rule.go
index c6a189dbe04..f8c93849859 100644
--- a/libgo/go/golang.org/x/mod/modfile/rule.go
+++ b/libgo/go/golang.org/x/mod/modfile/rule.go
@@ -125,6 +125,12 @@ func (f *File) AddComment(text string) {
 
 type VersionFixer func(path, version string) (string, error)
 
+// errDontFix is returned by a VersionFixer to indicate the version should be
+// left alone, even if it's not canonical.
+var dontFixRetract VersionFixer = func(_, vers string) (string, error) {
+       return vers, nil
+}
+
 // Parse parses the data, reported in errors as being from file,
 // into a File struct. It applies fix, if non-nil, to canonicalize all module 
versions found.
 func Parse(file string, data []byte, fix VersionFixer) (*File, error) {
@@ -142,7 +148,7 @@ func ParseLax(file string, data []byte, fix VersionFixer) 
(*File, error) {
        return parseToFile(file, data, fix, false)
 }
 
-func parseToFile(file string, data []byte, fix VersionFixer, strict bool) 
(*File, error) {
+func parseToFile(file string, data []byte, fix VersionFixer, strict bool) 
(parsed *File, err error) {
        fs, err := parse(file, data)
        if err != nil {
                return nil, err
@@ -150,8 +156,18 @@ func parseToFile(file string, data []byte, fix 
VersionFixer, strict bool) (*File
        f := &File{
                Syntax: fs,
        }
-
        var errs ErrorList
+
+       // fix versions in retract directives after the file is parsed.
+       // We need the module path to fix versions, and it might be at the end.
+       defer func() {
+               oldLen := len(errs)
+               f.fixRetract(fix, &errs)
+               if len(errs) > oldLen {
+                       parsed, err = nil, errs
+               }
+       }()
+
        for _, x := range fs.Stmt {
                switch x := x.(type) {
                case *Line:
@@ -370,7 +386,7 @@ func (f *File) add(errs *ErrorList, block *LineBlock, line 
*Line, verb string, a
 
        case "retract":
                rationale := parseRetractRationale(block, line)
-               vi, err := parseVersionInterval(verb, &args, fix)
+               vi, err := parseVersionInterval(verb, "", &args, dontFixRetract)
                if err != nil {
                        if strict {
                                wrapError(err)
@@ -397,6 +413,47 @@ func (f *File) add(errs *ErrorList, block *LineBlock, line 
*Line, verb string, a
        }
 }
 
+// fixRetract applies fix to each retract directive in f, appending any errors
+// to errs.
+//
+// Most versions are fixed as we parse the file, but for retract directives,
+// the relevant module path is the one specified with the module directive,
+// and that might appear at the end of the file (or not at all).
+func (f *File) fixRetract(fix VersionFixer, errs *ErrorList) {
+       if fix == nil {
+               return
+       }
+       path := ""
+       if f.Module != nil {
+               path = f.Module.Mod.Path
+       }
+       var r *Retract
+       wrapError := func(err error) {
+               *errs = append(*errs, Error{
+                       Filename: f.Syntax.Name,
+                       Pos:      r.Syntax.Start,
+                       Err:      err,
+               })
+       }
+
+       for _, r = range f.Retract {
+               if path == "" {
+                       wrapError(errors.New("no module directive found, so 
retract cannot be used"))
+                       return // only print the first one of these
+               }
+
+               args := r.Syntax.Token
+               if args[0] == "retract" {
+                       args = args[1:]
+               }
+               vi, err := parseVersionInterval("retract", path, &args, fix)
+               if err != nil {
+                       wrapError(err)
+               }
+               r.VersionInterval = vi
+       }
+}
+
 // isIndirect reports whether line has a "// indirect" comment,
 // meaning it is in go.mod only for its effect on indirect dependencies,
 // so that it can be dropped entirely once the effective version of the
@@ -491,13 +548,13 @@ func AutoQuote(s string) string {
        return s
 }
 
-func parseVersionInterval(verb string, args *[]string, fix VersionFixer) 
(VersionInterval, error) {
+func parseVersionInterval(verb string, path string, args *[]string, fix 
VersionFixer) (VersionInterval, error) {
        toks := *args
        if len(toks) == 0 || toks[0] == "(" {
                return VersionInterval{}, fmt.Errorf("expected '[' or version")
        }
        if toks[0] != "[" {
-               v, err := parseVersion(verb, "", &toks[0], fix)
+               v, err := parseVersion(verb, path, &toks[0], fix)
                if err != nil {
                        return VersionInterval{}, err
                }
@@ -509,7 +566,7 @@ func parseVersionInterval(verb string, args *[]string, fix 
VersionFixer) (Versio
        if len(toks) == 0 {
                return VersionInterval{}, fmt.Errorf("expected version after 
'['")
        }
-       low, err := parseVersion(verb, "", &toks[0], fix)
+       low, err := parseVersion(verb, path, &toks[0], fix)
        if err != nil {
                return VersionInterval{}, err
        }
@@ -523,7 +580,7 @@ func parseVersionInterval(verb string, args *[]string, fix 
VersionFixer) (Versio
        if len(toks) == 0 {
                return VersionInterval{}, fmt.Errorf("expected version after 
','")
        }
-       high, err := parseVersion(verb, "", &toks[0], fix)
+       high, err := parseVersion(verb, path, &toks[0], fix)
        if err != nil {
                return VersionInterval{}, err
        }
@@ -631,8 +688,7 @@ func parseVersion(verb string, path string, s *string, fix 
VersionFixer) (string
                }
        }
        if fix != nil {
-               var err error
-               t, err = fix(path, t)
+               fixed, err := fix(path, t)
                if err != nil {
                        if err, ok := err.(*module.ModuleError); ok {
                                return "", &Error{
@@ -643,19 +699,23 @@ func parseVersion(verb string, path string, s *string, 
fix VersionFixer) (string
                        }
                        return "", err
                }
+               t = fixed
+       } else {
+               cv := module.CanonicalVersion(t)
+               if cv == "" {
+                       return "", &Error{
+                               Verb:    verb,
+                               ModPath: path,
+                               Err: &module.InvalidVersionError{
+                                       Version: t,
+                                       Err:     errors.New("must be of the 
form v1.2.3"),
+                               },
+                       }
+               }
+               t = cv
        }
-       if v := module.CanonicalVersion(t); v != "" {
-               *s = v
-               return *s, nil
-       }
-       return "", &Error{
-               Verb:    verb,
-               ModPath: path,
-               Err: &module.InvalidVersionError{
-                       Version: t,
-                       Err:     errors.New("must be of the form v1.2.3"),
-               },
-       }
+       *s = t
+       return *s, nil
 }
 
 func modulePathMajor(path string) (string, error) {
@@ -835,11 +895,8 @@ func (f *File) DropRequire(path string) error {
 // AddExclude adds a exclude statement to the mod file. Errors if the provided
 // version is not a canonical version string
 func (f *File) AddExclude(path, vers string) error {
-       if !isCanonicalVersion(vers) {
-               return &module.InvalidVersionError{
-                       Version: vers,
-                       Err:     errors.New("must be of the form v1.2.3"),
-               }
+       if err := checkCanonicalVersion(path, vers); err != nil {
+               return err
        }
 
        var hint *Line
@@ -916,17 +973,15 @@ func (f *File) DropReplace(oldPath, oldVers string) error 
{
 // AddRetract adds a retract statement to the mod file. Errors if the provided
 // version interval does not consist of canonical version strings
 func (f *File) AddRetract(vi VersionInterval, rationale string) error {
-       if !isCanonicalVersion(vi.High) {
-               return &module.InvalidVersionError{
-                       Version: vi.High,
-                       Err:     errors.New("must be of the form v1.2.3"),
-               }
+       var path string
+       if f.Module != nil {
+               path = f.Module.Mod.Path
        }
-       if !isCanonicalVersion(vi.Low) {
-               return &module.InvalidVersionError{
-                       Version: vi.Low,
-                       Err:     errors.New("must be of the form v1.2.3"),
-               }
+       if err := checkCanonicalVersion(path, vi.High); err != nil {
+               return err
+       }
+       if err := checkCanonicalVersion(path, vi.Low); err != nil {
+               return err
        }
 
        r := &Retract{
@@ -1086,8 +1141,40 @@ func lineRetractLess(li, lj *Line) bool {
        return semver.Compare(vii.High, vij.High) > 0
 }
 
-// isCanonicalVersion tests if the provided version string represents a valid
-// canonical version.
-func isCanonicalVersion(vers string) bool {
-       return vers != "" && semver.Canonical(vers) == vers
+// checkCanonicalVersion returns a non-nil error if vers is not a canonical
+// version string or does not match the major version of path.
+//
+// If path is non-empty, the error text suggests a format with a major version
+// corresponding to the path.
+func checkCanonicalVersion(path, vers string) error {
+       _, pathMajor, pathMajorOk := module.SplitPathVersion(path)
+
+       if vers == "" || vers != module.CanonicalVersion(vers) {
+               if pathMajor == "" {
+                       return &module.InvalidVersionError{
+                               Version: vers,
+                               Err:     fmt.Errorf("must be of the form 
v1.2.3"),
+                       }
+               }
+               return &module.InvalidVersionError{
+                       Version: vers,
+                       Err:     fmt.Errorf("must be of the form %s.2.3", 
module.PathMajorPrefix(pathMajor)),
+               }
+       }
+
+       if pathMajorOk {
+               if err := module.CheckPathMajor(vers, pathMajor); err != nil {
+                       if pathMajor == "" {
+                               // In this context, the user probably wrote 
"v2.3.4" when they meant
+                               // "v2.3.4+incompatible". Suggest that instead 
of "v0 or v1".
+                               return &module.InvalidVersionError{
+                                       Version: vers,
+                                       Err:     fmt.Errorf("should be 
%s+incompatible (or module %s/%v)", vers, path, semver.Major(vers)),
+                               }
+                       }
+                       return err
+               }
+       }
+
+       return nil
 }
diff --git a/libgo/go/golang.org/x/mod/module/module.go 
b/libgo/go/golang.org/x/mod/module/module.go
index c1c5263c427..272baeef176 100644
--- a/libgo/go/golang.org/x/mod/module/module.go
+++ b/libgo/go/golang.org/x/mod/module/module.go
@@ -270,7 +270,7 @@ func fileNameOK(r rune) bool {
 
 // CheckPath checks that a module path is valid.
 // A valid module path is a valid import path, as checked by CheckImportPath,
-// with two additional constraints.
+// with three additional constraints.
 // First, the leading path element (up to the first slash, if any),
 // by convention a domain name, must contain only lower-case ASCII letters,
 // ASCII digits, dots (U+002E), and dashes (U+002D);
@@ -280,8 +280,9 @@ func fileNameOK(r rune) bool {
 // and must not contain any dots. For paths beginning with "gopkg.in/",
 // this second requirement is replaced by a requirement that the path
 // follow the gopkg.in server's conventions.
+// Third, no path element may begin with a dot.
 func CheckPath(path string) error {
-       if err := checkPath(path, false); err != nil {
+       if err := checkPath(path, modulePath); err != nil {
                return fmt.Errorf("malformed module path %q: %v", path, err)
        }
        i := strings.Index(path, "/")
@@ -315,7 +316,7 @@ func CheckPath(path string) error {
 //
 // A valid path element is a non-empty string made up of
 // ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~.
-// It must not begin or end with a dot (U+002E), nor contain two dots in a row.
+// It must not end with a dot (U+002E), nor contain two dots in a row.
 //
 // The element prefix up to the first dot must not be a reserved file name
 // on Windows, regardless of case (CON, com1, NuL, and so on). The element
@@ -326,19 +327,29 @@ func CheckPath(path string) error {
 // top-level package documentation for additional information about
 // subtleties of Unicode.
 func CheckImportPath(path string) error {
-       if err := checkPath(path, false); err != nil {
+       if err := checkPath(path, importPath); err != nil {
                return fmt.Errorf("malformed import path %q: %v", path, err)
        }
        return nil
 }
 
+// pathKind indicates what kind of path we're checking. Module paths,
+// import paths, and file paths have different restrictions.
+type pathKind int
+
+const (
+       modulePath pathKind = iota
+       importPath
+       filePath
+)
+
 // checkPath checks that a general path is valid.
 // It returns an error describing why but not mentioning path.
 // Because these checks apply to both module paths and import paths,
 // the caller is expected to add the "malformed ___ path %q: " prefix.
 // fileName indicates whether the final element of the path is a file name
 // (as opposed to a directory name).
-func checkPath(path string, fileName bool) error {
+func checkPath(path string, kind pathKind) error {
        if !utf8.ValidString(path) {
                return fmt.Errorf("invalid UTF-8")
        }
@@ -357,35 +368,34 @@ func checkPath(path string, fileName bool) error {
        elemStart := 0
        for i, r := range path {
                if r == '/' {
-                       if err := checkElem(path[elemStart:i], fileName); err 
!= nil {
+                       if err := checkElem(path[elemStart:i], kind); err != 
nil {
                                return err
                        }
                        elemStart = i + 1
                }
        }
-       if err := checkElem(path[elemStart:], fileName); err != nil {
+       if err := checkElem(path[elemStart:], kind); err != nil {
                return err
        }
        return nil
 }
 
 // checkElem checks whether an individual path element is valid.
-// fileName indicates whether the element is a file name (not a directory 
name).
-func checkElem(elem string, fileName bool) error {
+func checkElem(elem string, kind pathKind) error {
        if elem == "" {
                return fmt.Errorf("empty path element")
        }
        if strings.Count(elem, ".") == len(elem) {
                return fmt.Errorf("invalid path element %q", elem)
        }
-       if elem[0] == '.' && !fileName {
+       if elem[0] == '.' && kind == modulePath {
                return fmt.Errorf("leading dot in path element")
        }
        if elem[len(elem)-1] == '.' {
                return fmt.Errorf("trailing dot in path element")
        }
        charOK := pathOK
-       if fileName {
+       if kind == filePath {
                charOK = fileNameOK
        }
        for _, r := range elem {
@@ -406,7 +416,7 @@ func checkElem(elem string, fileName bool) error {
                }
        }
 
-       if fileName {
+       if kind == filePath {
                // don't check for Windows short-names in file names. They're
                // only an issue for import paths.
                return nil
@@ -444,7 +454,7 @@ func checkElem(elem string, fileName bool) error {
 // top-level package documentation for additional information about
 // subtleties of Unicode.
 func CheckFilePath(path string) error {
-       if err := checkPath(path, true); err != nil {
+       if err := checkPath(path, filePath); err != nil {
                return fmt.Errorf("malformed file path %q: %v", path, err)
        }
        return nil
@@ -647,7 +657,7 @@ func EscapePath(path string) (escaped string, err error) {
 // Versions are allowed to be in non-semver form but must be valid file names
 // and not contain exclamation marks.
 func EscapeVersion(v string) (escaped string, err error) {
-       if err := checkElem(v, true); err != nil || strings.Contains(v, "!") {
+       if err := checkElem(v, filePath); err != nil || strings.Contains(v, 
"!") {
                return "", &InvalidVersionError{
                        Version: v,
                        Err:     fmt.Errorf("disallowed version string"),
@@ -706,7 +716,7 @@ func UnescapeVersion(escaped string) (v string, err error) {
        if !ok {
                return "", fmt.Errorf("invalid escaped version %q", escaped)
        }
-       if err := checkElem(v, true); err != nil {
+       if err := checkElem(v, filePath); err != nil {
                return "", fmt.Errorf("invalid escaped version %q: %v", v, err)
        }
        return v, nil
diff --git a/libgo/go/time/zoneinfo.go b/libgo/go/time/zoneinfo.go
index c3662297c7d..6db94434747 100644
--- a/libgo/go/time/zoneinfo.go
+++ b/libgo/go/time/zoneinfo.go
@@ -377,8 +377,10 @@ func tzsetOffset(s string) (offset int, rest string, ok 
bool) {
                neg = true
        }
 
+       // The tzdata code permits values up to 24 * 7 here,
+       // although POSIX does not.
        var hours int
-       hours, s, ok = tzsetNum(s, 0, 24)
+       hours, s, ok = tzsetNum(s, 0, 24*7)
        if !ok {
                return 0, "", false
        }
@@ -487,7 +489,7 @@ func tzsetRule(s string) (rule, string, bool) {
        }
 
        offset, s, ok := tzsetOffset(s[1:])
-       if !ok || offset < 0 {
+       if !ok {
                return rule{}, "", false
        }
        r.time = offset
diff --git a/libgo/go/time/zoneinfo_test.go b/libgo/go/time/zoneinfo_test.go
index d543f93e3b7..3e32da02b2e 100644
--- a/libgo/go/time/zoneinfo_test.go
+++ b/libgo/go/time/zoneinfo_test.go
@@ -189,22 +189,50 @@ func TestMalformedTZData(t *testing.T) {
        }
 }
 
-func TestLoadLocationFromTZDataSlim(t *testing.T) {
-       // A 2020b slim tzdata for Europe/Berlin
-       tzData := 
"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffo\xa2a\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xffѶ\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xffҡO\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59\xd1
 
\xff\xff\xff\xff\xd5g\xe7\x90\xff\xff\xff\xffըs\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00
 
lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\f\x88\x00\x00\x00\x00\x1c
 
\x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\rLMT\x00CEST\x00CET\x00CEMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\n"
+var slimTests = []struct {
+       zoneName   string
+       tzData     string
+       wantName   string
+       wantOffset int
+}{
+       {
+               // 2020b slim tzdata for Europe/Berlin.
+               zoneName:   "Europe/Berlin",
+               tzData:     
"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffo\xa2a\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xffѶ\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xffҡO\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59\xd1
 
\xff\xff\xff\xff\xd5g\xe7\x90\xff\xff\xff\xffըs\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00
 
lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\f\x88\x00\x00\x00\x00\x1c
 
\x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\rLMT\x00CEST\x00CET\x00CEMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\n",
+               wantName:   "CET",
+               wantOffset: 3600,
+       },
+       {
+               // 2021a slim tzdata for America/Nuuk.
+               zoneName:   "America/Nuuk",
+               tzData:     
"TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x9b\x80h\x00\x00\x00\x00\x00\x13M|P\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00
 
lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xffπ\x00\x00\xff\xff\xd5\xd0\x00\x04\xff\xff\xe3\xe0\x01\bLMT\x00-03\x00-02\x00\n<-03>3<-02>,M3.5.0/-2,M10.5.0/-1\n",
+               wantName:   "-03",
+               wantOffset: -10800,
+       },
+       {
+               // 2021a slim tzdata for Asia/Gaza.
+               zoneName:   "Asia/Gaza",
+               tzData:     
"TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff}\xbdJ\xb0\xff\xff\xff\xff\xc8Y\xcf\x00\xff\xff\xff\xff\xc8\xfa\xa6\x00\xff\xff\xff\xff\xc98\x9c\x80\xff\xff\xff\xff\xcc\xe5\xeb\x80\xff\xff\xff\xffͬ\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xffϏ\x83\x00\xff\xff\xff\xffЩ\xa4\x00\xff\xff\xff\xffф}\x00\xff\xff\xff\xffҊ׀\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\v\x00\xff\xff\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec\xfa\xf0\xff\xff\xff\xff\xec\xb5m\x00\xff\xff\xff\xff\xed\xcf\u007f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xffﰳp\xff\xff\xff\xff\xf0y%\x80\xff\xff\xff\xff\xf1\x91\xe6\xf0\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3s\x1ap\xff\xff\xff\xff\xf4;\x8c\x80\xff\xff\xff\xff\xf5U\x9fp\xff\xff\xff\xff\xf6\x1e\x11\x80\xff\xff\xff\xff\xf76\xd2\xf0\xff\xff\xff\xff\xf7\xffE\x00\xff\xff\xff\xff\xf9\x18\x06p\xff\xff\xff\xff\xf9\xe1\xca\x00\xff\xff\xff\xff\xfa\xf99\xf0\xff\xff\xff\xff\xfb'BP\x00\x00\x00\x00\b|\x8b\xe0\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe9\xfc`\x00\x00\x00\x00\x14![`\x00\x00\x00\x00\x1a\xfa\xc6`\x00\x00\x00\x00\x1b\x8en`\x00\x00\x00\x00\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1dw|\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00
 
\x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00\x00\"^\x9e\xe0\x00\x00\x00\x00# 
]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03P\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xa9\x1f\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00\x000H\xc5\xd0\x00\x00\x00\x000\xe7\a\xe0\x00\x00\x00\x001dF`\x00\x00\x00\x002A\xc2`\x00\x00\x00\x003D(`\x00\x00\x00\x004!\xa4`\x00\x00\x00\x005$\n`\x00\x00\x00\x006\x01\x86`\x00\x00\x00\x007\x16a`\x00\x00\x00\x008\x06DP\x00\x00\x00\x008\xff}\xe0\x00\x00\x00\x009\xef`\xd0\x00\x00\x00\x00:\xdf_\xe0\x00\x00\x00\x00;\xcfB\xd0\x00\x00\x00\x00<\xbfA\xe0\x00\x00\x00\x00=\xaf$\xd0\x00\x00\x00\x00>\x9f#\xe0\x00\x00\x00\x00?\x8f\x06\xd0\x00\x00\x00\x00@\u007f\x05\xe0\x00\x00\x00\x00A\\\x81\xe0\x00\x00\x00\x00B^\xe7\xe0\x00\x00\x00\x00CA\xb7\xf0\x00\x00\x00\x00D-\xa6`\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F\x0e\xd9\xe0\x00\x00\x00\x00F\xe8op\x00\x00\x00\x00G\xec\x18\xe0\x00\x00\x00\x00H\xb7\x11\xd0\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xa0<`\x00\x00\x00\x00K\xad.\x9c\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00M\x94\xf9\x9c\x00\x00\x00\x00N5\xc2P\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00P[\x91\xe0\x00\x00\x00\x00QT\xbd`\x00\x00\x00\x00RD\xa0P\x00\x00\x00\x00S4\x9f`\x00\x00\x00\x00TIlP\x00\x00\x00\x00U\x15\xd2\xe0\x00\x00\x00\x00V)\\`\x00\x00\x00\x00V\xf5\xc2\xf0\x00\x00\x00\x00X\x13\xca`\x00\x00\x00\x00Xդ\xf0\x00\x00\x00\x00Y\xf3\xac`\x00\x00\x00\x00Z\xb5\x86\xf0\x00\x00\x00\x00[ӎ`\x00\x00\x00\x00\\\x9dC\xe0\x00\x00\x00\x00]\xb3bP\x00\x00\x00\x00^~w`\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00
 P\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x01\r\x00\x00\x1c 
\x00\x11LMT\x00EEST\x00EET\x00IDT\x00IST\x00\nEET-2EEST,M3.4.4/48,M10.4.4/49\n",
+               wantName:   "EET",
+               wantOffset: 7200,
+       },
+}
 
-       reference, err := time.LoadLocationFromTZData("Europe/Berlin", 
[]byte(tzData))
-       if err != nil {
-               t.Fatal(err)
-       }
+func TestLoadLocationFromTZDataSlim(t *testing.T) {
+       for _, test := range slimTests {
+               reference, err := time.LoadLocationFromTZData(test.zoneName, 
[]byte(test.tzData))
+               if err != nil {
+                       t.Fatal(err)
+               }
 
-       d := time.Date(2020, time.October, 29, 15, 30, 0, 0, reference)
-       tzName, tzOffset := d.Zone()
-       if want := "CET"; tzName != want {
-               t.Errorf("Zone name == %s, want %s", tzName, want)
-       }
-       if want := 3600; tzOffset != want {
-               t.Errorf("Zone offset == %d, want %d", tzOffset, want)
+               d := time.Date(2020, time.October, 29, 15, 30, 0, 0, reference)
+               tzName, tzOffset := d.Zone()
+               if tzName != test.wantName {
+                       t.Errorf("Zone name == %s, want %s", tzName, 
test.wantName)
+               }
+               if tzOffset != test.wantOffset {
+                       t.Errorf("Zone offset == %d, want %d", tzOffset, 
test.wantOffset)
+               }
        }
 }
 
@@ -269,7 +297,8 @@ func TestTzsetOffset(t *testing.T) {
                {"+08", 8 * 60 * 60, "", true},
                {"-01:02:03", -1*60*60 - 2*60 - 3, "", true},
                {"01", 1 * 60 * 60, "", true},
-               {"100", 0, "", false},
+               {"100", 100 * 60 * 60, "", true},
+               {"1000", 0, "", false},
                {"8PDT", 8 * 60 * 60, "PDT", true},
        } {
                off, out, ok := time.TzsetOffset(test.in)
@@ -294,6 +323,7 @@ func TestTzsetRule(t *testing.T) {
                {"30/03:00:00", time.Rule{Kind: time.RuleDOY, Day: 30, Time: 3 
* 60 * 60}, "", true},
                {"M4.5.6/03:00:00", time.Rule{Kind: time.RuleMonthWeekDay, Mon: 
4, Week: 5, Day: 6, Time: 3 * 60 * 60}, "", true},
                {"M4.5.7/03:00:00", time.Rule{}, "", false},
+               {"M4.5.6/-04", time.Rule{Kind: time.RuleMonthWeekDay, Mon: 4, 
Week: 5, Day: 6, Time: -4 * 60 * 60}, "", true},
        } {
                r, out, ok := time.TzsetRule(test.in)
                if r != test.r || out != test.out || ok != test.ok {
diff --git a/libgo/misc/cgo/testplugin/plugin_test.go 
b/libgo/misc/cgo/testplugin/plugin_test.go
index 9055dbda044..2d991012c82 100644
--- a/libgo/misc/cgo/testplugin/plugin_test.go
+++ b/libgo/misc/cgo/testplugin/plugin_test.go
@@ -201,12 +201,11 @@ func TestMethod(t *testing.T) {
        // Exported symbol's method must be live.
        goCmd(t, "build", "-buildmode=plugin", "-o", "plugin.so", 
"./method/plugin.go")
        goCmd(t, "build", "-o", "method.exe", "./method/main.go")
+       run(t, "./method.exe")
+}
 
-       ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-       defer cancel()
-       cmd := exec.CommandContext(ctx, "./method.exe")
-       out, err := cmd.CombinedOutput()
-       if err != nil {
-               t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, out)
-       }
+func TestMethod2(t *testing.T) {
+       goCmd(t, "build", "-buildmode=plugin", "-o", "method2.so", 
"./method2/plugin.go")
+       goCmd(t, "build", "-o", "method2.exe", "./method2/main.go")
+       run(t, "./method2.exe")
 }
diff --git a/libgo/misc/cgo/testplugin/testdata/method2/main.go 
b/libgo/misc/cgo/testplugin/testdata/method2/main.go
new file mode 100644
index 00000000000..6a87e7b6a0f
--- /dev/null
+++ b/libgo/misc/cgo/testplugin/testdata/method2/main.go
@@ -0,0 +1,32 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// A type can be passed to a plugin and converted to interface
+// there. So its methods need to be live.
+
+package main
+
+import (
+       "plugin"
+
+       "testplugin/method2/p"
+)
+
+var t p.T
+
+type I interface { M() }
+
+func main() {
+       pl, err := plugin.Open("method2.so")
+       if err != nil {
+               panic(err)
+       }
+
+       f, err := pl.Lookup("F")
+       if err != nil {
+               panic(err)
+       }
+
+       f.(func(p.T) interface{})(t).(I).M()
+}
diff --git a/libgo/misc/cgo/testplugin/testdata/method2/p/p.go 
b/libgo/misc/cgo/testplugin/testdata/method2/p/p.go
new file mode 100644
index 00000000000..acb526acec9
--- /dev/null
+++ b/libgo/misc/cgo/testplugin/testdata/method2/p/p.go
@@ -0,0 +1,9 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T int
+
+func (T) M() { println("M") }
diff --git a/libgo/misc/cgo/testplugin/testdata/method2/plugin.go 
b/libgo/misc/cgo/testplugin/testdata/method2/plugin.go
new file mode 100644
index 00000000000..6198e7648ee
--- /dev/null
+++ b/libgo/misc/cgo/testplugin/testdata/method2/plugin.go
@@ -0,0 +1,11 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "testplugin/method2/p"
+
+func main() {}
+
+func F(t p.T) interface{} { return t }

Reply via email to