From c96833e5badedb025761de6a74ed5f9c848059de Mon Sep 17 00:00:00 2001 From: Michael Anthony Knyszek Date: Wed, 7 Jul 2021 14:58:36 +0000 Subject: [PATCH 01/49] doc: remove stale comment about arm64 port Fixes #47079. Change-Id: I8a671e3fdc13083e44e8d89064a5e7621e53bc4c Reviewed-on: https://go-review.googlesource.com/c/go/+/333075 Trust: Michael Knyszek Reviewed-by: Keith Randall Run-TryBot: Michael Knyszek TryBot-Result: Go Bot --- doc/asm.html | 4 ---- 1 file changed, 4 deletions(-) diff --git a/doc/asm.html b/doc/asm.html index 7173d9bd51..d578800086 100644 --- a/doc/asm.html +++ b/doc/asm.html @@ -827,10 +827,6 @@ The other codes are -> (arithmetic right shift),

ARM64

-

-The ARM64 port is in an experimental state. -

-

R18 is the "platform register", reserved on the Apple platform. To prevent accidental misuse, the register is named R18_PLATFORM. From f264879f74efc8b9a9bcf4e04df0f8f5affa11a9 Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Fri, 2 Jul 2021 14:00:49 -0400 Subject: [PATCH 02/49] cmd/go/internal/modload: fix an apparent typo in the AutoRoot comment Updates #40276 Change-Id: Ic192d51f9f0306e5c206c550ef02f6d4495d0851 Reviewed-on: https://go-review.googlesource.com/c/go/+/332569 Trust: Bryan C. Mills Reviewed-by: Jay Conrod --- src/cmd/go/internal/modload/init.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go index cbc7289afa..09136b7de1 100644 --- a/src/cmd/go/internal/modload/init.go +++ b/src/cmd/go/internal/modload/init.go @@ -71,7 +71,7 @@ type Root int const ( // AutoRoot is the default for most commands. modload.Init will look for // a go.mod file in the current directory or any parent. If none is found, - // modules may be disabled (GO111MODULE=on) or commands may run in a + // modules may be disabled (GO111MODULE=auto) or commands may run in a // limited module mode. AutoRoot Root = iota From 00c00558e1513d4f110f0b778242c965e7f6505a Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Fri, 2 Jul 2021 11:27:37 -0400 Subject: [PATCH 03/49] cmd/go/internal/modload: remove unused functions Also unexport functions that are not used outside the modload package. Change-Id: I0de187cbb673cadafce95a27f5ccff934ae21104 Reviewed-on: https://go-review.googlesource.com/c/go/+/332570 Trust: Bryan C. Mills Reviewed-by: Jay Conrod --- src/cmd/go/internal/modload/load.go | 37 ---------------------------- src/cmd/go/internal/modload/query.go | 4 +-- 2 files changed, 2 insertions(+), 39 deletions(-) diff --git a/src/cmd/go/internal/modload/load.go b/src/cmd/go/internal/modload/load.go index a3a8021c04..771b142b73 100644 --- a/src/cmd/go/internal/modload/load.go +++ b/src/cmd/go/internal/modload/load.go @@ -675,20 +675,6 @@ func DirImportPath(ctx context.Context, dir string) string { return "." } -// TargetPackages returns the list of packages in the target (top-level) module -// matching pattern, which may be relative to the working directory, under all -// build tag settings. -func TargetPackages(ctx context.Context, pattern string) *search.Match { - // TargetPackages is relative to the main module, so ensure that the main - // module is a thing that can contain packages. - LoadModFile(ctx) // Sets Target. - ModRoot() // Emits an error if Target cannot contain packages. - - m := search.NewMatch(pattern) - matchPackages(ctx, m, imports.AnyTags(), omitStd, []module.Version{Target}) - return m -} - // ImportMap returns the actual package import path // for an import path found in source code. // If the given import path does not appear in the source code @@ -720,29 +706,6 @@ func PackageModule(path string) module.Version { return pkg.mod } -// PackageImports returns the imports for the package named by the import path. -// Test imports will be returned as well if tests were loaded for the package -// (i.e., if "all" was loaded or if LoadTests was set and the path was matched -// by a command line argument). PackageImports will return nil for -// unknown package paths. -func PackageImports(path string) (imports, testImports []string) { - pkg, ok := loaded.pkgCache.Get(path).(*loadPkg) - if !ok { - return nil, nil - } - imports = make([]string, len(pkg.imports)) - for i, p := range pkg.imports { - imports[i] = p.path - } - if pkg.test != nil { - testImports = make([]string, len(pkg.test.imports)) - for i, p := range pkg.test.imports { - testImports[i] = p.path - } - } - return imports, testImports -} - // Lookup returns the source directory, import path, and any loading error for // the package at path as imported from the package in parentDir. // Lookup requires that one of the Load functions in this package has already diff --git a/src/cmd/go/internal/modload/query.go b/src/cmd/go/internal/modload/query.go index 6f6c6e8c98..dda9004a9f 100644 --- a/src/cmd/go/internal/modload/query.go +++ b/src/cmd/go/internal/modload/query.go @@ -920,8 +920,8 @@ func (e *PackageNotInModuleError) ImportPath() string { return "" } -// ModuleHasRootPackage returns whether module m contains a package m.Path. -func ModuleHasRootPackage(ctx context.Context, m module.Version) (bool, error) { +// moduleHasRootPackage returns whether module m contains a package m.Path. +func moduleHasRootPackage(ctx context.Context, m module.Version) (bool, error) { needSum := false root, isLocal, err := fetch(ctx, m, needSum) if err != nil { From 186a3bb4b0939837c855a4f0689d4a4401aff608 Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Fri, 25 Jun 2021 12:49:51 -0400 Subject: [PATCH 04/49] cmd/go/internal/modfetch/codehost: skip hg tests if no hg binary is present Change-Id: I5cf57bf1153eb662bcab71e3d2c04848212559a6 Reviewed-on: https://go-review.googlesource.com/c/go/+/330989 Trust: Bryan C. Mills Run-TryBot: Bryan C. Mills TryBot-Result: Go Bot Reviewed-by: Jay Conrod --- .../go/internal/modfetch/codehost/git_test.go | 49 +++++++++---------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/src/cmd/go/internal/modfetch/codehost/git_test.go b/src/cmd/go/internal/modfetch/codehost/git_test.go index 89a73baad9..a684fa1a9b 100644 --- a/src/cmd/go/internal/modfetch/codehost/git_test.go +++ b/src/cmd/go/internal/modfetch/codehost/git_test.go @@ -8,7 +8,6 @@ import ( "archive/zip" "bytes" "flag" - "fmt" "internal/testenv" "io" "io/fs" @@ -47,12 +46,6 @@ var altRepos = []string{ var localGitRepo string func testMain(m *testing.M) int { - if _, err := exec.LookPath("git"); err != nil { - fmt.Fprintln(os.Stderr, "skipping because git binary not found") - fmt.Println("PASS") - return 0 - } - dir, err := os.MkdirTemp("", "gitrepo-test-") if err != nil { log.Fatal(err) @@ -60,23 +53,25 @@ func testMain(m *testing.M) int { defer os.RemoveAll(dir) if testenv.HasExternalNetwork() && testenv.HasExec() { - // Clone gitrepo1 into a local directory. - // If we use a file:// URL to access the local directory, - // then git starts up all the usual protocol machinery, - // which will let us test remote git archive invocations. - localGitRepo = filepath.Join(dir, "gitrepo2") - if _, err := Run("", "git", "clone", "--mirror", gitrepo1, localGitRepo); err != nil { - log.Fatal(err) - } - if _, err := Run(localGitRepo, "git", "config", "daemon.uploadarch", "true"); err != nil { - log.Fatal(err) + if _, err := exec.LookPath("git"); err == nil { + // Clone gitrepo1 into a local directory. + // If we use a file:// URL to access the local directory, + // then git starts up all the usual protocol machinery, + // which will let us test remote git archive invocations. + localGitRepo = filepath.Join(dir, "gitrepo2") + if _, err := Run("", "git", "clone", "--mirror", gitrepo1, localGitRepo); err != nil { + log.Fatal(err) + } + if _, err := Run(localGitRepo, "git", "config", "daemon.uploadarch", "true"); err != nil { + log.Fatal(err) + } } } return m.Run() } -func testRepo(remote string) (Repo, error) { +func testRepo(t *testing.T, remote string) (Repo, error) { if remote == "localGitRepo" { // Convert absolute path to file URL. LocalGitRepo will not accept // Windows absolute paths because they look like a host:path remote. @@ -87,15 +82,17 @@ func testRepo(remote string) (Repo, error) { } else { url = "file:///" + filepath.ToSlash(localGitRepo) } + testenv.MustHaveExecPath(t, "git") return LocalGitRepo(url) } - kind := "git" + vcs := "git" for _, k := range []string{"hg"} { if strings.Contains(remote, "/"+k+"/") { - kind = k + vcs = k } } - return NewRepo(kind, remote) + testenv.MustHaveExecPath(t, vcs) + return NewRepo(vcs, remote) } var tagsTests = []struct { @@ -116,7 +113,7 @@ func TestTags(t *testing.T) { for _, tt := range tagsTests { f := func(t *testing.T) { - r, err := testRepo(tt.repo) + r, err := testRepo(t, tt.repo) if err != nil { t.Fatal(err) } @@ -168,7 +165,7 @@ func TestLatest(t *testing.T) { for _, tt := range latestTests { f := func(t *testing.T) { - r, err := testRepo(tt.repo) + r, err := testRepo(t, tt.repo) if err != nil { t.Fatal(err) } @@ -221,7 +218,7 @@ func TestReadFile(t *testing.T) { for _, tt := range readFileTests { f := func(t *testing.T) { - r, err := testRepo(tt.repo) + r, err := testRepo(t, tt.repo) if err != nil { t.Fatal(err) } @@ -412,7 +409,7 @@ func TestReadZip(t *testing.T) { for _, tt := range readZipTests { f := func(t *testing.T) { - r, err := testRepo(tt.repo) + r, err := testRepo(t, tt.repo) if err != nil { t.Fatal(err) } @@ -581,7 +578,7 @@ func TestStat(t *testing.T) { for _, tt := range statTests { f := func(t *testing.T) { - r, err := testRepo(tt.repo) + r, err := testRepo(t, tt.repo) if err != nil { t.Fatal(err) } From 991fd381d52e7cec37ab54732613d3e465916206 Mon Sep 17 00:00:00 2001 From: Jay Conrod Date: Tue, 6 Jul 2021 10:38:18 -0700 Subject: [PATCH 05/49] cmd/go: don't lock .mod and .sum files for read in overlay On Plan 9, locking a file requires a chmod call. In general, the go command should not modify files in the overlay, even metadata. With this change, we won't lock these files for reading. The go command already reported errors when attempting to write these files if they were in the overlay, but this change moves those checks to the point of access for clearer error messages. cmd/go/internal/lockedfile no longer imports cmd/go/internal/fsys. Fixes #44700 Change-Id: Ib544459dd6cf56ca0f7a27b3285f045f08040d7e Reviewed-on: https://go-review.googlesource.com/c/go/+/333012 Trust: Jay Conrod Run-TryBot: Jay Conrod TryBot-Result: Go Bot Reviewed-by: Bryan C. Mills --- .../internal/lockedfile/lockedfile_filelock.go | 3 +-- .../go/internal/lockedfile/lockedfile_plan9.go | 6 ++---- src/cmd/go/internal/modfetch/fetch.go | 17 ++++++++++++++++- src/cmd/go/internal/modload/init.go | 18 +++++++++++++++++- src/cmd/go/internal/modload/modfile.go | 14 ++++++++++++-- src/cmd/go/testdata/script/mod_overlay.txt | 10 +++++----- 6 files changed, 53 insertions(+), 15 deletions(-) diff --git a/src/cmd/go/internal/lockedfile/lockedfile_filelock.go b/src/cmd/go/internal/lockedfile/lockedfile_filelock.go index 729df5c681..e4923f6876 100644 --- a/src/cmd/go/internal/lockedfile/lockedfile_filelock.go +++ b/src/cmd/go/internal/lockedfile/lockedfile_filelock.go @@ -11,7 +11,6 @@ import ( "io/fs" "os" - "cmd/go/internal/fsys" "cmd/go/internal/lockedfile/internal/filelock" ) @@ -21,7 +20,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) { // calls for Linux and Windows anyway, so it's simpler to use that approach // consistently. - f, err := fsys.OpenFile(name, flag&^os.O_TRUNC, perm) + f, err := os.OpenFile(name, flag&^os.O_TRUNC, perm) if err != nil { return nil, err } diff --git a/src/cmd/go/internal/lockedfile/lockedfile_plan9.go b/src/cmd/go/internal/lockedfile/lockedfile_plan9.go index 3d4b97d78e..979118b10a 100644 --- a/src/cmd/go/internal/lockedfile/lockedfile_plan9.go +++ b/src/cmd/go/internal/lockedfile/lockedfile_plan9.go @@ -13,8 +13,6 @@ import ( "os" "strings" "time" - - "cmd/go/internal/fsys" ) // Opening an exclusive-use file returns an error. @@ -59,7 +57,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) { // If the file was unpacked or created by some other program, it might not // have the ModeExclusive bit set. Set it before we call OpenFile, so that we // can be confident that a successful OpenFile implies exclusive use. - if fi, err := fsys.Stat(name); err == nil { + if fi, err := os.Stat(name); err == nil { if fi.Mode()&fs.ModeExclusive == 0 { if err := os.Chmod(name, fi.Mode()|fs.ModeExclusive); err != nil { return nil, err @@ -72,7 +70,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) { nextSleep := 1 * time.Millisecond const maxSleep = 500 * time.Millisecond for { - f, err := fsys.OpenFile(name, flag, perm|fs.ModeExclusive) + f, err := os.OpenFile(name, flag, perm|fs.ModeExclusive) if err == nil { return f, nil } diff --git a/src/cmd/go/internal/modfetch/fetch.go b/src/cmd/go/internal/modfetch/fetch.go index e40593abae..d3d30d970b 100644 --- a/src/cmd/go/internal/modfetch/fetch.go +++ b/src/cmd/go/internal/modfetch/fetch.go @@ -22,6 +22,7 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/lockedfile" "cmd/go/internal/par" "cmd/go/internal/robustio" @@ -416,7 +417,18 @@ func initGoSum() (bool, error) { goSum.m = make(map[module.Version][]string) goSum.status = make(map[modSum]modSumStatus) - data, err := lockedfile.Read(GoSumFile) + var ( + data []byte + err error + ) + if actualSumFile, ok := fsys.OverlayPath(GoSumFile); ok { + // Don't lock go.sum if it's part of the overlay. + // On Plan 9, locking requires chmod, and we don't want to modify any file + // in the overlay. See #44700. + data, err = os.ReadFile(actualSumFile) + } else { + data, err = lockedfile.Read(GoSumFile) + } if err != nil && !os.IsNotExist(err) { return false, err } @@ -716,6 +728,9 @@ Outer: if cfg.BuildMod == "readonly" { base.Fatalf("go: updates to go.sum needed, disabled by -mod=readonly") } + if _, ok := fsys.OverlayPath(GoSumFile); ok { + base.Fatalf("go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay") + } // Make a best-effort attempt to acquire the side lock, only to exclude // previous versions of the 'go' command from making simultaneous edits. diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go index 09136b7de1..a8cbd9fe16 100644 --- a/src/cmd/go/internal/modload/init.go +++ b/src/cmd/go/internal/modload/init.go @@ -412,7 +412,16 @@ func loadModFile(ctx context.Context) (rs *Requirements, needCommit bool) { } gomod := ModFilePath() - data, err := lockedfile.Read(gomod) + var data []byte + var err error + if gomodActual, ok := fsys.OverlayPath(gomod); ok { + // Don't lock go.mod if it's part of the overlay. + // On Plan 9, locking requires chmod, and we don't want to modify any file + // in the overlay. See #44700. + data, err = os.ReadFile(gomodActual) + } else { + data, err = lockedfile.Read(gomodActual) + } if err != nil { base.Fatalf("go: %v", err) } @@ -1026,6 +1035,13 @@ func commitRequirements(ctx context.Context, goVersion string, rs *Requirements) } return } + gomod := ModFilePath() + if _, ok := fsys.OverlayPath(gomod); ok { + if dirty { + base.Fatalf("go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay") + } + return + } new, err := modFile.Format() if err != nil { diff --git a/src/cmd/go/internal/modload/modfile.go b/src/cmd/go/internal/modload/modfile.go index 1145ac4ba5..d280945ea6 100644 --- a/src/cmd/go/internal/modload/modfile.go +++ b/src/cmd/go/internal/modload/modfile.go @@ -8,6 +8,7 @@ import ( "context" "errors" "fmt" + "os" "path/filepath" "strings" "sync" @@ -15,6 +16,7 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/lockedfile" "cmd/go/internal/modfetch" "cmd/go/internal/par" @@ -601,8 +603,16 @@ func rawGoModSummary(m module.Version) (*modFileSummary, error) { dir = filepath.Join(ModRoot(), dir) } gomod := filepath.Join(dir, "go.mod") - - data, err := lockedfile.Read(gomod) + var data []byte + var err error + if gomodActual, ok := fsys.OverlayPath(gomod); ok { + // Don't lock go.mod if it's part of the overlay. + // On Plan 9, locking requires chmod, and we don't want to modify any file + // in the overlay. See #44700. + data, err = os.ReadFile(gomodActual) + } else { + data, err = lockedfile.Read(gomodActual) + } if err != nil { return cached{nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(gomod), err))} } diff --git a/src/cmd/go/testdata/script/mod_overlay.txt b/src/cmd/go/testdata/script/mod_overlay.txt index 92e79c725a..86ab04bd3c 100644 --- a/src/cmd/go/testdata/script/mod_overlay.txt +++ b/src/cmd/go/testdata/script/mod_overlay.txt @@ -21,7 +21,7 @@ go list -deps -overlay overlay.json . cd $WORK/gopath/src/get-doesnt-add-dep cp $WORK/overlay/get_doesnt_add_dep_go_mod $WORK/want_go_mod ! go get -d -overlay overlay.json . -stderr 'overlaid files can''t be opened for write' +stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$' cmp $WORK/overlay/get_doesnt_add_dep_go_mod $WORK/want_go_mod # Content of overlaid go.sum is used. @@ -41,10 +41,10 @@ go mod verify -overlay overlay.json # attempting to update the file cp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums ! go get -d -overlay overlay.json . -stderr 'overlaid files can''t be opened for write' +stderr '^go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay$' cmp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums ! go mod tidy -overlay overlay.json -stderr 'overlaid files can''t be opened for write' +stderr '^go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay$' cmp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums # -overlay works with -modfile. @@ -56,7 +56,7 @@ go list -modfile=alternate.mod -overlay overlay.json . stdout 'found.the/module' # Even with -modfile, overlaid files can't be opened for write. ! go get -modfile=alternate.mod -overlay overlay.json -d rsc.io/quote -stderr 'overlaid files can''t be opened for write' +stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$' # Carving out a module by adding an overlaid go.mod file cd $WORK/gopath/src/carve @@ -78,7 +78,7 @@ go list -overlay overlay.json all stdout ^carve2/nomod$ # Editing go.mod file fails because overlay is read only ! go get -overlay overlay.json -d rsc.io/quote -stderr 'overlaid files can''t be opened for write' +stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$' ! grep rsc.io/quote $WORK/overlay/carve2-nomod-go.mod # Editing go.mod file succeeds because we use -modfile to redirect to same file go get -overlay overlay.json -modfile $WORK/overlay/carve2-nomod-go.mod -d rsc.io/quote From 11f5df2d6703b3fbd61a256e4e32ba67d835e7ad Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Wed, 7 Jul 2021 12:11:37 -0700 Subject: [PATCH 06/49] cmd/compile: extract pkgqual from symfmt The logic in symfmt for deciding how to package-qualify an identifier is easily refactored into a separate function, loosely similar to go/types.Qualifier's API. Passes toolstash -cmp. Updates #47087. Change-Id: Ib3e7cc35a6577dc28df8eca79ba3457c48168e86 Reviewed-on: https://go-review.googlesource.com/c/go/+/333161 Trust: Matthew Dempsky Run-TryBot: Matthew Dempsky TryBot-Result: Go Bot Reviewed-by: Robert Griesemer --- src/cmd/compile/internal/types/fmt.go | 43 +++++++++++++-------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/cmd/compile/internal/types/fmt.go b/src/cmd/compile/internal/types/fmt.go index b538ea8054..0ce423dae7 100644 --- a/src/cmd/compile/internal/types/fmt.go +++ b/src/cmd/compile/internal/types/fmt.go @@ -137,47 +137,44 @@ func sconv2(b *bytes.Buffer, s *Sym, verb rune, mode fmtMode) { } func symfmt(b *bytes.Buffer, s *Sym, verb rune, mode fmtMode) { + if q := pkgqual(s.Pkg, verb, mode); q != "" { + b.WriteString(q) + b.WriteByte('.') + } + b.WriteString(s.Name) +} + +// pkgqual returns the qualifier that should be used for printing +// symbols from the given package in the given mode. +// If it returns the empty string, no qualification is needed. +func pkgqual(pkg *Pkg, verb rune, mode fmtMode) string { if verb != 'S' { switch mode { case fmtGo: // This is for the user - if s.Pkg == BuiltinPkg || s.Pkg == LocalPkg { - b.WriteString(s.Name) - return + if pkg == BuiltinPkg || pkg == LocalPkg { + return "" } // If the name was used by multiple packages, display the full path, - if s.Pkg.Name != "" && NumImport[s.Pkg.Name] > 1 { - fmt.Fprintf(b, "%q.%s", s.Pkg.Path, s.Name) - return + if pkg.Name != "" && NumImport[pkg.Name] > 1 { + return strconv.Quote(pkg.Path) } - b.WriteString(s.Pkg.Name) - b.WriteByte('.') - b.WriteString(s.Name) - return + return pkg.Name case fmtDebug: - b.WriteString(s.Pkg.Name) - b.WriteByte('.') - b.WriteString(s.Name) - return + return pkg.Name case fmtTypeIDName: // dcommontype, typehash - b.WriteString(s.Pkg.Name) - b.WriteByte('.') - b.WriteString(s.Name) - return + return pkg.Name case fmtTypeID: // (methodsym), typesym, weaksym - b.WriteString(s.Pkg.Prefix) - b.WriteByte('.') - b.WriteString(s.Name) - return + return pkg.Prefix } } - b.WriteString(s.Name) + return "" } // Type From b003a8b1ae26fa684ec35eb7543efa1ded1bcae7 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Wed, 7 Jul 2021 12:33:40 -0700 Subject: [PATCH 07/49] cmd/compile: optimize types.sconv Now that symfmt is simpler, we can simply manually inline it into sconv. Importantly, this allows us to avoid allocating a buffer + writing a string + re-interning it when we don't need to qualify the identifier. Passes toolstash -cmp. Updates #47087. Change-Id: I47b57aef22301ba242556a645346f478f0c1a7d1 Reviewed-on: https://go-review.googlesource.com/c/go/+/333162 Trust: Matthew Dempsky Run-TryBot: Matthew Dempsky TryBot-Result: Go Bot Reviewed-by: Robert Griesemer --- src/cmd/compile/internal/types/fmt.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/cmd/compile/internal/types/fmt.go b/src/cmd/compile/internal/types/fmt.go index 0ce423dae7..7b284aa661 100644 --- a/src/cmd/compile/internal/types/fmt.go +++ b/src/cmd/compile/internal/types/fmt.go @@ -112,11 +112,19 @@ func sconv(s *Sym, verb rune, mode fmtMode) string { if s.Name == "_" { return "_" } + + q := pkgqual(s.Pkg, verb, mode) + if q == "" { + return s.Name + } + buf := fmtBufferPool.Get().(*bytes.Buffer) buf.Reset() defer fmtBufferPool.Put(buf) - symfmt(buf, s, verb, mode) + buf.WriteString(q) + buf.WriteByte('.') + buf.WriteString(s.Name) return InternString(buf.Bytes()) } From 5c59e11f5e1fe2e6d5b684f9a348022c07807126 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Wed, 7 Jul 2021 13:18:42 -0700 Subject: [PATCH 08/49] cmd/compile: remove special-casing of blank in types.sconv{,2} I'm not sure why blank was special-cased here before, but it's wrong. Blank is a non-exported identifier, and writing it out without package-qualification can result in linker symbol collisions. Fixes #47087. Change-Id: Ie600037c8e54e3d4fdaeec21e2ca212badbd830b Reviewed-on: https://go-review.googlesource.com/c/go/+/333163 Trust: Matthew Dempsky Run-TryBot: Matthew Dempsky TryBot-Result: Go Bot Reviewed-by: Robert Griesemer --- src/cmd/compile/internal/types/fmt.go | 8 -------- test/fixedbugs/issue47087.dir/a.go | 9 +++++++++ test/fixedbugs/issue47087.dir/b.go | 9 +++++++++ test/fixedbugs/issue47087.dir/main.go | 19 +++++++++++++++++++ test/fixedbugs/issue47087.go | 7 +++++++ 5 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 test/fixedbugs/issue47087.dir/a.go create mode 100644 test/fixedbugs/issue47087.dir/b.go create mode 100644 test/fixedbugs/issue47087.dir/main.go create mode 100644 test/fixedbugs/issue47087.go diff --git a/src/cmd/compile/internal/types/fmt.go b/src/cmd/compile/internal/types/fmt.go index 7b284aa661..8b988952a7 100644 --- a/src/cmd/compile/internal/types/fmt.go +++ b/src/cmd/compile/internal/types/fmt.go @@ -109,10 +109,6 @@ func sconv(s *Sym, verb rune, mode fmtMode) string { return "" } - if s.Name == "_" { - return "_" - } - q := pkgqual(s.Pkg, verb, mode) if q == "" { return s.Name @@ -136,10 +132,6 @@ func sconv2(b *bytes.Buffer, s *Sym, verb rune, mode fmtMode) { b.WriteString("") return } - if s.Name == "_" { - b.WriteString("_") - return - } symfmt(b, s, verb, mode) } diff --git a/test/fixedbugs/issue47087.dir/a.go b/test/fixedbugs/issue47087.dir/a.go new file mode 100644 index 0000000000..6093092ace --- /dev/null +++ b/test/fixedbugs/issue47087.dir/a.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 a + +func F() interface{} { return struct{ _ []int }{} } + +var X = F() diff --git a/test/fixedbugs/issue47087.dir/b.go b/test/fixedbugs/issue47087.dir/b.go new file mode 100644 index 0000000000..8f96d25a12 --- /dev/null +++ b/test/fixedbugs/issue47087.dir/b.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 b + +func F() interface{} { return struct{ _ []int }{} } + +var X = F() diff --git a/test/fixedbugs/issue47087.dir/main.go b/test/fixedbugs/issue47087.dir/main.go new file mode 100644 index 0000000000..ccd0891a61 --- /dev/null +++ b/test/fixedbugs/issue47087.dir/main.go @@ -0,0 +1,19 @@ +// 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 ( + "a" + "b" +) + +func main() { + if a.F() == b.F() { + panic("FAIL") + } + if a.X == b.X { + panic("FAIL") + } +} diff --git a/test/fixedbugs/issue47087.go b/test/fixedbugs/issue47087.go new file mode 100644 index 0000000000..40df49f83b --- /dev/null +++ b/test/fixedbugs/issue47087.go @@ -0,0 +1,7 @@ +// rundir + +// 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 ignored From 2ca44fe2213b53ccaf6f555c11858c6e36490624 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 5 Jul 2021 10:35:53 +0200 Subject: [PATCH 09/49] doc/go1.17: linkify time.UnixMilli and time.UnixMicro Change-Id: I8503c4649fc42670f13d981f98af480467d6a3e8 Reviewed-on: https://go-review.googlesource.com/c/go/+/332829 Trust: Tobias Klauser Reviewed-by: Dmitri Shuralyov --- doc/go1.17.html | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/go1.17.html b/doc/go1.17.html index 66b4f48b61..4fa30158bb 100644 --- a/doc/go1.17.html +++ b/doc/go1.17.html @@ -1132,10 +1132,13 @@ func Foo() bool {

The new Time.UnixMilli and - Time.UnixMicro methods return the number of milliseconds and - microseconds elapsed since January 1, 1970 UTC respectively.
- The new UnixMilli and UnixMicro functions return local Time corresponding to given - Unix time. + Time.UnixMicro + methods return the number of milliseconds and microseconds elapsed since + January 1, 1970 UTC respectively. +
+ The new UnixMilli and + UnixMicro functions + return the local Time corresponding to the given Unix time.

From ce76298ee7b2cc237b015f798abbfe891a6f5463 Mon Sep 17 00:00:00 2001 From: makdon Date: Mon, 17 May 2021 16:27:11 +0000 Subject: [PATCH 10/49] Update oudated comment Update comment cause gc/select.go has been moved to walk/select.go and gc/reflect.go has been moved to reflectdata/reflect.go Change-Id: I6894527e1e9dbca50ace92a51bf942f9495ce88c GitHub-Last-Rev: 6d6a4471440403218b68ba32d4038ca41eae2901 GitHub-Pull-Request: golang/go#45976 Reviewed-on: https://go-review.googlesource.com/c/go/+/317191 Reviewed-by: Keith Randall Trust: Michael Pratt --- src/cmd/compile/internal/reflectdata/reflect.go | 2 +- src/cmd/link/internal/ld/decodesym.go | 4 ++-- src/internal/reflectlite/type.go | 4 ++-- src/reflect/type.go | 10 +++++----- src/runtime/runtime2.go | 4 ++-- src/runtime/select.go | 2 +- src/runtime/type.go | 6 +++--- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/cmd/compile/internal/reflectdata/reflect.go b/src/cmd/compile/internal/reflectdata/reflect.go index e07294be0f..eb9a8a6c9b 100644 --- a/src/cmd/compile/internal/reflectdata/reflect.go +++ b/src/cmd/compile/internal/reflectdata/reflect.go @@ -669,7 +669,7 @@ var kinds = []int{ // tflag is documented in reflect/type.go. // // tflag values must be kept in sync with copies in: -// cmd/compile/internal/gc/reflect.go +// cmd/compile/internal/reflectdata/reflect.go // cmd/link/internal/ld/decodesym.go // reflect/type.go // runtime/type.go diff --git a/src/cmd/link/internal/ld/decodesym.go b/src/cmd/link/internal/ld/decodesym.go index c41d97706e..629bdcf4ca 100644 --- a/src/cmd/link/internal/ld/decodesym.go +++ b/src/cmd/link/internal/ld/decodesym.go @@ -16,12 +16,12 @@ import ( // Decoding the type.* symbols. This has to be in sync with // ../../runtime/type.go, or more specifically, with what -// cmd/compile/internal/gc/reflect.go stuffs in these. +// cmd/compile/internal/reflectdata/reflect.go stuffs in these. // tflag is documented in reflect/type.go. // // tflag values must be kept in sync with copies in: -// cmd/compile/internal/gc/reflect.go +// cmd/compile/internal/reflectdata/reflect.go // cmd/link/internal/ld/decodesym.go // reflect/type.go // runtime/type.go diff --git a/src/internal/reflectlite/type.go b/src/internal/reflectlite/type.go index f529f7c5fc..b1899b0191 100644 --- a/src/internal/reflectlite/type.go +++ b/src/internal/reflectlite/type.go @@ -68,7 +68,7 @@ type Type interface { } /* - * These data structures are known to the compiler (../../cmd/internal/gc/reflect.go). + * These data structures are known to the compiler (../../cmd/internal/reflectdata/reflect.go). * A few are known to ../runtime/type.go to convey to debuggers. * They are also known to ../runtime/type.go. */ @@ -111,7 +111,7 @@ const ( // available in the memory directly following the rtype value. // // tflag values must be kept in sync with copies in: -// cmd/compile/internal/gc/reflect.go +// cmd/compile/internal/reflectdata/reflect.go // cmd/link/internal/ld/decodesym.go // runtime/type.go type tflag uint8 diff --git a/src/reflect/type.go b/src/reflect/type.go index df863ae106..f672a7a5d5 100644 --- a/src/reflect/type.go +++ b/src/reflect/type.go @@ -228,7 +228,7 @@ type Type interface { // See https://golang.org/issue/4876 for more details. /* - * These data structures are known to the compiler (../../cmd/internal/gc/reflect.go). + * These data structures are known to the compiler (../../cmd/internal/reflectdata/reflect.go). * A few are known to ../runtime/type.go to convey to debuggers. * They are also known to ../runtime/type.go. */ @@ -271,7 +271,7 @@ const ( // available in the memory directly following the rtype value. // // tflag values must be kept in sync with copies in: -// cmd/compile/internal/gc/reflect.go +// cmd/compile/internal/reflectdata/reflect.go // cmd/link/internal/ld/decodesym.go // runtime/type.go type tflag uint8 @@ -1910,7 +1910,7 @@ func MapOf(key, elem Type) Type { // Make a map type. // Note: flag values must match those used in the TMAP case - // in ../cmd/compile/internal/gc/reflect.go:writeType. + // in ../cmd/compile/internal/reflectdata/reflect.go:writeType. var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil) mt := **(**mapType)(unsafe.Pointer(&imap)) mt.str = resolveReflectName(newName(s, "", false)) @@ -2841,7 +2841,7 @@ func runtimeStructField(field StructField) (structField, string) { // typeptrdata returns the length in bytes of the prefix of t // containing pointer data. Anything after this offset is scalar data. -// keep in sync with ../cmd/compile/internal/gc/reflect.go +// keep in sync with ../cmd/compile/internal/reflectdata/reflect.go func typeptrdata(t *rtype) uintptr { switch t.Kind() { case Struct: @@ -2865,7 +2865,7 @@ func typeptrdata(t *rtype) uintptr { } } -// See cmd/compile/internal/gc/reflect.go for derivation of constant. +// See cmd/compile/internal/reflectdata/reflect.go for derivation of constant. const maxPtrmaskBytes = 2048 // ArrayOf returns the array type with the given length and element type. diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go index 0e0eb0b728..2a66826f34 100644 --- a/src/runtime/runtime2.go +++ b/src/runtime/runtime2.go @@ -895,7 +895,7 @@ type funcinl struct { // layout of Itab known to compilers // allocated in non-garbage-collected memory // Needs to be in sync with -// ../cmd/compile/internal/gc/reflect.go:/^func.WriteTabs. +// ../cmd/compile/internal/reflectdata/reflect.go:/^func.WriteTabs. type itab struct { inter *interfacetype _type *_type @@ -940,7 +940,7 @@ func extendRandom(r []byte, n int) { // A _defer holds an entry on the list of deferred calls. // If you add a field here, add code to clear it in freedefer and deferProcStack -// This struct must match the code in cmd/compile/internal/gc/reflect.go:deferstruct +// This struct must match the code in cmd/compile/internal/reflectdata/reflect.go:deferstruct // and cmd/compile/internal/gc/ssa.go:(*state).call. // Some defers will be allocated on the stack and some on the heap. // All defers are logically part of the stack, so write barriers to diff --git a/src/runtime/select.go b/src/runtime/select.go index e72761bfa9..06edb69f42 100644 --- a/src/runtime/select.go +++ b/src/runtime/select.go @@ -15,7 +15,7 @@ const debugSelect = false // Select case descriptor. // Known to compiler. -// Changes here must also be made in src/cmd/internal/gc/select.go's scasetype. +// Changes here must also be made in src/cmd/compile/internal/walk/select.go's scasetype. type scase struct { c *hchan // chan elem unsafe.Pointer // data element diff --git a/src/runtime/type.go b/src/runtime/type.go index 335fc57f4b..4039273695 100644 --- a/src/runtime/type.go +++ b/src/runtime/type.go @@ -11,7 +11,7 @@ import "unsafe" // tflag is documented in reflect/type.go. // // tflag values must be kept in sync with copies in: -// cmd/compile/internal/gc/reflect.go +// cmd/compile/internal/reflectdata/reflect.go // cmd/link/internal/ld/decodesym.go // reflect/type.go // internal/reflectlite/type.go @@ -25,7 +25,7 @@ const ( ) // Needs to be in sync with ../cmd/link/internal/ld/decodesym.go:/^func.commonsize, -// ../cmd/compile/internal/gc/reflect.go:/^func.dcommontype and +// ../cmd/compile/internal/reflectdata/reflect.go:/^func.dcommontype and // ../reflect/type.go:/^type.rtype. // ../internal/reflectlite/type.go:/^type.rtype. type _type struct { @@ -383,7 +383,7 @@ type maptype struct { } // Note: flag values must match those used in the TMAP case -// in ../cmd/compile/internal/gc/reflect.go:writeType. +// in ../cmd/compile/internal/reflectdata/reflect.go:writeType. func (mt *maptype) indirectkey() bool { // store ptr to key instead of key itself return mt.flags&1 != 0 } From 296ddf2a936a30866303a64d49bc0e3e034730a8 Mon Sep 17 00:00:00 2001 From: Roland Shoemaker Date: Fri, 2 Jul 2021 10:25:49 -0700 Subject: [PATCH 11/49] net: filter bad names from Lookup functions instead of hard failing Instead of hard failing on a single bad record, filter the bad records and return anything valid. This only applies to the methods which can return multiple records, LookupMX, LookupNS, LookupSRV, and LookupAddr. When bad results are filtered out, also return an error, indicating that this filtering has happened. Updates #46241 Fixes #46979 Change-Id: I6493e0002beaf89f5a9795333a93605abd30d171 Reviewed-on: https://go-review.googlesource.com/c/go/+/332549 Trust: Roland Shoemaker Reviewed-by: Filippo Valsorda --- src/net/dnsclient_unix_test.go | 222 +++++++++++++++++++++++++-------- src/net/lookup.go | 74 ++++++++--- 2 files changed, 229 insertions(+), 67 deletions(-) diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go index 59cdd2bf3e..350ad5def7 100644 --- a/src/net/dnsclient_unix_test.go +++ b/src/net/dnsclient_unix_test.go @@ -1846,6 +1846,17 @@ func TestCVE202133195(t *testing.T) { Target: dnsmessage.MustNewName(".golang.org."), }, }, + dnsmessage.Resource{ + Header: dnsmessage.ResourceHeader{ + Name: n, + Type: dnsmessage.TypeSRV, + Class: dnsmessage.ClassINET, + Length: 4, + }, + Body: &dnsmessage.SRVResource{ + Target: dnsmessage.MustNewName("good.golang.org."), + }, + }, ) case dnsmessage.TypeMX: r.Answers = append(r.Answers, @@ -1860,6 +1871,17 @@ func TestCVE202133195(t *testing.T) { MX: dnsmessage.MustNewName(".golang.org."), }, }, + dnsmessage.Resource{ + Header: dnsmessage.ResourceHeader{ + Name: dnsmessage.MustNewName("good.golang.org."), + Type: dnsmessage.TypeMX, + Class: dnsmessage.ClassINET, + Length: 4, + }, + Body: &dnsmessage.MXResource{ + MX: dnsmessage.MustNewName("good.golang.org."), + }, + }, ) case dnsmessage.TypeNS: r.Answers = append(r.Answers, @@ -1874,6 +1896,17 @@ func TestCVE202133195(t *testing.T) { NS: dnsmessage.MustNewName(".golang.org."), }, }, + dnsmessage.Resource{ + Header: dnsmessage.ResourceHeader{ + Name: dnsmessage.MustNewName("good.golang.org."), + Type: dnsmessage.TypeNS, + Class: dnsmessage.ClassINET, + Length: 4, + }, + Body: &dnsmessage.NSResource{ + NS: dnsmessage.MustNewName("good.golang.org."), + }, + }, ) case dnsmessage.TypePTR: r.Answers = append(r.Answers, @@ -1888,6 +1921,17 @@ func TestCVE202133195(t *testing.T) { PTR: dnsmessage.MustNewName(".golang.org."), }, }, + dnsmessage.Resource{ + Header: dnsmessage.ResourceHeader{ + Name: dnsmessage.MustNewName("good.golang.org."), + Type: dnsmessage.TypePTR, + Class: dnsmessage.ClassINET, + Length: 4, + }, + Body: &dnsmessage.PTRResource{ + PTR: dnsmessage.MustNewName("good.golang.org."), + }, + }, ) } return r, nil @@ -1903,59 +1947,139 @@ func TestCVE202133195(t *testing.T) { defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath) testHookHostsPath = "testdata/hosts" - _, err := r.LookupCNAME(context.Background(), "golang.org") - if expected := "lookup golang.org: CNAME target is invalid"; err == nil || err.Error() != expected { - t.Errorf("Resolver.LookupCNAME returned unexpected error, got %q, want %q", err, expected) - } - _, err = LookupCNAME("golang.org") - if expected := "lookup golang.org: CNAME target is invalid"; err == nil || err.Error() != expected { - t.Errorf("LookupCNAME returned unexpected error, got %q, want %q", err, expected) + tests := []struct { + name string + f func(*testing.T) + }{ + { + name: "CNAME", + f: func(t *testing.T) { + expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"} + _, err := r.LookupCNAME(context.Background(), "golang.org") + if err.Error() != expectedErr.Error() { + t.Fatalf("unexpected error: %s", err) + } + _, err = LookupCNAME("golang.org") + if err.Error() != expectedErr.Error() { + t.Fatalf("unexpected error: %s", err) + } + }, + }, + { + name: "SRV (bad record)", + f: func(t *testing.T) { + expected := []*SRV{ + { + Target: "good.golang.org.", + }, + } + expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"} + _, records, err := r.LookupSRV(context.Background(), "target", "tcp", "golang.org") + if err.Error() != expectedErr.Error() { + t.Fatalf("unexpected error: %s", err) + } + if !reflect.DeepEqual(records, expected) { + t.Error("Unexpected record set") + } + _, records, err = LookupSRV("target", "tcp", "golang.org") + if err.Error() != expectedErr.Error() { + t.Errorf("unexpected error: %s", err) + } + if !reflect.DeepEqual(records, expected) { + t.Error("Unexpected record set") + } + }, + }, + { + name: "SRV (bad header)", + f: func(t *testing.T) { + _, _, err := r.LookupSRV(context.Background(), "hdr", "tcp", "golang.org.") + if expected := "lookup golang.org.: SRV header name is invalid"; err == nil || err.Error() != expected { + t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err, expected) + } + _, _, err = LookupSRV("hdr", "tcp", "golang.org.") + if expected := "lookup golang.org.: SRV header name is invalid"; err == nil || err.Error() != expected { + t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err, expected) + } + }, + }, + { + name: "MX", + f: func(t *testing.T) { + expected := []*MX{ + { + Host: "good.golang.org.", + }, + } + expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"} + records, err := r.LookupMX(context.Background(), "golang.org") + if err.Error() != expectedErr.Error() { + t.Fatalf("unexpected error: %s", err) + } + if !reflect.DeepEqual(records, expected) { + t.Error("Unexpected record set") + } + records, err = LookupMX("golang.org") + if err.Error() != expectedErr.Error() { + t.Fatalf("unexpected error: %s", err) + } + if !reflect.DeepEqual(records, expected) { + t.Error("Unexpected record set") + } + }, + }, + { + name: "NS", + f: func(t *testing.T) { + expected := []*NS{ + { + Host: "good.golang.org.", + }, + } + expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"} + records, err := r.LookupNS(context.Background(), "golang.org") + if err.Error() != expectedErr.Error() { + t.Fatalf("unexpected error: %s", err) + } + if !reflect.DeepEqual(records, expected) { + t.Error("Unexpected record set") + } + records, err = LookupNS("golang.org") + if err.Error() != expectedErr.Error() { + t.Fatalf("unexpected error: %s", err) + } + if !reflect.DeepEqual(records, expected) { + t.Error("Unexpected record set") + } + }, + }, + { + name: "Addr", + f: func(t *testing.T) { + expected := []string{"good.golang.org."} + expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "192.0.2.42"} + records, err := r.LookupAddr(context.Background(), "192.0.2.42") + if err.Error() != expectedErr.Error() { + t.Fatalf("unexpected error: %s", err) + } + if !reflect.DeepEqual(records, expected) { + t.Error("Unexpected record set") + } + records, err = LookupAddr("192.0.2.42") + if err.Error() != expectedErr.Error() { + t.Fatalf("unexpected error: %s", err) + } + if !reflect.DeepEqual(records, expected) { + t.Error("Unexpected record set") + } + }, + }, } - _, _, err = r.LookupSRV(context.Background(), "target", "tcp", "golang.org") - if expected := "lookup golang.org: SRV target is invalid"; err == nil || err.Error() != expected { - t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err, expected) - } - _, _, err = LookupSRV("target", "tcp", "golang.org") - if expected := "lookup golang.org: SRV target is invalid"; err == nil || err.Error() != expected { - t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err, expected) + for _, tc := range tests { + t.Run(tc.name, tc.f) } - _, _, err = r.LookupSRV(context.Background(), "hdr", "tcp", "golang.org.") - if expected := "lookup golang.org.: SRV header name is invalid"; err == nil || err.Error() != expected { - t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err, expected) - } - _, _, err = LookupSRV("hdr", "tcp", "golang.org.") - if expected := "lookup golang.org.: SRV header name is invalid"; err == nil || err.Error() != expected { - t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err, expected) - } - - _, err = r.LookupMX(context.Background(), "golang.org") - if expected := "lookup golang.org: MX target is invalid"; err == nil || err.Error() != expected { - t.Errorf("Resolver.LookupMX returned unexpected error, got %q, want %q", err, expected) - } - _, err = LookupMX("golang.org") - if expected := "lookup golang.org: MX target is invalid"; err == nil || err.Error() != expected { - t.Errorf("LookupMX returned unexpected error, got %q, want %q", err, expected) - } - - _, err = r.LookupNS(context.Background(), "golang.org") - if expected := "lookup golang.org: NS target is invalid"; err == nil || err.Error() != expected { - t.Errorf("Resolver.LookupNS returned unexpected error, got %q, want %q", err, expected) - } - _, err = LookupNS("golang.org") - if expected := "lookup golang.org: NS target is invalid"; err == nil || err.Error() != expected { - t.Errorf("LookupNS returned unexpected error, got %q, want %q", err, expected) - } - - _, err = r.LookupAddr(context.Background(), "192.0.2.42") - if expected := "lookup 192.0.2.42: PTR target is invalid"; err == nil || err.Error() != expected { - t.Errorf("Resolver.LookupAddr returned unexpected error, got %q, want %q", err, expected) - } - _, err = LookupAddr("192.0.2.42") - if expected := "lookup 192.0.2.42: PTR target is invalid"; err == nil || err.Error() != expected { - t.Errorf("LookupAddr returned unexpected error, got %q, want %q", err, expected) - } } func TestNullMX(t *testing.T) { diff --git a/src/net/lookup.go b/src/net/lookup.go index b5af3a0f86..d350ef7fc0 100644 --- a/src/net/lookup.go +++ b/src/net/lookup.go @@ -424,7 +424,7 @@ func (r *Resolver) LookupCNAME(ctx context.Context, host string) (string, error) return "", err } if !isDomainName(cname) { - return "", &DNSError{Err: "CNAME target is invalid", Name: host} + return "", &DNSError{Err: errMalformedDNSRecordsDetail, Name: host} } return cname, nil } @@ -440,7 +440,9 @@ func (r *Resolver) LookupCNAME(ctx context.Context, host string) (string, error) // and proto are empty strings, LookupSRV looks up name directly. // // The returned service names are validated to be properly -// formatted presentation-format domain names. +// formatted presentation-format domain names. If the response contains +// invalid names, those records are filtered out and an error +// will be returned alongside the the remaining results, if any. func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) { return DefaultResolver.LookupSRV(context.Background(), service, proto, name) } @@ -456,7 +458,9 @@ func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err err // and proto are empty strings, LookupSRV looks up name directly. // // The returned service names are validated to be properly -// formatted presentation-format domain names. +// formatted presentation-format domain names. If the response contains +// invalid names, those records are filtered out and an error +// will be returned alongside the the remaining results, if any. func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) { cname, addrs, err := r.lookupSRV(ctx, service, proto, name) if err != nil { @@ -465,21 +469,28 @@ func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) ( if cname != "" && !isDomainName(cname) { return "", nil, &DNSError{Err: "SRV header name is invalid", Name: name} } + filteredAddrs := make([]*SRV, 0, len(addrs)) for _, addr := range addrs { if addr == nil { continue } if !isDomainName(addr.Target) { - return "", nil, &DNSError{Err: "SRV target is invalid", Name: name} + continue } + filteredAddrs = append(filteredAddrs, addr) } - return cname, addrs, nil + if len(addrs) != len(filteredAddrs) { + return cname, filteredAddrs, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name} + } + return cname, filteredAddrs, nil } // LookupMX returns the DNS MX records for the given domain name sorted by preference. // // The returned mail server names are validated to be properly -// formatted presentation-format domain names. +// formatted presentation-format domain names. If the response contains +// invalid names, those records are filtered out and an error +// will be returned alongside the the remaining results, if any. // // LookupMX uses context.Background internally; to specify the context, use // Resolver.LookupMX. @@ -490,12 +501,15 @@ func LookupMX(name string) ([]*MX, error) { // LookupMX returns the DNS MX records for the given domain name sorted by preference. // // The returned mail server names are validated to be properly -// formatted presentation-format domain names. +// formatted presentation-format domain names. If the response contains +// invalid names, those records are filtered out and an error +// will be returned alongside the the remaining results, if any. func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*MX, error) { records, err := r.lookupMX(ctx, name) if err != nil { return nil, err } + filteredMX := make([]*MX, 0, len(records)) for _, mx := range records { if mx == nil { continue @@ -503,16 +517,22 @@ func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*MX, error) { // Bypass the hostname validity check for targets which contain only a dot, // as this is used to represent a 'Null' MX record. if mx.Host != "." && !isDomainName(mx.Host) { - return nil, &DNSError{Err: "MX target is invalid", Name: name} + continue } + filteredMX = append(filteredMX, mx) } - return records, nil + if len(records) != len(filteredMX) { + return filteredMX, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name} + } + return filteredMX, nil } // LookupNS returns the DNS NS records for the given domain name. // // The returned name server names are validated to be properly -// formatted presentation-format domain names. +// formatted presentation-format domain names. If the response contains +// invalid names, those records are filtered out and an error +// will be returned alongside the the remaining results, if any. // // LookupNS uses context.Background internally; to specify the context, use // Resolver.LookupNS. @@ -523,21 +543,28 @@ func LookupNS(name string) ([]*NS, error) { // LookupNS returns the DNS NS records for the given domain name. // // The returned name server names are validated to be properly -// formatted presentation-format domain names. +// formatted presentation-format domain names. If the response contains +// invalid names, those records are filtered out and an error +// will be returned alongside the the remaining results, if any. func (r *Resolver) LookupNS(ctx context.Context, name string) ([]*NS, error) { records, err := r.lookupNS(ctx, name) if err != nil { return nil, err } + filteredNS := make([]*NS, 0, len(records)) for _, ns := range records { if ns == nil { continue } if !isDomainName(ns.Host) { - return nil, &DNSError{Err: "NS target is invalid", Name: name} + continue } + filteredNS = append(filteredNS, ns) } - return records, nil + if len(records) != len(filteredNS) { + return filteredNS, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name} + } + return filteredNS, nil } // LookupTXT returns the DNS TXT records for the given domain name. @@ -557,7 +584,8 @@ func (r *Resolver) LookupTXT(ctx context.Context, name string) ([]string, error) // of names mapping to that address. // // The returned names are validated to be properly formatted presentation-format -// domain names. +// domain names. If the response contains invalid names, those records are filtered +// out and an error will be returned alongside the the remaining results, if any. // // When using the host C library resolver, at most one result will be // returned. To bypass the host resolver, use a custom Resolver. @@ -572,16 +600,26 @@ func LookupAddr(addr string) (names []string, err error) { // of names mapping to that address. // // The returned names are validated to be properly formatted presentation-format -// domain names. +// domain names. If the response contains invalid names, those records are filtered +// out and an error will be returned alongside the the remaining results, if any. func (r *Resolver) LookupAddr(ctx context.Context, addr string) ([]string, error) { names, err := r.lookupAddr(ctx, addr) if err != nil { return nil, err } + filteredNames := make([]string, 0, len(names)) for _, name := range names { - if !isDomainName(name) { - return nil, &DNSError{Err: "PTR target is invalid", Name: addr} + if isDomainName(name) { + filteredNames = append(filteredNames, name) } } - return names, nil + if len(names) != len(filteredNames) { + return filteredNames, &DNSError{Err: errMalformedDNSRecordsDetail, Name: addr} + } + return filteredNames, nil } + +// errMalformedDNSRecordsDetail is the DNSError detail which is returned when a Resolver.Lookup... +// method recieves DNS records which contain invalid DNS names. This may be returned alongside +// results which have had the malformed records filtered out. +var errMalformedDNSRecordsDetail = "DNS response contained records which contain invalid names" From ab4085ce84f8378b4ec2dfdbbc44c98cb92debe5 Mon Sep 17 00:00:00 2001 From: Michael Anthony Knyszek Date: Fri, 9 Jul 2021 17:34:07 +0000 Subject: [PATCH 12/49] runtime/pprof: call runtime.GC twice in memory profile test This change fixes #46500 by working around #45315 which may cause freed objects to get missed in the heap profile published for the test. By calling runtime.GC one more time this change ensures that all freed objects are accounted for. Fixes #46500. Change-Id: Iedcd0b37dbaffa688b0ff8631a8b79f7a1169634 Reviewed-on: https://go-review.googlesource.com/c/go/+/333549 Trust: Michael Knyszek Run-TryBot: Michael Knyszek TryBot-Result: Go Bot Reviewed-by: Austin Clements --- src/runtime/pprof/mprof_test.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/runtime/pprof/mprof_test.go b/src/runtime/pprof/mprof_test.go index 3ef40d3de7..b4680fbdee 100644 --- a/src/runtime/pprof/mprof_test.go +++ b/src/runtime/pprof/mprof_test.go @@ -86,6 +86,17 @@ func TestMemoryProfiler(t *testing.T) { runtime.GC() // materialize stats + // TODO(mknyszek): Fix #45315 and remove this extra call. + // + // Unfortunately, it's possible for the sweep termination condition + // to flap, so with just one runtime.GC call, a freed object could be + // missed, leading this test to fail. A second call reduces the chance + // of this happening to zero, because sweeping actually has to finish + // to move on to the next GC, during which nothing will happen. + // + // See #46500 for more details. + runtime.GC() + memoryProfilerRun++ tests := []struct { From cfbd73ba33fc6a3635b3a63096fd6c6bff9d73e8 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Fri, 9 Jul 2021 16:22:32 -0400 Subject: [PATCH 13/49] doc/go1.17: editing pass over the "Compiler" section Change-Id: I08c082f548daa7011a8dc42769371329684c90e6 Reviewed-on: https://go-review.googlesource.com/c/go/+/333609 Trust: Austin Clements Trust: Dan Scales Reviewed-by: Dan Scales --- doc/go1.17.html | 62 ++++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/doc/go1.17.html b/doc/go1.17.html index 4fa30158bb..fa8f14de99 100644 --- a/doc/go1.17.html +++ b/doc/go1.17.html @@ -401,30 +401,37 @@ func Foo() bool {

Go 1.17 implements a new way of passing function arguments and results using - registers instead of the stack. This work is enabled for Linux, macOS, and - Windows on the 64-bit x86 architecture (the linux/amd64, - darwin/amd64, windows/amd64 ports). For a - representative set of Go packages and programs, benchmarking has shown - performance improvements of about 5%, and a typical reduction in binary size - of about 2%. + registers instead of the stack. + Benchmarks for a representative set of Go packages and programs show + performance improvements of about 5%, and a typical reduction in + binary size of about 2%. + This is currently enabled for Linux, macOS, and Windows on the + 64-bit x86 architecture (the linux/amd64, + darwin/amd64, and windows/amd64 ports).

- This change does not affect the functionality of any safe Go code. It can affect - code outside the compatibility guidelines with - minimal impact. To maintain compatibility with existing assembly functions, - adapter functions converting between the new register-based calling convention - and the previous stack-based calling convention (also known as ABI wrappers) - are sometimes used. This is mostly invisible to users, except for assembly - functions that have their addresses taken in Go. Using reflect.ValueOf(fn).Pointer() - (or similar approaches such as via unsafe.Pointer) to get the address - of an assembly function will now return the address of the ABI wrapper. This is - mostly harmless, except for special-purpose assembly code (such as accessing - thread-local storage or requiring a special stack alignment). Assembly functions - called indirectly from Go via func values will now be made through - ABI wrappers, which may cause a very small performance overhead. Also, calling - Go functions from assembly may now go through ABI wrappers, with a very small - performance overhead. + This change does not affect the functionality of any safe Go code + and is designed to have no impact on most assembly code. + It may affect code that violates + the unsafe.Pointer + rules when accessing function arguments, or that depends on + undocumented behavior involving comparing function code pointers. + To maintain compatibility with existing assembly functions, the + compiler generates adapter functions that convert between the new + register-based calling convention and the previous stack-based + calling convention. + These adapters are typically invisible to users, except that taking + the address of a Go function in assembly code or taking the address + of an assembly function in Go code + using reflect.ValueOf(fn).Pointer() + or unsafe.Pointer will now return the address of the + adapter. + Code that depends on the value of these code pointers may no longer + behave as expected. + Adapters also may cause a very small performance overhead in two + cases: calling an assembly function indirectly from Go via + a func value, and calling Go functions from assembly.

@@ -440,11 +447,14 @@ func Foo() bool {

- Functions containing closures can now be inlined. One effect of this change is - that a function with a closure may actually produce a distinct closure function - for each place that the function is inlined. Hence, this change could reveal - bugs where Go functions are compared (incorrectly) by pointer value. Go - functions are by definition not comparable. + Functions containing closures can now be inlined. + One effect of this change is that a function with a closure may + produce a distinct closure code pointer for each place that the + function is inlined. + Go function values are not directly comparable, but this change + could reveal bugs in code that uses reflect + or unsafe.Pointer to bypass this language restriction + and compare functions by code pointer.

Core library

From a98589711da5e9d935e8d690cfca92892e86d557 Mon Sep 17 00:00:00 2001 From: Roland Shoemaker Date: Wed, 9 Jun 2021 11:31:27 -0700 Subject: [PATCH 14/49] crypto/tls: test key type when casting When casting the certificate public key in generateClientKeyExchange, check the type is appropriate. This prevents a panic when a server agrees to a RSA based key exchange, but then sends an ECDSA (or other) certificate. Fixes #47143 Fixes CVE-2021-34558 Thanks to Imre Rad for reporting this issue. Change-Id: Iabccacca6052769a605cccefa1216a9f7b7f6aea Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1116723 Reviewed-by: Filippo Valsorda Reviewed-by: Katie Hockman Reviewed-on: https://go-review.googlesource.com/c/go/+/334031 Trust: Filippo Valsorda Run-TryBot: Filippo Valsorda TryBot-Result: Go Bot Reviewed-by: Dmitri Shuralyov --- src/crypto/tls/key_agreement.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/crypto/tls/key_agreement.go b/src/crypto/tls/key_agreement.go index 8cfbd734f1..c28a64f3a8 100644 --- a/src/crypto/tls/key_agreement.go +++ b/src/crypto/tls/key_agreement.go @@ -86,7 +86,11 @@ func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello return nil, nil, err } - encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret) + rsaKey, ok := cert.PublicKey.(*rsa.PublicKey) + if !ok { + return nil, nil, errors.New("tls: server certificate contains incorrect key type for selected ciphersuite") + } + encrypted, err := rsa.EncryptPKCS1v15(config.rand(), rsaKey, preMasterSecret) if err != nil { return nil, nil, err } From d8f348a589b3df4bb48636023be4ccf9ac96d307 Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Tue, 13 Jul 2021 17:25:26 -0400 Subject: [PATCH 15/49] cmd/go: remove a duplicated word from 'go help mod graph' For #46366 Change-Id: Ie9735027a3c4c0f4a604df30ca4d64dcdc62b45a Reviewed-on: https://go-review.googlesource.com/c/go/+/334375 Trust: Bryan C. Mills Run-TryBot: Bryan C. Mills Reviewed-by: Jay Conrod TryBot-Result: Go Bot --- src/cmd/go/alldocs.go | 2 +- src/cmd/go/internal/modcmd/graph.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go index 90eb3e2a00..954caae9fb 100644 --- a/src/cmd/go/alldocs.go +++ b/src/cmd/go/alldocs.go @@ -1193,7 +1193,7 @@ // and one of its requirements. Each module is identified as a string of the form // path@version, except for the main module, which has no @version suffix. // -// The -go flag causes graph to report the module graph as loaded by by the +// The -go flag causes graph to report the module graph as loaded by the // given Go version, instead of the version indicated by the 'go' directive // in the go.mod file. // diff --git a/src/cmd/go/internal/modcmd/graph.go b/src/cmd/go/internal/modcmd/graph.go index 903bd9970f..ac81f26dad 100644 --- a/src/cmd/go/internal/modcmd/graph.go +++ b/src/cmd/go/internal/modcmd/graph.go @@ -26,7 +26,7 @@ in text form. Each line in the output has two space-separated fields: a module and one of its requirements. Each module is identified as a string of the form path@version, except for the main module, which has no @version suffix. -The -go flag causes graph to report the module graph as loaded by by the +The -go flag causes graph to report the module graph as loaded by the given Go version, instead of the version indicated by the 'go' directive in the go.mod file. From 60ddf42b4627fb4ff5f92d2193c294456175af9a Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Fri, 2 Jul 2021 16:41:22 -0400 Subject: [PATCH 16/49] cmd/go: change link in error message from /wiki to /doc. The /doc link is currently a redirect (CL 334389), but I plan to update it soon with a more detailed guide. Updates #36460 Change-Id: I9e4a47ad0c8bcb7361cfa3e5b9d07ad241b13ba6 Reviewed-on: https://go-review.googlesource.com/c/go/+/332573 Trust: Bryan C. Mills Reviewed-by: Jay Conrod Reviewed-by: Michael Matloob --- src/cmd/go/internal/modload/load.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd/go/internal/modload/load.go b/src/cmd/go/internal/modload/load.go index 771b142b73..bce9ad85f4 100644 --- a/src/cmd/go/internal/modload/load.go +++ b/src/cmd/go/internal/modload/load.go @@ -1808,7 +1808,7 @@ func (ld *loader) checkTidyCompatibility(ctx context.Context, rs *Requirements) fmt.Fprintf(os.Stderr, "If reproducibility with go %s is not needed:\n\tgo mod tidy%s -compat=%s\n", ld.TidyCompatibleVersion, goFlag, ld.GoVersion) // TODO(#46141): Populate the linked wiki page. - fmt.Fprintf(os.Stderr, "For other options, see:\n\thttps://golang.org/wiki/PruningModules\n") + fmt.Fprintf(os.Stderr, "For other options, see:\n\thttps://golang.org/doc/modules/pruning\n") } mg, err := rs.Graph(ctx) From 2b00a54baf2b677b2aaddd93c25b11ea4642a86f Mon Sep 17 00:00:00 2001 From: WANG Xuerui Date: Mon, 12 Jul 2021 04:40:28 +0000 Subject: [PATCH 17/49] go/build, runtime/internal/sys: reserve GOARCH=loong64 Per discussion at #46229 we are taking the "loong64" GOARCH value for the upcoming LoongArch 64-bit port. It is not clear whether any 32-bit non-bare-metal userland will exist for LoongArch, so only reserve "loong64" for now. Change-Id: I97d262b4ab68ff61c22ccf83e26baf70eefd568d GitHub-Last-Rev: ecdd8c53bdee57fec093ddba18ec8878b8ae7c74 GitHub-Pull-Request: golang/go#47129 Reviewed-on: https://go-review.googlesource.com/c/go/+/333909 Run-TryBot: Ian Lance Taylor TryBot-Result: Go Bot Reviewed-by: Ian Lance Taylor Trust: Alexander Rakoczy --- src/go/build/syslist.go | 2 +- src/runtime/internal/sys/zgoarch_386.go | 1 + src/runtime/internal/sys/zgoarch_amd64.go | 1 + src/runtime/internal/sys/zgoarch_arm.go | 1 + src/runtime/internal/sys/zgoarch_arm64.go | 1 + src/runtime/internal/sys/zgoarch_arm64be.go | 1 + src/runtime/internal/sys/zgoarch_armbe.go | 1 + src/runtime/internal/sys/zgoarch_loong64.go | 33 +++++++++++++++++++ src/runtime/internal/sys/zgoarch_mips.go | 1 + src/runtime/internal/sys/zgoarch_mips64.go | 1 + src/runtime/internal/sys/zgoarch_mips64le.go | 1 + src/runtime/internal/sys/zgoarch_mips64p32.go | 1 + .../internal/sys/zgoarch_mips64p32le.go | 1 + src/runtime/internal/sys/zgoarch_mipsle.go | 1 + src/runtime/internal/sys/zgoarch_ppc.go | 1 + src/runtime/internal/sys/zgoarch_ppc64.go | 1 + src/runtime/internal/sys/zgoarch_ppc64le.go | 1 + src/runtime/internal/sys/zgoarch_riscv.go | 1 + src/runtime/internal/sys/zgoarch_riscv64.go | 1 + src/runtime/internal/sys/zgoarch_s390.go | 1 + src/runtime/internal/sys/zgoarch_s390x.go | 1 + src/runtime/internal/sys/zgoarch_sparc.go | 1 + src/runtime/internal/sys/zgoarch_sparc64.go | 1 + src/runtime/internal/sys/zgoarch_wasm.go | 1 + 24 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/runtime/internal/sys/zgoarch_loong64.go diff --git a/src/go/build/syslist.go b/src/go/build/syslist.go index 1275f7c986..60ac5511bd 100644 --- a/src/go/build/syslist.go +++ b/src/go/build/syslist.go @@ -8,4 +8,4 @@ package build // Do not remove from this list, as these are used for go/build filename matching. const goosList = "aix android darwin dragonfly freebsd hurd illumos ios js linux nacl netbsd openbsd plan9 solaris windows zos " -const goarchList = "386 amd64 amd64p32 arm armbe arm64 arm64be ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc riscv riscv64 s390 s390x sparc sparc64 wasm " +const goarchList = "386 amd64 amd64p32 arm armbe arm64 arm64be ppc64 ppc64le loong64 mips mipsle mips64 mips64le mips64p32 mips64p32le ppc riscv riscv64 s390 s390x sparc sparc64 wasm " diff --git a/src/runtime/internal/sys/zgoarch_386.go b/src/runtime/internal/sys/zgoarch_386.go index 98a2401bfe..5b189e7e73 100644 --- a/src/runtime/internal/sys/zgoarch_386.go +++ b/src/runtime/internal/sys/zgoarch_386.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_amd64.go b/src/runtime/internal/sys/zgoarch_amd64.go index d8faa5c786..312977d079 100644 --- a/src/runtime/internal/sys/zgoarch_amd64.go +++ b/src/runtime/internal/sys/zgoarch_amd64.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_arm.go b/src/runtime/internal/sys/zgoarch_arm.go index b64a69c9b4..5781870324 100644 --- a/src/runtime/internal/sys/zgoarch_arm.go +++ b/src/runtime/internal/sys/zgoarch_arm.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_arm64.go b/src/runtime/internal/sys/zgoarch_arm64.go index de6f85347b..f72a1f2161 100644 --- a/src/runtime/internal/sys/zgoarch_arm64.go +++ b/src/runtime/internal/sys/zgoarch_arm64.go @@ -16,6 +16,7 @@ const GoarchArm64 = 1 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_arm64be.go b/src/runtime/internal/sys/zgoarch_arm64be.go index b762bb069f..e805646058 100644 --- a/src/runtime/internal/sys/zgoarch_arm64be.go +++ b/src/runtime/internal/sys/zgoarch_arm64be.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 1 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_armbe.go b/src/runtime/internal/sys/zgoarch_armbe.go index e5297e4b16..d8d4e56d9a 100644 --- a/src/runtime/internal/sys/zgoarch_armbe.go +++ b/src/runtime/internal/sys/zgoarch_armbe.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_loong64.go b/src/runtime/internal/sys/zgoarch_loong64.go new file mode 100644 index 0000000000..6f35eb44a3 --- /dev/null +++ b/src/runtime/internal/sys/zgoarch_loong64.go @@ -0,0 +1,33 @@ +// Code generated by gengoos.go using 'go generate'. DO NOT EDIT. + +//go:build loong64 +// +build loong64 + +package sys + +const GOARCH = `loong64` + +const Goarch386 = 0 +const GoarchAmd64 = 0 +const GoarchAmd64p32 = 0 +const GoarchArm = 0 +const GoarchArmbe = 0 +const GoarchArm64 = 0 +const GoarchArm64be = 0 +const GoarchPpc64 = 0 +const GoarchPpc64le = 0 +const GoarchLoong64 = 1 +const GoarchMips = 0 +const GoarchMipsle = 0 +const GoarchMips64 = 0 +const GoarchMips64le = 0 +const GoarchMips64p32 = 0 +const GoarchMips64p32le = 0 +const GoarchPpc = 0 +const GoarchRiscv = 0 +const GoarchRiscv64 = 0 +const GoarchS390 = 0 +const GoarchS390x = 0 +const GoarchSparc = 0 +const GoarchSparc64 = 0 +const GoarchWasm = 0 diff --git a/src/runtime/internal/sys/zgoarch_mips.go b/src/runtime/internal/sys/zgoarch_mips.go index b5f4ed390c..bd58a92a0e 100644 --- a/src/runtime/internal/sys/zgoarch_mips.go +++ b/src/runtime/internal/sys/zgoarch_mips.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 1 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_mips64.go b/src/runtime/internal/sys/zgoarch_mips64.go index 73777cceb2..8e4a3dcd52 100644 --- a/src/runtime/internal/sys/zgoarch_mips64.go +++ b/src/runtime/internal/sys/zgoarch_mips64.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 1 diff --git a/src/runtime/internal/sys/zgoarch_mips64le.go b/src/runtime/internal/sys/zgoarch_mips64le.go index 0c81c36c09..d8e00339ea 100644 --- a/src/runtime/internal/sys/zgoarch_mips64le.go +++ b/src/runtime/internal/sys/zgoarch_mips64le.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_mips64p32.go b/src/runtime/internal/sys/zgoarch_mips64p32.go index d63ce27d24..8549cc0ba3 100644 --- a/src/runtime/internal/sys/zgoarch_mips64p32.go +++ b/src/runtime/internal/sys/zgoarch_mips64p32.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_mips64p32le.go b/src/runtime/internal/sys/zgoarch_mips64p32le.go index 2d577890b2..667b6fe514 100644 --- a/src/runtime/internal/sys/zgoarch_mips64p32le.go +++ b/src/runtime/internal/sys/zgoarch_mips64p32le.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_mipsle.go b/src/runtime/internal/sys/zgoarch_mipsle.go index 8af919d03a..8bedb2bb90 100644 --- a/src/runtime/internal/sys/zgoarch_mipsle.go +++ b/src/runtime/internal/sys/zgoarch_mipsle.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 1 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_ppc.go b/src/runtime/internal/sys/zgoarch_ppc.go index f6f12a5ddc..fe2196a327 100644 --- a/src/runtime/internal/sys/zgoarch_ppc.go +++ b/src/runtime/internal/sys/zgoarch_ppc.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_ppc64.go b/src/runtime/internal/sys/zgoarch_ppc64.go index a8379601f4..bd7cc43de3 100644 --- a/src/runtime/internal/sys/zgoarch_ppc64.go +++ b/src/runtime/internal/sys/zgoarch_ppc64.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 1 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_ppc64le.go b/src/runtime/internal/sys/zgoarch_ppc64le.go index f2ec5dcba7..e101892401 100644 --- a/src/runtime/internal/sys/zgoarch_ppc64le.go +++ b/src/runtime/internal/sys/zgoarch_ppc64le.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 1 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_riscv.go b/src/runtime/internal/sys/zgoarch_riscv.go index 83a3312f5f..559f86071a 100644 --- a/src/runtime/internal/sys/zgoarch_riscv.go +++ b/src/runtime/internal/sys/zgoarch_riscv.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_riscv64.go b/src/runtime/internal/sys/zgoarch_riscv64.go index 1dfcc84997..8485a94b3d 100644 --- a/src/runtime/internal/sys/zgoarch_riscv64.go +++ b/src/runtime/internal/sys/zgoarch_riscv64.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_s390.go b/src/runtime/internal/sys/zgoarch_s390.go index 91aba5a0f6..4c4569e376 100644 --- a/src/runtime/internal/sys/zgoarch_s390.go +++ b/src/runtime/internal/sys/zgoarch_s390.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_s390x.go b/src/runtime/internal/sys/zgoarch_s390x.go index edce50234e..e50d2edbb5 100644 --- a/src/runtime/internal/sys/zgoarch_s390x.go +++ b/src/runtime/internal/sys/zgoarch_s390x.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_sparc.go b/src/runtime/internal/sys/zgoarch_sparc.go index 5ae9560ab0..0d08752c7b 100644 --- a/src/runtime/internal/sys/zgoarch_sparc.go +++ b/src/runtime/internal/sys/zgoarch_sparc.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_sparc64.go b/src/runtime/internal/sys/zgoarch_sparc64.go index e2a0134aff..ba405bbf35 100644 --- a/src/runtime/internal/sys/zgoarch_sparc64.go +++ b/src/runtime/internal/sys/zgoarch_sparc64.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 diff --git a/src/runtime/internal/sys/zgoarch_wasm.go b/src/runtime/internal/sys/zgoarch_wasm.go index 52e85dea37..7c3e5afd1e 100644 --- a/src/runtime/internal/sys/zgoarch_wasm.go +++ b/src/runtime/internal/sys/zgoarch_wasm.go @@ -16,6 +16,7 @@ const GoarchArm64 = 0 const GoarchArm64be = 0 const GoarchPpc64 = 0 const GoarchPpc64le = 0 +const GoarchLoong64 = 0 const GoarchMips = 0 const GoarchMipsle = 0 const GoarchMips64 = 0 From 21a04e33353316635b5f3351e807916f3bb1e844 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 14 Jul 2021 16:04:49 -0700 Subject: [PATCH 18/49] doc/go1.17: mention GOARCH=loong64 For #46229 Change-Id: I54d01d90f2b0c892d76121f1350c0e8cf4b2772f Reviewed-on: https://go-review.googlesource.com/c/go/+/334729 Trust: Ian Lance Taylor Reviewed-by: Dmitri Shuralyov --- doc/go1.17.html | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/go1.17.html b/doc/go1.17.html index fa8f14de99..b31006fe65 100644 --- a/doc/go1.17.html +++ b/doc/go1.17.html @@ -119,6 +119,17 @@ Do not send CLs removing the interior tags from such phrases. stack frame pointers only on Linux, macOS, and iOS.

+

loong64 GOARCH value reserved

+ +

+ The main Go compiler does not yet support the LoongArch + architecture, but we've reserved the GOARCH value + "loong64". + This means that Go files named *_loong64.go will now + be ignored by Go + tools except when that GOARCH value is being used. +

+

Tools

Go command

From c1cc9f9c3d5ed789a080ef9f8dd9c11eca7e2026 Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Thu, 15 Jul 2021 00:56:44 +0700 Subject: [PATCH 19/49] cmd/compile: fix lookup package of redeclared dot import symbol The compiler is relying on Sym.Def field to lookup symbol package in DotImportRefs map. But the Sym.Def field is clear whenever the compiler finish processing a file. If the dot import happen in file A, then the redeclaration happen in file B, then the symbol lookup in file B will see a nil Sym.Def, that cause the compiler crashes. To fix this, we can interate over DotImportRefs and check for matching symbol name and return the corresponding package. Though this operation can be slow, but it only happens in invalid program, when printing error message, so it's not worth to optimize it further. Fixes #47201 Change-Id: I4ca1cb0a8e7432b19cf71434592a4cbb58d54adf Reviewed-on: https://go-review.googlesource.com/c/go/+/334589 Trust: Cuong Manh Le Run-TryBot: Cuong Manh Le TryBot-Result: Go Bot Reviewed-by: Matthew Dempsky --- src/cmd/compile/internal/typecheck/dcl.go | 12 +++++++++++- test/fixedbugs/issue47201.dir/a.go | 13 +++++++++++++ test/fixedbugs/issue47201.dir/b.go | 9 +++++++++ test/fixedbugs/issue47201.go | 7 +++++++ 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 test/fixedbugs/issue47201.dir/a.go create mode 100644 test/fixedbugs/issue47201.dir/b.go create mode 100644 test/fixedbugs/issue47201.go diff --git a/src/cmd/compile/internal/typecheck/dcl.go b/src/cmd/compile/internal/typecheck/dcl.go index f3058d8811..5b771e3c0b 100644 --- a/src/cmd/compile/internal/typecheck/dcl.go +++ b/src/cmd/compile/internal/typecheck/dcl.go @@ -106,7 +106,17 @@ func Export(n *ir.Name) { // Redeclared emits a diagnostic about symbol s being redeclared at pos. func Redeclared(pos src.XPos, s *types.Sym, where string) { if !s.Lastlineno.IsKnown() { - pkgName := DotImportRefs[s.Def.(*ir.Ident)] + var pkgName *ir.PkgName + if s.Def == nil { + for id, pkg := range DotImportRefs { + if id.Sym().Name == s.Name { + pkgName = pkg + break + } + } + } else { + pkgName = DotImportRefs[s.Def.(*ir.Ident)] + } base.ErrorfAt(pos, "%v redeclared %s\n"+ "\t%v: previous declaration during import %q", s, where, base.FmtPos(pkgName.Pos()), pkgName.Pkg.Path) } else { diff --git a/test/fixedbugs/issue47201.dir/a.go b/test/fixedbugs/issue47201.dir/a.go new file mode 100644 index 0000000000..54b7079092 --- /dev/null +++ b/test/fixedbugs/issue47201.dir/a.go @@ -0,0 +1,13 @@ +// 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 ( + . "fmt" +) + +func test() { + Println("foo") +} diff --git a/test/fixedbugs/issue47201.dir/b.go b/test/fixedbugs/issue47201.dir/b.go new file mode 100644 index 0000000000..5fd0635af2 --- /dev/null +++ b/test/fixedbugs/issue47201.dir/b.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 main + +func Println() {} // ERROR "Println redeclared in this block" + +func main() {} diff --git a/test/fixedbugs/issue47201.go b/test/fixedbugs/issue47201.go new file mode 100644 index 0000000000..e3a470b419 --- /dev/null +++ b/test/fixedbugs/issue47201.go @@ -0,0 +1,7 @@ +// errorcheckdir + +// 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 ignored From 69728ead871f15cc1fd7e70b67e6768dd1100bae Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Thu, 15 Jul 2021 14:48:45 -0400 Subject: [PATCH 20/49] cmd/go: update error messages in tests to match CL 332573 I neglected to run the 'longtest' builder, and the tests that cover the error message changed in CL 332573 apparently do not run in short mode. Updates #36460 Updates #42661 Change-Id: I53500ddaca8ac9f0dfaab538923b3c9a4f71665e Reviewed-on: https://go-review.googlesource.com/c/go/+/334889 Trust: Bryan C. Mills Run-TryBot: Bryan C. Mills Reviewed-by: Jay Conrod TryBot-Result: Go Bot --- src/cmd/go/testdata/script/mod_tidy_compat_ambiguous.txt | 2 +- src/cmd/go/testdata/script/mod_tidy_compat_deleted.txt | 2 +- src/cmd/go/testdata/script/mod_tidy_compat_implicit.txt | 2 +- src/cmd/go/testdata/script/mod_tidy_compat_incompatible.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cmd/go/testdata/script/mod_tidy_compat_ambiguous.txt b/src/cmd/go/testdata/script/mod_tidy_compat_ambiguous.txt index ed1dd53eff..c544cb7413 100644 --- a/src/cmd/go/testdata/script/mod_tidy_compat_ambiguous.txt +++ b/src/cmd/go/testdata/script/mod_tidy_compat_ambiguous.txt @@ -23,7 +23,7 @@ cp go.mod go.mod.orig stderr '^example\.com/m imports\n\texample\.net/indirect imports\n\texample\.net/ambiguous/nested/pkg loaded from example\.net/ambiguous/nested@v0\.1\.0,\n\tbut go 1.16 would fail to locate it:\n\tambiguous import: found package example\.net/ambiguous/nested/pkg in multiple modules:\n\texample\.net/ambiguous v0.1.0 \(.*\)\n\texample\.net/ambiguous/nested v0.1.0 \(.*\)\n\n' -stderr '\n\nTo proceed despite packages unresolved in go 1\.16:\n\tgo mod tidy -e\nIf reproducibility with go 1.16 is not needed:\n\tgo mod tidy -compat=1\.17\nFor other options, see:\n\thttps://golang\.org/wiki/PruningModules\n' +stderr '\n\nTo proceed despite packages unresolved in go 1\.16:\n\tgo mod tidy -e\nIf reproducibility with go 1.16 is not needed:\n\tgo mod tidy -compat=1\.17\nFor other options, see:\n\thttps://golang\.org/doc/modules/pruning\n' cmp go.mod go.mod.orig diff --git a/src/cmd/go/testdata/script/mod_tidy_compat_deleted.txt b/src/cmd/go/testdata/script/mod_tidy_compat_deleted.txt index 3aacde2025..dcf13e2049 100644 --- a/src/cmd/go/testdata/script/mod_tidy_compat_deleted.txt +++ b/src/cmd/go/testdata/script/mod_tidy_compat_deleted.txt @@ -19,7 +19,7 @@ cp go.mod go.mod.orig stderr '^example\.com/m imports\n\texample\.net/deleted loaded from example\.net/deleted@v0\.1\.0,\n\tbut go 1\.16 would fail to locate it in example\.net/deleted@v0\.2\.0\n\n' -stderr '\n\nTo upgrade to the versions selected by go 1.16, leaving some packages unresolved:\n\tgo mod tidy -e -go=1\.16 && go mod tidy -e -go=1\.17\nIf reproducibility with go 1.16 is not needed:\n\tgo mod tidy -compat=1\.17\nFor other options, see:\n\thttps://golang\.org/wiki/PruningModules\n' +stderr '\n\nTo upgrade to the versions selected by go 1.16, leaving some packages unresolved:\n\tgo mod tidy -e -go=1\.16 && go mod tidy -e -go=1\.17\nIf reproducibility with go 1.16 is not needed:\n\tgo mod tidy -compat=1\.17\nFor other options, see:\n\thttps://golang\.org/doc/modules/pruning\n' # The suggested 'go mod tidy -e' command should proceed anyway. diff --git a/src/cmd/go/testdata/script/mod_tidy_compat_implicit.txt b/src/cmd/go/testdata/script/mod_tidy_compat_implicit.txt index e00aea930e..186a3f8e67 100644 --- a/src/cmd/go/testdata/script/mod_tidy_compat_implicit.txt +++ b/src/cmd/go/testdata/script/mod_tidy_compat_implicit.txt @@ -33,7 +33,7 @@ env MODFMT='{{with .Module}}{{.Path}} {{.Version}}{{end}}' cp go.mod go.mod.orig ! go mod tidy stderr '^example\.com/m imports\n\texample\.net/lazy tested by\n\texample\.net/lazy.test imports\n\texample\.com/retract/incompatible loaded from example\.com/retract/incompatible@v1\.0\.0,\n\tbut go 1\.16 would select v2\.0\.0\+incompatible\n\n' -stderr '\n\nTo upgrade to the versions selected by go 1\.16:\n\tgo mod tidy -go=1\.16 && go mod tidy -go=1\.17\nIf reproducibility with go 1.16 is not needed:\n\tgo mod tidy -compat=1.17\nFor other options, see:\n\thttps://golang\.org/wiki/PruningModules\n' +stderr '\n\nTo upgrade to the versions selected by go 1\.16:\n\tgo mod tidy -go=1\.16 && go mod tidy -go=1\.17\nIf reproducibility with go 1.16 is not needed:\n\tgo mod tidy -compat=1.17\nFor other options, see:\n\thttps://golang\.org/doc/modules/pruning\n' cmp go.mod go.mod.orig diff --git a/src/cmd/go/testdata/script/mod_tidy_compat_incompatible.txt b/src/cmd/go/testdata/script/mod_tidy_compat_incompatible.txt index 2d8726544a..ea9e42e87e 100644 --- a/src/cmd/go/testdata/script/mod_tidy_compat_incompatible.txt +++ b/src/cmd/go/testdata/script/mod_tidy_compat_incompatible.txt @@ -33,7 +33,7 @@ env MODFMT='{{with .Module}}{{.Path}} {{.Version}}{{end}}' cp go.mod go.mod.orig ! go mod tidy stderr '^example\.com/m imports\n\texample\.net/lazy imports\n\texample\.com/retract/incompatible loaded from example\.com/retract/incompatible@v1\.0\.0,\n\tbut go 1\.16 would select v2\.0\.0\+incompatible\n\n' -stderr '\n\nTo upgrade to the versions selected by go 1\.16:\n\tgo mod tidy -go=1\.16 && go mod tidy -go=1\.17\nIf reproducibility with go 1\.16 is not needed:\n\tgo mod tidy -compat=1.17\nFor other options, see:\n\thttps://golang\.org/wiki/PruningModules\n' +stderr '\n\nTo upgrade to the versions selected by go 1\.16:\n\tgo mod tidy -go=1\.16 && go mod tidy -go=1\.17\nIf reproducibility with go 1\.16 is not needed:\n\tgo mod tidy -compat=1.17\nFor other options, see:\n\thttps://golang\.org/doc/modules/pruning\n' cmp go.mod go.mod.orig From 0941dbca6ae805dd7b5f7871d5811b7b7f14f77f Mon Sep 17 00:00:00 2001 From: "Matt T. Proud" Date: Wed, 14 Jul 2021 22:42:31 +0200 Subject: [PATCH 21/49] testing: clarify in docs that TestMain is advanced Beginner and intermediate Go users periodically use TestMain when requirements do not necessitate TestMain (exceeding least-mechanism design). This commit expands package testing's documentation to convey that the TestMain feature itself is somewhat low-level and potentially unsuitable for casual testing where ordinary test functions would suffice. Fixes #42161 Updates #44200 Change-Id: I91ba0b048c3d6f79110fe8f0fbb58d896edca366 Reviewed-on: https://go-review.googlesource.com/c/go/+/334649 Trust: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Go Bot Reviewed-by: Rob Pike --- src/testing/testing.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/testing/testing.go b/src/testing/testing.go index eeee0aac17..681f99ef93 100644 --- a/src/testing/testing.go +++ b/src/testing/testing.go @@ -233,6 +233,8 @@ // os.Exit(m.Run()) // } // +// TestMain is a low-level primitive and should not be necessary for casual +// testing needs, where ordinary test functions suffice. package testing import ( From aa4e0f528e1e018e2847decb549cfc5ac07ecf20 Mon Sep 17 00:00:00 2001 From: shota3506 Date: Tue, 13 Jul 2021 21:27:05 +0000 Subject: [PATCH 22/49] net/http: correct capitalization in cancelTimeBody comment Change-Id: I7acda22c01c5350ebf5ddabb1c12af96d368de5d GitHub-Last-Rev: 3e5c022f8764d4abf91c964ceb4fc0e01ebd1352 GitHub-Pull-Request: golang/go#47160 Reviewed-on: https://go-review.googlesource.com/c/go/+/334229 Reviewed-by: Ian Lance Taylor Trust: Cherry Mui Run-TryBot: Ian Lance Taylor --- src/net/http/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net/http/client.go b/src/net/http/client.go index e0cabc9d4c..4d380c65db 100644 --- a/src/net/http/client.go +++ b/src/net/http/client.go @@ -951,7 +951,7 @@ func (c *Client) CloseIdleConnections() { } // cancelTimerBody is an io.ReadCloser that wraps rc with two features: -// 1) on Read error or close, the stop func is called. +// 1) On Read error or close, the stop func is called. // 2) On Read failure, if reqDidTimeout is true, the error is wrapped and // marked as net.Error that hit its timeout. type cancelTimerBody struct { From 650fc2117aaffbc4d596dc35cc88400ba11b2f25 Mon Sep 17 00:00:00 2001 From: mehradsadeghi <2012.linkinpark@gmail.com> Date: Fri, 16 Jul 2021 21:25:28 +0000 Subject: [PATCH 23/49] text/scanner: use Go convention in Position doc comment Change-Id: Ib872f139af7bfb0a75cc21dace5358fe8fcf2cf0 GitHub-Last-Rev: 8fd5ab01fab3bc1d7701092f31071d07ab79acc5 GitHub-Pull-Request: golang/go#47250 Reviewed-on: https://go-review.googlesource.com/c/go/+/335149 Reviewed-by: Robert Griesemer Reviewed-by: Ian Lance Taylor Trust: Robert Griesemer --- src/text/scanner/scanner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/text/scanner/scanner.go b/src/text/scanner/scanner.go index e0847a7239..c5fc4ff93b 100644 --- a/src/text/scanner/scanner.go +++ b/src/text/scanner/scanner.go @@ -23,7 +23,7 @@ import ( "unicode/utf8" ) -// A source position is represented by a Position value. +// Position is a value that represents a source position. // A position is valid if Line > 0. type Position struct { Filename string // filename, if any From a66190eceeea63aab0b5410ae3222454e5e0cd96 Mon Sep 17 00:00:00 2001 From: nimelehin Date: Fri, 16 Jul 2021 20:41:21 +0000 Subject: [PATCH 24/49] test/bench/go1: fix size for RegexpMatchMedium_32 Change-Id: Idc67abb95248bc010820a89dd6096a2da334e723 GitHub-Last-Rev: ae9014b011efb2692f853888c1860920d1acc3cb GitHub-Pull-Request: golang/go#47254 Reviewed-on: https://go-review.googlesource.com/c/go/+/335189 Reviewed-by: Rob Pike Run-TryBot: Rob Pike TryBot-Result: Go Bot Trust: Alberto Donizetti --- test/bench/go1/regexp_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/bench/go1/regexp_test.go b/test/bench/go1/regexp_test.go index 3ce9f3a2c6..dd1034fde5 100644 --- a/test/bench/go1/regexp_test.go +++ b/test/bench/go1/regexp_test.go @@ -53,7 +53,7 @@ func BenchmarkRegexpMatchEasy0_32(b *testing.B) { benchmark(b, easy0, 32<<0) } func BenchmarkRegexpMatchEasy0_1K(b *testing.B) { benchmark(b, easy0, 1<<10) } func BenchmarkRegexpMatchEasy1_32(b *testing.B) { benchmark(b, easy1, 32<<0) } func BenchmarkRegexpMatchEasy1_1K(b *testing.B) { benchmark(b, easy1, 1<<10) } -func BenchmarkRegexpMatchMedium_32(b *testing.B) { benchmark(b, medium, 1<<0) } +func BenchmarkRegexpMatchMedium_32(b *testing.B) { benchmark(b, medium, 32<<0) } func BenchmarkRegexpMatchMedium_1K(b *testing.B) { benchmark(b, medium, 1<<10) } func BenchmarkRegexpMatchHard_32(b *testing.B) { benchmark(b, hard, 32<<0) } func BenchmarkRegexpMatchHard_1K(b *testing.B) { benchmark(b, hard, 1<<10) } From 49402bee36fd3d5cee9f4b2d2e1e8560ead0203b Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Thu, 15 Jul 2021 16:29:36 -0400 Subject: [PATCH 25/49] cmd/{compile,link}: fix bug in map.zero handling In CL 326211 a change was made to switch "go.map.zero" symbols from non-pkg DUPOK symbols to hashed symbols. The intent of this change was ensure that in cases where there are multiple competing go.map.zero symbols feeding into a link, the largest map.zero symbol is selected. The change was buggy, however, and resulted in duplicate symbols in the final binary (see bug cited below for details). This duplication was relatively benign for linux/ELF, but causes duplicate definition errors on Windows. This patch switches "go.map.zero" symbols back from hashed symbols to non-pkg DUPOK symbols, and updates the relevant code in the loader to ensure that we do the right thing when there are multiple competing DUPOK symbols with different sizes. Fixes #47185. Change-Id: I8aeb910c65827f5380144d07646006ba553c9251 Reviewed-on: https://go-review.googlesource.com/c/go/+/334930 Trust: Than McIntosh Run-TryBot: Than McIntosh TryBot-Result: Go Bot Reviewed-by: Cherry Mui --- src/cmd/compile/internal/gc/obj.go | 2 +- src/cmd/link/internal/loader/loader.go | 9 +++ test/fixedbugs/issue47185.dir/bad/bad.go | 72 ++++++++++++++++++++++++ test/fixedbugs/issue47185.dir/main.go | 28 +++++++++ test/fixedbugs/issue47185.go | 11 ++++ 5 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 test/fixedbugs/issue47185.dir/bad/bad.go create mode 100644 test/fixedbugs/issue47185.dir/main.go create mode 100644 test/fixedbugs/issue47185.go diff --git a/src/cmd/compile/internal/gc/obj.go b/src/cmd/compile/internal/gc/obj.go index 55a0ab7da7..474d718525 100644 --- a/src/cmd/compile/internal/gc/obj.go +++ b/src/cmd/compile/internal/gc/obj.go @@ -148,7 +148,7 @@ func dumpdata() { if reflectdata.ZeroSize > 0 { zero := base.PkgLinksym("go.map", "zero", obj.ABI0) objw.Global(zero, int32(reflectdata.ZeroSize), obj.DUPOK|obj.RODATA) - zero.Set(obj.AttrContentAddressable, true) + zero.Set(obj.AttrStatic, true) } staticdata.WriteFuncSyms() diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go index efca824d98..9d5319c312 100644 --- a/src/cmd/link/internal/loader/loader.go +++ b/src/cmd/link/internal/loader/loader.go @@ -459,6 +459,15 @@ func (st *loadState) addSym(name string, ver int, r *oReader, li uint32, kind in if l.flags&FlagStrictDups != 0 { l.checkdup(name, r, li, oldi) } + // Fix for issue #47185 -- given two dupok symbols with + // different sizes, favor symbol with larger size. See + // also issue #46653. + szdup := l.SymSize(oldi) + sz := int64(r.Sym(li).Siz()) + if szdup < sz { + // new symbol overwrites old symbol. + l.objSyms[oldi] = objSym{r.objidx, li} + } return oldi } oldr, oldli := l.toLocal(oldi) diff --git a/test/fixedbugs/issue47185.dir/bad/bad.go b/test/fixedbugs/issue47185.dir/bad/bad.go new file mode 100644 index 0000000000..1aa4fbb909 --- /dev/null +++ b/test/fixedbugs/issue47185.dir/bad/bad.go @@ -0,0 +1,72 @@ +// 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 a + +// Note that the use of CGO here is solely to trigger external +// linking, since that is required to trigger that bad behavior +// in this bug. + +// #include +import "C" + +func Bad() { + m := make(map[int64]A) + a := m[0] + if len(a.B.C1.D2.E2.F1) != 0 || + len(a.B.C1.D2.E2.F2) != 0 || + len(a.B.C1.D2.E2.F3) != 0 || + len(a.B.C1.D2.E2.F4) != 0 || + len(a.B.C1.D2.E2.F5) != 0 || + len(a.B.C1.D2.E2.F6) != 0 || + len(a.B.C1.D2.E2.F7) != 0 || + len(a.B.C1.D2.E2.F8) != 0 || + len(a.B.C1.D2.E2.F9) != 0 || + len(a.B.C1.D2.E2.F10) != 0 || + len(a.B.C1.D2.E2.F11) != 0 || + len(a.B.C1.D2.E2.F16) != 0 { + panic("bad") + } + C.malloc(100) +} + +type A struct { + B +} + +type B struct { + C1 C + C2 C +} + +type C struct { + D1 D + D2 D +} + +type D struct { + E1 E + E2 E + E3 E + E4 E +} + +type E struct { + F1 string + F2 string + F3 string + F4 string + F5 string + F6 string + F7 string + F8 string + F9 string + F10 string + F11 string + F12 string + F13 string + F14 string + F15 string + F16 string +} diff --git a/test/fixedbugs/issue47185.dir/main.go b/test/fixedbugs/issue47185.dir/main.go new file mode 100644 index 0000000000..7b46e55d8b --- /dev/null +++ b/test/fixedbugs/issue47185.dir/main.go @@ -0,0 +1,28 @@ +// 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 ( + bad "issue47185.dir/bad" +) + +func main() { + another() + bad.Bad() +} + +func another() L { + m := make(map[string]L) + return m[""] +} + +type L struct { + A Data + B Data +} + +type Data struct { + F1 [22][]string +} diff --git a/test/fixedbugs/issue47185.go b/test/fixedbugs/issue47185.go new file mode 100644 index 0000000000..9c921b8698 --- /dev/null +++ b/test/fixedbugs/issue47185.go @@ -0,0 +1,11 @@ +// +build cgo +// runindir + +// 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. + +// Another test to verify compiler and linker handling of multiple +// competing map.zero symbol definitions. + +package ignored From 6298cfe6724e3ca24dedd3f62b2b358aafe17276 Mon Sep 17 00:00:00 2001 From: Leonard Wang Date: Sun, 11 Jul 2021 11:46:26 +0800 Subject: [PATCH 26/49] cmd/compile: fix typo in fatal message of builtinCall Change-Id: I523d5fd810b82154a204670d46fc250a0fc66791 Reviewed-on: https://go-review.googlesource.com/c/go/+/333849 Reviewed-by: Ian Lance Taylor Reviewed-by: Matthew Dempsky Run-TryBot: Ian Lance Taylor TryBot-Result: Go Bot --- src/cmd/compile/internal/typecheck/iimport.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd/compile/internal/typecheck/iimport.go b/src/cmd/compile/internal/typecheck/iimport.go index a5ddbb5a74..37f5a7bba0 100644 --- a/src/cmd/compile/internal/typecheck/iimport.go +++ b/src/cmd/compile/internal/typecheck/iimport.go @@ -1540,7 +1540,7 @@ func (r *importReader) exprsOrNil() (a, b ir.Node) { func builtinCall(pos src.XPos, op ir.Op) *ir.CallExpr { if go117ExportTypes { // These should all be encoded as direct ops, not OCALL. - base.Fatalf("builtinCall should not be invoked when types are included in inport/export") + base.Fatalf("builtinCall should not be invoked when types are included in import/export") } return ir.NewCallExpr(pos, ir.OCALL, ir.NewIdent(base.Pos, types.BuiltinPkg.Lookup(ir.OpNames[op])), nil) } From 404127c30f3f66eb234da2dc1a78e6eea0ef4ee0 Mon Sep 17 00:00:00 2001 From: Cherry Mui Date: Wed, 14 Jul 2021 18:52:44 -0400 Subject: [PATCH 27/49] cmd/compile: fix off-by-one error in traceback argument counting For traceback argument printing, we want to print at most 10 words, then print "..." if there are still more args and/or fields. The current code has off-by-one error that for 11 non-aggregate typed args, it prints the first 10 but without the "...". Also, for aggregate-typed args, in some cases it may print an extra "..." when there is actually no more fields. The problem for this is that visitType return false (meaning not to continue visiting) if it reaches the limit anywhere during the recursive visit. It doesn't distinguish whether it has printed anything for the current arg. If it reaches the limit before it prints anything, it means that we're visiting the extra arg/field, so the caller should print "..." and stop. If it prints something then reaches the limit, however, the caller should keep going, and only print "..." at the next iteration when there is actually an extra arg/field. This CL does so. Fixes #47159. Change-Id: I93fc25b73ada2b5a98df780c45e5b0c9565dc2fc Reviewed-on: https://go-review.googlesource.com/c/go/+/334710 Trust: Cherry Mui Run-TryBot: Cherry Mui TryBot-Result: Go Bot Reviewed-by: Michael Knyszek --- src/cmd/compile/internal/ssagen/ssa.go | 43 +++--- src/runtime/traceback_test.go | 179 ++++++++++++++++++++++++- 2 files changed, 190 insertions(+), 32 deletions(-) diff --git a/src/cmd/compile/internal/ssagen/ssa.go b/src/cmd/compile/internal/ssagen/ssa.go index f1dc56e729..a5cb0857b3 100644 --- a/src/cmd/compile/internal/ssagen/ssa.go +++ b/src/cmd/compile/internal/ssagen/ssa.go @@ -6598,6 +6598,7 @@ func EmitArgInfo(f *ir.Func, abiInfo *abi.ABIParamResultInfo) *obj.LSym { x := base.Ctxt.Lookup(fmt.Sprintf("%s.arginfo%d", f.LSym.Name, f.ABI)) PtrSize := int64(types.PtrSize) + uintptrTyp := types.Types[types.TUINTPTR] isAggregate := func(t *types.Type) bool { return t.IsStruct() || t.IsArray() || t.IsComplex() || t.IsInterface() || t.IsString() || t.IsSlice() @@ -6641,12 +6642,8 @@ func EmitArgInfo(f *ir.Func, abiInfo *abi.ABIParamResultInfo) *obj.LSym { n := 0 writebyte := func(o uint8) { wOff = objw.Uint8(x, wOff, o) } - // Write one non-aggrgate arg/field/element if there is room. - // Returns whether to continue. - write1 := func(sz, offset int64) bool { - if n >= limit { - return false - } + // Write one non-aggrgate arg/field/element. + write1 := func(sz, offset int64) { if offset >= _special { writebyte(_offsetTooLarge) } else { @@ -6654,7 +6651,6 @@ func EmitArgInfo(f *ir.Func, abiInfo *abi.ABIParamResultInfo) *obj.LSym { writebyte(uint8(sz)) } n++ - return true } // Visit t recursively and write it out. @@ -6662,10 +6658,12 @@ func EmitArgInfo(f *ir.Func, abiInfo *abi.ABIParamResultInfo) *obj.LSym { var visitType func(baseOffset int64, t *types.Type, depth int) bool visitType = func(baseOffset int64, t *types.Type, depth int) bool { if n >= limit { + writebyte(_dotdotdot) return false } if !isAggregate(t) { - return write1(t.Size(), baseOffset) + write1(t.Size(), baseOffset) + return true } writebyte(_startAgg) depth++ @@ -6675,58 +6673,47 @@ func EmitArgInfo(f *ir.Func, abiInfo *abi.ABIParamResultInfo) *obj.LSym { n++ return true } - var r bool switch { case t.IsInterface(), t.IsString(): - r = write1(PtrSize, baseOffset) && - write1(PtrSize, baseOffset+PtrSize) + _ = visitType(baseOffset, uintptrTyp, depth) && + visitType(baseOffset+PtrSize, uintptrTyp, depth) case t.IsSlice(): - r = write1(PtrSize, baseOffset) && - write1(PtrSize, baseOffset+PtrSize) && - write1(PtrSize, baseOffset+PtrSize*2) + _ = visitType(baseOffset, uintptrTyp, depth) && + visitType(baseOffset+PtrSize, uintptrTyp, depth) && + visitType(baseOffset+PtrSize*2, uintptrTyp, depth) case t.IsComplex(): - r = write1(t.Size()/2, baseOffset) && - write1(t.Size()/2, baseOffset+t.Size()/2) + _ = visitType(baseOffset, types.FloatForComplex(t), depth) && + visitType(baseOffset+t.Size()/2, types.FloatForComplex(t), depth) case t.IsArray(): - r = true if t.NumElem() == 0 { n++ // {} counts as a component break } for i := int64(0); i < t.NumElem(); i++ { if !visitType(baseOffset, t.Elem(), depth) { - r = false break } baseOffset += t.Elem().Size() } case t.IsStruct(): - r = true if t.NumFields() == 0 { n++ // {} counts as a component break } for _, field := range t.Fields().Slice() { if !visitType(baseOffset+field.Offset, field.Type, depth) { - r = false break } } } - if !r { - writebyte(_dotdotdot) - } writebyte(_endAgg) - return r + return true } - c := true for _, a := range abiInfo.InParams() { - if !c { - writebyte(_dotdotdot) + if !visitType(a.FrameOffset(abiInfo), a.Type, 0) { break } - c = visitType(a.FrameOffset(abiInfo), a.Type, 0) } writebyte(_endSeq) if wOff > maxLen { diff --git a/src/runtime/traceback_test.go b/src/runtime/traceback_test.go index 2a0497e9a9..83b86a7e90 100644 --- a/src/runtime/traceback_test.go +++ b/src/runtime/traceback_test.go @@ -19,8 +19,8 @@ func TestTracebackArgs(t *testing.T) { }{ // simple ints { - func() int { return testTracebackArgs1(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) }, - "testTracebackArgs1(0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, ...)", + func() int { return testTracebackArgs1(1, 2, 3, 4, 5) }, + "testTracebackArgs1(0x1, 0x2, 0x3, 0x4, 0x5)", }, // some aggregates { @@ -53,6 +53,58 @@ func TestTracebackArgs(t *testing.T) { }, "testTracebackArgs5(0x0, {0x1, {}, {{}, {}}}, {}, {}, {}, {}, {}, ...)", }, + + // edge cases for ... + // no ... for 10 args + { + func() int { return testTracebackArgs6a(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) }, + "testTracebackArgs6a(0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa)", + }, + // has ... for 11 args + { + func() int { return testTracebackArgs6b(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) }, + "testTracebackArgs6b(0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, ...)", + }, + // no ... for aggregates with 10 words + { + func() int { return testTracebackArgs7a([10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) }, + "testTracebackArgs7a({0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa})", + }, + // has ... for aggregates with 11 words + { + func() int { return testTracebackArgs7b([11]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}) }, + "testTracebackArgs7b({0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, ...})", + }, + // no ... for aggregates, but with more args + { + func() int { return testTracebackArgs7c([10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 11) }, + "testTracebackArgs7c({0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa}, ...)", + }, + // has ... for aggregates and also for more args + { + func() int { return testTracebackArgs7d([11]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 12) }, + "testTracebackArgs7d({0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, ...}, ...)", + }, + // nested aggregates, no ... + { + func() int { return testTracebackArgs8a(testArgsType8a{1, 2, 3, 4, 5, 6, 7, 8, [2]int{9, 10}}) }, + "testTracebackArgs8a({0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, {0x9, 0xa}})", + }, + // nested aggregates, ... in inner but not outer + { + func() int { return testTracebackArgs8b(testArgsType8b{1, 2, 3, 4, 5, 6, 7, 8, [3]int{9, 10, 11}}) }, + "testTracebackArgs8b({0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, {0x9, 0xa, ...}})", + }, + // nested aggregates, ... in outer but not inner + { + func() int { return testTracebackArgs8c(testArgsType8c{1, 2, 3, 4, 5, 6, 7, 8, [2]int{9, 10}, 11}) }, + "testTracebackArgs8c({0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, {0x9, 0xa}, ...})", + }, + // nested aggregates, ... in both inner and outer + { + func() int { return testTracebackArgs8d(testArgsType8d{1, 2, 3, 4, 5, 6, 7, 8, [3]int{9, 10, 11}, 12}) }, + "testTracebackArgs8d({0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, {0x9, 0xa, ...}, ...})", + }, } for _, test := range tests { n := test.fn() @@ -64,11 +116,11 @@ func TestTracebackArgs(t *testing.T) { } //go:noinline -func testTracebackArgs1(a, b, c, d, e, f, g, h, i, j, k, l int) int { +func testTracebackArgs1(a, b, c, d, e int) int { n := runtime.Stack(testTracebackArgsBuf[:], false) if a < 0 { // use in-reg args to keep them alive - return a + b + c + d + e + f + g + h + i + j + k + l + return a + b + c + d + e } return n } @@ -119,3 +171,122 @@ func testTracebackArgs5(a bool, x struct { } return n } + +//go:noinline +func testTracebackArgs6a(a, b, c, d, e, f, g, h, i, j int) int { + n := runtime.Stack(testTracebackArgsBuf[:], false) + if a < 0 { + // use in-reg args to keep them alive + return a + b + c + d + e + f + g + h + i + j + } + return n +} + +//go:noinline +func testTracebackArgs6b(a, b, c, d, e, f, g, h, i, j, k int) int { + n := runtime.Stack(testTracebackArgsBuf[:], false) + if a < 0 { + // use in-reg args to keep them alive + return a + b + c + d + e + f + g + h + i + j + k + } + return n +} + +//go:noinline +func testTracebackArgs7a(a [10]int) int { + n := runtime.Stack(testTracebackArgsBuf[:], false) + if a[0] < 0 { + // use in-reg args to keep them alive + return a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9] + } + return n +} + +//go:noinline +func testTracebackArgs7b(a [11]int) int { + n := runtime.Stack(testTracebackArgsBuf[:], false) + if a[0] < 0 { + // use in-reg args to keep them alive + return a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9] + a[10] + } + return n +} + +//go:noinline +func testTracebackArgs7c(a [10]int, b int) int { + n := runtime.Stack(testTracebackArgsBuf[:], false) + if a[0] < 0 { + // use in-reg args to keep them alive + return a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9] + b + } + return n +} + +//go:noinline +func testTracebackArgs7d(a [11]int, b int) int { + n := runtime.Stack(testTracebackArgsBuf[:], false) + if a[0] < 0 { + // use in-reg args to keep them alive + return a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9] + a[10] + b + } + return n +} + +type testArgsType8a struct { + a, b, c, d, e, f, g, h int + i [2]int +} +type testArgsType8b struct { + a, b, c, d, e, f, g, h int + i [3]int +} +type testArgsType8c struct { + a, b, c, d, e, f, g, h int + i [2]int + j int +} +type testArgsType8d struct { + a, b, c, d, e, f, g, h int + i [3]int + j int +} + +//go:noinline +func testTracebackArgs8a(a testArgsType8a) int { + n := runtime.Stack(testTracebackArgsBuf[:], false) + if a.a < 0 { + // use in-reg args to keep them alive + return a.b + a.c + a.d + a.e + a.f + a.g + a.h + a.i[0] + a.i[1] + } + return n +} + +//go:noinline +func testTracebackArgs8b(a testArgsType8b) int { + n := runtime.Stack(testTracebackArgsBuf[:], false) + if a.a < 0 { + // use in-reg args to keep them alive + return a.b + a.c + a.d + a.e + a.f + a.g + a.h + a.i[0] + a.i[1] + a.i[2] + } + return n +} + +//go:noinline +func testTracebackArgs8c(a testArgsType8c) int { + n := runtime.Stack(testTracebackArgsBuf[:], false) + if a.a < 0 { + // use in-reg args to keep them alive + return a.b + a.c + a.d + a.e + a.f + a.g + a.h + a.i[0] + a.i[1] + a.j + } + return n +} + +//go:noinline +func testTracebackArgs8d(a testArgsType8d) int { + n := runtime.Stack(testTracebackArgsBuf[:], false) + if a.a < 0 { + // use in-reg args to keep them alive + return a.b + a.c + a.d + a.e + a.f + a.g + a.h + a.i[0] + a.i[1] + a.i[2] + a.j + } + return n +} From 1d91551b7326383343c7c143a8ac299d0a685289 Mon Sep 17 00:00:00 2001 From: helloPiers Date: Mon, 19 Jul 2021 20:08:50 +0000 Subject: [PATCH 28/49] time: correct typo in documentation for UnixMicro Fixes #47283. Change-Id: Ibdc35433d22be3caa70197b6a95c66999812a16a GitHub-Last-Rev: 75962b029467a5e26e1ee78a38bf01c954445ea1 GitHub-Pull-Request: golang/go#47284 Reviewed-on: https://go-review.googlesource.com/c/go/+/335549 Reviewed-by: Ian Lance Taylor Trust: Than McIntosh --- src/time/time.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/time/time.go b/src/time/time.go index 1cf1e2bbf6..4ecc3d82dc 100644 --- a/src/time/time.go +++ b/src/time/time.go @@ -1334,7 +1334,7 @@ func UnixMilli(msec int64) Time { } // UnixMicro returns the local Time corresponding to the given Unix time, -// usec milliseconds since January 1, 1970 UTC. +// usec microseconds since January 1, 1970 UTC. func UnixMicro(usec int64) Time { return Unix(usec/1e6, (usec%1e6)*1e3) } From c8f4e6152d5f0b767a8177b7d09884cf2279d8e6 Mon Sep 17 00:00:00 2001 From: Piers Date: Mon, 19 Jul 2021 20:11:29 +0000 Subject: [PATCH 29/49] spec: correct example comment in Conversions from slice to array Fixes #47280 Change-Id: I78a8d235949b4878c7f075ac4ca37700e7e6c31c GitHub-Last-Rev: 067f96eeb2c918eb4f775c428edc945c75af44d8 GitHub-Pull-Request: golang/go#47282 Reviewed-on: https://go-review.googlesource.com/c/go/+/335470 Reviewed-by: Robert Griesemer Trust: Robert Griesemer Trust: Than McIntosh --- doc/go_spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/go_spec.html b/doc/go_spec.html index ad21ffb1b8..df256f0f0e 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -4334,7 +4334,7 @@ s4 := (*[4]byte)(s) // panics: len([4]byte) > len(s) var t []string t0 := (*[0]string)(t) // t0 == nil -t1 := (*[1]string)(t) // panics: len([1]string) > len(s) +t1 := (*[1]string)(t) // panics: len([1]string) > len(t)

Constant expressions

From d568e6e075e6434635268d3caf55963f4e564579 Mon Sep 17 00:00:00 2001 From: Benny Siegert Date: Tue, 20 Jul 2021 09:36:08 -0400 Subject: [PATCH 30/49] runtime/debug: skip TestPanicOnFault on netbsd/arm This test has been failing since the builder was updated to NetBSD 9. While the issue is under investigation, skip the test so that we do not miss other breakage. Update issue #45026 Change-Id: Id083901c517f3f88e6b4bc2b51208f65170d47a6 Reviewed-on: https://go-review.googlesource.com/c/go/+/335909 Reviewed-by: Than McIntosh Reviewed-by: Keith Randall Trust: Benny Siegert Run-TryBot: Benny Siegert TryBot-Result: Go Bot --- src/runtime/debug/panic_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/runtime/debug/panic_test.go b/src/runtime/debug/panic_test.go index b93631e1d8..65f9555f37 100644 --- a/src/runtime/debug/panic_test.go +++ b/src/runtime/debug/panic_test.go @@ -24,6 +24,9 @@ func TestPanicOnFault(t *testing.T) { if runtime.GOOS == "ios" { t.Skip("iOS doesn't provide fault addresses") } + if runtime.GOOS == "netbsd" && runtime.GOARCH == "arm" { + t.Skip("netbsd-arm doesn't provide fault address (golang.org/issue/45026)") + } m, err := syscall.Mmap(-1, 0, 0x1000, syscall.PROT_READ /* Note: no PROT_WRITE */, syscall.MAP_SHARED|syscall.MAP_ANON) if err != nil { t.Fatalf("can't map anonymous memory: %s", err) From 9e26569293c13974d210fd588ebfd29b857d8525 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sun, 18 Jul 2021 13:58:13 -0700 Subject: [PATCH 31/49] cmd/go: don't add C compiler ID to hash for standard library No test because a real test requires installing two different compilers. For #40042 For #47251 Change-Id: Iefddd67830d242a119378b7ce20be481904806e4 Reviewed-on: https://go-review.googlesource.com/c/go/+/335409 Trust: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Go Bot Reviewed-by: Bryan C. Mills Reviewed-by: Jay Conrod --- src/cmd/go/go_test.go | 32 ++++++++++++++++++++++++++++++++ src/cmd/go/internal/work/exec.go | 11 +++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go index c0c86ab9f5..6ce276537b 100644 --- a/src/cmd/go/go_test.go +++ b/src/cmd/go/go_test.go @@ -2848,3 +2848,35 @@ func TestExecInDeletedDir(t *testing.T) { // `go version` should not fail tg.run("version") } + +// A missing C compiler should not force the net package to be stale. +// Issue 47215. +func TestMissingCC(t *testing.T) { + if !canCgo { + t.Skip("test is only meaningful on systems with cgo") + } + cc := os.Getenv("CC") + if cc == "" { + cc = "gcc" + } + if filepath.IsAbs(cc) { + t.Skipf(`"CC" (%s) is an absolute path`, cc) + } + _, err := exec.LookPath(cc) + if err != nil { + t.Skipf(`"CC" (%s) not on PATH`, cc) + } + + tg := testgo(t) + defer tg.cleanup() + netStale, _ := tg.isStale("net") + if netStale { + t.Skip(`skipping test because "net" package is currently stale`) + } + + tg.setenv("PATH", "") // No C compiler on PATH. + netStale, _ = tg.isStale("net") + if netStale { + t.Error(`clearing "PATH" causes "net" to be stale`) + } +} diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go index b506b83656..5a225fb9f1 100644 --- a/src/cmd/go/internal/work/exec.go +++ b/src/cmd/go/internal/work/exec.go @@ -252,8 +252,15 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID { ccExe := b.ccExe() fmt.Fprintf(h, "CC=%q %q %q %q\n", ccExe, cppflags, cflags, ldflags) - if ccID, err := b.gccToolID(ccExe[0], "c"); err == nil { - fmt.Fprintf(h, "CC ID=%q\n", ccID) + // Include the C compiler tool ID so that if the C + // compiler changes we rebuild the package. + // But don't do that for standard library packages like net, + // so that the prebuilt .a files from a Go binary install + // don't need to be rebuilt with the local compiler. + if !p.Standard { + if ccID, err := b.gccToolID(ccExe[0], "c"); err == nil { + fmt.Fprintf(h, "CC ID=%q\n", ccID) + } } if len(p.CXXFiles)+len(p.SwigCXXFiles) > 0 { cxxExe := b.cxxExe() From 48c88f1b1bac1ef4fc81246a7f31933f8f922706 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 14 Jul 2021 14:46:09 -0700 Subject: [PATCH 32/49] reflect: add Value.CanConvert For #395 For #46746 Change-Id: I4bfc094cf1cecd27ce48e31f92384cf470f371a6 Reviewed-on: https://go-review.googlesource.com/c/go/+/334669 Trust: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Go Bot Reviewed-by: Keith Randall Reviewed-by: Joe Tsai --- api/go1.17.txt | 1 + doc/go1.17.html | 12 ++++++++++++ src/reflect/all_test.go | 9 +++++++++ src/reflect/value.go | 20 ++++++++++++++++++++ 4 files changed, 42 insertions(+) diff --git a/api/go1.17.txt b/api/go1.17.txt index 3d0a464fec..48505381f1 100644 --- a/api/go1.17.txt +++ b/api/go1.17.txt @@ -80,6 +80,7 @@ pkg net/url, method (Values) Has(string) bool pkg reflect, func VisibleFields(Type) []StructField pkg reflect, method (Method) IsExported() bool pkg reflect, method (StructField) IsExported() bool +pkg reflect, method (Value) CanConvert(Type) bool pkg runtime/cgo (darwin-amd64-cgo), func NewHandle(interface{}) Handle pkg runtime/cgo (darwin-amd64-cgo), method (Handle) Delete() pkg runtime/cgo (darwin-amd64-cgo), method (Handle) Value() interface{} diff --git a/doc/go1.17.html b/doc/go1.17.html index b31006fe65..7739d1c62e 100644 --- a/doc/go1.17.html +++ b/doc/go1.17.html @@ -989,6 +989,18 @@ func Foo() bool {
reflect
+

+ The new + Value.CanConvert + method reports whether a value can be converted to a type. + This may be used to avoid a panic when converting a slice to an + array pointer type if the slice is too short. + Previously it was sufficient to use + Type.ConvertibleTo + for this, but the newly permitted conversion from slice to array + pointer type can panic even if the types are convertible. +

+

The new StructField.IsExported diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go index 0db5e13217..eac27e886f 100644 --- a/src/reflect/all_test.go +++ b/src/reflect/all_test.go @@ -4304,6 +4304,9 @@ func TestConvert(t *testing.T) { // vout1 represents the in value converted to the in type. v1 := tt.in + if !v1.CanConvert(t1) { + t.Errorf("ValueOf(%T(%[1]v)).CanConvert(%s) = false, want true", tt.in.Interface(), t1) + } vout1 := v1.Convert(t1) out1 := vout1.Interface() if vout1.Type() != tt.in.Type() || !DeepEqual(out1, tt.in.Interface()) { @@ -4311,6 +4314,9 @@ func TestConvert(t *testing.T) { } // vout2 represents the in value converted to the out type. + if !v1.CanConvert(t2) { + t.Errorf("ValueOf(%T(%[1]v)).CanConvert(%s) = false, want true", tt.in.Interface(), t2) + } vout2 := v1.Convert(t2) out2 := vout2.Interface() if vout2.Type() != tt.out.Type() || !DeepEqual(out2, tt.out.Interface()) { @@ -4371,6 +4377,9 @@ func TestConvertPanic(t *testing.T) { if !v.Type().ConvertibleTo(pt) { t.Errorf("[]byte should be convertible to *[8]byte") } + if v.CanConvert(pt) { + t.Errorf("slice with length 4 should not be convertible to *[8]byte") + } shouldPanic("reflect: cannot convert slice with length 4 to pointer to array with length 8", func() { _ = v.Convert(pt) }) diff --git a/src/reflect/value.go b/src/reflect/value.go index 9dce251ac5..6f878eba5b 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -2811,6 +2811,26 @@ func (v Value) Convert(t Type) Value { return op(v, t) } +// CanConvert reports whether the value v can be converted to type t. +// If v.CanConvert(t) returns true then v.Convert(t) will not panic. +func (v Value) CanConvert(t Type) bool { + vt := v.Type() + if !vt.ConvertibleTo(t) { + return false + } + // Currently the only conversion that is OK in terms of type + // but that can panic depending on the value is converting + // from slice to pointer-to-array. + if vt.Kind() == Slice && t.Kind() == Ptr && t.Elem().Kind() == Array { + n := t.Elem().Len() + h := (*unsafeheader.Slice)(v.ptr) + if n > h.Len { + return false + } + } + return true +} + // convertOp returns the function to convert a value of type src // to a value of type dst. If the conversion is illegal, convertOp returns nil. func convertOp(dst, src *rtype) func(Value, Type) Value { From 3e48c0381fd1beb78e993e940c3b46ca9898ce6d Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Wed, 21 Jul 2021 11:59:45 +0800 Subject: [PATCH 33/49] reflect: add missing copyright header Change-Id: I5a2f7203f83be02b03aa7be5fe386e485bf68ca3 Reviewed-on: https://go-review.googlesource.com/c/go/+/336189 Reviewed-by: Ian Lance Taylor Trust: Robert Findley --- src/reflect/visiblefields.go | 4 ++++ src/reflect/visiblefields_test.go | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/reflect/visiblefields.go b/src/reflect/visiblefields.go index c068979dcc..1a2b53570b 100644 --- a/src/reflect/visiblefields.go +++ b/src/reflect/visiblefields.go @@ -1,3 +1,7 @@ +// 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 reflect // VisibleFields returns all the visible fields in t, which must be a diff --git a/src/reflect/visiblefields_test.go b/src/reflect/visiblefields_test.go index 2688b63091..915bbee867 100644 --- a/src/reflect/visiblefields_test.go +++ b/src/reflect/visiblefields_test.go @@ -1,3 +1,7 @@ +// 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 reflect_test import ( From fdb45acd1f062884c77ea6961fb638e004af1b8e Mon Sep 17 00:00:00 2001 From: David Chase Date: Wed, 21 Jul 2021 18:38:05 -0400 Subject: [PATCH 34/49] runtime: move mem profile sampling into m-acquired section It was not safe to do mcache profiling updates outside the critical section, but we got lucky because the runtime was not preemptible. Adding chunked memory clearing (CL 270943) created preemption opportunities, which led to corruption of runtime data structures. Fixes #47304. Fixes #47302. Change-Id: I461615470d62328a83ccbac537fbdc6dcde81c85 Reviewed-on: https://go-review.googlesource.com/c/go/+/336449 Trust: David Chase Run-TryBot: David Chase TryBot-Result: Go Bot Reviewed-by: Austin Clements Reviewed-by: Keith Randall --- src/runtime/malloc.go | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go index 2759bbdaf9..cc22b0f276 100644 --- a/src/runtime/malloc.go +++ b/src/runtime/malloc.go @@ -1135,13 +1135,21 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer { msanmalloc(x, size) } + if rate := MemProfileRate; rate > 0 { + // Note cache c only valid while m acquired; see #47302 + if rate != 1 && size < c.nextSample { + c.nextSample -= size + } else { + profilealloc(mp, x, size) + } + } mp.mallocing = 0 releasem(mp) // Pointerfree data can be zeroed late in a context where preemption can occur. // x will keep the memory alive. if !isZeroed && needzero { - memclrNoHeapPointersChunked(size, x) + memclrNoHeapPointersChunked(size, x) // This is a possible preemption point: see #47302 } if debug.malloc { @@ -1155,16 +1163,6 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer { } } - if rate := MemProfileRate; rate > 0 { - if rate != 1 && size < c.nextSample { - c.nextSample -= size - } else { - mp := acquirem() - profilealloc(mp, x, size) - releasem(mp) - } - } - if assistG != nil { // Account for internal fragmentation in the assist // debt now that we know it. From 798ec73519a7226d6d436e42498a54aed23b8468 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 21 Jul 2021 19:57:56 -0700 Subject: [PATCH 35/49] runtime: don't clear timerModifiedEarliest if adjustTimers is 0 This avoids a race when a new timerModifiedEarlier timer is created by a different goroutine. Fixes #47329 Change-Id: I6f6c87b4a9b5491b201c725c10bc98e23e0ed9d1 Reviewed-on: https://go-review.googlesource.com/c/go/+/336432 Trust: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Go Bot Reviewed-by: Michael Knyszek --- src/runtime/runtime2.go | 2 +- src/runtime/time.go | 5 ----- src/time/sleep_test.go | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go index 2a66826f34..8a15787382 100644 --- a/src/runtime/runtime2.go +++ b/src/runtime/runtime2.go @@ -681,7 +681,7 @@ type p struct { // timerModifiedEarlier status. Because the timer may have been // modified again, there need not be any timer with this value. // This is updated using atomic functions. - // This is 0 if the value is unknown. + // This is 0 if there are no timerModifiedEarlier timers. timerModifiedEarliest uint64 // Per-P GC state diff --git a/src/runtime/time.go b/src/runtime/time.go index dee6a674e4..7b84d2af57 100644 --- a/src/runtime/time.go +++ b/src/runtime/time.go @@ -668,11 +668,6 @@ func adjusttimers(pp *p, now int64) { if verifyTimers { verifyTimerHeap(pp) } - // There are no timers to adjust, so it is safe to clear - // timerModifiedEarliest. Do so in case it is stale. - // Everything will work if we don't do this, - // but clearing here may save future calls to adjusttimers. - atomic.Store64(&pp.timerModifiedEarliest, 0) return } diff --git a/src/time/sleep_test.go b/src/time/sleep_test.go index 6ee0631a85..e0172bf5e0 100644 --- a/src/time/sleep_test.go +++ b/src/time/sleep_test.go @@ -527,6 +527,40 @@ func TestZeroTimer(t *testing.T) { } } +// Test that rapidly moving a timer earlier doesn't cause it to get dropped. +// Issue 47329. +func TestTimerModifiedEarlier(t *testing.T) { + past := Until(Unix(0, 0)) + count := 1000 + fail := 0 + for i := 0; i < count; i++ { + timer := NewTimer(Hour) + for j := 0; j < 10; j++ { + if !timer.Stop() { + <-timer.C + } + timer.Reset(past) + } + + deadline := NewTimer(10 * Second) + defer deadline.Stop() + now := Now() + select { + case <-timer.C: + if since := Since(now); since > 8*Second { + t.Errorf("timer took too long (%v)", since) + fail++ + } + case <-deadline.C: + t.Error("deadline expired") + } + } + + if fail > 0 { + t.Errorf("%d failures", fail) + } +} + // Benchmark timer latency when the thread that creates the timer is busy with // other work and the timers must be serviced by other threads. // https://golang.org/issue/38860 From 052da5717e02659da49707873b3868fe36f2aaf0 Mon Sep 17 00:00:00 2001 From: Cherry Mui Date: Thu, 22 Jul 2021 12:42:09 -0400 Subject: [PATCH 36/49] cmd/compile: do not change field offset in ABI analysis Currently, the ABI analysis assigns parameter/result offsets to the fields of function *Type. In some cases, we may have an ABI0 function reference and an ABIInternal reference share the same function *Type. For example, for an ABI0 function F, "f := F" will make f and (ABI0) F having the same *Type. But f, as a func value, should use ABIInternal. Analyses on F and f will collide and cause ICE. Also, changing field offsets in ABI analysis has to be done very carefully to avoid data races. It has been causing trickiness/difficulty. This CL removes the change of field offsets in ABI analysis altogether. The analysis result is stored in ABIParamAssignment, which is the only way to access parameter/result stack offset now. Fixes #47317. Fixes #47227. Change-Id: I23a3e081a6cf327ac66855da222daaa636ed1ead Reviewed-on: https://go-review.googlesource.com/c/go/+/336629 Trust: Cherry Mui Reviewed-by: Cuong Manh Le Reviewed-by: Than McIntosh --- src/cmd/compile/internal/abi/abiutils.go | 21 +++------------------ src/cmd/compile/internal/ssagen/ssa.go | 11 +++++++---- test/fixedbugs/issue47317.dir/a.s | 6 ++++++ test/fixedbugs/issue47317.dir/x.go | 17 +++++++++++++++++ test/fixedbugs/issue47317.go | 7 +++++++ 5 files changed, 40 insertions(+), 22 deletions(-) create mode 100644 test/fixedbugs/issue47317.dir/a.s create mode 100644 test/fixedbugs/issue47317.dir/x.go create mode 100644 test/fixedbugs/issue47317.go diff --git a/src/cmd/compile/internal/abi/abiutils.go b/src/cmd/compile/internal/abi/abiutils.go index b8ea1955d1..d657ddc867 100644 --- a/src/cmd/compile/internal/abi/abiutils.go +++ b/src/cmd/compile/internal/abi/abiutils.go @@ -446,35 +446,20 @@ func (config *ABIConfig) ABIAnalyze(t *types.Type, setNname bool) *ABIParamResul return result } -// parameterUpdateMu protects the Offset field of function/method parameters (a subset of structure Fields) -var parameterUpdateMu sync.Mutex - -// FieldOffsetOf returns a concurrency-safe version of f.Offset -func FieldOffsetOf(f *types.Field) int64 { - parameterUpdateMu.Lock() - defer parameterUpdateMu.Unlock() - return f.Offset -} - func (config *ABIConfig) updateOffset(result *ABIParamResultInfo, f *types.Field, a ABIParamAssignment, isReturn, setNname bool) { // Everything except return values in registers has either a frame home (if not in a register) or a frame spill location. if !isReturn || len(a.Registers) == 0 { // The type frame offset DOES NOT show effects of minimum frame size. // Getting this wrong breaks stackmaps, see liveness/plive.go:WriteFuncMap and typebits/typebits.go:Set - parameterUpdateMu.Lock() - defer parameterUpdateMu.Unlock() off := a.FrameOffset(result) fOffset := f.Offset if fOffset == types.BOGUS_FUNARG_OFFSET { - // Set the Offset the first time. After that, we may recompute it, but it should never change. - f.Offset = off - if f.Nname != nil { - // always set it in this case. + if setNname && f.Nname != nil { f.Nname.(*ir.Name).SetFrameOffset(off) f.Nname.(*ir.Name).SetIsOutputParamInRegisters(false) } - } else if fOffset != off { - base.Fatalf("offset for %s at %s changed from %d to %d", f.Sym.Name, base.FmtPos(f.Pos), fOffset, off) + } else { + base.Fatalf("field offset for %s at %s has been set to %d", f.Sym.Name, base.FmtPos(f.Pos), fOffset) } } else { if setNname && f.Nname != nil { diff --git a/src/cmd/compile/internal/ssagen/ssa.go b/src/cmd/compile/internal/ssagen/ssa.go index a5cb0857b3..dfa76006de 100644 --- a/src/cmd/compile/internal/ssagen/ssa.go +++ b/src/cmd/compile/internal/ssagen/ssa.go @@ -1296,7 +1296,7 @@ func (s *state) instrumentFields(t *types.Type, addr *ssa.Value, kind instrument if f.Sym.IsBlank() { continue } - offptr := s.newValue1I(ssa.OpOffPtr, types.NewPtr(f.Type), abi.FieldOffsetOf(f), addr) + offptr := s.newValue1I(ssa.OpOffPtr, types.NewPtr(f.Type), f.Offset, addr) s.instrumentFields(f.Type, offptr, kind) } } @@ -5053,19 +5053,23 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val ft := fn.Type() off := t.FieldOff(12) // TODO register args: be sure this isn't a hardcoded param stack offset. args := n.Args + i0 := 0 // Set receiver (for interface calls). Always a pointer. if rcvr != nil { p := s.newValue1I(ssa.OpOffPtr, ft.Recv().Type.PtrTo(), off, addr) s.store(types.Types[types.TUINTPTR], p, rcvr) + i0 = 1 } // Set receiver (for method calls). if n.Op() == ir.OCALLMETH { base.Fatalf("OCALLMETH missed by walkCall") } // Set other args. - for _, f := range ft.Params().Fields().Slice() { - s.storeArgWithBase(args[0], f.Type, addr, off+abi.FieldOffsetOf(f)) + // This code is only used when RegabiDefer is not enabled, and arguments are always + // passed on stack. + for i, f := range ft.Params().Fields().Slice() { + s.storeArgWithBase(args[0], f.Type, addr, off+params.InParam(i+i0).FrameOffset(params)) args = args[1:] } @@ -5078,7 +5082,6 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val if stksize < int64(types.PtrSize) { // We need room for both the call to deferprocStack and the call to // the deferred function. - // TODO(register args) Revisit this if/when we pass args in registers. stksize = int64(types.PtrSize) } call.AuxInt = stksize diff --git a/test/fixedbugs/issue47317.dir/a.s b/test/fixedbugs/issue47317.dir/a.s new file mode 100644 index 0000000000..b969ddb972 --- /dev/null +++ b/test/fixedbugs/issue47317.dir/a.s @@ -0,0 +1,6 @@ +// 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. + +TEXT ·G(SB),4,$0 + RET diff --git a/test/fixedbugs/issue47317.dir/x.go b/test/fixedbugs/issue47317.dir/x.go new file mode 100644 index 0000000000..83b5542144 --- /dev/null +++ b/test/fixedbugs/issue47317.dir/x.go @@ -0,0 +1,17 @@ +// 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. + +// Issue 47317: ICE when calling ABI0 function via func value. + +package main + +func main() { F() } + +func F() interface{} { + g := G + g(1) + return G +} + +func G(x int) [2]int diff --git a/test/fixedbugs/issue47317.go b/test/fixedbugs/issue47317.go new file mode 100644 index 0000000000..3548e90d02 --- /dev/null +++ b/test/fixedbugs/issue47317.go @@ -0,0 +1,7 @@ +// builddir + +// 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 ignored From 0914646ab91a3157666d845d74d8d9a4a2831e1e Mon Sep 17 00:00:00 2001 From: Alberto Donizetti Date: Fri, 23 Jul 2021 18:45:41 +0200 Subject: [PATCH 37/49] doc/1.17: fix two dead rfc links Updates #44513 Change-Id: Ia0c6b48bde2719f3a99cb216b6166d82159198d1 Reviewed-on: https://go-review.googlesource.com/c/go/+/336930 Trust: Alberto Donizetti Reviewed-by: Ian Lance Taylor --- doc/go1.17.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/go1.17.html b/doc/go1.17.html index 7739d1c62e..48811e6b67 100644 --- a/doc/go1.17.html +++ b/doc/go1.17.html @@ -886,8 +886,8 @@ func Foo() bool {

The new method IP.IsPrivate reports whether an address is - a private IPv4 address according to RFC 1918 - or a local IPv6 address according RFC 4193. + a private IPv4 address according to RFC 1918 + or a local IPv6 address according RFC 4193.

From 849b7911293c3cb11d76ff2778ed560100f987d1 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 24 Jul 2021 16:53:02 -0700 Subject: [PATCH 38/49] spec: use consistent capitalization for rune literal hex constants Fixes #47368 Change-Id: I2f65c0008658532123f04d08e99e5d083f33461a Reviewed-on: https://go-review.googlesource.com/c/go/+/337234 Trust: Ian Lance Taylor Trust: Robert Griesemer Reviewed-by: Emmanuel Odeke Reviewed-by: Robert Griesemer --- doc/go_spec.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/go_spec.html b/doc/go_spec.html index df256f0f0e..cc7ed6a561 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -1,6 +1,6 @@ @@ -490,8 +490,8 @@ After a backslash, certain single-character escapes represent special values: \n U+000A line feed or newline \r U+000D carriage return \t U+0009 horizontal tab -\v U+000b vertical tab -\\ U+005c backslash +\v U+000B vertical tab +\\ U+005C backslash \' U+0027 single quote (valid escape only within rune literals) \" U+0022 double quote (valid escape only within string literals) From 1868f8296eb15d11c45c2c7c1d373b211f745d84 Mon Sep 17 00:00:00 2001 From: Dmitri Shuralyov Date: Sun, 25 Jul 2021 21:04:33 -0400 Subject: [PATCH 39/49] crypto/x509: update iOS bundled roots to version 55188.120.1.0.1 Updates #38843. Change-Id: I6e003ed03cd13d8ecf86ce05ab0e11c47e271c0b Reviewed-on: https://go-review.googlesource.com/c/go/+/337329 Trust: Dmitri Shuralyov Run-TryBot: Dmitri Shuralyov TryBot-Result: Go Bot Reviewed-by: Filippo Valsorda --- src/crypto/x509/root.go | 2 +- src/crypto/x509/root_ios.go | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/crypto/x509/root.go b/src/crypto/x509/root.go index cc53f7aefc..eef9c047b2 100644 --- a/src/crypto/x509/root.go +++ b/src/crypto/x509/root.go @@ -8,7 +8,7 @@ package x509 // argument to the latest security_certificates version from // https://opensource.apple.com/source/security_certificates/ // and run "go generate". See https://golang.org/issue/38843. -//go:generate go run root_ios_gen.go -version 55188.40.9 +//go:generate go run root_ios_gen.go -version 55188.120.1.0.1 import "sync" diff --git a/src/crypto/x509/root_ios.go b/src/crypto/x509/root_ios.go index 50432f3d2c..9bc62f8abb 100644 --- a/src/crypto/x509/root_ios.go +++ b/src/crypto/x509/root_ios.go @@ -1,4 +1,4 @@ -// Code generated by root_ios_gen.go -version 55188.40.9; DO NOT EDIT. +// Code generated by root_ios_gen.go -version 55188.120.1.0.1; DO NOT EDIT. // Update the version in root.go and regenerate with "go generate". //go:build ios && !x509omitbundledroots @@ -2223,6 +2223,41 @@ uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs ewv4n4Q= -----END CERTIFICATE----- +# "GlobalSign" +# 2C AB EA FE 37 D0 6C A2 2A BA 73 91 C0 03 3D 25 +# 98 29 52 C4 53 64 73 49 76 3A 3A B5 AD 6C CF 69 +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg +MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx +MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET +MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI +xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k +ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD +aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw +LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw +1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX +k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 +SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h +bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n +WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY +rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce +MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu +bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN +nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt +Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 +55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj +vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf +cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz +oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp +nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs +pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v +JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R +8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 +5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= +-----END CERTIFICATE----- # "GlobalSign Root CA" # EB D4 10 40 E4 BB 3E C7 42 C9 E3 81 D3 1E F2 A4 # 1A 48 B6 68 5C 96 E7 CE F3 C1 DF 6C D4 33 1C 99 From ecaa6816bfdbcef2ad749958a11a321de5c2ebd8 Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Sat, 24 Jul 2021 18:34:16 +0700 Subject: [PATCH 40/49] doc: clarify non-nil zero length slice to array pointer conversion There is an example for nil slice already, so adding example for non-nil zero length slice, too, clarifying to the reader that the result is also non-nil and different from nil slice case. Updates #395 Change-Id: I019db1b1a1c0c621161ecaaacab5a4d888764b1a Reviewed-on: https://go-review.googlesource.com/c/go/+/336890 Trust: Cuong Manh Le Trust: Robert Griesemer Run-TryBot: Cuong Manh Le TryBot-Result: Go Bot Reviewed-by: Robert Griesemer --- doc/go_spec.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/go_spec.html b/doc/go_spec.html index cc7ed6a561..0e14a1f3b6 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -1,6 +1,6 @@ @@ -4335,6 +4335,9 @@ s4 := (*[4]byte)(s) // panics: len([4]byte) > len(s) var t []string t0 := (*[0]string)(t) // t0 == nil t1 := (*[1]string)(t) // panics: len([1]string) > len(t) + +u := make([]byte, 0) +u0 = (*[0]byte)(u) // u0 != nil

Constant expressions

From 9c81fd53b3ae52e286d3020ee8b381328b6b9bd2 Mon Sep 17 00:00:00 2001 From: 180909 <734461790@qq.com> Date: Sun, 25 Jul 2021 11:21:14 +0000 Subject: [PATCH 41/49] cmd/vet: add missing copyright header Change-Id: I78942dde77547f91daebe763328f52b4c476ddaf GitHub-Last-Rev: 423f1683fc7db8c1764383cf0a61c54ee21c06f2 GitHub-Pull-Request: golang/go#47334 Reviewed-on: https://go-review.googlesource.com/c/go/+/336434 Reviewed-by: Ian Lance Taylor Trust: Than McIntosh --- src/cmd/vet/main.go | 4 ++++ src/cmd/vet/testdata/copylock/copylock.go | 4 ++++ src/cmd/vet/testdata/httpresponse/httpresponse.go | 4 ++++ src/cmd/vet/testdata/testingpkg/tests.go | 4 ++++ src/cmd/vet/testdata/testingpkg/tests_test.go | 4 ++++ 5 files changed, 20 insertions(+) diff --git a/src/cmd/vet/main.go b/src/cmd/vet/main.go index a33bba2466..7da8606ece 100644 --- a/src/cmd/vet/main.go +++ b/src/cmd/vet/main.go @@ -1,3 +1,7 @@ +// Copyright 2012 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 ( diff --git a/src/cmd/vet/testdata/copylock/copylock.go b/src/cmd/vet/testdata/copylock/copylock.go index 8079cf3248..7cfafe6408 100644 --- a/src/cmd/vet/testdata/copylock/copylock.go +++ b/src/cmd/vet/testdata/copylock/copylock.go @@ -1,3 +1,7 @@ +// Copyright 2018 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 copylock import "sync" diff --git a/src/cmd/vet/testdata/httpresponse/httpresponse.go b/src/cmd/vet/testdata/httpresponse/httpresponse.go index 6141f6e06d..98e394a271 100644 --- a/src/cmd/vet/testdata/httpresponse/httpresponse.go +++ b/src/cmd/vet/testdata/httpresponse/httpresponse.go @@ -1,3 +1,7 @@ +// Copyright 2018 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 httpresponse import ( diff --git a/src/cmd/vet/testdata/testingpkg/tests.go b/src/cmd/vet/testdata/testingpkg/tests.go index 69d29d3c6c..8f4674d33c 100644 --- a/src/cmd/vet/testdata/testingpkg/tests.go +++ b/src/cmd/vet/testdata/testingpkg/tests.go @@ -1 +1,5 @@ +// Copyright 2018 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 testdata diff --git a/src/cmd/vet/testdata/testingpkg/tests_test.go b/src/cmd/vet/testdata/testingpkg/tests_test.go index 09bb98d980..815dcc8a95 100644 --- a/src/cmd/vet/testdata/testingpkg/tests_test.go +++ b/src/cmd/vet/testdata/testingpkg/tests_test.go @@ -1,3 +1,7 @@ +// Copyright 2018 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 testdata func Example_BadSuffix() {} // ERROR "Example_BadSuffix has malformed example suffix: BadSuffix" From bfbb288574841f2db2499a580d7bf985a5df4556 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sun, 25 Jul 2021 16:26:13 -0700 Subject: [PATCH 42/49] runtime: remove adjustTimers counter In CL 336432 we changed adjusttimers so that it no longer cleared timerModifiedEarliest if there were no timersModifiedEarlier timers. This caused some Google internal tests to time out, presumably due to the increased contention on timersLock. We can avoid that by simply not skipping the loop in adjusttimers, which lets us safely clear timerModifiedEarliest. And if we don't skip the loop, then there isn't much reason to keep the count of timerModifiedEarlier timers at all. So remove it. The effect will be that for programs that create some timerModifiedEarlier timers and then remove them all, the program will do an occasional additional loop over all the timers. And, programs that have some timerModifiedEarlier timers will always loop over all the timers, without the quicker exit when they have all been seen. But the loops should not occur all that often, due to timerModifiedEarliest. For #47329 Change-Id: I7b244c1244d97b169a3c7fbc8f8a8b115731ddee Reviewed-on: https://go-review.googlesource.com/c/go/+/337309 Trust: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Go Bot Reviewed-by: Michael Pratt --- src/runtime/proc.go | 1 - src/runtime/runtime2.go | 6 ----- src/runtime/time.go | 55 +++++++---------------------------------- 3 files changed, 9 insertions(+), 53 deletions(-) diff --git a/src/runtime/proc.go b/src/runtime/proc.go index 4c92588a66..7bc2a92590 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -4919,7 +4919,6 @@ func (pp *p) destroy() { moveTimers(plocal, pp.timers) pp.timers = nil pp.numTimers = 0 - pp.adjustTimers = 0 pp.deletedTimers = 0 atomic.Store64(&pp.timer0When, 0) unlock(&pp.timersLock) diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go index 8a15787382..5051ec4d3e 100644 --- a/src/runtime/runtime2.go +++ b/src/runtime/runtime2.go @@ -727,12 +727,6 @@ type p struct { // Modified using atomic instructions. numTimers uint32 - // Number of timerModifiedEarlier timers on P's heap. - // This should only be modified while holding timersLock, - // or while the timer status is in a transient state - // such as timerModifying. - adjustTimers uint32 - // Number of timerDeleted timers in P's heap. // Modified using atomic instructions. deletedTimers uint32 diff --git a/src/runtime/time.go b/src/runtime/time.go index 7b84d2af57..666b242316 100644 --- a/src/runtime/time.go +++ b/src/runtime/time.go @@ -333,7 +333,6 @@ func deltimer(t *timer) bool { // Must fetch t.pp before setting status // to timerDeleted. tpp := t.pp.ptr() - atomic.Xadd(&tpp.adjustTimers, -1) if !atomic.Cas(&t.status, timerModifying, timerDeleted) { badTimer() } @@ -510,20 +509,9 @@ loop: tpp := t.pp.ptr() - // Update the adjustTimers field. Subtract one if we - // are removing a timerModifiedEarlier, add one if we - // are adding a timerModifiedEarlier. - adjust := int32(0) - if status == timerModifiedEarlier { - adjust-- - } if newStatus == timerModifiedEarlier { - adjust++ updateTimerModifiedEarliest(tpp, when) } - if adjust != 0 { - atomic.Xadd(&tpp.adjustTimers, adjust) - } // Set the new status of the timer. if !atomic.Cas(&t.status, timerModifying, newStatus) { @@ -591,9 +579,6 @@ func cleantimers(pp *p) { // Move t to the right position. dodeltimer0(pp) doaddtimer(pp, t) - if s == timerModifiedEarlier { - atomic.Xadd(&pp.adjustTimers, -1) - } if !atomic.Cas(&t.status, timerMoving, timerWaiting) { badTimer() } @@ -664,32 +649,23 @@ func moveTimers(pp *p, timers []*timer) { // it also moves timers that have been modified to run later, // and removes deleted timers. The caller must have locked the timers for pp. func adjusttimers(pp *p, now int64) { - if atomic.Load(&pp.adjustTimers) == 0 { + // If we haven't yet reached the time of the first timerModifiedEarlier + // timer, don't do anything. This speeds up programs that adjust + // a lot of timers back and forth if the timers rarely expire. + // We'll postpone looking through all the adjusted timers until + // one would actually expire. + first := atomic.Load64(&pp.timerModifiedEarliest) + if first == 0 || int64(first) > now { if verifyTimers { verifyTimerHeap(pp) } return } - // If we haven't yet reached the time of the first timerModifiedEarlier - // timer, don't do anything. This speeds up programs that adjust - // a lot of timers back and forth if the timers rarely expire. - // We'll postpone looking through all the adjusted timers until - // one would actually expire. - if first := atomic.Load64(&pp.timerModifiedEarliest); first != 0 { - if int64(first) > now { - if verifyTimers { - verifyTimerHeap(pp) - } - return - } - - // We are going to clear all timerModifiedEarlier timers. - atomic.Store64(&pp.timerModifiedEarliest, 0) - } + // We are going to clear all timerModifiedEarlier timers. + atomic.Store64(&pp.timerModifiedEarliest, 0) var moved []*timer -loop: for i := 0; i < len(pp.timers); i++ { t := pp.timers[i] if t.pp.ptr() != pp { @@ -716,11 +692,6 @@ loop: // loop to skip some other timer. dodeltimer(pp, i) moved = append(moved, t) - if s == timerModifiedEarlier { - if n := atomic.Xadd(&pp.adjustTimers, -1); int32(n) <= 0 { - break loop - } - } // Look at this heap position again. i-- } @@ -819,9 +790,6 @@ func runtimer(pp *p, now int64) int64 { t.when = t.nextwhen dodeltimer0(pp) doaddtimer(pp, t) - if s == timerModifiedEarlier { - atomic.Xadd(&pp.adjustTimers, -1) - } if !atomic.Cas(&t.status, timerMoving, timerWaiting) { badTimer() } @@ -916,7 +884,6 @@ func clearDeletedTimers(pp *p) { atomic.Store64(&pp.timerModifiedEarliest, 0) cdel := int32(0) - cearlier := int32(0) to := 0 changedHeap := false timers := pp.timers @@ -941,9 +908,6 @@ nextTimer: if !atomic.Cas(&t.status, timerMoving, timerWaiting) { badTimer() } - if s == timerModifiedEarlier { - cearlier++ - } continue nextTimer } case timerDeleted: @@ -980,7 +944,6 @@ nextTimer: atomic.Xadd(&pp.deletedTimers, -cdel) atomic.Xadd(&pp.numTimers, -cdel) - atomic.Xadd(&pp.adjustTimers, -cearlier) timers = timers[:to] pp.timers = timers From 840e583ff340d22a6263a348922283e6d5cd2e31 Mon Sep 17 00:00:00 2001 From: Koichi Shiraishi Date: Sun, 25 Jul 2021 03:00:04 +0900 Subject: [PATCH 43/49] runtime: correct variable name in comment Change-Id: Ic35ec2ed320c3c266afbeec8bdea1dedac4725e4 Reviewed-on: https://go-review.googlesource.com/c/go/+/336892 Reviewed-by: Ian Lance Taylor Trust: Austin Clements --- src/runtime/race.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/race.go b/src/runtime/race.go index cc8c5db1bd..ce6b5b5468 100644 --- a/src/runtime/race.go +++ b/src/runtime/race.go @@ -343,7 +343,7 @@ func racereadrangepc1(addr, size, pc uintptr) func racewriterangepc1(addr, size, pc uintptr) func racecallbackthunk(uintptr) -// racecall allows calling an arbitrary function f from C race runtime +// racecall allows calling an arbitrary function fn from C race runtime // with up to 4 uintptr arguments. func racecall(fn *byte, arg0, arg1, arg2, arg3 uintptr) From 33ff1559702388c57c45f9e6cd032f06e8c3c163 Mon Sep 17 00:00:00 2001 From: Rob Findley Date: Mon, 26 Jul 2021 16:33:44 -0400 Subject: [PATCH 44/49] go/types: preserve untyped constants on the RHS of a shift expression CL 291316 fixed go/types to verify that untyped shift counts are representable by uint, but as a side effect also converted their types to uint. Rearrange the logic to keep the check for representability, but not actually convert untyped integer constants. Untyped non-integer constants are still converted, to preserve the behavior of 1.16. This behavior for non-integer types is a bug, filed as #47410. Updates #47410 Fixes #47243 Change-Id: I5eab4aab35b97f932fccdee2d4a18623ee2ccad5 Reviewed-on: https://go-review.googlesource.com/c/go/+/337529 Trust: Robert Findley Trust: Robert Griesemer Run-TryBot: Robert Findley TryBot-Result: Go Bot Reviewed-by: Robert Griesemer --- src/go/types/api_test.go | 12 ++++++++++++ src/go/types/check_test.go | 7 +++++++ src/go/types/expr.go | 34 +++++++++++++++++++++++++--------- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/go/types/api_test.go b/src/go/types/api_test.go index f37b91d5a4..f964c656f9 100644 --- a/src/go/types/api_test.go +++ b/src/go/types/api_test.go @@ -322,6 +322,18 @@ func TestTypesInfo(t *testing.T) { `[][]struct{}`, }, + // issue 47243 + {`package issue47243_a; var x int32; var _ = x << 3`, `3`, `untyped int`}, + {`package issue47243_b; var x int32; var _ = x << 3.`, `3.`, `uint`}, // issue 47410: should be untyped float + {`package issue47243_c; var x int32; var _ = 1 << x`, `1 << x`, `int`}, + {`package issue47243_d; var x int32; var _ = 1 << x`, `1`, `int`}, + {`package issue47243_e; var x int32; var _ = 1 << 2`, `1`, `untyped int`}, + {`package issue47243_f; var x int32; var _ = 1 << 2`, `2`, `untyped int`}, + {`package issue47243_g; var x int32; var _ = int(1) << 2`, `2`, `untyped int`}, + {`package issue47243_h; var x int32; var _ = 1 << (2 << x)`, `1`, `int`}, + {`package issue47243_i; var x int32; var _ = 1 << (2 << x)`, `(2 << x)`, `untyped int`}, + {`package issue47243_j; var x int32; var _ = 1 << (2 << x)`, `2`, `untyped int`}, + // tests for broken code that doesn't parse or type-check {broken + `x0; func _() { var x struct {f string}; x.f := 0 }`, `x.f`, `string`}, {broken + `x1; func _() { var z string; type x struct {f string}; y := &x{q: z}}`, `z`, `string`}, diff --git a/src/go/types/check_test.go b/src/go/types/check_test.go index c85a8e46fb..f83abf11ce 100644 --- a/src/go/types/check_test.go +++ b/src/go/types/check_test.go @@ -344,6 +344,13 @@ func TestIssue46453(t *testing.T) { checkFiles(t, nil, "", []string{"issue46453.go"}, [][]byte{[]byte(src)}, false, nil) } +func TestIssue47243_TypedRHS(t *testing.T) { + // The RHS of the shift expression below overflows uint on 32bit platforms, + // but this is OK as it is explicitly typed. + const src = "package issue47243\n\nvar a uint64; var _ = a << uint64(4294967296)" // uint64(1<<32) + checkFiles(t, &StdSizes{4, 4}, "", []string{"p.go"}, [][]byte{[]byte(src)}, false, nil) +} + func TestCheck(t *testing.T) { DefPredeclaredTestFuncs(); testDir(t, "check") } func TestExamples(t *testing.T) { testDir(t, "examples") } func TestFixedbugs(t *testing.T) { testDir(t, "fixedbugs") } diff --git a/src/go/types/expr.go b/src/go/types/expr.go index 5c65fad447..58962e777b 100644 --- a/src/go/types/expr.go +++ b/src/go/types/expr.go @@ -778,32 +778,48 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) { // spec: "The right operand in a shift expression must have integer type // or be an untyped constant representable by a value of type uint." - // Provide a good error message for negative shift counts. + // Check that constants are representable by uint, but do not convert them + // (see also issue #47243). if y.mode == constant_ { + // Provide a good error message for negative shift counts. yval := constant.ToInt(y.val) // consider -1, 1.0, but not -1.1 if yval.Kind() == constant.Int && constant.Sign(yval) < 0 { check.invalidOp(y, _InvalidShiftCount, "negative shift count %s", y) x.mode = invalid return } + + if isUntyped(y.typ) { + // Caution: Check for representability here, rather than in the switch + // below, because isInteger includes untyped integers (was bug #43697). + check.representable(y, Typ[Uint]) + if y.mode == invalid { + x.mode = invalid + return + } + } } - // Caution: Check for isUntyped first because isInteger includes untyped - // integers (was bug #43697). - if isUntyped(y.typ) { + // Check that RHS is otherwise at least of integer type. + switch { + case isInteger(y.typ): + if !isUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) { + check.invalidOp(y, _InvalidShiftCount, "signed shift count %s requires go1.13 or later", y) + x.mode = invalid + return + } + case isUntyped(y.typ): + // This is incorrect, but preserves pre-existing behavior. + // See also bug #47410. check.convertUntyped(y, Typ[Uint]) if y.mode == invalid { x.mode = invalid return } - } else if !isInteger(y.typ) { + default: check.invalidOp(y, _InvalidShiftCount, "shift count %s must be integer", y) x.mode = invalid return - } else if !isUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) { - check.invalidOp(y, _InvalidShiftCount, "signed shift count %s requires go1.13 or later", y) - x.mode = invalid - return } if x.mode == constant_ { From 7ba8e796c91eaf4befcacc4d24127ae54475d6a5 Mon Sep 17 00:00:00 2001 From: Changkun Ou Date: Mon, 26 Jul 2021 15:04:48 +0200 Subject: [PATCH 45/49] testing: clarify T.Name returns a distinct name of the running test According to the discussion, it is clear that T.Name returns a distinct name among all tests. However, there is no specification of how sub-tests with the same specified test name are constructed. This change only clarifies the uniqueness and the components of the name without suggesting any explicit format of the returned name. Fixes #46488 Change-Id: I6cebd419b69fb08d8646cb744a129548452042ef Reviewed-on: https://go-review.googlesource.com/c/go/+/337392 Reviewed-by: Ian Lance Taylor Reviewed-by: Emmanuel Odeke Run-TryBot: Ian Lance Taylor TryBot-Result: Go Bot --- src/testing/testing.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/testing/testing.go b/src/testing/testing.go index 681f99ef93..a19238d31e 100644 --- a/src/testing/testing.go +++ b/src/testing/testing.go @@ -680,7 +680,11 @@ type T struct { func (c *common) private() {} -// Name returns the name of the running test or benchmark. +// Name returns the name of the running (sub-) test or benchmark. +// +// The name will include the name of the test along with the names of +// any nested sub-tests. If two sibling sub-tests have the same name, +// Name will append a suffix to guarantee the returned name is unique. func (c *common) Name() string { return c.name } From c8cf0f74e4a8f078ab5570e76c37621a0daf0309 Mon Sep 17 00:00:00 2001 From: 180909 <734461790@qq.com> Date: Tue, 27 Jul 2021 09:49:55 +0000 Subject: [PATCH 46/49] cmd/go: add missing flag in UsageLine Change-Id: I31689dc8de1f6b95bb35578b20533c63903f7258 GitHub-Last-Rev: 5bfee0535ded703f84d45390d5a87295b6e5fe5a GitHub-Pull-Request: golang/go#47418 Reviewed-on: https://go-review.googlesource.com/c/go/+/337691 Run-TryBot: Jay Conrod TryBot-Result: Go Bot Reviewed-by: Jay Conrod Trust: Jay Conrod Trust: Russ Cox --- src/cmd/go/alldocs.go | 4 ++-- src/cmd/go/internal/modcmd/edit.go | 2 +- src/cmd/go/internal/modcmd/init.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go index 954caae9fb..7f88d3216c 100644 --- a/src/cmd/go/alldocs.go +++ b/src/cmd/go/alldocs.go @@ -1078,7 +1078,7 @@ // // Usage: // -// go mod edit [editing flags] [go.mod] +// go mod edit [editing flags] [-fmt|-print|-json] [go.mod] // // Edit provides a command-line interface for editing go.mod, // for use primarily by tools or scripts. It reads only go.mod; @@ -1204,7 +1204,7 @@ // // Usage: // -// go mod init [module] +// go mod init [module-path] // // Init initializes and writes a new go.mod file in the current directory, in // effect creating a new module rooted at the current directory. The go.mod file diff --git a/src/cmd/go/internal/modcmd/edit.go b/src/cmd/go/internal/modcmd/edit.go index e856e7c630..bb3d521092 100644 --- a/src/cmd/go/internal/modcmd/edit.go +++ b/src/cmd/go/internal/modcmd/edit.go @@ -25,7 +25,7 @@ import ( ) var cmdEdit = &base.Command{ - UsageLine: "go mod edit [editing flags] [go.mod]", + UsageLine: "go mod edit [editing flags] [-fmt|-print|-json] [go.mod]", Short: "edit go.mod from tools or scripts", Long: ` Edit provides a command-line interface for editing go.mod, diff --git a/src/cmd/go/internal/modcmd/init.go b/src/cmd/go/internal/modcmd/init.go index 73cc282d81..958c3066ac 100644 --- a/src/cmd/go/internal/modcmd/init.go +++ b/src/cmd/go/internal/modcmd/init.go @@ -13,7 +13,7 @@ import ( ) var cmdInit = &base.Command{ - UsageLine: "go mod init [module]", + UsageLine: "go mod init [module-path]", Short: "initialize new module in current directory", Long: ` Init initializes and writes a new go.mod file in the current directory, in From 7cd10c1149e51a9d2f0868babaf66b8091b9c0b9 Mon Sep 17 00:00:00 2001 From: Jay Conrod Date: Tue, 27 Jul 2021 10:22:35 -0700 Subject: [PATCH 47/49] cmd/go: use .mod instead of .zip to determine if version has go.mod file When checking for updates, the go command checks whether the highest compatible version has a go.mod file in order to determine whether +incompatible versions may be considered "latest". Previously, to perform this check, the go command would download the content of the module (the .zip file) to see whether a go.mod file was present at the root. This is slower than necessary, and it caused 'go list -m -u' to try to save the sum for the .zip file in go.sum in some cases. With this change, the go command only downloads the .mod file and checks whether it appears to be a fake file generated for a version that didn't have a go.mod file. This is faster and requires less verification. Fake files only have a "module" directive. It's possible to commit a file that passes this test, but it would be difficult to do accidentally: Go 1.12 and later at least add a "go" directive. A false positive here would cause version queries to have slightly different results but would not affect builds. Fixes #47377 Change-Id: Ie5ffd0b45e39bd0921328a60af99a9f6e5ab6346 Reviewed-on: https://go-review.googlesource.com/c/go/+/337850 Trust: Jay Conrod Run-TryBot: Jay Conrod TryBot-Result: Go Bot Reviewed-by: Michael Matloob --- src/cmd/go/internal/modfetch/coderepo.go | 23 ++--- src/cmd/go/internal/modload/modfile.go | 83 ++++++++++--------- src/cmd/go/internal/modload/query.go | 30 +++++-- .../script/mod_update_sum_readonly.txt | 34 ++++++++ 4 files changed, 114 insertions(+), 56 deletions(-) create mode 100644 src/cmd/go/testdata/script/mod_update_sum_readonly.txt diff --git a/src/cmd/go/internal/modfetch/coderepo.go b/src/cmd/go/internal/modfetch/coderepo.go index f817a04583..dfef9f73c2 100644 --- a/src/cmd/go/internal/modfetch/coderepo.go +++ b/src/cmd/go/internal/modfetch/coderepo.go @@ -864,22 +864,25 @@ func (r *codeRepo) GoMod(version string) (data []byte, err error) { data, err = r.code.ReadFile(rev, path.Join(dir, "go.mod"), codehost.MaxGoMod) if err != nil { if os.IsNotExist(err) { - return r.legacyGoMod(rev, dir), nil + return LegacyGoMod(r.modPath), nil } return nil, err } return data, nil } -func (r *codeRepo) legacyGoMod(rev, dir string) []byte { - // We used to try to build a go.mod reflecting pre-existing - // package management metadata files, but the conversion - // was inherently imperfect (because those files don't have - // exactly the same semantics as go.mod) and, when done - // for dependencies in the middle of a build, impossible to - // correct. So we stopped. - // Return a fake go.mod that simply declares the module path. - return []byte(fmt.Sprintf("module %s\n", modfile.AutoQuote(r.modPath))) +// LegacyGoMod generates a fake go.mod file for a module that doesn't have one. +// The go.mod file contains a module directive and nothing else: no go version, +// no requirements. +// +// We used to try to build a go.mod reflecting pre-existing +// package management metadata files, but the conversion +// was inherently imperfect (because those files don't have +// exactly the same semantics as go.mod) and, when done +// for dependencies in the middle of a build, impossible to +// correct. So we stopped. +func LegacyGoMod(modPath string) []byte { + return []byte(fmt.Sprintf("module %s\n", modfile.AutoQuote(modPath))) } func (r *codeRepo) modPrefix(rev string) string { diff --git a/src/cmd/go/internal/modload/modfile.go b/src/cmd/go/internal/modload/modfile.go index d280945ea6..6145e8b2f0 100644 --- a/src/cmd/go/internal/modload/modfile.go +++ b/src/cmd/go/internal/modload/modfile.go @@ -595,47 +595,14 @@ func rawGoModSummary(m module.Version) (*modFileSummary, error) { } c := rawGoModSummaryCache.Do(m, func() interface{} { summary := new(modFileSummary) - var f *modfile.File - if m.Version == "" { - // m is a replacement module with only a file path. - dir := m.Path - if !filepath.IsAbs(dir) { - dir = filepath.Join(ModRoot(), dir) - } - gomod := filepath.Join(dir, "go.mod") - var data []byte - var err error - if gomodActual, ok := fsys.OverlayPath(gomod); ok { - // Don't lock go.mod if it's part of the overlay. - // On Plan 9, locking requires chmod, and we don't want to modify any file - // in the overlay. See #44700. - data, err = os.ReadFile(gomodActual) - } else { - data, err = lockedfile.Read(gomodActual) - } - if err != nil { - return cached{nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(gomod), err))} - } - f, err = modfile.ParseLax(gomod, data, nil) - if err != nil { - return cached{nil, module.VersionError(m, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err))} - } - } else { - if !semver.IsValid(m.Version) { - // Disallow the broader queries supported by fetch.Lookup. - base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", m.Path, m.Version) - } - - data, err := modfetch.GoMod(m.Path, m.Version) - if err != nil { - return cached{nil, err} - } - f, err = modfile.ParseLax("go.mod", data, nil) - if err != nil { - return cached{nil, module.VersionError(m, fmt.Errorf("parsing go.mod: %v", err))} - } + name, data, err := rawGoModData(m) + if err != nil { + return cached{nil, err} + } + f, err := modfile.ParseLax(name, data, nil) + if err != nil { + return cached{nil, module.VersionError(m, fmt.Errorf("parsing %s: %v", base.ShortPath(name), err))} } - if f.Module != nil { summary.module = f.Module.Mod summary.deprecated = f.Module.Deprecated @@ -671,6 +638,42 @@ func rawGoModSummary(m module.Version) (*modFileSummary, error) { var rawGoModSummaryCache par.Cache // module.Version → rawGoModSummary result +// rawGoModData returns the content of the go.mod file for module m, ignoring +// all replacements that may apply to m. +// +// rawGoModData cannot be used on the Target module. +// +// Unlike rawGoModSummary, rawGoModData does not cache its results in memory. +// Use rawGoModSummary instead unless you specifically need these bytes. +func rawGoModData(m module.Version) (name string, data []byte, err error) { + if m.Version == "" { + // m is a replacement module with only a file path. + dir := m.Path + if !filepath.IsAbs(dir) { + dir = filepath.Join(ModRoot(), dir) + } + gomod := filepath.Join(dir, "go.mod") + if gomodActual, ok := fsys.OverlayPath(gomod); ok { + // Don't lock go.mod if it's part of the overlay. + // On Plan 9, locking requires chmod, and we don't want to modify any file + // in the overlay. See #44700. + data, err = os.ReadFile(gomodActual) + } else { + data, err = lockedfile.Read(gomodActual) + } + if err != nil { + return gomod, nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(gomod), err)) + } + } else { + if !semver.IsValid(m.Version) { + // Disallow the broader queries supported by fetch.Lookup. + base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", m.Path, m.Version) + } + data, err = modfetch.GoMod(m.Path, m.Version) + } + return "go.mod", data, err +} + // queryLatestVersionIgnoringRetractions looks up the latest version of the // module with the given path without considering retracted or excluded // versions. diff --git a/src/cmd/go/internal/modload/query.go b/src/cmd/go/internal/modload/query.go index dda9004a9f..e737ca90fc 100644 --- a/src/cmd/go/internal/modload/query.go +++ b/src/cmd/go/internal/modload/query.go @@ -5,13 +5,13 @@ package modload import ( + "bytes" "context" "errors" "fmt" "io/fs" "os" pathpkg "path" - "path/filepath" "sort" "strings" "sync" @@ -931,14 +931,32 @@ func moduleHasRootPackage(ctx context.Context, m module.Version) (bool, error) { return ok, err } -func versionHasGoMod(ctx context.Context, m module.Version) (bool, error) { - needSum := false - root, _, err := fetch(ctx, m, needSum) +// versionHasGoMod returns whether a version has a go.mod file. +// +// versionHasGoMod fetches the go.mod file (possibly a fake) and true if it +// contains anything other than a module directive with the same path. When a +// module does not have a real go.mod file, the go command acts as if it had one +// that only contained a module directive. Normal go.mod files created after +// 1.12 at least have a go directive. +// +// This function is a heuristic, since it's possible to commit a file that would +// pass this test. However, we only need a heurstic for determining whether +// +incompatible versions may be "latest", which is what this function is used +// for. +// +// This heuristic is useful for two reasons: first, when using a proxy, +// this lets us fetch from the .mod endpoint which is much faster than the .zip +// endpoint. The .mod file is used anyway, even if the .zip file contains a +// go.mod with different content. Second, if we don't fetch the .zip, then +// we don't need to verify it in go.sum. This makes 'go list -m -u' faster +// and simpler. +func versionHasGoMod(_ context.Context, m module.Version) (bool, error) { + _, data, err := rawGoModData(m) if err != nil { return false, err } - fi, err := os.Stat(filepath.Join(root, "go.mod")) - return err == nil && !fi.IsDir(), nil + isFake := bytes.Equal(data, modfetch.LegacyGoMod(m.Path)) + return !isFake, nil } // A versionRepo is a subset of modfetch.Repo that can report information about diff --git a/src/cmd/go/testdata/script/mod_update_sum_readonly.txt b/src/cmd/go/testdata/script/mod_update_sum_readonly.txt new file mode 100644 index 0000000000..41f12e4084 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_update_sum_readonly.txt @@ -0,0 +1,34 @@ +# When finding the latest version of a module, we should not download version +# contents. Previously, we downloaded .zip files to determine whether a real +# .mod file was present in order to decide whether +incompatible versions +# could be "latest". +# +# Verifies #47377. + +# rsc.io/breaker has two versions, neither of which has a .mod file. +go list -m -versions rsc.io/breaker +stdout '^rsc.io/breaker v1.0.0 v2.0.0\+incompatible$' +go mod download rsc.io/breaker@v1.0.0 +! grep '^go' $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v1.0.0.mod +go mod download rsc.io/breaker@v2.0.0+incompatible +! grep '^go' $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v2.0.0+incompatible.mod + +# Delete downloaded .zip files. +go clean -modcache + +# Check for updates. +go list -m -u rsc.io/breaker +stdout '^rsc.io/breaker v1.0.0 \[v2.0.0\+incompatible\]$' + +# We should not have downloaded zips. +! exists $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v1.0.0.zip +! exists $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v2.0.0+incompatible.zip + +-- go.mod -- +module m + +go 1.16 + +require rsc.io/breaker v1.0.0 +-- go.sum -- +rsc.io/breaker v1.0.0/go.mod h1:s5yxDXvD88U1/ESC23I2FK3Lkv4YIKaB1ij/Hbm805g= From b39e0f461c099abf98f5a8c81d58d32d9a765a03 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Tue, 27 Jul 2021 18:30:38 -0700 Subject: [PATCH 48/49] runtime: don't crash on nil pointers in checkptrAlignment Ironically, checkptrAlignment had a latent case of bad pointer arithmetic: if ptr is nil, then `add(ptr, size-1)` might produce an illegal pointer value. The fix is to simply check for nil at the top of checkptrAlignment, and short-circuit if so. This CL also adds a more explicit bounds check in checkptrStraddles, rather than relying on `add(ptr, size-1)` to wrap around. I don't think this is necessary today, but it seems prudent to be careful. Fixes #47430. Change-Id: I5c50b2f7f41415dbebbd803e1b8e7766ca95e1fd Reviewed-on: https://go-review.googlesource.com/c/go/+/338029 Trust: Matthew Dempsky Run-TryBot: Matthew Dempsky TryBot-Result: Go Bot Reviewed-by: Keith Randall --- src/runtime/checkptr.go | 11 +++++-- src/runtime/checkptr_test.go | 1 + src/runtime/testdata/testprog/checkptr.go | 36 ++++++++++++++++++++++- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/runtime/checkptr.go b/src/runtime/checkptr.go index d42950844b..2d4afd5cf6 100644 --- a/src/runtime/checkptr.go +++ b/src/runtime/checkptr.go @@ -7,6 +7,11 @@ package runtime import "unsafe" func checkptrAlignment(p unsafe.Pointer, elem *_type, n uintptr) { + // nil pointer is always suitably aligned (#47430). + if p == nil { + return + } + // Check that (*[n]elem)(p) is appropriately aligned. // Note that we allow unaligned pointers if the types they point to contain // no pointers themselves. See issue 37298. @@ -29,10 +34,12 @@ func checkptrStraddles(ptr unsafe.Pointer, size uintptr) bool { return false } - end := add(ptr, size-1) - if uintptr(end) < uintptr(ptr) { + // Check that add(ptr, size-1) won't overflow. This avoids the risk + // of producing an illegal pointer value (assuming ptr is legal). + if uintptr(ptr) >= -(size - 1) { return true } + end := add(ptr, size-1) // TODO(mdempsky): Detect when [ptr, end] contains Go allocations, // but neither ptr nor end point into one themselves. diff --git a/src/runtime/checkptr_test.go b/src/runtime/checkptr_test.go index 2a5c364e97..d5dd101adb 100644 --- a/src/runtime/checkptr_test.go +++ b/src/runtime/checkptr_test.go @@ -26,6 +26,7 @@ func TestCheckPtr(t *testing.T) { }{ {"CheckPtrAlignmentPtr", "fatal error: checkptr: misaligned pointer conversion\n"}, {"CheckPtrAlignmentNoPtr", ""}, + {"CheckPtrAlignmentNilPtr", ""}, {"CheckPtrArithmetic", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"}, {"CheckPtrArithmetic2", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"}, {"CheckPtrSize", "fatal error: checkptr: converted pointer straddles multiple allocations\n"}, diff --git a/src/runtime/testdata/testprog/checkptr.go b/src/runtime/testdata/testprog/checkptr.go index f76b64ad96..9c5561396e 100644 --- a/src/runtime/testdata/testprog/checkptr.go +++ b/src/runtime/testdata/testprog/checkptr.go @@ -4,11 +4,16 @@ package main -import "unsafe" +import ( + "runtime" + "time" + "unsafe" +) func init() { register("CheckPtrAlignmentNoPtr", CheckPtrAlignmentNoPtr) register("CheckPtrAlignmentPtr", CheckPtrAlignmentPtr) + register("CheckPtrAlignmentNilPtr", CheckPtrAlignmentNilPtr) register("CheckPtrArithmetic", CheckPtrArithmetic) register("CheckPtrArithmetic2", CheckPtrArithmetic2) register("CheckPtrSize", CheckPtrSize) @@ -29,6 +34,35 @@ func CheckPtrAlignmentPtr() { sink2 = (**int64)(unsafe.Pointer(uintptr(p) + 1)) } +// CheckPtrAlignmentNilPtr tests that checkptrAlignment doesn't crash +// on nil pointers (#47430). +func CheckPtrAlignmentNilPtr() { + var do func(int) + do = func(n int) { + // Inflate the stack so runtime.shrinkstack gets called during GC + if n > 0 { + do(n - 1) + } + + var p unsafe.Pointer + _ = (*int)(p) + } + + go func() { + for { + runtime.GC() + } + }() + + go func() { + for i := 0; ; i++ { + do(i % 1024) + } + }() + + time.Sleep(time.Second) +} + func CheckPtrArithmetic() { var x int i := uintptr(unsafe.Pointer(&x)) From 9eee0ed4391942c73157c868a9ddcfdef48982f9 Mon Sep 17 00:00:00 2001 From: Jay Conrod Date: Wed, 28 Jul 2021 11:52:14 -0700 Subject: [PATCH 49/49] cmd/go: fix go.mod file name printed in error messages for replacements This fixes a logic error introduced in CL 337850. Fixes #47444 Change-Id: I6a49c8fc71fdde4ecb7f2e3329ad1f2cd286b7eb Reviewed-on: https://go-review.googlesource.com/c/go/+/338189 Run-TryBot: Jay Conrod TryBot-Result: Go Bot Reviewed-by: Michael Matloob Trust: Jay Conrod --- src/cmd/go/internal/modload/modfile.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cmd/go/internal/modload/modfile.go b/src/cmd/go/internal/modload/modfile.go index 6145e8b2f0..03e02e73b6 100644 --- a/src/cmd/go/internal/modload/modfile.go +++ b/src/cmd/go/internal/modload/modfile.go @@ -652,8 +652,8 @@ func rawGoModData(m module.Version) (name string, data []byte, err error) { if !filepath.IsAbs(dir) { dir = filepath.Join(ModRoot(), dir) } - gomod := filepath.Join(dir, "go.mod") - if gomodActual, ok := fsys.OverlayPath(gomod); ok { + name = filepath.Join(dir, "go.mod") + if gomodActual, ok := fsys.OverlayPath(name); ok { // Don't lock go.mod if it's part of the overlay. // On Plan 9, locking requires chmod, and we don't want to modify any file // in the overlay. See #44700. @@ -662,16 +662,17 @@ func rawGoModData(m module.Version) (name string, data []byte, err error) { data, err = lockedfile.Read(gomodActual) } if err != nil { - return gomod, nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(gomod), err)) + return "", nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(name), err)) } } else { if !semver.IsValid(m.Version) { // Disallow the broader queries supported by fetch.Lookup. base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", m.Path, m.Version) } + name = "go.mod" data, err = modfetch.GoMod(m.Path, m.Version) } - return "go.mod", data, err + return name, data, err } // queryLatestVersionIgnoringRetractions looks up the latest version of the