Compare commits

..

2 Commits

Author SHA1 Message Date
Than McIntosh
71aaa8bde1 [dev.inline] merge with master at 894d24d617
Change-Id: I845eec08108c69228ebcba921f8a807a376d3fae
2023-07-07 16:49:15 -04:00
Than McIntosh
3aba453b66 [dev.inline] add back in codereview.cfg
Add back in an appropriately set up codereview.cfg for this work
branch.

Change-Id: I0e9f649da31c6ea1cbf8ddc1d906c20c41248721
Reviewed-on: https://go-review.googlesource.com/c/go/+/507157
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Bypass: Than McIntosh <thanm@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2023-06-29 17:09:13 +00:00
108 changed files with 556 additions and 1075 deletions

View File

@@ -1,2 +0,0 @@
go1.21rc3
time 2023-07-13T19:00:35Z

View File

@@ -219,18 +219,18 @@ pkg log/slog, func Any(string, interface{}) Attr #56345
pkg log/slog, func AnyValue(interface{}) Value #56345
pkg log/slog, func Bool(string, bool) Attr #56345
pkg log/slog, func BoolValue(bool) Value #56345
pkg log/slog, func DebugContext(context.Context, string, ...interface{}) #61200
pkg log/slog, func DebugCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, func Debug(string, ...interface{}) #56345
pkg log/slog, func Default() *Logger #56345
pkg log/slog, func Duration(string, time.Duration) Attr #56345
pkg log/slog, func DurationValue(time.Duration) Value #56345
pkg log/slog, func ErrorContext(context.Context, string, ...interface{}) #61200
pkg log/slog, func ErrorCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, func Error(string, ...interface{}) #56345
pkg log/slog, func Float64(string, float64) Attr #56345
pkg log/slog, func Float64Value(float64) Value #56345
pkg log/slog, func Group(string, ...interface{}) Attr #59204
pkg log/slog, func GroupValue(...Attr) Value #56345
pkg log/slog, func InfoContext(context.Context, string, ...interface{}) #61200
pkg log/slog, func InfoCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, func Info(string, ...interface{}) #56345
pkg log/slog, func Int64(string, int64) Attr #56345
pkg log/slog, func Int64Value(int64) Value #56345
@@ -250,7 +250,7 @@ pkg log/slog, func Time(string, time.Time) Attr #56345
pkg log/slog, func TimeValue(time.Time) Value #56345
pkg log/slog, func Uint64(string, uint64) Attr #56345
pkg log/slog, func Uint64Value(uint64) Value #56345
pkg log/slog, func WarnContext(context.Context, string, ...interface{}) #61200
pkg log/slog, func WarnCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, func Warn(string, ...interface{}) #56345
pkg log/slog, func With(...interface{}) *Logger #56345
pkg log/slog, method (Attr) Equal(Attr) bool #56345
@@ -271,17 +271,17 @@ pkg log/slog, method (*LevelVar) MarshalText() ([]uint8, error) #56345
pkg log/slog, method (*LevelVar) Set(Level) #56345
pkg log/slog, method (*LevelVar) String() string #56345
pkg log/slog, method (*LevelVar) UnmarshalText([]uint8) error #56345
pkg log/slog, method (*Logger) DebugContext(context.Context, string, ...interface{}) #61200
pkg log/slog, method (*Logger) DebugCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, method (*Logger) Debug(string, ...interface{}) #56345
pkg log/slog, method (*Logger) Enabled(context.Context, Level) bool #56345
pkg log/slog, method (*Logger) ErrorContext(context.Context, string, ...interface{}) #61200
pkg log/slog, method (*Logger) ErrorCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, method (*Logger) Error(string, ...interface{}) #56345
pkg log/slog, method (*Logger) Handler() Handler #56345
pkg log/slog, method (*Logger) InfoContext(context.Context, string, ...interface{}) #61200
pkg log/slog, method (*Logger) InfoCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, method (*Logger) Info(string, ...interface{}) #56345
pkg log/slog, method (*Logger) LogAttrs(context.Context, Level, string, ...Attr) #56345
pkg log/slog, method (*Logger) Log(context.Context, Level, string, ...interface{}) #56345
pkg log/slog, method (*Logger) WarnContext(context.Context, string, ...interface{}) #61200
pkg log/slog, method (*Logger) WarnCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, method (*Logger) Warn(string, ...interface{}) #56345
pkg log/slog, method (*Logger) WithGroup(string) *Logger #56345
pkg log/slog, method (*Logger) With(...interface{}) *Logger #56345

View File

@@ -1,2 +1,2 @@
branch: release-branch.go1.21
branch: dev.inline
parent-branch: master

View File

@@ -917,12 +917,6 @@ Do not send CLs removing the interior tags from such phrases.
names, stored as UTF-16, can't be represented as valid UTF-8.
</p>
<p><!-- CL 463177 -->
On Windows <a href="/pkg/os/#Lstat"><code>Lstat</code></a> now resolves
symbolic links for paths ending with a path separator, consistent with its
behavior on POSIX platforms.
</p>
<p><!-- https://go.dev/issue/54451, CL 491175 -->
The implementation of the
<a href="/pkg/io/fs/#DirEntry"><code>io/fs.DirEntry</code></a>

View File

@@ -142,10 +142,6 @@ forms, controlled by the
respectively.
This behavior was backported to Go 1.19.8+ and Go 1.20.3+.
Go 1.21 adds the support of Multipath TCP but it is only used if the application
explicitly asked for it. This behavior can be controlled by the
[`multipathtcp` setting](/pkg/net#Dialer.SetMultipathTCP).
There is no plan to remove any of these settings.
### Go 1.20

View File

@@ -38,7 +38,7 @@ The vendor directory may be updated with 'go mod vendor'.
A typical sequence might be:
cd src
go get golang.org/x/net@master
go get golang.org/x/net@latest
go mod tidy
go mod vendor

View File

@@ -588,16 +588,16 @@
// small and of zero-extend => either zero-extend or small and
(Select0 (ANDCCconst [c] y:(MOVBZreg _))) && c&0xFF == 0xFF => y
(Select0 (ANDCCconst [0xFF] (MOVBreg x))) => (MOVBZreg x)
(Select0 (ANDCCconst [0xFF] y:(MOVBreg _))) => y
(Select0 (ANDCCconst [c] y:(MOVHZreg _))) && c&0xFFFF == 0xFFFF => y
(Select0 (ANDCCconst [0xFFFF] (MOVHreg x))) => (MOVHZreg x)
(Select0 (ANDCCconst [0xFFFF] y:(MOVHreg _))) => y
(AND (MOVDconst [c]) y:(MOVWZreg _)) && c&0xFFFFFFFF == 0xFFFFFFFF => y
(AND (MOVDconst [0xFFFFFFFF]) y:(MOVWreg x)) => (MOVWZreg x)
// normal case
(Select0 (ANDCCconst [c] (MOVBZreg x))) => (Select0 (ANDCCconst [c&0xFF] x))
(Select0 (ANDCCconst [c] (MOVHZreg x))) => (Select0 (ANDCCconst [c&0xFFFF] x))
(Select0 (ANDCCconst [c] (MOVWZreg x))) => (Select0 (ANDCCconst [c&0xFFFFFFFF] x))
(Select0 (ANDCCconst [c] (MOV(B|BZ)reg x))) => (Select0 (ANDCCconst [c&0xFF] x))
(Select0 (ANDCCconst [c] (MOV(H|HZ)reg x))) => (Select0 (ANDCCconst [c&0xFFFF] x))
(Select0 (ANDCCconst [c] (MOV(W|WZ)reg x))) => (Select0 (ANDCCconst [c&0xFFFFFFFF] x))
// Eliminate unnecessary sign/zero extend following right shift
(MOV(B|H|W)Zreg (SRWconst [c] (MOVBZreg x))) => (SRWconst [c] (MOVBZreg x))

View File

@@ -14410,19 +14410,17 @@ func rewriteValuePPC64_OpSelect0(v *Value) bool {
v.copyOf(y)
return true
}
// match: (Select0 (ANDCCconst [0xFF] (MOVBreg x)))
// result: (MOVBZreg x)
// match: (Select0 (ANDCCconst [0xFF] y:(MOVBreg _)))
// result: y
for {
if v_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0.AuxInt) != 0xFF {
break
}
v_0_0 := v_0.Args[0]
if v_0_0.Op != OpPPC64MOVBreg {
y := v_0.Args[0]
if y.Op != OpPPC64MOVBreg {
break
}
x := v_0_0.Args[0]
v.reset(OpPPC64MOVBZreg)
v.AddArg(x)
v.copyOf(y)
return true
}
// match: (Select0 (ANDCCconst [c] y:(MOVHZreg _)))
@@ -14440,19 +14438,36 @@ func rewriteValuePPC64_OpSelect0(v *Value) bool {
v.copyOf(y)
return true
}
// match: (Select0 (ANDCCconst [0xFFFF] (MOVHreg x)))
// result: (MOVHZreg x)
// match: (Select0 (ANDCCconst [0xFFFF] y:(MOVHreg _)))
// result: y
for {
if v_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0.AuxInt) != 0xFFFF {
break
}
y := v_0.Args[0]
if y.Op != OpPPC64MOVHreg {
break
}
v.copyOf(y)
return true
}
// match: (Select0 (ANDCCconst [c] (MOVBreg x)))
// result: (Select0 (ANDCCconst [c&0xFF] x))
for {
if v_0.Op != OpPPC64ANDCCconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
v_0_0 := v_0.Args[0]
if v_0_0.Op != OpPPC64MOVHreg {
if v_0_0.Op != OpPPC64MOVBreg {
break
}
x := v_0_0.Args[0]
v.reset(OpPPC64MOVHZreg)
v.AddArg(x)
v.reset(OpSelect0)
v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
v0.AuxInt = int64ToAuxInt(c & 0xFF)
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (Select0 (ANDCCconst [c] (MOVBZreg x)))
@@ -14474,6 +14489,25 @@ func rewriteValuePPC64_OpSelect0(v *Value) bool {
v.AddArg(v0)
return true
}
// match: (Select0 (ANDCCconst [c] (MOVHreg x)))
// result: (Select0 (ANDCCconst [c&0xFFFF] x))
for {
if v_0.Op != OpPPC64ANDCCconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
v_0_0 := v_0.Args[0]
if v_0_0.Op != OpPPC64MOVHreg {
break
}
x := v_0_0.Args[0]
v.reset(OpSelect0)
v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
v0.AuxInt = int64ToAuxInt(c & 0xFFFF)
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (Select0 (ANDCCconst [c] (MOVHZreg x)))
// result: (Select0 (ANDCCconst [c&0xFFFF] x))
for {
@@ -14493,6 +14527,25 @@ func rewriteValuePPC64_OpSelect0(v *Value) bool {
v.AddArg(v0)
return true
}
// match: (Select0 (ANDCCconst [c] (MOVWreg x)))
// result: (Select0 (ANDCCconst [c&0xFFFFFFFF] x))
for {
if v_0.Op != OpPPC64ANDCCconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
v_0_0 := v_0.Args[0]
if v_0_0.Op != OpPPC64MOVWreg {
break
}
x := v_0_0.Args[0]
v.reset(OpSelect0)
v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
v0.AuxInt = int64ToAuxInt(c & 0xFFFFFFFF)
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (Select0 (ANDCCconst [c] (MOVWZreg x)))
// result: (Select0 (ANDCCconst [c&0xFFFFFFFF] x))
for {

View File

@@ -53,10 +53,7 @@ func mightContainHeapPointer(ptr *Value, size int64, mem *Value, zeroes map[ID]Z
}
ptrSize := ptr.Block.Func.Config.PtrSize
if off%ptrSize != 0 {
return true // see issue 61187
}
if size%ptrSize != 0 {
if off%ptrSize != 0 || size%ptrSize != 0 {
ptr.Fatalf("unaligned pointer write")
}
if off < 0 || off+size > 64*ptrSize {
@@ -133,7 +130,7 @@ func needWBdst(ptr, mem *Value, zeroes map[ID]ZeroRegion) bool {
}
ptrSize := ptr.Block.Func.Config.PtrSize
if off%ptrSize != 0 {
return true // see issue 61187
ptr.Fatalf("unaligned pointer write")
}
if off < 0 || off >= 64*ptrSize {
// write goes off end of tracked offsets

View File

@@ -135,11 +135,7 @@ func walkClear(n *ir.UnaryExpr) ir.Node {
typ := n.X.Type()
switch {
case typ.IsSlice():
if n := arrayClear(n.X.Pos(), n.X, nil); n != nil {
return n
}
// If n == nil, we are clearing an array which takes zero memory, do nothing.
return ir.NewBlockStmt(n.Pos(), nil)
return arrayClear(n.X.Pos(), n.X, nil)
case typ.IsMap():
return mapClear(n.X, reflectdata.TypePtrAt(n.X.Pos(), n.X.Type()))
}

View File

@@ -4,12 +4,12 @@ go 1.21
require (
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26
golang.org/x/arch v0.4.0
golang.org/x/mod v0.12.0
golang.org/x/sync v0.3.0
golang.org/x/sys v0.10.0
golang.org/x/term v0.10.0
golang.org/x/tools v0.11.1-0.20230712164437-1ca21856af7b
golang.org/x/arch v0.3.0
golang.org/x/mod v0.10.1-0.20230606122920-62c7e578f1a7
golang.org/x/sync v0.2.1-0.20230601203510-93782cc822b6
golang.org/x/sys v0.9.0
golang.org/x/term v0.9.0
golang.org/x/tools v0.9.4-0.20230613194514-c6c983054920
)
require github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2 // indirect

View File

@@ -2,15 +2,15 @@ github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbu
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2 h1:rcanfLhLDA8nozr/K289V1zcntHr3V+SHlXwzz1ZI2g=
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc=
golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/tools v0.11.1-0.20230712164437-1ca21856af7b h1:KIZCni6lCdxd4gxHx49Zp9mhckTFRbI/ZPDbR3jKu90=
golang.org/x/tools v0.11.1-0.20230712164437-1ca21856af7b/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/mod v0.10.1-0.20230606122920-62c7e578f1a7 h1:OSEstGpBW1+G0wiXI0bBgOnI8nRJQKX3GCNxF75VR1s=
golang.org/x/mod v0.10.1-0.20230606122920-62c7e578f1a7/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/sync v0.2.1-0.20230601203510-93782cc822b6 h1:kiysxTbHE5FVnrNyc9BC/yeJi3DTUBHIJtNbC9uvXk4=
golang.org/x/sync v0.2.1-0.20230601203510-93782cc822b6/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/tools v0.9.4-0.20230613194514-c6c983054920 h1:FJIPEU9owLOeJgghpx63YhobtkWkORJ3O5ZnbFr8Bzs=
golang.org/x/tools v0.9.4-0.20230613194514-c6c983054920/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=

View File

@@ -179,9 +179,6 @@ func parse(x string) version {
// Parse prerelease.
i := 0
for i < len(x) && (x[i] < '0' || '9' < x[i]) {
if x[i] < 'a' || 'z' < x[i] {
return version{}
}
i++
}
if i == 0 {

View File

@@ -95,25 +95,6 @@ var prevTests = []testCase1[string, string]{
{"1.40000000000000000", "1.39999999999999999"},
}
func TestIsValid(t *testing.T) { test1(t, isValidTests, "IsValid", IsValid) }
var isValidTests = []testCase1[string, bool]{
{"1.2rc3", true},
{"1.2.3", true},
{"1.999testmod", true},
{"1.600+auto", false},
{"1.22", true},
{"1.21.0", true},
{"1.21rc2", true},
{"1.21", true},
{"1.20.0", true},
{"1.20", true},
{"1.19", true},
{"1.3", true},
{"1.2", true},
{"1", true},
}
type testCase1[In, Out any] struct {
in In
out Out

View File

@@ -15,7 +15,7 @@ import (
// FromToolchain returns the Go version for the named toolchain,
// derived from the name itself (not by running the toolchain).
// A toolchain is named "goVERSION".
// A suffix after the VERSION introduced by a -, space, or tab is removed.
// A suffix after the VERSION introduced by a +, -, space, or tab is removed.
// Examples:
//
// FromToolchain("go1.2.3") == "1.2.3"

View File

@@ -60,15 +60,6 @@ func (r *toolchainRepo) Versions(ctx context.Context, prefix string) (*Versions,
}
}
// Always include our own version.
// This means that the development branch of Go 1.21 (say) will allow 'go get go@1.21'
// even though there are no Go 1.21 releases yet.
// Once there is a release, 1.21 will be treated as a query matching the latest available release.
// Before then, 1.21 will be treated as a query that resolves to this entry we are adding (1.21).
if v := gover.Local(); !have[v] {
list = append(list, goPrefix+v)
}
if r.path == "go" {
sort.Slice(list, func(i, j int) bool {
return gover.Compare(list[i], list[j]) < 0
@@ -83,38 +74,21 @@ func (r *toolchainRepo) Versions(ctx context.Context, prefix string) (*Versions,
}
func (r *toolchainRepo) Stat(ctx context.Context, rev string) (*RevInfo, error) {
// If we're asking about "go" (not "toolchain"), pretend to have
// all earlier Go versions available without network access:
// we will provide those ourselves, at least in GOTOOLCHAIN=auto mode.
if r.path == "go" && gover.Compare(rev, gover.Local()) <= 0 {
return &RevInfo{Version: rev}, nil
}
// Convert rev to DL version and stat that to make sure it exists.
// In theory the go@ versions should be like 1.21.0
// and the toolchain@ versions should be like go1.21.0
// but people will type the wrong one, and so we accept
// both and silently correct it to the standard form.
prefix := ""
v := rev
v = strings.TrimPrefix(v, "go")
if r.path == "toolchain" {
prefix = "go"
}
if !gover.IsValid(v) {
return nil, fmt.Errorf("invalid %s version %s", r.path, rev)
}
// If we're asking about "go" (not "toolchain"), pretend to have
// all earlier Go versions available without network access:
// we will provide those ourselves, at least in GOTOOLCHAIN=auto mode.
if r.path == "go" && gover.Compare(v, gover.Local()) <= 0 {
return &RevInfo{Version: prefix + v}, nil
}
// Similarly, if we're asking about *exactly* the current toolchain,
// we don't need to access the network to know that it exists.
if r.path == "toolchain" && v == gover.Local() {
return &RevInfo{Version: prefix + v}, nil
}
if gover.IsLang(v) {
// We can only use a language (development) version if the current toolchain
// implements that version, and the two checks above have ruled that out.
return nil, fmt.Errorf("go language version %s is not a toolchain version", rev)
}

View File

@@ -239,13 +239,10 @@ func (q *query) matchesPath(path string) bool {
// canMatchInModule reports whether the given module path can potentially
// contain q.pattern.
func (q *query) canMatchInModule(mPath string) bool {
if gover.IsToolchain(mPath) {
return false
}
if q.canMatchWildcardInModule != nil {
return q.canMatchWildcardInModule(mPath)
}
return str.HasPathPrefix(q.pattern, mPath)
return str.HasPathPrefix(q.pattern, mPath) && !gover.IsToolchain(mPath)
}
// pathOnce invokes f to generate the pathSet for the given path,

View File

@@ -473,11 +473,7 @@ func newQueryMatcher(path string, query, current string, allowed AllowedFunc) (*
// AllowedFunc of qm.
func (qm *queryMatcher) allowsVersion(ctx context.Context, v string) bool {
if qm.prefix != "" && !strings.HasPrefix(v, qm.prefix) {
if gover.IsToolchain(qm.path) && strings.TrimSuffix(qm.prefix, ".") == v {
// Allow 1.21 to match "1.21." prefix.
} else {
return false
}
return false
}
if qm.filter != nil && !qm.filter(v) {
return false

View File

@@ -131,7 +131,7 @@ func Select() {
} else {
min, suffix, plus := strings.Cut(gotoolchain, "+") // go1.2.3+auto
if min != "local" {
v := gover.FromToolchain(min)
v := gover.FromToolchain(gotoolchain)
if v == "" {
if plus {
base.Fatalf("invalid GOTOOLCHAIN %q: invalid minimum toolchain %q", gotoolchain, min)

View File

@@ -34,9 +34,9 @@ env GOTOOLCHAIN=go1.600+auto
go version
stdout go1.600
env GOTOOLCHAIN=go1.400.0+auto
env GOTOOLCHAIN=go1.400+auto
go version
stdout go1.400.0
stdout go1.400
# GOTOOLCHAIN=version+path sets a minimum too.
env GOTOOLCHAIN=go1.600+path

View File

@@ -1,5 +1,5 @@
# setup
env TESTGO_VERSION=go1.99rc1
env TESTGO_VERSION=go1.99.0
env TESTGO_VERSION_SWITCH=switch
# go get go should use the latest Go 1.23
@@ -7,28 +7,28 @@ cp go.mod.orig go.mod
go get go
stderr '^go: upgraded go 1.21 => 1.23.9$'
grep 'go 1.23.9' go.mod
grep 'toolchain go1.99rc1' go.mod
grep 'toolchain go1.99.0' go.mod
# go get go@1.23 should use the latest Go 1.23
cp go.mod.orig go.mod
go get go@1.23
stderr '^go: upgraded go 1.21 => 1.23.9$'
grep 'go 1.23.9' go.mod
grep 'toolchain go1.99rc1' go.mod
grep 'toolchain go1.99.0' go.mod
# go get go@1.22 should use the latest Go 1.22
cp go.mod.orig go.mod
go get go@1.22
stderr '^go: upgraded go 1.21 => 1.22.9$'
grep 'go 1.22.9' go.mod
grep 'toolchain go1.99rc1' go.mod
grep 'toolchain go1.99.0' go.mod
# go get go@patch should use the latest patch release
go get go@1.22.1
go get go@patch
stderr '^go: upgraded go 1.22.1 => 1.22.9$'
grep 'go 1.22.9' go.mod
grep 'toolchain go1.99rc1' go.mod
grep 'toolchain go1.99.0' go.mod
# go get go@1.24 does NOT find the release candidate
cp go.mod.orig go.mod
@@ -40,20 +40,20 @@ cp go.mod.orig go.mod
go get go@1.24rc1
stderr '^go: upgraded go 1.21 => 1.24rc1$'
grep 'go 1.24rc1' go.mod
grep 'toolchain go1.99rc1' go.mod
grep 'toolchain go1.99.0' go.mod
# go get go@latest finds the latest Go 1.23
cp go.mod.orig go.mod
go get go@latest
stderr '^go: upgraded go 1.21 => 1.23.9$'
grep 'go 1.23.9' go.mod
grep 'toolchain go1.99rc1' go.mod
grep 'toolchain go1.99.0' go.mod
# Again, with toolchains.
# go get toolchain should find go1.999testmod.
go get toolchain
stderr '^go: upgraded toolchain go1.99rc1 => go1.999testmod$'
stderr '^go: upgraded toolchain go1.99.0 => go1.999testmod$'
grep 'go 1.23.9' go.mod
grep 'toolchain go1.999testmod' go.mod
@@ -96,33 +96,6 @@ stderr '^go: added toolchain go1.999testmod$'
grep 'go 1.21' go.mod
grep 'toolchain go1.999testmod' go.mod
# Bug fixes.
# go get go@garbage should fail but not crash
! go get go@garbage
! stderr panic
stderr '^go: invalid go version garbage$'
# go get go@go1.21.0 is OK - we silently correct to 1.21.0
go get go@1.19
go get go@go1.21.0
stderr '^go: upgraded go 1.19 => 1.21.0'
# go get toolchain@1.24rc1 is OK too.
go get toolchain@1.24rc1
stderr '^go: downgraded toolchain go1.999testmod => go1.24rc1$'
# go get go@1.21 should work if we are the Go 1.21 language version,
# even though there's no toolchain for it.
# (Older versions resolve to the latest release in that version, so for example
# go get go@1.20 might resolve to 1.20.9, but if we're the devel copy of
# Go 1.21, there's no release yet to resolve to, so we resolve to ourselves.)
env TESTGO_VERSION=go1.21
go get go@1.19 toolchain@none
go get go@1.21
grep 'go 1.21$' go.mod
! grep toolchain go.mod
-- go.mod.orig --
module m

View File

@@ -222,7 +222,7 @@ type peLoaderState struct {
var comdatDefinitions = make(map[string]int64)
// Load loads the PE file pn from input.
// Symbols from the object file are created via the loader 'l',
// Symbols from the object file are created via the loader 'l', and
// and a slice of the text symbols is returned.
// If an .rsrc section or set of .rsrc$xx sections is found, its symbols are
// returned as rsrc.

View File

@@ -83,12 +83,6 @@ func GoSyntax(inst Inst, pc uint64, symname SymLookup) string {
}
}
if inst.Op == CMP {
// Use reads-left-to-right ordering for comparisons.
// See issue 60920.
args[0], args[1] = args[1], args[0]
}
if args != nil {
op += " " + strings.Join(args, ", ")
}

View File

@@ -13,7 +13,7 @@ import (
"sync"
)
// Regexp is a wrapper around [regexp.Regexp], where the underlying regexp will be
// Regexp is a wrapper around regexp.Regexp, where the underlying regexp will be
// compiled the first time it is needed.
type Regexp struct {
str string

View File

@@ -65,7 +65,7 @@ type Comments struct {
}
// Comment returns the receiver. This isn't useful by itself, but
// a [Comments] struct is embedded into all the expression
// a Comments struct is embedded into all the expression
// implementation types, and this gives each of those a Comment
// method to satisfy the Expr interface.
func (c *Comments) Comment() *Comments {

View File

@@ -5,17 +5,17 @@
// Package modfile implements a parser and formatter for go.mod files.
//
// The go.mod syntax is described in
// https://pkg.go.dev/cmd/go/#hdr-The_go_mod_file.
// https://golang.org/cmd/go/#hdr-The_go_mod_file.
//
// The [Parse] and [ParseLax] functions both parse a go.mod file and return an
// The Parse and ParseLax functions both parse a go.mod file and return an
// abstract syntax tree. ParseLax ignores unknown statements and may be used to
// parse go.mod files that may have been developed with newer versions of Go.
//
// The [File] struct returned by Parse and ParseLax represent an abstract
// go.mod file. File has several methods like [File.AddNewRequire] and
// [File.DropReplace] that can be used to programmatically edit a file.
// The File struct returned by Parse and ParseLax represent an abstract
// go.mod file. File has several methods like AddNewRequire and DropReplace
// that can be used to programmatically edit a file.
//
// The [Format] function formats a File back to a byte slice which can be
// The Format function formats a File back to a byte slice which can be
// written to a file.
package modfile
@@ -226,7 +226,7 @@ var dontFixRetract VersionFixer = func(_, vers string) (string, error) {
// data is the content of the file.
//
// fix is an optional function that canonicalizes module versions.
// If fix is nil, all module versions must be canonical ([module.CanonicalVersion]
// If fix is nil, all module versions must be canonical (module.CanonicalVersion
// must return the same string).
func Parse(file string, data []byte, fix VersionFixer) (*File, error) {
return parseToFile(file, data, fix, true)
@@ -923,7 +923,7 @@ func (f *File) Format() ([]byte, error) {
}
// Cleanup cleans up the file f after any edit operations.
// To avoid quadratic behavior, modifications like [File.DropRequire]
// To avoid quadratic behavior, modifications like DropRequire
// clear the entry but do not remove it from the slice.
// Cleanup cleans out all the cleared entries.
func (f *File) Cleanup() {
@@ -1075,8 +1075,8 @@ func (f *File) AddNewRequire(path, vers string, indirect bool) {
// The requirements in req must specify at most one distinct version for each
// module path.
//
// If any existing requirements may be removed, the caller should call
// [File.Cleanup] after all edits are complete.
// If any existing requirements may be removed, the caller should call Cleanup
// after all edits are complete.
func (f *File) SetRequire(req []*Require) {
type elem struct {
version string

View File

@@ -34,7 +34,7 @@ type Use struct {
// data is the content of the file.
//
// fix is an optional function that canonicalizes module versions.
// If fix is nil, all module versions must be canonical ([module.CanonicalVersion]
// If fix is nil, all module versions must be canonical (module.CanonicalVersion
// must return the same string).
func ParseWork(file string, data []byte, fix VersionFixer) (*WorkFile, error) {
fs, err := parse(file, data)
@@ -83,7 +83,7 @@ func ParseWork(file string, data []byte, fix VersionFixer) (*WorkFile, error) {
}
// Cleanup cleans up the file f after any edit operations.
// To avoid quadratic behavior, modifications like [WorkFile.DropRequire]
// To avoid quadratic behavior, modifications like DropRequire
// clear the entry but do not remove it from the slice.
// Cleanup cleans out all the cleared entries.
func (f *WorkFile) Cleanup() {

View File

@@ -4,7 +4,7 @@
// Package module defines the module.Version type along with support code.
//
// The [module.Version] type is a simple Path, Version pair:
// The module.Version type is a simple Path, Version pair:
//
// type Version struct {
// Path string
@@ -12,7 +12,7 @@
// }
//
// There are no restrictions imposed directly by use of this structure,
// but additional checking functions, most notably [Check], verify that
// but additional checking functions, most notably Check, verify that
// a particular path, version pair is valid.
//
// # Escaped Paths
@@ -140,7 +140,7 @@ type ModuleError struct {
Err error
}
// VersionError returns a [ModuleError] derived from a [Version] and error,
// VersionError returns a ModuleError derived from a Version and error,
// or err itself if it is already such an error.
func VersionError(v Version, err error) error {
var mErr *ModuleError
@@ -169,7 +169,7 @@ func (e *ModuleError) Unwrap() error { return e.Err }
// An InvalidVersionError indicates an error specific to a version, with the
// module path unknown or specified externally.
//
// A [ModuleError] may wrap an InvalidVersionError, but an InvalidVersionError
// A ModuleError may wrap an InvalidVersionError, but an InvalidVersionError
// must not wrap a ModuleError.
type InvalidVersionError struct {
Version string
@@ -193,8 +193,8 @@ func (e *InvalidVersionError) Error() string {
func (e *InvalidVersionError) Unwrap() error { return e.Err }
// An InvalidPathError indicates a module, import, or file path doesn't
// satisfy all naming constraints. See [CheckPath], [CheckImportPath],
// and [CheckFilePath] for specific restrictions.
// satisfy all naming constraints. See CheckPath, CheckImportPath,
// and CheckFilePath for specific restrictions.
type InvalidPathError struct {
Kind string // "module", "import", or "file"
Path string
@@ -294,7 +294,7 @@ func fileNameOK(r rune) bool {
}
// CheckPath checks that a module path is valid.
// A valid module path is a valid import path, as checked by [CheckImportPath],
// A valid module path is a valid import path, as checked by CheckImportPath,
// with three additional constraints.
// First, the leading path element (up to the first slash, if any),
// by convention a domain name, must contain only lower-case ASCII letters,
@@ -380,7 +380,7 @@ const (
// checkPath returns an error describing why the path is not valid.
// Because these checks apply to module, import, and file paths,
// and because other checks may be applied, the caller is expected to wrap
// this error with [InvalidPathError].
// this error with InvalidPathError.
func checkPath(path string, kind pathKind) error {
if !utf8.ValidString(path) {
return fmt.Errorf("invalid UTF-8")
@@ -532,7 +532,7 @@ var badWindowsNames = []string{
// they require ".vN" instead of "/vN", and for all N, not just N >= 2.
// SplitPathVersion returns with ok = false when presented with
// a path whose last path element does not satisfy the constraints
// applied by [CheckPath], such as "example.com/pkg/v1" or "example.com/pkg/v1.2".
// applied by CheckPath, such as "example.com/pkg/v1" or "example.com/pkg/v1.2".
func SplitPathVersion(path string) (prefix, pathMajor string, ok bool) {
if strings.HasPrefix(path, "gopkg.in/") {
return splitGopkgIn(path)
@@ -582,7 +582,7 @@ func splitGopkgIn(path string) (prefix, pathMajor string, ok bool) {
// MatchPathMajor reports whether the semantic version v
// matches the path major version pathMajor.
//
// MatchPathMajor returns true if and only if [CheckPathMajor] returns nil.
// MatchPathMajor returns true if and only if CheckPathMajor returns nil.
func MatchPathMajor(v, pathMajor string) bool {
return CheckPathMajor(v, pathMajor) == nil
}
@@ -622,7 +622,7 @@ func CheckPathMajor(v, pathMajor string) error {
// PathMajorPrefix returns the major-version tag prefix implied by pathMajor.
// An empty PathMajorPrefix allows either v0 or v1.
//
// Note that [MatchPathMajor] may accept some versions that do not actually begin
// Note that MatchPathMajor may accept some versions that do not actually begin
// with this prefix: namely, it accepts a 'v0.0.0-' prefix for a '.v1'
// pathMajor, even though that pathMajor implies 'v1' tagging.
func PathMajorPrefix(pathMajor string) string {
@@ -643,7 +643,7 @@ func PathMajorPrefix(pathMajor string) string {
}
// CanonicalVersion returns the canonical form of the version string v.
// It is the same as [semver.Canonical] except that it preserves the special build suffix "+incompatible".
// It is the same as semver.Canonical(v) except that it preserves the special build suffix "+incompatible".
func CanonicalVersion(v string) string {
cv := semver.Canonical(v)
if semver.Build(v) == "+incompatible" {
@@ -652,8 +652,8 @@ func CanonicalVersion(v string) string {
return cv
}
// Sort sorts the list by Path, breaking ties by comparing [Version] fields.
// The Version fields are interpreted as semantic versions (using [semver.Compare])
// Sort sorts the list by Path, breaking ties by comparing Version fields.
// The Version fields are interpreted as semantic versions (using semver.Compare)
// optionally followed by a tie-breaking suffix introduced by a slash character,
// like in "v0.0.1/go.mod".
func Sort(list []Version) {
@@ -793,7 +793,7 @@ func unescapeString(escaped string) (string, bool) {
}
// MatchPrefixPatterns reports whether any path prefix of target matches one of
// the glob patterns (as defined by [path.Match]) in the comma-separated globs
// the glob patterns (as defined by path.Match) in the comma-separated globs
// list. This implements the algorithm used when matching a module path to the
// GOPRIVATE environment variable, as described by 'go help module-private'.
//

View File

@@ -125,7 +125,7 @@ func IsPseudoVersion(v string) bool {
}
// IsZeroPseudoVersion returns whether v is a pseudo-version with a zero base,
// timestamp, and revision, as returned by [ZeroPseudoVersion].
// timestamp, and revision, as returned by ZeroPseudoVersion.
func IsZeroPseudoVersion(v string) bool {
return v == ZeroPseudoVersion(semver.Major(v))
}

View File

@@ -140,7 +140,7 @@ func Compare(v, w string) int {
// Max canonicalizes its arguments and then returns the version string
// that compares greater.
//
// Deprecated: use [Compare] instead. In most cases, returning a canonicalized
// Deprecated: use Compare instead. In most cases, returning a canonicalized
// version is not expected or desired.
func Max(v, w string) string {
v = Canonical(v)
@@ -151,7 +151,7 @@ func Max(v, w string) string {
return w
}
// ByVersion implements [sort.Interface] for sorting semantic version strings.
// ByVersion implements sort.Interface for sorting semantic version strings.
type ByVersion []string
func (vs ByVersion) Len() int { return len(vs) }
@@ -164,7 +164,7 @@ func (vs ByVersion) Less(i, j int) bool {
return vs[i] < vs[j]
}
// Sort sorts a list of semantic version strings using [ByVersion].
// Sort sorts a list of semantic version strings using ByVersion.
func Sort(list []string) {
sort.Sort(ByVersion(list))
}

View File

@@ -19,7 +19,7 @@ import (
)
// A ClientOps provides the external operations
// (file caching, HTTP fetches, and so on) needed by the [Client].
// (file caching, HTTP fetches, and so on) needed by the Client.
// The methods must be safe for concurrent use by multiple goroutines.
type ClientOps interface {
// ReadRemote reads and returns the content served at the given path
@@ -72,7 +72,7 @@ type ClientOps interface {
// ErrWriteConflict signals a write conflict during Client.WriteConfig.
var ErrWriteConflict = errors.New("write conflict")
// ErrSecurity is returned by [Client] operations that invoke Client.SecurityError.
// ErrSecurity is returned by Client operations that invoke Client.SecurityError.
var ErrSecurity = errors.New("security error: misbehaving server")
// A Client is a client connection to a checksum database.
@@ -102,7 +102,7 @@ type Client struct {
tileSaved map[tlog.Tile]bool // which tiles have been saved using c.ops.WriteCache already
}
// NewClient returns a new [Client] using the given [ClientOps].
// NewClient returns a new Client using the given Client.
func NewClient(ops ClientOps) *Client {
return &Client{
ops: ops,
@@ -155,7 +155,7 @@ func (c *Client) initWork() {
}
// SetTileHeight sets the tile height for the Client.
// Any call to SetTileHeight must happen before the first call to [Client.Lookup].
// Any call to SetTileHeight must happen before the first call to Lookup.
// If SetTileHeight is not called, the Client defaults to tile height 8.
// SetTileHeight can be called at most once,
// and if so it must be called before the first call to Lookup.
@@ -174,7 +174,7 @@ func (c *Client) SetTileHeight(height int) {
// SetGONOSUMDB sets the list of comma-separated GONOSUMDB patterns for the Client.
// For any module path matching one of the patterns,
// [Client.Lookup] will return ErrGONOSUMDB.
// Lookup will return ErrGONOSUMDB.
// SetGONOSUMDB can be called at most once,
// and if so it must be called before the first call to Lookup.
func (c *Client) SetGONOSUMDB(list string) {
@@ -187,8 +187,8 @@ func (c *Client) SetGONOSUMDB(list string) {
c.nosumdb = list
}
// ErrGONOSUMDB is returned by [Client.Lookup] for paths that match
// a pattern listed in the GONOSUMDB list (set by [Client.SetGONOSUMDB],
// ErrGONOSUMDB is returned by Lookup for paths that match
// a pattern listed in the GONOSUMDB list (set by SetGONOSUMDB,
// usually from the environment variable).
var ErrGONOSUMDB = errors.New("skipped (listed in GONOSUMDB)")

View File

@@ -20,45 +20,45 @@
//
// # Verifying Notes
//
// A [Verifier] allows verification of signatures by one server public key.
// A Verifier allows verification of signatures by one server public key.
// It can report the name of the server and the uint32 hash of the key,
// and it can verify a purported signature by that key.
//
// The standard implementation of a Verifier is constructed
// by [NewVerifier] starting from a verifier key, which is a
// by NewVerifier starting from a verifier key, which is a
// plain text string of the form "<name>+<hash>+<keydata>".
//
// A [Verifiers] allows looking up a Verifier by the combination
// A Verifiers allows looking up a Verifier by the combination
// of server name and key hash.
//
// The standard implementation of a Verifiers is constructed
// by VerifierList from a list of known verifiers.
//
// A [Note] represents a text with one or more signatures.
// A Note represents a text with one or more signatures.
// An implementation can reject a note with too many signatures
// (for example, more than 100 signatures).
//
// A [Signature] represents a signature on a note, verified or not.
// A Signature represents a signature on a note, verified or not.
//
// The [Open] function takes as input a signed message
// The Open function takes as input a signed message
// and a set of known verifiers. It decodes and verifies
// the message signatures and returns a [Note] structure
// the message signatures and returns a Note structure
// containing the message text and (verified or unverified) signatures.
//
// # Signing Notes
//
// A [Signer] allows signing a text with a given key.
// A Signer allows signing a text with a given key.
// It can report the name of the server and the hash of the key
// and can sign a raw text using that key.
//
// The standard implementation of a Signer is constructed
// by [NewSigner] starting from an encoded signer key, which is a
// by NewSigner starting from an encoded signer key, which is a
// plain text string of the form "PRIVATE+KEY+<name>+<hash>+<keydata>".
// Anyone with an encoded signer key can sign messages using that key,
// so it must be kept secret. The encoding begins with the literal text
// "PRIVATE+KEY" to avoid confusion with the public server key.
//
// The [Sign] function takes as input a Note and a list of Signers
// The Sign function takes as input a Note and a list of Signers
// and returns an encoded, signed message.
//
// # Signed Note Format
@@ -88,7 +88,7 @@
// although doing so will require deploying the new algorithms to all clients
// before starting to depend on them for signatures.
//
// The [GenerateKey] function generates and returns a new signer
// The GenerateKey function generates and returns a new signer
// and corresponding verifier.
//
// # Example
@@ -123,9 +123,9 @@
// base URLs, the only syntactic requirement is that they
// not contain spaces or newlines).
//
// If [Open] is given access to a [Verifiers] including the
// [Verifier] for this key, then it will succeed at verifying
// the encoded message and returning the parsed [Note]:
// If Open is given access to a Verifiers including the
// Verifier for this key, then it will succeed at verifying
// the encoded message and returning the parsed Note:
//
// vkey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW"
// msg := []byte("If you think cryptography is the answer to your problem,\n" +
@@ -238,7 +238,7 @@ func isValidName(name string) bool {
return name != "" && utf8.ValidString(name) && strings.IndexFunc(name, unicode.IsSpace) < 0 && !strings.Contains(name, "+")
}
// NewVerifier construct a new [Verifier] from an encoded verifier key.
// NewVerifier construct a new Verifier from an encoded verifier key.
func NewVerifier(vkey string) (Verifier, error) {
name, vkey := chop(vkey, "+")
hash16, key64 := chop(vkey, "+")
@@ -295,7 +295,7 @@ func (v *verifier) Name() string { return v.name }
func (v *verifier) KeyHash() uint32 { return v.hash }
func (v *verifier) Verify(msg, sig []byte) bool { return v.verify(msg, sig) }
// NewSigner constructs a new [Signer] from an encoded signer key.
// NewSigner constructs a new Signer from an encoded signer key.
func NewSigner(skey string) (Signer, error) {
priv1, skey := chop(skey, "+")
priv2, skey := chop(skey, "+")
@@ -409,7 +409,7 @@ func (e *UnknownVerifierError) Error() string {
}
// An ambiguousVerifierError indicates that the given name and hash
// match multiple keys passed to [VerifierList].
// match multiple keys passed to VerifierList.
// (If this happens, some malicious actor has taken control of the
// verifier list, at which point we may as well give up entirely,
// but we diagnose the problem instead.)
@@ -422,7 +422,7 @@ func (e *ambiguousVerifierError) Error() string {
return fmt.Sprintf("ambiguous key %s+%08x", e.name, e.hash)
}
// VerifierList returns a [Verifiers] implementation that uses the given list of verifiers.
// VerifierList returns a Verifiers implementation that uses the given list of verifiers.
func VerifierList(list ...Verifier) Verifiers {
m := make(verifierMap)
for _, v := range list {
@@ -510,7 +510,7 @@ var (
// If known.Verifier returns any other error, Open returns that error.
//
// If no known verifier has signed an otherwise valid note,
// Open returns an [UnverifiedNoteError].
// Open returns an UnverifiedNoteError.
// In this case, the unverified note can be fetched from inside the error.
func Open(msg []byte, known Verifiers) (*Note, error) {
if known == nil {

View File

@@ -17,7 +17,7 @@ import (
)
// A ServerOps provides the external operations
// (underlying database access and so on) needed by the [Server].
// (underlying database access and so on) needed by the Server.
type ServerOps interface {
// Signed returns the signed hash of the latest tree.
Signed(ctx context.Context) ([]byte, error)
@@ -36,7 +36,7 @@ type ServerOps interface {
// A Server is the checksum database HTTP server,
// which implements http.Handler and should be invoked
// to serve the paths listed in [ServerPaths].
// to serve the paths listed in ServerPaths.
type Server struct {
ops ServerOps
}

View File

@@ -14,15 +14,15 @@ import (
"golang.org/x/mod/sumdb/tlog"
)
// NewTestServer constructs a new [TestServer]
// NewTestServer constructs a new TestServer
// that will sign its tree with the given signer key
// (see [golang.org/x/mod/sumdb/note])
// (see golang.org/x/mod/sumdb/note)
// and fetch new records as needed by calling gosum.
func NewTestServer(signer string, gosum func(path, vers string) ([]byte, error)) *TestServer {
return &TestServer{signer: signer, gosum: gosum}
}
// A TestServer is an in-memory implementation of [ServerOps] for testing.
// A TestServer is an in-memory implementation of Server for testing.
type TestServer struct {
signer string
gosum func(path, vers string) ([]byte, error)

View File

@@ -28,7 +28,7 @@ import (
// is tile/3/4/x001/x234/067.p/1, and
// Tile{H: 3, L: 4, N: 1234067, W: 8}'s path
// is tile/3/4/x001/x234/067.
// See the [Tile.Path] method and the [ParseTilePath] function.
// See Tile's Path method and the ParseTilePath function.
//
// The special level L=-1 holds raw record data instead of hashes.
// In this case, the level encodes into a tile path as the path element
@@ -46,7 +46,7 @@ type Tile struct {
// TileForIndex returns the tile of fixed height h ≥ 1
// and least width storing the given hash storage index.
//
// If h ≤ 0, [TileForIndex] panics.
// If h ≤ 0, TileForIndex panics.
func TileForIndex(h int, index int64) Tile {
if h <= 0 {
panic(fmt.Sprintf("TileForIndex: invalid height %d", h))
@@ -105,7 +105,7 @@ func tileHash(data []byte) Hash {
// size newTreeSize to replace a tree of size oldTreeSize.
// (No tiles need to be published for a tree of size zero.)
//
// If h ≤ 0, NewTiles panics.
// If h ≤ 0, TileForIndex panics.
func NewTiles(h int, oldTreeSize, newTreeSize int64) []Tile {
if h <= 0 {
panic(fmt.Sprintf("NewTiles: invalid height %d", h))
@@ -272,7 +272,7 @@ type TileReader interface {
// TileHashReader returns a HashReader that satisfies requests
// by loading tiles of the given tree.
//
// The returned [HashReader] checks that loaded tiles are
// The returned HashReader checks that loaded tiles are
// valid for the given tree. Therefore, any hashes returned
// by the HashReader are already proven to be in the tree.
func TileHashReader(tree Tree, tr TileReader) HashReader {

View File

@@ -131,7 +131,7 @@ func StoredHashIndex(level int, n int64) int64 {
return i + int64(level)
}
// SplitStoredHashIndex is the inverse of [StoredHashIndex].
// SplitStoredHashIndex is the inverse of StoredHashIndex.
// That is, SplitStoredHashIndex(StoredHashIndex(level, n)) == level, n.
func SplitStoredHashIndex(index int64) (level int, n int64) {
// Determine level 0 record before index.
@@ -183,7 +183,7 @@ func StoredHashes(n int64, data []byte, r HashReader) ([]Hash, error) {
return StoredHashesForRecordHash(n, RecordHash(data), r)
}
// StoredHashesForRecordHash is like [StoredHashes] but takes
// StoredHashesForRecordHash is like StoredHashes but takes
// as its second argument RecordHash(data) instead of data itself.
func StoredHashesForRecordHash(n int64, h Hash, r HashReader) ([]Hash, error) {
// Start with the record hash.
@@ -227,7 +227,7 @@ type HashReader interface {
ReadHashes(indexes []int64) ([]Hash, error)
}
// A HashReaderFunc is a function implementing [HashReader].
// A HashReaderFunc is a function implementing HashReader.
type HashReaderFunc func([]int64) ([]Hash, error)
func (f HashReaderFunc) ReadHashes(indexes []int64) ([]Hash, error) {

View File

@@ -10,31 +10,31 @@
//
// • All file paths within a zip file must start with "<module>@<version>/",
// where "<module>" is the module path and "<version>" is the version.
// The module path must be valid (see [golang.org/x/mod/module.CheckPath]).
// The module path must be valid (see golang.org/x/mod/module.CheckPath).
// The version must be valid and canonical (see
// [golang.org/x/mod/module.CanonicalVersion]). The path must have a major
// golang.org/x/mod/module.CanonicalVersion). The path must have a major
// version suffix consistent with the version (see
// [golang.org/x/mod/module.Check]). The part of the file path after the
// golang.org/x/mod/module.Check). The part of the file path after the
// "<module>@<version>/" prefix must be valid (see
// [golang.org/x/mod/module.CheckFilePath]).
// golang.org/x/mod/module.CheckFilePath).
//
// • No two file paths may be equal under Unicode case-folding (see
// [strings.EqualFold]).
// strings.EqualFold).
//
// • A go.mod file may or may not appear in the top-level directory. If present,
// it must be named "go.mod", not any other case. Files named "go.mod"
// are not allowed in any other directory.
//
// • The total size in bytes of a module zip file may be at most [MaxZipFile]
// • The total size in bytes of a module zip file may be at most MaxZipFile
// bytes (500 MiB). The total uncompressed size of the files within the
// zip may also be at most [MaxZipFile] bytes.
// zip may also be at most MaxZipFile bytes.
//
// • Each file's uncompressed size must match its declared 64-bit uncompressed
// size in the zip file header.
//
// • If the zip contains files named "<module>@<version>/go.mod" or
// "<module>@<version>/LICENSE", their sizes in bytes may be at most
// [MaxGoMod] or [MaxLICENSE], respectively (both are 16 MiB).
// MaxGoMod or MaxLICENSE, respectively (both are 16 MiB).
//
// • Empty directories are ignored. File permissions and timestamps are also
// ignored.
@@ -42,7 +42,7 @@
// • Symbolic links and other irregular files are not allowed.
//
// Note that this package does not provide hashing functionality. See
// [golang.org/x/mod/sumdb/dirhash].
// golang.org/x/mod/sumdb/dirhash.
package zip
import (
@@ -56,7 +56,6 @@ import (
"path"
"path/filepath"
"strings"
"time"
"unicode"
"unicode/utf8"
@@ -118,9 +117,8 @@ type CheckedFiles struct {
SizeError error
}
// Err returns an error if [CheckedFiles] does not describe a valid module zip
// file. [CheckedFiles.SizeError] is returned if that field is set.
// A [FileErrorList] is returned
// Err returns an error if CheckedFiles does not describe a valid module zip
// file. SizeError is returned if that field is set. A FileErrorList is returned
// if there are one or more invalid files. Other errors may be returned in the
// future.
func (cf CheckedFiles) Err() error {
@@ -323,17 +321,17 @@ func checkFiles(files []File) (cf CheckedFiles, validFiles []File, validSizes []
}
// CheckDir reports whether the files in dir satisfy the name and size
// constraints listed in the package documentation. The returned [CheckedFiles]
// constraints listed in the package documentation. The returned CheckedFiles
// record contains lists of valid, invalid, and omitted files. If a directory is
// omitted (for example, a nested module or vendor directory), it will appear in
// the omitted list, but its files won't be listed.
//
// CheckDir returns an error if it encounters an I/O error or if the returned
// [CheckedFiles] does not describe a valid module zip file (according to
// [CheckedFiles.Err]). The returned [CheckedFiles] is still populated when such
// CheckedFiles does not describe a valid module zip file (according to
// CheckedFiles.Err). The returned CheckedFiles is still populated when such
// an error is returned.
//
// Note that CheckDir will not open any files, so [CreateFromDir] may still fail
// Note that CheckDir will not open any files, so CreateFromDir may still fail
// when CheckDir is successful due to I/O errors.
func CheckDir(dir string) (CheckedFiles, error) {
// List files (as CreateFromDir would) and check which ones are omitted
@@ -364,13 +362,13 @@ func CheckDir(dir string) (CheckedFiles, error) {
// CheckZip reports whether the files contained in a zip file satisfy the name
// and size constraints listed in the package documentation.
//
// CheckZip returns an error if the returned [CheckedFiles] does not describe
// a valid module zip file (according to [CheckedFiles.Err]). The returned
// CheckZip returns an error if the returned CheckedFiles does not describe
// a valid module zip file (according to CheckedFiles.Err). The returned
// CheckedFiles is still populated when an error is returned. CheckZip will
// also return an error if the module path or version is malformed or if it
// encounters an error reading the zip file.
//
// Note that CheckZip does not read individual files, so [Unzip] may still fail
// Note that CheckZip does not read individual files, so Unzip may still fail
// when CheckZip is successful due to I/O errors.
func CheckZip(m module.Version, zipFile string) (CheckedFiles, error) {
f, err := os.Open(zipFile)
@@ -478,7 +476,7 @@ func checkZip(m module.Version, f *os.File) (*zip.Reader, CheckedFiles, error) {
// and writes it to w.
//
// Create verifies the restrictions described in the package documentation
// and should not produce an archive that [Unzip] cannot extract. Create does not
// and should not produce an archive that Unzip cannot extract. Create does not
// include files in the output archive if they don't belong in the module zip.
// In particular, Create will not include files in modules found in
// subdirectories, most files in vendor directories, or irregular files (such
@@ -545,12 +543,12 @@ func Create(w io.Writer, m module.Version, files []File) (err error) {
// a directory, dir. The zip content is written to w.
//
// CreateFromDir verifies the restrictions described in the package
// documentation and should not produce an archive that [Unzip] cannot extract.
// documentation and should not produce an archive that Unzip cannot extract.
// CreateFromDir does not include files in the output archive if they don't
// belong in the module zip. In particular, CreateFromDir will not include
// files in modules found in subdirectories, most files in vendor directories,
// or irregular files (such as symbolic links) in the output archive.
// Additionally, unlike [Create], CreateFromDir will not include directories
// Additionally, unlike Create, CreateFromDir will not include directories
// named ".bzr", ".git", ".hg", or ".svn".
func CreateFromDir(w io.Writer, m module.Version, dir string) (err error) {
defer func() {
@@ -582,8 +580,8 @@ func CreateFromDir(w io.Writer, m module.Version, dir string) (err error) {
// "sub/dir". To create a zip from the base of the repository, pass an empty
// string.
//
// If CreateFromVCS returns [UnrecognizedVCSError], consider falling back to
// [CreateFromDir].
// If CreateFromVCS returns ErrUnrecognizedVCS, consider falling back to
// CreateFromDir.
func CreateFromVCS(w io.Writer, m module.Version, repoRoot, revision, subdir string) (err error) {
defer func() {
if zerr, ok := err.(*zipError); ok {
@@ -655,7 +653,6 @@ func filesInGitRepo(dir, rev, subdir string) ([]File, error) {
return nil, err
}
haveLICENSE := false
var fs []File
for _, zf := range zipReader.File {
if !strings.HasPrefix(zf.Name, subdir) || strings.HasSuffix(zf.Name, "/") {
@@ -672,23 +669,6 @@ func filesInGitRepo(dir, rev, subdir string) ([]File, error) {
name: n,
f: zf,
})
if n == "LICENSE" {
haveLICENSE = true
}
}
if !haveLICENSE && subdir != "" {
// Note: this method of extracting the license from the root copied from
// https://go.googlesource.com/go/+/refs/tags/go1.20.4/src/cmd/go/internal/modfetch/coderepo.go#1118
// https://go.googlesource.com/go/+/refs/tags/go1.20.4/src/cmd/go/internal/modfetch/codehost/git.go#657
cmd := exec.Command("git", "cat-file", "blob", rev+":LICENSE")
cmd.Dir = dir
cmd.Env = append(os.Environ(), "PWD="+dir)
stdout := bytes.Buffer{}
cmd.Stdout = &stdout
if err := cmd.Run(); err == nil {
fs = append(fs, dataFile{name: "LICENSE", data: stdout.Bytes()})
}
}
return fs, nil
@@ -730,26 +710,6 @@ func (f zipFile) Path() string { return f.name }
func (f zipFile) Lstat() (os.FileInfo, error) { return f.f.FileInfo(), nil }
func (f zipFile) Open() (io.ReadCloser, error) { return f.f.Open() }
type dataFile struct {
name string
data []byte
}
func (f dataFile) Path() string { return f.name }
func (f dataFile) Lstat() (os.FileInfo, error) { return dataFileInfo{f}, nil }
func (f dataFile) Open() (io.ReadCloser, error) { return io.NopCloser(bytes.NewReader(f.data)), nil }
type dataFileInfo struct {
f dataFile
}
func (fi dataFileInfo) Name() string { return path.Base(fi.f.name) }
func (fi dataFileInfo) Size() int64 { return int64(len(fi.f.data)) }
func (fi dataFileInfo) Mode() os.FileMode { return 0644 }
func (fi dataFileInfo) ModTime() time.Time { return time.Time{} }
func (fi dataFileInfo) IsDir() bool { return false }
func (fi dataFileInfo) Sys() interface{} { return nil }
// isVendoredPackage attempts to report whether the given filename is contained
// in a package whose import path contains (but does not end with) the component
// "vendor".

View File

@@ -519,7 +519,7 @@ ccflags="$@"
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MREMAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ ||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ ||
$2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ ||
$2 ~ /^NFC_.*_(MAX)?SIZE$/ ||
$2 ~ /^RAW_PAYLOAD_/ ||

View File

@@ -1,40 +0,0 @@
// Copyright 2023 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.
//go:build linux
// +build linux
package unix
import "unsafe"
type mremapMmapper struct {
mmapper
mremap func(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error)
}
func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
if newLength <= 0 || len(oldData) == 0 || len(oldData) != cap(oldData) || flags&MREMAP_FIXED != 0 {
return nil, EINVAL
}
pOld := &oldData[cap(oldData)-1]
m.Lock()
defer m.Unlock()
bOld := m.active[pOld]
if bOld == nil || &bOld[0] != &oldData[0] {
return nil, EINVAL
}
newAddr, errno := m.mremap(uintptr(unsafe.Pointer(&bOld[0])), uintptr(len(bOld)), uintptr(newLength), flags, 0)
if errno != nil {
return nil, errno
}
bNew := unsafe.Slice((*byte)(unsafe.Pointer(newAddr)), newLength)
pNew := &bNew[cap(bNew)-1]
if flags&MREMAP_DONTUNMAP == 0 {
delete(m.active, pOld)
}
m.active[pNew] = bNew
return bNew, nil
}

View File

@@ -2124,15 +2124,11 @@ func writevRacedetect(iovecs []Iovec, n int) {
// mmap varies by architecture; see syscall_linux_*.go.
//sys munmap(addr uintptr, length uintptr) (err error)
//sys mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error)
var mapper = &mremapMmapper{
mmapper: mmapper{
active: make(map[*byte][]byte),
mmap: mmap,
munmap: munmap,
},
mremap: mremap,
var mapper = &mmapper{
active: make(map[*byte][]byte),
mmap: mmap,
munmap: munmap,
}
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
@@ -2143,10 +2139,6 @@ func Munmap(b []byte) (err error) {
return mapper.Munmap(b)
}
func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
return mapper.Mremap(oldData, newLength, flags)
}
//sys Madvise(b []byte, advice int) (err error)
//sys Mprotect(b []byte, prot int) (err error)
//sys Mlock(b []byte) (err error)
@@ -2495,6 +2487,7 @@ func Getresgid() (rgid, egid, sgid int) {
// MqTimedreceive
// MqTimedsend
// MqUnlink
// Mremap
// Msgctl
// Msgget
// Msgrcv

View File

@@ -493,7 +493,6 @@ const (
BPF_F_TEST_RUN_ON_CPU = 0x1
BPF_F_TEST_STATE_FREQ = 0x8
BPF_F_TEST_XDP_LIVE_FRAMES = 0x2
BPF_F_XDP_DEV_BOUND_ONLY = 0x40
BPF_F_XDP_HAS_FRAGS = 0x20
BPF_H = 0x8
BPF_IMM = 0x0
@@ -827,9 +826,9 @@ const (
DM_UUID_FLAG = 0x4000
DM_UUID_LEN = 0x81
DM_VERSION = 0xc138fd00
DM_VERSION_EXTRA = "-ioctl (2023-03-01)"
DM_VERSION_EXTRA = "-ioctl (2022-07-28)"
DM_VERSION_MAJOR = 0x4
DM_VERSION_MINOR = 0x30
DM_VERSION_MINOR = 0x2f
DM_VERSION_PATCHLEVEL = 0x0
DT_BLK = 0x6
DT_CHR = 0x2
@@ -1198,7 +1197,6 @@ const (
FAN_EVENT_METADATA_LEN = 0x18
FAN_EVENT_ON_CHILD = 0x8000000
FAN_FS_ERROR = 0x8000
FAN_INFO = 0x20
FAN_MARK_ADD = 0x1
FAN_MARK_DONT_FOLLOW = 0x4
FAN_MARK_EVICTABLE = 0x200
@@ -1235,8 +1233,6 @@ const (
FAN_REPORT_PIDFD = 0x80
FAN_REPORT_TARGET_FID = 0x1000
FAN_REPORT_TID = 0x100
FAN_RESPONSE_INFO_AUDIT_RULE = 0x1
FAN_RESPONSE_INFO_NONE = 0x0
FAN_UNLIMITED_MARKS = 0x20
FAN_UNLIMITED_QUEUE = 0x10
FD_CLOEXEC = 0x1
@@ -1864,7 +1860,6 @@ const (
MEMWRITEOOB64 = 0xc0184d15
MFD_ALLOW_SEALING = 0x2
MFD_CLOEXEC = 0x1
MFD_EXEC = 0x10
MFD_HUGETLB = 0x4
MFD_HUGE_16GB = 0x88000000
MFD_HUGE_16MB = 0x60000000
@@ -1880,7 +1875,6 @@ const (
MFD_HUGE_8MB = 0x5c000000
MFD_HUGE_MASK = 0x3f
MFD_HUGE_SHIFT = 0x1a
MFD_NOEXEC_SEAL = 0x8
MINIX2_SUPER_MAGIC = 0x2468
MINIX2_SUPER_MAGIC2 = 0x2478
MINIX3_SUPER_MAGIC = 0x4d5a
@@ -1904,9 +1898,6 @@ const (
MOUNT_ATTR_SIZE_VER0 = 0x20
MOUNT_ATTR_STRICTATIME = 0x20
MOUNT_ATTR__ATIME = 0x70
MREMAP_DONTUNMAP = 0x4
MREMAP_FIXED = 0x2
MREMAP_MAYMOVE = 0x1
MSDOS_SUPER_MAGIC = 0x4d44
MSG_BATCH = 0x40000
MSG_CMSG_CLOEXEC = 0x40000000
@@ -2213,7 +2204,6 @@ const (
PACKET_USER = 0x6
PACKET_VERSION = 0xa
PACKET_VNET_HDR = 0xf
PACKET_VNET_HDR_SZ = 0x18
PARITY_CRC16_PR0 = 0x2
PARITY_CRC16_PR0_CCITT = 0x4
PARITY_CRC16_PR1 = 0x3
@@ -2231,7 +2221,6 @@ const (
PERF_ATTR_SIZE_VER5 = 0x70
PERF_ATTR_SIZE_VER6 = 0x78
PERF_ATTR_SIZE_VER7 = 0x80
PERF_ATTR_SIZE_VER8 = 0x88
PERF_AUX_FLAG_COLLISION = 0x8
PERF_AUX_FLAG_CORESIGHT_FORMAT_CORESIGHT = 0x0
PERF_AUX_FLAG_CORESIGHT_FORMAT_RAW = 0x100
@@ -2372,7 +2361,6 @@ const (
PR_FP_EXC_UND = 0x40000
PR_FP_MODE_FR = 0x1
PR_FP_MODE_FRE = 0x2
PR_GET_AUXV = 0x41555856
PR_GET_CHILD_SUBREAPER = 0x25
PR_GET_DUMPABLE = 0x3
PR_GET_ENDIAN = 0x13
@@ -2381,8 +2369,6 @@ const (
PR_GET_FP_MODE = 0x2e
PR_GET_IO_FLUSHER = 0x3a
PR_GET_KEEPCAPS = 0x7
PR_GET_MDWE = 0x42
PR_GET_MEMORY_MERGE = 0x44
PR_GET_NAME = 0x10
PR_GET_NO_NEW_PRIVS = 0x27
PR_GET_PDEATHSIG = 0x2
@@ -2403,7 +2389,6 @@ const (
PR_MCE_KILL_GET = 0x22
PR_MCE_KILL_LATE = 0x0
PR_MCE_KILL_SET = 0x1
PR_MDWE_REFUSE_EXEC_GAIN = 0x1
PR_MPX_DISABLE_MANAGEMENT = 0x2c
PR_MPX_ENABLE_MANAGEMENT = 0x2b
PR_MTE_TAG_MASK = 0x7fff8
@@ -2438,8 +2423,6 @@ const (
PR_SET_FP_MODE = 0x2d
PR_SET_IO_FLUSHER = 0x39
PR_SET_KEEPCAPS = 0x8
PR_SET_MDWE = 0x41
PR_SET_MEMORY_MERGE = 0x43
PR_SET_MM = 0x23
PR_SET_MM_ARG_END = 0x9
PR_SET_MM_ARG_START = 0x8
@@ -2523,7 +2506,6 @@ const (
PTRACE_GETSIGMASK = 0x420a
PTRACE_GET_RSEQ_CONFIGURATION = 0x420f
PTRACE_GET_SYSCALL_INFO = 0x420e
PTRACE_GET_SYSCALL_USER_DISPATCH_CONFIG = 0x4211
PTRACE_INTERRUPT = 0x4207
PTRACE_KILL = 0x8
PTRACE_LISTEN = 0x4208
@@ -2554,7 +2536,6 @@ const (
PTRACE_SETREGSET = 0x4205
PTRACE_SETSIGINFO = 0x4203
PTRACE_SETSIGMASK = 0x420b
PTRACE_SET_SYSCALL_USER_DISPATCH_CONFIG = 0x4210
PTRACE_SINGLESTEP = 0x9
PTRACE_SYSCALL = 0x18
PTRACE_SYSCALL_INFO_ENTRY = 0x1
@@ -3091,7 +3072,7 @@ const (
TASKSTATS_GENL_NAME = "TASKSTATS"
TASKSTATS_GENL_VERSION = 0x1
TASKSTATS_TYPE_MAX = 0x6
TASKSTATS_VERSION = 0xe
TASKSTATS_VERSION = 0xd
TCIFLUSH = 0x0
TCIOFF = 0x2
TCIOFLUSH = 0x2
@@ -3257,7 +3238,6 @@ const (
TP_STATUS_COPY = 0x2
TP_STATUS_CSUMNOTREADY = 0x8
TP_STATUS_CSUM_VALID = 0x80
TP_STATUS_GSO_TCP = 0x100
TP_STATUS_KERNEL = 0x0
TP_STATUS_LOSING = 0x4
TP_STATUS_SENDING = 0x2

View File

@@ -443,7 +443,6 @@ const (
TIOCSWINSZ = 0x5414
TIOCVHANGUP = 0x5437
TOSTOP = 0x100
TPIDR2_MAGIC = 0x54504902
TUNATTACHFILTER = 0x401054d5
TUNDETACHFILTER = 0x401054d6
TUNGETDEVNETNS = 0x54e3
@@ -516,7 +515,6 @@ const (
XCASE = 0x4
XTABS = 0x1800
ZA_MAGIC = 0x54366345
ZT_MAGIC = 0x5a544e01
_HIDIOCGRAWNAME = 0x80804804
_HIDIOCGRAWPHYS = 0x80404805
_HIDIOCGRAWUNIQ = 0x80404808

View File

@@ -1868,17 +1868,6 @@ func munmap(addr uintptr, length uintptr) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error) {
r0, _, e1 := Syscall6(SYS_MREMAP, uintptr(oldaddr), uintptr(oldlength), uintptr(newlength), uintptr(flags), uintptr(newaddr), 0)
xaddr = uintptr(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Madvise(b []byte, advice int) (err error) {
var _p0 unsafe.Pointer
if len(b) > 0 {

View File

@@ -372,7 +372,6 @@ const (
SYS_LANDLOCK_CREATE_RULESET = 444
SYS_LANDLOCK_ADD_RULE = 445
SYS_LANDLOCK_RESTRICT_SELF = 446
SYS_MEMFD_SECRET = 447
SYS_PROCESS_MRELEASE = 448
SYS_FUTEX_WAITV = 449
SYS_SET_MEMPOLICY_HOME_NODE = 450

View File

@@ -1538,10 +1538,6 @@ const (
IFLA_GRO_MAX_SIZE = 0x3a
IFLA_TSO_MAX_SIZE = 0x3b
IFLA_TSO_MAX_SEGS = 0x3c
IFLA_ALLMULTI = 0x3d
IFLA_DEVLINK_PORT = 0x3e
IFLA_GSO_IPV4_MAX_SIZE = 0x3f
IFLA_GRO_IPV4_MAX_SIZE = 0x40
IFLA_PROTO_DOWN_REASON_UNSPEC = 0x0
IFLA_PROTO_DOWN_REASON_MASK = 0x1
IFLA_PROTO_DOWN_REASON_VALUE = 0x2
@@ -1972,7 +1968,7 @@ const (
NFT_MSG_GETFLOWTABLE = 0x17
NFT_MSG_DELFLOWTABLE = 0x18
NFT_MSG_GETRULE_RESET = 0x19
NFT_MSG_MAX = 0x21
NFT_MSG_MAX = 0x1a
NFTA_LIST_UNSPEC = 0x0
NFTA_LIST_ELEM = 0x1
NFTA_HOOK_UNSPEC = 0x0
@@ -3655,7 +3651,7 @@ const (
ETHTOOL_MSG_PSE_GET = 0x24
ETHTOOL_MSG_PSE_SET = 0x25
ETHTOOL_MSG_RSS_GET = 0x26
ETHTOOL_MSG_USER_MAX = 0x2b
ETHTOOL_MSG_USER_MAX = 0x26
ETHTOOL_MSG_KERNEL_NONE = 0x0
ETHTOOL_MSG_STRSET_GET_REPLY = 0x1
ETHTOOL_MSG_LINKINFO_GET_REPLY = 0x2
@@ -3695,7 +3691,7 @@ const (
ETHTOOL_MSG_MODULE_NTF = 0x24
ETHTOOL_MSG_PSE_GET_REPLY = 0x25
ETHTOOL_MSG_RSS_GET_REPLY = 0x26
ETHTOOL_MSG_KERNEL_MAX = 0x2b
ETHTOOL_MSG_KERNEL_MAX = 0x26
ETHTOOL_A_HEADER_UNSPEC = 0x0
ETHTOOL_A_HEADER_DEV_INDEX = 0x1
ETHTOOL_A_HEADER_DEV_NAME = 0x2
@@ -3799,7 +3795,7 @@ const (
ETHTOOL_A_RINGS_TCP_DATA_SPLIT = 0xb
ETHTOOL_A_RINGS_CQE_SIZE = 0xc
ETHTOOL_A_RINGS_TX_PUSH = 0xd
ETHTOOL_A_RINGS_MAX = 0x10
ETHTOOL_A_RINGS_MAX = 0xd
ETHTOOL_A_CHANNELS_UNSPEC = 0x0
ETHTOOL_A_CHANNELS_HEADER = 0x1
ETHTOOL_A_CHANNELS_RX_MAX = 0x2
@@ -3837,14 +3833,14 @@ const (
ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL = 0x17
ETHTOOL_A_COALESCE_USE_CQE_MODE_TX = 0x18
ETHTOOL_A_COALESCE_USE_CQE_MODE_RX = 0x19
ETHTOOL_A_COALESCE_MAX = 0x1c
ETHTOOL_A_COALESCE_MAX = 0x19
ETHTOOL_A_PAUSE_UNSPEC = 0x0
ETHTOOL_A_PAUSE_HEADER = 0x1
ETHTOOL_A_PAUSE_AUTONEG = 0x2
ETHTOOL_A_PAUSE_RX = 0x3
ETHTOOL_A_PAUSE_TX = 0x4
ETHTOOL_A_PAUSE_STATS = 0x5
ETHTOOL_A_PAUSE_MAX = 0x6
ETHTOOL_A_PAUSE_MAX = 0x5
ETHTOOL_A_PAUSE_STAT_UNSPEC = 0x0
ETHTOOL_A_PAUSE_STAT_PAD = 0x1
ETHTOOL_A_PAUSE_STAT_TX_FRAMES = 0x2
@@ -4494,7 +4490,7 @@ const (
NL80211_ATTR_MAC_HINT = 0xc8
NL80211_ATTR_MAC_MASK = 0xd7
NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca
NL80211_ATTR_MAX = 0x145
NL80211_ATTR_MAX = 0x141
NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4
NL80211_ATTR_MAX_CSA_COUNTERS = 0xce
NL80211_ATTR_MAX_MATCH_SETS = 0x85
@@ -4723,7 +4719,7 @@ const (
NL80211_BAND_ATTR_HT_CAPA = 0x4
NL80211_BAND_ATTR_HT_MCS_SET = 0x3
NL80211_BAND_ATTR_IFTYPE_DATA = 0x9
NL80211_BAND_ATTR_MAX = 0xd
NL80211_BAND_ATTR_MAX = 0xb
NL80211_BAND_ATTR_RATES = 0x2
NL80211_BAND_ATTR_VHT_CAPA = 0x8
NL80211_BAND_ATTR_VHT_MCS_SET = 0x7
@@ -4864,7 +4860,7 @@ const (
NL80211_CMD_LEAVE_IBSS = 0x2c
NL80211_CMD_LEAVE_MESH = 0x45
NL80211_CMD_LEAVE_OCB = 0x6d
NL80211_CMD_MAX = 0x99
NL80211_CMD_MAX = 0x98
NL80211_CMD_MICHAEL_MIC_FAILURE = 0x29
NL80211_CMD_MODIFY_LINK_STA = 0x97
NL80211_CMD_NAN_MATCH = 0x78
@@ -5845,8 +5841,6 @@ const (
TUN_F_TSO6 = 0x4
TUN_F_TSO_ECN = 0x8
TUN_F_UFO = 0x10
TUN_F_USO4 = 0x20
TUN_F_USO6 = 0x40
)
const (
@@ -5856,10 +5850,9 @@ const (
)
const (
VIRTIO_NET_HDR_GSO_NONE = 0x0
VIRTIO_NET_HDR_GSO_TCPV4 = 0x1
VIRTIO_NET_HDR_GSO_UDP = 0x3
VIRTIO_NET_HDR_GSO_TCPV6 = 0x4
VIRTIO_NET_HDR_GSO_UDP_L4 = 0x5
VIRTIO_NET_HDR_GSO_ECN = 0x80
VIRTIO_NET_HDR_GSO_NONE = 0x0
VIRTIO_NET_HDR_GSO_TCPV4 = 0x1
VIRTIO_NET_HDR_GSO_UDP = 0x3
VIRTIO_NET_HDR_GSO_TCPV6 = 0x4
VIRTIO_NET_HDR_GSO_ECN = 0x80
)

View File

@@ -337,8 +337,6 @@ type Taskstats struct {
Ac_exe_inode uint64
Wpcopy_count uint64
Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
}
type cpuMask uint32

View File

@@ -350,8 +350,6 @@ type Taskstats struct {
Ac_exe_inode uint64
Wpcopy_count uint64
Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
}
type cpuMask uint64

View File

@@ -328,8 +328,6 @@ type Taskstats struct {
Ac_exe_inode uint64
Wpcopy_count uint64
Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
}
type cpuMask uint32

View File

@@ -329,8 +329,6 @@ type Taskstats struct {
Ac_exe_inode uint64
Wpcopy_count uint64
Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
}
type cpuMask uint64

View File

@@ -330,8 +330,6 @@ type Taskstats struct {
Ac_exe_inode uint64
Wpcopy_count uint64
Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
}
type cpuMask uint64

View File

@@ -333,8 +333,6 @@ type Taskstats struct {
Ac_exe_inode uint64
Wpcopy_count uint64
Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
}
type cpuMask uint32

View File

@@ -332,8 +332,6 @@ type Taskstats struct {
Ac_exe_inode uint64
Wpcopy_count uint64
Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
}
type cpuMask uint64

View File

@@ -332,8 +332,6 @@ type Taskstats struct {
Ac_exe_inode uint64
Wpcopy_count uint64
Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
}
type cpuMask uint64

View File

@@ -333,8 +333,6 @@ type Taskstats struct {
Ac_exe_inode uint64
Wpcopy_count uint64
Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
}
type cpuMask uint32

View File

@@ -340,8 +340,6 @@ type Taskstats struct {
Ac_exe_inode uint64
Wpcopy_count uint64
Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
}
type cpuMask uint32

View File

@@ -339,8 +339,6 @@ type Taskstats struct {
Ac_exe_inode uint64
Wpcopy_count uint64
Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
}
type cpuMask uint64

View File

@@ -339,8 +339,6 @@ type Taskstats struct {
Ac_exe_inode uint64
Wpcopy_count uint64
Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
}
type cpuMask uint64

View File

@@ -357,8 +357,6 @@ type Taskstats struct {
Ac_exe_inode uint64
Wpcopy_count uint64
Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
}
type cpuMask uint64

View File

@@ -352,8 +352,6 @@ type Taskstats struct {
Ac_exe_inode uint64
Wpcopy_count uint64
Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
}
type cpuMask uint64

View File

@@ -334,8 +334,6 @@ type Taskstats struct {
Ac_exe_inode uint64
Wpcopy_count uint64
Wpcopy_delay_total uint64
Irq_count uint64
Irq_delay_total uint64
}
type cpuMask uint64

View File

@@ -218,10 +218,6 @@ type SERVICE_FAILURE_ACTIONS struct {
Actions *SC_ACTION
}
type SERVICE_FAILURE_ACTIONS_FLAG struct {
FailureActionsOnNonCrashFailures int32
}
type SC_ACTION struct {
Type uint32
Delay uint32

View File

@@ -60,7 +60,7 @@ func restore(fd int, state *State) error {
func getSize(fd int) (width, height int, err error) {
ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
if err != nil {
return 0, 0, err
return -1, -1, err
}
return int(ws.Col), int(ws.Row), nil
}

View File

@@ -271,7 +271,6 @@ func typeCheckCgoSourceFiles(fset *token.FileSet, pkg *types.Package, files []*a
Sizes: sizes,
Error: func(error) {}, // ignore errors (e.g. unused import)
}
setGoVersion(tc, pkg)
// It's tempting to record the new types in the
// existing pass.TypesInfo, but we don't own it.

View File

@@ -1,13 +0,0 @@
// Copyright 2023 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.
//go:build !go1.21
package cgocall
import "go/types"
func setGoVersion(tc *types.Config, pkg *types.Package) {
// no types.Package.GoVersion until Go 1.21
}

View File

@@ -1,13 +0,0 @@
// Copyright 2023 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.
//go:build go1.21
package cgocall
import "go/types"
func setGoVersion(tc *types.Config, pkg *types.Package) {
tc.GoVersion = pkg.GoVersion()
}

View File

@@ -118,3 +118,12 @@ func Imports(pkg *types.Package, path string) bool {
}
return false
}
// IsNamed reports whether t is exactly a named type in a package with a given path.
func IsNamed(t types.Type, path, name string) bool {
if n, ok := t.(*types.Named); ok {
obj := n.Obj()
return obj.Pkg().Path() == path && obj.Name() == name
}
return false
}

View File

@@ -139,7 +139,7 @@ func run(pass *analysis.Pass) (any, error) {
}
func isAttr(t types.Type) bool {
return isNamed(t, "log/slog", "Attr")
return analysisutil.IsNamed(t, "log/slog", "Attr")
}
// shortName returns a name for the function that is shorter than FullName.
@@ -195,28 +195,28 @@ func kvFuncSkipArgs(fn *types.Func) (int, bool) {
// The first key is the dereferenced receiver type name, or "" for a function.
var kvFuncs = map[string]map[string]int{
"": map[string]int{
"Debug": 1,
"Info": 1,
"Warn": 1,
"Error": 1,
"DebugContext": 2,
"InfoContext": 2,
"WarnContext": 2,
"ErrorContext": 2,
"Log": 3,
"Group": 1,
"Debug": 1,
"Info": 1,
"Warn": 1,
"Error": 1,
"DebugCtx": 2,
"InfoCtx": 2,
"WarnCtx": 2,
"ErrorCtx": 2,
"Log": 3,
"Group": 1,
},
"Logger": map[string]int{
"Debug": 1,
"Info": 1,
"Warn": 1,
"Error": 1,
"DebugContext": 2,
"InfoContext": 2,
"WarnContext": 2,
"ErrorContext": 2,
"Log": 3,
"With": 0,
"Debug": 1,
"Info": 1,
"Warn": 1,
"Error": 1,
"DebugCtx": 2,
"InfoCtx": 2,
"WarnCtx": 2,
"ErrorCtx": 2,
"Log": 3,
"With": 0,
},
"Record": map[string]int{
"Add": 0,
@@ -232,12 +232,3 @@ func isMethodExpr(info *types.Info, c *ast.CallExpr) bool {
sel := info.Selections[s]
return sel != nil && sel.Kind() == types.MethodExpr
}
// isNamed reports whether t is exactly a named type in a package with a given path.
func isNamed(t types.Type, path, name string) bool {
if n, ok := t.(*types.Named); ok {
obj := n.Obj()
return obj.Pkg() != nil && obj.Pkg().Path() == path && obj.Name() == name
}
return false
}

View File

@@ -62,7 +62,6 @@ type Config struct {
Compiler string
Dir string
ImportPath string
GoVersion string // minimum required Go version, such as "go1.21.0"
GoFiles []string
NonGoFiles []string
IgnoredFiles []string
@@ -218,9 +217,8 @@ func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]re
return compilerImporter.Import(path)
})
tc := &types.Config{
Importer: importer,
Sizes: types.SizesFor("gc", build.Default.GOARCH), // assume gccgo ≡ gc?
GoVersion: cfg.GoVersion,
Importer: importer,
Sizes: types.SizesFor("gc", build.Default.GOARCH), // assume gccgo ≡ gc?
}
info := &types.Info{
Types: make(map[ast.Expr]types.TypeAndValue),

View File

@@ -64,9 +64,8 @@ type event struct {
// depth-first order. It calls f(n) for each node n before it visits
// n's children.
//
// The complete traversal sequence is determined by ast.Inspect.
// The types argument, if non-empty, enables type-based filtering of
// events. The function f is called only for nodes whose type
// events. The function f if is called only for nodes whose type
// matches an element of the types slice.
func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node)) {
// Because it avoids postorder calls to f, and the pruning
@@ -98,7 +97,6 @@ func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node)) {
// of the non-nil children of the node, followed by a call of
// f(n, false).
//
// The complete traversal sequence is determined by ast.Inspect.
// The types argument, if non-empty, enables type-based filtering of
// events. The function f if is called only for nodes whose type
// matches an element of the types slice.

View File

@@ -137,17 +137,6 @@ type Encoder struct {
// These objects are sufficient to define the API of their package.
// The objects described by a package's export data are drawn from this set.
//
// The set of objects accessible from a package's Scope depends on
// whether the package was produced by type-checking syntax, or
// reading export data; the latter may have a smaller Scope since
// export data trims objects that are not reachable from an exported
// declaration. For example, the For function will return a path for
// an exported method of an unexported type that is not reachable
// from any public declaration; this path will cause the Object
// function to fail if called on a package loaded from export data.
// TODO(adonovan): is this a bug or feature? Should this package
// compute accessibility in the same way?
//
// For does not return a path for predeclared names, imported package
// names, local names, and unexported package-level names (except
// types).

View File

@@ -158,52 +158,24 @@ type gobFact struct {
// for the same package. Each call to Decode returns an independent
// fact set.
type Decoder struct {
pkg *types.Package
getPackage GetPackageFunc
pkg *types.Package
packages map[string]*types.Package
}
// NewDecoder returns a fact decoder for the specified package.
//
// It uses a brute-force recursive approach to enumerate all objects
// defined by dependencies of pkg, so that it can learn the set of
// package paths that may be mentioned in the fact encoding. This does
// not scale well; use [NewDecoderFunc] where possible.
func NewDecoder(pkg *types.Package) *Decoder {
// Compute the import map for this package.
// See the package doc comment.
m := importMap(pkg.Imports())
getPackageFunc := func(path string) *types.Package { return m[path] }
return NewDecoderFunc(pkg, getPackageFunc)
return &Decoder{pkg, importMap(pkg.Imports())}
}
// NewDecoderFunc returns a fact decoder for the specified package.
//
// It calls the getPackage function for the package path string of
// each dependency (perhaps indirect) that it encounters in the
// encoding. If the function returns nil, the fact is discarded.
//
// This function is preferred over [NewDecoder] when the client is
// capable of efficient look-up of packages by package path.
func NewDecoderFunc(pkg *types.Package, getPackage GetPackageFunc) *Decoder {
return &Decoder{
pkg: pkg,
getPackage: getPackage,
}
}
// A GetPackageFunc function returns the package denoted by a package path.
type GetPackageFunc = func(pkgPath string) *types.Package
// Decode decodes all the facts relevant to the analysis of package
// pkg. The read function reads serialized fact data from an external
// source for one of pkg's direct imports, identified by package path.
// The empty file is a valid encoding of an empty fact set.
// Decode decodes all the facts relevant to the analysis of package pkg.
// The read function reads serialized fact data from an external source
// for one of of pkg's direct imports. The empty file is a valid
// encoding of an empty fact set.
//
// It is the caller's responsibility to call gob.Register on all
// necessary fact types.
//
// Concurrent calls to Decode are safe, so long as the
// [GetPackageFunc] (if any) is also concurrency-safe.
func (d *Decoder) Decode(read func(*types.Package) ([]byte, error)) (*Set, error) {
// Read facts from imported packages.
// Facts may describe indirectly imported packages, or their objects.
@@ -230,11 +202,13 @@ func (d *Decoder) Decode(read func(*types.Package) ([]byte, error)) (*Set, error
if err := gob.NewDecoder(bytes.NewReader(data)).Decode(&gobFacts); err != nil {
return nil, fmt.Errorf("decoding facts for %q: %v", imp.Path(), err)
}
logf("decoded %d facts: %v", len(gobFacts), gobFacts)
if debug {
logf("decoded %d facts: %v", len(gobFacts), gobFacts)
}
// Parse each one into a key and a Fact.
for _, f := range gobFacts {
factPkg := d.getPackage(f.PkgPath) // possibly an indirect dependency
factPkg := d.packages[f.PkgPath]
if factPkg == nil {
// Fact relates to a dependency that was
// unused in this translation unit. Skip.

View File

@@ -21,10 +21,6 @@ import (
// Packages in the map that are only indirectly imported may be
// incomplete (!pkg.Complete()).
//
// This function scales very poorly with packages' transitive object
// references, which can be more than a million for each package near
// the top of a large project. (This was a significant contributor to
// #60621.)
// TODO(adonovan): opt: compute this information more efficiently
// by obtaining it from the internals of the gcexportdata decoder.
func importMap(imports []*types.Package) map[string]*types.Package {

View File

@@ -17,13 +17,13 @@ github.com/google/pprof/third_party/svgpan
# github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2
## explicit; go 1.12
github.com/ianlancetaylor/demangle
# golang.org/x/arch v0.4.0
# golang.org/x/arch v0.3.0
## explicit; go 1.17
golang.org/x/arch/arm/armasm
golang.org/x/arch/arm64/arm64asm
golang.org/x/arch/ppc64/ppc64asm
golang.org/x/arch/x86/x86asm
# golang.org/x/mod v0.12.0
# golang.org/x/mod v0.10.1-0.20230606122920-62c7e578f1a7
## explicit; go 1.17
golang.org/x/mod/internal/lazyregexp
golang.org/x/mod/modfile
@@ -34,19 +34,19 @@ golang.org/x/mod/sumdb/dirhash
golang.org/x/mod/sumdb/note
golang.org/x/mod/sumdb/tlog
golang.org/x/mod/zip
# golang.org/x/sync v0.3.0
# golang.org/x/sync v0.2.1-0.20230601203510-93782cc822b6
## explicit; go 1.17
golang.org/x/sync/semaphore
# golang.org/x/sys v0.10.0
# golang.org/x/sys v0.9.0
## explicit; go 1.17
golang.org/x/sys/internal/unsafeheader
golang.org/x/sys/plan9
golang.org/x/sys/unix
golang.org/x/sys/windows
# golang.org/x/term v0.10.0
# golang.org/x/term v0.9.0
## explicit; go 1.17
golang.org/x/term
# golang.org/x/tools v0.11.1-0.20230712164437-1ca21856af7b
# golang.org/x/tools v0.9.4-0.20230613194514-c6c983054920
## explicit; go 1.18
golang.org/x/tools/cmd/bisect
golang.org/x/tools/cover

View File

@@ -3,11 +3,11 @@ module std
go 1.21
require (
golang.org/x/crypto v0.11.1-0.20230711161743-2e82bdd1719d
golang.org/x/net v0.12.1-0.20230712162946-57553cbff163
golang.org/x/crypto v0.10.0
golang.org/x/net v0.11.1-0.20230613203745-f5464ddb689c
)
require (
golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/text v0.10.1-0.20230613190012-2df65d769a9e // indirect
)

View File

@@ -1,8 +1,8 @@
golang.org/x/crypto v0.11.1-0.20230711161743-2e82bdd1719d h1:LiA25/KWKuXfIq5pMIBq1s5hz3HQxhJJSu/SUGlD+SM=
golang.org/x/crypto v0.11.1-0.20230711161743-2e82bdd1719d/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/net v0.12.1-0.20230712162946-57553cbff163 h1:1EDKNuaCsog7zGLEml1qRuO4gt23jORUQX2f0IKZ860=
golang.org/x/net v0.12.1-0.20230712162946-57553cbff163/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/net v0.11.1-0.20230613203745-f5464ddb689c h1:icjsA5jFPWsTcuIb/yIeU6mgXRHPQBfo0Lzd1GQmKZI=
golang.org/x/net v0.11.1-0.20230613203745-f5464ddb689c/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.10.1-0.20230613190012-2df65d769a9e h1:GTf7SHdimRGQ2uYYuJ0eJUoAEJ9ufU2ocSTVWnbeVQc=
golang.org/x/text v0.10.1-0.20230613190012-2df65d769a9e/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=

View File

@@ -68,7 +68,7 @@ func (m *Merger) SaturatingAdd(dst, src uint32) uint32 {
return result
}
// Saturating add does a saturating addition of 'dst' and 'src',
// Saturating add does a saturing addition of 'dst' and 'src',
// returning added value or math.MaxUint32 plus an overflow flag.
func SaturatingAdd(dst, src uint32) (uint32, bool) {
d, s := uint64(dst), uint64(src)

View File

@@ -76,7 +76,7 @@ func Diff(oldName string, old []byte, newName string, new []byte) []byte {
// Expand matching lines as far possible,
// establishing that x[start.x:end.x] == y[start.y:end.y].
// Note that on the first (or last) iteration we may (or definitely do)
// Note that on the first (or last) iteration we may (or definitey do)
// have an empty match: start.x==end.x and start.y==end.y.
start := m
for start.x > done.x && start.y > done.y && x[start.x-1] == y[start.y-1] {

View File

@@ -37,7 +37,6 @@ var All = []Info{
//{Name: "multipartfiles", Package: "mime/multipart"},
{Name: "multipartmaxheaders", Package: "mime/multipart"},
{Name: "multipartmaxparts", Package: "mime/multipart"},
{Name: "multipathtcp", Package: "net"},
{Name: "netdns", Package: "net", Opaque: true},
{Name: "panicnil", Package: "runtime", Changed: 21, Old: "1"},
{Name: "randautoseed", Package: "math/rand"},

View File

@@ -163,8 +163,8 @@ func CommandContext(t testing.TB, ctx context.Context, name string, args ...stri
// grace periods to clean up: one for the delay between the first
// termination signal being sent (via the Cancel callback when the Context
// expires) and the process being forcibly terminated (via the WaitDelay
// field), and a second one for the delay between the process being
// terminated and the test logging its output for debugging.
// field), and a second one for the delay becween the process being
// terminated and and the test logging its output for debugging.
//
// (We want to ensure that the test process itself has enough time to
// log the output before it is also terminated.)

View File

@@ -174,9 +174,9 @@ argument, as do their corresponding top-level functions.
Although the convenience methods on Logger (Info and so on) and the
corresponding top-level functions do not take a context, the alternatives ending
in "Context" do. For example,
in "Ctx" do. For example,
slog.InfoContext(ctx, "message")
slog.InfoCtx(ctx, "message")
It is recommended to pass a context to an output method if one is available.
@@ -206,7 +206,7 @@ keys and values; this allows it, too, to avoid allocation.
The call
logger.LogAttrs(ctx, slog.LevelInfo, "hello", slog.Int("count", 3))
logger.LogAttrs(nil, slog.LevelInfo, "hello", slog.Int("count", 3))
is the most efficient way to achieve the same output as

View File

@@ -5,7 +5,6 @@
package slog_test
import (
"context"
"log/slog"
"os"
)
@@ -73,14 +72,13 @@ func ExampleHandlerOptions_customLevels() {
})
logger := slog.New(th)
ctx := context.Background()
logger.Log(ctx, LevelEmergency, "missing pilots")
logger.Log(nil, LevelEmergency, "missing pilots")
logger.Error("failed to start engines", "err", "missing fuel")
logger.Warn("falling back to default value")
logger.Log(ctx, LevelNotice, "all systems are running")
logger.Log(nil, LevelNotice, "all systems are running")
logger.Info("initiating launch")
logger.Debug("starting background job")
logger.Log(ctx, LevelTrace, "button clicked")
logger.Log(nil, LevelTrace, "button clicked")
// Output:
// sev=EMERGENCY msg="missing pilots"

View File

@@ -108,6 +108,8 @@ func TestDefaultHandle(t *testing.T) {
// Verify the common parts of TextHandler and JSONHandler.
func TestJSONAndTextHandlers(t *testing.T) {
ctx := context.Background()
// remove all Attrs
removeAll := func(_ []string, a Attr) Attr { return Attr{} }
@@ -410,7 +412,7 @@ func TestJSONAndTextHandlers(t *testing.T) {
h = test.with(h)
}
buf.Reset()
if err := h.Handle(nil, r); err != nil {
if err := h.Handle(ctx, r); err != nil {
t.Fatal(err)
}
want := strings.ReplaceAll(handler.want, "$LINE", line)

View File

@@ -174,7 +174,6 @@ func BenchmarkJSONHandler(b *testing.B) {
}},
} {
b.Run(bench.name, func(b *testing.B) {
ctx := context.Background()
l := New(NewJSONHandler(io.Discard, &bench.opts)).With(
String("program", "my-test-program"),
String("package", "log/slog"),
@@ -183,7 +182,7 @@ func BenchmarkJSONHandler(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
l.LogAttrs(ctx, LevelInfo, "this is a typical log message",
l.LogAttrs(nil, LevelInfo, "this is a typical log message",
String("module", "github.com/google/go-cmp"),
String("version", "v1.23.4"),
Int("count", 23),
@@ -239,13 +238,12 @@ func BenchmarkPreformatting(b *testing.B) {
{"struct", io.Discard, structAttrs},
{"struct file", outFile, structAttrs},
} {
ctx := context.Background()
b.Run(bench.name, func(b *testing.B) {
l := New(NewJSONHandler(bench.wc, nil)).With(bench.attrs...)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
l.LogAttrs(ctx, LevelInfo, "this is a typical log message",
l.LogAttrs(nil, LevelInfo, "this is a typical log message",
String("module", "github.com/google/go-cmp"),
String("version", "v1.23.4"),
Int("count", 23),

View File

@@ -165,41 +165,41 @@ func (l *Logger) LogAttrs(ctx context.Context, level Level, msg string, attrs ..
// Debug logs at LevelDebug.
func (l *Logger) Debug(msg string, args ...any) {
l.log(context.Background(), LevelDebug, msg, args...)
l.log(nil, LevelDebug, msg, args...)
}
// DebugContext logs at LevelDebug with the given context.
func (l *Logger) DebugContext(ctx context.Context, msg string, args ...any) {
// DebugCtx logs at LevelDebug with the given context.
func (l *Logger) DebugCtx(ctx context.Context, msg string, args ...any) {
l.log(ctx, LevelDebug, msg, args...)
}
// Info logs at LevelInfo.
func (l *Logger) Info(msg string, args ...any) {
l.log(context.Background(), LevelInfo, msg, args...)
l.log(nil, LevelInfo, msg, args...)
}
// InfoContext logs at LevelInfo with the given context.
func (l *Logger) InfoContext(ctx context.Context, msg string, args ...any) {
// InfoCtx logs at LevelInfo with the given context.
func (l *Logger) InfoCtx(ctx context.Context, msg string, args ...any) {
l.log(ctx, LevelInfo, msg, args...)
}
// Warn logs at LevelWarn.
func (l *Logger) Warn(msg string, args ...any) {
l.log(context.Background(), LevelWarn, msg, args...)
l.log(nil, LevelWarn, msg, args...)
}
// WarnContext logs at LevelWarn with the given context.
func (l *Logger) WarnContext(ctx context.Context, msg string, args ...any) {
// WarnCtx logs at LevelWarn with the given context.
func (l *Logger) WarnCtx(ctx context.Context, msg string, args ...any) {
l.log(ctx, LevelWarn, msg, args...)
}
// Error logs at LevelError.
func (l *Logger) Error(msg string, args ...any) {
l.log(context.Background(), LevelError, msg, args...)
l.log(nil, LevelError, msg, args...)
}
// ErrorContext logs at LevelError with the given context.
func (l *Logger) ErrorContext(ctx context.Context, msg string, args ...any) {
// ErrorCtx logs at LevelError with the given context.
func (l *Logger) ErrorCtx(ctx context.Context, msg string, args ...any) {
l.log(ctx, LevelError, msg, args...)
}
@@ -247,41 +247,41 @@ func (l *Logger) logAttrs(ctx context.Context, level Level, msg string, attrs ..
// Debug calls Logger.Debug on the default logger.
func Debug(msg string, args ...any) {
Default().log(context.Background(), LevelDebug, msg, args...)
Default().log(nil, LevelDebug, msg, args...)
}
// DebugContext calls Logger.DebugContext on the default logger.
func DebugContext(ctx context.Context, msg string, args ...any) {
// DebugCtx calls Logger.DebugCtx on the default logger.
func DebugCtx(ctx context.Context, msg string, args ...any) {
Default().log(ctx, LevelDebug, msg, args...)
}
// Info calls Logger.Info on the default logger.
func Info(msg string, args ...any) {
Default().log(context.Background(), LevelInfo, msg, args...)
Default().log(nil, LevelInfo, msg, args...)
}
// InfoContext calls Logger.InfoContext on the default logger.
func InfoContext(ctx context.Context, msg string, args ...any) {
// InfoCtx calls Logger.InfoCtx on the default logger.
func InfoCtx(ctx context.Context, msg string, args ...any) {
Default().log(ctx, LevelInfo, msg, args...)
}
// Warn calls Logger.Warn on the default logger.
func Warn(msg string, args ...any) {
Default().log(context.Background(), LevelWarn, msg, args...)
Default().log(nil, LevelWarn, msg, args...)
}
// WarnContext calls Logger.WarnContext on the default logger.
func WarnContext(ctx context.Context, msg string, args ...any) {
// WarnCtx calls Logger.WarnCtx on the default logger.
func WarnCtx(ctx context.Context, msg string, args ...any) {
Default().log(ctx, LevelWarn, msg, args...)
}
// Error calls Logger.Error on the default logger.
func Error(msg string, args ...any) {
Default().log(context.Background(), LevelError, msg, args...)
Default().log(nil, LevelError, msg, args...)
}
// ErrorContext calls Logger.ErrorContext on the default logger.
func ErrorContext(ctx context.Context, msg string, args ...any) {
// ErrorCtx calls Logger.ErrorCtx on the default logger.
func ErrorCtx(ctx context.Context, msg string, args ...any) {
Default().log(ctx, LevelError, msg, args...)
}

View File

@@ -25,7 +25,6 @@ import (
const timeRE = `\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}(Z|[+-]\d{2}:\d{2})`
func TestLogTextHandler(t *testing.T) {
ctx := context.Background()
var buf bytes.Buffer
l := New(NewTextHandler(&buf, nil))
@@ -52,10 +51,10 @@ func TestLogTextHandler(t *testing.T) {
l.Error("bad", "a", 1)
check(`level=ERROR msg=bad a=1`)
l.Log(ctx, LevelWarn+1, "w", Int("a", 1), String("b", "two"))
l.Log(nil, LevelWarn+1, "w", Int("a", 1), String("b", "two"))
check(`level=WARN\+1 msg=w a=1 b=two`)
l.LogAttrs(ctx, LevelInfo+1, "a b c", Int("a", 1), String("b", "two"))
l.LogAttrs(nil, LevelInfo+1, "a b c", Int("a", 1), String("b", "two"))
check(`level=INFO\+1 msg="a b c" a=1 b=two`)
l.Info("info", "a", []Attr{Int("i", 1)})
@@ -157,7 +156,6 @@ func TestAttrs(t *testing.T) {
}
func TestCallDepth(t *testing.T) {
ctx := context.Background()
h := &captureHandler{}
var startLine int
@@ -183,9 +181,9 @@ func TestCallDepth(t *testing.T) {
startLine = f.Line + 4
// Do not change the number of lines between here and the call to check(0).
logger.Log(ctx, LevelInfo, "")
logger.Log(nil, LevelInfo, "")
check(0)
logger.LogAttrs(ctx, LevelInfo, "")
logger.LogAttrs(nil, LevelInfo, "")
check(1)
logger.Debug("")
check(2)
@@ -203,14 +201,13 @@ func TestCallDepth(t *testing.T) {
check(8)
Error("")
check(9)
Log(ctx, LevelInfo, "")
Log(nil, LevelInfo, "")
check(10)
LogAttrs(ctx, LevelInfo, "")
LogAttrs(nil, LevelInfo, "")
check(11)
}
func TestAlloc(t *testing.T) {
ctx := context.Background()
dl := New(discardHandler{})
defer SetDefault(Default()) // restore
SetDefault(dl)
@@ -225,7 +222,7 @@ func TestAlloc(t *testing.T) {
wantAllocs(t, 0, func() { dl.Info("hello") })
})
t.Run("logger.Log", func(t *testing.T) {
wantAllocs(t, 0, func() { dl.Log(ctx, LevelDebug, "hello") })
wantAllocs(t, 0, func() { dl.Log(nil, LevelDebug, "hello") })
})
t.Run("2 pairs", func(t *testing.T) {
s := "abc"
@@ -242,7 +239,7 @@ func TestAlloc(t *testing.T) {
s := "abc"
i := 2000
wantAllocs(t, 2, func() {
l.Log(ctx, LevelInfo, "hello",
l.Log(nil, LevelInfo, "hello",
"n", i,
"s", s,
)
@@ -253,8 +250,8 @@ func TestAlloc(t *testing.T) {
s := "abc"
i := 2000
wantAllocs(t, 0, func() {
if l.Enabled(ctx, LevelInfo) {
l.Log(ctx, LevelInfo, "hello",
if l.Enabled(nil, LevelInfo) {
l.Log(nil, LevelInfo, "hello",
"n", i,
"s", s,
)
@@ -276,30 +273,30 @@ func TestAlloc(t *testing.T) {
wantAllocs(t, 0, func() { dl.Info("", "error", io.EOF) })
})
t.Run("attrs1", func(t *testing.T) {
wantAllocs(t, 0, func() { dl.LogAttrs(ctx, LevelInfo, "", Int("a", 1)) })
wantAllocs(t, 0, func() { dl.LogAttrs(ctx, LevelInfo, "", Any("error", io.EOF)) })
wantAllocs(t, 0, func() { dl.LogAttrs(nil, LevelInfo, "", Int("a", 1)) })
wantAllocs(t, 0, func() { dl.LogAttrs(nil, LevelInfo, "", Any("error", io.EOF)) })
})
t.Run("attrs3", func(t *testing.T) {
wantAllocs(t, 0, func() {
dl.LogAttrs(ctx, LevelInfo, "hello", Int("a", 1), String("b", "two"), Duration("c", time.Second))
dl.LogAttrs(nil, LevelInfo, "hello", Int("a", 1), String("b", "two"), Duration("c", time.Second))
})
})
t.Run("attrs3 disabled", func(t *testing.T) {
logger := New(discardHandler{disabled: true})
wantAllocs(t, 0, func() {
logger.LogAttrs(ctx, LevelInfo, "hello", Int("a", 1), String("b", "two"), Duration("c", time.Second))
logger.LogAttrs(nil, LevelInfo, "hello", Int("a", 1), String("b", "two"), Duration("c", time.Second))
})
})
t.Run("attrs6", func(t *testing.T) {
wantAllocs(t, 1, func() {
dl.LogAttrs(ctx, LevelInfo, "hello",
dl.LogAttrs(nil, LevelInfo, "hello",
Int("a", 1), String("b", "two"), Duration("c", time.Second),
Int("d", 1), String("e", "two"), Duration("f", time.Second))
})
})
t.Run("attrs9", func(t *testing.T) {
wantAllocs(t, 1, func() {
dl.LogAttrs(ctx, LevelInfo, "hello",
dl.LogAttrs(nil, LevelInfo, "hello",
Int("a", 1), String("b", "two"), Duration("c", time.Second),
Int("d", 1), String("e", "two"), Duration("f", time.Second),
Int("d", 1), String("e", "two"), Duration("f", time.Second))
@@ -398,14 +395,14 @@ func TestContext(t *testing.T) {
f func(context.Context, string, ...any)
wantLevel Level
}{
{l.DebugContext, LevelDebug},
{l.InfoContext, LevelInfo},
{l.WarnContext, LevelWarn},
{l.ErrorContext, LevelError},
{DebugContext, LevelDebug},
{InfoContext, LevelInfo},
{WarnContext, LevelWarn},
{ErrorContext, LevelError},
{l.DebugCtx, LevelDebug},
{l.InfoCtx, LevelInfo},
{l.WarnCtx, LevelWarn},
{l.ErrorCtx, LevelError},
{DebugCtx, LevelDebug},
{InfoCtx, LevelInfo},
{WarnCtx, LevelWarn},
{ErrorCtx, LevelError},
} {
h.clear()
ctx := context.WithValue(context.Background(), "L", test.wantLevel)
@@ -514,27 +511,27 @@ func BenchmarkNopLog(b *testing.B) {
b.Run("no attrs", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
l.LogAttrs(ctx, LevelInfo, "msg")
l.LogAttrs(nil, LevelInfo, "msg")
}
})
b.Run("attrs", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
l.LogAttrs(ctx, LevelInfo, "msg", Int("a", 1), String("b", "two"), Bool("c", true))
l.LogAttrs(nil, LevelInfo, "msg", Int("a", 1), String("b", "two"), Bool("c", true))
}
})
b.Run("attrs-parallel", func(b *testing.B) {
b.ReportAllocs()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
l.LogAttrs(ctx, LevelInfo, "msg", Int("a", 1), String("b", "two"), Bool("c", true))
l.LogAttrs(nil, LevelInfo, "msg", Int("a", 1), String("b", "two"), Bool("c", true))
}
})
})
b.Run("keys-values", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
l.Log(ctx, LevelInfo, "msg", "a", 1, "b", "two", "c", true)
l.Log(nil, LevelInfo, "msg", "a", 1, "b", "two", "c", true)
}
})
b.Run("WithContext", func(b *testing.B) {

View File

@@ -6,7 +6,6 @@ package net
import (
"context"
"internal/godebug"
"internal/nettrace"
"syscall"
"time"
@@ -22,8 +21,6 @@ const (
defaultMPTCPEnabled = false
)
var multipathtcp = godebug.New("multipathtcp")
// mptcpStatus is a tristate for Multipath TCP, see go.dev/issue/56539
type mptcpStatus uint8
@@ -42,13 +39,6 @@ func (m *mptcpStatus) get() bool {
return false
}
// If MPTCP is forced via GODEBUG=multipathtcp=1
if multipathtcp.Value() == "1" {
multipathtcp.IncNonDefault()
return true
}
return defaultMPTCPEnabled
}
@@ -339,7 +329,7 @@ func (d *Dialer) MultipathTCP() bool {
// SetMultipathTCP directs the Dial methods to use, or not use, MPTCP,
// if supported by the operating system. This method overrides the
// system default and the GODEBUG=multipathtcp=... setting if any.
// system default.
//
// If MPTCP is not available on the host or not supported by the server,
// the Dial methods will fall back to TCP.
@@ -700,7 +690,7 @@ func (lc *ListenConfig) MultipathTCP() bool {
// SetMultipathTCP directs the Listen method to use, or not use, MPTCP,
// if supported by the operating system. This method overrides the
// system default and the GODEBUG=multipathtcp=... setting if any.
// system default.
//
// If MPTCP is not available on the host or not supported by the client,
// the Listen method will fall back to TCP.

View File

@@ -99,10 +99,8 @@ func (h *header) init(recType recType, reqId uint16, contentLength int) {
// conn sends records over rwc
type conn struct {
mutex sync.Mutex
rwc io.ReadWriteCloser
closeErr error
closed bool
mutex sync.Mutex
rwc io.ReadWriteCloser
// to avoid allocations
buf bytes.Buffer
@@ -113,15 +111,10 @@ func newConn(rwc io.ReadWriteCloser) *conn {
return &conn{rwc: rwc}
}
// Close closes the conn if it is not already closed.
func (c *conn) Close() error {
c.mutex.Lock()
defer c.mutex.Unlock()
if !c.closed {
c.closeErr = c.rwc.Close()
c.closed = true
}
return c.closeErr
return c.rwc.Close()
}
type record struct {

View File

@@ -241,7 +241,7 @@ func TestChildServeCleansUp(t *testing.T) {
input := make([]byte, len(tt.input))
copy(input, tt.input)
rc := nopWriteCloser{bytes.NewReader(input)}
done := make(chan struct{})
done := make(chan bool)
c := newChild(rc, http.HandlerFunc(func(
w http.ResponseWriter,
r *http.Request,
@@ -252,9 +252,9 @@ func TestChildServeCleansUp(t *testing.T) {
t.Errorf("Expected %#v, got %#v", tt.err, err)
}
// not reached if body of request isn't closed
close(done)
done <- true
}))
c.serve()
go c.serve()
// wait for body of request to be closed or all goroutines to block
<-done
}
@@ -331,7 +331,7 @@ func TestChildServeReadsEnvVars(t *testing.T) {
input := make([]byte, len(tt.input))
copy(input, tt.input)
rc := nopWriteCloser{bytes.NewReader(input)}
done := make(chan struct{})
done := make(chan bool)
c := newChild(rc, http.HandlerFunc(func(
w http.ResponseWriter,
r *http.Request,
@@ -343,9 +343,9 @@ func TestChildServeReadsEnvVars(t *testing.T) {
} else if env[tt.envVar] != tt.expectedVal {
t.Errorf("Expected %s, got %s", tt.expectedVal, env[tt.envVar])
}
close(done)
done <- true
}))
c.serve()
go c.serve()
<-done
}
}
@@ -381,7 +381,7 @@ func TestResponseWriterSniffsContentType(t *testing.T) {
input := make([]byte, len(streamFullRequestStdin))
copy(input, streamFullRequestStdin)
rc := nopWriteCloser{bytes.NewReader(input)}
done := make(chan struct{})
done := make(chan bool)
var resp *response
c := newChild(rc, http.HandlerFunc(func(
w http.ResponseWriter,
@@ -389,9 +389,10 @@ func TestResponseWriterSniffsContentType(t *testing.T) {
) {
io.WriteString(w, tt.body)
resp = w.(*response)
close(done)
done <- true
}))
c.serve()
defer c.cleanUp()
go c.serve()
<-done
if got := resp.Header().Get("Content-Type"); got != tt.wantCT {
t.Errorf("got a Content-Type of %q; expected it to start with %q", got, tt.wantCT)
@@ -400,27 +401,25 @@ func TestResponseWriterSniffsContentType(t *testing.T) {
}
}
type signalingNopWriteCloser struct {
io.ReadCloser
type signalingNopCloser struct {
io.Reader
closed chan bool
}
func (*signalingNopWriteCloser) Write(buf []byte) (int, error) {
func (*signalingNopCloser) Write(buf []byte) (int, error) {
return len(buf), nil
}
func (rc *signalingNopWriteCloser) Close() error {
func (rc *signalingNopCloser) Close() error {
close(rc.closed)
return rc.ReadCloser.Close()
return nil
}
// Test whether server properly closes connection when processing slow
// requests
func TestSlowRequest(t *testing.T) {
pr, pw := io.Pipe()
writerDone := make(chan struct{})
go func() {
go func(w io.Writer) {
for _, buf := range [][]byte{
streamBeginTypeStdin,
makeRecord(typeStdin, 1, nil),
@@ -428,14 +427,9 @@ func TestSlowRequest(t *testing.T) {
pw.Write(buf)
time.Sleep(100 * time.Millisecond)
}
close(writerDone)
}()
defer func() {
<-writerDone
pw.Close()
}()
}(pw)
rc := &signalingNopWriteCloser{pr, make(chan bool)}
rc := &signalingNopCloser{pr, make(chan bool)}
handlerDone := make(chan bool)
c := newChild(rc, http.HandlerFunc(func(
@@ -445,9 +439,16 @@ func TestSlowRequest(t *testing.T) {
w.WriteHeader(200)
close(handlerDone)
}))
c.serve()
go c.serve()
defer c.cleanUp()
timeout := time.After(2 * time.Second)
<-handlerDone
<-rc.closed
t.Log("FastCGI child closed connection")
select {
case <-rc.closed:
t.Log("FastCGI child closed connection")
case <-timeout:
t.Error("FastCGI child did not close socket after handling request")
}
}

View File

@@ -7540,14 +7540,11 @@ func (t *http2Transport) RoundTrip(req *Request) (*Response, error) {
func http2authorityAddr(scheme string, authority string) (addr string) {
host, port, err := net.SplitHostPort(authority)
if err != nil { // authority didn't have a port
host = authority
port = ""
}
if port == "" { // authority's port was empty
port = "443"
if scheme == "http" {
port = "80"
}
host = authority
}
if a, err := idna.ToASCII(host); err == nil {
host = a
@@ -8293,7 +8290,22 @@ func (cc *http2ClientConn) RoundTrip(req *Request) (*Response, error) {
cancelRequest := func(cs *http2clientStream, err error) error {
cs.cc.mu.Lock()
cs.abortStreamLocked(err)
bodyClosed := cs.reqBodyClosed
if cs.ID != 0 {
// This request may have failed because of a problem with the connection,
// or for some unrelated reason. (For example, the user might have canceled
// the request without waiting for a response.) Mark the connection as
// not reusable, since trying to reuse a dead connection is worse than
// unnecessarily creating a new one.
//
// If cs.ID is 0, then the request was never allocated a stream ID and
// whatever went wrong was unrelated to the connection. We might have
// timed out waiting for a stream slot when StrictMaxConcurrentStreams
// is set, for example, in which case retrying on a different connection
// will not help.
cs.cc.doNotReuse = true
}
cs.cc.mu.Unlock()
// Wait for the request body to be closed.
//
@@ -8328,14 +8340,11 @@ func (cc *http2ClientConn) RoundTrip(req *Request) (*Response, error) {
return handleResponseHeaders()
default:
waitDone()
return nil, cs.abortErr
return nil, cancelRequest(cs, cs.abortErr)
}
case <-ctx.Done():
err := ctx.Err()
cs.abortStream(err)
return nil, cancelRequest(cs, err)
return nil, cancelRequest(cs, ctx.Err())
case <-cs.reqCancel:
cs.abortStream(http2errRequestCanceled)
return nil, cancelRequest(cs, http2errRequestCanceled)
}
}
@@ -8893,9 +8902,6 @@ func (cc *http2ClientConn) encodeHeaders(req *Request, addGzipHeader bool, trail
if err != nil {
return nil, err
}
if !httpguts.ValidHostHeader(host) {
return nil, errors.New("http2: invalid Host header")
}
var path string
if req.Method != "CONNECT" {

View File

@@ -12,22 +12,15 @@ import (
"testing"
)
func newLocalListenerMPTCP(t *testing.T, envVar bool) Listener {
func newLocalListenerMPTCP(t *testing.T) Listener {
lc := &ListenConfig{}
if lc.MultipathTCP() {
t.Error("MultipathTCP should be off by default")
}
if envVar {
if !lc.MultipathTCP() {
t.Fatal("MultipathTCP Listen is not on despite GODEBUG=multipathtcp=1")
}
} else {
if lc.MultipathTCP() {
t.Error("MultipathTCP should be off by default")
}
lc.SetMultipathTCP(true)
if !lc.MultipathTCP() {
t.Fatal("MultipathTCP is not on after having been forced to on")
}
lc.SetMultipathTCP(true)
if !lc.MultipathTCP() {
t.Fatal("MultipathTCP is not on after having been forced to on")
}
ln, err := lc.Listen(context.Background(), "tcp", "127.0.0.1:0")
@@ -71,22 +64,15 @@ func postAcceptMPTCP(ls *localServer, ch chan<- error) {
}
}
func dialerMPTCP(t *testing.T, addr string, envVar bool) {
func dialerMPTCP(t *testing.T, addr string) {
d := &Dialer{}
if d.MultipathTCP() {
t.Error("MultipathTCP should be off by default")
}
if envVar {
if !d.MultipathTCP() {
t.Fatal("MultipathTCP Dialer is not on despite GODEBUG=multipathtcp=1")
}
} else {
if d.MultipathTCP() {
t.Error("MultipathTCP should be off by default")
}
d.SetMultipathTCP(true)
if !d.MultipathTCP() {
t.Fatal("MultipathTCP is not on after having been forced to on")
}
d.SetMultipathTCP(true)
if !d.MultipathTCP() {
t.Fatal("MultipathTCP is not on after having been forced to on")
}
c, err := d.Dial("tcp", addr)
@@ -142,16 +128,12 @@ func canCreateMPTCPSocket() bool {
return true
}
func testMultiPathTCP(t *testing.T, envVar bool) {
if envVar {
t.Log("Test with GODEBUG=multipathtcp=1")
t.Setenv("GODEBUG", "multipathtcp=1")
} else {
t.Log("Test with GODEBUG=multipathtcp=0")
t.Setenv("GODEBUG", "multipathtcp=0")
func TestMultiPathTCP(t *testing.T) {
if !canCreateMPTCPSocket() {
t.Skip("Cannot create MPTCP sockets")
}
ln := newLocalListenerMPTCP(t, envVar)
ln := newLocalListenerMPTCP(t)
// similar to tcpsock_test:TestIPv6LinkLocalUnicastTCP
ls := (&streamListener{Listener: ln}).newLocalServer()
@@ -171,7 +153,7 @@ func testMultiPathTCP(t *testing.T, envVar bool) {
t.Fatal(err)
}
dialerMPTCP(t, ln.Addr().String(), envVar)
dialerMPTCP(t, ln.Addr().String())
if err := <-genericCh; err != nil {
t.Error(err)
@@ -180,13 +162,3 @@ func testMultiPathTCP(t *testing.T, envVar bool) {
t.Error(err)
}
}
func TestMultiPathTCP(t *testing.T) {
if !canCreateMPTCPSocket() {
t.Skip("Cannot create MPTCP sockets")
}
for _, envVar := range []bool{false, true} {
testMultiPathTCP(t, envVar)
}
}

View File

@@ -84,18 +84,6 @@ func (file *File) readdir(n int, mode readdirMode) (names []string, dirents []Di
if err == syscall.ERROR_NO_MORE_FILES {
break
}
if infoClass == windows.FileIdBothDirectoryRestartInfo && err == syscall.ERROR_FILE_NOT_FOUND {
// GetFileInformationByHandleEx doesn't document the return error codes when the info class is FileIdBothDirectoryRestartInfo,
// but MS-FSA 2.1.5.6.3 [1] specifies that the underlying file system driver should return STATUS_NO_SUCH_FILE when
// reading an empty root directory, which is mapped to ERROR_FILE_NOT_FOUND by Windows.
// Note that some file system drivers may never return this error code, as the spec allows to return the "." and ".."
// entries in such cases, making the directory appear non-empty.
// The chances of false positive are very low, as we know that the directory exists, else GetVolumeInformationByHandle
// would have failed, and that the handle is still valid, as we haven't closed it.
// See go.dev/issue/61159.
// [1] https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fsa/fa8194e0-53ec-413b-8315-e8fa85396fd8
break
}
if s, _ := file.Stat(); s != nil && !s.IsDir() {
err = &PathError{Op: "readdir", Path: file.name, Err: syscall.ENOTDIR}
} else {

View File

@@ -31,7 +31,7 @@ func errNoDeadline() error { return poll.ErrNoDeadline }
// errDeadlineExceeded returns the value for os.ErrDeadlineExceeded.
// This error comes from the internal/poll package, which is also
// used by package net. Doing it this way ensures that the net
// used by package net. Doing this this way ensures that the net
// package will return os.ErrDeadlineExceeded for an exceeded deadline,
// as documented by net.Conn.SetDeadline, without requiring any extra
// work in the net package and without requiring the internal/poll

View File

@@ -1708,77 +1708,3 @@ func TestCancelErrors(t *testing.T) {
}
})
}
// TestConcurrentExec is a regression test for https://go.dev/issue/61080.
//
// Forking multiple child processes concurrently would sometimes hang on darwin.
// (This test hung on a gomote with -count=100 after only a few iterations.)
func TestConcurrentExec(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
// This test will spawn nHangs subprocesses that hang reading from stdin,
// and nExits subprocesses that exit immediately.
//
// When issue #61080 was present, a long-lived "hang" subprocess would
// occasionally inherit the fork/exec status pipe from an "exit" subprocess,
// causing the parent process (which expects to see an EOF on that pipe almost
// immediately) to unexpectedly block on reading from the pipe.
var (
nHangs = runtime.GOMAXPROCS(0)
nExits = runtime.GOMAXPROCS(0)
hangs, exits sync.WaitGroup
)
hangs.Add(nHangs)
exits.Add(nExits)
// ready is done when the goroutines have done as much work as possible to
// prepare to create subprocesses. It isn't strictly necessary for the test,
// but helps to increase the repro rate by making it more likely that calls to
// syscall.StartProcess for the "hang" and "exit" goroutines overlap.
var ready sync.WaitGroup
ready.Add(nHangs + nExits)
for i := 0; i < nHangs; i++ {
go func() {
defer hangs.Done()
cmd := helperCommandContext(t, ctx, "pipetest")
stdin, err := cmd.StdinPipe()
if err != nil {
ready.Done()
t.Error(err)
return
}
cmd.Cancel = stdin.Close
ready.Done()
ready.Wait()
if err := cmd.Start(); err != nil {
if !errors.Is(err, context.Canceled) {
t.Error(err)
}
return
}
cmd.Wait()
}()
}
for i := 0; i < nExits; i++ {
go func() {
defer exits.Done()
cmd := helperCommandContext(t, ctx, "exit", "0")
ready.Done()
ready.Wait()
if err := cmd.Run(); err != nil {
t.Error(err)
}
}()
}
exits.Wait()
cancel()
hangs.Wait()
}

View File

@@ -660,7 +660,7 @@ type cpuStatsAggregate struct {
// compute populates the cpuStatsAggregate with values from the runtime.
func (a *cpuStatsAggregate) compute() {
a.cpuStats = work.cpuStats
// TODO(mknyszek): Update the CPU stats again so that we're not
// TODO(mknyszek): Update the the CPU stats again so that we're not
// just relying on the STW snapshot. The issue here is that currently
// this will cause non-monotonicity in the "user" CPU time metric.
//

View File

@@ -273,10 +273,6 @@ Below is the full list of supported metrics, ordered lexicographically.
the mime/multipart package due to a non-default
GODEBUG=multipartmaxparts=... setting.
/godebug/non-default-behavior/multipathtcp:events
The number of non-default behaviors executed by the net package
due to a non-default GODEBUG=multipathtcp=... setting.
/godebug/non-default-behavior/panicnil:events
The number of non-default behaviors executed by the runtime
package due to a non-default GODEBUG=panicnil=... setting.

View File

@@ -884,7 +884,7 @@ func fillAligned(x uint64, m uint) uint64 {
// segment which represents a contiguous region of free and unscavenged memory.
//
// searchIdx indicates the page index within this chunk to start the search, but
// note that findScavengeCandidate searches backwards through the pallocData. As
// note that findScavengeCandidate searches backwards through the pallocData. As a
// a result, it will return the highest scavenge candidate in address order.
//
// min indicates a hard minimum size and alignment for runs of pages. That is,

View File

@@ -641,6 +641,11 @@ childerror:
}
}
// Try to open a pipe with O_CLOEXEC set on both file descriptors.
func forkExecPipe(p []int) (err error) {
return Pipe2(p, O_CLOEXEC)
}
func formatIDMappings(idMap []SysProcIDMap) []byte {
var data []byte
for _, im := range idMap {

View File

@@ -241,6 +241,89 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)
return pid, nil
}
var (
// Guard the forking variable.
forkingLock sync.Mutex
// Number of goroutines currently forking, and thus the
// number of goroutines holding a conceptual write lock
// on ForkLock.
forking int
)
// hasWaitingReaders reports whether any goroutine is waiting
// to acquire a read lock on rw. It is defined in the sync package.
func hasWaitingReaders(rw *sync.RWMutex) bool
// acquireForkLock acquires a write lock on ForkLock.
// ForkLock is exported and we've promised that during a fork
// we will call ForkLock.Lock, so that no other threads create
// new fds that are not yet close-on-exec before we fork.
// But that forces all fork calls to be serialized, which is bad.
// But we haven't promised that serialization, and it is essentially
// undetectable by other users of ForkLock, which is good.
// Avoid the serialization by ensuring that ForkLock is locked
// at the first fork and unlocked when there are no more forks.
func acquireForkLock() {
forkingLock.Lock()
defer forkingLock.Unlock()
if forking == 0 {
// There is no current write lock on ForkLock.
ForkLock.Lock()
forking++
return
}
// ForkLock is currently locked for writing.
if hasWaitingReaders(&ForkLock) {
// ForkLock is locked for writing, and at least one
// goroutine is waiting to read from it.
// To avoid lock starvation, allow readers to proceed.
// The simple way to do this is for us to acquire a
// read lock. That will block us until all current
// conceptual write locks are released.
//
// Note that this case is unusual on modern systems
// with O_CLOEXEC and SOCK_CLOEXEC. On those systems
// the standard library should never take a read
// lock on ForkLock.
forkingLock.Unlock()
ForkLock.RLock()
ForkLock.RUnlock()
forkingLock.Lock()
// Readers got a chance, so now take the write lock.
if forking == 0 {
ForkLock.Lock()
}
}
forking++
}
// releaseForkLock releases the conceptual write lock on ForkLock
// acquired by acquireForkLock.
func releaseForkLock() {
forkingLock.Lock()
defer forkingLock.Unlock()
if forking <= 0 {
panic("syscall.releaseForkLock: negative count")
}
forking--
if forking == 0 {
// No more conceptual write locks.
ForkLock.Unlock()
}
}
// Combination of fork and exec, careful to be thread safe.
func ForkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
return forkExec(argv0, argv, attr)

View File

@@ -6,8 +6,7 @@
package syscall
// forkExecPipe opens a pipe and non-atomically sets O_CLOEXEC on both file
// descriptors.
// Try to open a pipe with O_CLOEXEC set on both file descriptors.
func forkExecPipe(p []int) error {
err := Pipe(p)
if err != nil {
@@ -20,11 +19,3 @@ func forkExecPipe(p []int) error {
_, err = fcntl(p[1], F_SETFD, FD_CLOEXEC)
return err
}
func acquireForkLock() {
ForkLock.Lock()
}
func releaseForkLock() {
ForkLock.Unlock()
}

View File

@@ -2,97 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build dragonfly || freebsd || linux || netbsd || openbsd || solaris
//go:build dragonfly || freebsd || netbsd || openbsd || solaris
package syscall
import "sync"
// forkExecPipe atomically opens a pipe with O_CLOEXEC set on both file
// descriptors.
func forkExecPipe(p []int) error {
return Pipe2(p, O_CLOEXEC)
}
var (
// Guard the forking variable.
forkingLock sync.Mutex
// Number of goroutines currently forking, and thus the
// number of goroutines holding a conceptual write lock
// on ForkLock.
forking int
)
// hasWaitingReaders reports whether any goroutine is waiting
// to acquire a read lock on rw. It is defined in the sync package.
func hasWaitingReaders(rw *sync.RWMutex) bool
// acquireForkLock acquires a write lock on ForkLock.
// ForkLock is exported and we've promised that during a fork
// we will call ForkLock.Lock, so that no other threads create
// new fds that are not yet close-on-exec before we fork.
// But that forces all fork calls to be serialized, which is bad.
// But we haven't promised that serialization, and it is essentially
// undetectable by other users of ForkLock, which is good.
// Avoid the serialization by ensuring that ForkLock is locked
// at the first fork and unlocked when there are no more forks.
func acquireForkLock() {
forkingLock.Lock()
defer forkingLock.Unlock()
if forking == 0 {
// There is no current write lock on ForkLock.
ForkLock.Lock()
forking++
return
}
// ForkLock is currently locked for writing.
if hasWaitingReaders(&ForkLock) {
// ForkLock is locked for writing, and at least one
// goroutine is waiting to read from it.
// To avoid lock starvation, allow readers to proceed.
// The simple way to do this is for us to acquire a
// read lock. That will block us until all current
// conceptual write locks are released.
//
// Note that this case is unusual on modern systems
// with O_CLOEXEC and SOCK_CLOEXEC. On those systems
// the standard library should never take a read
// lock on ForkLock.
forkingLock.Unlock()
ForkLock.RLock()
ForkLock.RUnlock()
forkingLock.Lock()
// Readers got a chance, so now take the write lock.
if forking == 0 {
ForkLock.Lock()
}
}
forking++
}
// releaseForkLock releases the conceptual write lock on ForkLock
// acquired by acquireForkLock.
func releaseForkLock() {
forkingLock.Lock()
defer forkingLock.Unlock()
if forking <= 0 {
panic("syscall.releaseForkLock: negative count")
}
forking--
if forking == 0 {
// No more conceptual write locks.
ForkLock.Unlock()
}
}

Some files were not shown because too many files have changed in this diff Show More