diff options
-rw-r--r-- | VERSION | 4 | ||||
-rw-r--r-- | src/cmd/compile/internal/compare/compare.go | 7 | ||||
-rw-r--r-- | src/cmd/go/internal/toolchain/select.go | 11 | ||||
-rw-r--r-- | src/cmd/go/internal/work/security.go | 19 | ||||
-rw-r--r-- | src/cmd/go/testdata/script/build_issue48319.txt | 7 | ||||
-rw-r--r-- | src/cmd/go/testdata/script/build_plugin_reproducible.txt | 7 | ||||
-rw-r--r-- | src/cmd/go/testdata/script/darwin_lto_library_ldflag.txt | 17 | ||||
-rw-r--r-- | src/cmd/go/testdata/script/gotoolchain_issue66175.txt | 109 | ||||
-rw-r--r-- | src/net/dnsclient_unix.go | 4 | ||||
-rw-r--r-- | src/runtime/alg.go | 2 | ||||
-rw-r--r-- | src/runtime/map_test.go | 80 | ||||
-rw-r--r-- | test/fixedbugs/issue67160.go | 32 |
12 files changed, 290 insertions, 9 deletions
@@ -1,2 +1,2 @@ -go1.22.2 -time 2024-03-29T15:27:02Z +go1.22.3 +time 2024-05-01T19:49:47Z diff --git a/src/cmd/compile/internal/compare/compare.go b/src/cmd/compile/internal/compare/compare.go index e165cd67db..cb2f84ef55 100644 --- a/src/cmd/compile/internal/compare/compare.go +++ b/src/cmd/compile/internal/compare/compare.go @@ -148,7 +148,7 @@ func calculateCostForType(t *types.Type) int64 { return EqStructCost(t) case types.TSLICE: // Slices are not comparable. - base.Fatalf("eqStructFieldCost: unexpected slice type") + base.Fatalf("calculateCostForType: unexpected slice type") case types.TARRAY: elemCost := calculateCostForType(t.Elem()) cost = t.NumElem() * elemCost @@ -371,6 +371,11 @@ func eqmem(p, q ir.Node, field int, size int64) ir.Node { } func eqmemfunc(size int64, t *types.Type) (fn *ir.Name, needsize bool) { + if !base.Ctxt.Arch.CanMergeLoads && t.Alignment() < int64(base.Ctxt.Arch.Alignment) && t.Alignment() < t.Size() { + // We can't use larger comparisons if the value might not be aligned + // enough for the larger comparison. See issues 46283 and 67160. + size = 0 + } switch size { case 1, 2, 4, 8, 16: buf := fmt.Sprintf("memequal%d", int(size)*8) diff --git a/src/cmd/go/internal/toolchain/select.go b/src/cmd/go/internal/toolchain/select.go index dcf3be92cc..14a8d3c21d 100644 --- a/src/cmd/go/internal/toolchain/select.go +++ b/src/cmd/go/internal/toolchain/select.go @@ -184,6 +184,13 @@ func Select() { } if gover.Compare(goVers, minVers) > 0 { gotoolchain = "go" + goVers + // Starting with Go 1.21, the first released version has a .0 patch version suffix. + // Don't try to download a language version (sans patch component), such as go1.22. + // Instead, use the first toolchain of that language version, such as 1.22.0. + // See golang.org/issue/62278. + if gover.IsLang(goVers) && gover.Compare(goVers, "1.21") >= 0 { + gotoolchain += ".0" + } gover.Startup.AutoGoVersion = goVers gover.Startup.AutoToolchain = "" // in case we are overriding it for being too old } @@ -312,6 +319,10 @@ func Exec(gotoolchain string) { dir, err := modfetch.Download(context.Background(), m) if err != nil { if errors.Is(err, fs.ErrNotExist) { + toolVers := gover.FromToolchain(gotoolchain) + if gover.IsLang(toolVers) && gover.Compare(toolVers, "1.21") >= 0 { + base.Fatalf("invalid toolchain: %s is a language version but not a toolchain version (%s.x)", gotoolchain, gotoolchain) + } base.Fatalf("download %s for %s/%s: toolchain not available", gotoolchain, runtime.GOOS, runtime.GOARCH) } base.Fatalf("download %s: %v", gotoolchain, err) diff --git a/src/cmd/go/internal/work/security.go b/src/cmd/go/internal/work/security.go index 88504be6cd..568eecd325 100644 --- a/src/cmd/go/internal/work/security.go +++ b/src/cmd/go/internal/work/security.go @@ -145,6 +145,12 @@ var validCompilerFlagsWithNextArg = []string{ "-x", } +var invalidLinkerFlags = []*lazyregexp.Regexp{ + // On macOS this means the linker loads and executes the next argument. + // Have to exclude separately because -lfoo is allowed in general. + re(`-lto_library`), +} + var validLinkerFlags = []*lazyregexp.Regexp{ re(`-F([^@\-].*)`), re(`-l([^@\-].*)`), @@ -235,12 +241,12 @@ var validLinkerFlagsWithNextArg = []string{ func checkCompilerFlags(name, source string, list []string) error { checkOverrides := true - return checkFlags(name, source, list, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides) + return checkFlags(name, source, list, nil, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides) } func checkLinkerFlags(name, source string, list []string) error { checkOverrides := true - return checkFlags(name, source, list, validLinkerFlags, validLinkerFlagsWithNextArg, checkOverrides) + return checkFlags(name, source, list, invalidLinkerFlags, validLinkerFlags, validLinkerFlagsWithNextArg, checkOverrides) } // checkCompilerFlagsForInternalLink returns an error if 'list' @@ -249,7 +255,7 @@ func checkLinkerFlags(name, source string, list []string) error { // external linker). func checkCompilerFlagsForInternalLink(name, source string, list []string) error { checkOverrides := false - if err := checkFlags(name, source, list, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides); err != nil { + if err := checkFlags(name, source, list, nil, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides); err != nil { return err } // Currently the only flag on the allow list that causes problems @@ -262,7 +268,7 @@ func checkCompilerFlagsForInternalLink(name, source string, list []string) error return nil } -func checkFlags(name, source string, list []string, valid []*lazyregexp.Regexp, validNext []string, checkOverrides bool) error { +func checkFlags(name, source string, list []string, invalid, valid []*lazyregexp.Regexp, validNext []string, checkOverrides bool) error { // Let users override rules with $CGO_CFLAGS_ALLOW, $CGO_CFLAGS_DISALLOW, etc. var ( allow *regexp.Regexp @@ -294,6 +300,11 @@ Args: if allow != nil && allow.FindString(arg) == arg { continue Args } + for _, re := range invalid { + if re.FindString(arg) == arg { // must be complete match + goto Bad + } + } for _, re := range valid { if re.FindString(arg) == arg { // must be complete match continue Args diff --git a/src/cmd/go/testdata/script/build_issue48319.txt b/src/cmd/go/testdata/script/build_issue48319.txt index 4543303059..148d8f0ff6 100644 --- a/src/cmd/go/testdata/script/build_issue48319.txt +++ b/src/cmd/go/testdata/script/build_issue48319.txt @@ -4,6 +4,13 @@ [short] skip [!cgo] skip +# This test has problems when run on the LUCI darwin longtest builder, +# which uses a more contemporary Xcode version that is unfriendly to +# reproducible builds (see issue #64947 for the gory details). Note +# that individual developers running "go test cmd/go" on Darwin may +# still run into failures depending on their Xcode version. +[GOOS:darwin] [go-builder] skip + # This test is sensitive to cache invalidation, # so use a separate build cache that we can control. env GOCACHE=$WORK/gocache diff --git a/src/cmd/go/testdata/script/build_plugin_reproducible.txt b/src/cmd/go/testdata/script/build_plugin_reproducible.txt index 5369954859..aa489df728 100644 --- a/src/cmd/go/testdata/script/build_plugin_reproducible.txt +++ b/src/cmd/go/testdata/script/build_plugin_reproducible.txt @@ -1,6 +1,13 @@ [!buildmode:plugin] skip [short] skip +# This test has problems when run on the LUCI darwin longtest builder, +# which uses a more contemporary Xcode version that is unfriendly to +# reproducible builds (see issue #64947 for the gory details). Note +# that individual developers running "go test cmd/go" on Darwin may +# still run into failures depending on their Xcode version. +[GOOS:darwin] [go-builder] skip + go build -trimpath -buildvcs=false -buildmode=plugin -o a.so main.go go build -trimpath -buildvcs=false -buildmode=plugin -o b.so main.go cmp -q a.so b.so diff --git a/src/cmd/go/testdata/script/darwin_lto_library_ldflag.txt b/src/cmd/go/testdata/script/darwin_lto_library_ldflag.txt new file mode 100644 index 0000000000..d7acefdbad --- /dev/null +++ b/src/cmd/go/testdata/script/darwin_lto_library_ldflag.txt @@ -0,0 +1,17 @@ +[!GOOS:darwin] skip +[!cgo] skip + +! go build +stderr 'invalid flag in #cgo LDFLAGS: -lto_library' + +-- go.mod -- +module ldflag + +-- main.go -- +package main + +// #cgo CFLAGS: -flto +// #cgo LDFLAGS: -lto_library bad.dylib +import "C" + +func main() {}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/gotoolchain_issue66175.txt b/src/cmd/go/testdata/script/gotoolchain_issue66175.txt new file mode 100644 index 0000000000..5db4dbf381 --- /dev/null +++ b/src/cmd/go/testdata/script/gotoolchain_issue66175.txt @@ -0,0 +1,109 @@ +env TESTGO_VERSION=go1.14 + +# Clear the path so this test doesn't fail if the system running it\ +# has a binary named go1.21 or go1.22 on its path. +[GOOS:plan9] env path= +[!GOOS:plan9] env PATH= + +# check for invalid toolchain in go.mod +go mod init m +go mod edit -go=1.14 -toolchain=go1.22 +! go version +stderr 'go: invalid toolchain: go1.22 is a language version but not a toolchain version \(go1.22.x\)' + +rm go.mod +go mod init m +go mod edit -go=1.14 -toolchain=go1.21 +! go version +stderr 'go: invalid toolchain: go1.21 is a language version but not a toolchain version \(go1.21.x\)' + +rm go.mod +go mod init m +go mod edit -go=1.14 -toolchain=go1.20 +! go version +stderr 'go: downloading go1.20 ' + + +# check for invalid GOTOOLCHAIN +env GOTOOLCHAIN=go1.14 +go version +stdout 'go1.14' + +env GOTOOLCHAIN=go1.20 +! go version +stderr 'go: downloading go1.20 ' + +env GOTOOLCHAIN=go1.21 +! go version +stderr 'go: invalid toolchain: go1.21 is a language version but not a toolchain version \(go1.21.x\)' + +env GOTOOLCHAIN=go1.22 +! go version +stderr 'go: invalid toolchain: go1.22 is a language version but not a toolchain version \(go1.22.x\)' + +env GOTOOLCHAIN=go1.20+auto +! go version +stderr 'go: downloading go1.20 ' + +env GOTOOLCHAIN=go1.21+auto +! go version +stderr 'go: invalid toolchain: go1.21 is a language version but not a toolchain version \(go1.21.x\)' + +env GOTOOLCHAIN=go1.22+auto +! go version +stderr 'go: invalid toolchain: go1.22 is a language version but not a toolchain version \(go1.22.x\)' + +env GOTOOLCHAIN=go1.21rc3 +! go version +stderr 'go: downloading go1.21rc3 ' + +env GOTOOLCHAIN=go1.22rc2 +! go version +stderr 'go: downloading go1.22rc2 ' + +env GOTOOLCHAIN=go1.66 +! go version +stderr 'go: invalid toolchain: go1.66 is a language version but not a toolchain version \(go1.66.x\)' + +env GOTOOLCHAIN=go1.18beta2 +! go version +stderr 'go: downloading go1.18beta2 ' + +# go1.X is okay for path lookups +env GOTOOLCHAIN=go1.20+path +! go version +stderr 'go: cannot find "go1.20" in PATH' + +env GOTOOLCHAIN=go1.21+path +! go version +stderr 'go: cannot find "go1.21" in PATH' + +env GOTOOLCHAIN=go1.22+path +! go version +stderr 'go: cannot find "go1.22" in PATH' + +# When a toolchain download takes place, download 1.X.0 +env GOTOOLCHAIN=auto +rm go.mod +go mod init m +go mod edit -go=1.300 -toolchain=none +! go version +stderr 'go: downloading go1.300.0 ' + +rm go.mod +go mod init m +go mod edit -go=1.21 -toolchain=none +! go version +stderr 'go: downloading go1.21.0 ' + +rm go.mod +go mod init m +go mod edit -go=1.22 -toolchain=none +! go version +stderr 'go: downloading go1.22.0 ' + +rm go.mod +go mod init m +go mod edit -go=1.15 -toolchain=none +! go version +stderr 'go: downloading go1.15 ' diff --git a/src/net/dnsclient_unix.go b/src/net/dnsclient_unix.go index c291d5eb4f..8b3dd5371a 100644 --- a/src/net/dnsclient_unix.go +++ b/src/net/dnsclient_unix.go @@ -267,7 +267,9 @@ func extractExtendedRCode(p dnsmessage.Parser, hdr dnsmessage.Header) dnsmessage if ahdr.Type == dnsmessage.TypeOPT { return ahdr.ExtendedRCode(hdr.RCode) } - p.SkipAdditional() + if err := p.SkipAdditional(); err != nil { + return hdr.RCode + } } } diff --git a/src/runtime/alg.go b/src/runtime/alg.go index eaf9c91490..ef4f859c23 100644 --- a/src/runtime/alg.go +++ b/src/runtime/alg.go @@ -391,7 +391,7 @@ func alginit() { return } for i := range hashkey { - hashkey[i] = uintptr(rand()) | 1 // make sure these numbers are odd + hashkey[i] = uintptr(bootstrapRand()) | 1 // make sure these numbers are odd } } diff --git a/src/runtime/map_test.go b/src/runtime/map_test.go index 2c51236f16..c29fb933ee 100644 --- a/src/runtime/map_test.go +++ b/src/runtime/map_test.go @@ -8,7 +8,9 @@ import ( "fmt" "internal/abi" "internal/goarch" + "internal/testenv" "math" + "os" "reflect" "runtime" "sort" @@ -1464,3 +1466,81 @@ func TestMapValues(t *testing.T) { } } } + +func computeHash() uintptr { + var v struct{} + return runtime.MemHash(unsafe.Pointer(&v), 0, unsafe.Sizeof(v)) +} + +func subprocessHash(t *testing.T, env string) uintptr { + t.Helper() + + cmd := testenv.CleanCmdEnv(testenv.Command(t, os.Args[0], "-test.run=^TestMemHashGlobalSeed$")) + cmd.Env = append(cmd.Env, "GO_TEST_SUBPROCESS_HASH=1") + if env != "" { + cmd.Env = append(cmd.Env, env) + } + + out, err := cmd.Output() + if err != nil { + t.Fatalf("cmd.Output got err %v want nil", err) + } + + s := strings.TrimSpace(string(out)) + h, err := strconv.ParseUint(s, 10, 64) + if err != nil { + t.Fatalf("Parse output %q got err %v want nil", s, err) + } + return uintptr(h) +} + +// memhash has unique per-process seeds, so hashes should differ across +// processes. +// +// Regression test for https://go.dev/issue/66885. +func TestMemHashGlobalSeed(t *testing.T) { + if os.Getenv("GO_TEST_SUBPROCESS_HASH") != "" { + fmt.Println(computeHash()) + os.Exit(0) + return + } + + testenv.MustHaveExec(t) + + // aeshash and memhashFallback use separate per-process seeds, so test + // both. + t.Run("aes", func(t *testing.T) { + if !*runtime.UseAeshash { + t.Skip("No AES") + } + + h1 := subprocessHash(t, "") + t.Logf("%d", h1) + h2 := subprocessHash(t, "") + t.Logf("%d", h2) + h3 := subprocessHash(t, "") + t.Logf("%d", h3) + + if h1 == h2 && h2 == h3 { + t.Errorf("got duplicate hash %d want unique", h1) + } + }) + + t.Run("noaes", func(t *testing.T) { + env := "" + if *runtime.UseAeshash { + env = "GODEBUG=cpu.aes=off" + } + + h1 := subprocessHash(t, env) + t.Logf("%d", h1) + h2 := subprocessHash(t, env) + t.Logf("%d", h2) + h3 := subprocessHash(t, env) + t.Logf("%d", h3) + + if h1 == h2 && h2 == h3 { + t.Errorf("got duplicate hash %d want unique", h1) + } + }) +} diff --git a/test/fixedbugs/issue67160.go b/test/fixedbugs/issue67160.go new file mode 100644 index 0000000000..be45a61420 --- /dev/null +++ b/test/fixedbugs/issue67160.go @@ -0,0 +1,32 @@ +// run + +// Copyright 2024 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. + +// Test to make sure that we don't try using larger loads for +// generated equality functions on architectures that can't do +// unaligned loads. + +package main + +// T has a big field that wants to be compared with larger loads/stores. +// T is "special" because of the unnamed field, so it needs a generated equality function. +// T is an odd number of bytes in size and has alignment 1. +type T struct { + src [8]byte + _ byte +} + +// U contains 8 copies of T, each at a different %8 alignment. +type U [8]T + +//go:noinline +func f(x, y *U) bool { + return *x == *y +} + +func main() { + var a U + _ = f(&a, &a) +} |