all: update vendored dependencies [generated]

The Go 1.25 RC is due soon. This is the time to once again update all
golang.org/x/... module versions that contribute packages to the std and
cmd modules in the standard library to latest master versions.

For #36905.

[git-generate]
go install golang.org/x/build/cmd/updatestd@latest
go install golang.org/x/tools/cmd/bundle@latest
updatestd -goroot=$(pwd) -branch=master

cat << EOF | patch
diff --git a/src/cmd/go/testdata/script/test_json_build.txt b/src/cmd/go/testdata/script/test_json_build.txt
index df8863ae03..2a572ace72 100644
--- a/src/cmd/go/testdata/script/test_json_build.txt
+++ b/src/cmd/go/testdata/script/test_json_build.txt
@@ -56,7 +56,7 @@ stdout '"Action":"fail","Package":"m/cycle/p","Elapsed":.*,"FailedBuild":"m/cycl
 ! go test -json -o=$devnull ./veterror
 stdout '"ImportPath":"m/veterror \[m/veterror.test\]","Action":"build-output","Output":"# m/veterror\\n"'
 stdout '"ImportPath":"m/veterror \[m/veterror.test\]","Action":"build-output","Output":"# \[m/veterror\]\\n"'
-stdout '"ImportPath":"m/veterror \[m/veterror.test\]","Action":"build-output","Output":"veterror(/|\\\\)main_test.go:9:9: fmt.Printf format %s reads arg #1, but call has 0 args\\n"'
+stdout '"ImportPath":"m/veterror \[m/veterror.test\]","Action":"build-output","Output":"veterror(/|\\\\)main_test.go:9:21: fmt.Printf format %s reads arg #1, but call has 0 args\\n"'
 stdout '"ImportPath":"m/veterror \[m/veterror.test\]","Action":"build-fail"'
 stdout '"Action":"start","Package":"m/veterror"'
 stdout '"Action":"output","Package":"m/veterror","Output":"FAIL\\tm/veterror \[build failed\]\\n"'
EOF

Change-Id: I6a8d35acdeab90c3bbd6395b8b1abb021673b5cb
Reviewed-on: https://go-review.googlesource.com/c/go/+/678556
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
Carlos Amedee 2025-06-04 15:35:31 -04:00
parent 4d1c255f15
commit 78eadf5b3d
55 changed files with 18527 additions and 18060 deletions

View file

@ -4,18 +4,18 @@ go 1.25
require ( require (
github.com/google/pprof v0.0.0-20250208200701-d0013a598941 github.com/google/pprof v0.0.0-20250208200701-d0013a598941
golang.org/x/arch v0.14.0 golang.org/x/arch v0.18.1-0.20250605182141-b2f4e2807dec
golang.org/x/build v0.0.0-20250211223606-a5e3f75caa63 golang.org/x/build v0.0.0-20250606033421-8c8ff6f34a83
golang.org/x/mod v0.24.1-0.20250508140430-9d3333156f46 golang.org/x/mod v0.25.0
golang.org/x/sync v0.13.0 golang.org/x/sync v0.15.0
golang.org/x/sys v0.32.0 golang.org/x/sys v0.33.0
golang.org/x/telemetry v0.0.0-20250212145848-75305293b65a golang.org/x/telemetry v0.0.0-20250606142133-60998feb31a8
golang.org/x/term v0.29.0 golang.org/x/term v0.32.0
golang.org/x/tools v0.32.1-0.20250423190156-68e94bd1775e golang.org/x/tools v0.34.0
) )
require ( require (
github.com/ianlancetaylor/demangle v0.0.0-20240912202439-0a2b6291aafd // indirect github.com/ianlancetaylor/demangle v0.0.0-20240912202439-0a2b6291aafd // indirect
golang.org/x/text v0.24.0 // indirect golang.org/x/text v0.26.0 // indirect
rsc.io/markdown v0.0.0-20240306144322-0bf8f97ee8ef // indirect rsc.io/markdown v0.0.0-20240306144322-0bf8f97ee8ef // indirect
) )

View file

@ -6,23 +6,23 @@ github.com/ianlancetaylor/demangle v0.0.0-20240912202439-0a2b6291aafd h1:EVX1s+X
github.com/ianlancetaylor/demangle v0.0.0-20240912202439-0a2b6291aafd/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= github.com/ianlancetaylor/demangle v0.0.0-20240912202439-0a2b6291aafd/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=
github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68= github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68=
github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/arch v0.14.0 h1:z9JUEZWr8x4rR0OU6c4/4t6E6jOZ8/QBS2bBYBm4tx4= golang.org/x/arch v0.18.1-0.20250605182141-b2f4e2807dec h1:fCOjXc18tBlkVy4m+VuL1WU8VTukYOGtAk7nC5QYPRY=
golang.org/x/arch v0.14.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/arch v0.18.1-0.20250605182141-b2f4e2807dec/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
golang.org/x/build v0.0.0-20250211223606-a5e3f75caa63 h1:QZ8/V1B4oK7N5t6w0zX5dAxFIHt0WaTX+r1z29cWXjY= golang.org/x/build v0.0.0-20250606033421-8c8ff6f34a83 h1:IiFSc399rOkpudtnsTDKdtfFEsvd+dGfNfl+ytV267c=
golang.org/x/build v0.0.0-20250211223606-a5e3f75caa63/go.mod h1:JhINjMoWj8G2oLkaBLNDBIr/GLqJNOkCr4XzFWWYCf4= golang.org/x/build v0.0.0-20250606033421-8c8ff6f34a83/go.mod h1:SDzKvZFXqZyl3tLink1AnKsAocWm0yFc3UfmxR6aIOw=
golang.org/x/mod v0.24.1-0.20250508140430-9d3333156f46 h1:0wufKs7434dECGChJ8f683kuQsBh+1MXieCdOlBOBw8= golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
golang.org/x/mod v0.24.1-0.20250508140430-9d3333156f46/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/telemetry v0.0.0-20250212145848-75305293b65a h1:3fgycqG+90xOafOruMBVZXa8DUeOt5qbGLjQoNvZ8Ew= golang.org/x/telemetry v0.0.0-20250606142133-60998feb31a8 h1:jBJ3nsFeGb1DzjhOg2ZgZTpnDnOZfHId7RNlBJUtkOM=
golang.org/x/telemetry v0.0.0-20250212145848-75305293b65a/go.mod h1:Ng+6E7PnWNge4EifZkPKeQUnm5iyAoH8qQgw3pLCiF4= golang.org/x/telemetry v0.0.0-20250606142133-60998feb31a8/go.mod h1:mUcjA5g0luJpMYCLjhH91f4t4RAUNp+zq9ZmUoqPD7M=
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
golang.org/x/tools v0.32.1-0.20250423190156-68e94bd1775e h1:t16U5lZsxU6d2R2ax2lfujEzzsctlYTvXppAlsAWP4A= golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
golang.org/x/tools v0.32.1-0.20250423190156-68e94bd1775e/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s= golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
rsc.io/markdown v0.0.0-20240306144322-0bf8f97ee8ef h1:mqLYrXCXYEZOop9/Dbo6RPX11539nwiCNBb1icVPmw8= rsc.io/markdown v0.0.0-20240306144322-0bf8f97ee8ef h1:mqLYrXCXYEZOop9/Dbo6RPX11539nwiCNBb1icVPmw8=
rsc.io/markdown v0.0.0-20240306144322-0bf8f97ee8ef/go.mod h1:8xcPgWmwlZONN1D9bjxtHEjrUtSEa3fakVF8iaewYKQ= rsc.io/markdown v0.0.0-20240306144322-0bf8f97ee8ef/go.mod h1:8xcPgWmwlZONN1D9bjxtHEjrUtSEa3fakVF8iaewYKQ=

View file

@ -56,7 +56,7 @@ stdout '"Action":"fail","Package":"m/cycle/p","Elapsed":.*,"FailedBuild":"m/cycl
! go test -json -o=$devnull ./veterror ! go test -json -o=$devnull ./veterror
stdout '"ImportPath":"m/veterror \[m/veterror.test\]","Action":"build-output","Output":"# m/veterror\\n"' stdout '"ImportPath":"m/veterror \[m/veterror.test\]","Action":"build-output","Output":"# m/veterror\\n"'
stdout '"ImportPath":"m/veterror \[m/veterror.test\]","Action":"build-output","Output":"# \[m/veterror\]\\n"' stdout '"ImportPath":"m/veterror \[m/veterror.test\]","Action":"build-output","Output":"# \[m/veterror\]\\n"'
stdout '"ImportPath":"m/veterror \[m/veterror.test\]","Action":"build-output","Output":"veterror(/|\\\\)main_test.go:9:9: fmt.Printf format %s reads arg #1, but call has 0 args\\n"' stdout '"ImportPath":"m/veterror \[m/veterror.test\]","Action":"build-output","Output":"veterror(/|\\\\)main_test.go:9:21: fmt.Printf format %s reads arg #1, but call has 0 args\\n"'
stdout '"ImportPath":"m/veterror \[m/veterror.test\]","Action":"build-fail"' stdout '"ImportPath":"m/veterror \[m/veterror.test\]","Action":"build-fail"'
stdout '"Action":"start","Package":"m/veterror"' stdout '"Action":"start","Package":"m/veterror"'
stdout '"Action":"output","Package":"m/veterror","Output":"FAIL\\tm/veterror \[build failed\]\\n"' stdout '"Action":"output","Package":"m/veterror","Output":"FAIL\\tm/veterror \[build failed\]\\n"'

View file

@ -469,7 +469,7 @@ func (rea RegExtshiftAmount) String() string {
if rea.amount != 0 { if rea.amount != 0 {
buf += fmt.Sprintf(" #%d", rea.amount) buf += fmt.Sprintf(" #%d", rea.amount)
} else { } else {
if rea.show_zero == true { if rea.show_zero {
buf += fmt.Sprintf(" #%d", rea.amount) buf += fmt.Sprintf(" #%d", rea.amount)
} }
} }
@ -527,7 +527,7 @@ func (m MemImmediate) String() string {
postR := post.String() postR := post.String()
return fmt.Sprintf("[%s], %s", R, postR) return fmt.Sprintf("[%s], %s", R, postR)
} }
return fmt.Sprintf("unimplemented!") return "unimplemented!"
} }
// A MemExtend is a memory reference made up of a base R and index expression X. // A MemExtend is a memory reference made up of a base R and index expression X.
@ -1021,110 +1021,110 @@ func (s sysInstFields) getType() sys {
} }
var sysInstsAttrs = map[sysInstFields]sysInstAttrs{ var sysInstsAttrs = map[sysInstFields]sysInstAttrs{
sysInstFields{0, 8, 3, 0}: {sys_TLBI, "VMALLE1IS", false}, {0, 8, 3, 0}: {sys_TLBI, "VMALLE1IS", false},
sysInstFields{0, 8, 3, 1}: {sys_TLBI, "VAE1IS", true}, {0, 8, 3, 1}: {sys_TLBI, "VAE1IS", true},
sysInstFields{0, 8, 3, 2}: {sys_TLBI, "ASIDE1IS", true}, {0, 8, 3, 2}: {sys_TLBI, "ASIDE1IS", true},
sysInstFields{0, 8, 3, 3}: {sys_TLBI, "VAAE1IS", true}, {0, 8, 3, 3}: {sys_TLBI, "VAAE1IS", true},
sysInstFields{0, 8, 3, 5}: {sys_TLBI, "VALE1IS", true}, {0, 8, 3, 5}: {sys_TLBI, "VALE1IS", true},
sysInstFields{0, 8, 3, 7}: {sys_TLBI, "VAALE1IS", true}, {0, 8, 3, 7}: {sys_TLBI, "VAALE1IS", true},
sysInstFields{0, 8, 7, 0}: {sys_TLBI, "VMALLE1", false}, {0, 8, 7, 0}: {sys_TLBI, "VMALLE1", false},
sysInstFields{0, 8, 7, 1}: {sys_TLBI, "VAE1", true}, {0, 8, 7, 1}: {sys_TLBI, "VAE1", true},
sysInstFields{0, 8, 7, 2}: {sys_TLBI, "ASIDE1", true}, {0, 8, 7, 2}: {sys_TLBI, "ASIDE1", true},
sysInstFields{0, 8, 7, 3}: {sys_TLBI, "VAAE1", true}, {0, 8, 7, 3}: {sys_TLBI, "VAAE1", true},
sysInstFields{0, 8, 7, 5}: {sys_TLBI, "VALE1", true}, {0, 8, 7, 5}: {sys_TLBI, "VALE1", true},
sysInstFields{0, 8, 7, 7}: {sys_TLBI, "VAALE1", true}, {0, 8, 7, 7}: {sys_TLBI, "VAALE1", true},
sysInstFields{4, 8, 0, 1}: {sys_TLBI, "IPAS2E1IS", true}, {4, 8, 0, 1}: {sys_TLBI, "IPAS2E1IS", true},
sysInstFields{4, 8, 0, 5}: {sys_TLBI, "IPAS2LE1IS", true}, {4, 8, 0, 5}: {sys_TLBI, "IPAS2LE1IS", true},
sysInstFields{4, 8, 3, 0}: {sys_TLBI, "ALLE2IS", false}, {4, 8, 3, 0}: {sys_TLBI, "ALLE2IS", false},
sysInstFields{4, 8, 3, 1}: {sys_TLBI, "VAE2IS", true}, {4, 8, 3, 1}: {sys_TLBI, "VAE2IS", true},
sysInstFields{4, 8, 3, 4}: {sys_TLBI, "ALLE1IS", false}, {4, 8, 3, 4}: {sys_TLBI, "ALLE1IS", false},
sysInstFields{4, 8, 3, 5}: {sys_TLBI, "VALE2IS", true}, {4, 8, 3, 5}: {sys_TLBI, "VALE2IS", true},
sysInstFields{4, 8, 3, 6}: {sys_TLBI, "VMALLS12E1IS", false}, {4, 8, 3, 6}: {sys_TLBI, "VMALLS12E1IS", false},
sysInstFields{4, 8, 4, 1}: {sys_TLBI, "IPAS2E1", true}, {4, 8, 4, 1}: {sys_TLBI, "IPAS2E1", true},
sysInstFields{4, 8, 4, 5}: {sys_TLBI, "IPAS2LE1", true}, {4, 8, 4, 5}: {sys_TLBI, "IPAS2LE1", true},
sysInstFields{4, 8, 7, 0}: {sys_TLBI, "ALLE2", false}, {4, 8, 7, 0}: {sys_TLBI, "ALLE2", false},
sysInstFields{4, 8, 7, 1}: {sys_TLBI, "VAE2", true}, {4, 8, 7, 1}: {sys_TLBI, "VAE2", true},
sysInstFields{4, 8, 7, 4}: {sys_TLBI, "ALLE1", false}, {4, 8, 7, 4}: {sys_TLBI, "ALLE1", false},
sysInstFields{4, 8, 7, 5}: {sys_TLBI, "VALE2", true}, {4, 8, 7, 5}: {sys_TLBI, "VALE2", true},
sysInstFields{4, 8, 7, 6}: {sys_TLBI, "VMALLS12E1", false}, {4, 8, 7, 6}: {sys_TLBI, "VMALLS12E1", false},
sysInstFields{6, 8, 3, 0}: {sys_TLBI, "ALLE3IS", false}, {6, 8, 3, 0}: {sys_TLBI, "ALLE3IS", false},
sysInstFields{6, 8, 3, 1}: {sys_TLBI, "VAE3IS", true}, {6, 8, 3, 1}: {sys_TLBI, "VAE3IS", true},
sysInstFields{6, 8, 3, 5}: {sys_TLBI, "VALE3IS", true}, {6, 8, 3, 5}: {sys_TLBI, "VALE3IS", true},
sysInstFields{6, 8, 7, 0}: {sys_TLBI, "ALLE3", false}, {6, 8, 7, 0}: {sys_TLBI, "ALLE3", false},
sysInstFields{6, 8, 7, 1}: {sys_TLBI, "VAE3", true}, {6, 8, 7, 1}: {sys_TLBI, "VAE3", true},
sysInstFields{6, 8, 7, 5}: {sys_TLBI, "VALE3", true}, {6, 8, 7, 5}: {sys_TLBI, "VALE3", true},
sysInstFields{0, 8, 1, 0}: {sys_TLBI, "VMALLE1OS", false}, {0, 8, 1, 0}: {sys_TLBI, "VMALLE1OS", false},
sysInstFields{0, 8, 1, 1}: {sys_TLBI, "VAE1OS", true}, {0, 8, 1, 1}: {sys_TLBI, "VAE1OS", true},
sysInstFields{0, 8, 1, 2}: {sys_TLBI, "ASIDE1OS", true}, {0, 8, 1, 2}: {sys_TLBI, "ASIDE1OS", true},
sysInstFields{0, 8, 1, 3}: {sys_TLBI, "VAAE1OS", true}, {0, 8, 1, 3}: {sys_TLBI, "VAAE1OS", true},
sysInstFields{0, 8, 1, 5}: {sys_TLBI, "VALE1OS", true}, {0, 8, 1, 5}: {sys_TLBI, "VALE1OS", true},
sysInstFields{0, 8, 1, 7}: {sys_TLBI, "VAALE1OS", true}, {0, 8, 1, 7}: {sys_TLBI, "VAALE1OS", true},
sysInstFields{0, 8, 2, 1}: {sys_TLBI, "RVAE1IS", true}, {0, 8, 2, 1}: {sys_TLBI, "RVAE1IS", true},
sysInstFields{0, 8, 2, 3}: {sys_TLBI, "RVAAE1IS", true}, {0, 8, 2, 3}: {sys_TLBI, "RVAAE1IS", true},
sysInstFields{0, 8, 2, 5}: {sys_TLBI, "RVALE1IS", true}, {0, 8, 2, 5}: {sys_TLBI, "RVALE1IS", true},
sysInstFields{0, 8, 2, 7}: {sys_TLBI, "RVAALE1IS", true}, {0, 8, 2, 7}: {sys_TLBI, "RVAALE1IS", true},
sysInstFields{0, 8, 5, 1}: {sys_TLBI, "RVAE1OS", true}, {0, 8, 5, 1}: {sys_TLBI, "RVAE1OS", true},
sysInstFields{0, 8, 5, 3}: {sys_TLBI, "RVAAE1OS", true}, {0, 8, 5, 3}: {sys_TLBI, "RVAAE1OS", true},
sysInstFields{0, 8, 5, 5}: {sys_TLBI, "RVALE1OS", true}, {0, 8, 5, 5}: {sys_TLBI, "RVALE1OS", true},
sysInstFields{0, 8, 5, 7}: {sys_TLBI, "RVAALE1OS", true}, {0, 8, 5, 7}: {sys_TLBI, "RVAALE1OS", true},
sysInstFields{0, 8, 6, 1}: {sys_TLBI, "RVAE1", true}, {0, 8, 6, 1}: {sys_TLBI, "RVAE1", true},
sysInstFields{0, 8, 6, 3}: {sys_TLBI, "RVAAE1", true}, {0, 8, 6, 3}: {sys_TLBI, "RVAAE1", true},
sysInstFields{0, 8, 6, 5}: {sys_TLBI, "RVALE1", true}, {0, 8, 6, 5}: {sys_TLBI, "RVALE1", true},
sysInstFields{0, 8, 6, 7}: {sys_TLBI, "RVAALE1", true}, {0, 8, 6, 7}: {sys_TLBI, "RVAALE1", true},
sysInstFields{4, 8, 0, 2}: {sys_TLBI, "RIPAS2E1IS", true}, {4, 8, 0, 2}: {sys_TLBI, "RIPAS2E1IS", true},
sysInstFields{4, 8, 0, 6}: {sys_TLBI, "RIPAS2LE1IS", true}, {4, 8, 0, 6}: {sys_TLBI, "RIPAS2LE1IS", true},
sysInstFields{4, 8, 1, 0}: {sys_TLBI, "ALLE2OS", false}, {4, 8, 1, 0}: {sys_TLBI, "ALLE2OS", false},
sysInstFields{4, 8, 1, 1}: {sys_TLBI, "VAE2OS", true}, {4, 8, 1, 1}: {sys_TLBI, "VAE2OS", true},
sysInstFields{4, 8, 1, 4}: {sys_TLBI, "ALLE1OS", false}, {4, 8, 1, 4}: {sys_TLBI, "ALLE1OS", false},
sysInstFields{4, 8, 1, 5}: {sys_TLBI, "VALE2OS", true}, {4, 8, 1, 5}: {sys_TLBI, "VALE2OS", true},
sysInstFields{4, 8, 1, 6}: {sys_TLBI, "VMALLS12E1OS", false}, {4, 8, 1, 6}: {sys_TLBI, "VMALLS12E1OS", false},
sysInstFields{4, 8, 2, 1}: {sys_TLBI, "RVAE2IS", true}, {4, 8, 2, 1}: {sys_TLBI, "RVAE2IS", true},
sysInstFields{4, 8, 2, 5}: {sys_TLBI, "RVALE2IS", true}, {4, 8, 2, 5}: {sys_TLBI, "RVALE2IS", true},
sysInstFields{4, 8, 4, 0}: {sys_TLBI, "IPAS2E1OS", true}, {4, 8, 4, 0}: {sys_TLBI, "IPAS2E1OS", true},
sysInstFields{4, 8, 4, 2}: {sys_TLBI, "RIPAS2E1", true}, {4, 8, 4, 2}: {sys_TLBI, "RIPAS2E1", true},
sysInstFields{4, 8, 4, 3}: {sys_TLBI, "RIPAS2E1OS", true}, {4, 8, 4, 3}: {sys_TLBI, "RIPAS2E1OS", true},
sysInstFields{4, 8, 4, 4}: {sys_TLBI, "IPAS2LE1OS", true}, {4, 8, 4, 4}: {sys_TLBI, "IPAS2LE1OS", true},
sysInstFields{4, 8, 4, 6}: {sys_TLBI, "RIPAS2LE1", true}, {4, 8, 4, 6}: {sys_TLBI, "RIPAS2LE1", true},
sysInstFields{4, 8, 4, 7}: {sys_TLBI, "RIPAS2LE1OS", true}, {4, 8, 4, 7}: {sys_TLBI, "RIPAS2LE1OS", true},
sysInstFields{4, 8, 5, 1}: {sys_TLBI, "RVAE2OS", true}, {4, 8, 5, 1}: {sys_TLBI, "RVAE2OS", true},
sysInstFields{4, 8, 5, 5}: {sys_TLBI, "RVALE2OS", true}, {4, 8, 5, 5}: {sys_TLBI, "RVALE2OS", true},
sysInstFields{4, 8, 6, 1}: {sys_TLBI, "RVAE2", true}, {4, 8, 6, 1}: {sys_TLBI, "RVAE2", true},
sysInstFields{4, 8, 6, 5}: {sys_TLBI, "RVALE2", true}, {4, 8, 6, 5}: {sys_TLBI, "RVALE2", true},
sysInstFields{6, 8, 1, 0}: {sys_TLBI, "ALLE3OS", false}, {6, 8, 1, 0}: {sys_TLBI, "ALLE3OS", false},
sysInstFields{6, 8, 1, 1}: {sys_TLBI, "VAE3OS", true}, {6, 8, 1, 1}: {sys_TLBI, "VAE3OS", true},
sysInstFields{6, 8, 1, 5}: {sys_TLBI, "VALE3OS", true}, {6, 8, 1, 5}: {sys_TLBI, "VALE3OS", true},
sysInstFields{6, 8, 2, 1}: {sys_TLBI, "RVAE3IS", true}, {6, 8, 2, 1}: {sys_TLBI, "RVAE3IS", true},
sysInstFields{6, 8, 2, 5}: {sys_TLBI, "RVALE3IS", true}, {6, 8, 2, 5}: {sys_TLBI, "RVALE3IS", true},
sysInstFields{6, 8, 5, 1}: {sys_TLBI, "RVAE3OS", true}, {6, 8, 5, 1}: {sys_TLBI, "RVAE3OS", true},
sysInstFields{6, 8, 5, 5}: {sys_TLBI, "RVALE3OS", true}, {6, 8, 5, 5}: {sys_TLBI, "RVALE3OS", true},
sysInstFields{6, 8, 6, 1}: {sys_TLBI, "RVAE3", true}, {6, 8, 6, 1}: {sys_TLBI, "RVAE3", true},
sysInstFields{6, 8, 6, 5}: {sys_TLBI, "RVALE3", true}, {6, 8, 6, 5}: {sys_TLBI, "RVALE3", true},
sysInstFields{0, 7, 6, 1}: {sys_DC, "IVAC", true}, {0, 7, 6, 1}: {sys_DC, "IVAC", true},
sysInstFields{0, 7, 6, 2}: {sys_DC, "ISW", true}, {0, 7, 6, 2}: {sys_DC, "ISW", true},
sysInstFields{0, 7, 10, 2}: {sys_DC, "CSW", true}, {0, 7, 10, 2}: {sys_DC, "CSW", true},
sysInstFields{0, 7, 14, 2}: {sys_DC, "CISW", true}, {0, 7, 14, 2}: {sys_DC, "CISW", true},
sysInstFields{3, 7, 4, 1}: {sys_DC, "ZVA", true}, {3, 7, 4, 1}: {sys_DC, "ZVA", true},
sysInstFields{3, 7, 10, 1}: {sys_DC, "CVAC", true}, {3, 7, 10, 1}: {sys_DC, "CVAC", true},
sysInstFields{3, 7, 11, 1}: {sys_DC, "CVAU", true}, {3, 7, 11, 1}: {sys_DC, "CVAU", true},
sysInstFields{3, 7, 14, 1}: {sys_DC, "CIVAC", true}, {3, 7, 14, 1}: {sys_DC, "CIVAC", true},
sysInstFields{0, 7, 6, 3}: {sys_DC, "IGVAC", true}, {0, 7, 6, 3}: {sys_DC, "IGVAC", true},
sysInstFields{0, 7, 6, 4}: {sys_DC, "IGSW", true}, {0, 7, 6, 4}: {sys_DC, "IGSW", true},
sysInstFields{0, 7, 6, 5}: {sys_DC, "IGDVAC", true}, {0, 7, 6, 5}: {sys_DC, "IGDVAC", true},
sysInstFields{0, 7, 6, 6}: {sys_DC, "IGDSW", true}, {0, 7, 6, 6}: {sys_DC, "IGDSW", true},
sysInstFields{0, 7, 10, 4}: {sys_DC, "CGSW", true}, {0, 7, 10, 4}: {sys_DC, "CGSW", true},
sysInstFields{0, 7, 10, 6}: {sys_DC, "CGDSW", true}, {0, 7, 10, 6}: {sys_DC, "CGDSW", true},
sysInstFields{0, 7, 14, 4}: {sys_DC, "CIGSW", true}, {0, 7, 14, 4}: {sys_DC, "CIGSW", true},
sysInstFields{0, 7, 14, 6}: {sys_DC, "CIGDSW", true}, {0, 7, 14, 6}: {sys_DC, "CIGDSW", true},
sysInstFields{3, 7, 4, 3}: {sys_DC, "GVA", true}, {3, 7, 4, 3}: {sys_DC, "GVA", true},
sysInstFields{3, 7, 4, 4}: {sys_DC, "GZVA", true}, {3, 7, 4, 4}: {sys_DC, "GZVA", true},
sysInstFields{3, 7, 10, 3}: {sys_DC, "CGVAC", true}, {3, 7, 10, 3}: {sys_DC, "CGVAC", true},
sysInstFields{3, 7, 10, 5}: {sys_DC, "CGDVAC", true}, {3, 7, 10, 5}: {sys_DC, "CGDVAC", true},
sysInstFields{3, 7, 12, 3}: {sys_DC, "CGVAP", true}, {3, 7, 12, 3}: {sys_DC, "CGVAP", true},
sysInstFields{3, 7, 12, 5}: {sys_DC, "CGDVAP", true}, {3, 7, 12, 5}: {sys_DC, "CGDVAP", true},
sysInstFields{3, 7, 13, 3}: {sys_DC, "CGVADP", true}, {3, 7, 13, 3}: {sys_DC, "CGVADP", true},
sysInstFields{3, 7, 13, 5}: {sys_DC, "CGDVADP", true}, {3, 7, 13, 5}: {sys_DC, "CGDVADP", true},
sysInstFields{3, 7, 14, 3}: {sys_DC, "CIGVAC", true}, {3, 7, 14, 3}: {sys_DC, "CIGVAC", true},
sysInstFields{3, 7, 14, 5}: {sys_DC, "CIGDVAC", true}, {3, 7, 14, 5}: {sys_DC, "CIGDVAC", true},
sysInstFields{3, 7, 12, 1}: {sys_DC, "CVAP", true}, {3, 7, 12, 1}: {sys_DC, "CVAP", true},
sysInstFields{3, 7, 13, 1}: {sys_DC, "CVADP", true}, {3, 7, 13, 1}: {sys_DC, "CVADP", true},
} }

View file

@ -142,7 +142,7 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
case LRVH: case LRVH:
op = "MOVHBR" op = "MOVHBR"
} }
case LA, LAY: case LA, LAY, LARL:
args[0], args[1] = args[1], args[0] args[0], args[1] = args[1], args[0]
op = "MOVD" op = "MOVD"
@ -349,6 +349,17 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
case SLBGR: case SLBGR:
op = "SUBE" op = "SUBE"
args[0], args[1] = args[1], args[0] args[0], args[1] = args[1], args[0]
case MADBR:
op = "FMADD"
args[0], args[1], args[2] = args[1], args[2], args[0]
case VFM:
op = "WFMDB"
args[0], args[1], args[2] = args[1], args[2], args[0]
args = args[0:3]
case VFS:
op = "WFSDB"
args[0], args[2] = args[2], args[0]
args = args[0:3]
case MSGFR, MHI, MSFI, MSGFI: case MSGFR, MHI, MSFI, MSGFI:
switch inst.Op { switch inst.Op {
case MSGFR, MHI, MSFI: case MSGFR, MHI, MSFI:
@ -500,16 +511,16 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
if err != nil { if err != nil {
return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err) return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
} }
opStr, check := branchOnConditionOp(mask, inst.Op) opStr := branchOnConditionOp(mask, inst.Op)
if opStr != "" { if opStr != "" {
op = opStr op = opStr
} }
if op == "SYNC" || op == "NOPH" { if op == "SYNC" || op == "NOPH" {
return op return op
} }
if check { if op == "RET" {
args[0] = args[1] args = args[:0]
args = args[:1] return op
} }
case LOCGR: case LOCGR:
mask, err := strconv.Atoi(args[2][1:]) mask, err := strconv.Atoi(args[2][1:])
@ -1036,6 +1047,9 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
// branch on relative mnemonic. // branch on relative mnemonic.
func branch_relative_op(mask int, opconst Op) (op string, check bool) { func branch_relative_op(mask int, opconst Op) (op string, check bool) {
switch mask & 0xf { switch mask & 0xf {
case 1:
op = "BVS"
check = true
case 2: case 2:
op = "BGT" op = "BGT"
check = true check = true
@ -1061,7 +1075,7 @@ func branch_relative_op(mask int, opconst Op) (op string, check bool) {
op = "BLEU" op = "BLEU"
check = true check = true
case 15: case 15:
op = "JMP" // BR op = "BR"
check = true check = true
} }
return op, check return op, check
@ -1069,17 +1083,16 @@ func branch_relative_op(mask int, opconst Op) (op string, check bool) {
// This function returns corresponding extended mnemonic for the given // This function returns corresponding extended mnemonic for the given
// brach on condition mnemonic. // brach on condition mnemonic.
func branchOnConditionOp(mask int, opconst Op) (op string, check bool) { func branchOnConditionOp(mask int, opconst Op) (op string) {
switch mask & 0xf { switch mask & 0xf {
case 0: case 0:
op = "NOPH" op = "NOPH"
case 14: case 14:
op = "SYNC" op = "SYNC"
case 15: case 15:
op = "JMP" op = "RET"
check = true
} }
return op, check return op
} }
// This function returns corresponding plan9 mnemonic for the native bitwise mnemonic. // This function returns corresponding plan9 mnemonic for the native bitwise mnemonic.
@ -1260,7 +1273,7 @@ func reverseOperandOrder(op Op) bool {
switch op { switch op {
case LOCR, MLGR: case LOCR, MLGR:
return true return true
case LTEBR, LTDBR: case LTEBR, LTDBR, LCDBR, LGDR:
return true return true
case VLEIB, VLEIH, VLEIF, VLEIG, VPDI: case VLEIB, VLEIH, VLEIF, VLEIG, VPDI:
return true return true

View file

@ -667,6 +667,7 @@ func gnuArg(inst *Inst, pc uint64, symname SymLookup, x Arg, usedPrefixes *bool)
} }
} }
case Imm: case Imm:
if (inst.Op == MOV || inst.Op == PUSH) && inst.DataSize == 32 { // See comment in plan9x.go.
if s, base := symname(uint64(x)); s != "" { if s, base := symname(uint64(x)); s != "" {
suffix := "" suffix := ""
if uint64(x) != base { if uint64(x) != base {
@ -674,6 +675,7 @@ func gnuArg(inst *Inst, pc uint64, symname SymLookup, x Arg, usedPrefixes *bool)
} }
return fmt.Sprintf("$%s%s", s, suffix) return fmt.Sprintf("$%s%s", s, suffix)
} }
}
if inst.Mode == 32 { if inst.Mode == 32 {
return fmt.Sprintf("$%#x", uint32(x)) return fmt.Sprintf("$%#x", uint32(x))
} }

View file

@ -341,6 +341,7 @@ func IntelSyntax(inst Inst, pc uint64, symname SymLookup) string {
func intelArg(inst *Inst, pc uint64, symname SymLookup, arg Arg) string { func intelArg(inst *Inst, pc uint64, symname SymLookup, arg Arg) string {
switch a := arg.(type) { switch a := arg.(type) {
case Imm: case Imm:
if (inst.Op == MOV || inst.Op == PUSH) && inst.DataSize == 32 { // See comment in plan9x.go.
if s, base := symname(uint64(a)); s != "" { if s, base := symname(uint64(a)); s != "" {
suffix := "" suffix := ""
if uint64(a) != base { if uint64(a) != base {
@ -348,6 +349,7 @@ func intelArg(inst *Inst, pc uint64, symname SymLookup, arg Arg) string {
} }
return fmt.Sprintf("$%s%s", s, suffix) return fmt.Sprintf("$%s%s", s, suffix)
} }
}
if inst.Mode == 32 { if inst.Mode == 32 {
return fmt.Sprintf("%#x", uint32(a)) return fmt.Sprintf("%#x", uint32(a))
} }

View file

@ -116,6 +116,16 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg
return fmt.Sprintf("%#x", addr) return fmt.Sprintf("%#x", addr)
case Imm: case Imm:
if (inst.Op == MOV || inst.Op == PUSH) && inst.DataSize == 32 {
// Only try to convert an immediate to a symbol in certain
// special circumstances. See issue 72942.
//
// On 64-bit, symbol addresses always hit the Mem case below.
// Particularly, we use LEAQ to materialize the address of
// a global or function.
//
// On 32-bit, we sometimes use MOVL. Still try to symbolize
// those immediates.
if s, base := symname(uint64(a)); s != "" { if s, base := symname(uint64(a)); s != "" {
suffix := "" suffix := ""
if uint64(a) != base { if uint64(a) != base {
@ -123,6 +133,7 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg
} }
return fmt.Sprintf("$%s%s(SB)", s, suffix) return fmt.Sprintf("$%s%s(SB)", s, suffix)
} }
}
if inst.Mode == 32 { if inst.Mode == 32 {
return fmt.Sprintf("$%#x", uint32(a)) return fmt.Sprintf("$%#x", uint32(a))
} }

View file

@ -12,6 +12,8 @@ package errgroup
import ( import (
"context" "context"
"fmt" "fmt"
"runtime"
"runtime/debug"
"sync" "sync"
) )
@ -31,6 +33,10 @@ type Group struct {
errOnce sync.Once errOnce sync.Once
err error err error
mu sync.Mutex
panicValue any // = PanicError | PanicValue; non-nil if some Group.Go goroutine panicked.
abnormal bool // some Group.Go goroutine terminated abnormally (panic or goexit).
} }
func (g *Group) done() { func (g *Group) done() {
@ -50,33 +56,78 @@ func WithContext(ctx context.Context) (*Group, context.Context) {
return &Group{cancel: cancel}, ctx return &Group{cancel: cancel}, ctx
} }
// Wait blocks until all function calls from the Go method have returned, then // Wait blocks until all function calls from the Go method have returned
// returns the first non-nil error (if any) from them. // normally, then returns the first non-nil error (if any) from them.
//
// If any of the calls panics, Wait panics with a [PanicValue];
// and if any of them calls [runtime.Goexit], Wait calls runtime.Goexit.
func (g *Group) Wait() error { func (g *Group) Wait() error {
g.wg.Wait() g.wg.Wait()
if g.cancel != nil { if g.cancel != nil {
g.cancel(g.err) g.cancel(g.err)
} }
if g.panicValue != nil {
panic(g.panicValue)
}
if g.abnormal {
runtime.Goexit()
}
return g.err return g.err
} }
// Go calls the given function in a new goroutine. // Go calls the given function in a new goroutine.
//
// The first call to Go must happen before a Wait. // The first call to Go must happen before a Wait.
// It blocks until the new goroutine can be added without the number of // It blocks until the new goroutine can be added without the number of
// active goroutines in the group exceeding the configured limit. // goroutines in the group exceeding the configured limit.
// //
// The first call to return a non-nil error cancels the group's context, if the // The first goroutine in the group that returns a non-nil error, panics, or
// group was created by calling WithContext. The error will be returned by Wait. // invokes [runtime.Goexit] will cancel the associated Context, if any.
func (g *Group) Go(f func() error) { func (g *Group) Go(f func() error) {
if g.sem != nil { if g.sem != nil {
g.sem <- token{} g.sem <- token{}
} }
g.add(f)
}
func (g *Group) add(f func() error) {
g.wg.Add(1) g.wg.Add(1)
go func() { go func() {
defer g.done() defer g.done()
normalReturn := false
defer func() {
if normalReturn {
return
}
v := recover()
g.mu.Lock()
defer g.mu.Unlock()
if !g.abnormal {
if g.cancel != nil {
g.cancel(g.err)
}
g.abnormal = true
}
if v != nil && g.panicValue == nil {
switch v := v.(type) {
case error:
g.panicValue = PanicError{
Recovered: v,
Stack: debug.Stack(),
}
default:
g.panicValue = PanicValue{
Recovered: v,
Stack: debug.Stack(),
}
}
}
}()
if err := f(); err != nil { err := f()
normalReturn = true
if err != nil {
g.errOnce.Do(func() { g.errOnce.Do(func() {
g.err = err g.err = err
if g.cancel != nil { if g.cancel != nil {
@ -101,19 +152,7 @@ func (g *Group) TryGo(f func() error) bool {
} }
} }
g.wg.Add(1) g.add(f)
go func() {
defer g.done()
if err := f(); err != nil {
g.errOnce.Do(func() {
g.err = err
if g.cancel != nil {
g.cancel(g.err)
}
})
}
}()
return true return true
} }
@ -135,3 +174,34 @@ func (g *Group) SetLimit(n int) {
} }
g.sem = make(chan token, n) g.sem = make(chan token, n)
} }
// PanicError wraps an error recovered from an unhandled panic
// when calling a function passed to Go or TryGo.
type PanicError struct {
Recovered error
Stack []byte // result of call to [debug.Stack]
}
func (p PanicError) Error() string {
if len(p.Stack) > 0 {
return fmt.Sprintf("recovered from errgroup.Group: %v\n%s", p.Recovered, p.Stack)
}
return fmt.Sprintf("recovered from errgroup.Group: %v", p.Recovered)
}
func (p PanicError) Unwrap() error { return p.Recovered }
// PanicValue wraps a value that does not implement the error interface,
// recovered from an unhandled panic when calling a function passed to Go or
// TryGo.
type PanicValue struct {
Recovered any
Stack []byte // result of call to [debug.Stack]
}
func (p PanicValue) String() string {
if len(p.Stack) > 0 {
return fmt.Sprintf("recovered from errgroup.Group: %v\n%s", p.Recovered, p.Stack)
}
return fmt.Sprintf("recovered from errgroup.Group: %v", p.Recovered)
}

View file

@ -1303,7 +1303,10 @@ func (selfRelativeSD *SECURITY_DESCRIPTOR) ToAbsolute() (absoluteSD *SECURITY_DE
return nil, err return nil, err
} }
if absoluteSDSize > 0 { if absoluteSDSize > 0 {
absoluteSD = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, absoluteSDSize)[0])) absoluteSD = new(SECURITY_DESCRIPTOR)
if unsafe.Sizeof(*absoluteSD) < uintptr(absoluteSDSize) {
panic("sizeof(SECURITY_DESCRIPTOR) too small")
}
} }
var ( var (
dacl *ACL dacl *ACL
@ -1312,19 +1315,55 @@ func (selfRelativeSD *SECURITY_DESCRIPTOR) ToAbsolute() (absoluteSD *SECURITY_DE
group *SID group *SID
) )
if daclSize > 0 { if daclSize > 0 {
dacl = (*ACL)(unsafe.Pointer(&make([]byte, daclSize)[0])) dacl = (*ACL)(unsafe.Pointer(unsafe.SliceData(make([]byte, daclSize))))
} }
if saclSize > 0 { if saclSize > 0 {
sacl = (*ACL)(unsafe.Pointer(&make([]byte, saclSize)[0])) sacl = (*ACL)(unsafe.Pointer(unsafe.SliceData(make([]byte, saclSize))))
} }
if ownerSize > 0 { if ownerSize > 0 {
owner = (*SID)(unsafe.Pointer(&make([]byte, ownerSize)[0])) owner = (*SID)(unsafe.Pointer(unsafe.SliceData(make([]byte, ownerSize))))
} }
if groupSize > 0 { if groupSize > 0 {
group = (*SID)(unsafe.Pointer(&make([]byte, groupSize)[0])) group = (*SID)(unsafe.Pointer(unsafe.SliceData(make([]byte, groupSize))))
} }
// We call into Windows via makeAbsoluteSD, which sets up
// pointers within absoluteSD that point to other chunks of memory
// we pass into makeAbsoluteSD, and that happens outside the view of the GC.
// We therefore take some care here to then verify the pointers are as we expect
// and set them explicitly in view of the GC. See https://go.dev/issue/73199.
// TODO: consider weak pointers once Go 1.24 is appropriate. See suggestion in https://go.dev/cl/663575.
err = makeAbsoluteSD(selfRelativeSD, absoluteSD, &absoluteSDSize, err = makeAbsoluteSD(selfRelativeSD, absoluteSD, &absoluteSDSize,
dacl, &daclSize, sacl, &saclSize, owner, &ownerSize, group, &groupSize) dacl, &daclSize, sacl, &saclSize, owner, &ownerSize, group, &groupSize)
if err != nil {
// Don't return absoluteSD, which might be partially initialized.
return nil, err
}
// Before using any fields, verify absoluteSD is in the format we expect according to Windows.
// See https://learn.microsoft.com/en-us/windows/win32/secauthz/absolute-and-self-relative-security-descriptors
absControl, _, err := absoluteSD.Control()
if err != nil {
panic("absoluteSD: " + err.Error())
}
if absControl&SE_SELF_RELATIVE != 0 {
panic("absoluteSD not in absolute format")
}
if absoluteSD.dacl != dacl {
panic("dacl pointer mismatch")
}
if absoluteSD.sacl != sacl {
panic("sacl pointer mismatch")
}
if absoluteSD.owner != owner {
panic("owner pointer mismatch")
}
if absoluteSD.group != group {
panic("group pointer mismatch")
}
absoluteSD.dacl = dacl
absoluteSD.sacl = sacl
absoluteSD.owner = owner
absoluteSD.group = group
return return
} }

View file

@ -870,6 +870,7 @@ const socket_error = uintptr(^uint32(0))
//sys WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecvFrom //sys WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecvFrom
//sys WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASendTo //sys WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASendTo
//sys WSASocket(af int32, typ int32, protocol int32, protoInfo *WSAProtocolInfo, group uint32, flags uint32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.WSASocketW //sys WSASocket(af int32, typ int32, protocol int32, protoInfo *WSAProtocolInfo, group uint32, flags uint32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.WSASocketW
//sys WSADuplicateSocket(s Handle, processID uint32, info *WSAProtocolInfo) (err error) [failretval!=0] = ws2_32.WSADuplicateSocketW
//sys GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname //sys GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname
//sys GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname //sys GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname
//sys Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs //sys Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs
@ -1698,8 +1699,9 @@ func NewNTUnicodeString(s string) (*NTUnicodeString, error) {
// Slice returns a uint16 slice that aliases the data in the NTUnicodeString. // Slice returns a uint16 slice that aliases the data in the NTUnicodeString.
func (s *NTUnicodeString) Slice() []uint16 { func (s *NTUnicodeString) Slice() []uint16 {
slice := unsafe.Slice(s.Buffer, s.MaximumLength) // Note: this rounds the length down, if it happens
return slice[:s.Length] // to (incorrectly) be odd. Probably safer than rounding up.
return unsafe.Slice(s.Buffer, s.MaximumLength/2)[:s.Length/2]
} }
func (s *NTUnicodeString) String() string { func (s *NTUnicodeString) String() string {

View file

@ -2700,6 +2700,8 @@ type CommTimeouts struct {
// NTUnicodeString is a UTF-16 string for NT native APIs, corresponding to UNICODE_STRING. // NTUnicodeString is a UTF-16 string for NT native APIs, corresponding to UNICODE_STRING.
type NTUnicodeString struct { type NTUnicodeString struct {
// Note: Length and MaximumLength are in *bytes*, not uint16s.
// They should always be even.
Length uint16 Length uint16
MaximumLength uint16 MaximumLength uint16
Buffer *uint16 Buffer *uint16
@ -3628,3 +3630,213 @@ const (
KLF_NOTELLSHELL = 0x00000080 KLF_NOTELLSHELL = 0x00000080
KLF_SETFORPROCESS = 0x00000100 KLF_SETFORPROCESS = 0x00000100
) )
// Virtual Key codes
// https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
const (
VK_LBUTTON = 0x01
VK_RBUTTON = 0x02
VK_CANCEL = 0x03
VK_MBUTTON = 0x04
VK_XBUTTON1 = 0x05
VK_XBUTTON2 = 0x06
VK_BACK = 0x08
VK_TAB = 0x09
VK_CLEAR = 0x0C
VK_RETURN = 0x0D
VK_SHIFT = 0x10
VK_CONTROL = 0x11
VK_MENU = 0x12
VK_PAUSE = 0x13
VK_CAPITAL = 0x14
VK_KANA = 0x15
VK_HANGEUL = 0x15
VK_HANGUL = 0x15
VK_IME_ON = 0x16
VK_JUNJA = 0x17
VK_FINAL = 0x18
VK_HANJA = 0x19
VK_KANJI = 0x19
VK_IME_OFF = 0x1A
VK_ESCAPE = 0x1B
VK_CONVERT = 0x1C
VK_NONCONVERT = 0x1D
VK_ACCEPT = 0x1E
VK_MODECHANGE = 0x1F
VK_SPACE = 0x20
VK_PRIOR = 0x21
VK_NEXT = 0x22
VK_END = 0x23
VK_HOME = 0x24
VK_LEFT = 0x25
VK_UP = 0x26
VK_RIGHT = 0x27
VK_DOWN = 0x28
VK_SELECT = 0x29
VK_PRINT = 0x2A
VK_EXECUTE = 0x2B
VK_SNAPSHOT = 0x2C
VK_INSERT = 0x2D
VK_DELETE = 0x2E
VK_HELP = 0x2F
VK_LWIN = 0x5B
VK_RWIN = 0x5C
VK_APPS = 0x5D
VK_SLEEP = 0x5F
VK_NUMPAD0 = 0x60
VK_NUMPAD1 = 0x61
VK_NUMPAD2 = 0x62
VK_NUMPAD3 = 0x63
VK_NUMPAD4 = 0x64
VK_NUMPAD5 = 0x65
VK_NUMPAD6 = 0x66
VK_NUMPAD7 = 0x67
VK_NUMPAD8 = 0x68
VK_NUMPAD9 = 0x69
VK_MULTIPLY = 0x6A
VK_ADD = 0x6B
VK_SEPARATOR = 0x6C
VK_SUBTRACT = 0x6D
VK_DECIMAL = 0x6E
VK_DIVIDE = 0x6F
VK_F1 = 0x70
VK_F2 = 0x71
VK_F3 = 0x72
VK_F4 = 0x73
VK_F5 = 0x74
VK_F6 = 0x75
VK_F7 = 0x76
VK_F8 = 0x77
VK_F9 = 0x78
VK_F10 = 0x79
VK_F11 = 0x7A
VK_F12 = 0x7B
VK_F13 = 0x7C
VK_F14 = 0x7D
VK_F15 = 0x7E
VK_F16 = 0x7F
VK_F17 = 0x80
VK_F18 = 0x81
VK_F19 = 0x82
VK_F20 = 0x83
VK_F21 = 0x84
VK_F22 = 0x85
VK_F23 = 0x86
VK_F24 = 0x87
VK_NUMLOCK = 0x90
VK_SCROLL = 0x91
VK_OEM_NEC_EQUAL = 0x92
VK_OEM_FJ_JISHO = 0x92
VK_OEM_FJ_MASSHOU = 0x93
VK_OEM_FJ_TOUROKU = 0x94
VK_OEM_FJ_LOYA = 0x95
VK_OEM_FJ_ROYA = 0x96
VK_LSHIFT = 0xA0
VK_RSHIFT = 0xA1
VK_LCONTROL = 0xA2
VK_RCONTROL = 0xA3
VK_LMENU = 0xA4
VK_RMENU = 0xA5
VK_BROWSER_BACK = 0xA6
VK_BROWSER_FORWARD = 0xA7
VK_BROWSER_REFRESH = 0xA8
VK_BROWSER_STOP = 0xA9
VK_BROWSER_SEARCH = 0xAA
VK_BROWSER_FAVORITES = 0xAB
VK_BROWSER_HOME = 0xAC
VK_VOLUME_MUTE = 0xAD
VK_VOLUME_DOWN = 0xAE
VK_VOLUME_UP = 0xAF
VK_MEDIA_NEXT_TRACK = 0xB0
VK_MEDIA_PREV_TRACK = 0xB1
VK_MEDIA_STOP = 0xB2
VK_MEDIA_PLAY_PAUSE = 0xB3
VK_LAUNCH_MAIL = 0xB4
VK_LAUNCH_MEDIA_SELECT = 0xB5
VK_LAUNCH_APP1 = 0xB6
VK_LAUNCH_APP2 = 0xB7
VK_OEM_1 = 0xBA
VK_OEM_PLUS = 0xBB
VK_OEM_COMMA = 0xBC
VK_OEM_MINUS = 0xBD
VK_OEM_PERIOD = 0xBE
VK_OEM_2 = 0xBF
VK_OEM_3 = 0xC0
VK_OEM_4 = 0xDB
VK_OEM_5 = 0xDC
VK_OEM_6 = 0xDD
VK_OEM_7 = 0xDE
VK_OEM_8 = 0xDF
VK_OEM_AX = 0xE1
VK_OEM_102 = 0xE2
VK_ICO_HELP = 0xE3
VK_ICO_00 = 0xE4
VK_PROCESSKEY = 0xE5
VK_ICO_CLEAR = 0xE6
VK_OEM_RESET = 0xE9
VK_OEM_JUMP = 0xEA
VK_OEM_PA1 = 0xEB
VK_OEM_PA2 = 0xEC
VK_OEM_PA3 = 0xED
VK_OEM_WSCTRL = 0xEE
VK_OEM_CUSEL = 0xEF
VK_OEM_ATTN = 0xF0
VK_OEM_FINISH = 0xF1
VK_OEM_COPY = 0xF2
VK_OEM_AUTO = 0xF3
VK_OEM_ENLW = 0xF4
VK_OEM_BACKTAB = 0xF5
VK_ATTN = 0xF6
VK_CRSEL = 0xF7
VK_EXSEL = 0xF8
VK_EREOF = 0xF9
VK_PLAY = 0xFA
VK_ZOOM = 0xFB
VK_NONAME = 0xFC
VK_PA1 = 0xFD
VK_OEM_CLEAR = 0xFE
)
// Mouse button constants.
// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str
const (
FROM_LEFT_1ST_BUTTON_PRESSED = 0x0001
RIGHTMOST_BUTTON_PRESSED = 0x0002
FROM_LEFT_2ND_BUTTON_PRESSED = 0x0004
FROM_LEFT_3RD_BUTTON_PRESSED = 0x0008
FROM_LEFT_4TH_BUTTON_PRESSED = 0x0010
)
// Control key state constaints.
// https://docs.microsoft.com/en-us/windows/console/key-event-record-str
// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str
const (
CAPSLOCK_ON = 0x0080
ENHANCED_KEY = 0x0100
LEFT_ALT_PRESSED = 0x0002
LEFT_CTRL_PRESSED = 0x0008
NUMLOCK_ON = 0x0020
RIGHT_ALT_PRESSED = 0x0001
RIGHT_CTRL_PRESSED = 0x0004
SCROLLLOCK_ON = 0x0040
SHIFT_PRESSED = 0x0010
)
// Mouse event record event flags.
// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str
const (
MOUSE_MOVED = 0x0001
DOUBLE_CLICK = 0x0002
MOUSE_WHEELED = 0x0004
MOUSE_HWHEELED = 0x0008
)
// Input Record Event Types
// https://learn.microsoft.com/en-us/windows/console/input-record-str
const (
FOCUS_EVENT = 0x0010
KEY_EVENT = 0x0001
MENU_EVENT = 0x0008
MOUSE_EVENT = 0x0002
WINDOW_BUFFER_SIZE_EVENT = 0x0004
)

View file

@ -511,6 +511,7 @@ var (
procFreeAddrInfoW = modws2_32.NewProc("FreeAddrInfoW") procFreeAddrInfoW = modws2_32.NewProc("FreeAddrInfoW")
procGetAddrInfoW = modws2_32.NewProc("GetAddrInfoW") procGetAddrInfoW = modws2_32.NewProc("GetAddrInfoW")
procWSACleanup = modws2_32.NewProc("WSACleanup") procWSACleanup = modws2_32.NewProc("WSACleanup")
procWSADuplicateSocketW = modws2_32.NewProc("WSADuplicateSocketW")
procWSAEnumProtocolsW = modws2_32.NewProc("WSAEnumProtocolsW") procWSAEnumProtocolsW = modws2_32.NewProc("WSAEnumProtocolsW")
procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult") procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult")
procWSAIoctl = modws2_32.NewProc("WSAIoctl") procWSAIoctl = modws2_32.NewProc("WSAIoctl")
@ -4391,6 +4392,14 @@ func WSACleanup() (err error) {
return return
} }
func WSADuplicateSocket(s Handle, processID uint32, info *WSAProtocolInfo) (err error) {
r1, _, e1 := syscall.Syscall(procWSADuplicateSocketW.Addr(), 3, uintptr(s), uintptr(processID), uintptr(unsafe.Pointer(info)))
if r1 != 0 {
err = errnoErr(e1)
}
return
}
func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) { func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) {
r0, _, e1 := syscall.Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength))) r0, _, e1 := syscall.Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength)))
n = int32(r0) n = int32(r0)

View file

@ -8,6 +8,7 @@ package countertest
import ( import (
"sync" "sync"
"testing"
"golang.org/x/telemetry/counter" "golang.org/x/telemetry/counter"
ic "golang.org/x/telemetry/internal/counter" ic "golang.org/x/telemetry/internal/counter"
@ -61,3 +62,10 @@ func ReadStackCounter(c *counter.StackCounter) (stackCounts map[string]uint64, _
func ReadFile(name string) (counters, stackCounters map[string]uint64, _ error) { func ReadFile(name string) (counters, stackCounters map[string]uint64, _ error) {
return ic.ReadFile(name) return ic.ReadFile(name)
} }
func init() {
// Extra safety check.
if !testing.Testing() {
panic("use of this package is disallowed in non-testing code")
}
}

View file

@ -1,16 +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 countertest
import "testing"
func init() {
// Extra safety check for go1.21+.
if !testing.Testing() {
panic("use of this package is disallowed in non-testing code")
}
}

View file

@ -93,12 +93,22 @@ func EncodeStack(pcs []uintptr, prefix string) string {
// Use function-relative line numbering. // Use function-relative line numbering.
// f:+2 means two lines into function f. // f:+2 means two lines into function f.
// f:-1 should never happen, but be conservative. // f:-1 should never happen, but be conservative.
//
// An inlined call is replaced by a NOP instruction
// with the correct pclntab information.
_, entryLine := fr.Func.FileLine(fr.Entry) _, entryLine := fr.Func.FileLine(fr.Entry)
loc = fmt.Sprintf("%s.%s:%+d", path, fname, fr.Line-entryLine) loc = fmt.Sprintf("%s.%s:%+d,+0x%x", path, fname, fr.Line-entryLine, fr.PC-fr.Entry)
} else { } else {
// The function is non-Go code or is fully inlined: // The function is non-Go code or is fully inlined:
// use absolute line number within enclosing file. // use absolute line number within enclosing file.
loc = fmt.Sprintf("%s.%s:=%d", path, fname, fr.Line) //
// For inlined calls, the PC and Entry values
// both refer to the enclosing combined function.
// For example, both these PCs are relative to "caller":
//
// callee:=1,+0x12 ('=' means inlined)
// caller:+2,+0x34
loc = fmt.Sprintf("%s.%s:=%d,+0x%x", path, fname, fr.Line, fr.PC-fr.Entry)
} }
locs = append(locs, loc) locs = append(locs, loc)
if !more { if !more {

View file

@ -1,17 +0,0 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build go1.23
// +build go1.23
package crashmonitor
import (
"os"
"runtime/debug"
)
func init() {
setCrashOutput = func(f *os.File) error { return debug.SetCrashOutput(f, debug.CrashOptions{}) }
}

View file

@ -21,20 +21,13 @@ import (
"golang.org/x/telemetry/internal/counter" "golang.org/x/telemetry/internal/counter"
) )
// Supported reports whether the runtime supports [runtime/debug.SetCrashOutput].
//
// TODO(adonovan): eliminate once go1.23+ is assured.
func Supported() bool { return setCrashOutput != nil }
var setCrashOutput func(*os.File) error // = runtime/debug.SetCrashOutput on go1.23+
// Parent sets up the parent side of the crashmonitor. It requires // Parent sets up the parent side of the crashmonitor. It requires
// exclusive use of a writable pipe connected to the child process's stdin. // exclusive use of a writable pipe connected to the child process's stdin.
func Parent(pipe *os.File) { func Parent(pipe *os.File) {
writeSentinel(pipe) writeSentinel(pipe)
// Ensure that we get pc=0x%x values in the traceback. // Ensure that we get pc=0x%x values in the traceback.
debug.SetTraceback("system") debug.SetTraceback("system")
setCrashOutput(pipe) debug.SetCrashOutput(pipe, debug.CrashOptions{}) // ignore error
} }
// Child runs the part of the crashmonitor that runs in the child process. // Child runs the part of the crashmonitor that runs in the child process.
@ -284,7 +277,7 @@ func parseStackPCs(crash string) ([]uintptr, error) {
continue continue
} }
pc = pc-parentSentinel+childSentinel pc = pc - parentSentinel + childSentinel
// If the previous frame was sigpanic, then this frame // If the previous frame was sigpanic, then this frame
// was a trap (e.g., SIGSEGV). // was a trap (e.g., SIGSEGV).

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build (js && wasm) || wasip1 || plan9 || (solaris && !go1.20) //go:build (js && wasm) || wasip1 || plan9
package mmap package mmap

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build unix && (!solaris || go1.20) //go:build unix
package mmap package mmap

View file

@ -5,6 +5,7 @@
package telemetry package telemetry
import ( import (
"go/version"
"os" "os"
"path/filepath" "path/filepath"
"runtime/debug" "runtime/debug"
@ -26,9 +27,7 @@ func IsToolchainProgram(progPath string) bool {
// special characters. // special characters.
func ProgramInfo(info *debug.BuildInfo) (goVers, progPath, progVers string) { func ProgramInfo(info *debug.BuildInfo) (goVers, progPath, progVers string) {
goVers = info.GoVersion goVers = info.GoVersion
// TODO(matloob): Use go/version.IsValid instead of checking for X: once the telemetry if strings.Contains(goVers, "devel") || strings.Contains(goVers, "-") || !version.IsValid(goVers) {
// module can be upgraded to require Go 1.22.
if strings.Contains(goVers, "devel") || strings.Contains(goVers, "-") || strings.Contains(goVers, "X:") {
goVers = "devel" goVers = "devel"
} }

View file

@ -166,7 +166,7 @@ func parent(config Config) *StartResult {
} }
childShouldUpload := config.Upload && acquireUploadToken() childShouldUpload := config.Upload && acquireUploadToken()
reportCrashes := config.ReportCrashes && crashmonitor.Supported() reportCrashes := config.ReportCrashes
if reportCrashes || childShouldUpload { if reportCrashes || childShouldUpload {
startChild(reportCrashes, childShouldUpload, result) startChild(reportCrashes, childShouldUpload, result)
@ -267,10 +267,6 @@ func child(config Config) {
os.Setenv(telemetryChildVar, "2") os.Setenv(telemetryChildVar, "2")
upload := os.Getenv(telemetryUploadVar) == "1" upload := os.Getenv(telemetryUploadVar) == "1"
reportCrashes := config.ReportCrashes && crashmonitor.Supported()
uploadStartTime := config.UploadStartTime
uploadURL := config.UploadURL
// The crashmonitor and/or upload process may themselves record counters. // The crashmonitor and/or upload process may themselves record counters.
counter.Open() counter.Open()
@ -280,7 +276,7 @@ func child(config Config) {
// upload to finish before exiting // upload to finish before exiting
var g errgroup.Group var g errgroup.Group
if reportCrashes { if config.ReportCrashes {
g.Go(func() error { g.Go(func() error {
crashmonitor.Child() crashmonitor.Child()
return nil return nil
@ -288,7 +284,7 @@ func child(config Config) {
} }
if upload { if upload {
g.Go(func() error { g.Go(func() error {
uploaderChild(uploadStartTime, uploadURL) uploaderChild(config.UploadStartTime, config.UploadURL)
return nil return nil
}) })
} }

View file

@ -6,6 +6,7 @@ package term
import ( import (
"bytes" "bytes"
"fmt"
"io" "io"
"runtime" "runtime"
"strconv" "strconv"
@ -36,6 +37,26 @@ var vt100EscapeCodes = EscapeCodes{
Reset: []byte{keyEscape, '[', '0', 'm'}, Reset: []byte{keyEscape, '[', '0', 'm'},
} }
// A History provides a (possibly bounded) queue of input lines read by [Terminal.ReadLine].
type History interface {
// Add will be called by [Terminal.ReadLine] to add
// a new, most recent entry to the history.
// It is allowed to drop any entry, including
// the entry being added (e.g., if it's deemed an invalid entry),
// the least-recent entry (e.g., to keep the history bounded),
// or any other entry.
Add(entry string)
// Len returns the number of entries in the history.
Len() int
// At returns an entry from the history.
// Index 0 is the most-recently added entry and
// index Len()-1 is the least-recently added entry.
// If index is < 0 or >= Len(), it panics.
At(idx int) string
}
// Terminal contains the state for running a VT100 terminal that is capable of // Terminal contains the state for running a VT100 terminal that is capable of
// reading lines of input. // reading lines of input.
type Terminal struct { type Terminal struct {
@ -44,6 +65,8 @@ type Terminal struct {
// bytes, as an index into |line|). If it returns ok=false, the key // bytes, as an index into |line|). If it returns ok=false, the key
// press is processed normally. Otherwise it returns a replacement line // press is processed normally. Otherwise it returns a replacement line
// and the new cursor position. // and the new cursor position.
//
// This will be disabled during ReadPassword.
AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool) AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool)
// Escape contains a pointer to the escape codes for this terminal. // Escape contains a pointer to the escape codes for this terminal.
@ -84,9 +107,14 @@ type Terminal struct {
remainder []byte remainder []byte
inBuf [256]byte inBuf [256]byte
// history contains previously entered commands so that they can be // History records and retrieves lines of input read by [ReadLine] which
// accessed with the up and down keys. // a user can retrieve and navigate using the up and down arrow keys.
history stRingBuffer //
// It is not safe to call ReadLine concurrently with any methods on History.
//
// [NewTerminal] sets this to a default implementation that records the
// last 100 lines of input.
History History
// historyIndex stores the currently accessed history entry, where zero // historyIndex stores the currently accessed history entry, where zero
// means the immediately previous entry. // means the immediately previous entry.
historyIndex int historyIndex int
@ -109,6 +137,7 @@ func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
termHeight: 24, termHeight: 24,
echo: true, echo: true,
historyIndex: -1, historyIndex: -1,
History: &stRingBuffer{},
} }
} }
@ -448,6 +477,23 @@ func visualLength(runes []rune) int {
return length return length
} }
// histroryAt unlocks the terminal and relocks it while calling History.At.
func (t *Terminal) historyAt(idx int) (string, bool) {
t.lock.Unlock() // Unlock to avoid deadlock if History methods use the output writer.
defer t.lock.Lock() // panic in At (or Len) protection.
if idx < 0 || idx >= t.History.Len() {
return "", false
}
return t.History.At(idx), true
}
// historyAdd unlocks the terminal and relocks it while calling History.Add.
func (t *Terminal) historyAdd(entry string) {
t.lock.Unlock() // Unlock to avoid deadlock if History methods use the output writer.
defer t.lock.Lock() // panic in Add protection.
t.History.Add(entry)
}
// handleKey processes the given key and, optionally, returns a line of text // handleKey processes the given key and, optionally, returns a line of text
// that the user has entered. // that the user has entered.
func (t *Terminal) handleKey(key rune) (line string, ok bool) { func (t *Terminal) handleKey(key rune) (line string, ok bool) {
@ -495,7 +541,7 @@ func (t *Terminal) handleKey(key rune) (line string, ok bool) {
t.pos = len(t.line) t.pos = len(t.line)
t.moveCursorToPos(t.pos) t.moveCursorToPos(t.pos)
case keyUp: case keyUp:
entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1) entry, ok := t.historyAt(t.historyIndex + 1)
if !ok { if !ok {
return "", false return "", false
} }
@ -514,7 +560,7 @@ func (t *Terminal) handleKey(key rune) (line string, ok bool) {
t.setLine(runes, len(runes)) t.setLine(runes, len(runes))
t.historyIndex-- t.historyIndex--
default: default:
entry, ok := t.history.NthPreviousEntry(t.historyIndex - 1) entry, ok := t.historyAt(t.historyIndex - 1)
if ok { if ok {
t.historyIndex-- t.historyIndex--
runes := []rune(entry) runes := []rune(entry)
@ -692,6 +738,8 @@ func (t *Terminal) Write(buf []byte) (n int, err error) {
// ReadPassword temporarily changes the prompt and reads a password, without // ReadPassword temporarily changes the prompt and reads a password, without
// echo, from the terminal. // echo, from the terminal.
//
// The AutoCompleteCallback is disabled during this call.
func (t *Terminal) ReadPassword(prompt string) (line string, err error) { func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
t.lock.Lock() t.lock.Lock()
defer t.lock.Unlock() defer t.lock.Unlock()
@ -699,6 +747,11 @@ func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
oldPrompt := t.prompt oldPrompt := t.prompt
t.prompt = []rune(prompt) t.prompt = []rune(prompt)
t.echo = false t.echo = false
oldAutoCompleteCallback := t.AutoCompleteCallback
t.AutoCompleteCallback = nil
defer func() {
t.AutoCompleteCallback = oldAutoCompleteCallback
}()
line, err = t.readLine() line, err = t.readLine()
@ -772,7 +825,7 @@ func (t *Terminal) readLine() (line string, err error) {
if lineOk { if lineOk {
if t.echo { if t.echo {
t.historyIndex = -1 t.historyIndex = -1
t.history.Add(line) t.historyAdd(line)
} }
if lineIsPasted { if lineIsPasted {
err = ErrPasteIndicator err = ErrPasteIndicator
@ -929,19 +982,23 @@ func (s *stRingBuffer) Add(a string) {
} }
} }
// NthPreviousEntry returns the value passed to the nth previous call to Add. func (s *stRingBuffer) Len() int {
return s.size
}
// At returns the value passed to the nth previous call to Add.
// If n is zero then the immediately prior value is returned, if one, then the // If n is zero then the immediately prior value is returned, if one, then the
// next most recent, and so on. If such an element doesn't exist then ok is // next most recent, and so on. If such an element doesn't exist then ok is
// false. // false.
func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) { func (s *stRingBuffer) At(n int) string {
if n < 0 || n >= s.size { if n < 0 || n >= s.size {
return "", false panic(fmt.Sprintf("term: history index [%d] out of range [0,%d)", n, s.size))
} }
index := s.head - n index := s.head - n
if index < 0 { if index < 0 {
index += s.max index += s.max
} }
return s.entries[index], true return s.entries[index]
} }
// readPasswordLine reads from reader until it finds \n or io.EOF. // readPasswordLine reads from reader until it finds \n or io.EOF.

View file

@ -57,7 +57,7 @@ type asmArch struct {
// include the first integer register and first floating-point register. Accessing // include the first integer register and first floating-point register. Accessing
// any of them counts as writing to result. // any of them counts as writing to result.
retRegs []string retRegs []string
// writeResult is a list of instructions that will change result register implicity. // writeResult is a list of instructions that will change result register implicitly.
writeResult []string writeResult []string
// calculated during initialization // calculated during initialization
sizes types.Sizes sizes types.Sizes

View file

@ -153,7 +153,8 @@ func isLocalType(pass *analysis.Pass, typ types.Type) bool {
return isLocalType(pass, x.Elem()) return isLocalType(pass, x.Elem())
case interface{ Obj() *types.TypeName }: // *Named or *TypeParam (aliases were removed already) case interface{ Obj() *types.TypeName }: // *Named or *TypeParam (aliases were removed already)
// names in package foo are local to foo_test too // names in package foo are local to foo_test too
return strings.TrimSuffix(x.Obj().Pkg().Path(), "_test") == strings.TrimSuffix(pass.Pkg.Path(), "_test") return x.Obj().Pkg() != nil &&
strings.TrimSuffix(x.Obj().Pkg().Path(), "_test") == strings.TrimSuffix(pass.Pkg.Path(), "_test")
} }
return false return false
} }

View file

@ -30,7 +30,7 @@ var Analyzer = &analysis.Analyzer{
type arch struct { type arch struct {
isFPWrite func(string) bool isFPWrite func(string) bool
isFPRead func(string) bool isFPRead func(string) bool
isBranch func(string) bool isUnconditionalBranch func(string) bool
} }
var re = regexp.MustCompile var re = regexp.MustCompile
@ -48,8 +48,8 @@ var arches = map[string]arch{
"amd64": { "amd64": {
isFPWrite: re(`,\s*BP$`).MatchString, // TODO: can have false positive, e.g. for TESTQ BP,BP. Seems unlikely. isFPWrite: re(`,\s*BP$`).MatchString, // TODO: can have false positive, e.g. for TESTQ BP,BP. Seems unlikely.
isFPRead: re(`\bBP\b`).MatchString, isFPRead: re(`\bBP\b`).MatchString,
isBranch: func(s string) bool { isUnconditionalBranch: func(s string) bool {
return hasAnyPrefix(s, "J", "RET") return hasAnyPrefix(s, "JMP", "RET")
}, },
}, },
"arm64": { "arm64": {
@ -70,49 +70,16 @@ var arches = map[string]arch{
return false return false
}, },
isFPRead: re(`\bR29\b`).MatchString, isFPRead: re(`\bR29\b`).MatchString,
isBranch: func(s string) bool { isUnconditionalBranch: func(s string) bool {
// Get just the instruction // Get just the instruction
if i := strings.IndexFunc(s, unicode.IsSpace); i > 0 { if i := strings.IndexFunc(s, unicode.IsSpace); i > 0 {
s = s[:i] s = s[:i]
} }
return arm64Branch[s] return s == "B" || s == "JMP" || s == "RET"
}, },
}, },
} }
// arm64 has many control flow instructions.
// ^(B|RET) isn't sufficient or correct (e.g. BIC, BFI aren't control flow.)
// It's easier to explicitly enumerate them in a map than to write a regex.
// Borrowed from Go tree, cmd/asm/internal/arch/arm64.go
var arm64Branch = map[string]bool{
"B": true,
"BL": true,
"BEQ": true,
"BNE": true,
"BCS": true,
"BHS": true,
"BCC": true,
"BLO": true,
"BMI": true,
"BPL": true,
"BVS": true,
"BVC": true,
"BHI": true,
"BLS": true,
"BGE": true,
"BLT": true,
"BGT": true,
"BLE": true,
"CBZ": true,
"CBZW": true,
"CBNZ": true,
"CBNZW": true,
"JMP": true,
"TBNZ": true,
"TBZ": true,
"RET": true,
}
func run(pass *analysis.Pass) (any, error) { func run(pass *analysis.Pass) (any, error) {
arch, ok := arches[build.Default.GOARCH] arch, ok := arches[build.Default.GOARCH]
if !ok { if !ok {
@ -164,7 +131,7 @@ func run(pass *analysis.Pass) (any, error) {
active = false active = false
continue continue
} }
if arch.isFPRead(line) || arch.isBranch(line) { if arch.isFPRead(line) || arch.isUnconditionalBranch(line) {
active = false active = false
continue continue
} }

View file

@ -88,7 +88,7 @@ func run(pass *analysis.Pass) (any, error) {
// //
// TODO: consider allowing the "last" go/defer/Go statement to be followed by // TODO: consider allowing the "last" go/defer/Go statement to be followed by
// N "trivial" statements, possibly under a recursive definition of "trivial" // N "trivial" statements, possibly under a recursive definition of "trivial"
// so that that checker could, for example, conclude that a go statement is // so that checker could, for example, conclude that a go statement is
// followed by an if statement made of only trivial statements and trivial expressions, // followed by an if statement made of only trivial statements and trivial expressions,
// and hence the go statement could still be checked. // and hence the go statement could still be checked.
forEachLastStmt(body.List, func(last ast.Stmt) { forEachLastStmt(body.List, func(last ast.Stmt) {

View file

@ -22,6 +22,7 @@ import (
"golang.org/x/tools/go/ast/inspector" "golang.org/x/tools/go/ast/inspector"
"golang.org/x/tools/go/types/typeutil" "golang.org/x/tools/go/types/typeutil"
"golang.org/x/tools/internal/analysisinternal" "golang.org/x/tools/internal/analysisinternal"
"golang.org/x/tools/internal/astutil"
"golang.org/x/tools/internal/fmtstr" "golang.org/x/tools/internal/fmtstr"
"golang.org/x/tools/internal/typeparams" "golang.org/x/tools/internal/typeparams"
"golang.org/x/tools/internal/versions" "golang.org/x/tools/internal/versions"
@ -540,7 +541,7 @@ func checkPrintf(pass *analysis.Pass, fileVersion string, kind Kind, call *ast.C
firstArg := idx + 1 // Arguments are immediately after format string. firstArg := idx + 1 // Arguments are immediately after format string.
if !strings.Contains(format, "%") { if !strings.Contains(format, "%") {
if len(call.Args) > firstArg { if len(call.Args) > firstArg {
pass.Reportf(call.Lparen, "%s call has arguments but no formatting directives", name) pass.ReportRangef(call.Args[firstArg], "%s call has arguments but no formatting directives", name)
} }
return return
} }
@ -552,7 +553,7 @@ func checkPrintf(pass *analysis.Pass, fileVersion string, kind Kind, call *ast.C
if err != nil { if err != nil {
// All error messages are in predicate form ("call has a problem") // All error messages are in predicate form ("call has a problem")
// so that they may be affixed into a subject ("log.Printf "). // so that they may be affixed into a subject ("log.Printf ").
pass.ReportRangef(call.Args[idx], "%s %s", name, err) pass.ReportRangef(formatArg, "%s %s", name, err)
return return
} }
@ -560,20 +561,21 @@ func checkPrintf(pass *analysis.Pass, fileVersion string, kind Kind, call *ast.C
maxArgIndex := firstArg - 1 maxArgIndex := firstArg - 1
anyIndex := false anyIndex := false
// Check formats against args. // Check formats against args.
for _, operation := range operations { for _, op := range operations {
if operation.Prec.Index != -1 || if op.Prec.Index != -1 ||
operation.Width.Index != -1 || op.Width.Index != -1 ||
operation.Verb.Index != -1 { op.Verb.Index != -1 {
anyIndex = true anyIndex = true
} }
if !okPrintfArg(pass, call, &maxArgIndex, firstArg, name, operation) { rng := opRange(formatArg, op)
if !okPrintfArg(pass, call, rng, &maxArgIndex, firstArg, name, op) {
// One error per format is enough. // One error per format is enough.
return return
} }
if operation.Verb.Verb == 'w' { if op.Verb.Verb == 'w' {
switch kind { switch kind {
case KindNone, KindPrint, KindPrintf: case KindNone, KindPrint, KindPrintf:
pass.Reportf(call.Pos(), "%s does not support error-wrapping directive %%w", name) pass.ReportRangef(rng, "%s does not support error-wrapping directive %%w", name)
return return
} }
} }
@ -594,6 +596,18 @@ func checkPrintf(pass *analysis.Pass, fileVersion string, kind Kind, call *ast.C
} }
} }
// opRange returns the source range for the specified printf operation,
// such as the position of the %v substring of "...%v...".
func opRange(formatArg ast.Expr, op *fmtstr.Operation) analysis.Range {
if lit, ok := formatArg.(*ast.BasicLit); ok {
start, end, err := astutil.RangeInStringLiteral(lit, op.Range.Start, op.Range.End)
if err == nil {
return analysisinternal.Range(start, end) // position of "%v"
}
}
return formatArg // entire format string
}
// printfArgType encodes the types of expressions a printf verb accepts. It is a bitmask. // printfArgType encodes the types of expressions a printf verb accepts. It is a bitmask.
type printfArgType int type printfArgType int
@ -657,7 +671,7 @@ var printVerbs = []printVerb{
// okPrintfArg compares the operation to the arguments actually present, // okPrintfArg compares the operation to the arguments actually present,
// reporting any discrepancies it can discern, maxArgIndex was the index of the highest used index. // reporting any discrepancies it can discern, maxArgIndex was the index of the highest used index.
// If the final argument is ellipsissed, there's little it can do for that. // If the final argument is ellipsissed, there's little it can do for that.
func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, maxArgIndex *int, firstArg int, name string, operation *fmtstr.Operation) (ok bool) { func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, rng analysis.Range, maxArgIndex *int, firstArg int, name string, operation *fmtstr.Operation) (ok bool) {
verb := operation.Verb.Verb verb := operation.Verb.Verb
var v printVerb var v printVerb
found := false found := false
@ -680,7 +694,7 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, maxArgIndex *int, firs
if !formatter { if !formatter {
if !found { if !found {
pass.ReportRangef(call, "%s format %s has unknown verb %c", name, operation.Text, verb) pass.ReportRangef(rng, "%s format %s has unknown verb %c", name, operation.Text, verb)
return false return false
} }
for _, flag := range operation.Flags { for _, flag := range operation.Flags {
@ -690,7 +704,7 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, maxArgIndex *int, firs
continue continue
} }
if !strings.ContainsRune(v.flags, rune(flag)) { if !strings.ContainsRune(v.flags, rune(flag)) {
pass.ReportRangef(call, "%s format %s has unrecognized flag %c", name, operation.Text, flag) pass.ReportRangef(rng, "%s format %s has unrecognized flag %c", name, operation.Text, flag)
return false return false
} }
} }
@ -707,7 +721,7 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, maxArgIndex *int, firs
// If len(argIndexes)>0, we have something like %.*s and all // If len(argIndexes)>0, we have something like %.*s and all
// indexes in argIndexes must be an integer. // indexes in argIndexes must be an integer.
for _, argIndex := range argIndexes { for _, argIndex := range argIndexes {
if !argCanBeChecked(pass, call, argIndex, firstArg, operation, name) { if !argCanBeChecked(pass, call, rng, argIndex, firstArg, operation, name) {
return return
} }
arg := call.Args[argIndex] arg := call.Args[argIndex]
@ -716,7 +730,7 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, maxArgIndex *int, firs
if reason != "" { if reason != "" {
details = " (" + reason + ")" details = " (" + reason + ")"
} }
pass.ReportRangef(call, "%s format %s uses non-int %s%s as argument of *", name, operation.Text, analysisinternal.Format(pass.Fset, arg), details) pass.ReportRangef(rng, "%s format %s uses non-int %s%s as argument of *", name, operation.Text, analysisinternal.Format(pass.Fset, arg), details)
return false return false
} }
} }
@ -738,12 +752,12 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, maxArgIndex *int, firs
// Now check verb's type. // Now check verb's type.
verbArgIndex := operation.Verb.ArgIndex verbArgIndex := operation.Verb.ArgIndex
if !argCanBeChecked(pass, call, verbArgIndex, firstArg, operation, name) { if !argCanBeChecked(pass, call, rng, verbArgIndex, firstArg, operation, name) {
return false return false
} }
arg := call.Args[verbArgIndex] arg := call.Args[verbArgIndex]
if isFunctionValue(pass, arg) && verb != 'p' && verb != 'T' { if isFunctionValue(pass, arg) && verb != 'p' && verb != 'T' {
pass.ReportRangef(call, "%s format %s arg %s is a func value, not called", name, operation.Text, analysisinternal.Format(pass.Fset, arg)) pass.ReportRangef(rng, "%s format %s arg %s is a func value, not called", name, operation.Text, analysisinternal.Format(pass.Fset, arg))
return false return false
} }
if reason, ok := matchArgType(pass, v.typ, arg); !ok { if reason, ok := matchArgType(pass, v.typ, arg); !ok {
@ -755,12 +769,14 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, maxArgIndex *int, firs
if reason != "" { if reason != "" {
details = " (" + reason + ")" details = " (" + reason + ")"
} }
pass.ReportRangef(call, "%s format %s has arg %s of wrong type %s%s", name, operation.Text, analysisinternal.Format(pass.Fset, arg), typeString, details) pass.ReportRangef(rng, "%s format %s has arg %s of wrong type %s%s", name, operation.Text, analysisinternal.Format(pass.Fset, arg), typeString, details)
return false return false
} }
if v.typ&argString != 0 && v.verb != 'T' && !strings.Contains(operation.Flags, "#") { // Detect recursive formatting via value's String/Error methods.
// The '#' flag suppresses the methods, except with %x, %X, and %q.
if v.typ&argString != 0 && v.verb != 'T' && (!strings.Contains(operation.Flags, "#") || strings.ContainsRune("qxX", v.verb)) {
if methodName, ok := recursiveStringer(pass, arg); ok { if methodName, ok := recursiveStringer(pass, arg); ok {
pass.ReportRangef(call, "%s format %s with arg %s causes recursive %s method call", name, operation.Text, analysisinternal.Format(pass.Fset, arg), methodName) pass.ReportRangef(rng, "%s format %s with arg %s causes recursive %s method call", name, operation.Text, analysisinternal.Format(pass.Fset, arg), methodName)
return false return false
} }
} }
@ -844,7 +860,7 @@ func isFunctionValue(pass *analysis.Pass, e ast.Expr) bool {
// argCanBeChecked reports whether the specified argument is statically present; // argCanBeChecked reports whether the specified argument is statically present;
// it may be beyond the list of arguments or in a terminal slice... argument, which // it may be beyond the list of arguments or in a terminal slice... argument, which
// means we can't see it. // means we can't see it.
func argCanBeChecked(pass *analysis.Pass, call *ast.CallExpr, argIndex, firstArg int, operation *fmtstr.Operation, name string) bool { func argCanBeChecked(pass *analysis.Pass, call *ast.CallExpr, rng analysis.Range, argIndex, firstArg int, operation *fmtstr.Operation, name string) bool {
if argIndex <= 0 { if argIndex <= 0 {
// Shouldn't happen, so catch it with prejudice. // Shouldn't happen, so catch it with prejudice.
panic("negative argIndex") panic("negative argIndex")
@ -861,7 +877,7 @@ func argCanBeChecked(pass *analysis.Pass, call *ast.CallExpr, argIndex, firstArg
// There are bad indexes in the format or there are fewer arguments than the format needs. // There are bad indexes in the format or there are fewer arguments than the format needs.
// This is the argument number relative to the format: Printf("%s", "hi") will give 1 for the "hi". // This is the argument number relative to the format: Printf("%s", "hi") will give 1 for the "hi".
arg := argIndex - firstArg + 1 // People think of arguments as 1-indexed. arg := argIndex - firstArg + 1 // People think of arguments as 1-indexed.
pass.ReportRangef(call, "%s format %s reads arg #%d, but call has %v", name, operation.Text, arg, count(len(call.Args)-firstArg, "arg")) pass.ReportRangef(rng, "%s format %s reads arg #%d, but call has %v", name, operation.Text, arg, count(len(call.Args)-firstArg, "arg"))
return false return false
} }

View file

@ -17,6 +17,7 @@ import (
"golang.org/x/tools/go/ast/inspector" "golang.org/x/tools/go/ast/inspector"
"golang.org/x/tools/internal/analysisinternal" "golang.org/x/tools/internal/analysisinternal"
"golang.org/x/tools/internal/typeparams" "golang.org/x/tools/internal/typeparams"
"golang.org/x/tools/internal/typesinternal"
) )
//go:embed doc.go //go:embed doc.go
@ -60,12 +61,11 @@ func describe(typ, inType types.Type, inName string) string {
} }
func typeName(t types.Type) string { func typeName(t types.Type) string {
type hasTypeName interface{ Obj() *types.TypeName } // Alias, Named, TypeParam if basic, ok := t.(*types.Basic); ok {
switch t := t.(type) { return basic.Name() // may be (e.g.) "untyped int", which has no TypeName
case *types.Basic: }
return t.Name() if tname := typesinternal.TypeNameFor(t); tname != nil {
case hasTypeName: return tname.Name()
return t.Obj().Name()
} }
return "" return ""
} }

View file

@ -107,7 +107,7 @@ func checkCanonicalFieldTag(pass *analysis.Pass, field *types.Var, tag string, s
// Embedded struct. Nothing to do for now, but that // Embedded struct. Nothing to do for now, but that
// may change, depending on what happens with issue 7363. // may change, depending on what happens with issue 7363.
// TODO(adonovan): investigate, now that that issue is fixed. // TODO(adonovan): investigate, now that issue is fixed.
if field.Anonymous() { if field.Anonymous() {
return return
} }

View file

@ -447,18 +447,6 @@ func checkExampleName(pass *analysis.Pass, fn *ast.FuncDecl) {
} }
} }
type tokenRange struct {
p, e token.Pos
}
func (r tokenRange) Pos() token.Pos {
return r.p
}
func (r tokenRange) End() token.Pos {
return r.e
}
func checkTest(pass *analysis.Pass, fn *ast.FuncDecl, prefix string) { func checkTest(pass *analysis.Pass, fn *ast.FuncDecl, prefix string) {
// Want functions with 0 results and 1 parameter. // Want functions with 0 results and 1 parameter.
if fn.Type.Results != nil && len(fn.Type.Results.List) > 0 || if fn.Type.Results != nil && len(fn.Type.Results.List) > 0 ||
@ -476,8 +464,9 @@ func checkTest(pass *analysis.Pass, fn *ast.FuncDecl, prefix string) {
if tparams := fn.Type.TypeParams; tparams != nil && len(tparams.List) > 0 { if tparams := fn.Type.TypeParams; tparams != nil && len(tparams.List) > 0 {
// Note: cmd/go/internal/load also errors about TestXXX and BenchmarkXXX functions with type parameters. // Note: cmd/go/internal/load also errors about TestXXX and BenchmarkXXX functions with type parameters.
// We have currently decided to also warn before compilation/package loading. This can help users in IDEs. // We have currently decided to also warn before compilation/package loading. This can help users in IDEs.
at := tokenRange{tparams.Opening, tparams.Closing} pass.ReportRangef(analysisinternal.Range(tparams.Opening, tparams.Closing),
pass.ReportRangef(at, "%s has type parameters: it will not be run by go test as a %sXXX function", fn.Name.Name, prefix) "%s has type parameters: it will not be run by go test as a %sXXX function",
fn.Name.Name, prefix)
} }
if !isTestSuffix(fn.Name.Name[len(prefix):]) { if !isTestSuffix(fn.Name.Name[len(prefix):]) {

View file

@ -26,6 +26,7 @@ import (
"golang.org/x/tools/go/analysis/passes/internal/analysisutil" "golang.org/x/tools/go/analysis/passes/internal/analysisutil"
"golang.org/x/tools/go/ast/inspector" "golang.org/x/tools/go/ast/inspector"
"golang.org/x/tools/go/types/typeutil" "golang.org/x/tools/go/types/typeutil"
"golang.org/x/tools/internal/analysisinternal"
) )
//go:embed doc.go //go:embed doc.go
@ -64,17 +65,56 @@ func init() {
"context.WithTimeout": true, "context.WithTimeout": true,
"context.WithValue": true, "context.WithValue": true,
"errors.New": true, "errors.New": true,
"fmt.Append": true,
"fmt.Appendf": true,
"fmt.Appendln": true,
"fmt.Errorf": true, "fmt.Errorf": true,
"fmt.Sprint": true, "fmt.Sprint": true,
"fmt.Sprintf": true, "fmt.Sprintf": true,
"fmt.Sprintln": true,
"maps.All": true,
"maps.Clone": true,
"maps.Collect": true,
"maps.Equal": true,
"maps.EqualFunc": true,
"maps.Keys": true,
"maps.Values": true,
"slices.All": true,
"slices.AppendSeq": true,
"slices.Backward": true,
"slices.BinarySearch": true,
"slices.BinarySearchFunc": true,
"slices.Chunk": true,
"slices.Clip": true, "slices.Clip": true,
"slices.Clone": true,
"slices.Collect": true,
"slices.Compact": true, "slices.Compact": true,
"slices.CompactFunc": true, "slices.CompactFunc": true,
"slices.Compare": true,
"slices.CompareFunc": true,
"slices.Concat": true,
"slices.Contains": true,
"slices.ContainsFunc": true,
"slices.Delete": true, "slices.Delete": true,
"slices.DeleteFunc": true, "slices.DeleteFunc": true,
"slices.Equal": true,
"slices.EqualFunc": true,
"slices.Grow": true, "slices.Grow": true,
"slices.Index": true,
"slices.IndexFunc": true,
"slices.Insert": true, "slices.Insert": true,
"slices.IsSorted": true,
"slices.IsSortedFunc": true,
"slices.Max": true,
"slices.MaxFunc": true,
"slices.Min": true,
"slices.MinFunc": true,
"slices.Repeat": true,
"slices.Replace": true, "slices.Replace": true,
"slices.Sorted": true,
"slices.SortedFunc": true,
"slices.SortedStableFunc": true,
"slices.Values": true,
"sort.Reverse": true, "sort.Reverse": true,
} }
Analyzer.Flags.Var(&funcs, "funcs", Analyzer.Flags.Var(&funcs, "funcs",
@ -114,14 +154,16 @@ func run(pass *analysis.Pass) (any, error) {
// method (e.g. foo.String()) // method (e.g. foo.String())
if types.Identical(sig, sigNoArgsStringResult) { if types.Identical(sig, sigNoArgsStringResult) {
if stringMethods[fn.Name()] { if stringMethods[fn.Name()] {
pass.Reportf(call.Lparen, "result of (%s).%s call not used", pass.ReportRangef(analysisinternal.Range(call.Pos(), call.Lparen),
"result of (%s).%s call not used",
sig.Recv().Type(), fn.Name()) sig.Recv().Type(), fn.Name())
} }
} }
} else { } else {
// package-level function (e.g. fmt.Errorf) // package-level function (e.g. fmt.Errorf)
if pkgFuncs[[2]string{fn.Pkg().Path(), fn.Name()}] { if pkgFuncs[[2]string{fn.Pkg().Path(), fn.Name()}] {
pass.Reportf(call.Lparen, "result of %s.%s call not used", pass.ReportRangef(analysisinternal.Range(call.Pos(), call.Lparen),
"result of %s.%s call not used",
fn.Pkg().Path(), fn.Name()) fn.Pkg().Path(), fn.Name())
} }
} }

View file

@ -1,18 +1,8 @@
// Copyright 2024 The Go Authors. All rights reserved. // Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build go1.23 package inspector
// Package cursor augments [inspector.Inspector] with [Cursor]
// functionality allowing more flexibility and control during
// inspection.
//
// This package is a temporary private extension of inspector until
// proposal #70859 is accepted, and which point it will be moved into
// the inspector package, and [Root] will become a method of
// Inspector.
package cursor
import ( import (
"fmt" "fmt"
@ -21,17 +11,29 @@ import (
"iter" "iter"
"reflect" "reflect"
"golang.org/x/tools/go/ast/inspector" "golang.org/x/tools/go/ast/edge"
"golang.org/x/tools/internal/astutil/edge"
) )
// A Cursor represents an [ast.Node]. It is immutable. // A Cursor represents an [ast.Node]. It is immutable.
// //
// Two Cursors compare equal if they represent the same node. // Two Cursors compare equal if they represent the same node.
// //
// Call [Root] to obtain a valid cursor. // Call [Inspector.Root] to obtain a valid cursor for the virtual root
// node of the traversal.
//
// Use the following methods to navigate efficiently around the tree:
// - for ancestors, use [Cursor.Parent] and [Cursor.Enclosing];
// - for children, use [Cursor.Child], [Cursor.Children],
// [Cursor.FirstChild], and [Cursor.LastChild];
// - for siblings, use [Cursor.PrevSibling] and [Cursor.NextSibling];
// - for descendants, use [Cursor.FindByPos], [Cursor.FindNode],
// [Cursor.Inspect], and [Cursor.Preorder].
//
// Use the [Cursor.ChildAt] and [Cursor.ParentEdge] methods for
// information about the edges in a tree: which field (and slice
// element) of the parent node holds the child.
type Cursor struct { type Cursor struct {
in *inspector.Inspector in *Inspector
index int32 // index of push node; -1 for virtual root node index int32 // index of push node; -1 for virtual root node
} }
@ -39,29 +41,28 @@ type Cursor struct {
// whose children are the files provided to [New]. // whose children are the files provided to [New].
// //
// Its [Cursor.Node] and [Cursor.Stack] methods return nil. // Its [Cursor.Node] and [Cursor.Stack] methods return nil.
func Root(in *inspector.Inspector) Cursor { func (in *Inspector) Root() Cursor {
return Cursor{in, -1} return Cursor{in, -1}
} }
// At returns the cursor at the specified index in the traversal, // At returns the cursor at the specified index in the traversal,
// which must have been obtained from [Cursor.Index] on a Cursor // which must have been obtained from [Cursor.Index] on a Cursor
// belonging to the same Inspector (see [Cursor.Inspector]). // belonging to the same Inspector (see [Cursor.Inspector]).
func At(in *inspector.Inspector, index int32) Cursor { func (in *Inspector) At(index int32) Cursor {
if index < 0 { if index < 0 {
panic("negative index") panic("negative index")
} }
events := events(in) if int(index) >= len(in.events) {
if int(index) >= len(events) {
panic("index out of range for this inspector") panic("index out of range for this inspector")
} }
if events[index].index < index { if in.events[index].index < index {
panic("invalid index") // (a push, not a pop) panic("invalid index") // (a push, not a pop)
} }
return Cursor{in, index} return Cursor{in, index}
} }
// Inspector returns the cursor's Inspector. // Inspector returns the cursor's Inspector.
func (c Cursor) Inspector() *inspector.Inspector { return c.in } func (c Cursor) Inspector() *Inspector { return c.in }
// Index returns the index of this cursor position within the package. // Index returns the index of this cursor position within the package.
// //
@ -83,7 +84,7 @@ func (c Cursor) Node() ast.Node {
if c.index < 0 { if c.index < 0 {
return nil return nil
} }
return c.events()[c.index].node return c.in.events[c.index].node
} }
// String returns information about the cursor's node, if any. // String returns information about the cursor's node, if any.
@ -100,9 +101,9 @@ func (c Cursor) String() string {
// indices return the [start, end) half-open interval of event indices. // indices return the [start, end) half-open interval of event indices.
func (c Cursor) indices() (int32, int32) { func (c Cursor) indices() (int32, int32) {
if c.index < 0 { if c.index < 0 {
return 0, int32(len(c.events())) // root: all events return 0, int32(len(c.in.events)) // root: all events
} else { } else {
return c.index, c.events()[c.index].index + 1 // just one subtree return c.index, c.in.events[c.index].index + 1 // just one subtree
} }
} }
@ -123,7 +124,7 @@ func (c Cursor) Preorder(types ...ast.Node) iter.Seq[Cursor] {
mask := maskOf(types) mask := maskOf(types)
return func(yield func(Cursor) bool) { return func(yield func(Cursor) bool) {
events := c.events() events := c.in.events
for i, limit := c.indices(); i < limit; { for i, limit := c.indices(); i < limit; {
ev := events[i] ev := events[i]
@ -158,7 +159,7 @@ func (c Cursor) Preorder(types ...ast.Node) iter.Seq[Cursor] {
// matches an element of the types slice. // matches an element of the types slice.
func (c Cursor) Inspect(types []ast.Node, f func(c Cursor) (descend bool)) { func (c Cursor) Inspect(types []ast.Node, f func(c Cursor) (descend bool)) {
mask := maskOf(types) mask := maskOf(types)
events := c.events() events := c.in.events
for i, limit := c.indices(); i < limit; { for i, limit := c.indices(); i < limit; {
ev := events[i] ev := events[i]
if ev.index > i { if ev.index > i {
@ -193,7 +194,7 @@ func (c Cursor) Enclosing(types ...ast.Node) iter.Seq[Cursor] {
mask := maskOf(types) mask := maskOf(types)
return func(yield func(Cursor) bool) { return func(yield func(Cursor) bool) {
events := c.events() events := c.in.events
for i := c.index; i >= 0; i = events[i].parent { for i := c.index; i >= 0; i = events[i].parent {
if events[i].typ&mask != 0 && !yield(Cursor{c.in, i}) { if events[i].typ&mask != 0 && !yield(Cursor{c.in, i}) {
break break
@ -210,7 +211,7 @@ func (c Cursor) Parent() Cursor {
panic("Cursor.Parent called on Root node") panic("Cursor.Parent called on Root node")
} }
return Cursor{c.in, c.events()[c.index].parent} return Cursor{c.in, c.in.events[c.index].parent}
} }
// ParentEdge returns the identity of the field in the parent node // ParentEdge returns the identity of the field in the parent node
@ -227,7 +228,7 @@ func (c Cursor) ParentEdge() (edge.Kind, int) {
if c.index < 0 { if c.index < 0 {
panic("Cursor.ParentEdge called on Root node") panic("Cursor.ParentEdge called on Root node")
} }
events := c.events() events := c.in.events
pop := events[c.index].index pop := events[c.index].index
return unpackEdgeKindAndIndex(events[pop].parent) return unpackEdgeKindAndIndex(events[pop].parent)
} }
@ -244,7 +245,7 @@ func (c Cursor) ChildAt(k edge.Kind, idx int) Cursor {
target := packEdgeKindAndIndex(k, idx) target := packEdgeKindAndIndex(k, idx)
// Unfortunately there's no shortcut to looping. // Unfortunately there's no shortcut to looping.
events := c.events() events := c.in.events
i := c.index + 1 i := c.index + 1
for { for {
pop := events[i].index pop := events[i].index
@ -277,7 +278,7 @@ func (c Cursor) Child(n ast.Node) Cursor {
} else { } else {
// optimized implementation // optimized implementation
events := c.events() events := c.in.events
for i := c.index + 1; events[i].index > i; i = events[i].index + 1 { for i := c.index + 1; events[i].index > i; i = events[i].index + 1 {
if events[i].node == n { if events[i].node == n {
return Cursor{c.in, i} return Cursor{c.in, i}
@ -300,7 +301,7 @@ func (c Cursor) NextSibling() (Cursor, bool) {
panic("Cursor.NextSibling called on Root node") panic("Cursor.NextSibling called on Root node")
} }
events := c.events() events := c.in.events
i := events[c.index].index + 1 // after corresponding pop i := events[c.index].index + 1 // after corresponding pop
if i < int32(len(events)) { if i < int32(len(events)) {
if events[i].index > i { // push? if events[i].index > i { // push?
@ -323,7 +324,7 @@ func (c Cursor) PrevSibling() (Cursor, bool) {
panic("Cursor.PrevSibling called on Root node") panic("Cursor.PrevSibling called on Root node")
} }
events := c.events() events := c.in.events
i := c.index - 1 i := c.index - 1
if i >= 0 { if i >= 0 {
if j := events[i].index; j < i { // pop? if j := events[i].index; j < i { // pop?
@ -336,7 +337,7 @@ func (c Cursor) PrevSibling() (Cursor, bool) {
// FirstChild returns the first direct child of the current node, // FirstChild returns the first direct child of the current node,
// or zero if it has no children. // or zero if it has no children.
func (c Cursor) FirstChild() (Cursor, bool) { func (c Cursor) FirstChild() (Cursor, bool) {
events := c.events() events := c.in.events
i := c.index + 1 // i=0 if c is root i := c.index + 1 // i=0 if c is root
if i < int32(len(events)) && events[i].index > i { // push? if i < int32(len(events)) && events[i].index > i { // push?
return Cursor{c.in, i}, true return Cursor{c.in, i}, true
@ -347,7 +348,7 @@ func (c Cursor) FirstChild() (Cursor, bool) {
// LastChild returns the last direct child of the current node, // LastChild returns the last direct child of the current node,
// or zero if it has no children. // or zero if it has no children.
func (c Cursor) LastChild() (Cursor, bool) { func (c Cursor) LastChild() (Cursor, bool) {
events := c.events() events := c.in.events
if c.index < 0 { // root? if c.index < 0 { // root?
if len(events) > 0 { if len(events) > 0 {
// return push of final event (a pop) // return push of final event (a pop)
@ -406,7 +407,7 @@ func (c Cursor) Contains(c2 Cursor) bool {
if c.in != c2.in { if c.in != c2.in {
panic("different inspectors") panic("different inspectors")
} }
events := c.events() events := c.in.events
return c.index <= c2.index && events[c2.index].index <= events[c.index].index return c.index <= c2.index && events[c2.index].index <= events[c.index].index
} }
@ -430,7 +431,7 @@ func (c Cursor) FindNode(n ast.Node) (Cursor, bool) {
// like FindByPos? // like FindByPos?
mask := maskOf([]ast.Node{n}) mask := maskOf([]ast.Node{n})
events := c.events() events := c.in.events
for i, limit := c.indices(); i < limit; i++ { for i, limit := c.indices(); i < limit; i++ {
ev := events[i] ev := events[i]
@ -461,7 +462,7 @@ func (c Cursor) FindByPos(start, end token.Pos) (Cursor, bool) {
if end < start { if end < start {
panic("end < start") panic("end < start")
} }
events := c.events() events := c.in.events
// This algorithm could be implemented using c.Inspect, // This algorithm could be implemented using c.Inspect,
// but it is about 2.5x slower. // but it is about 2.5x slower.

View file

@ -13,10 +13,19 @@
// This representation is sometimes called a "balanced parenthesis tree." // This representation is sometimes called a "balanced parenthesis tree."
// //
// Experiments suggest the inspector's traversals are about 2.5x faster // Experiments suggest the inspector's traversals are about 2.5x faster
// than ast.Inspect, but it may take around 5 traversals for this // than [ast.Inspect], but it may take around 5 traversals for this
// benefit to amortize the inspector's construction cost. // benefit to amortize the inspector's construction cost.
// If efficiency is the primary concern, do not use Inspector for // If efficiency is the primary concern, do not use Inspector for
// one-off traversals. // one-off traversals.
//
// The [Cursor] type provides a more flexible API for efficient
// navigation of syntax trees in all four "cardinal directions". For
// example, traversals may be nested, so you can find each node of
// type A and then search within it for nodes of type B. Or you can
// traverse from a node to its immediate neighbors: its parent, its
// previous and next sibling, or its first and last child. We
// recommend using methods of Cursor in preference to Inspector where
// possible.
package inspector package inspector
// There are four orthogonal features in a traversal: // There are four orthogonal features in a traversal:
@ -37,9 +46,8 @@ package inspector
import ( import (
"go/ast" "go/ast"
_ "unsafe"
"golang.org/x/tools/internal/astutil/edge" "golang.org/x/tools/go/ast/edge"
) )
// An Inspector provides methods for inspecting // An Inspector provides methods for inspecting
@ -48,18 +56,12 @@ type Inspector struct {
events []event events []event
} }
//go:linkname events golang.org/x/tools/go/ast/inspector.events
func events(in *Inspector) []event { return in.events }
//go:linkname packEdgeKindAndIndex golang.org/x/tools/go/ast/inspector.packEdgeKindAndIndex
func packEdgeKindAndIndex(ek edge.Kind, index int) int32 { func packEdgeKindAndIndex(ek edge.Kind, index int) int32 {
return int32(uint32(index+1)<<7 | uint32(ek)) return int32(uint32(index+1)<<7 | uint32(ek))
} }
// unpackEdgeKindAndIndex unpacks the edge kind and edge index (within // unpackEdgeKindAndIndex unpacks the edge kind and edge index (within
// an []ast.Node slice) from the parent field of a pop event. // an []ast.Node slice) from the parent field of a pop event.
//
//go:linkname unpackEdgeKindAndIndex golang.org/x/tools/go/ast/inspector.unpackEdgeKindAndIndex
func unpackEdgeKindAndIndex(x int32) (edge.Kind, int) { func unpackEdgeKindAndIndex(x int32) (edge.Kind, int) {
// The "parent" field of a pop node holds the // The "parent" field of a pop node holds the
// edge Kind in the lower 7 bits and the index+1 // edge Kind in the lower 7 bits and the index+1
@ -88,10 +90,15 @@ type event struct {
// depth-first order. It calls f(n) for each node n before it visits // depth-first order. It calls f(n) for each node n before it visits
// n's children. // n's children.
// //
// The complete traversal sequence is determined by ast.Inspect. // The complete traversal sequence is determined by [ast.Inspect].
// The types argument, if non-empty, enables type-based filtering of // 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 is called only for nodes whose type
// matches an element of the types slice. // matches an element of the types slice.
//
// The [Cursor.Preorder] method provides a richer alternative interface.
// Example:
//
// for c := range in.Root().Preorder(types) { ... }
func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node)) { func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node)) {
// Because it avoids postorder calls to f, and the pruning // Because it avoids postorder calls to f, and the pruning
// check, Preorder is almost twice as fast as Nodes. The two // check, Preorder is almost twice as fast as Nodes. The two
@ -131,10 +138,18 @@ func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node)) {
// of the non-nil children of the node, followed by a call of // of the non-nil children of the node, followed by a call of
// f(n, false). // f(n, false).
// //
// The complete traversal sequence is determined by ast.Inspect. // The complete traversal sequence is determined by [ast.Inspect].
// The types argument, if non-empty, enables type-based filtering of // The types argument, if non-empty, enables type-based filtering of
// events. The function f if 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. // matches an element of the types slice.
//
// The [Cursor.Inspect] method provides a richer alternative interface.
// Example:
//
// in.Root().Inspect(types, func(c Cursor) bool {
// ...
// return true
// }
func (in *Inspector) Nodes(types []ast.Node, f func(n ast.Node, push bool) (proceed bool)) { func (in *Inspector) Nodes(types []ast.Node, f func(n ast.Node, push bool) (proceed bool)) {
mask := maskOf(types) mask := maskOf(types)
for i := int32(0); i < int32(len(in.events)); { for i := int32(0); i < int32(len(in.events)); {
@ -168,6 +183,15 @@ func (in *Inspector) Nodes(types []ast.Node, f func(n ast.Node, push bool) (proc
// supplies each call to f an additional argument, the current // supplies each call to f an additional argument, the current
// traversal stack. The stack's first element is the outermost node, // traversal stack. The stack's first element is the outermost node,
// an *ast.File; its last is the innermost, n. // an *ast.File; its last is the innermost, n.
//
// The [Cursor.Inspect] method provides a richer alternative interface.
// Example:
//
// in.Root().Inspect(types, func(c Cursor) bool {
// stack := slices.Collect(c.Enclosing())
// ...
// return true
// })
func (in *Inspector) WithStack(types []ast.Node, f func(n ast.Node, push bool, stack []ast.Node) (proceed bool)) { func (in *Inspector) WithStack(types []ast.Node, f func(n ast.Node, push bool, stack []ast.Node) (proceed bool)) {
mask := maskOf(types) mask := maskOf(types)
var stack []ast.Node var stack []ast.Node
@ -233,7 +257,7 @@ type visitor struct {
type item struct { type item struct {
index int32 // index of current node's push event index int32 // index of current node's push event
parentIndex int32 // index of parent node's push event parentIndex int32 // index of parent node's push event
typAccum uint64 // accumulated type bits of current node's descendents typAccum uint64 // accumulated type bits of current node's descendants
edgeKindAndIndex int32 // edge.Kind and index, bit packed edgeKindAndIndex int32 // edge.Kind and index, bit packed
} }

View file

@ -13,7 +13,7 @@ import (
"fmt" "fmt"
"go/ast" "go/ast"
"golang.org/x/tools/internal/astutil/edge" "golang.org/x/tools/go/ast/edge"
) )
func walkList[N ast.Node](v *visitor, ek edge.Kind, list []N) { func walkList[N ast.Node](v *visitor, ek edge.Kind, list []N) {

View file

@ -603,7 +603,7 @@ func Object(pkg *types.Package, p Path) (types.Object, error) {
type hasTypeParams interface { type hasTypeParams interface {
TypeParams() *types.TypeParamList TypeParams() *types.TypeParamList
} }
// abstraction of *types.{Named,TypeParam} // abstraction of *types.{Alias,Named,TypeParam}
type hasObj interface { type hasObj interface {
Obj() *types.TypeName Obj() *types.TypeName
} }

View file

@ -22,7 +22,6 @@ import (
"golang.org/x/tools/go/analysis" "golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/ast/inspector" "golang.org/x/tools/go/ast/inspector"
"golang.org/x/tools/internal/astutil/cursor"
"golang.org/x/tools/internal/typesinternal" "golang.org/x/tools/internal/typesinternal"
) )
@ -526,7 +525,7 @@ func CanImport(from, to string) bool {
func DeleteStmt(fset *token.FileSet, astFile *ast.File, stmt ast.Stmt, report func(string, ...any)) []analysis.TextEdit { func DeleteStmt(fset *token.FileSet, astFile *ast.File, stmt ast.Stmt, report func(string, ...any)) []analysis.TextEdit {
// TODO: pass in the cursor to a ast.Stmt. callers should provide the Cursor // TODO: pass in the cursor to a ast.Stmt. callers should provide the Cursor
insp := inspector.New([]*ast.File{astFile}) insp := inspector.New([]*ast.File{astFile})
root := cursor.Root(insp) root := insp.Root()
cstmt, ok := root.FindNode(stmt) cstmt, ok := root.FindNode(stmt)
if !ok { if !ok {
report("%s not found in file", stmt.Pos()) report("%s not found in file", stmt.Pos())
@ -620,8 +619,8 @@ Outer:
// otherwise remove the line // otherwise remove the line
edit := analysis.TextEdit{Pos: stmt.Pos(), End: stmt.End()} edit := analysis.TextEdit{Pos: stmt.Pos(), End: stmt.End()}
if from.IsValid() || to.IsValid() { if from.IsValid() || to.IsValid() {
// remove just the statment. // remove just the statement.
// we can't tell if there is a ; or whitespace right after the statment // we can't tell if there is a ; or whitespace right after the statement
// ideally we'd like to remove the former and leave the latter // ideally we'd like to remove the former and leave the latter
// (if gofmt has run, there likely won't be a ;) // (if gofmt has run, there likely won't be a ;)
// In type switches we know there's a semicolon somewhere after the statement, // In type switches we know there's a semicolon somewhere after the statement,
@ -671,3 +670,14 @@ func IsStdPackage(path string) bool {
} }
return !strings.Contains(path[:slash], ".") && path != "testdata" return !strings.Contains(path[:slash], ".") && path != "testdata"
} }
// Range returns an [analysis.Range] for the specified start and end positions.
func Range(pos, end token.Pos) analysis.Range {
return tokenRange{pos, end}
}
// tokenRange is an implementation of the [analysis.Range] interface.
type tokenRange struct{ StartPos, EndPos token.Pos }
func (r tokenRange) Pos() token.Pos { return r.StartPos }
func (r tokenRange) End() token.Pos { return r.EndPos }

View file

@ -1,40 +0,0 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build go1.23
package cursor
import (
"go/ast"
_ "unsafe" // for go:linkname
"golang.org/x/tools/go/ast/inspector"
"golang.org/x/tools/internal/astutil/edge"
)
// This file defines backdoor access to inspector.
// Copied from inspector.event; must remain in sync.
// (Note that the linkname effects a type coercion too.)
type event struct {
node ast.Node
typ uint64 // typeOf(node) on push event, or union of typ strictly between push and pop events on pop events
index int32 // index of corresponding push or pop event (relative to this event's index, +ve=push, -ve=pop)
parent int32 // index of parent's push node (push nodes only); or edge and index, bit packed (pop nodes only)
}
//go:linkname maskOf golang.org/x/tools/go/ast/inspector.maskOf
func maskOf(nodes []ast.Node) uint64
//go:linkname events golang.org/x/tools/go/ast/inspector.events
func events(in *inspector.Inspector) []event
//go:linkname packEdgeKindAndIndex golang.org/x/tools/go/ast/inspector.packEdgeKindAndIndex
func packEdgeKindAndIndex(edge.Kind, int) int32
//go:linkname unpackEdgeKindAndIndex golang.org/x/tools/go/ast/inspector.unpackEdgeKindAndIndex
func unpackEdgeKindAndIndex(int32) (edge.Kind, int)
func (c Cursor) events() []event { return events(c.in) }

View file

@ -71,6 +71,8 @@ func PosInStringLiteral(lit *ast.BasicLit, offset int) (token.Pos, error) {
// In practice, the second call is nearly always used only to pop the // In practice, the second call is nearly always used only to pop the
// stack, and it is surprisingly tricky to do this correctly; see // stack, and it is surprisingly tricky to do this correctly; see
// https://go.dev/issue/73319. // https://go.dev/issue/73319.
//
// TODO(adonovan): replace with [ast.PreorderStack] when go1.25 is assured.
func PreorderStack(root ast.Node, stack []ast.Node, f func(n ast.Node, stack []ast.Node) bool) { func PreorderStack(root ast.Node, stack []ast.Node, f func(n ast.Node, stack []ast.Node) bool) {
before := len(stack) before := len(stack)
ast.Inspect(root, func(n ast.Node) bool { ast.Inspect(root, func(n ast.Node) bool {

View file

@ -52,7 +52,7 @@ func importMap(imports []*types.Package) map[string]*types.Package {
// nop // nop
case typesinternal.NamedOrAlias: // *types.{Named,Alias} case typesinternal.NamedOrAlias: // *types.{Named,Alias}
// Add the type arguments if this is an instance. // Add the type arguments if this is an instance.
if targs := typesinternal.TypeArgs(T); targs.Len() > 0 { if targs := T.TypeArgs(); targs.Len() > 0 {
for i := 0; i < targs.Len(); i++ { for i := 0; i < targs.Len(); i++ {
addType(targs.At(i)) addType(targs.At(i))
} }
@ -69,7 +69,7 @@ func importMap(imports []*types.Package) map[string]*types.Package {
// common aspects // common aspects
addObj(T.Obj()) addObj(T.Obj())
if tparams := typesinternal.TypeParams(T); tparams.Len() > 0 { if tparams := T.TypeParams(); tparams.Len() > 0 {
for i := 0; i < tparams.Len(); i++ { for i := 0; i < tparams.Len(); i++ {
addType(tparams.At(i)) addType(tparams.At(i))
} }

View file

@ -12,61 +12,61 @@ type pkginfo struct {
} }
var deps = [...]pkginfo{ var deps = [...]pkginfo{
{"archive/tar", "\x03j\x03E6\x01\v\x01\"\x01\x01\x02\x05\n\x02\x01\x02\x02\v"}, {"archive/tar", "\x03j\x03E5\x01\v\x01#\x01\x01\x02\x05\n\x02\x01\x02\x02\v"},
{"archive/zip", "\x02\x04`\a\x16\x0206\x01*\x05\x01\x11\x03\x02\r\x04"}, {"archive/zip", "\x02\x04`\a\x16\x0205\x01+\x05\x01\x11\x03\x02\r\x04"},
{"bufio", "\x03j~E\x13"}, {"bufio", "\x03j}F\x13"},
{"bytes", "m+S\x03\fG\x02\x02"}, {"bytes", "m+R\x03\fH\x02\x02"},
{"cmp", ""}, {"cmp", ""},
{"compress/bzip2", "\x02\x02\xe7\x01B"}, {"compress/bzip2", "\x02\x02\xe6\x01C"},
{"compress/flate", "\x02k\x03{\r\x024\x01\x03"}, {"compress/flate", "\x02k\x03z\r\x025\x01\x03"},
{"compress/gzip", "\x02\x04`\a\x03\x15fT"}, {"compress/gzip", "\x02\x04`\a\x03\x15eU"},
{"compress/lzw", "\x02k\x03{"}, {"compress/lzw", "\x02k\x03z"},
{"compress/zlib", "\x02\x04`\a\x03\x13\x01g"}, {"compress/zlib", "\x02\x04`\a\x03\x13\x01f"},
{"container/heap", "\xae\x02"}, {"container/heap", "\xae\x02"},
{"container/list", ""}, {"container/list", ""},
{"container/ring", ""}, {"container/ring", ""},
{"context", "m\\i\x01\f"}, {"context", "m\\i\x01\f"},
{"crypto", "\x83\x01hD"}, {"crypto", "\x83\x01gE"},
{"crypto/aes", "\x10\n\a\x8e\x02"}, {"crypto/aes", "\x10\n\a\x8e\x02"},
{"crypto/cipher", "\x03\x1e\x01\x01\x1d\x11\x1c,R"}, {"crypto/cipher", "\x03\x1e\x01\x01\x1d\x11\x1c,Q"},
{"crypto/des", "\x10\x13\x1d-,\x96\x01\x03"}, {"crypto/des", "\x10\x13\x1d-,\x96\x01\x03"},
{"crypto/dsa", "@\x04)~\x0e"}, {"crypto/dsa", "@\x04)}\x0e"},
{"crypto/ecdh", "\x03\v\f\x0e\x04\x14\x04\r\x1c~"}, {"crypto/ecdh", "\x03\v\f\x0e\x04\x14\x04\r\x1c}"},
{"crypto/ecdsa", "\x0e\x05\x03\x04\x01\x0e\x16\x01\x04\f\x01\x1c~\x0e\x04K\x01"}, {"crypto/ecdsa", "\x0e\x05\x03\x04\x01\x0e\x16\x01\x04\f\x01\x1c}\x0e\x04L\x01"},
{"crypto/ed25519", "\x0e\x1c\x16\n\a\x1c~D"}, {"crypto/ed25519", "\x0e\x1c\x16\n\a\x1c}E"},
{"crypto/elliptic", "0=~\x0e9"}, {"crypto/elliptic", "0=}\x0e:"},
{"crypto/fips140", " \x05\x90\x01"}, {"crypto/fips140", " \x05\x90\x01"},
{"crypto/hkdf", "-\x12\x01-\x16"}, {"crypto/hkdf", "-\x12\x01-\x16"},
{"crypto/hmac", "\x1a\x14\x11\x01\x112"}, {"crypto/hmac", "\x1a\x14\x11\x01\x112"},
{"crypto/internal/boring", "\x0e\x02\rf"}, {"crypto/internal/boring", "\x0e\x02\rf"},
{"crypto/internal/boring/bbig", "\x1a\xdf\x01L"}, {"crypto/internal/boring/bbig", "\x1a\xde\x01M"},
{"crypto/internal/boring/bcache", "\xb3\x02\x12"}, {"crypto/internal/boring/bcache", "\xb3\x02\x12"},
{"crypto/internal/boring/sig", ""}, {"crypto/internal/boring/sig", ""},
{"crypto/internal/cryptotest", "\x03\r\n)\x0e\x19\x06\x13\x12#\a\t\x11\x12\x11\x1a\r\r\x05\n"}, {"crypto/internal/cryptotest", "\x03\r\n)\x0e\x19\x06\x13\x12#\a\t\x11\x11\x11\x1b\x01\f\r\x05\n"},
{"crypto/internal/entropy", "E"}, {"crypto/internal/entropy", "E"},
{"crypto/internal/fips140", ">/~8\r\x15"}, {"crypto/internal/fips140", ">/}9\r\x15"},
{"crypto/internal/fips140/aes", "\x03\x1d\x03\x02\x13\x04\x01\x01\x05*\x8d\x015"}, {"crypto/internal/fips140/aes", "\x03\x1d\x03\x02\x13\x04\x01\x01\x05*\x8c\x016"},
{"crypto/internal/fips140/aes/gcm", " \x01\x02\x02\x02\x11\x04\x01\x06*\x8b\x01"}, {"crypto/internal/fips140/aes/gcm", " \x01\x02\x02\x02\x11\x04\x01\x06*\x8a\x01"},
{"crypto/internal/fips140/alias", "\xc5\x02"}, {"crypto/internal/fips140/alias", "\xc5\x02"},
{"crypto/internal/fips140/bigmod", "%\x17\x01\x06*\x8d\x01"}, {"crypto/internal/fips140/bigmod", "%\x17\x01\x06*\x8c\x01"},
{"crypto/internal/fips140/check", " \x0e\x06\b\x02\xad\x01Z"}, {"crypto/internal/fips140/check", " \x0e\x06\b\x02\xac\x01["},
{"crypto/internal/fips140/check/checktest", "%\xfe\x01\""}, {"crypto/internal/fips140/check/checktest", "%\xfe\x01\""},
{"crypto/internal/fips140/drbg", "\x03\x1c\x01\x01\x04\x13\x04\b\x01(~\x0f8"}, {"crypto/internal/fips140/drbg", "\x03\x1c\x01\x01\x04\x13\x04\b\x01(}\x0f9"},
{"crypto/internal/fips140/ecdh", "\x03\x1d\x05\x02\t\f1~\x0f8"}, {"crypto/internal/fips140/ecdh", "\x03\x1d\x05\x02\t\f1}\x0f9"},
{"crypto/internal/fips140/ecdsa", "\x03\x1d\x04\x01\x02\a\x02\x067~G"}, {"crypto/internal/fips140/ecdsa", "\x03\x1d\x04\x01\x02\a\x02\x067}H"},
{"crypto/internal/fips140/ed25519", "\x03\x1d\x05\x02\x04\v7\xc2\x01\x03"}, {"crypto/internal/fips140/ed25519", "\x03\x1d\x05\x02\x04\v7\xc2\x01\x03"},
{"crypto/internal/fips140/edwards25519", "%\a\f\x041\x8d\x018"}, {"crypto/internal/fips140/edwards25519", "%\a\f\x041\x8c\x019"},
{"crypto/internal/fips140/edwards25519/field", "%\x13\x041\x8d\x01"}, {"crypto/internal/fips140/edwards25519/field", "%\x13\x041\x8c\x01"},
{"crypto/internal/fips140/hkdf", "\x03\x1d\x05\t\x069"}, {"crypto/internal/fips140/hkdf", "\x03\x1d\x05\t\x069"},
{"crypto/internal/fips140/hmac", "\x03\x1d\x14\x01\x017"}, {"crypto/internal/fips140/hmac", "\x03\x1d\x14\x01\x017"},
{"crypto/internal/fips140/mlkem", "\x03\x1d\x05\x02\x0e\x03\x041"}, {"crypto/internal/fips140/mlkem", "\x03\x1d\x05\x02\x0e\x03\x041"},
{"crypto/internal/fips140/nistec", "%\f\a\x041\x8d\x01)\x0f\x13"}, {"crypto/internal/fips140/nistec", "%\f\a\x041\x8c\x01*\x0f\x13"},
{"crypto/internal/fips140/nistec/fiat", "%\x135\x8d\x01"}, {"crypto/internal/fips140/nistec/fiat", "%\x135\x8c\x01"},
{"crypto/internal/fips140/pbkdf2", "\x03\x1d\x05\t\x069"}, {"crypto/internal/fips140/pbkdf2", "\x03\x1d\x05\t\x069"},
{"crypto/internal/fips140/rsa", "\x03\x1d\x04\x01\x02\r\x01\x01\x025~G"}, {"crypto/internal/fips140/rsa", "\x03\x1d\x04\x01\x02\r\x01\x01\x025}H"},
{"crypto/internal/fips140/sha256", "\x03\x1d\x1c\x01\x06*\x8d\x01"}, {"crypto/internal/fips140/sha256", "\x03\x1d\x1c\x01\x06*\x8c\x01"},
{"crypto/internal/fips140/sha3", "\x03\x1d\x18\x04\x010\x8d\x01K"}, {"crypto/internal/fips140/sha3", "\x03\x1d\x18\x04\x010\x8c\x01L"},
{"crypto/internal/fips140/sha512", "\x03\x1d\x1c\x01\x06*\x8d\x01"}, {"crypto/internal/fips140/sha512", "\x03\x1d\x1c\x01\x06*\x8c\x01"},
{"crypto/internal/fips140/ssh", " \x05"}, {"crypto/internal/fips140/ssh", " \x05"},
{"crypto/internal/fips140/subtle", "#"}, {"crypto/internal/fips140/subtle", "#"},
{"crypto/internal/fips140/tls12", "\x03\x1d\x05\t\x06\x027"}, {"crypto/internal/fips140/tls12", "\x03\x1d\x05\t\x06\x027"},
@ -76,90 +76,90 @@ var deps = [...]pkginfo{
{"crypto/internal/fips140deps/cpu", "\xad\x01\a"}, {"crypto/internal/fips140deps/cpu", "\xad\x01\a"},
{"crypto/internal/fips140deps/godebug", "\xb5\x01"}, {"crypto/internal/fips140deps/godebug", "\xb5\x01"},
{"crypto/internal/fips140hash", "5\x1a4\xc2\x01"}, {"crypto/internal/fips140hash", "5\x1a4\xc2\x01"},
{"crypto/internal/fips140only", "'\r\x01\x01M26"}, {"crypto/internal/fips140only", "'\r\x01\x01M25"},
{"crypto/internal/fips140test", ""}, {"crypto/internal/fips140test", ""},
{"crypto/internal/hpke", "\x0e\x01\x01\x03\x1a\x1d#,aM"}, {"crypto/internal/hpke", "\x0e\x01\x01\x03\x1a\x1d#,`N"},
{"crypto/internal/impl", "\xb0\x02"}, {"crypto/internal/impl", "\xb0\x02"},
{"crypto/internal/randutil", "\xeb\x01\x12"}, {"crypto/internal/randutil", "\xea\x01\x12"},
{"crypto/internal/sysrand", "mi\"\x1e\r\x0f\x01\x01\v\x06"}, {"crypto/internal/sysrand", "mi!\x1f\r\x0f\x01\x01\v\x06"},
{"crypto/internal/sysrand/internal/seccomp", "m"}, {"crypto/internal/sysrand/internal/seccomp", "m"},
{"crypto/md5", "\x0e2-\x16\x16a"}, {"crypto/md5", "\x0e2-\x16\x16`"},
{"crypto/mlkem", "/"}, {"crypto/mlkem", "/"},
{"crypto/pbkdf2", "2\r\x01-\x16"}, {"crypto/pbkdf2", "2\r\x01-\x16"},
{"crypto/rand", "\x1a\x06\a\x19\x04\x01(~\x0eL"}, {"crypto/rand", "\x1a\x06\a\x19\x04\x01(}\x0eM"},
{"crypto/rc4", "#\x1d-\xc2\x01"}, {"crypto/rc4", "#\x1d-\xc2\x01"},
{"crypto/rsa", "\x0e\f\x01\t\x0f\f\x01\x04\x06\a\x1c\x03\x1326\r\x01"}, {"crypto/rsa", "\x0e\f\x01\t\x0f\f\x01\x04\x06\a\x1c\x03\x1325\r\x01"},
{"crypto/sha1", "\x0e\f&-\x16\x16\x14M"}, {"crypto/sha1", "\x0e\f&-\x16\x16\x14L"},
{"crypto/sha256", "\x0e\f\x1aO"}, {"crypto/sha256", "\x0e\f\x1aO"},
{"crypto/sha3", "\x0e'N\xc2\x01"}, {"crypto/sha3", "\x0e'N\xc2\x01"},
{"crypto/sha512", "\x0e\f\x1cM"}, {"crypto/sha512", "\x0e\f\x1cM"},
{"crypto/subtle", "8\x96\x01U"}, {"crypto/subtle", "8\x96\x01U"},
{"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x03\x01\a\x01\v\x02\n\x01\b\x05\x03\x01\x01\x01\x01\x02\x01\x02\x01\x17\x02\x03\x13\x16\x14\b6\x16\x15\r\n\x01\x01\x01\x02\x01\f\x06\x02\x01"}, {"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x03\x01\a\x01\v\x02\n\x01\b\x05\x03\x01\x01\x01\x01\x02\x01\x02\x01\x17\x02\x03\x13\x16\x14\b5\x16\x16\r\n\x01\x01\x01\x02\x01\f\x06\x02\x01"},
{"crypto/tls/internal/fips140tls", " \x93\x02"}, {"crypto/tls/internal/fips140tls", " \x93\x02"},
{"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x011\x03\x02\x01\x01\x02\x05\x0e\x06\x02\x02\x03E\x033\x01\x02\t\x01\x01\x01\a\x0f\x05\x01\x06\x02\x05\f\x01\x02\r\x02\x01\x01\x02\x03\x01"}, {"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x011\x03\x02\x01\x01\x02\x05\x0e\x06\x02\x02\x03E\x032\x01\x02\t\x01\x01\x01\a\x10\x05\x01\x06\x02\x05\f\x01\x02\r\x02\x01\x01\x02\x03\x01"},
{"crypto/x509/pkix", "c\x06\a\x89\x01F"}, {"crypto/x509/pkix", "c\x06\a\x88\x01G"},
{"database/sql", "\x03\nJ\x16\x03{\f\x06!\x05\n\x02\x03\x01\f\x02\x02\x02"}, {"database/sql", "\x03\nJ\x16\x03z\f\x06\"\x05\n\x02\x03\x01\f\x02\x02\x02"},
{"database/sql/driver", "\r`\x03\xae\x01\x11\x10"}, {"database/sql/driver", "\r`\x03\xae\x01\x11\x10"},
{"debug/buildinfo", "\x03W\x02\x01\x01\b\a\x03`\x19\x02\x01*\x0f "}, {"debug/buildinfo", "\x03W\x02\x01\x01\b\a\x03`\x18\x02\x01+\x0f "},
{"debug/dwarf", "\x03c\a\x03{0\x13\x01\x01"}, {"debug/dwarf", "\x03c\a\x03z1\x13\x01\x01"},
{"debug/elf", "\x03\x06P\r\a\x03`\x1a\x01+\x19\x01\x15"}, {"debug/elf", "\x03\x06P\r\a\x03`\x19\x01,\x19\x01\x15"},
{"debug/gosym", "\x03c\n\xbe\x01\x01\x01\x02"}, {"debug/gosym", "\x03c\n\xbe\x01\x01\x01\x02"},
{"debug/macho", "\x03\x06P\r\n`\x1b+\x19\x01"}, {"debug/macho", "\x03\x06P\r\n`\x1a,\x19\x01"},
{"debug/pe", "\x03\x06P\r\a\x03`\x1b+\x19\x01\x15"}, {"debug/pe", "\x03\x06P\r\a\x03`\x1a,\x19\x01\x15"},
{"debug/plan9obj", "f\a\x03`\x1b+"}, {"debug/plan9obj", "f\a\x03`\x1a,"},
{"embed", "m+:\x19\x01S"}, {"embed", "m+:\x18\x01T"},
{"embed/internal/embedtest", ""}, {"embed/internal/embedtest", ""},
{"encoding", ""}, {"encoding", ""},
{"encoding/ascii85", "\xeb\x01D"}, {"encoding/ascii85", "\xea\x01E"},
{"encoding/asn1", "\x03j\x03\x88\x01\x01%\x0f\x02\x01\x0f\x03\x01"}, {"encoding/asn1", "\x03j\x03\x87\x01\x01&\x0f\x02\x01\x0f\x03\x01"},
{"encoding/base32", "\xeb\x01B\x02"}, {"encoding/base32", "\xea\x01C\x02"},
{"encoding/base64", "f\x85\x01B\x02"}, {"encoding/base64", "\x99\x01QC\x02"},
{"encoding/binary", "m~\r&\x0f\x05"}, {"encoding/binary", "m}\r'\x0f\x05"},
{"encoding/csv", "\x02\x01j\x03{E\x11\x02"}, {"encoding/csv", "\x02\x01j\x03zF\x11\x02"},
{"encoding/gob", "\x02_\x05\a\x03`\x1b\f\x01\x02\x1c\b\x14\x01\x0e\x02"}, {"encoding/gob", "\x02_\x05\a\x03`\x1a\f\x01\x02\x1d\b\x14\x01\x0e\x02"},
{"encoding/hex", "m\x03{B\x03"}, {"encoding/hex", "m\x03zC\x03"},
{"encoding/json", "\x03\x01]\x04\b\x03{\r&\x0f\x02\x01\x02\x0f\x01\x01\x02"}, {"encoding/json", "\x03\x01]\x04\b\x03z\r'\x0f\x02\x01\x02\x0f\x01\x01\x02"},
{"encoding/pem", "\x03b\b~B\x03"}, {"encoding/pem", "\x03b\b}C\x03"},
{"encoding/xml", "\x02\x01^\f\x03{3\x05\f\x01\x02\x0f\x02"}, {"encoding/xml", "\x02\x01^\f\x03z4\x05\f\x01\x02\x0f\x02"},
{"errors", "\xc9\x01|"}, {"errors", "\xc9\x01|"},
{"expvar", "jK:\t\n\x14\r\n\x02\x03\x01\x10"}, {"expvar", "jK9\t\n\x15\r\n\x02\x03\x01\x10"},
{"flag", "a\f\x03{+\b\x05\n\x02\x01\x0f"}, {"flag", "a\f\x03z,\b\x05\n\x02\x01\x0f"},
{"fmt", "mE9\r\x1e\b\x0f\x02\x03\x11"}, {"fmt", "mE8\r\x1f\b\x0f\x02\x03\x11"},
{"go/ast", "\x03\x01l\x0f\x01k\x03(\b\x0f\x02\x01"}, {"go/ast", "\x03\x01l\x0f\x01j\x03)\b\x0f\x02\x01"},
{"go/ast/internal/tests", ""}, {"go/ast/internal/tests", ""},
{"go/build", "\x02\x01j\x03\x01\x03\x02\a\x02\x01\x17\x1e\x04\x02\t\x14\x13\x01*\x01\x04\x01\a\n\x02\x01\x11\x02\x02"}, {"go/build", "\x02\x01j\x03\x01\x03\x02\a\x02\x01\x17\x1e\x04\x02\t\x14\x12\x01+\x01\x04\x01\a\n\x02\x01\x11\x02\x02"},
{"go/build/constraint", "m\xc2\x01\x01\x11\x02"}, {"go/build/constraint", "m\xc2\x01\x01\x11\x02"},
{"go/constant", "p\x10x\x01\x015\x01\x02\x11"}, {"go/constant", "p\x10w\x01\x016\x01\x02\x11"},
{"go/doc", "\x04l\x01\x06\t=.0\x12\x02\x01\x11\x02"}, {"go/doc", "\x04l\x01\x06\t=-1\x12\x02\x01\x11\x02"},
{"go/doc/comment", "\x03m\xbd\x01\x01\x01\x01\x11\x02"}, {"go/doc/comment", "\x03m\xbd\x01\x01\x01\x01\x11\x02"},
{"go/format", "\x03m\x01\f\x01\x02kE"}, {"go/format", "\x03m\x01\f\x01\x02jF"},
{"go/importer", "s\a\x01\x01\x04\x01j8"}, {"go/importer", "s\a\x01\x01\x04\x01i9"},
{"go/internal/gccgoimporter", "\x02\x01W\x13\x03\x05\v\x01h\x02+\x01\x05\x13\x01\v\b"}, {"go/internal/gccgoimporter", "\x02\x01W\x13\x03\x05\v\x01g\x02,\x01\x05\x13\x01\v\b"},
{"go/internal/gcimporter", "\x02n\x10\x01/\x05\x0e(+\x17\x03\x02"}, {"go/internal/gcimporter", "\x02n\x10\x01/\x05\x0e',\x17\x03\x02"},
{"go/internal/srcimporter", "p\x01\x02\n\x03\x01j+\x01\x05\x14\x02\x13"}, {"go/internal/srcimporter", "p\x01\x02\n\x03\x01i,\x01\x05\x14\x02\x13"},
{"go/parser", "\x03j\x03\x01\x03\v\x01k\x01*\x06\x14"}, {"go/parser", "\x03j\x03\x01\x03\v\x01j\x01+\x06\x14"},
{"go/printer", "p\x01\x03\x03\tk\r\x1e\x17\x02\x01\x02\n\x05\x02"}, {"go/printer", "p\x01\x03\x03\tj\r\x1f\x17\x02\x01\x02\n\x05\x02"},
{"go/scanner", "\x03m\x10k1\x12\x01\x12\x02"}, {"go/scanner", "\x03m\x10j2\x12\x01\x12\x02"},
{"go/token", "\x04l\xbd\x01\x02\x03\x01\x0e\x02"}, {"go/token", "\x04l\xbd\x01\x02\x03\x01\x0e\x02"},
{"go/types", "\x03\x01\x06c\x03\x01\x04\b\x03\x02\x15\x1e\x06,\x04\x03\n$\a\n\x01\x01\x01\x02\x01\x0e\x02\x02"}, {"go/types", "\x03\x01\x06c\x03\x01\x04\b\x03\x02\x15\x1e\x06+\x04\x03\n%\a\n\x01\x01\x01\x02\x01\x0e\x02\x02"},
{"go/version", "\xba\x01v"}, {"go/version", "\xba\x01v"},
{"hash", "\xeb\x01"}, {"hash", "\xea\x01"},
{"hash/adler32", "m\x16\x16"}, {"hash/adler32", "m\x16\x16"},
{"hash/crc32", "m\x16\x16\x14\x85\x01\x01\x12"}, {"hash/crc32", "m\x16\x16\x14\x85\x01\x01\x12"},
{"hash/crc64", "m\x16\x16\x99\x01"}, {"hash/crc64", "m\x16\x16\x99\x01"},
{"hash/fnv", "m\x16\x16a"}, {"hash/fnv", "m\x16\x16`"},
{"hash/maphash", "\x94\x01\x05\x1b\x03AM"}, {"hash/maphash", "\x94\x01\x05\x1b\x03@N"},
{"html", "\xb0\x02\x02\x11"}, {"html", "\xb0\x02\x02\x11"},
{"html/template", "\x03g\x06\x19,6\x01\v\x1f\x05\x01\x02\x03\x0e\x01\x02\v\x01\x03\x02"}, {"html/template", "\x03g\x06\x19,5\x01\v \x05\x01\x02\x03\x0e\x01\x02\v\x01\x03\x02"},
{"image", "\x02k\x1f_\x0f5\x03\x01"}, {"image", "\x02k\x1f^\x0f6\x03\x01"},
{"image/color", ""}, {"image/color", ""},
{"image/color/palette", "\x8c\x01"}, {"image/color/palette", "\x8c\x01"},
{"image/draw", "\x8b\x01\x01\x04"}, {"image/draw", "\x8b\x01\x01\x04"},
{"image/gif", "\x02\x01\x05e\x03\x1b\x01\x01\x01\vR"}, {"image/gif", "\x02\x01\x05e\x03\x1b\x01\x01\x01\vQ"},
{"image/internal/imageutil", "\x8b\x01"}, {"image/internal/imageutil", "\x8b\x01"},
{"image/jpeg", "\x02k\x1e\x01\x04["}, {"image/jpeg", "\x02k\x1e\x01\x04Z"},
{"image/png", "\x02\a]\n\x13\x02\x06\x01_D"}, {"image/png", "\x02\a]\n\x13\x02\x06\x01^E"},
{"index/suffixarray", "\x03c\a~\r)\f\x01"}, {"index/suffixarray", "\x03c\a}\r*\f\x01"},
{"internal/abi", "\xb4\x01\x91\x01"}, {"internal/abi", "\xb4\x01\x91\x01"},
{"internal/asan", "\xc5\x02"}, {"internal/asan", "\xc5\x02"},
{"internal/bisect", "\xa3\x02\x0f\x01"}, {"internal/bisect", "\xa3\x02\x0f\x01"},
@ -171,27 +171,27 @@ var deps = [...]pkginfo{
{"internal/copyright", ""}, {"internal/copyright", ""},
{"internal/coverage", ""}, {"internal/coverage", ""},
{"internal/coverage/calloc", ""}, {"internal/coverage/calloc", ""},
{"internal/coverage/cfile", "j\x06\x17\x16\x01\x02\x01\x01\x01\x01\x01\x01\x01#\x01 +\x06\a\f\x01\x03\f\x06"}, {"internal/coverage/cfile", "j\x06\x17\x16\x01\x02\x01\x01\x01\x01\x01\x01\x01#\x01\x1f,\x06\a\f\x01\x03\f\x06"},
{"internal/coverage/cformat", "\x04l-\x04J\f6\x01\x02\f"}, {"internal/coverage/cformat", "\x04l-\x04I\f7\x01\x02\f"},
{"internal/coverage/cmerge", "p-["}, {"internal/coverage/cmerge", "p-Z"},
{"internal/coverage/decodecounter", "f\n-\v\x02A+\x19\x16"}, {"internal/coverage/decodecounter", "f\n-\v\x02@,\x19\x16"},
{"internal/coverage/decodemeta", "\x02d\n\x17\x16\v\x02A+"}, {"internal/coverage/decodemeta", "\x02d\n\x17\x16\v\x02@,"},
{"internal/coverage/encodecounter", "\x02d\n-\f\x01\x02?\f\x1f\x17"}, {"internal/coverage/encodecounter", "\x02d\n-\f\x01\x02>\f \x17"},
{"internal/coverage/encodemeta", "\x02\x01c\n\x13\x04\x16\r\x02?+/"}, {"internal/coverage/encodemeta", "\x02\x01c\n\x13\x04\x16\r\x02>,/"},
{"internal/coverage/pods", "\x04l-y\x06\x05\f\x02\x01"}, {"internal/coverage/pods", "\x04l-y\x06\x05\f\x02\x01"},
{"internal/coverage/rtcov", "\xc5\x02"}, {"internal/coverage/rtcov", "\xc5\x02"},
{"internal/coverage/slicereader", "f\n{Z"}, {"internal/coverage/slicereader", "f\nz["},
{"internal/coverage/slicewriter", "p{"}, {"internal/coverage/slicewriter", "pz"},
{"internal/coverage/stringtab", "p8\x04?"}, {"internal/coverage/stringtab", "p8\x04>"},
{"internal/coverage/test", ""}, {"internal/coverage/test", ""},
{"internal/coverage/uleb128", ""}, {"internal/coverage/uleb128", ""},
{"internal/cpu", "\xc5\x02"}, {"internal/cpu", "\xc5\x02"},
{"internal/dag", "\x04l\xbd\x01\x03"}, {"internal/dag", "\x04l\xbd\x01\x03"},
{"internal/diff", "\x03m\xbe\x01\x02"}, {"internal/diff", "\x03m\xbe\x01\x02"},
{"internal/exportdata", "\x02\x01j\x03\x03]\x1b+\x01\x05\x13\x01\x02"}, {"internal/exportdata", "\x02\x01j\x03\x03]\x1a,\x01\x05\x13\x01\x02"},
{"internal/filepathlite", "m+:\x1aA"}, {"internal/filepathlite", "m+:\x19B"},
{"internal/fmtsort", "\x04\x9a\x02\x0f"}, {"internal/fmtsort", "\x04\x9a\x02\x0f"},
{"internal/fuzz", "\x03\nA\x18\x04\x03\x03\x01\f\x0356\r\x02\x1c\x01\x05\x02\x05\f\x01\x02\x01\x01\v\x04\x02"}, {"internal/fuzz", "\x03\nA\x18\x04\x03\x03\x01\f\x0355\r\x02\x1d\x01\x05\x02\x05\f\x01\x02\x01\x01\v\x04\x02"},
{"internal/goarch", ""}, {"internal/goarch", ""},
{"internal/godebug", "\x96\x01 |\x01\x12"}, {"internal/godebug", "\x96\x01 |\x01\x12"},
{"internal/godebugs", ""}, {"internal/godebugs", ""},
@ -202,158 +202,158 @@ var deps = [...]pkginfo{
{"internal/goversion", ""}, {"internal/goversion", ""},
{"internal/itoa", ""}, {"internal/itoa", ""},
{"internal/lazyregexp", "\x96\x02\v\x0f\x02"}, {"internal/lazyregexp", "\x96\x02\v\x0f\x02"},
{"internal/lazytemplate", "\xeb\x01+\x1a\x02\v"}, {"internal/lazytemplate", "\xea\x01,\x1a\x02\v"},
{"internal/msan", "\xc5\x02"}, {"internal/msan", "\xc5\x02"},
{"internal/nettrace", ""}, {"internal/nettrace", ""},
{"internal/obscuretestdata", "e\x86\x01+"}, {"internal/obscuretestdata", "e\x85\x01,"},
{"internal/oserror", "m"}, {"internal/oserror", "m"},
{"internal/pkgbits", "\x03K\x18\a\x03\x05\vk\x0e\x1d\r\f\x01"}, {"internal/pkgbits", "\x03K\x18\a\x03\x05\vj\x0e\x1e\r\f\x01"},
{"internal/platform", ""}, {"internal/platform", ""},
{"internal/poll", "mO\x1a\x158\x0f\x01\x01\v\x06"}, {"internal/poll", "mO\x1a\x149\x0f\x01\x01\v\x06"},
{"internal/profile", "\x03\x04f\x03{6\r\x01\x01\x0f"}, {"internal/profile", "\x03\x04f\x03z7\r\x01\x01\x0f"},
{"internal/profilerecord", ""}, {"internal/profilerecord", ""},
{"internal/race", "\x94\x01\xb1\x01"}, {"internal/race", "\x94\x01\xb1\x01"},
{"internal/reflectlite", "\x94\x01 4;\""}, {"internal/reflectlite", "\x94\x01 3<\""},
{"internal/runtime/atomic", "\xc5\x02"}, {"internal/runtime/atomic", "\xc5\x02"},
{"internal/runtime/exithook", "\xca\x01{"}, {"internal/runtime/exithook", "\xca\x01{"},
{"internal/runtime/maps", "\x94\x01\x01\x1f\v\t\x05\x01w"}, {"internal/runtime/maps", "\x94\x01\x01\x1f\v\t\x05\x01w"},
{"internal/runtime/math", "\xb4\x01"}, {"internal/runtime/math", "\xb4\x01"},
{"internal/runtime/sys", "\xb4\x01\x04"}, {"internal/runtime/sys", "\xb4\x01\x04"},
{"internal/runtime/syscall", "\xc5\x02"}, {"internal/runtime/syscall", "\xc5\x02"},
{"internal/saferio", "\xeb\x01Z"}, {"internal/saferio", "\xea\x01["},
{"internal/singleflight", "\xb2\x02"}, {"internal/singleflight", "\xb2\x02"},
{"internal/stringslite", "\x98\x01\xad\x01"}, {"internal/stringslite", "\x98\x01\xad\x01"},
{"internal/sync", "\x94\x01 \x14k\x12"}, {"internal/sync", "\x94\x01 \x14k\x12"},
{"internal/synctest", "\xc5\x02"}, {"internal/synctest", "\xc5\x02"},
{"internal/syscall/execenv", "\xb4\x02"}, {"internal/syscall/execenv", "\xb4\x02"},
{"internal/syscall/unix", "\xa3\x02\x10\x01\x11"}, {"internal/syscall/unix", "\xa3\x02\x10\x01\x11"},
{"internal/sysinfo", "\x02\x01\xaa\x01>+\x1a\x02"}, {"internal/sysinfo", "\x02\x01\xaa\x01=,\x1a\x02"},
{"internal/syslist", ""}, {"internal/syslist", ""},
{"internal/testenv", "\x03\n`\x02\x01*\x1a\x10(*\x01\x05\a\f\x01\x02\x02\x01\n"}, {"internal/testenv", "\x03\n`\x02\x01*\x1a\x10'+\x01\x05\a\f\x01\x02\x02\x01\n"},
{"internal/testlog", "\xb2\x02\x01\x12"}, {"internal/testlog", "\xb2\x02\x01\x12"},
{"internal/testpty", "m\x03\xa6\x01"}, {"internal/testpty", "m\x03\xa6\x01"},
{"internal/trace", "\x02\x01\x01\x06\\\a\x03m\x01\x01\x06\x06\x03\n5\x01\x02\x0f"}, {"internal/trace", "\x02\x01\x01\x06\\\a\x03n\x03\x03\x06\x03\n6\x01\x02\x0f\x06"},
{"internal/trace/event", ""}, {"internal/trace/internal/testgen", "\x03c\nl\x03\x02\x03\x011\v\x0f"},
{"internal/trace/event/go122", "pm"}, {"internal/trace/internal/tracev1", "\x03\x01b\a\x03t\x06\r6\x01"},
{"internal/trace/internal/oldtrace", "\x03\x01b\a\x03m\b\x06\r5\x01"}, {"internal/trace/raw", "\x02d\nq\x03\x06E\x01\x11"},
{"internal/trace/internal/testgen/go122", "\x03c\nl\x01\x01\x03\x04\x010\v\x0f"}, {"internal/trace/testtrace", "\x02\x01j\x03l\x03\x06\x057\f\x02\x01"},
{"internal/trace/raw", "\x02d\nm\b\x06D\x01\x11"}, {"internal/trace/tracev2", ""},
{"internal/trace/testtrace", "\x02\x01j\x03l\x05\x05\x056\f\x02\x01"}, {"internal/trace/traceviewer", "\x02]\v\x06\x1a<\x16\a\a\x04\t\n\x15\x01\x05\a\f\x01\x02\r"},
{"internal/trace/traceviewer", "\x02]\v\x06\x1a<\x16\b\a\x04\t\n\x14\x01\x05\a\f\x01\x02\r"},
{"internal/trace/traceviewer/format", ""}, {"internal/trace/traceviewer/format", ""},
{"internal/trace/version", "pm\x01\r"}, {"internal/trace/version", "pq\t"},
{"internal/txtar", "\x03m\xa6\x01\x1a"}, {"internal/txtar", "\x03m\xa6\x01\x1a"},
{"internal/types/errors", "\xaf\x02"}, {"internal/types/errors", "\xaf\x02"},
{"internal/unsafeheader", "\xc5\x02"}, {"internal/unsafeheader", "\xc5\x02"},
{"internal/xcoff", "Y\r\a\x03`\x1b+\x19\x01"}, {"internal/xcoff", "Y\r\a\x03`\x1a,\x19\x01"},
{"internal/zstd", "f\a\x03{\x0f"}, {"internal/zstd", "f\a\x03z\x0f"},
{"io", "m\xc5\x01"}, {"io", "m\xc5\x01"},
{"io/fs", "m+*)0\x12\x12\x04"}, {"io/fs", "m+*(1\x12\x12\x04"},
{"io/ioutil", "\xeb\x01\x01*\x17\x03"}, {"io/ioutil", "\xea\x01\x01+\x17\x03"},
{"iter", "\xc8\x01[\""}, {"iter", "\xc8\x01[\""},
{"log", "p{\x05&\r\x0f\x01\f"}, {"log", "pz\x05'\r\x0f\x01\f"},
{"log/internal", ""}, {"log/internal", ""},
{"log/slog", "\x03\nT\t\x03\x03{\x04\x01\x02\x02\x04&\x05\n\x02\x01\x02\x01\f\x02\x02\x02"}, {"log/slog", "\x03\nT\t\x03\x03z\x04\x01\x02\x02\x04'\x05\n\x02\x01\x02\x01\f\x02\x02\x02"},
{"log/slog/internal", ""}, {"log/slog/internal", ""},
{"log/slog/internal/benchmarks", "\r`\x03{\x06\x03;\x10"}, {"log/slog/internal/benchmarks", "\r`\x03z\x06\x03<\x10"},
{"log/slog/internal/buffer", "\xb2\x02"}, {"log/slog/internal/buffer", "\xb2\x02"},
{"log/slog/internal/slogtest", "\xf1\x01"}, {"log/slog/internal/slogtest", "\xf0\x01"},
{"log/syslog", "m\x03\x7f\x12\x15\x1a\x02\r"}, {"log/syslog", "m\x03~\x12\x16\x1a\x02\r"},
{"maps", "\xee\x01W"}, {"maps", "\xed\x01X"},
{"math", "\xad\x01MK"}, {"math", "\xad\x01LL"},
{"math/big", "\x03j\x03)\x14>\r\x02\x023\x01\x02\x13"}, {"math/big", "\x03j\x03)\x14=\r\x02\x024\x01\x02\x13"},
{"math/bits", "\xc5\x02"}, {"math/bits", "\xc5\x02"},
{"math/cmplx", "\xf8\x01\x02"}, {"math/cmplx", "\xf7\x01\x02"},
{"math/rand", "\xb5\x01C:\x01\x12"}, {"math/rand", "\xb5\x01B;\x01\x12"},
{"math/rand/v2", "m,\x02]\x02K"}, {"math/rand/v2", "m,\x02\\\x02L"},
{"mime", "\x02\x01b\b\x03{\f\x1f\x17\x03\x02\x0f\x02"}, {"mime", "\x02\x01b\b\x03z\f \x17\x03\x02\x0f\x02"},
{"mime/multipart", "\x02\x01G#\x03E6\f\x01\x06\x02\x14\x02\x06\x11\x02\x01\x15"}, {"mime/multipart", "\x02\x01G#\x03E5\f\x01\x06\x02\x15\x02\x06\x11\x02\x01\x15"},
{"mime/quotedprintable", "\x02\x01m{"}, {"mime/quotedprintable", "\x02\x01mz"},
{"net", "\x04\t`+\x1d\a\x04\x05\f\x01\x04\x15\x01$\x06\r\n\x05\x01\x01\v\x06\a"}, {"net", "\x04\t`+\x1d\a\x04\x05\f\x01\x04\x14\x01%\x06\r\n\x05\x01\x01\v\x06\a"},
{"net/http", "\x02\x01\x04\x04\x02=\b\x13\x01\a\x03E6\x01\x03\b\x01\x02\x02\x02\x01\x02\x06\x02\x01\n\x01\x01\x05\x01\x02\x05\n\x01\x01\x01\x02\x01\f\x02\x02\x02\b\x01\x01\x01"}, {"net/http", "\x02\x01\x04\x04\x02=\b\x13\x01\a\x03E5\x01\x03\b\x01\x02\x02\x02\x01\x02\x06\x02\x01\x01\n\x01\x01\x05\x01\x02\x05\n\x01\x01\x01\x02\x01\x01\v\x02\x02\x02\b\x01\x01\x01"},
{"net/http/cgi", "\x02P\x1b\x03{\x04\b\n\x01\x12\x01\x01\x01\x04\x01\x05\x02\n\x02\x01\x0f\x0e"}, {"net/http/cgi", "\x02P\x1b\x03z\x04\b\n\x01\x13\x01\x01\x01\x04\x01\x05\x02\n\x02\x01\x0f\x0e"},
{"net/http/cookiejar", "\x04i\x03\x91\x01\x01\b\v\x18\x03\x02\r\x04"}, {"net/http/cookiejar", "\x04i\x03\x90\x01\x01\b\f\x18\x03\x02\r\x04"},
{"net/http/fcgi", "\x02\x01\nY\a\x03{\x16\x01\x01\x13\x1a\x02\r"}, {"net/http/fcgi", "\x02\x01\nY\a\x03z\x16\x01\x01\x14\x1a\x02\r"},
{"net/http/httptest", "\x02\x01\nE\x02\x1b\x01{\x04\x12\x01\t\t\x02\x19\x01\x02\r\x0e"}, {"net/http/httptest", "\x02\x01\nE\x02\x1b\x01z\x04\x12\x01\n\t\x02\x19\x01\x02\r\x0e"},
{"net/http/httptrace", "\rEnA\x13\n!"}, {"net/http/httptrace", "\rEn@\x14\n!"},
{"net/http/httputil", "\x02\x01\n`\x03{\x04\x0f\x03\x01\x05\x02\x01\n\x01\x1b\x02\r\x0e"}, {"net/http/httputil", "\x02\x01\n`\x03z\x04\x0f\x03\x01\x05\x02\x01\v\x01\x1b\x02\r\x0e"},
{"net/http/internal", "\x02\x01j\x03{"}, {"net/http/internal", "\x02\x01j\x03z"},
{"net/http/internal/ascii", "\xb0\x02\x11"}, {"net/http/internal/ascii", "\xb0\x02\x11"},
{"net/http/internal/httpcommon", "\r`\x03\x96\x01\x0e\x01\x19\x01\x01\x02\x1b\x02"},
{"net/http/internal/testcert", "\xb0\x02"}, {"net/http/internal/testcert", "\xb0\x02"},
{"net/http/pprof", "\x02\x01\nc\x19,\x11%\x04\x13\x13\x01\r\x06\x03\x01\x02\x01\x0f"}, {"net/http/pprof", "\x02\x01\nc\x19,\x11$\x04\x13\x14\x01\r\x06\x03\x01\x02\x01\x0f"},
{"net/internal/cgotest", ""}, {"net/internal/cgotest", ""},
{"net/internal/socktest", "p\xc2\x01\x02"}, {"net/internal/socktest", "p\xc2\x01\x02"},
{"net/mail", "\x02k\x03{\x04\x0f\x03\x13\x1c\x02\r\x04"}, {"net/mail", "\x02k\x03z\x04\x0f\x03\x14\x1c\x02\r\x04"},
{"net/netip", "\x04i+\x01#<\x025\x15"}, {"net/netip", "\x04i+\x01#;\x026\x15"},
{"net/rpc", "\x02f\x05\x03\x10\na\x04\x12\x01\x1c\x0f\x03\x02"}, {"net/rpc", "\x02f\x05\x03\x10\n`\x04\x12\x01\x1d\x0f\x03\x02"},
{"net/rpc/jsonrpc", "j\x03\x03{\x16\x10!"}, {"net/rpc/jsonrpc", "j\x03\x03z\x16\x11!"},
{"net/smtp", "\x19.\v\x13\b\x03{\x16\x13\x1c"}, {"net/smtp", "\x19.\v\x13\b\x03z\x16\x14\x1c"},
{"net/textproto", "\x02\x01j\x03{\r\t.\x01\x02\x13"}, {"net/textproto", "\x02\x01j\x03z\r\t/\x01\x02\x13"},
{"net/url", "m\x03\x87\x01$\x12\x02\x01\x15"}, {"net/url", "m\x03\x86\x01%\x12\x02\x01\x15"},
{"os", "m+\x01\x18\x03\b\t\r\x03\x01\x04\x11\x017\n\x05\x01\x01\v\x06"}, {"os", "m+\x01\x18\x03\b\t\r\x03\x01\x04\x10\x018\n\x05\x01\x01\v\x06"},
{"os/exec", "\x03\n`H \x01\x15\x01*\x06\a\f\x01\x04\v"}, {"os/exec", "\x03\n`H \x01\x14\x01+\x06\a\f\x01\x04\v"},
{"os/exec/internal/fdtest", "\xb4\x02"}, {"os/exec/internal/fdtest", "\xb4\x02"},
{"os/signal", "\r\x89\x02\x17\x05\x02"}, {"os/signal", "\r\x89\x02\x17\x05\x02"},
{"os/user", "\x02\x01j\x03{+\r\f\x01\x02"}, {"os/user", "\x02\x01j\x03z,\r\f\x01\x02"},
{"path", "m+\xab\x01"}, {"path", "m+\xab\x01"},
{"path/filepath", "m+\x19;*\r\n\x03\x04\x0f"}, {"path/filepath", "m+\x19:+\r\n\x03\x04\x0f"},
{"plugin", "m"}, {"plugin", "m"},
{"reflect", "m'\x04\x1c\b\f\x04\x02\x1a\x06\n+\f\x03\x0f\x02\x02"}, {"reflect", "m'\x04\x1c\b\f\x04\x02\x19\x10,\f\x03\x0f\x02\x02"},
{"reflect/internal/example1", ""}, {"reflect/internal/example1", ""},
{"reflect/internal/example2", ""}, {"reflect/internal/example2", ""},
{"regexp", "\x03\xe8\x017\v\x02\x01\x02\x0f\x02"}, {"regexp", "\x03\xe7\x018\v\x02\x01\x02\x0f\x02"},
{"regexp/syntax", "\xad\x02\x01\x01\x01\x11\x02"}, {"regexp/syntax", "\xad\x02\x01\x01\x01\x11\x02"},
{"runtime", "\x94\x01\x04\x01\x02\f\x06\a\x02\x01\x01\x0f\x03\x01\x01\x01\x01\x01\x03s"}, {"runtime", "\x94\x01\x04\x01\x02\f\x06\a\x02\x01\x01\x0f\x03\x01\x01\x01\x01\x01\x03\x0fd"},
{"runtime/coverage", "\x9f\x01L"}, {"runtime/coverage", "\x9f\x01K"},
{"runtime/debug", "pUQ\r\n\x02\x01\x0f\x06"}, {"runtime/debug", "pUQ\r\n\x02\x01\x0f\x06"},
{"runtime/internal/startlinetest", ""}, {"runtime/internal/startlinetest", ""},
{"runtime/internal/wasitest", ""}, {"runtime/internal/wasitest", ""},
{"runtime/metrics", "\xb6\x01B+\""}, {"runtime/metrics", "\xb6\x01A,\""},
{"runtime/pprof", "\x02\x01\x01\x03\x06Y\a\x03$3$\r\x1e\r\n\x01\x01\x01\x02\x02\b\x03\x06"}, {"runtime/pprof", "\x02\x01\x01\x03\x06Y\a\x03$3#\r\x1f\r\n\x01\x01\x01\x02\x02\b\x03\x06"},
{"runtime/race", "\xab\x02"}, {"runtime/race", "\xab\x02"},
{"runtime/race/internal/amd64v1", ""}, {"runtime/race/internal/amd64v1", ""},
{"runtime/trace", "\rc{8\x0f\x01\x12"}, {"runtime/trace", "\rcz9\x0f\x01\x12"},
{"slices", "\x04\xea\x01\fK"}, {"slices", "\x04\xe9\x01\fL"},
{"sort", "\xc9\x0113"}, {"sort", "\xc9\x0104"},
{"strconv", "m+:&\x02I"}, {"strconv", "m+:%\x02J"},
{"strings", "m'\x04:\x19\x03\f8\x0f\x02\x02"}, {"strings", "m'\x04:\x18\x03\f9\x0f\x02\x02"},
{"structs", ""}, {"structs", ""},
{"sync", "\xc8\x01\vP\x10\x12"}, {"sync", "\xc8\x01\vP\x10\x12"},
{"sync/atomic", "\xc5\x02"}, {"sync/atomic", "\xc5\x02"},
{"syscall", "m(\x03\x01\x1b\b\x03\x03\x06\aT\x0f\x01\x12"}, {"syscall", "m(\x03\x01\x1b\b\x03\x03\x06\aT\n\x05\x01\x12"},
{"testing", "\x03\n`\x02\x01G\x11\x0f\x14\r\x04\x1a\x06\x02\x05\x02\a\x01\x02\x01\x02\x01\f\x02\x02\x02"}, {"testing", "\x03\n`\x02\x01X\x0f\x13\r\x04\x1b\x06\x02\x05\x02\a\x01\x02\x01\x02\x01\f\x02\x02\x02"},
{"testing/fstest", "m\x03{\x01\v$\x12\x03\b\a"}, {"testing/fstest", "m\x03z\x01\v%\x12\x03\b\a"},
{"testing/internal/testdeps", "\x02\v\xa6\x01'\x11+\x03\x05\x03\b\a\x02\r"}, {"testing/internal/testdeps", "\x02\v\xa6\x01'\x10,\x03\x05\x03\b\a\x02\r"},
{"testing/iotest", "\x03j\x03{\x04"}, {"testing/iotest", "\x03j\x03z\x04"},
{"testing/quick", "o\x01\x88\x01\x04\"\x12\x0f"}, {"testing/quick", "o\x01\x87\x01\x04#\x12\x0f"},
{"testing/slogtest", "\r`\x03\x81\x01-\x05\x12\n"}, {"testing/slogtest", "\r`\x03\x80\x01.\x05\x12\n"},
{"text/scanner", "\x03m{++\x02"}, {"text/scanner", "\x03mz,+\x02"},
{"text/tabwriter", "p{X"}, {"text/tabwriter", "pzY"},
{"text/template", "m\x03B9\x01\v\x1e\x01\x05\x01\x02\x05\r\x02\f\x03\x02"}, {"text/template", "m\x03B8\x01\v\x1f\x01\x05\x01\x02\x05\r\x02\f\x03\x02"},
{"text/template/parse", "\x03m\xb3\x01\f\x01\x11\x02"}, {"text/template/parse", "\x03m\xb3\x01\f\x01\x11\x02"},
{"time", "m+\x1d\x1d()\x0f\x02\x11"}, {"time", "m+\x1d\x1d'*\x0f\x02\x11"},
{"time/tzdata", "m\xc7\x01\x11"}, {"time/tzdata", "m\xc7\x01\x11"},
{"unicode", ""}, {"unicode", ""},
{"unicode/utf16", ""}, {"unicode/utf16", ""},
{"unicode/utf8", ""}, {"unicode/utf8", ""},
{"unique", "\x94\x01>\x01P\x0f\x13\x12"}, {"unique", "\x94\x01>\x01P\x0f\x13\x12"},
{"unsafe", ""}, {"unsafe", ""},
{"vendor/golang.org/x/crypto/chacha20", "\x10V\a\x8d\x01)'"}, {"vendor/golang.org/x/crypto/chacha20", "\x10V\a\x8c\x01*'"},
{"vendor/golang.org/x/crypto/chacha20poly1305", "\x10V\a\xd9\x01\x04\x01\a"}, {"vendor/golang.org/x/crypto/chacha20poly1305", "\x10V\a\xd9\x01\x04\x01\a"},
{"vendor/golang.org/x/crypto/cryptobyte", "c\n\x03\x89\x01%!\n"}, {"vendor/golang.org/x/crypto/cryptobyte", "c\n\x03\x88\x01&!\n"},
{"vendor/golang.org/x/crypto/cryptobyte/asn1", ""}, {"vendor/golang.org/x/crypto/cryptobyte/asn1", ""},
{"vendor/golang.org/x/crypto/internal/alias", "\xc5\x02"}, {"vendor/golang.org/x/crypto/internal/alias", "\xc5\x02"},
{"vendor/golang.org/x/crypto/internal/poly1305", "Q\x15\x94\x01"}, {"vendor/golang.org/x/crypto/internal/poly1305", "Q\x15\x93\x01"},
{"vendor/golang.org/x/net/dns/dnsmessage", "m"}, {"vendor/golang.org/x/net/dns/dnsmessage", "m"},
{"vendor/golang.org/x/net/http/httpguts", "\x81\x02\x13\x1c\x13\r"}, {"vendor/golang.org/x/net/http/httpguts", "\x80\x02\x14\x1c\x13\r"},
{"vendor/golang.org/x/net/http/httpproxy", "m\x03\x91\x01\x0f\x05\x01\x1a\x13\r"}, {"vendor/golang.org/x/net/http/httpproxy", "m\x03\x90\x01\x15\x01\x1a\x13\r"},
{"vendor/golang.org/x/net/http2/hpack", "\x03j\x03{G"}, {"vendor/golang.org/x/net/http2/hpack", "\x03j\x03zH"},
{"vendor/golang.org/x/net/idna", "p\x88\x018\x13\x10\x02\x01"}, {"vendor/golang.org/x/net/idna", "p\x87\x019\x13\x10\x02\x01"},
{"vendor/golang.org/x/net/nettest", "\x03c\a\x03{\x11\x05\x15\x01\f\f\x01\x02\x02\x01\n"}, {"vendor/golang.org/x/net/nettest", "\x03c\a\x03z\x11\x05\x16\x01\f\f\x01\x02\x02\x01\n"},
{"vendor/golang.org/x/sys/cpu", "\x96\x02\r\f\x01\x15"}, {"vendor/golang.org/x/sys/cpu", "\x96\x02\r\f\x01\x15"},
{"vendor/golang.org/x/text/secure/bidirule", "m\xd6\x01\x11\x01"}, {"vendor/golang.org/x/text/secure/bidirule", "m\xd6\x01\x11\x01"},
{"vendor/golang.org/x/text/transform", "\x03j~X"}, {"vendor/golang.org/x/text/transform", "\x03j}Y"},
{"vendor/golang.org/x/text/unicode/bidi", "\x03\be\x7f?\x15"}, {"vendor/golang.org/x/text/unicode/bidi", "\x03\be~@\x15"},
{"vendor/golang.org/x/text/unicode/norm", "f\n{G\x11\x11"}, {"vendor/golang.org/x/text/unicode/norm", "f\nzH\x11\x11"},
{"weak", "\x94\x01\x8f\x01\""}, {"weak", "\x94\x01\x8f\x01\""},
} }

File diff suppressed because it is too large Load diff

View file

@ -18,6 +18,14 @@ type Symbol struct {
Name string Name string
Kind Kind Kind Kind
Version Version // Go version that first included the symbol Version Version // Go version that first included the symbol
// Signature provides the type of a function (defined only for Kind=Func).
// Imported types are denoted as pkg.T; pkg is not fully qualified.
// TODO(adonovan): use an unambiguous encoding that is parseable.
//
// Example2:
// func[M ~map[K]V, K comparable, V any](m M) M
// func(fi fs.FileInfo, link string) (*Header, error)
Signature string // if Kind == stdlib.Func
} }
// A Kind indicates the kind of a symbol: // A Kind indicates the kind of a symbol:

View file

@ -65,14 +65,16 @@ func ClassifyCall(info *types.Info, call *ast.CallExpr) CallKind {
if info.Types == nil { if info.Types == nil {
panic("ClassifyCall: info.Types is nil") panic("ClassifyCall: info.Types is nil")
} }
if info.Types[call.Fun].IsType() { tv := info.Types[call.Fun]
if tv.IsType() {
return CallConversion return CallConversion
} }
if tv.IsBuiltin() {
return CallBuiltin
}
obj := info.Uses[UsedIdent(info, call.Fun)] obj := info.Uses[UsedIdent(info, call.Fun)]
// Classify the call by the type of the object, if any. // Classify the call by the type of the object, if any.
switch obj := obj.(type) { switch obj := obj.(type) {
case *types.Builtin:
return CallBuiltin
case *types.Func: case *types.Func:
if interfaceMethod(obj) { if interfaceMethod(obj) {
return CallInterface return CallInterface

View file

@ -4,7 +4,7 @@
// Package typeindex provides an [Index] of type information for a // Package typeindex provides an [Index] of type information for a
// package, allowing efficient lookup of, say, whether a given symbol // package, allowing efficient lookup of, say, whether a given symbol
// is referenced and, if so, where from; or of the [cursor.Cursor] for // is referenced and, if so, where from; or of the [inspector.Cursor] for
// the declaration of a particular [types.Object] symbol. // the declaration of a particular [types.Object] symbol.
package typeindex package typeindex
@ -14,10 +14,9 @@ import (
"go/types" "go/types"
"iter" "iter"
"golang.org/x/tools/go/ast/edge"
"golang.org/x/tools/go/ast/inspector" "golang.org/x/tools/go/ast/inspector"
"golang.org/x/tools/go/types/typeutil" "golang.org/x/tools/go/types/typeutil"
"golang.org/x/tools/internal/astutil/cursor"
"golang.org/x/tools/internal/astutil/edge"
"golang.org/x/tools/internal/typesinternal" "golang.org/x/tools/internal/typesinternal"
) )
@ -30,7 +29,7 @@ func New(inspect *inspector.Inspector, pkg *types.Package, info *types.Info) *In
inspect: inspect, inspect: inspect,
info: info, info: info,
packages: make(map[string]*types.Package), packages: make(map[string]*types.Package),
def: make(map[types.Object]cursor.Cursor), def: make(map[types.Object]inspector.Cursor),
uses: make(map[types.Object]*uses), uses: make(map[types.Object]*uses),
} }
@ -40,7 +39,7 @@ func New(inspect *inspector.Inspector, pkg *types.Package, info *types.Info) *In
} }
} }
for cur := range cursor.Root(inspect).Preorder((*ast.ImportSpec)(nil), (*ast.Ident)(nil)) { for cur := range inspect.Root().Preorder((*ast.ImportSpec)(nil), (*ast.Ident)(nil)) {
switch n := cur.Node().(type) { switch n := cur.Node().(type) {
case *ast.ImportSpec: case *ast.ImportSpec:
// Index direct imports, including blank ones. // Index direct imports, including blank ones.
@ -84,7 +83,7 @@ type Index struct {
inspect *inspector.Inspector inspect *inspector.Inspector
info *types.Info info *types.Info
packages map[string]*types.Package // packages of all symbols referenced from this package packages map[string]*types.Package // packages of all symbols referenced from this package
def map[types.Object]cursor.Cursor // Cursor of *ast.Ident that defines the Object def map[types.Object]inspector.Cursor // Cursor of *ast.Ident that defines the Object
uses map[types.Object]*uses // Cursors of *ast.Idents that use the Object uses map[types.Object]*uses // Cursors of *ast.Idents that use the Object
} }
@ -107,14 +106,14 @@ type uses struct {
// Uses returns the sequence of Cursors of [*ast.Ident]s in this package // Uses returns the sequence of Cursors of [*ast.Ident]s in this package
// that refer to obj. If obj is nil, the sequence is empty. // that refer to obj. If obj is nil, the sequence is empty.
func (ix *Index) Uses(obj types.Object) iter.Seq[cursor.Cursor] { func (ix *Index) Uses(obj types.Object) iter.Seq[inspector.Cursor] {
return func(yield func(cursor.Cursor) bool) { return func(yield func(inspector.Cursor) bool) {
if uses := ix.uses[obj]; uses != nil { if uses := ix.uses[obj]; uses != nil {
var last int32 var last int32
for code := uses.code; len(code) > 0; { for code := uses.code; len(code) > 0; {
delta, n := binary.Uvarint(code) delta, n := binary.Uvarint(code)
last += int32(delta) last += int32(delta)
if !yield(cursor.At(ix.inspect, last)) { if !yield(ix.inspect.At(last)) {
return return
} }
code = code[n:] code = code[n:]
@ -140,7 +139,7 @@ func (ix *Index) Used(objs ...types.Object) bool {
// Def returns the Cursor of the [*ast.Ident] in this package // Def returns the Cursor of the [*ast.Ident] in this package
// that declares the specified object, if any. // that declares the specified object, if any.
func (ix *Index) Def(obj types.Object) (cursor.Cursor, bool) { func (ix *Index) Def(obj types.Object) (inspector.Cursor, bool) {
cur, ok := ix.def[obj] cur, ok := ix.def[obj]
return cur, ok return cur, ok
} }
@ -176,8 +175,8 @@ func (ix *Index) Selection(path, typename, name string) types.Object {
// Calls returns the sequence of cursors for *ast.CallExpr nodes that // Calls returns the sequence of cursors for *ast.CallExpr nodes that
// call the specified callee, as defined by [typeutil.Callee]. // call the specified callee, as defined by [typeutil.Callee].
// If callee is nil, the sequence is empty. // If callee is nil, the sequence is empty.
func (ix *Index) Calls(callee types.Object) iter.Seq[cursor.Cursor] { func (ix *Index) Calls(callee types.Object) iter.Seq[inspector.Cursor] {
return func(yield func(cursor.Cursor) bool) { return func(yield func(inspector.Cursor) bool) {
for cur := range ix.Uses(callee) { for cur := range ix.Uses(callee) {
ek, _ := cur.ParentEdge() ek, _ := cur.ParentEdge()

View file

@ -69,6 +69,34 @@ func NameRelativeTo(pkg *types.Package) types.Qualifier {
} }
} }
// TypeNameFor returns the type name symbol for the specified type, if
// it is a [*types.Alias], [*types.Named], [*types.TypeParam], or a
// [*types.Basic] representing a type.
//
// For all other types, and for Basic types representing a builtin,
// constant, or nil, it returns nil. Be careful not to convert the
// resulting nil pointer to a [types.Object]!
//
// If t is the type of a constant, it may be an "untyped" type, which
// has no TypeName. To access the name of such types (e.g. "untyped
// int"), use [types.Basic.Name].
func TypeNameFor(t types.Type) *types.TypeName {
switch t := t.(type) {
case *types.Alias:
return t.Obj()
case *types.Named:
return t.Obj()
case *types.TypeParam:
return t.Obj()
case *types.Basic:
// See issues #71886 and #66890 for some history.
if tname, ok := types.Universe.Lookup(t.Name()).(*types.TypeName); ok {
return tname
}
}
return nil
}
// A NamedOrAlias is a [types.Type] that is named (as // A NamedOrAlias is a [types.Type] that is named (as
// defined by the spec) and capable of bearing type parameters: it // defined by the spec) and capable of bearing type parameters: it
// abstracts aliases ([types.Alias]) and defined types // abstracts aliases ([types.Alias]) and defined types
@ -77,7 +105,7 @@ func NameRelativeTo(pkg *types.Package) types.Qualifier {
// Every type declared by an explicit "type" declaration is a // Every type declared by an explicit "type" declaration is a
// NamedOrAlias. (Built-in type symbols may additionally // NamedOrAlias. (Built-in type symbols may additionally
// have type [types.Basic], which is not a NamedOrAlias, // have type [types.Basic], which is not a NamedOrAlias,
// though the spec regards them as "named".) // though the spec regards them as "named"; see [TypeNameFor].)
// //
// NamedOrAlias cannot expose the Origin method, because // NamedOrAlias cannot expose the Origin method, because
// [types.Alias.Origin] and [types.Named.Origin] have different // [types.Alias.Origin] and [types.Named.Origin] have different
@ -85,32 +113,15 @@ func NameRelativeTo(pkg *types.Package) types.Qualifier {
type NamedOrAlias interface { type NamedOrAlias interface {
types.Type types.Type
Obj() *types.TypeName Obj() *types.TypeName
// TODO(hxjiang): add method TypeArgs() *types.TypeList after stop supporting go1.22. TypeArgs() *types.TypeList
TypeParams() *types.TypeParamList
SetTypeParams(tparams []*types.TypeParam)
} }
// TypeParams is a light shim around t.TypeParams(). var (
// (go/types.Alias).TypeParams requires >= 1.23. _ NamedOrAlias = (*types.Alias)(nil)
func TypeParams(t NamedOrAlias) *types.TypeParamList { _ NamedOrAlias = (*types.Named)(nil)
switch t := t.(type) { )
case *types.Alias:
return aliases.TypeParams(t)
case *types.Named:
return t.TypeParams()
}
return nil
}
// TypeArgs is a light shim around t.TypeArgs().
// (go/types.Alias).TypeArgs requires >= 1.23.
func TypeArgs(t NamedOrAlias) *types.TypeList {
switch t := t.(type) {
case *types.Alias:
return aliases.TypeArgs(t)
case *types.Named:
return t.TypeArgs()
}
return nil
}
// Origin returns the generic type of the Named or Alias type t if it // Origin returns the generic type of the Named or Alias type t if it
// is instantiated, otherwise it returns t. // is instantiated, otherwise it returns t.

View file

@ -16,8 +16,8 @@ github.com/google/pprof/third_party/svgpan
# github.com/ianlancetaylor/demangle v0.0.0-20240912202439-0a2b6291aafd # github.com/ianlancetaylor/demangle v0.0.0-20240912202439-0a2b6291aafd
## explicit; go 1.13 ## explicit; go 1.13
github.com/ianlancetaylor/demangle github.com/ianlancetaylor/demangle
# golang.org/x/arch v0.14.0 # golang.org/x/arch v0.18.1-0.20250605182141-b2f4e2807dec
## explicit; go 1.18 ## explicit; go 1.23.0
golang.org/x/arch/arm/armasm golang.org/x/arch/arm/armasm
golang.org/x/arch/arm64/arm64asm golang.org/x/arch/arm64/arm64asm
golang.org/x/arch/loong64/loong64asm golang.org/x/arch/loong64/loong64asm
@ -25,10 +25,10 @@ golang.org/x/arch/ppc64/ppc64asm
golang.org/x/arch/riscv64/riscv64asm golang.org/x/arch/riscv64/riscv64asm
golang.org/x/arch/s390x/s390xasm golang.org/x/arch/s390x/s390xasm
golang.org/x/arch/x86/x86asm golang.org/x/arch/x86/x86asm
# golang.org/x/build v0.0.0-20250211223606-a5e3f75caa63 # golang.org/x/build v0.0.0-20250606033421-8c8ff6f34a83
## explicit; go 1.22.0 ## explicit; go 1.23.0
golang.org/x/build/relnote golang.org/x/build/relnote
# golang.org/x/mod v0.24.1-0.20250508140430-9d3333156f46 # golang.org/x/mod v0.25.0
## explicit; go 1.23.0 ## explicit; go 1.23.0
golang.org/x/mod/internal/lazyregexp golang.org/x/mod/internal/lazyregexp
golang.org/x/mod/modfile golang.org/x/mod/modfile
@ -39,17 +39,17 @@ golang.org/x/mod/sumdb/dirhash
golang.org/x/mod/sumdb/note golang.org/x/mod/sumdb/note
golang.org/x/mod/sumdb/tlog golang.org/x/mod/sumdb/tlog
golang.org/x/mod/zip golang.org/x/mod/zip
# golang.org/x/sync v0.13.0 # golang.org/x/sync v0.15.0
## explicit; go 1.23.0 ## explicit; go 1.23.0
golang.org/x/sync/errgroup golang.org/x/sync/errgroup
golang.org/x/sync/semaphore golang.org/x/sync/semaphore
# golang.org/x/sys v0.32.0 # golang.org/x/sys v0.33.0
## explicit; go 1.23.0 ## explicit; go 1.23.0
golang.org/x/sys/plan9 golang.org/x/sys/plan9
golang.org/x/sys/unix golang.org/x/sys/unix
golang.org/x/sys/windows golang.org/x/sys/windows
# golang.org/x/telemetry v0.0.0-20250212145848-75305293b65a # golang.org/x/telemetry v0.0.0-20250606142133-60998feb31a8
## explicit; go 1.22.0 ## explicit; go 1.23.0
golang.org/x/telemetry golang.org/x/telemetry
golang.org/x/telemetry/counter golang.org/x/telemetry/counter
golang.org/x/telemetry/counter/countertest golang.org/x/telemetry/counter/countertest
@ -60,10 +60,10 @@ golang.org/x/telemetry/internal/crashmonitor
golang.org/x/telemetry/internal/mmap golang.org/x/telemetry/internal/mmap
golang.org/x/telemetry/internal/telemetry golang.org/x/telemetry/internal/telemetry
golang.org/x/telemetry/internal/upload golang.org/x/telemetry/internal/upload
# golang.org/x/term v0.29.0 # golang.org/x/term v0.32.0
## explicit; go 1.18 ## explicit; go 1.23.0
golang.org/x/term golang.org/x/term
# golang.org/x/text v0.24.0 # golang.org/x/text v0.26.0
## explicit; go 1.23.0 ## explicit; go 1.23.0
golang.org/x/text/cases golang.org/x/text/cases
golang.org/x/text/internal golang.org/x/text/internal
@ -73,7 +73,7 @@ golang.org/x/text/internal/tag
golang.org/x/text/language golang.org/x/text/language
golang.org/x/text/transform golang.org/x/text/transform
golang.org/x/text/unicode/norm golang.org/x/text/unicode/norm
# golang.org/x/tools v0.32.1-0.20250423190156-68e94bd1775e # golang.org/x/tools v0.34.0
## explicit; go 1.23.0 ## explicit; go 1.23.0
golang.org/x/tools/cmd/bisect golang.org/x/tools/cmd/bisect
golang.org/x/tools/cover golang.org/x/tools/cover
@ -118,6 +118,7 @@ golang.org/x/tools/go/analysis/passes/unsafeptr
golang.org/x/tools/go/analysis/passes/unusedresult golang.org/x/tools/go/analysis/passes/unusedresult
golang.org/x/tools/go/analysis/passes/waitgroup golang.org/x/tools/go/analysis/passes/waitgroup
golang.org/x/tools/go/analysis/unitchecker golang.org/x/tools/go/analysis/unitchecker
golang.org/x/tools/go/ast/edge
golang.org/x/tools/go/ast/inspector golang.org/x/tools/go/ast/inspector
golang.org/x/tools/go/cfg golang.org/x/tools/go/cfg
golang.org/x/tools/go/types/objectpath golang.org/x/tools/go/types/objectpath
@ -126,8 +127,6 @@ golang.org/x/tools/internal/aliases
golang.org/x/tools/internal/analysisinternal golang.org/x/tools/internal/analysisinternal
golang.org/x/tools/internal/analysisinternal/typeindex golang.org/x/tools/internal/analysisinternal/typeindex
golang.org/x/tools/internal/astutil golang.org/x/tools/internal/astutil
golang.org/x/tools/internal/astutil/cursor
golang.org/x/tools/internal/astutil/edge
golang.org/x/tools/internal/bisect golang.org/x/tools/internal/bisect
golang.org/x/tools/internal/facts golang.org/x/tools/internal/facts
golang.org/x/tools/internal/fmtstr golang.org/x/tools/internal/fmtstr

View file

@ -3,11 +3,11 @@ module std
go 1.25 go 1.25
require ( require (
golang.org/x/crypto v0.37.0 golang.org/x/crypto v0.39.0
golang.org/x/net v0.39.0 golang.org/x/net v0.41.0
) )
require ( require (
golang.org/x/sys v0.32.0 // indirect golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.24.0 // indirect golang.org/x/text v0.26.0 // indirect
) )

View file

@ -1,8 +1,8 @@
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=

View file

@ -1608,7 +1608,7 @@ const (
http2FrameContinuation http2FrameType = 0x9 http2FrameContinuation http2FrameType = 0x9
) )
var http2frameName = map[http2FrameType]string{ var http2frameNames = [...]string{
http2FrameData: "DATA", http2FrameData: "DATA",
http2FrameHeaders: "HEADERS", http2FrameHeaders: "HEADERS",
http2FramePriority: "PRIORITY", http2FramePriority: "PRIORITY",
@ -1622,10 +1622,10 @@ var http2frameName = map[http2FrameType]string{
} }
func (t http2FrameType) String() string { func (t http2FrameType) String() string {
if s, ok := http2frameName[t]; ok { if int(t) < len(http2frameNames) {
return s return http2frameNames[t]
} }
return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", uint8(t)) return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", t)
} }
// Flags is a bitmask of HTTP/2 flags. // Flags is a bitmask of HTTP/2 flags.
@ -1693,7 +1693,7 @@ var http2flagName = map[http2FrameType]map[http2Flags]string{
// might be 0). // might be 0).
type http2frameParser func(fc *http2frameCache, fh http2FrameHeader, countError func(string), payload []byte) (http2Frame, error) type http2frameParser func(fc *http2frameCache, fh http2FrameHeader, countError func(string), payload []byte) (http2Frame, error)
var http2frameParsers = map[http2FrameType]http2frameParser{ var http2frameParsers = [...]http2frameParser{
http2FrameData: http2parseDataFrame, http2FrameData: http2parseDataFrame,
http2FrameHeaders: http2parseHeadersFrame, http2FrameHeaders: http2parseHeadersFrame,
http2FramePriority: http2parsePriorityFrame, http2FramePriority: http2parsePriorityFrame,
@ -1707,8 +1707,8 @@ var http2frameParsers = map[http2FrameType]http2frameParser{
} }
func http2typeFrameParser(t http2FrameType) http2frameParser { func http2typeFrameParser(t http2FrameType) http2frameParser {
if f := http2frameParsers[t]; f != nil { if int(t) < len(http2frameParsers) {
return f return http2frameParsers[t]
} }
return http2parseUnknownFrame return http2parseUnknownFrame
} }
@ -2081,7 +2081,7 @@ func (fr *http2Framer) ReadFrame() (http2Frame, error) {
} }
if fh.Length > fr.maxReadSize { if fh.Length > fr.maxReadSize {
if fh == http2invalidHTTP1LookingFrameHeader() { if fh == http2invalidHTTP1LookingFrameHeader() {
return nil, fmt.Errorf("http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header", err) return nil, fmt.Errorf("http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header", http2ErrFrameTooLarge)
} }
return nil, http2ErrFrameTooLarge return nil, http2ErrFrameTooLarge
} }

View file

@ -232,6 +232,17 @@ var RISCV64 struct {
HasZba bool // Address generation instructions extension HasZba bool // Address generation instructions extension
HasZbb bool // Basic bit-manipulation extension HasZbb bool // Basic bit-manipulation extension
HasZbs bool // Single-bit instructions extension HasZbs bool // Single-bit instructions extension
HasZvbb bool // Vector Basic Bit-manipulation
HasZvbc bool // Vector Carryless Multiplication
HasZvkb bool // Vector Cryptography Bit-manipulation
HasZvkt bool // Vector Data-Independent Execution Latency
HasZvkg bool // Vector GCM/GMAC
HasZvkn bool // NIST Algorithm Suite (AES/SHA256/SHA512)
HasZvknc bool // NIST Algorithm Suite with carryless multiply
HasZvkng bool // NIST Algorithm Suite with GCM
HasZvks bool // ShangMi Algorithm Suite
HasZvksc bool // ShangMi Algorithm Suite with carryless multiplication
HasZvksg bool // ShangMi Algorithm Suite with GCM
_ CacheLinePad _ CacheLinePad
} }

View file

@ -58,6 +58,15 @@ const (
riscv_HWPROBE_EXT_ZBA = 0x8 riscv_HWPROBE_EXT_ZBA = 0x8
riscv_HWPROBE_EXT_ZBB = 0x10 riscv_HWPROBE_EXT_ZBB = 0x10
riscv_HWPROBE_EXT_ZBS = 0x20 riscv_HWPROBE_EXT_ZBS = 0x20
riscv_HWPROBE_EXT_ZVBB = 0x20000
riscv_HWPROBE_EXT_ZVBC = 0x40000
riscv_HWPROBE_EXT_ZVKB = 0x80000
riscv_HWPROBE_EXT_ZVKG = 0x100000
riscv_HWPROBE_EXT_ZVKNED = 0x200000
riscv_HWPROBE_EXT_ZVKNHB = 0x800000
riscv_HWPROBE_EXT_ZVKSED = 0x1000000
riscv_HWPROBE_EXT_ZVKSH = 0x2000000
riscv_HWPROBE_EXT_ZVKT = 0x4000000
riscv_HWPROBE_KEY_CPUPERF_0 = 0x5 riscv_HWPROBE_KEY_CPUPERF_0 = 0x5
riscv_HWPROBE_MISALIGNED_FAST = 0x3 riscv_HWPROBE_MISALIGNED_FAST = 0x3
riscv_HWPROBE_MISALIGNED_MASK = 0x7 riscv_HWPROBE_MISALIGNED_MASK = 0x7
@ -99,6 +108,20 @@ func doinit() {
RISCV64.HasZba = isSet(v, riscv_HWPROBE_EXT_ZBA) RISCV64.HasZba = isSet(v, riscv_HWPROBE_EXT_ZBA)
RISCV64.HasZbb = isSet(v, riscv_HWPROBE_EXT_ZBB) RISCV64.HasZbb = isSet(v, riscv_HWPROBE_EXT_ZBB)
RISCV64.HasZbs = isSet(v, riscv_HWPROBE_EXT_ZBS) RISCV64.HasZbs = isSet(v, riscv_HWPROBE_EXT_ZBS)
RISCV64.HasZvbb = isSet(v, riscv_HWPROBE_EXT_ZVBB)
RISCV64.HasZvbc = isSet(v, riscv_HWPROBE_EXT_ZVBC)
RISCV64.HasZvkb = isSet(v, riscv_HWPROBE_EXT_ZVKB)
RISCV64.HasZvkg = isSet(v, riscv_HWPROBE_EXT_ZVKG)
RISCV64.HasZvkt = isSet(v, riscv_HWPROBE_EXT_ZVKT)
// Cryptography shorthand extensions
RISCV64.HasZvkn = isSet(v, riscv_HWPROBE_EXT_ZVKNED) &&
isSet(v, riscv_HWPROBE_EXT_ZVKNHB) && RISCV64.HasZvkb && RISCV64.HasZvkt
RISCV64.HasZvknc = RISCV64.HasZvkn && RISCV64.HasZvbc
RISCV64.HasZvkng = RISCV64.HasZvkn && RISCV64.HasZvkg
RISCV64.HasZvks = isSet(v, riscv_HWPROBE_EXT_ZVKSED) &&
isSet(v, riscv_HWPROBE_EXT_ZVKSH) && RISCV64.HasZvkb && RISCV64.HasZvkt
RISCV64.HasZvksc = RISCV64.HasZvks && RISCV64.HasZvbc
RISCV64.HasZvksg = RISCV64.HasZvks && RISCV64.HasZvkg
} }
if pairs[1].key != -1 { if pairs[1].key != -1 {
v := pairs[1].value & riscv_HWPROBE_MISALIGNED_MASK v := pairs[1].value & riscv_HWPROBE_MISALIGNED_MASK

View file

@ -16,5 +16,17 @@ func initOptions() {
{Name: "zba", Feature: &RISCV64.HasZba}, {Name: "zba", Feature: &RISCV64.HasZba},
{Name: "zbb", Feature: &RISCV64.HasZbb}, {Name: "zbb", Feature: &RISCV64.HasZbb},
{Name: "zbs", Feature: &RISCV64.HasZbs}, {Name: "zbs", Feature: &RISCV64.HasZbs},
// RISC-V Cryptography Extensions
{Name: "zvbb", Feature: &RISCV64.HasZvbb},
{Name: "zvbc", Feature: &RISCV64.HasZvbc},
{Name: "zvkb", Feature: &RISCV64.HasZvkb},
{Name: "zvkg", Feature: &RISCV64.HasZvkg},
{Name: "zvkt", Feature: &RISCV64.HasZvkt},
{Name: "zvkn", Feature: &RISCV64.HasZvkn},
{Name: "zvknc", Feature: &RISCV64.HasZvknc},
{Name: "zvkng", Feature: &RISCV64.HasZvkng},
{Name: "zvks", Feature: &RISCV64.HasZvks},
{Name: "zvksc", Feature: &RISCV64.HasZvksc},
{Name: "zvksg", Feature: &RISCV64.HasZvksg},
} }
} }

View file

@ -1,4 +1,4 @@
# golang.org/x/crypto v0.37.0 # golang.org/x/crypto v0.39.0
## explicit; go 1.23.0 ## explicit; go 1.23.0
golang.org/x/crypto/chacha20 golang.org/x/crypto/chacha20
golang.org/x/crypto/chacha20poly1305 golang.org/x/crypto/chacha20poly1305
@ -6,7 +6,7 @@ golang.org/x/crypto/cryptobyte
golang.org/x/crypto/cryptobyte/asn1 golang.org/x/crypto/cryptobyte/asn1
golang.org/x/crypto/internal/alias golang.org/x/crypto/internal/alias
golang.org/x/crypto/internal/poly1305 golang.org/x/crypto/internal/poly1305
# golang.org/x/net v0.39.0 # golang.org/x/net v0.41.0
## explicit; go 1.23.0 ## explicit; go 1.23.0
golang.org/x/net/dns/dnsmessage golang.org/x/net/dns/dnsmessage
golang.org/x/net/http/httpguts golang.org/x/net/http/httpguts
@ -15,10 +15,10 @@ golang.org/x/net/http2/hpack
golang.org/x/net/idna golang.org/x/net/idna
golang.org/x/net/lif golang.org/x/net/lif
golang.org/x/net/nettest golang.org/x/net/nettest
# golang.org/x/sys v0.32.0 # golang.org/x/sys v0.33.0
## explicit; go 1.23.0 ## explicit; go 1.23.0
golang.org/x/sys/cpu golang.org/x/sys/cpu
# golang.org/x/text v0.24.0 # golang.org/x/text v0.26.0
## explicit; go 1.23.0 ## explicit; go 1.23.0
golang.org/x/text/secure/bidirule golang.org/x/text/secure/bidirule
golang.org/x/text/transform golang.org/x/text/transform