aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--VERSION4
-rw-r--r--src/cmd/compile/internal/compare/compare.go7
-rw-r--r--src/cmd/go/internal/toolchain/select.go11
-rw-r--r--src/cmd/go/internal/work/security.go19
-rw-r--r--src/cmd/go/testdata/script/build_issue48319.txt7
-rw-r--r--src/cmd/go/testdata/script/build_plugin_reproducible.txt7
-rw-r--r--src/cmd/go/testdata/script/darwin_lto_library_ldflag.txt17
-rw-r--r--src/cmd/go/testdata/script/gotoolchain_issue66175.txt109
-rw-r--r--src/net/dnsclient_unix.go4
-rw-r--r--src/runtime/alg.go2
-rw-r--r--src/runtime/map_test.go80
-rw-r--r--test/fixedbugs/issue67160.go32
12 files changed, 290 insertions, 9 deletions
diff --git a/VERSION b/VERSION
index 90486b0138..e2a3741add 100644
--- a/VERSION
+++ b/VERSION
@@ -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)
+}