Compare commits

..

2 Commits

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

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

45
.github/ISSUE_TEMPLATE/00-bug.md vendored Normal file
View File

@@ -0,0 +1,45 @@
---
name: Bugs
about: The go command, standard library, or anything else
title: "affected/package: "
---
<!--
Please answer these questions before submitting your issue. Thanks!
-->
### What version of Go are you using (`go version`)?
<pre>
$ go version
</pre>
### Does this issue reproduce with the latest release?
### What operating system and processor architecture are you using (`go env`)?
<details><summary><code>go env</code> Output</summary><br><pre>
$ go env
</pre></details>
### What did you do?
<!--
If possible, provide a recipe for reproducing the error.
A complete runnable program is good.
A link on go.dev/play is best.
-->
### What did you expect to see?
### What did you see instead?

View File

@@ -1,94 +0,0 @@
# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#creating-issue-forms
# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
name: Bugs
description: The go command, standard library, or anything else
title: "import/path: issue title"
body:
- type: markdown
attributes:
value: |
Thanks for helping us improve! 🙏 Please answer these questions and provide as much information as possible about your problem.
- type: input
id: go-version
attributes:
label: Go version
description: |
What version of Go are you using (`go version`)?
Note: we only [support](https://go.dev/doc/devel/release#policy) the two most recent major releases.
placeholder: ex. go version go1.20.7 darwin/arm64
validations:
required: true
- type: textarea
id: go-env
attributes:
label: "Output of `go env` in your module/workspace:"
placeholder: |
GO111MODULE=""
GOARCH="arm64"
GOBIN="/Users/gopher/go/bin"
GOCACHE="/Users/gopher/go/cache"
GOENV="/Users/gopher/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/gopher/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/gopher/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="go1.20.7"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/44/nbbyll_10jd0z8rj_qxm43740000gn/T/go-build2331607515=/tmp/go-build -gno-record-gcc-switches -fno-common"
render: shell
validations:
required: true
- type: textarea
id: what-did-you-do
attributes:
label: "What did you do?"
description: "If possible, provide a recipe for reproducing the error. A complete runnable program is good. A link on [go.dev/play](https://go.dev/play) is best."
validations:
required: true
- type: textarea
id: actual-behavior
attributes:
label: "What did you see happen?"
description: Command invocations and their associated output, functions with their arguments and return results, full stacktraces for panics (upload a file if it is very long), etc. Prefer copying text output over using screenshots.
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: "What did you expect to see?"
description: Why is the current output incorrect, and any additional context we may need to understand the issue.
validations:
required: true

49
.github/ISSUE_TEMPLATE/01-pkgsite.md vendored Normal file
View File

@@ -0,0 +1,49 @@
---
name: Pkg.go.dev bugs or feature requests
about: Issues or feature requests for the documentation site
title: "x/pkgsite: "
labels: pkgsite
---
<!--
Please answer these questions before submitting your issue. Thanks!
-->
### What is the URL of the page with the issue?
### What is your user agent?
<!--
You can find your user agent here:
https://www.google.com/search?q=what+is+my+user+agent
-->
### Screenshot
<!--
Please paste a screenshot of the page.
-->
### What did you do?
<!--
If possible, provide a recipe for reproducing the error.
Starting with a Private/Incognito tab/window may help rule out problematic browser extensions.
-->
### What did you expect to see?
### What did you see instead?

View File

@@ -1,47 +0,0 @@
name: Pkg.go.dev bugs or feature requests
description: Issues or feature requests for the documentation site
title: "x/pkgsite: issue title"
labels: ["pkgsite"]
body:
- type: markdown
attributes:
value: "Please answer these questions before submitting your issue. Thanks!"
- type: input
id: url
attributes:
label: "What is the URL of the page with the issue?"
validations:
required: true
- type: input
id: user-agent
attributes:
label: "What is your user agent?"
description: "You can find your user agent here: https://www.google.com/search?q=what+is+my+user+agent"
validations:
required: true
- type: textarea
id: screenshot
attributes:
label: "Screenshot"
description: "Please paste a screenshot of the page."
validations:
required: false
- type: textarea
id: what-did-you-do
attributes:
label: "What did you do?"
description: "If possible, provide a recipe for reproducing the error. Starting with a Private/Incognito tab/window may help rule out problematic browser extensions."
validations:
required: true
- type: textarea
id: actual-behavior
attributes:
label: "What did you see happen?"
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: "What did you expect to see?"
validations:
required: true

View File

@@ -0,0 +1,39 @@
---
name: Pkg.go.dev package removal request
about: Request a package be removed from the documentation site (pkg.go.dev)
title: "x/pkgsite: package removal request for [type path here]"
labels: pkgsite/package-removal
---
<!--
Please answer these questions before submitting your issue. Thanks!
-->
### What is the path of the package that you would like to have removed?
<!---
We can remove packages with a shared path prefix.
For example, a request for "github.com/author" would remove all pkg.go.dev pages with that package path prefix.
--->
### Are you the owner of this package?
<!---
Only the package owners can request to have their packages removed from pkg.go.dev.
--->
### What is the reason that you could not retract this package instead?
<!---
If you would like to have your module removed from pkg.go.dev, we recommend that you retract them, so that they can be removed from the go command and proxy.golang.org as well.
Retracting a module version involves adding a retract directive to your go.mod file and publishing a new version. For example: https://github.com/jba/retract-demo/blob/main/go.mod#L5-L8
See https://pkg.go.dev/about#removing-a-package for additional tips on retractions.
--->

View File

@@ -1,42 +0,0 @@
name: Pkg.go.dev package removal request
description: Request a package be removed from the documentation site (pkg.go.dev)
title: "x/pkgsite: package removal request for [type path here]"
labels: ["pkgsite/package-removal"]
body:
- type: markdown
attributes:
value: "Please answer these questions before submitting your issue. Thanks!"
- type: input
id: package-path
attributes:
label: "What is the path of the package that you would like to have removed?"
description: |
We can remove packages with a shared path prefix.
For example, a request for 'github.com/author' would remove all pkg.go.dev pages with that package path prefix.
validations:
required: true
- type: textarea
id: package-owner
attributes:
label: "Are you the owner of this package?"
description: |
Only the package owners can request to have their packages removed from pkg.go.dev.
If the package path doesn't include your github username, please provide some other form of proof of ownership.
validations:
required: true
- type: textarea
id: retraction-reason
attributes:
label: "What is the reason that you could not retract this package instead?"
description: |
Requesting we remove a module here only hides the generated documentation on pkg.go.dev.
It does not affect the behaviour of proxy.golang.org or the go command.
Instead we recommend using the retract directive which will be processed by all 3 of the above.
If you have deleted your repo, please recreate it and publish a retraction.
Retracting a module version involves adding a retract directive to your go.mod file and publishing a new version.
For example: https://github.com/jba/retract-demo/blob/main/go.mod#L5-L8.
See https://pkg.go.dev/about#removing-a-package for additional tips on retractions.
validations:
required: true

61
.github/ISSUE_TEMPLATE/03-gopls.md vendored Normal file
View File

@@ -0,0 +1,61 @@
---
name: Gopls bugs or feature requests
about: Issues or feature requests for the Go language server (gopls)
title: "x/tools/gopls: "
labels: gopls Tools
---
<!--
Please answer these questions before submitting your issue. Thanks!
-->
### gopls version
<!--
Output of `gopls -v version` on the command line
-->
### go env
<!--
Output of `go env` on the command line in your workspace directory
-->
### What did you do?
<!--
If possible, provide a recipe for reproducing the error.
A complete runnable program is good.
A link on go.dev/play is better.
A failing unit test is the best.
-->
### What did you expect to see?
### What did you see instead?
### Editor and settings
<!--
Your editor and any settings you have configured (for example, your VSCode settings.json file)
-->
### Logs
<!--
If possible please include gopls logs. Instructions for capturing them can be found here:
https://github.com/golang/tools/blob/master/gopls/doc/troubleshooting.md#capture-logs
-->

View File

@@ -1,56 +0,0 @@
name: Gopls bugs or feature requests
description: Issues or feature requests for the Go language server (gopls)
title: "x/tools/gopls: issue title"
labels: ["gopls", "Tools"]
body:
- type: markdown
attributes:
value: "Please answer these questions before submitting your issue. Thanks!"
- type: input
id: gopls-version
attributes:
label: "gopls version"
description: "Output of `gopls -v version` on the command line"
validations:
required: true
- type: textarea
id: go-env
attributes:
label: "go env"
description: "Output of `go env` on the command line in your workspace directory"
render: shell
validations:
required: true
- type: textarea
id: what-did-you-do
attributes:
label: "What did you do?"
description: "If possible, provide a recipe for reproducing the error. A complete runnable program is good. A link on [go.dev/play](https://go.dev/play) is better. A failing unit test is the best."
validations:
required: true
- type: textarea
id: actual-behavior
attributes:
label: "What did you see happen?"
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: "What did you expect to see?"
validations:
required: true
- type: textarea
id: editor-and-settings
attributes:
label: "Editor and settings"
description: "Your editor and any settings you have configured (for example, your VSCode settings.json file)"
validations:
required: false
- type: textarea
id: logs
attributes:
label: "Logs"
description: "If possible please include gopls logs. Instructions for capturing them can be found here: https://github.com/golang/tools/blob/master/gopls/doc/troubleshooting.md#capture-logs"
validations:
required: false

51
.github/ISSUE_TEMPLATE/04-vuln.md vendored Normal file
View File

@@ -0,0 +1,51 @@
---
name: Go vulnerability management - bugs and feature requests
about: Issues or feature requests about Go vulnerability management
title: "x/vuln: "
labels: "vulncheck or vulndb"
---
<!--
Please answer these questions before submitting your issue. Thanks!
To add a new vulnerability to the Go vulnerability database
(https://vuln.go.dev), see https://go.dev/s/vulndb-report-new.
To report an issue about a report, see https://go.dev/s/vulndb-report-feedback.
-->
### What version of Go are you using (`go version`)?
<pre>
$ go version
</pre>
### Does this issue reproduce at the latest version of golang.org/x/vuln?
### What operating system and processor architecture are you using (`go env`)?
<details><summary><code>go env</code> Output</summary><br><pre>
$ go env
</pre></details>
### What did you do?
<!--
If possible, provide a recipe for reproducing the error.
A complete runnable program is good.
A link on go.dev/play is best.
-->
### What did you expect to see?
### What did you see instead?

View File

@@ -1,52 +0,0 @@
name: Go vulnerability management - bugs and feature requests
description: Issues or feature requests about Go vulnerability management
title: "x/vuln: issue title"
labels: ["vulncheck or vulndb"]
body:
- type: markdown
attributes:
value: "Please answer these questions before submitting your issue. Thanks! To add a new vulnerability to the Go vulnerability database (https://vuln.go.dev), see https://go.dev/s/vulndb-report-new. To report an issue about a report, see https://go.dev/s/vulndb-report-feedback."
- type: textarea
id: govulncheck-version
attributes:
label: govulncheck version
description: What version of govulncheck are you using (`govulncheck -version`)?
placeholder: |
Go: devel go1.22-0262ea1ff9 Thu Oct 26 18:46:50 2023 +0000
Scanner: govulncheck@v1.0.2-0.20231108200754-fcf7dff7b242
DB: https://vuln.go.dev
DB updated: 2023-11-21 15:39:17 +0000 UTC
validations:
required: true
- type: textarea
id: reproduce-latest-version
attributes:
label: "Does this issue reproduce at the latest version of golang.org/x/vuln?"
validations:
required: true
- type: textarea
id: go-env
attributes:
label: "Output of `go env` in your module/workspace:"
render: shell
validations:
required: true
- type: textarea
id: what-did-you-do
attributes:
label: "What did you do?"
description: "If possible, provide a recipe for reproducing the error. A complete runnable program is good. A link on [go.dev/play](https://go.dev/play) is best."
validations:
required: true
- type: textarea
id: actual-behavior
attributes:
label: "What did you see happen?"
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: "What did you expect to see?"
validations:
required: true

13
.github/ISSUE_TEMPLATE/10-proposal.md vendored Normal file
View File

@@ -0,0 +1,13 @@
---
name: Proposals
about: New external API or other notable changes
title: "proposal: affected/package: "
labels: Proposal
---
<!--
Our proposal process is documented here:
https://go.dev/s/proposal-process
-->

View File

@@ -1,15 +0,0 @@
name: Proposals
description: New external API or other notable changes
title: "proposal: import/path: proposal title"
labels: ["Proposal"]
body:
- type: markdown
attributes:
value: "Our proposal process is documented here: https://go.dev/s/proposal-process"
- type: textarea
id: proposal-details
attributes:
label: "Proposal Details"
description: "Please provide the details of your proposal here."
validations:
required: true

View File

@@ -0,0 +1,52 @@
---
name: Language Change Proposals
about: Changes to the language
title: "proposal: Go 2: "
labels: Proposal Go2 LanguageChange
---
<!--
Our process for evaluating language changes can be found here:
https://go.googlesource.com/proposal/+/refs/heads/master#language-changes
-->
### Author background
- **Would you consider yourself a novice, intermediate, or experienced Go programmer?**
- **What other languages do you have experience with?**
### Related proposals
- **Has this idea, or one like it, been proposed before?**
- **If so, how does this proposal differ?**
- **Does this affect error handling?**
- **If so, how does this differ from previous error handling proposals?**
- **Is this about generics?**
- **If so, how does this relate to the accepted design and other generics proposals?**
### Proposal
- **What is the proposed change?**
- **Who does this proposal help, and why?**
- **Please describe as precisely as possible the change to the language.**
- **What would change in the language spec?**
- **Please also describe the change informally, as in a class teaching Go.**
- **Is this change backward compatible?**
- Breaking the Go 1 compatibility guarantee is a large cost and requires a large benefit.
Show example code before and after the change.
- **Before**
- **After**
- **Orthogonality: how does this change interact or overlap with existing features?**
- **Is the goal of this change a performance improvement?**
- **If so, what quantifiable improvement should we expect?**
- **How would we measure it?**
### Costs
- **Would this change make Go easier or harder to learn, and why?**
- **What is the cost of this proposal? (Every language change has a cost).**
- **How many tools (such as vet, gopls, gofmt, goimports, etc.) would be affected?**
- **What is the compile time cost?**
- **What is the run time cost?**
- **Can you describe a possible implementation?**
- **Do you have a prototype? (This is not required.)**

View File

@@ -1,165 +0,0 @@
name: Language Change Proposals
description: Changes to the language
labels: ["Proposal", "v2", "LanguageChange"]
title: "proposal: Go 2: proposal title"
body:
- type: markdown
attributes:
value: |
## Our process for evaluating language changes can be found [here](https://go.googlesource.com/proposal/+/refs/heads/master#language-changes)
- type: dropdown
id: author-go-experience
attributes:
label: "Go Programming Experience"
description: "Would you consider yourself a novice, intermediate, or experienced Go programmer?"
options:
- "Novice"
- "Intermediate"
- "Experienced"
default: 1
- type: input
id: author-other-languages-experience
attributes:
label: "Other Languages Experience"
description: "What other languages do you have experience with?"
placeholder: "Go, Python, JS, Rust"
validations:
required: false
- type: checkboxes
id: related-idea
attributes:
label: "Related Idea"
options:
- label: "Has this idea, or one like it, been proposed before?"
- label: "Does this affect error handling?"
- label: "Is this about generics?"
- label: "Is this change backward compatible? Breaking the Go 1 compatibility guarantee is a large cost and requires a large benefit"
- type: textarea
id: related-proposals
attributes:
label: Has this idea, or one like it, been proposed before?
description: If so, how does this proposal differ?
placeholder: |
Yes or No
If yes,
1. Mention the related proposals
2. then describe how this proposal differs
validations:
required: true
- type: textarea
id: error-handling-proposal
attributes:
label: Does this affect error handling?
description: If so, how does this differ from previous error handling proposals?
placeholder: |
Yes or No
If yes,
1.how does this differ from previous error handling proposals?
validations:
required: true
- type: textarea
id: generics-proposal
attributes:
label: Is this about generics?
description: If so, how does this relate to the accepted design and other generics proposals?
placeholder: |
Yes or No
If yes,
1. how does this relate to the accepted design and other generics proposals?
validations:
required: true
- type: textarea
id: proposal
attributes:
label: "Proposal"
description: "What is the proposed change? Who does this proposal help, and why? Please describe as precisely as possible the change to the language."
validations:
required: true
- type: textarea
id: language-spec-changes
attributes:
label: "Language Spec Changes"
description: "What would change in the language spec?"
validations:
required: false
- type: textarea
id: informal-change
attributes:
label: "Informal Change"
description: "Please also describe the change informally, as in a class teaching Go."
validations:
required: false
- type: textarea
id: go-backwards-compatiblity
attributes:
label: Is this change backward compatible?
description: Breaking the Go 1 compatibility guarantee is a large cost and requires a large benefit.
placeholder: |
Yes or No
If yes,
1. Show example code before and after the change.
validations:
required: true
- type: textarea
id: orthogonality
attributes:
label: "Orthogonality: How does this change interact or overlap with existing features?"
description: "Is the goal of this change a performance improvement? If so, what quantifiable improvement should we expect? How would we measure it?"
validations:
required: false
- type: textarea
id: learning-curve
attributes:
label: "Would this change make Go easier or harder to learn, and why?"
- type: textarea
id: cost-description
attributes:
label: "Cost Description"
description: "What is the cost of this proposal? (Every language change has a cost)"
- type: input
id: go-toolchain
attributes:
label: Changes to Go ToolChain
description: "How many tools (such as vet, gopls, gofmt, goimports, etc.) would be affected? "
validations:
required: false
- type: input
id: perf-costs
attributes:
label: Performance Costs
description: "What is the compile time cost? What is the run time cost? "
validations:
required: false
- type: textarea
id: prototype
attributes:
label: "Prototype"
description: "Can you describe a possible implementation?"
validations:
required: false

View File

@@ -1,68 +0,0 @@
name: Go Telemetry Proposals
description: New telemetry counter or update on an existing one
title: "x/telemetry/config: proposal title"
labels: ["Telemetry-Proposal"]
projects: ["golang/29"]
body:
- type: textarea
attributes:
label: Counter names
description: Names of counters to add or update.
validations:
required: true
- type: textarea
attributes:
label: Description
description: What do these counters measure?
validations:
required: true
- type: textarea
attributes:
label: Rationale
description: |
Why is the counter important?
For example, what new insights will it provide, and how will that information be used?
If this is about updating existing counters, why is the change necessary?
validations:
required: true
- type: textarea
attributes:
label: Do the counters carry sensitive user information?
validations:
required: true
- type: textarea
attributes:
label: How?
description: |
How do we plan to compute the info?
If available, include the code location or cl that uses the golang.org/x/telemetry/counter API.
validations:
required: true
- type: textarea
attributes:
label: Proposed Graph Config
description: |
Approved telemetry counters are maintained as [Go Telemetry Graph Config](https://golang.org/x/telemetry/internal/graphconfig) records.
Please draft the record entry for your proposal here.
If multiple records need to be included, separate them with `---` lines.
You can check the list of the approved counters and their current configuration in [config.txt](https://go.googlesource.com/telemetry/+/master/internal/configgen/config.txt).
render: Text
value: |
counter: gopls/bug
title: Gopls bug reports
description: Stacks of bugs encountered on the gopls server.
type: partition, histogram, stack # choose only one.
program: golang.org/x/tools/gopls
counter: gopls/bug
depth: 16 # only if type is stack.
version: v0.13.0 # the first binary version containing this counter.
validations:
required: true
- type: dropdown
attributes:
label: New or Update
description: Is this a new counter? See [config.txt](https://go.googlesource.com/telemetry/+/master/internal/configgen/config.txt) for the list of approved counters.
options:
- New
- Update
default: 0

View File

@@ -1,4 +1,4 @@
blank_issues_enabled: true
blank_issues_enabled: false
contact_links:
- name: Questions
about: Please use one of the forums for questions or general discussions

View File

@@ -10,4 +10,4 @@ part of that page.
## Reporting a Vulnerability
See https://go.dev/security/policy for how to report a vulnerability.
See https://go.dev/security for how to report a vulnerability.

View File

@@ -1,2 +0,0 @@
go1.22.12
time 2025-01-31T18:38:03Z

View File

@@ -60,9 +60,7 @@ pkg crypto/tls, method (*QUICConn) Close() error #44886
pkg crypto/tls, method (*QUICConn) ConnectionState() ConnectionState #44886
pkg crypto/tls, method (*QUICConn) HandleData(QUICEncryptionLevel, []uint8) error #44886
pkg crypto/tls, method (*QUICConn) NextEvent() QUICEvent #44886
pkg crypto/tls, method (*QUICConn) SendSessionTicket(QUICSessionTicketOptions) error #60107
pkg crypto/tls, type QUICSessionTicketOptions struct #60107
pkg crypto/tls, type QUICSessionTicketOptions struct, EarlyData bool #60107
pkg crypto/tls, method (*QUICConn) SendSessionTicket(bool) error #60107
pkg crypto/tls, method (*QUICConn) SetTransportParameters([]uint8) #44886
pkg crypto/tls, method (*QUICConn) Start(context.Context) error #44886
pkg crypto/tls, method (QUICEncryptionLevel) String() string #44886
@@ -167,12 +165,7 @@ pkg errors, var ErrUnsupported error #41198
pkg flag, func BoolFunc(string, string, func(string) error) #53747
pkg flag, method (*FlagSet) BoolFunc(string, string, func(string) error) #53747
pkg go/ast, func IsGenerated(*File) bool #28089
pkg go/ast, func NewPackage //deprecated #52463
pkg go/ast, type File struct, GoVersion string #59033
pkg go/ast, type Importer //deprecated #52463
pkg go/ast, type Object //deprecated #52463
pkg go/ast, type Package //deprecated #52463
pkg go/ast, type Scope //deprecated #52463
pkg go/build/constraint, func GoVersion(Expr) string #59033
pkg go/build, type Directive struct #56986
pkg go/build, type Directive struct, Pos token.Position #56986
@@ -226,18 +219,18 @@ pkg log/slog, func Any(string, interface{}) Attr #56345
pkg log/slog, func AnyValue(interface{}) Value #56345
pkg log/slog, func Bool(string, bool) Attr #56345
pkg log/slog, func BoolValue(bool) Value #56345
pkg log/slog, func DebugContext(context.Context, string, ...interface{}) #61200
pkg log/slog, func DebugCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, func Debug(string, ...interface{}) #56345
pkg log/slog, func Default() *Logger #56345
pkg log/slog, func Duration(string, time.Duration) Attr #56345
pkg log/slog, func DurationValue(time.Duration) Value #56345
pkg log/slog, func ErrorContext(context.Context, string, ...interface{}) #61200
pkg log/slog, func ErrorCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, func Error(string, ...interface{}) #56345
pkg log/slog, func Float64(string, float64) Attr #56345
pkg log/slog, func Float64Value(float64) Value #56345
pkg log/slog, func Group(string, ...interface{}) Attr #59204
pkg log/slog, func GroupValue(...Attr) Value #56345
pkg log/slog, func InfoContext(context.Context, string, ...interface{}) #61200
pkg log/slog, func InfoCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, func Info(string, ...interface{}) #56345
pkg log/slog, func Int64(string, int64) Attr #56345
pkg log/slog, func Int64Value(int64) Value #56345
@@ -257,7 +250,7 @@ pkg log/slog, func Time(string, time.Time) Attr #56345
pkg log/slog, func TimeValue(time.Time) Value #56345
pkg log/slog, func Uint64(string, uint64) Attr #56345
pkg log/slog, func Uint64Value(uint64) Value #56345
pkg log/slog, func WarnContext(context.Context, string, ...interface{}) #61200
pkg log/slog, func WarnCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, func Warn(string, ...interface{}) #56345
pkg log/slog, func With(...interface{}) *Logger #56345
pkg log/slog, method (Attr) Equal(Attr) bool #56345
@@ -278,17 +271,17 @@ pkg log/slog, method (*LevelVar) MarshalText() ([]uint8, error) #56345
pkg log/slog, method (*LevelVar) Set(Level) #56345
pkg log/slog, method (*LevelVar) String() string #56345
pkg log/slog, method (*LevelVar) UnmarshalText([]uint8) error #56345
pkg log/slog, method (*Logger) DebugContext(context.Context, string, ...interface{}) #61200
pkg log/slog, method (*Logger) DebugCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, method (*Logger) Debug(string, ...interface{}) #56345
pkg log/slog, method (*Logger) Enabled(context.Context, Level) bool #56345
pkg log/slog, method (*Logger) ErrorContext(context.Context, string, ...interface{}) #61200
pkg log/slog, method (*Logger) ErrorCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, method (*Logger) Error(string, ...interface{}) #56345
pkg log/slog, method (*Logger) Handler() Handler #56345
pkg log/slog, method (*Logger) InfoContext(context.Context, string, ...interface{}) #61200
pkg log/slog, method (*Logger) InfoCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, method (*Logger) Info(string, ...interface{}) #56345
pkg log/slog, method (*Logger) LogAttrs(context.Context, Level, string, ...Attr) #56345
pkg log/slog, method (*Logger) Log(context.Context, Level, string, ...interface{}) #56345
pkg log/slog, method (*Logger) WarnContext(context.Context, string, ...interface{}) #61200
pkg log/slog, method (*Logger) WarnCtx(context.Context, string, ...interface{}) #56345
pkg log/slog, method (*Logger) Warn(string, ...interface{}) #56345
pkg log/slog, method (*Logger) WithGroup(string) *Logger #56345
pkg log/slog, method (*Logger) With(...interface{}) *Logger #56345
@@ -351,6 +344,8 @@ pkg maps, func Copy[$0 interface{ ~map[$2]$3 }, $1 interface{ ~map[$2]$3 }, $2 c
pkg maps, func DeleteFunc[$0 interface{ ~map[$1]$2 }, $1 comparable, $2 interface{}]($0, func($1, $2) bool) #57436
pkg maps, func Equal[$0 interface{ ~map[$2]$3 }, $1 interface{ ~map[$2]$3 }, $2 comparable, $3 comparable]($0, $1) bool #57436
pkg maps, func EqualFunc[$0 interface{ ~map[$2]$3 }, $1 interface{ ~map[$2]$4 }, $2 comparable, $3 interface{}, $4 interface{}]($0, $1, func($3, $4) bool) bool #57436
pkg maps, func Keys[$0 interface{ ~map[$1]$2 }, $1 comparable, $2 interface{}]($0) []$1 #57436
pkg maps, func Values[$0 interface{ ~map[$1]$2 }, $1 comparable, $2 interface{}]($0) []$2 #57436
pkg math/big, method (*Int) Float64() (float64, Accuracy) #56984
pkg net/http, method (*ProtocolError) Is(error) bool #41198
pkg net/http, method (*ResponseController) EnableFullDuplex() error #57786

View File

@@ -1,135 +0,0 @@
pkg archive/tar, method (*Writer) AddFS(fs.FS) error #58000
pkg archive/zip, method (*Writer) AddFS(fs.FS) error #54898
pkg cmp, func Or[$0 comparable](...$0) $0 #60204
pkg crypto/x509, func OIDFromInts([]uint64) (OID, error) #60665
pkg crypto/x509, method (*CertPool) AddCertWithConstraint(*Certificate, func([]*Certificate) error) #57178
pkg crypto/x509, method (OID) Equal(OID) bool #60665
pkg crypto/x509, method (OID) EqualASN1OID(asn1.ObjectIdentifier) bool #60665
pkg crypto/x509, method (OID) String() string #60665
pkg crypto/x509, type Certificate struct, Policies []OID #60665
pkg crypto/x509, type OID struct #60665
pkg database/sql, method (*Null[$0]) Scan(interface{}) error #60370
pkg database/sql, method (Null[$0]) Value() (driver.Value, error) #60370
pkg database/sql, type Null[$0 interface{}] struct #60370
pkg database/sql, type Null[$0 interface{}] struct, V $0 #60370
pkg database/sql, type Null[$0 interface{}] struct, Valid bool #60370
pkg debug/elf, const R_LARCH_64_PCREL = 109 #63725
pkg debug/elf, const R_LARCH_64_PCREL R_LARCH #63725
pkg debug/elf, const R_LARCH_ADD6 = 105 #63725
pkg debug/elf, const R_LARCH_ADD6 R_LARCH #63725
pkg debug/elf, const R_LARCH_ADD_ULEB128 = 107 #63725
pkg debug/elf, const R_LARCH_ADD_ULEB128 R_LARCH #63725
pkg debug/elf, const R_LARCH_ALIGN = 102 #63725
pkg debug/elf, const R_LARCH_ALIGN R_LARCH #63725
pkg debug/elf, const R_LARCH_CFA = 104 #63725
pkg debug/elf, const R_LARCH_CFA R_LARCH #63725
pkg debug/elf, const R_LARCH_DELETE = 101 #63725
pkg debug/elf, const R_LARCH_DELETE R_LARCH #63725
pkg debug/elf, const R_LARCH_PCREL20_S2 = 103 #63725
pkg debug/elf, const R_LARCH_PCREL20_S2 R_LARCH #63725
pkg debug/elf, const R_LARCH_SUB6 = 106 #63725
pkg debug/elf, const R_LARCH_SUB6 R_LARCH #63725
pkg debug/elf, const R_LARCH_SUB_ULEB128 = 108 #63725
pkg debug/elf, const R_LARCH_SUB_ULEB128 R_LARCH #63725
pkg debug/elf, const R_MIPS_PC32 = 248 #61974
pkg debug/elf, const R_MIPS_PC32 R_MIPS #61974
pkg encoding/base32, method (*Encoding) AppendDecode([]uint8, []uint8) ([]uint8, error) #53693
pkg encoding/base32, method (*Encoding) AppendEncode([]uint8, []uint8) []uint8 #53693
pkg encoding/base64, method (*Encoding) AppendDecode([]uint8, []uint8) ([]uint8, error) #53693
pkg encoding/base64, method (*Encoding) AppendEncode([]uint8, []uint8) []uint8 #53693
pkg encoding/hex, func AppendDecode([]uint8, []uint8) ([]uint8, error) #53693
pkg encoding/hex, func AppendEncode([]uint8, []uint8) []uint8 #53693
pkg go/ast, func NewPackage //deprecated #52463
pkg go/ast, func Unparen(Expr) Expr #60061
pkg go/ast, type Importer //deprecated #52463
pkg go/ast, type Object //deprecated #52463
pkg go/ast, type Package //deprecated #52463
pkg go/ast, type Scope //deprecated #52463
pkg go/types, func NewAlias(*TypeName, Type) *Alias #63223
pkg go/types, func Unalias(Type) Type #63223
pkg go/types, method (*Alias) Obj() *TypeName #63223
pkg go/types, method (*Alias) String() string #63223
pkg go/types, method (*Alias) Underlying() Type #63223
pkg go/types, method (*Info) PkgNameOf(*ast.ImportSpec) *PkgName #62037
pkg go/types, method (Checker) PkgNameOf(*ast.ImportSpec) *PkgName #62037
pkg go/types, type Alias struct #63223
pkg go/types, type Info struct, FileVersions map[*ast.File]string #62605
pkg go/version, func Compare(string, string) int #62039
pkg go/version, func IsValid(string) bool #62039
pkg go/version, func Lang(string) string #62039
pkg html/template, const ErrJSTemplate //deprecated #61619
pkg io, method (*SectionReader) Outer() (ReaderAt, int64, int64) #61870
pkg log/slog, func SetLogLoggerLevel(Level) Level #62418
pkg math/big, method (*Rat) FloatPrec() (int, bool) #50489
pkg math/rand/v2, func ExpFloat64() float64 #61716
pkg math/rand/v2, func Float32() float32 #61716
pkg math/rand/v2, func Float64() float64 #61716
pkg math/rand/v2, func Int() int #61716
pkg math/rand/v2, func Int32() int32 #61716
pkg math/rand/v2, func Int32N(int32) int32 #61716
pkg math/rand/v2, func Int64() int64 #61716
pkg math/rand/v2, func Int64N(int64) int64 #61716
pkg math/rand/v2, func IntN(int) int #61716
pkg math/rand/v2, func N[$0 intType]($0) $0 #61716
pkg math/rand/v2, func New(Source) *Rand #61716
pkg math/rand/v2, func NewChaCha8([32]uint8) *ChaCha8 #61716
pkg math/rand/v2, func NewPCG(uint64, uint64) *PCG #61716
pkg math/rand/v2, func NewZipf(*Rand, float64, float64, uint64) *Zipf #61716
pkg math/rand/v2, func NormFloat64() float64 #61716
pkg math/rand/v2, func Perm(int) []int #61716
pkg math/rand/v2, func Shuffle(int, func(int, int)) #61716
pkg math/rand/v2, func Uint32() uint32 #61716
pkg math/rand/v2, func Uint32N(uint32) uint32 #61716
pkg math/rand/v2, func Uint64() uint64 #61716
pkg math/rand/v2, func Uint64N(uint64) uint64 #61716
pkg math/rand/v2, func UintN(uint) uint #61716
pkg math/rand/v2, method (*ChaCha8) MarshalBinary() ([]uint8, error) #61716
pkg math/rand/v2, method (*ChaCha8) Seed([32]uint8) #61716
pkg math/rand/v2, method (*ChaCha8) Uint64() uint64 #61716
pkg math/rand/v2, method (*ChaCha8) UnmarshalBinary([]uint8) error #61716
pkg math/rand/v2, method (*PCG) MarshalBinary() ([]uint8, error) #61716
pkg math/rand/v2, method (*PCG) Seed(uint64, uint64) #61716
pkg math/rand/v2, method (*PCG) Uint64() uint64 #61716
pkg math/rand/v2, method (*PCG) UnmarshalBinary([]uint8) error #61716
pkg math/rand/v2, method (*Rand) ExpFloat64() float64 #61716
pkg math/rand/v2, method (*Rand) Float32() float32 #61716
pkg math/rand/v2, method (*Rand) Float64() float64 #61716
pkg math/rand/v2, method (*Rand) Int() int #61716
pkg math/rand/v2, method (*Rand) Int32() int32 #61716
pkg math/rand/v2, method (*Rand) Int32N(int32) int32 #61716
pkg math/rand/v2, method (*Rand) Int64() int64 #61716
pkg math/rand/v2, method (*Rand) Int64N(int64) int64 #61716
pkg math/rand/v2, method (*Rand) IntN(int) int #61716
pkg math/rand/v2, method (*Rand) NormFloat64() float64 #61716
pkg math/rand/v2, method (*Rand) Perm(int) []int #61716
pkg math/rand/v2, method (*Rand) Shuffle(int, func(int, int)) #61716
pkg math/rand/v2, method (*Rand) Uint32() uint32 #61716
pkg math/rand/v2, method (*Rand) Uint32N(uint32) uint32 #61716
pkg math/rand/v2, method (*Rand) Uint64() uint64 #61716
pkg math/rand/v2, method (*Rand) Uint64N(uint64) uint64 #61716
pkg math/rand/v2, method (*Rand) UintN(uint) uint #61716
pkg math/rand/v2, method (*Zipf) Uint64() uint64 #61716
pkg math/rand/v2, type ChaCha8 struct #61716
pkg math/rand/v2, type PCG struct #61716
pkg math/rand/v2, type Rand struct #61716
pkg math/rand/v2, type Source interface { Uint64 } #61716
pkg math/rand/v2, type Source interface, Uint64() uint64 #61716
pkg math/rand/v2, type Zipf struct #61716
pkg net, method (*TCPConn) WriteTo(io.Writer) (int64, error) #58808
pkg net/http, func FileServerFS(fs.FS) Handler #51971
pkg net/http, func NewFileTransportFS(fs.FS) RoundTripper #51971
pkg net/http, func ServeFileFS(ResponseWriter, *Request, fs.FS, string) #51971
pkg net/http, method (*Request) PathValue(string) string #61410
pkg net/http, method (*Request) SetPathValue(string, string) #61410
pkg net/netip, method (AddrPort) Compare(AddrPort) int #61642
pkg os, method (*File) WriteTo(io.Writer) (int64, error) #58808
pkg reflect, func PtrTo //deprecated #59599
pkg reflect, func TypeFor[$0 interface{}]() Type #60088
pkg slices, func Concat[$0 interface{ ~[]$1 }, $1 interface{}](...$0) $0 #56353
pkg syscall (linux-386), type SysProcAttr struct, PidFD *int #51246
pkg syscall (linux-386-cgo), type SysProcAttr struct, PidFD *int #51246
pkg syscall (linux-amd64), type SysProcAttr struct, PidFD *int #51246
pkg syscall (linux-amd64-cgo), type SysProcAttr struct, PidFD *int #51246
pkg syscall (linux-arm), type SysProcAttr struct, PidFD *int #51246
pkg syscall (linux-arm-cgo), type SysProcAttr struct, PidFD *int #51246
pkg testing/slogtest, func Run(*testing.T, func(*testing.T) slog.Handler, func(*testing.T) map[string]interface{}) #61758

View File

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

View File

@@ -464,23 +464,6 @@ Function is the outermost frame of the call stack. Traceback should stop at this
</li>
</ul>
<h3 id="special-instructions">Special instructions</h3>
<p>
The <code>PCALIGN</code> pseudo-instruction is used to indicate that the next instruction should be aligned
to a specified boundary by padding with no-op instructions.
</p>
<p>
It is currently supported on arm64, amd64, ppc64, loong64 and riscv64.
For example, the start of the <code>MOVD</code> instruction below is aligned to 32 bytes:
<pre>
PCALIGN $32
MOVD $2, R0
</pre>
</p>
<h3 id="data-offsets">Interacting with Go types and constants</h3>
<p>

View File

@@ -7,11 +7,8 @@
<h2 id="Introduction">Introduction</h2>
<p>
This is the reference manual for the Go programming language as it was for
language version 1.17, in October 2021, before the introduction of generics.
It is provided for historical interest.
The current reference manual can be found <a href="/doc/go_spec.html">here</a>.
For more information and other documents, see <a href="/">go.dev</a>.
This is a reference manual for the Go programming language. For
more information and other documents, see <a href="/">golang.org</a>.
</p>
<p>
@@ -917,7 +914,7 @@ are required when different numeric types are mixed in an expression
or assignment. For instance, <code>int32</code> and <code>int</code>
are not the same type even though they may have the same size on a
particular architecture.
</p>
<h3 id="String_types">String types</h3>
@@ -1454,7 +1451,6 @@ maps grow to accommodate the number of items
stored in them, with the exception of <code>nil</code> maps.
A <code>nil</code> map is equivalent to an empty map except that no elements
may be added.
</p>
<h3 id="Channel_types">Channel types</h3>
@@ -3645,8 +3641,6 @@ As the <code>++</code> and <code>--</code> operators form
statements, not expressions, they fall
outside the operator hierarchy.
As a consequence, statement <code>*p++</code> is the same as <code>(*p)++</code>.
</p>
<p>
There are five precedence levels for binary operators.
Multiplication operators bind strongest, followed by addition

1246
doc/go1.21.html Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -159,7 +159,6 @@ union of the sequenced before and synchronized before relations.
For an ordinary (non-synchronizing) data read <i>r</i> on a memory location <i>x</i>,
<i>W</i>(<i>r</i>) must be a write <i>w</i> that is <i>visible</i> to <i>r</i>,
where visible means that both of the following hold:
</p>
<ol>
<li><i>w</i> happens before <i>r</i>.
@@ -222,7 +221,7 @@ for programs that do contain races.
</p>
<p>
Any implementation can, upon detecting a data race,
First, any implementation can, upon detecting a data race,
report the race and halt execution of the program.
Implementations using ThreadSanitizer
(accessed with “<code>go</code> <code>build</code> <code>-race</code>”)
@@ -230,18 +229,7 @@ do exactly this.
</p>
<p>
A read of an array, struct, or complex number
may by implemented as a read of each individual sub-value
(array element, struct field, or real/imaginary component),
in any order.
Similarly, a write of an array, struct, or complex number
may be implemented as a write of each individual sub-value,
in any order.
</p>
<p>
A read <i>r</i> of a memory location <i>x</i>
holding a value
Otherwise, a read <i>r</i> of a memory location <i>x</i>
that is not larger than a machine word must observe
some write <i>w</i> such that <i>r</i> does not happen before <i>w</i>
and there is no write <i>w'</i> such that <i>w</i> happens before <i>w'</i>

File diff suppressed because it is too large Load Diff

View File

@@ -126,74 +126,6 @@ for example,
see the [runtime documentation](/pkg/runtime#hdr-Environment_Variables)
and the [go command documentation](/cmd/go#hdr-Build_and_test_caching).
### Go 1.22
Go 1.22 adds a configurable limit to control the maximum acceptable RSA key size
that can be used in TLS handshakes, controlled by the [`tlsmaxrsasize` setting](/pkg/crypto/tls#Conn.Handshake).
The default is tlsmaxrsasize=8192, limiting RSA to 8192-bit keys. To avoid
denial of service attacks, this setting and default was backported to Go
1.19.13, Go 1.20.8, and Go 1.21.1.
Go 1.22 made it an error for a request or response read by a net/http
client or server to have an empty Content-Length header.
This behavior is controlled by the `httplaxcontentlength` setting.
Go 1.22 changed the behavior of ServeMux to accept extended
patterns and unescape both patterns and request paths by segment.
This behavior can be controlled by the
[`httpmuxgo121` setting](/pkg/net/http/#ServeMux).
Go 1.22 added the [Alias type](/pkg/go/types#Alias) to [go/types](/pkg/go/types)
for the explicit representation of [type aliases](/ref/spec#Type_declarations).
Whether the type checker produces `Alias` types or not is controlled by the
[`gotypesalias` setting](/pkg/go/types#Alias).
For Go 1.22 it defaults to `gotypesalias=0`.
For Go 1.23, `gotypealias=1` will become the default.
This setting will be removed in a future release, Go 1.24 at the earliest.
Go 1.22 changed the default minimum TLS version supported by both servers
and clients to TLS 1.2. The default can be reverted to TLS 1.0 using the
[`tls10server` setting](/pkg/crypto/tls/#Config).
Go 1.22 changed the default TLS cipher suites used by clients and servers when
not explicitly configured, removing the cipher suites which used RSA based key
exchange. The default can be revert using the [`tlsrsakex` setting](/pkg/crypto/tls/#Config).
Go 1.22 disabled
[`ConnectionState.ExportKeyingMaterial`](/pkg/crypto/tls/#ConnectionState.ExportKeyingMaterial)
when the connection supports neither TLS 1.3 nor Extended Master Secret
(implemented in Go 1.21). It can be reenabled with the [`tlsunsafeekm`
setting](/pkg/crypto/tls/#ConnectionState.ExportKeyingMaterial).
Go 1.22 changed how the runtime interacts with transparent huge pages on Linux.
In particular, a common default Linux kernel configuration can result in
significant memory overheads, and Go 1.22 no longer works around this default.
To work around this issue without adjusting kernel settings, transparent huge
pages can be disabled for Go memory with the
[`disablethp` setting](/pkg/runtime#hdr-Environment_Variable).
This behavior was backported to Go 1.21.1, but the setting is only available
starting with Go 1.21.6.
This setting may be removed in a future release, and users impacted by this issue
should adjust their Linux configuration according to the recommendations in the
[GC guide](/doc/gc-guide#Linux_transparent_huge_pages), or switch to a Linux
distribution that disables transparent huge pages altogether.
Go 1.22 added contention on runtime-internal locks to the [`mutex`
profile](/pkg/runtime/pprof#Profile). Contention on these locks is always
reported at `runtime._LostContendedRuntimeLock`. Complete stack traces of
runtime locks can be enabled with the [`runtimecontentionstacks`
setting](/pkg/runtime#hdr-Environment_Variable). These stack traces have
non-standard semantics, see setting documentation for details.
Go 1.22 added a new [`crypto/x509.Certificate`](/pkg/crypto/x509/#Certificate)
field, [`Policies`](/pkg/crypto/x509/#Certificate.Policies), which supports
certificate policy OIDs with components larger than 31 bits. By default this
field is only used during parsing, when it is populated with policy OIDs, but
not used during marshaling. It can be used to marshal these larger OIDs, instead
of the existing PolicyIdentifiers field, by using the
[`x509usepolicies` setting.](/pkg/crypto/x509/#CreateCertificate).
### Go 1.21
Go 1.21 made it a run-time error to call `panic` with a nil interface value,
@@ -210,10 +142,6 @@ forms, controlled by the
respectively.
This behavior was backported to Go 1.19.8+ and Go 1.20.3+.
Go 1.21 adds the support of Multipath TCP but it is only used if the application
explicitly asked for it. This behavior can be controlled by the
[`multipathtcp` setting](/pkg/net#Dialer.SetMultipathTCP).
There is no plan to remove any of these settings.
### Go 1.20
@@ -248,17 +176,10 @@ Go 1.19 made it an error for path lookups to resolve to binaries in the current
controlled by the [`execerrdot` setting](/pkg/os/exec#hdr-Executables_in_the_current_directory).
There is no plan to remove this setting.
Go 1.19 started sending EDNS0 additional headers on DNS requests.
This can reportedly break the DNS server provided on some routers,
such as CenturyLink Zyxel C3000Z.
This can be changed by the [`netedns0` setting](/pkg/net#hdr-Name_Resolution).
This setting is available in Go 1.21.12, Go 1.22.5, Go 1.23, and later.
There is no plan to remove this setting.
### Go 1.18
Go 1.18 removed support for SHA1 in most X.509 certificates,
controlled by the [`x509sha1` setting](/pkg/crypto/x509#InsecureAlgorithmError).
controlled by the [`x509sha1` setting](/crypto/x509#InsecureAlgorithmError).
This setting will be removed in a future release, Go 1.22 at the earliest.
### Go 1.10

View File

@@ -24,8 +24,8 @@
# in the CL match the update.bash in the CL.
# Versions to use.
CODE=2023d
DATA=2023d
CODE=2023c
DATA=2023c
set -e

Binary file not shown.

View File

@@ -3,4 +3,4 @@
// tests and tools.
module misc
go 1.22
go 1.21

View File

@@ -204,7 +204,6 @@ func runMain() (int, error) {
`; export GOPROXY=` + os.Getenv("GOPROXY") +
`; export GOCACHE="` + deviceRoot + `/gocache"` +
`; export PATH="` + deviceGoroot + `/bin":$PATH` +
`; export HOME="` + deviceRoot + `/home"` +
`; cd "` + deviceCwd + `"` +
"; '" + deviceBin + "' " + strings.Join(os.Args[2:], " ")
code, err := adbRun(cmd)

View File

@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.
//go:build ignore
// +build ignore
// detect attempts to autodetect the correct
// values of the environment variables

View File

@@ -10,19 +10,11 @@ case "$GOWASIRUNTIME" in
"wasmer")
exec wasmer run --dir=/ --env PWD="$PWD" --env PATH="$PATH" ${GOWASIRUNTIMEARGS:-} "$1" -- "${@:2}"
;;
"wazero")
exec wazero run -mount /:/ -env-inherit -cachedir "${TMPDIR:-/tmp}"/wazero ${GOWASIRUNTIMEARGS:-} "$1" "${@:2}"
"wasmtime")
exec wasmtime run --dir=/ --env PWD="$PWD" --env PATH="$PATH" --max-wasm-stack 1048576 ${GOWASIRUNTIMEARGS:-} "$1" -- "${@:2}"
;;
"wasmtime" | "")
# Match the major version in "wasmtime-cli 14.0.0". For versions before 14
# we need to use the old CLI. This requires Bash v3.0 and above.
# TODO(johanbrandhorst): Remove this condition once 1.22 is released.
# From 1.23 onwards we'll only support the new wasmtime CLI.
if [[ "$(wasmtime --version)" =~ wasmtime-cli[[:space:]]([0-9]+)\.[0-9]+\.[0-9]+ && "${BASH_REMATCH[1]}" -lt 14 ]]; then
exec wasmtime run --dir=/ --env PWD="$PWD" --env PATH="$PATH" --max-wasm-stack 1048576 ${GOWASIRUNTIMEARGS:-} "$1" -- "${@:2}"
else
exec wasmtime run --dir=/ --env PWD="$PWD" --env PATH="$PATH" -W max-wasm-stack=1048576 ${GOWASIRUNTIMEARGS:-} "$1" "${@:2}"
fi
"wazero" | "")
exec wazero run -mount /:/ -env-inherit -cachedir "${TMPDIR:-/tmp}"/wazero ${GOWASIRUNTIMEARGS:-} "$1" "${@:2}"
;;
*)
echo "Unknown Go WASI runtime specified: $GOWASIRUNTIME"

View File

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

View File

@@ -632,7 +632,7 @@ const (
c_ISSOCK = 0140000 // Socket
)
// FileInfoHeader creates a partially-populated [Header] from fi.
// FileInfoHeader creates a partially-populated Header from fi.
// If fi describes a symlink, FileInfoHeader records link as the link target.
// If fi describes a directory, a slash is appended to the name.
//
@@ -727,3 +727,10 @@ func isHeaderOnlyType(flag byte) bool {
return false
}
}
func min(a, b int64) int64 {
if a < b {
return a
}
return b
}

View File

@@ -33,7 +33,7 @@ import "strings"
// sub-second times | no | yes | no
// sparse files | no | yes | yes
//
// The table's upper portion shows the [Header] fields, where each format reports
// The table's upper portion shows the Header fields, where each format reports
// the maximum number of bytes allowed for each string field and
// the integer type used to store each numeric field
// (where timestamps are stored as the number of seconds since the Unix epoch).

View File

@@ -35,7 +35,7 @@ type fileReader interface {
WriteTo(io.Writer) (int64, error)
}
// NewReader creates a new [Reader] reading from r.
// NewReader creates a new Reader reading from r.
func NewReader(r io.Reader) *Reader {
return &Reader{r: r, curr: &regFileReader{r, 0}}
}
@@ -47,10 +47,10 @@ func NewReader(r io.Reader) *Reader {
//
// If Next encounters a non-local name (as defined by [filepath.IsLocal])
// and the GODEBUG environment variable contains `tarinsecurepath=0`,
// Next returns the header with an [ErrInsecurePath] error.
// Next returns the header with an ErrInsecurePath error.
// A future version of Go may introduce this behavior by default.
// Programs that want to accept non-local names can ignore
// the [ErrInsecurePath] error and use the returned header.
// the ErrInsecurePath error and use the returned header.
func (tr *Reader) Next() (*Header, error) {
if tr.err != nil {
return nil, tr.err
@@ -623,14 +623,14 @@ func readGNUSparseMap0x1(paxHdrs map[string]string) (sparseDatas, error) {
// Read reads from the current file in the tar archive.
// It returns (0, io.EOF) when it reaches the end of that file,
// until [Next] is called to advance to the next file.
// until Next is called to advance to the next file.
//
// If the current file is sparse, then the regions marked as a hole
// are read back as NUL-bytes.
//
// Calling Read on special types like [TypeLink], [TypeSymlink], [TypeChar],
// [TypeBlock], [TypeDir], and [TypeFifo] returns (0, [io.EOF]) regardless of what
// the [Header.Size] claims.
// Calling Read on special types like TypeLink, TypeSymlink, TypeChar,
// TypeBlock, TypeDir, and TypeFifo returns (0, io.EOF) regardless of what
// the Header.Size claims.
func (tr *Reader) Read(b []byte) (int, error) {
if tr.err != nil {
return 0, tr.err

View File

@@ -73,7 +73,7 @@ func (f *formatter) formatString(b []byte, s string) {
// in the V7 path field as a directory even though the full path
// recorded elsewhere (e.g., via PAX record) contains no trailing slash.
if len(s) > len(b) && b[len(b)-1] == '/' {
n := len(strings.TrimRight(s[:len(b)-1], "/"))
n := len(strings.TrimRight(s[:len(b)], "/"))
b[n] = 0 // Replace trailing slash with NUL terminator
}
}

View File

@@ -5,10 +5,8 @@
package tar
import (
"errors"
"fmt"
"io"
"io/fs"
"path"
"sort"
"strings"
@@ -16,7 +14,7 @@ import (
)
// Writer provides sequential writing of a tar archive.
// [Writer.WriteHeader] begins a new file with the provided [Header],
// Write.WriteHeader begins a new file with the provided Header,
// and then Writer can be treated as an io.Writer to supply that file's data.
type Writer struct {
w io.Writer
@@ -46,7 +44,7 @@ type fileWriter interface {
// Flush finishes writing the current file's block padding.
// The current file must be fully written before Flush can be called.
//
// This is unnecessary as the next call to [Writer.WriteHeader] or [Writer.Close]
// This is unnecessary as the next call to WriteHeader or Close
// will implicitly flush out the file's padding.
func (tw *Writer) Flush() error {
if tw.err != nil {
@@ -405,43 +403,6 @@ func (tw *Writer) writeRawHeader(blk *block, size int64, flag byte) error {
return nil
}
// AddFS adds the files from fs.FS to the archive.
// It walks the directory tree starting at the root of the filesystem
// adding each file to the tar archive while maintaining the directory structure.
func (tw *Writer) AddFS(fsys fs.FS) error {
return fs.WalkDir(fsys, ".", func(name string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return nil
}
info, err := d.Info()
if err != nil {
return err
}
// TODO(#49580): Handle symlinks when fs.ReadLinkFS is available.
if !info.Mode().IsRegular() {
return errors.New("tar: cannot add non-regular file")
}
h, err := FileInfoHeader(info, "")
if err != nil {
return err
}
h.Name = name
if err := tw.WriteHeader(h); err != nil {
return err
}
f, err := fsys.Open(name)
if err != nil {
return err
}
defer f.Close()
_, err = io.Copy(tw, f)
return err
})
}
// splitUSTARPath splits a path according to USTAR prefix and suffix rules.
// If the path is not splittable, then it will return ("", "", false).
func splitUSTARPath(name string) (prefix, suffix string, ok bool) {
@@ -464,12 +425,12 @@ func splitUSTARPath(name string) (prefix, suffix string, ok bool) {
}
// Write writes to the current file in the tar archive.
// Write returns the error [ErrWriteTooLong] if more than
// Header.Size bytes are written after [Writer.WriteHeader].
// Write returns the error ErrWriteTooLong if more than
// Header.Size bytes are written after WriteHeader.
//
// Calling Write on special types like [TypeLink], [TypeSymlink], [TypeChar],
// [TypeBlock], [TypeDir], and [TypeFifo] returns (0, [ErrWriteTooLong]) regardless
// of what the [Header.Size] claims.
// Calling Write on special types like TypeLink, TypeSymlink, TypeChar,
// TypeBlock, TypeDir, and TypeFifo returns (0, ErrWriteTooLong) regardless
// of what the Header.Size claims.
func (tw *Writer) Write(b []byte) (int, error) {
if tw.err != nil {
return 0, tw.err
@@ -503,7 +464,7 @@ func (tw *Writer) readFrom(r io.Reader) (int64, error) {
}
// Close closes the tar archive by flushing the padding, and writing the footer.
// If the current file (from a prior call to [Writer.WriteHeader]) is not fully written,
// If the current file (from a prior call to WriteHeader) is not fully written,
// then this returns an error.
func (tw *Writer) Close() error {
if tw.err == ErrWriteAfterClose {

View File

@@ -9,14 +9,12 @@ import (
"encoding/hex"
"errors"
"io"
"io/fs"
"os"
"path"
"reflect"
"sort"
"strings"
"testing"
"testing/fstest"
"testing/iotest"
"time"
)
@@ -1335,67 +1333,3 @@ func TestFileWriter(t *testing.T) {
}
}
}
func TestWriterAddFS(t *testing.T) {
fsys := fstest.MapFS{
"file.go": {Data: []byte("hello")},
"subfolder/another.go": {Data: []byte("world")},
}
var buf bytes.Buffer
tw := NewWriter(&buf)
if err := tw.AddFS(fsys); err != nil {
t.Fatal(err)
}
// Test that we can get the files back from the archive
tr := NewReader(&buf)
entries, err := fsys.ReadDir(".")
if err != nil {
t.Fatal(err)
}
var curfname string
for _, entry := range entries {
curfname = entry.Name()
if entry.IsDir() {
curfname += "/"
continue
}
hdr, err := tr.Next()
if err == io.EOF {
break // End of archive
}
if err != nil {
t.Fatal(err)
}
data, err := io.ReadAll(tr)
if err != nil {
t.Fatal(err)
}
if hdr.Name != curfname {
t.Fatalf("got filename %v, want %v",
curfname, hdr.Name)
}
origdata := fsys[curfname].Data
if string(data) != string(origdata) {
t.Fatalf("got file content %v, want %v",
data, origdata)
}
}
}
func TestWriterAddFSNonRegularFiles(t *testing.T) {
fsys := fstest.MapFS{
"device": {Data: []byte("hello"), Mode: 0755 | fs.ModeDevice},
"symlink": {Data: []byte("world"), Mode: 0755 | fs.ModeSymlink},
}
var buf bytes.Buffer
tw := NewWriter(&buf)
if err := tw.AddFS(fsys); err == nil {
t.Fatal("expected error, got nil")
}
}

View File

@@ -48,15 +48,15 @@ type Reader struct {
fileList []fileListEntry
}
// A ReadCloser is a [Reader] that must be closed when no longer needed.
// A ReadCloser is a Reader that must be closed when no longer needed.
type ReadCloser struct {
f *os.File
Reader
}
// A File is a single file in a ZIP archive.
// The file information is in the embedded [FileHeader].
// The file content can be accessed by calling [File.Open].
// The file information is in the embedded FileHeader.
// The file content can be accessed by calling Open.
type File struct {
FileHeader
zip *Reader
@@ -93,16 +93,16 @@ func OpenReader(name string) (*ReadCloser, error) {
return r, err
}
// NewReader returns a new [Reader] reading from r, which is assumed to
// NewReader returns a new Reader reading from r, which is assumed to
// have the given size in bytes.
//
// If any file inside the archive uses a non-local name
// (as defined by [filepath.IsLocal]) or a name containing backslashes
// and the GODEBUG environment variable contains `zipinsecurepath=0`,
// NewReader returns the reader with an [ErrInsecurePath] error.
// NewReader returns the reader with an ErrInsecurePath error.
// A future version of Go may introduce this behavior by default.
// Programs that want to accept non-local names can ignore
// the [ErrInsecurePath] error and use the returned reader.
// the ErrInsecurePath error and use the returned reader.
func NewReader(r io.ReaderAt, size int64) (*Reader, error) {
if size < 0 {
return nil, errors.New("zip: size cannot be negative")
@@ -178,7 +178,7 @@ func (r *Reader) init(rdr io.ReaderAt, size int64) error {
// RegisterDecompressor registers or overrides a custom decompressor for a
// specific method ID. If a decompressor for a given method is not found,
// [Reader] will default to looking up the decompressor at the package level.
// Reader will default to looking up the decompressor at the package level.
func (r *Reader) RegisterDecompressor(method uint16, dcomp Decompressor) {
if r.decompressors == nil {
r.decompressors = make(map[uint16]Decompressor)
@@ -202,7 +202,7 @@ func (rc *ReadCloser) Close() error {
// DataOffset returns the offset of the file's possibly-compressed
// data, relative to the beginning of the zip file.
//
// Most callers should instead use [File.Open], which transparently
// Most callers should instead use Open, which transparently
// decompresses data and verifies checksums.
func (f *File) DataOffset() (offset int64, err error) {
bodyOffset, err := f.findBodyOffset()
@@ -212,7 +212,7 @@ func (f *File) DataOffset() (offset int64, err error) {
return f.headerOffset + bodyOffset, nil
}
// Open returns a [ReadCloser] that provides access to the [File]'s contents.
// Open returns a ReadCloser that provides access to the File's contents.
// Multiple files may be read concurrently.
func (f *File) Open() (io.ReadCloser, error) {
bodyOffset, err := f.findBodyOffset()
@@ -255,7 +255,7 @@ func (f *File) Open() (io.ReadCloser, error) {
return rc, nil
}
// OpenRaw returns a [Reader] that provides access to the [File]'s contents without
// OpenRaw returns a Reader that provides access to the File's contents without
// decompression.
func (f *File) OpenRaw() (io.Reader, error) {
bodyOffset, err := f.findBodyOffset()
@@ -469,8 +469,8 @@ parseExtras:
const ticksPerSecond = 1e7 // Windows timestamp resolution
ts := int64(attrBuf.uint64()) // ModTime since Windows epoch
secs := ts / ticksPerSecond
nsecs := (1e9 / ticksPerSecond) * (ts % ticksPerSecond)
secs := int64(ts / ticksPerSecond)
nsecs := (1e9 / ticksPerSecond) * int64(ts%ticksPerSecond)
epoch := time.Date(1601, time.January, 1, 0, 0, 0, 0, time.UTC)
modified = time.Unix(epoch.Unix()+secs, nsecs)
}
@@ -699,13 +699,9 @@ func findSignatureInBlock(b []byte) int {
if b[i] == 'P' && b[i+1] == 'K' && b[i+2] == 0x05 && b[i+3] == 0x06 {
// n is length of comment
n := int(b[i+directoryEndLen-2]) | int(b[i+directoryEndLen-1])<<8
if n+directoryEndLen+i > len(b) {
// Truncated comment.
// Some parsers (such as Info-ZIP) ignore the truncated comment
// rather than treating it as a hard error.
return -1
if n+directoryEndLen+i <= len(b) {
return i
}
return i
}
}
return -1

View File

@@ -570,14 +570,6 @@ var tests = []ZipTest{
},
},
},
// Issue 66869: Don't skip over an EOCDR with a truncated comment.
// The test file sneakily hides a second EOCDR before the first one;
// previously we would extract one file ("file") from this archive,
// while most other tools would reject the file or extract a different one ("FILE").
{
Name: "comment-truncated.zip",
Error: ErrFormat,
},
}
func TestReader(t *testing.T) {
@@ -1194,7 +1186,7 @@ func TestIssue12449(t *testing.T) {
0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
}
// Read in the archive.
_, err := NewReader(bytes.NewReader(data), int64(len(data)))
_, err := NewReader(bytes.NewReader([]byte(data)), int64(len(data)))
if err != nil {
t.Errorf("Error reading the archive: %v", err)
}
@@ -1341,7 +1333,7 @@ func TestCVE202127919(t *testing.T) {
0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x39, 0x00,
0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00,
}
r, err := NewReader(bytes.NewReader(data), int64(len(data)))
r, err := NewReader(bytes.NewReader([]byte(data)), int64(len(data)))
if err != ErrInsecurePath {
t.Fatalf("Error reading the archive: %v", err)
}
@@ -1567,7 +1559,7 @@ func TestCVE202141772(t *testing.T) {
0x00, 0x04, 0x00, 0x04, 0x00, 0x31, 0x01, 0x00,
0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00,
}
r, err := NewReader(bytes.NewReader(data), int64(len(data)))
r, err := NewReader(bytes.NewReader([]byte(data)), int64(len(data)))
if err != ErrInsecurePath {
t.Fatalf("Error reading the archive: %v", err)
}
@@ -1830,7 +1822,7 @@ func TestBaseOffsetPlusOverflow(t *testing.T) {
}
}()
// Previously, this would trigger a panic as we attempt to read from
// an io.SectionReader which would access a slice at a negative offset
// a io.SectionReader which would access a slice at a negative offset
// as the section reader offset & size were < 0.
NewReader(bytes.NewReader(data), int64(len(data))+1875)
}

View File

@@ -19,7 +19,7 @@ import (
type Compressor func(w io.Writer) (io.WriteCloser, error)
// A Decompressor returns a new decompressing reader, reading from r.
// The [io.ReadCloser]'s Close method must be used to release associated resources.
// The ReadCloser's Close method must be used to release associated resources.
// The Decompressor itself must be safe to invoke from multiple goroutines
// simultaneously, but each returned reader will be used only by
// one goroutine at a time.
@@ -115,7 +115,7 @@ func init() {
}
// RegisterDecompressor allows custom decompressors for a specified method ID.
// The common methods [Store] and [Deflate] are built in.
// The common methods Store and Deflate are built in.
func RegisterDecompressor(method uint16, dcomp Decompressor) {
if _, dup := decompressors.LoadOrStore(method, dcomp); dup {
panic("decompressor already registered")
@@ -123,7 +123,7 @@ func RegisterDecompressor(method uint16, dcomp Decompressor) {
}
// RegisterCompressor registers custom compressors for a specified method ID.
// The common methods [Store] and [Deflate] are built in.
// The common methods Store and Deflate are built in.
func RegisterCompressor(method uint16, comp Compressor) {
if _, dup := compressors.LoadOrStore(method, comp); dup {
panic("compressor already registered")

View File

@@ -17,7 +17,7 @@ for normal archives both fields will be the same. For files requiring
the ZIP64 format the 32 bit fields will be 0xffffffff and the 64 bit
fields must be used instead.
[ZIP specification]: https://support.pkware.com/pkzip/appnote
[ZIP specification]: https://www.pkware.com/appnote
*/
package zip
@@ -82,7 +82,7 @@ const (
// FileHeader describes a file within a ZIP file.
// See the [ZIP specification] for details.
//
// [ZIP specification]: https://support.pkware.com/pkzip/appnote
// [ZIP specification]: https://www.pkware.com/appnote
type FileHeader struct {
// Name is the name of the file.
//
@@ -160,12 +160,12 @@ type FileHeader struct {
ExternalAttrs uint32 // Meaning depends on CreatorVersion
}
// FileInfo returns an fs.FileInfo for the [FileHeader].
// FileInfo returns an fs.FileInfo for the FileHeader.
func (h *FileHeader) FileInfo() fs.FileInfo {
return headerFileInfo{h}
}
// headerFileInfo implements [fs.FileInfo].
// headerFileInfo implements fs.FileInfo.
type headerFileInfo struct {
fh *FileHeader
}
@@ -194,7 +194,7 @@ func (fi headerFileInfo) String() string {
return fs.FormatFileInfo(fi)
}
// FileInfoHeader creates a partially-populated [FileHeader] from an
// FileInfoHeader creates a partially-populated FileHeader from an
// fs.FileInfo.
// Because fs.FileInfo's Name method returns only the base name of
// the file it describes, it may be necessary to modify the Name field
@@ -245,7 +245,7 @@ func timeZone(offset time.Duration) *time.Location {
// msDosTimeToTime converts an MS-DOS date and time into a time.Time.
// The resolution is 2s.
// See: https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-dosdatetimetofiletime
// See: https://msdn.microsoft.com/en-us/library/ms724247(v=VS.85).aspx
func msDosTimeToTime(dosDate, dosTime uint16) time.Time {
return time.Date(
// date bits 0-4: day of month; 5-8: month; 9-15: years since 1980
@@ -265,7 +265,7 @@ func msDosTimeToTime(dosDate, dosTime uint16) time.Time {
// timeToMsDosTime converts a time.Time to an MS-DOS date and time.
// The resolution is 2s.
// See: https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-filetimetodosdatetime
// See: https://msdn.microsoft.com/en-us/library/ms724274(v=VS.85).aspx
func timeToMsDosTime(t time.Time) (fDate uint16, fTime uint16) {
fDate = uint16(t.Day() + int(t.Month())<<5 + (t.Year()-1980)<<9)
fTime = uint16(t.Second()/2 + t.Minute()<<5 + t.Hour()<<11)
@@ -273,17 +273,17 @@ func timeToMsDosTime(t time.Time) (fDate uint16, fTime uint16) {
}
// ModTime returns the modification time in UTC using the legacy
// [ModifiedDate] and [ModifiedTime] fields.
// ModifiedDate and ModifiedTime fields.
//
// Deprecated: Use [Modified] instead.
// Deprecated: Use Modified instead.
func (h *FileHeader) ModTime() time.Time {
return msDosTimeToTime(h.ModifiedDate, h.ModifiedTime)
}
// SetModTime sets the [Modified], [ModifiedTime], and [ModifiedDate] fields
// SetModTime sets the Modified, ModifiedTime, and ModifiedDate fields
// to the given time in UTC.
//
// Deprecated: Use [Modified] instead.
// Deprecated: Use Modified instead.
func (h *FileHeader) SetModTime(t time.Time) {
t = t.UTC() // Convert to UTC for compatibility
h.Modified = t
@@ -309,7 +309,7 @@ const (
msdosReadOnly = 0x01
)
// Mode returns the permission and mode bits for the [FileHeader].
// Mode returns the permission and mode bits for the FileHeader.
func (h *FileHeader) Mode() (mode fs.FileMode) {
switch h.CreatorVersion >> 8 {
case creatorUnix, creatorMacOSX:
@@ -323,7 +323,7 @@ func (h *FileHeader) Mode() (mode fs.FileMode) {
return mode
}
// SetMode changes the permission and mode bits for the [FileHeader].
// SetMode changes the permission and mode bits for the FileHeader.
func (h *FileHeader) SetMode(mode fs.FileMode) {
h.CreatorVersion = h.CreatorVersion&0xff | creatorUnix<<8
h.ExternalAttrs = fileModeToUnixMode(mode) << 16

Binary file not shown.

View File

@@ -11,7 +11,6 @@ import (
"hash"
"hash/crc32"
"io"
"io/fs"
"strings"
"unicode/utf8"
)
@@ -41,7 +40,7 @@ type header struct {
raw bool
}
// NewWriter returns a new [Writer] writing a zip file to w.
// NewWriter returns a new Writer writing a zip file to w.
func NewWriter(w io.Writer) *Writer {
return &Writer{cw: &countWriter{w: bufio.NewWriter(w)}}
}
@@ -64,7 +63,7 @@ func (w *Writer) Flush() error {
}
// SetComment sets the end-of-central-directory comment field.
// It can only be called before [Writer.Close].
// It can only be called before Close.
func (w *Writer) SetComment(comment string) error {
if len(comment) > uint16max {
return errors.New("zip: Writer.Comment too long")
@@ -208,14 +207,14 @@ func (w *Writer) Close() error {
}
// Create adds a file to the zip file using the provided name.
// It returns a [Writer] to which the file contents should be written.
// The file contents will be compressed using the [Deflate] method.
// It returns a Writer to which the file contents should be written.
// The file contents will be compressed using the Deflate method.
// The name must be a relative path: it must not start with a drive
// letter (e.g. C:) or leading slash, and only forward slashes are
// allowed. To create a directory instead of a file, add a trailing
// slash to the name.
// The file's contents must be written to the [io.Writer] before the next
// call to [Writer.Create], [Writer.CreateHeader], or [Writer.Close].
// The file's contents must be written to the io.Writer before the next
// call to Create, CreateHeader, or Close.
func (w *Writer) Create(name string) (io.Writer, error) {
header := &FileHeader{
Name: name,
@@ -262,13 +261,13 @@ func (w *Writer) prepare(fh *FileHeader) error {
return nil
}
// CreateHeader adds a file to the zip archive using the provided [FileHeader]
// for the file metadata. [Writer] takes ownership of fh and may mutate
// its fields. The caller must not modify fh after calling [Writer.CreateHeader].
// CreateHeader adds a file to the zip archive using the provided FileHeader
// for the file metadata. Writer takes ownership of fh and may mutate
// its fields. The caller must not modify fh after calling CreateHeader.
//
// This returns a [Writer] to which the file contents should be written.
// This returns a Writer to which the file contents should be written.
// The file's contents must be written to the io.Writer before the next
// call to [Writer.Create], [Writer.CreateHeader], [Writer.CreateRaw], or [Writer.Close].
// call to Create, CreateHeader, CreateRaw, or Close.
func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
if err := w.prepare(fh); err != nil {
return nil, err
@@ -406,8 +405,8 @@ func writeHeader(w io.Writer, h *header) error {
// flags.
if h.raw && !h.hasDataDescriptor() {
b.uint32(h.CRC32)
b.uint32(uint32(min(h.CompressedSize64, uint32max)))
b.uint32(uint32(min(h.UncompressedSize64, uint32max)))
b.uint32(uint32(min64(h.CompressedSize64, uint32max)))
b.uint32(uint32(min64(h.UncompressedSize64, uint32max)))
} else {
// When this package handle the compression, these values are
// always written to the trailing data descriptor.
@@ -427,19 +426,26 @@ func writeHeader(w io.Writer, h *header) error {
return err
}
// CreateRaw adds a file to the zip archive using the provided [FileHeader] and
// returns a [Writer] to which the file contents should be written. The file's
// contents must be written to the io.Writer before the next call to [Writer.Create],
// [Writer.CreateHeader], [Writer.CreateRaw], or [Writer.Close].
func min64(x, y uint64) uint64 {
if x < y {
return x
}
return y
}
// CreateRaw adds a file to the zip archive using the provided FileHeader and
// returns a Writer to which the file contents should be written. The file's
// contents must be written to the io.Writer before the next call to Create,
// CreateHeader, CreateRaw, or Close.
//
// In contrast to [Writer.CreateHeader], the bytes passed to Writer are not compressed.
// In contrast to CreateHeader, the bytes passed to Writer are not compressed.
func (w *Writer) CreateRaw(fh *FileHeader) (io.Writer, error) {
if err := w.prepare(fh); err != nil {
return nil, err
}
fh.CompressedSize = uint32(min(fh.CompressedSize64, uint32max))
fh.UncompressedSize = uint32(min(fh.UncompressedSize64, uint32max))
fh.CompressedSize = uint32(min64(fh.CompressedSize64, uint32max))
fh.UncompressedSize = uint32(min64(fh.UncompressedSize64, uint32max))
h := &header{
FileHeader: fh,
@@ -464,7 +470,7 @@ func (w *Writer) CreateRaw(fh *FileHeader) (io.Writer, error) {
return fw, nil
}
// Copy copies the file f (obtained from a [Reader]) into w. It copies the raw
// Copy copies the file f (obtained from a Reader) into w. It copies the raw
// form directly bypassing decompression, compression, and validation.
func (w *Writer) Copy(f *File) error {
r, err := f.OpenRaw()
@@ -480,7 +486,7 @@ func (w *Writer) Copy(f *File) error {
}
// RegisterCompressor registers or overrides a custom compressor for a specific
// method ID. If a compressor for a given method is not found, [Writer] will
// method ID. If a compressor for a given method is not found, Writer will
// default to looking up the compressor at the package level.
func (w *Writer) RegisterCompressor(method uint16, comp Compressor) {
if w.compressors == nil {
@@ -489,44 +495,6 @@ func (w *Writer) RegisterCompressor(method uint16, comp Compressor) {
w.compressors[method] = comp
}
// AddFS adds the files from fs.FS to the archive.
// It walks the directory tree starting at the root of the filesystem
// adding each file to the zip using deflate while maintaining the directory structure.
func (w *Writer) AddFS(fsys fs.FS) error {
return fs.WalkDir(fsys, ".", func(name string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return nil
}
info, err := d.Info()
if err != nil {
return err
}
if !info.Mode().IsRegular() {
return errors.New("zip: cannot add non-regular file")
}
h, err := FileInfoHeader(info)
if err != nil {
return err
}
h.Name = name
h.Method = Deflate
fw, err := w.CreateHeader(h)
if err != nil {
return err
}
f, err := fsys.Open(name)
if err != nil {
return err
}
defer f.Close()
_, err = io.Copy(fw, f)
return err
})
}
func (w *Writer) compressor(method uint16) Compressor {
comp := w.compressors[method]
if comp == nil {

View File

@@ -16,7 +16,6 @@ import (
"os"
"strings"
"testing"
"testing/fstest"
"time"
)
@@ -603,71 +602,3 @@ func BenchmarkCompressedZipGarbage(b *testing.B) {
}
})
}
func writeTestsToFS(tests []WriteTest) fs.FS {
fsys := fstest.MapFS{}
for _, wt := range tests {
fsys[wt.Name] = &fstest.MapFile{
Data: wt.Data,
Mode: wt.Mode,
}
}
return fsys
}
func TestWriterAddFS(t *testing.T) {
buf := new(bytes.Buffer)
w := NewWriter(buf)
tests := []WriteTest{
{
Name: "file.go",
Data: []byte("hello"),
Mode: 0644,
},
{
Name: "subfolder/another.go",
Data: []byte("world"),
Mode: 0644,
},
}
err := w.AddFS(writeTestsToFS(tests))
if err != nil {
t.Fatal(err)
}
if err := w.Close(); err != nil {
t.Fatal(err)
}
// read it back
r, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
if err != nil {
t.Fatal(err)
}
for i, wt := range tests {
testReadFile(t, r.File[i], &wt)
}
}
func TestIssue61875(t *testing.T) {
buf := new(bytes.Buffer)
w := NewWriter(buf)
tests := []WriteTest{
{
Name: "symlink",
Data: []byte("../link/target"),
Method: Deflate,
Mode: 0755 | fs.ModeSymlink,
},
{
Name: "device",
Data: []byte(""),
Method: Deflate,
Mode: 0755 | fs.ModeDevice,
},
}
err := w.AddFS(writeTestsToFS(tests))
if err == nil {
t.Errorf("expected error, got nil")
}
}

View File

@@ -198,6 +198,13 @@ func (r *rleBuffer) Write(p []byte) (n int, err error) {
return len(p), nil
}
func min(x, y int64) int64 {
if x < y {
return x
}
return y
}
func memset(a []byte, b byte) {
if len(a) == 0 {
return
@@ -590,7 +597,7 @@ func testZip64(t testing.TB, size int64) *rleBuffer {
}
// read back zip file and check that we get to the end of it
r, err := NewReader(buf, buf.Size())
r, err := NewReader(buf, int64(buf.Size()))
if err != nil {
t.Fatal("reader:", err)
}

View File

@@ -41,21 +41,24 @@ type Reader struct {
const minReadBufferSize = 16
const maxConsecutiveEmptyReads = 100
// NewReaderSize returns a new [Reader] whose buffer has at least the specified
// size. If the argument io.Reader is already a [Reader] with large enough
// size, it returns the underlying [Reader].
// NewReaderSize returns a new Reader whose buffer has at least the specified
// size. If the argument io.Reader is already a Reader with large enough
// size, it returns the underlying Reader.
func NewReaderSize(rd io.Reader, size int) *Reader {
// Is it already a Reader?
b, ok := rd.(*Reader)
if ok && len(b.buf) >= size {
return b
}
if size < minReadBufferSize {
size = minReadBufferSize
}
r := new(Reader)
r.reset(make([]byte, max(size, minReadBufferSize)), rd)
r.reset(make([]byte, size), rd)
return r
}
// NewReader returns a new [Reader] whose buffer has the default size.
// NewReader returns a new Reader whose buffer has the default size.
func NewReader(rd io.Reader) *Reader {
return NewReaderSize(rd, defaultBufSize)
}
@@ -65,9 +68,9 @@ func (b *Reader) Size() int { return len(b.buf) }
// Reset discards any buffered data, resets all state, and switches
// the buffered reader to read from r.
// Calling Reset on the zero value of [Reader] initializes the internal buffer
// Calling Reset on the zero value of Reader initializes the internal buffer
// to the default size.
// Calling b.Reset(b) (that is, resetting a [Reader] to itself) does nothing.
// Calling b.Reset(b) (that is, resetting a Reader to itself) does nothing.
func (b *Reader) Reset(r io.Reader) {
// If a Reader r is passed to NewReader, NewReader will return r.
// Different layers of code may do that, and then later pass r
@@ -132,9 +135,9 @@ func (b *Reader) readErr() error {
// Peek returns the next n bytes without advancing the reader. The bytes stop
// being valid at the next read call. If Peek returns fewer than n bytes, it
// also returns an error explaining why the read is short. The error is
// [ErrBufferFull] if n is larger than b's buffer size.
// ErrBufferFull if n is larger than b's buffer size.
//
// Calling Peek prevents a [Reader.UnreadByte] or [Reader.UnreadRune] call from succeeding
// Calling Peek prevents a UnreadByte or UnreadRune call from succeeding
// until the next read operation.
func (b *Reader) Peek(n int) ([]byte, error) {
if n < 0 {
@@ -204,10 +207,10 @@ func (b *Reader) Discard(n int) (discarded int, err error) {
// Read reads data into p.
// It returns the number of bytes read into p.
// The bytes are taken from at most one Read on the underlying [Reader],
// The bytes are taken from at most one Read on the underlying Reader,
// hence n may be less than len(p).
// To read exactly len(p) bytes, use io.ReadFull(b, p).
// If the underlying [Reader] can return a non-zero count with io.EOF,
// If the underlying Reader can return a non-zero count with io.EOF,
// then this Read method can do so as well; see the [io.Reader] docs.
func (b *Reader) Read(p []byte) (n int, err error) {
n = len(p)
@@ -277,7 +280,7 @@ func (b *Reader) ReadByte() (byte, error) {
// UnreadByte unreads the last byte. Only the most recently read byte can be unread.
//
// UnreadByte returns an error if the most recent method called on the
// [Reader] was not a read operation. Notably, [Reader.Peek], [Reader.Discard], and [Reader.WriteTo] are not
// Reader was not a read operation. Notably, Peek, Discard, and WriteTo are not
// considered read operations.
func (b *Reader) UnreadByte() error {
if b.lastByte < 0 || b.r == 0 && b.w > 0 {
@@ -318,8 +321,8 @@ func (b *Reader) ReadRune() (r rune, size int, err error) {
}
// UnreadRune unreads the last rune. If the most recent method called on
// the [Reader] was not a [Reader.ReadRune], [Reader.UnreadRune] returns an error. (In this
// regard it is stricter than [Reader.UnreadByte], which will unread the last byte
// the Reader was not a ReadRune, UnreadRune returns an error. (In this
// regard it is stricter than UnreadByte, which will unread the last byte
// from any read operation.)
func (b *Reader) UnreadRune() error {
if b.lastRuneSize < 0 || b.r < b.lastRuneSize {
@@ -339,10 +342,10 @@ func (b *Reader) Buffered() int { return b.w - b.r }
// The bytes stop being valid at the next read.
// If ReadSlice encounters an error before finding a delimiter,
// it returns all the data in the buffer and the error itself (often io.EOF).
// ReadSlice fails with error [ErrBufferFull] if the buffer fills without a delim.
// ReadSlice fails with error ErrBufferFull if the buffer fills without a delim.
// Because the data returned from ReadSlice will be overwritten
// by the next I/O operation, most clients should use
// [Reader.ReadBytes] or ReadString instead.
// ReadBytes or ReadString instead.
// ReadSlice returns err != nil if and only if line does not end in delim.
func (b *Reader) ReadSlice(delim byte) (line []byte, err error) {
s := 0 // search start index
@@ -386,7 +389,7 @@ func (b *Reader) ReadSlice(delim byte) (line []byte, err error) {
}
// ReadLine is a low-level line-reading primitive. Most callers should use
// [Reader.ReadBytes]('\n') or [Reader.ReadString]('\n') instead or use a [Scanner].
// ReadBytes('\n') or ReadString('\n') instead or use a Scanner.
//
// ReadLine tries to return a single line, not including the end-of-line bytes.
// If the line was too long for the buffer then isPrefix is set and the
@@ -398,7 +401,7 @@ func (b *Reader) ReadSlice(delim byte) (line []byte, err error) {
//
// The text returned from ReadLine does not include the line end ("\r\n" or "\n").
// No indication or error is given if the input ends without a final line end.
// Calling [Reader.UnreadByte] after ReadLine will always unread the last byte read
// Calling UnreadByte after ReadLine will always unread the last byte read
// (possibly a character belonging to the line end) even if that byte is not
// part of the line returned by ReadLine.
func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error) {
@@ -508,9 +511,9 @@ func (b *Reader) ReadString(delim byte) (string, error) {
}
// WriteTo implements io.WriterTo.
// This may make multiple calls to the [Reader.Read] method of the underlying [Reader].
// If the underlying reader supports the [Reader.WriteTo] method,
// this calls the underlying [Reader.WriteTo] without buffering.
// This may make multiple calls to the Read method of the underlying Reader.
// If the underlying reader supports the WriteTo method,
// this calls the underlying WriteTo without buffering.
func (b *Reader) WriteTo(w io.Writer) (n int64, err error) {
b.lastByte = -1
b.lastRuneSize = -1
@@ -555,7 +558,7 @@ func (b *Reader) WriteTo(w io.Writer) (n int64, err error) {
var errNegativeWrite = errors.New("bufio: writer returned negative count from Write")
// writeBuf writes the [Reader]'s buffer to the writer.
// writeBuf writes the Reader's buffer to the writer.
func (b *Reader) writeBuf(w io.Writer) (int64, error) {
n, err := w.Write(b.buf[b.r:b.w])
if n < 0 {
@@ -567,12 +570,12 @@ func (b *Reader) writeBuf(w io.Writer) (int64, error) {
// buffered output
// Writer implements buffering for an [io.Writer] object.
// If an error occurs writing to a [Writer], no more data will be
// accepted and all subsequent writes, and [Writer.Flush], will return the error.
// Writer implements buffering for an io.Writer object.
// If an error occurs writing to a Writer, no more data will be
// accepted and all subsequent writes, and Flush, will return the error.
// After all data has been written, the client should call the
// [Writer.Flush] method to guarantee all data has been forwarded to
// the underlying [io.Writer].
// Flush method to guarantee all data has been forwarded to
// the underlying io.Writer.
type Writer struct {
err error
buf []byte
@@ -580,9 +583,9 @@ type Writer struct {
wr io.Writer
}
// NewWriterSize returns a new [Writer] whose buffer has at least the specified
// size. If the argument io.Writer is already a [Writer] with large enough
// size, it returns the underlying [Writer].
// NewWriterSize returns a new Writer whose buffer has at least the specified
// size. If the argument io.Writer is already a Writer with large enough
// size, it returns the underlying Writer.
func NewWriterSize(w io.Writer, size int) *Writer {
// Is it already a Writer?
b, ok := w.(*Writer)
@@ -598,9 +601,9 @@ func NewWriterSize(w io.Writer, size int) *Writer {
}
}
// NewWriter returns a new [Writer] whose buffer has the default size.
// If the argument io.Writer is already a [Writer] with large enough buffer size,
// it returns the underlying [Writer].
// NewWriter returns a new Writer whose buffer has the default size.
// If the argument io.Writer is already a Writer with large enough buffer size,
// it returns the underlying Writer.
func NewWriter(w io.Writer) *Writer {
return NewWriterSize(w, defaultBufSize)
}
@@ -610,9 +613,9 @@ func (b *Writer) Size() int { return len(b.buf) }
// Reset discards any unflushed buffered data, clears any error, and
// resets b to write its output to w.
// Calling Reset on the zero value of [Writer] initializes the internal buffer
// Calling Reset on the zero value of Writer initializes the internal buffer
// to the default size.
// Calling w.Reset(w) (that is, resetting a [Writer] to itself) does nothing.
// Calling w.Reset(w) (that is, resetting a Writer to itself) does nothing.
func (b *Writer) Reset(w io.Writer) {
// If a Writer w is passed to NewWriter, NewWriter will return w.
// Different layers of code may do that, and then later pass w
@@ -628,7 +631,7 @@ func (b *Writer) Reset(w io.Writer) {
b.wr = w
}
// Flush writes any buffered data to the underlying [io.Writer].
// Flush writes any buffered data to the underlying io.Writer.
func (b *Writer) Flush() error {
if b.err != nil {
return b.err
@@ -657,7 +660,7 @@ func (b *Writer) Available() int { return len(b.buf) - b.n }
// AvailableBuffer returns an empty buffer with b.Available() capacity.
// This buffer is intended to be appended to and
// passed to an immediately succeeding [Writer.Write] call.
// passed to an immediately succeeding Write call.
// The buffer is only valid until the next write operation on b.
func (b *Writer) AvailableBuffer() []byte {
return b.buf[b.n:][:0]
@@ -774,7 +777,7 @@ func (b *Writer) WriteString(s string) (int, error) {
return nn, nil
}
// ReadFrom implements [io.ReaderFrom]. If the underlying writer
// ReadFrom implements io.ReaderFrom. If the underlying writer
// supports the ReadFrom method, this calls the underlying ReadFrom.
// If there is buffered data and an underlying ReadFrom, this fills
// the buffer and writes it before calling ReadFrom.
@@ -826,14 +829,14 @@ func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
// buffered input and output
// ReadWriter stores pointers to a [Reader] and a [Writer].
// It implements [io.ReadWriter].
// ReadWriter stores pointers to a Reader and a Writer.
// It implements io.ReadWriter.
type ReadWriter struct {
*Reader
*Writer
}
// NewReadWriter allocates a new [ReadWriter] that dispatches to r and w.
// NewReadWriter allocates a new ReadWriter that dispatches to r and w.
func NewReadWriter(r *Reader, w *Writer) *ReadWriter {
return &ReadWriter{r, w}
}

View File

@@ -6,7 +6,6 @@ package bufio_test
import (
"bufio"
"bytes"
"fmt"
"os"
"strconv"
@@ -138,36 +137,3 @@ func ExampleScanner_emptyFinalToken() {
}
// Output: "1" "2" "3" "4" ""
}
// Use a Scanner with a custom split function to parse a comma-separated
// list with an empty final value but stops at the token "STOP".
func ExampleScanner_earlyStop() {
onComma := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
i := bytes.IndexByte(data, ',')
if i == -1 {
if !atEOF {
return 0, nil, nil
}
// If we have reached the end, return the last token.
return 0, data, bufio.ErrFinalToken
}
// If the token is "STOP", stop the scanning and ignore the rest.
if string(data[:i]) == "STOP" {
return i + 1, nil, bufio.ErrFinalToken
}
// Otherwise, return the token before the comma.
return i + 1, data[:i], nil
}
const input = "1,2,STOP,4,"
scanner := bufio.NewScanner(strings.NewReader(input))
scanner.Split(onComma)
for scanner.Scan() {
fmt.Printf("Got a token %q\n", scanner.Text())
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "reading input:", err)
}
// Output:
// Got a token "1"
// Got a token "2"
}

View File

@@ -13,19 +13,19 @@ import (
// Scanner provides a convenient interface for reading data such as
// a file of newline-delimited lines of text. Successive calls to
// the [Scanner.Scan] method will step through the 'tokens' of a file, skipping
// the Scan method will step through the 'tokens' of a file, skipping
// the bytes between the tokens. The specification of a token is
// defined by a split function of type [SplitFunc]; the default split
// function breaks the input into lines with line termination stripped. [Scanner.Split]
// defined by a split function of type SplitFunc; the default split
// function breaks the input into lines with line termination stripped. Split
// functions are defined in this package for scanning a file into
// lines, bytes, UTF-8-encoded runes, and space-delimited words. The
// client may instead provide a custom split function.
//
// Scanning stops unrecoverably at EOF, the first I/O error, or a token too
// large to fit in the [Scanner.Buffer]. When a scan stops, the reader may have
// large to fit in the buffer. When a scan stops, the reader may have
// advanced arbitrarily far past the last token. Programs that need more
// control over error handling or large tokens, or must run sequential scans
// on a reader, should use [bufio.Reader] instead.
// on a reader, should use bufio.Reader instead.
type Scanner struct {
r io.Reader // The reader provided by the client.
split SplitFunc // The function to split the tokens.
@@ -42,23 +42,21 @@ type Scanner struct {
// SplitFunc is the signature of the split function used to tokenize the
// input. The arguments are an initial substring of the remaining unprocessed
// data and a flag, atEOF, that reports whether the [Reader] has no more data
// data and a flag, atEOF, that reports whether the Reader has no more data
// to give. The return values are the number of bytes to advance the input
// and the next token to return to the user, if any, plus an error, if any.
//
// Scanning stops if the function returns an error, in which case some of
// the input may be discarded. If that error is [ErrFinalToken], scanning
// stops with no error. A non-nil token delivered with [ErrFinalToken]
// will be the last token, and a nil token with [ErrFinalToken]
// immediately stops the scanning.
// the input may be discarded. If that error is ErrFinalToken, scanning
// stops with no error.
//
// Otherwise, the [Scanner] advances the input. If the token is not nil,
// the [Scanner] returns it to the user. If the token is nil, the
// Otherwise, the Scanner advances the input. If the token is not nil,
// the Scanner returns it to the user. If the token is nil, the
// Scanner reads more data and continues scanning; if there is no more
// data--if atEOF was true--the [Scanner] returns. If the data does not
// data--if atEOF was true--the Scanner returns. If the data does not
// yet hold a complete token, for instance if it has no newline while
// scanning lines, a [SplitFunc] can return (0, nil, nil) to signal the
// [Scanner] to read more data into the slice and try again with a
// scanning lines, a SplitFunc can return (0, nil, nil) to signal the
// Scanner to read more data into the slice and try again with a
// longer slice starting at the same point in the input.
//
// The function is never called with an empty data slice unless atEOF
@@ -76,7 +74,7 @@ var (
const (
// MaxScanTokenSize is the maximum size used to buffer a token
// unless the user provides an explicit buffer with [Scanner.Buffer].
// unless the user provides an explicit buffer with Scanner.Buffer.
// The actual maximum token size may be smaller as the buffer
// may need to include, for instance, a newline.
MaxScanTokenSize = 64 * 1024
@@ -84,8 +82,8 @@ const (
startBufSize = 4096 // Size of initial allocation for buffer.
)
// NewScanner returns a new [Scanner] to read from r.
// The split function defaults to [ScanLines].
// NewScanner returns a new Scanner to read from r.
// The split function defaults to ScanLines.
func NewScanner(r io.Reader) *Scanner {
return &Scanner{
r: r,
@@ -94,7 +92,7 @@ func NewScanner(r io.Reader) *Scanner {
}
}
// Err returns the first non-EOF error that was encountered by the [Scanner].
// Err returns the first non-EOF error that was encountered by the Scanner.
func (s *Scanner) Err() error {
if s.err == io.EOF {
return nil
@@ -102,36 +100,34 @@ func (s *Scanner) Err() error {
return s.err
}
// Bytes returns the most recent token generated by a call to [Scanner.Scan].
// Bytes returns the most recent token generated by a call to Scan.
// The underlying array may point to data that will be overwritten
// by a subsequent call to Scan. It does no allocation.
func (s *Scanner) Bytes() []byte {
return s.token
}
// Text returns the most recent token generated by a call to [Scanner.Scan]
// Text returns the most recent token generated by a call to Scan
// as a newly allocated string holding its bytes.
func (s *Scanner) Text() string {
return string(s.token)
}
// ErrFinalToken is a special sentinel error value. It is intended to be
// returned by a Split function to indicate that the scanning should stop
// with no error. If the token being delivered with this error is not nil,
// the token is the last token.
//
// returned by a Split function to indicate that the token being delivered
// with the error is the last token and scanning should stop after this one.
// After ErrFinalToken is received by Scan, scanning stops with no error.
// The value is useful to stop processing early or when it is necessary to
// deliver a final empty token (which is different from a nil token).
// One could achieve the same behavior with a custom error value but
// providing one here is tidier.
// deliver a final empty token. One could achieve the same behavior
// with a custom error value but providing one here is tidier.
// See the emptyFinalToken example for a use of this value.
var ErrFinalToken = errors.New("final token")
// Scan advances the [Scanner] to the next token, which will then be
// available through the [Scanner.Bytes] or [Scanner.Text] method. It returns false when
// there are no more tokens, either by reaching the end of the input or an error.
// After Scan returns false, the [Scanner.Err] method will return any error that
// occurred during scanning, except that if it was [io.EOF], [Scanner.Err]
// Scan advances the Scanner to the next token, which will then be
// available through the Bytes or Text method. It returns false when the
// scan stops, either by reaching the end of the input or an error.
// After Scan returns false, the Err method will return any error that
// occurred during scanning, except that if it was io.EOF, Err
// will return nil.
// Scan panics if the split function returns too many empty
// tokens without advancing the input. This is a common error mode for
@@ -152,10 +148,7 @@ func (s *Scanner) Scan() bool {
if err == ErrFinalToken {
s.token = token
s.done = true
// When token is not nil, it means the scanning stops
// with a trailing token, and thus the return value
// should be true to indicate the existence of the token.
return token != nil
return true
}
s.setErr(err)
return false
@@ -205,7 +198,9 @@ func (s *Scanner) Scan() bool {
if newSize == 0 {
newSize = startBufSize
}
newSize = min(newSize, s.maxTokenSize)
if newSize > s.maxTokenSize {
newSize = s.maxTokenSize
}
newBuf := make([]byte, newSize)
copy(newBuf, s.buf[s.start:s.end])
s.buf = newBuf
@@ -260,13 +255,13 @@ func (s *Scanner) setErr(err error) {
}
}
// Buffer sets the initial buffer to use when scanning
// and the maximum size of buffer that may be allocated during scanning.
// The maximum token size must be less than the larger of max and cap(buf).
// If max <= cap(buf), [Scanner.Scan] will use this buffer only and do no allocation.
// Buffer sets the initial buffer to use when scanning and the maximum
// size of buffer that may be allocated during scanning. The maximum
// token size is the larger of max and cap(buf). If max <= cap(buf),
// Scan will use this buffer only and do no allocation.
//
// By default, [Scanner.Scan] uses an internal buffer and sets the
// maximum token size to [MaxScanTokenSize].
// By default, Scan uses an internal buffer and sets the
// maximum token size to MaxScanTokenSize.
//
// Buffer panics if it is called after scanning has started.
func (s *Scanner) Buffer(buf []byte, max int) {
@@ -277,8 +272,8 @@ func (s *Scanner) Buffer(buf []byte, max int) {
s.maxTokenSize = max
}
// Split sets the split function for the [Scanner].
// The default split function is [ScanLines].
// Split sets the split function for the Scanner.
// The default split function is ScanLines.
//
// Split panics if it is called after scanning has started.
func (s *Scanner) Split(split SplitFunc) {
@@ -290,7 +285,7 @@ func (s *Scanner) Split(split SplitFunc) {
// Split functions
// ScanBytes is a split function for a [Scanner] that returns each byte as a token.
// ScanBytes is a split function for a Scanner that returns each byte as a token.
func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
@@ -300,7 +295,7 @@ func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) {
var errorRune = []byte(string(utf8.RuneError))
// ScanRunes is a split function for a [Scanner] that returns each
// ScanRunes is a split function for a Scanner that returns each
// UTF-8-encoded rune as a token. The sequence of runes returned is
// equivalent to that from a range loop over the input as a string, which
// means that erroneous UTF-8 encodings translate to U+FFFD = "\xef\xbf\xbd".
@@ -346,7 +341,7 @@ func dropCR(data []byte) []byte {
return data
}
// ScanLines is a split function for a [Scanner] that returns each line of
// ScanLines is a split function for a Scanner that returns each line of
// text, stripped of any trailing end-of-line marker. The returned line may
// be empty. The end-of-line marker is one optional carriage return followed
// by one mandatory newline. In regular expression notation, it is `\r?\n`.
@@ -393,7 +388,7 @@ func isSpace(r rune) bool {
return false
}
// ScanWords is a split function for a [Scanner] that returns each
// ScanWords is a split function for a Scanner that returns each
// space-separated word of text, with surrounding spaces deleted. It will
// never return an empty string. The definition of space is set by
// unicode.IsSpace.

View File

@@ -68,7 +68,7 @@ func TestScanRune(t *testing.T) {
var i, runeCount int
var expect rune
// Use a string range loop to validate the sequence of runes.
for i, expect = range test {
for i, expect = range string(test) {
if !s.Scan() {
break
}

View File

@@ -6,12 +6,8 @@
# Usage: buildall.bash [-e] [pattern]
#
# buildall.bash builds the standard library for all Go-supported
# architectures.
#
# Originally the Go build system used it as a smoke test to quickly
# flag portability issues in builders named "misc-compile" or "all-compile".
# As of CL 464955, the build system uses make.bash -compile-only instead,
# so this script no longer runs in any automated fashion.
# architectures. It is used by the "misc-compile" trybot builders,
# as a smoke test to quickly flag portability issues.
#
# Options:
# -e: stop at first failure

View File

@@ -284,10 +284,9 @@ func panic(v any)
// by restoring normal execution and retrieves the error value passed to the
// call of panic. If recover is called outside the deferred function it will
// not stop a panicking sequence. In this case, or when the goroutine is not
// panicking, recover returns nil.
//
// Prior to Go 1.21, recover would also return nil if panic is called with
// a nil argument. See [panic] for details.
// panicking, or if the argument supplied to panic was nil, recover returns
// nil. Thus the return value from recover reports whether the goroutine is
// panicking.
func recover() any
// The print built-in function formats its arguments in an

View File

@@ -98,18 +98,3 @@ func TestIndexNearPageBoundary(t *testing.T) {
}
q[len(q)-1] = 0
}
func TestCountNearPageBoundary(t *testing.T) {
t.Parallel()
b := dangerousSlice(t)
for i := range b {
c := Count(b[i:], []byte{1})
if c != 0 {
t.Fatalf("Count(b[%d:], {1})=%d, want 0\n", i, c)
}
c = Count(b[:i], []byte{0})
if c != i {
t.Fatalf("Count(b[:%d], {0})=%d, want %d\n", i, c, i)
}
}
}

View File

@@ -15,7 +15,7 @@ import (
// smallBufferSize is an initial allocation minimal capacity.
const smallBufferSize = 64
// A Buffer is a variable-sized buffer of bytes with [Buffer.Read] and [Buffer.Write] methods.
// A Buffer is a variable-sized buffer of bytes with Read and Write methods.
// The zero value for Buffer is an empty buffer ready to use.
type Buffer struct {
buf []byte // contents are the bytes buf[off : len(buf)]
@@ -48,19 +48,19 @@ const maxInt = int(^uint(0) >> 1)
// Bytes returns a slice of length b.Len() holding the unread portion of the buffer.
// The slice is valid for use only until the next buffer modification (that is,
// only until the next call to a method like [Buffer.Read], [Buffer.Write], [Buffer.Reset], or [Buffer.Truncate]).
// only until the next call to a method like Read, Write, Reset, or Truncate).
// The slice aliases the buffer content at least until the next buffer modification,
// so immediate changes to the slice will affect the result of future reads.
func (b *Buffer) Bytes() []byte { return b.buf[b.off:] }
// AvailableBuffer returns an empty buffer with b.Available() capacity.
// This buffer is intended to be appended to and
// passed to an immediately succeeding [Buffer.Write] call.
// passed to an immediately succeeding Write call.
// The buffer is only valid until the next write operation on b.
func (b *Buffer) AvailableBuffer() []byte { return b.buf[len(b.buf):] }
// String returns the contents of the unread portion of the buffer
// as a string. If the [Buffer] is a nil pointer, it returns "<nil>".
// as a string. If the Buffer is a nil pointer, it returns "<nil>".
//
// To build strings more efficiently, see the strings.Builder type.
func (b *Buffer) String() string {
@@ -102,7 +102,7 @@ func (b *Buffer) Truncate(n int) {
// Reset resets the buffer to be empty,
// but it retains the underlying storage for use by future writes.
// Reset is the same as [Buffer.Truncate](0).
// Reset is the same as Truncate(0).
func (b *Buffer) Reset() {
b.buf = b.buf[:0]
b.off = 0
@@ -160,7 +160,7 @@ func (b *Buffer) grow(n int) int {
// another n bytes. After Grow(n), at least n bytes can be written to the
// buffer without another allocation.
// If n is negative, Grow will panic.
// If the buffer can't grow it will panic with [ErrTooLarge].
// If the buffer can't grow it will panic with ErrTooLarge.
func (b *Buffer) Grow(n int) {
if n < 0 {
panic("bytes.Buffer.Grow: negative count")
@@ -171,7 +171,7 @@ func (b *Buffer) Grow(n int) {
// Write appends the contents of p to the buffer, growing the buffer as
// needed. The return value n is the length of p; err is always nil. If the
// buffer becomes too large, Write will panic with [ErrTooLarge].
// buffer becomes too large, Write will panic with ErrTooLarge.
func (b *Buffer) Write(p []byte) (n int, err error) {
b.lastRead = opInvalid
m, ok := b.tryGrowByReslice(len(p))
@@ -183,7 +183,7 @@ func (b *Buffer) Write(p []byte) (n int, err error) {
// WriteString appends the contents of s to the buffer, growing the buffer as
// needed. The return value n is the length of s; err is always nil. If the
// buffer becomes too large, WriteString will panic with [ErrTooLarge].
// buffer becomes too large, WriteString will panic with ErrTooLarge.
func (b *Buffer) WriteString(s string) (n int, err error) {
b.lastRead = opInvalid
m, ok := b.tryGrowByReslice(len(s))
@@ -194,7 +194,7 @@ func (b *Buffer) WriteString(s string) (n int, err error) {
}
// MinRead is the minimum slice size passed to a Read call by
// [Buffer.ReadFrom]. As long as the [Buffer] has at least MinRead bytes beyond
// Buffer.ReadFrom. As long as the Buffer has at least MinRead bytes beyond
// what is required to hold the contents of r, ReadFrom will not grow the
// underlying buffer.
const MinRead = 512
@@ -202,7 +202,7 @@ const MinRead = 512
// ReadFrom reads data from r until EOF and appends it to the buffer, growing
// the buffer as needed. The return value n is the number of bytes read. Any
// error except io.EOF encountered during the read is also returned. If the
// buffer becomes too large, ReadFrom will panic with [ErrTooLarge].
// buffer becomes too large, ReadFrom will panic with ErrTooLarge.
func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) {
b.lastRead = opInvalid
for {
@@ -279,9 +279,9 @@ func (b *Buffer) WriteTo(w io.Writer) (n int64, err error) {
}
// WriteByte appends the byte c to the buffer, growing the buffer as needed.
// The returned error is always nil, but is included to match [bufio.Writer]'s
// The returned error is always nil, but is included to match bufio.Writer's
// WriteByte. If the buffer becomes too large, WriteByte will panic with
// [ErrTooLarge].
// ErrTooLarge.
func (b *Buffer) WriteByte(c byte) error {
b.lastRead = opInvalid
m, ok := b.tryGrowByReslice(1)
@@ -294,8 +294,8 @@ func (b *Buffer) WriteByte(c byte) error {
// WriteRune appends the UTF-8 encoding of Unicode code point r to the
// buffer, returning its length and an error, which is always nil but is
// included to match [bufio.Writer]'s WriteRune. The buffer is grown as needed;
// if it becomes too large, WriteRune will panic with [ErrTooLarge].
// included to match bufio.Writer's WriteRune. The buffer is grown as needed;
// if it becomes too large, WriteRune will panic with ErrTooLarge.
func (b *Buffer) WriteRune(r rune) (n int, err error) {
// Compare as uint32 to correctly handle negative runes.
if uint32(r) < utf8.RuneSelf {
@@ -334,7 +334,7 @@ func (b *Buffer) Read(p []byte) (n int, err error) {
}
// Next returns a slice containing the next n bytes from the buffer,
// advancing the buffer as if the bytes had been returned by [Buffer.Read].
// advancing the buffer as if the bytes had been returned by Read.
// If there are fewer than n bytes in the buffer, Next returns the entire buffer.
// The slice is only valid until the next call to a read or write method.
func (b *Buffer) Next(n int) []byte {
@@ -388,10 +388,10 @@ func (b *Buffer) ReadRune() (r rune, size int, err error) {
return r, n, nil
}
// UnreadRune unreads the last rune returned by [Buffer.ReadRune].
// UnreadRune unreads the last rune returned by ReadRune.
// If the most recent read or write operation on the buffer was
// not a successful [Buffer.ReadRune], UnreadRune returns an error. (In this regard
// it is stricter than [Buffer.UnreadByte], which will unread the last byte
// not a successful ReadRune, UnreadRune returns an error. (In this regard
// it is stricter than UnreadByte, which will unread the last byte
// from any read operation.)
func (b *Buffer) UnreadRune() error {
if b.lastRead <= opInvalid {
@@ -460,23 +460,23 @@ func (b *Buffer) ReadString(delim byte) (line string, err error) {
return string(slice), err
}
// NewBuffer creates and initializes a new [Buffer] using buf as its
// initial contents. The new [Buffer] takes ownership of buf, and the
// NewBuffer creates and initializes a new Buffer using buf as its
// initial contents. The new Buffer takes ownership of buf, and the
// caller should not use buf after this call. NewBuffer is intended to
// prepare a [Buffer] to read existing data. It can also be used to set
// prepare a Buffer to read existing data. It can also be used to set
// the initial size of the internal buffer for writing. To do that,
// buf should have the desired capacity but a length of zero.
//
// In most cases, new([Buffer]) (or just declaring a [Buffer] variable) is
// sufficient to initialize a [Buffer].
// In most cases, new(Buffer) (or just declaring a Buffer variable) is
// sufficient to initialize a Buffer.
func NewBuffer(buf []byte) *Buffer { return &Buffer{buf: buf} }
// NewBufferString creates and initializes a new [Buffer] using string s as its
// NewBufferString creates and initializes a new Buffer using string s as its
// initial contents. It is intended to prepare a buffer to read an existing
// string.
//
// In most cases, new([Buffer]) (or just declaring a [Buffer] variable) is
// sufficient to initialize a [Buffer].
// In most cases, new(Buffer) (or just declaring a Buffer variable) is
// sufficient to initialize a Buffer.
func NewBufferString(s string) *Buffer {
return &Buffer{buf: []byte(s)}
}

View File

@@ -112,7 +112,7 @@ func LastIndex(s, sep []byte) int {
case n == 0:
return len(s)
case n == 1:
return bytealg.LastIndexByte(s, sep[0])
return LastIndexByte(s, sep[0])
case n == len(s):
if Equal(s, sep) {
return 0
@@ -121,12 +121,35 @@ func LastIndex(s, sep []byte) int {
case n > len(s):
return -1
}
return bytealg.LastIndexRabinKarp(s, sep)
// Rabin-Karp search from the end of the string
hashss, pow := bytealg.HashStrRevBytes(sep)
last := len(s) - n
var h uint32
for i := len(s) - 1; i >= last; i-- {
h = h*bytealg.PrimeRK + uint32(s[i])
}
if h == hashss && Equal(s[last:], sep) {
return last
}
for i := last - 1; i >= 0; i-- {
h *= bytealg.PrimeRK
h += uint32(s[i])
h -= pow * uint32(s[i+n])
if h == hashss && Equal(s[i:i+n], sep) {
return i
}
}
return -1
}
// LastIndexByte returns the index of the last instance of c in s, or -1 if c is not present in s.
func LastIndexByte(s []byte, c byte) int {
return bytealg.LastIndexByte(s, c)
for i := len(s) - 1; i >= 0; i-- {
if s[i] == c {
return i
}
}
return -1
}
// IndexRune interprets s as a sequence of UTF-8-encoded code points.
@@ -534,12 +557,12 @@ func Join(s [][]byte, sep []byte) []byte {
return b
}
// HasPrefix reports whether the byte slice s begins with prefix.
// HasPrefix tests whether the byte slice s begins with prefix.
func HasPrefix(s, prefix []byte) bool {
return len(s) >= len(prefix) && Equal(s[0:len(prefix)], prefix)
}
// HasSuffix reports whether the byte slice s ends with suffix.
// HasSuffix tests whether the byte slice s ends with suffix.
func HasSuffix(s, suffix []byte) bool {
return len(s) >= len(suffix) && Equal(s[len(s)-len(suffix):], suffix)
}
@@ -1313,7 +1336,7 @@ func Index(s, sep []byte) int {
// we should cutover at even larger average skips,
// because Equal becomes that much more expensive.
// This code does not take that effect into account.
j := bytealg.IndexRabinKarp(s[i:], sep)
j := bytealg.IndexRabinKarpBytes(s[i:], sep)
if j < 0 {
return -1
}

View File

@@ -1,21 +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 js && wasm
package bytes_test
import (
"bytes"
"testing"
)
func TestIssue65571(t *testing.T) {
b := make([]byte, 1<<31+1)
b[1<<31] = 1
i := bytes.IndexByte(b, 1)
if i != 1<<31 {
t.Errorf("IndexByte(b, 1) = %d; want %d", i, 1<<31)
}
}

View File

@@ -7,6 +7,7 @@ package bytes_test
import (
. "bytes"
"fmt"
"internal/testenv"
"testing"
)
@@ -72,7 +73,7 @@ func TestCompareBytes(t *testing.T) {
}
lengths = append(lengths, 256, 512, 1024, 1333, 4095, 4096, 4097)
if !testing.Short() {
if !testing.Short() || testenv.Builder() != "" {
lengths = append(lengths, 65535, 65536, 65537, 99999)
}

View File

@@ -81,9 +81,9 @@ func ExampleBuffer_Next() {
var b bytes.Buffer
b.Grow(64)
b.Write([]byte("abcde"))
fmt.Printf("%s\n", b.Next(2))
fmt.Printf("%s\n", b.Next(2))
fmt.Printf("%s", b.Next(2))
fmt.Printf("%s\n", string(b.Next(2)))
fmt.Printf("%s\n", string(b.Next(2)))
fmt.Printf("%s", string(b.Next(2)))
// Output:
// ab
// cd
@@ -212,17 +212,6 @@ func ExampleContainsRune() {
// false
}
func ExampleContainsFunc() {
f := func(r rune) bool {
return r >= 'a' && r <= 'z'
}
fmt.Println(bytes.ContainsFunc([]byte("HELLO"), f))
fmt.Println(bytes.ContainsFunc([]byte("World"), f))
// Output:
// false
// true
}
func ExampleCount() {
fmt.Println(bytes.Count([]byte("cheese"), []byte("e")))
fmt.Println(bytes.Count([]byte("five"), []byte(""))) // before & after each rune

View File

@@ -13,7 +13,7 @@ import (
// A Reader implements the io.Reader, io.ReaderAt, io.WriterTo, io.Seeker,
// io.ByteScanner, and io.RuneScanner interfaces by reading from
// a byte slice.
// Unlike a [Buffer], a Reader is read-only and supports seeking.
// Unlike a Buffer, a Reader is read-only and supports seeking.
// The zero value for Reader operates like a Reader of an empty slice.
type Reader struct {
s []byte
@@ -31,11 +31,11 @@ func (r *Reader) Len() int {
}
// Size returns the original length of the underlying byte slice.
// Size is the number of bytes available for reading via [Reader.ReadAt].
// The result is unaffected by any method calls except [Reader.Reset].
// Size is the number of bytes available for reading via ReadAt.
// The result is unaffected by any method calls except Reset.
func (r *Reader) Size() int64 { return int64(len(r.s)) }
// Read implements the [io.Reader] interface.
// Read implements the io.Reader interface.
func (r *Reader) Read(b []byte) (n int, err error) {
if r.i >= int64(len(r.s)) {
return 0, io.EOF
@@ -46,7 +46,7 @@ func (r *Reader) Read(b []byte) (n int, err error) {
return
}
// ReadAt implements the [io.ReaderAt] interface.
// ReadAt implements the io.ReaderAt interface.
func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) {
// cannot modify state - see io.ReaderAt
if off < 0 {
@@ -62,7 +62,7 @@ func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) {
return
}
// ReadByte implements the [io.ByteReader] interface.
// ReadByte implements the io.ByteReader interface.
func (r *Reader) ReadByte() (byte, error) {
r.prevRune = -1
if r.i >= int64(len(r.s)) {
@@ -73,7 +73,7 @@ func (r *Reader) ReadByte() (byte, error) {
return b, nil
}
// UnreadByte complements [Reader.ReadByte] in implementing the [io.ByteScanner] interface.
// UnreadByte complements ReadByte in implementing the io.ByteScanner interface.
func (r *Reader) UnreadByte() error {
if r.i <= 0 {
return errors.New("bytes.Reader.UnreadByte: at beginning of slice")
@@ -83,7 +83,7 @@ func (r *Reader) UnreadByte() error {
return nil
}
// ReadRune implements the [io.RuneReader] interface.
// ReadRune implements the io.RuneReader interface.
func (r *Reader) ReadRune() (ch rune, size int, err error) {
if r.i >= int64(len(r.s)) {
r.prevRune = -1
@@ -99,7 +99,7 @@ func (r *Reader) ReadRune() (ch rune, size int, err error) {
return
}
// UnreadRune complements [Reader.ReadRune] in implementing the [io.RuneScanner] interface.
// UnreadRune complements ReadRune in implementing the io.RuneScanner interface.
func (r *Reader) UnreadRune() error {
if r.i <= 0 {
return errors.New("bytes.Reader.UnreadRune: at beginning of slice")
@@ -112,7 +112,7 @@ func (r *Reader) UnreadRune() error {
return nil
}
// Seek implements the [io.Seeker] interface.
// Seek implements the io.Seeker interface.
func (r *Reader) Seek(offset int64, whence int) (int64, error) {
r.prevRune = -1
var abs int64
@@ -133,7 +133,7 @@ func (r *Reader) Seek(offset int64, whence int) (int64, error) {
return abs, nil
}
// WriteTo implements the [io.WriterTo] interface.
// WriteTo implements the io.WriterTo interface.
func (r *Reader) WriteTo(w io.Writer) (n int64, err error) {
r.prevRune = -1
if r.i >= int64(len(r.s)) {
@@ -152,8 +152,8 @@ func (r *Reader) WriteTo(w io.Writer) (n int64, err error) {
return
}
// Reset resets the [Reader.Reader] to be reading from b.
// Reset resets the Reader to be reading from b.
func (r *Reader) Reset(b []byte) { *r = Reader{b, 0, -1} }
// NewReader returns a new [Reader.Reader] reading from b.
// NewReader returns a new Reader reading from b.
func NewReader(b []byte) *Reader { return &Reader{b, 0, -1} }

View File

@@ -2,10 +2,9 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This package computes the exported API of a set of Go packages.
// Package api computes the exported API of a set of Go packages.
// It is only a test, not a command, nor a usefully importable package.
package main
package api
import (
"bufio"
@@ -106,7 +105,7 @@ func Check(t *testing.T) {
}
var nextFiles []string
if v := runtime.Version(); strings.Contains(v, "devel") || strings.Contains(v, "beta") {
if strings.Contains(runtime.Version(), "devel") {
next, err := filepath.Glob(filepath.Join(testenv.GOROOT(t), "api/next/*.txt"))
if err != nil {
t.Fatal(err)
@@ -490,8 +489,7 @@ func (w *Walker) loadImports() {
if w.context.Dir != "" {
cmd.Dir = w.context.Dir
}
cmd.Stderr = os.Stderr
out, err := cmd.Output()
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatalf("loading imports: %v\n%s", err, out)
}
@@ -957,17 +955,17 @@ func (w *Walker) emitType(obj *types.TypeName) {
if w.isDeprecated(obj) {
w.emitf("type %s //deprecated", name)
}
typ := obj.Type()
if obj.IsAlias() {
w.emitf("type %s = %s", name, w.typeString(typ))
return
}
if tparams := obj.Type().(*types.Named).TypeParams(); tparams != nil {
var buf bytes.Buffer
buf.WriteString(name)
w.writeTypeParams(&buf, tparams, true)
name = buf.String()
}
typ := obj.Type()
if obj.IsAlias() {
w.emitf("type %s = %s", name, w.typeString(typ))
return
}
switch typ := typ.Underlying().(type) {
case *types.Struct:
w.emitStructType(name, typ)

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
package api
import (
"flag"
@@ -285,25 +285,6 @@ func TestIssue41358(t *testing.T) {
}
}
func TestIssue64958(t *testing.T) {
defer func() {
if x := recover(); x != nil {
t.Errorf("expected no panic; recovered %v", x)
}
}()
testenv.MustHaveGoBuild(t)
for _, context := range contexts {
w := NewWalker(context, "testdata/src/issue64958")
pkg, err := w.importFrom("p", "", 0)
if err != nil {
t.Errorf("expected no error importing; got %T", err)
}
w.export(pkg)
}
}
func TestCheck(t *testing.T) {
if !*flagCheck {
t.Skip("-check not specified")

View File

@@ -4,7 +4,7 @@
//go:build boringcrypto
package main
package api
import (
"fmt"

View File

@@ -1,3 +0,0 @@
package p
type BasicAlias = uint8

View File

@@ -33,8 +33,6 @@ Flags:
Dump instructions as they are parsed.
-dynlink
Support references to Go symbols defined in other shared libraries.
-e
No limit on number of errors reported.
-gensymabis
Write symbol ABI information to output file. Don't assemble.
-o file
@@ -47,8 +45,6 @@ Flags:
Enable spectre mitigations in list (all, ret).
-trimpath prefix
Remove prefix from recorded source file paths.
-v
Print debug output.
Input language:

View File

@@ -445,7 +445,7 @@ func (p *Parser) asmJump(op obj.As, cond string, a []obj.Addr) {
// BC x,CR0EQ,...
// BC x,CR1LT,...
// BC x,CR1GT,...
// The first and second cases demonstrate a symbol name which is
// The first and second case demonstrate a symbol name which is
// effectively discarded. In these cases, the offset determines
// the CR bit.
prog.Reg = a[1].Reg
@@ -909,7 +909,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
p.append(prog, cond, true)
}
// symbolName returns the symbol name, or an error string if none is available.
// symbolName returns the symbol name, or an error string if none if available.
func symbolName(addr *obj.Addr) string {
if addr.Sym != nil {
return addr.Sym.Name

View File

@@ -30,7 +30,7 @@ func testEndToEnd(t *testing.T, goarch, file string) {
architecture, ctxt := setArch(goarch)
architecture.Init(ctxt)
lexer := lex.NewLexer(input)
parser := NewParser(ctxt, architecture, lexer)
parser := NewParser(ctxt, architecture, lexer, false)
pList := new(obj.Plist)
var ok bool
testOut = new(strings.Builder) // The assembler writes test output to this buffer.
@@ -68,11 +68,6 @@ Diff:
continue
}
// Ignore GLOBL.
if strings.HasPrefix(line, "GLOBL ") {
continue
}
// The general form of a test input line is:
// // comment
// INST args [// printed form] [// hex encoding]
@@ -141,17 +136,11 @@ Diff:
// Turn relative (PC) into absolute (PC) automatically,
// so that most branch instructions don't need comments
// giving the absolute form.
if len(f) > 0 && strings.Contains(printed, "(PC)") {
index := len(f) - 1
suf := "(PC)"
for !strings.HasSuffix(f[index], suf) {
index--
suf = "(PC),"
}
str := f[index]
n, err := strconv.Atoi(str[:len(str)-len(suf)])
if len(f) > 0 && strings.HasSuffix(printed, "(PC)") {
last := f[len(f)-1]
n, err := strconv.Atoi(last[:len(last)-len("(PC)")])
if err == nil {
f[index] = fmt.Sprintf("%d%s", seq+n, suf)
f[len(f)-1] = fmt.Sprintf("%d(PC)", seq+n)
}
}
@@ -197,7 +186,7 @@ Diff:
t.Errorf(format, args...)
ok = false
}
obj.Flushplist(ctxt, pList, nil)
obj.Flushplist(ctxt, pList, nil, "")
for p := top; p != nil; p = p.Link {
if p.As == obj.ATEXT {
@@ -283,9 +272,8 @@ var (
func testErrors(t *testing.T, goarch, file string, flags ...string) {
input := filepath.Join("testdata", file+".s")
architecture, ctxt := setArch(goarch)
architecture.Init(ctxt)
lexer := lex.NewLexer(input)
parser := NewParser(ctxt, architecture, lexer)
parser := NewParser(ctxt, architecture, lexer, false)
pList := new(obj.Plist)
var ok bool
ctxt.Bso = bufio.NewWriter(os.Stdout)
@@ -311,7 +299,7 @@ func testErrors(t *testing.T, goarch, file string, flags ...string) {
}
}
pList.Firstpc, ok = parser.Parse()
obj.Flushplist(ctxt, pList, nil)
obj.Flushplist(ctxt, pList, nil, "")
if ok && !failed {
t.Errorf("asm: %s had no errors", file)
}
@@ -378,10 +366,10 @@ func Test386EndToEnd(t *testing.T) {
}
func TestARMEndToEnd(t *testing.T) {
defer func(old int) { buildcfg.GOARM.Version = old }(buildcfg.GOARM.Version)
defer func(old int) { buildcfg.GOARM = old }(buildcfg.GOARM)
for _, goarm := range []int{5, 6, 7} {
t.Logf("GOARM=%d", goarm)
buildcfg.GOARM.Version = goarm
buildcfg.GOARM = goarm
testEndToEnd(t, "arm", "arm")
if goarm == 6 {
testEndToEnd(t, "arm", "armv6")

View File

@@ -57,7 +57,7 @@ var exprTests = []exprTest{
}
func TestExpr(t *testing.T) {
p := NewParser(nil, nil, nil) // Expression evaluation uses none of these fields of the parser.
p := NewParser(nil, nil, nil, false) // Expression evaluation uses none of these fields of the parser.
for i, test := range exprTests {
p.start(lex.Tokenize(test.input))
result := int64(p.expr())
@@ -113,7 +113,7 @@ func TestBadExpr(t *testing.T) {
}
func runBadTest(i int, test badExprTest, t *testing.T) (err error) {
p := NewParser(nil, nil, nil) // Expression evaluation uses none of these fields of the parser.
p := NewParser(nil, nil, nil, false) // Expression evaluation uses none of these fields of the parser.
p.start(lex.Tokenize(test.input))
return tryParse(t, func() {
p.expr()

View File

@@ -39,7 +39,7 @@ func testBadInstParser(t *testing.T, goarch string, tests []badInstTest) {
for i, test := range tests {
arch, ctxt := setArch(goarch)
tokenizer := lex.NewTokenizer("", strings.NewReader(test.input+"\n"), nil)
parser := NewParser(ctxt, arch, tokenizer)
parser := NewParser(ctxt, arch, tokenizer, false)
err := tryParse(t, func() {
parser.Parse()

View File

@@ -23,14 +23,12 @@ func setArch(goarch string) (*arch.Arch, *obj.Link) {
if architecture == nil {
panic("asm: unrecognized architecture " + goarch)
}
ctxt := obj.Linknew(architecture.LinkArch)
ctxt.Pkgpath = "pkg"
return architecture, ctxt
return architecture, obj.Linknew(architecture.LinkArch)
}
func newParser(goarch string) *Parser {
architecture, ctxt := setArch(goarch)
return NewParser(ctxt, architecture, nil)
return NewParser(ctxt, architecture, nil, false)
}
// tryParse executes parse func in panicOnError=true context.
@@ -78,7 +76,7 @@ func testOperandParser(t *testing.T, parser *Parser, tests []operandTest) {
addr := obj.Addr{}
parser.operand(&addr)
var result string
if parser.allowABI {
if parser.compilingRuntime {
result = obj.DconvWithABIDetail(&emptyProg, &addr)
} else {
result = obj.Dconv(&emptyProg, &addr)
@@ -93,7 +91,7 @@ func TestAMD64OperandParser(t *testing.T) {
parser := newParser("amd64")
testOperandParser(t, parser, amd64OperandTests)
testBadOperandParser(t, parser, amd64BadOperandTests)
parser.allowABI = true
parser.compilingRuntime = true
testOperandParser(t, parser, amd64RuntimeOperandTests)
testBadOperandParser(t, parser, amd64BadOperandRuntimeTests)
}
@@ -306,8 +304,8 @@ var amd64OperandTests = []operandTest{
{"x·y+8(SB)", "x.y+8(SB)"},
{"x·y+8(SP)", "x.y+8(SP)"},
{"y+56(FP)", "y+56(FP)"},
{"·AddUint32(SB)", "pkg.AddUint32(SB)"},
{"·callReflect(SB)", "pkg.callReflect(SB)"},
{"·AddUint32(SB)", "\"\".AddUint32(SB)"},
{"·callReflect(SB)", "\"\".callReflect(SB)"},
{"[X0-X0]", "[X0-X0]"},
{"[ Z9 - Z12 ]", "[Z9-Z12]"},
{"[X0-AX]", "[X0-AX]"},
@@ -393,8 +391,8 @@ var x86OperandTests = []operandTest{
{"sec+4(FP)", "sec+4(FP)"},
{"shifts<>(SB)(CX*8)", "shifts<>(SB)(CX*8)"},
{"x+4(FP)", "x+4(FP)"},
{"·AddUint32(SB)", "pkg.AddUint32(SB)"},
{"·reflectcall(SB)", "pkg.reflectcall(SB)"},
{"·AddUint32(SB)", "\"\".AddUint32(SB)"},
{"·reflectcall(SB)", "\"\".reflectcall(SB)"},
{"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.
}
@@ -442,7 +440,7 @@ var armOperandTests = []operandTest{
{"gosave<>(SB)", "gosave<>(SB)"},
{"retlo+12(FP)", "retlo+12(FP)"},
{"runtime·gogo(SB)", "runtime.gogo(SB)"},
{"·AddUint32(SB)", "pkg.AddUint32(SB)"},
{"·AddUint32(SB)", "\"\".AddUint32(SB)"},
{"(R1, R3)", "(R1, R3)"},
{"[R0,R1,g,R15", ""}, // Issue 11764 - asm hung parsing ']' missing register lists.
{"[):[o-FP", ""}, // Issue 12469 - there was no infinite loop for ARM; these are just sanity checks.
@@ -631,8 +629,8 @@ var ppc64OperandTests = []operandTest{
{"g", "g"},
{"ret+8(FP)", "ret+8(FP)"},
{"runtime·abort(SB)", "runtime.abort(SB)"},
{"·AddUint32(SB)", "pkg.AddUint32(SB)"},
{"·trunc(SB)", "pkg.trunc(SB)"},
{"·AddUint32(SB)", "\"\".AddUint32(SB)"},
{"·trunc(SB)", "\"\".trunc(SB)"},
{"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.
}
@@ -664,7 +662,7 @@ var arm64OperandTests = []operandTest{
{"$(8-1)", "$7"},
{"a+0(FP)", "a(FP)"},
{"a1+8(FP)", "a1+8(FP)"},
{"·AddInt32(SB)", `pkg.AddInt32(SB)`},
{"·AddInt32(SB)", `"".AddInt32(SB)`},
{"runtime·divWVW(SB)", "runtime.divWVW(SB)"},
{"$argframe+0(FP)", "$argframe(FP)"},
{"$asmcgocall<>(SB)", "$asmcgocall<>(SB)"},
@@ -765,8 +763,8 @@ var mips64OperandTests = []operandTest{
{"RSB", "R28"},
{"ret+8(FP)", "ret+8(FP)"},
{"runtime·abort(SB)", "runtime.abort(SB)"},
{"·AddUint32(SB)", "pkg.AddUint32(SB)"},
{"·trunc(SB)", "pkg.trunc(SB)"},
{"·AddUint32(SB)", "\"\".AddUint32(SB)"},
{"·trunc(SB)", "\"\".trunc(SB)"},
{"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.
}
@@ -848,8 +846,8 @@ var mipsOperandTests = []operandTest{
{"g", "g"},
{"ret+8(FP)", "ret+8(FP)"},
{"runtime·abort(SB)", "runtime.abort(SB)"},
{"·AddUint32(SB)", "pkg.AddUint32(SB)"},
{"·trunc(SB)", "pkg.trunc(SB)"},
{"·AddUint32(SB)", "\"\".AddUint32(SB)"},
{"·trunc(SB)", "\"\".trunc(SB)"},
{"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.
}
@@ -930,8 +928,8 @@ var loong64OperandTests = []operandTest{
{"g", "g"},
{"ret+8(FP)", "ret+8(FP)"},
{"runtime·abort(SB)", "runtime.abort(SB)"},
{"·AddUint32(SB)", "pkg.AddUint32(SB)"},
{"·trunc(SB)", "pkg.trunc(SB)"},
{"·AddUint32(SB)", "\"\".AddUint32(SB)"},
{"·trunc(SB)", "\"\".trunc(SB)"},
{"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.
}
@@ -1028,7 +1026,7 @@ var s390xOperandTests = []operandTest{
{"g", "g"},
{"ret+8(FP)", "ret+8(FP)"},
{"runtime·abort(SB)", "runtime.abort(SB)"},
{"·AddUint32(SB)", "pkg.AddUint32(SB)"},
{"·trunc(SB)", "pkg.trunc(SB)"},
{"·AddUint32(SB)", "\"\".AddUint32(SB)"},
{"·trunc(SB)", "\"\".trunc(SB)"},
{"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.
}

View File

@@ -12,7 +12,6 @@ import (
"log"
"os"
"strconv"
"strings"
"text/scanner"
"unicode/utf8"
@@ -22,33 +21,31 @@ import (
"cmd/internal/obj"
"cmd/internal/obj/arm64"
"cmd/internal/obj/x86"
"cmd/internal/objabi"
"cmd/internal/src"
"cmd/internal/sys"
)
type Parser struct {
lex lex.TokenReader
lineNum int // Line number in source file.
errorLine int // Line number of last error.
errorCount int // Number of errors.
sawCode bool // saw code in this file (as opposed to comments and blank lines)
pc int64 // virtual PC; count of Progs; doesn't advance for GLOBL or DATA.
input []lex.Token
inputPos int
pendingLabels []string // Labels to attach to next instruction.
labels map[string]*obj.Prog
toPatch []Patch
addr []obj.Addr
arch *arch.Arch
ctxt *obj.Link
firstProg *obj.Prog
lastProg *obj.Prog
dataAddr map[string]int64 // Most recent address for DATA for this symbol.
isJump bool // Instruction being assembled is a jump.
allowABI bool // Whether ABI selectors are allowed.
pkgPrefix string // Prefix to add to local symbols.
errorWriter io.Writer
lex lex.TokenReader
lineNum int // Line number in source file.
errorLine int // Line number of last error.
errorCount int // Number of errors.
sawCode bool // saw code in this file (as opposed to comments and blank lines)
pc int64 // virtual PC; count of Progs; doesn't advance for GLOBL or DATA.
input []lex.Token
inputPos int
pendingLabels []string // Labels to attach to next instruction.
labels map[string]*obj.Prog
toPatch []Patch
addr []obj.Addr
arch *arch.Arch
ctxt *obj.Link
firstProg *obj.Prog
lastProg *obj.Prog
dataAddr map[string]int64 // Most recent address for DATA for this symbol.
isJump bool // Instruction being assembled is a jump.
compilingRuntime bool
errorWriter io.Writer
}
type Patch struct {
@@ -56,20 +53,15 @@ type Patch struct {
label string
}
func NewParser(ctxt *obj.Link, ar *arch.Arch, lexer lex.TokenReader) *Parser {
pkgPrefix := obj.UnlinkablePkg
if ctxt != nil {
pkgPrefix = objabi.PathToPrefix(ctxt.Pkgpath)
}
func NewParser(ctxt *obj.Link, ar *arch.Arch, lexer lex.TokenReader, compilingRuntime bool) *Parser {
return &Parser{
ctxt: ctxt,
arch: ar,
lex: lexer,
labels: make(map[string]*obj.Prog),
dataAddr: make(map[string]int64),
errorWriter: os.Stderr,
allowABI: ctxt != nil && objabi.LookupPkgSpecial(ctxt.Pkgpath).AllowAsmABI,
pkgPrefix: pkgPrefix,
ctxt: ctxt,
arch: ar,
lex: lexer,
labels: make(map[string]*obj.Prog),
dataAddr: make(map[string]int64),
errorWriter: os.Stderr,
compilingRuntime: compilingRuntime,
}
}
@@ -409,7 +401,7 @@ func (p *Parser) operand(a *obj.Addr) {
fallthrough
default:
// We have a symbol. Parse $sym±offset(symkind)
p.symbolReference(a, p.qualifySymbol(name), prefix)
p.symbolReference(a, name, prefix)
}
// fmt.Printf("SYM %s\n", obj.Dconv(&emptyProg, 0, a))
if p.peek() == scanner.EOF {
@@ -777,16 +769,6 @@ func (p *Parser) registerExtension(a *obj.Addr, name string, prefix rune) {
}
}
// qualifySymbol returns name as a package-qualified symbol name. If
// name starts with a period, qualifySymbol prepends the package
// prefix. Otherwise it returns name unchanged.
func (p *Parser) qualifySymbol(name string) string {
if strings.HasPrefix(name, ".") {
name = p.pkgPrefix + name
}
return name
}
// symbolReference parses a symbol that is known not to be a register.
func (p *Parser) symbolReference(a *obj.Addr, name string, prefix rune) {
// Identifier is a name.
@@ -882,7 +864,7 @@ func (p *Parser) symRefAttrs(name string, issueError bool) (bool, obj.ABI) {
isStatic = true
} else if tok == scanner.Ident {
abistr := p.get(scanner.Ident).String()
if !p.allowABI {
if !p.compilingRuntime {
if issueError {
p.errorf("ABI selector only permitted when compiling runtime, reference was to %q", name)
}
@@ -919,7 +901,6 @@ func (p *Parser) funcAddress() (string, obj.ABI, bool) {
if tok.ScanToken != scanner.Ident || p.atStartOfRegister(name) {
return "", obj.ABI0, false
}
name = p.qualifySymbol(name)
// Parse optional <> (indicates a static symbol) or
// <ABIxxx> (selecting text symbol with specific ABI).
noErrMsg := false
@@ -947,7 +928,7 @@ func (p *Parser) funcAddress() (string, obj.ABI, bool) {
}
// registerIndirect parses the general form of a register indirection.
// It can be (R1), (R2*scale), (R1)(R2*scale), (R1)(R2.SXTX<<3) or (R1)(R2<<3)
// It is can be (R1), (R2*scale), (R1)(R2*scale), (R1)(R2.SXTX<<3) or (R1)(R2<<3)
// where R1 may be a simple register or register pair R:R or (R, R) or (R+R).
// Or it might be a pseudo-indirection like (FP).
// We are sitting on the opening parenthesis.
@@ -1205,7 +1186,7 @@ func (p *Parser) registerListX86(a *obj.Addr) {
a.Offset = x86.EncodeRegisterRange(lo, hi)
}
// registerNumber is ARM-specific. It returns the number of the specified register.
// register number is ARM-specific. It returns the number of the specified register.
func (p *Parser) registerNumber(name string) uint16 {
if p.arch.Family == sys.ARM && name == "g" {
return 10

View File

@@ -64,16 +64,16 @@ func TestErroneous(t *testing.T) {
}
testcats := []struct {
allowABI bool
tests []errtest
compilingRuntime bool
tests []errtest
}{
{
allowABI: false,
tests: nonRuntimeTests,
compilingRuntime: false,
tests: nonRuntimeTests,
},
{
allowABI: true,
tests: runtimeTests,
compilingRuntime: true,
tests: runtimeTests,
},
}
@@ -85,7 +85,7 @@ func TestErroneous(t *testing.T) {
for _, cat := range testcats {
for _, test := range cat.tests {
parser.allowABI = cat.allowABI
parser.compilingRuntime = cat.compilingRuntime
parser.errorCount = 0
parser.lineNum++
if !parser.pseudo(test.pseudo, tokenize(test.operands)) {

View File

@@ -870,13 +870,10 @@ jmp_label_3:
BIC.S R0@>R1, R2 // 7021d2e1
// SRL
SRL $0, R5, R6 // 0560a0e1
SRL $1, R5, R6 // a560a0e1
SRL $14, R5, R6 // 2567a0e1
SRL $15, R5, R6 // a567a0e1
SRL $30, R5, R6 // 256fa0e1
SRL $31, R5, R6 // a56fa0e1
SRL $32, R5, R6 // 2560a0e1
SRL.S $14, R5, R6 // 2567b0e1
SRL.S $15, R5, R6 // a567b0e1
SRL.S $30, R5, R6 // 256fb0e1
@@ -895,13 +892,10 @@ jmp_label_3:
SRL.S R5, R7 // 3775b0e1
// SRA
SRA $0, R5, R6 // 0560a0e1
SRA $1, R5, R6 // c560a0e1
SRA $14, R5, R6 // 4567a0e1
SRA $15, R5, R6 // c567a0e1
SRA $30, R5, R6 // 456fa0e1
SRA $31, R5, R6 // c56fa0e1
SRA $32, R5, R6 // 4560a0e1
SRA.S $14, R5, R6 // 4567b0e1
SRA.S $15, R5, R6 // c567b0e1
SRA.S $30, R5, R6 // 456fb0e1
@@ -920,8 +914,6 @@ jmp_label_3:
SRA.S R5, R7 // 5775b0e1
// SLL
SLL $0, R5, R6 // 0560a0e1
SLL $1, R5, R6 // 8560a0e1
SLL $14, R5, R6 // 0567a0e1
SLL $15, R5, R6 // 8567a0e1
SLL $30, R5, R6 // 056fa0e1
@@ -943,20 +935,6 @@ jmp_label_3:
SLL R5, R7 // 1775a0e1
SLL.S R5, R7 // 1775b0e1
// Ops with zero shifts should encode as left shifts
ADD R0<<0, R1, R2 // 002081e0
ADD R0>>0, R1, R2 // 002081e0
ADD R0->0, R1, R2 // 002081e0
ADD R0@>0, R1, R2 // 002081e0
MOVW R0<<0(R1), R2 // 002091e7
MOVW R0>>0(R1), R2 // 002091e7
MOVW R0->0(R1), R2 // 002091e7
MOVW R0@>0(R1), R2 // 002091e7
MOVW R0, R1<<0(R2) // 010082e7
MOVW R0, R1>>0(R2) // 010082e7
MOVW R0, R1->0(R2) // 010082e7
MOVW R0, R1@>0(R2) // 010082e7
// MULA / MULS
MULAWT R1, R2, R3, R4 // c23124e1
MULAWB R1, R2, R3, R4 // 823124e1

View File

@@ -557,92 +557,37 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
FMOVQ 65520(R10), F10 // 4afdff3d
FMOVQ 64(RSP), F11 // eb13c03d
// medium offsets that either fit a single instruction or can use add+ldr/str
MOVD -4095(R17), R3 // 3bfe3fd1630340f9
MOVD -391(R17), R3 // 3b1e06d1630340f9
MOVD -257(R17), R3 // 3b0604d1630340f9
MOVD -256(R17), R3 // 230250f8
MOVD 255(R17), R3 // 23f24ff8
MOVD 256(R17), R3 // 238240f9
MOVD 257(R17), R3 // 3b060491630340f9
MOVD 391(R17), R3 // 3b1e0691630340f9
MOVD 4095(R17), R3 // 3bfe3f91630340f9
// large aligned offset, use two instructions(add+ldr/store).
MOVB R1, 0x1001(R2) // MOVB R1, 4097(R2) // 5b04409161070039
MOVH R1, 0x2002(R2) // MOVH R1, 8194(R2) // 5b08409161070079
MOVW R1, 0x4004(R2) // MOVW R1, 16388(R2) // 5b104091610700b9
MOVD R1, 0x8008(R2) // MOVD R1, 32776(R2) // 5b204091610700f9
FMOVS F1, 0x4004(R2) // FMOVS F1, 16388(R2) // 5b104091610700bd
FMOVD F1, 0x8008(R2) // FMOVD F1, 32776(R2) // 5b204091610700fd
MOVD R0, -4095(R17) // 3bfe3fd1600300f9
MOVD R0, -391(R17) // 3b1e06d1600300f9
MOVD R0, -257(R17) // 3b0604d1600300f9
MOVD R0, -256(R17) // 200210f8
MOVD R0, 255(R17) // 20f20ff8
MOVD R0, 256(R17) // 208200f9
MOVD R0, 257(R17) // 3b060491600300f9
MOVD R0, 391(R17) // 3b1e0691600300f9
MOVD R0, 4095(R17) // 3bfe3f91600300f9
MOVD R0, 4096(R17) // 200208f9
MOVD R3, -4095(R17) // 3bfe3fd1630300f9
MOVD R3, -391(R17) // 3b1e06d1630300f9
MOVD R3, -257(R17) // 3b0604d1630300f9
MOVD R3, -256(R17) // 230210f8
MOVD R3, 255(R17) // 23f20ff8
MOVD R3, 256(R17) // 238200f9
MOVD R3, 257(R17) // 3b060491630300f9
MOVD R3, 391(R17) // 3b1e0691630300f9
MOVD R3, 4095(R17) // 3bfe3f91630300f9
// large aligned offset, use two instructions(add+ldr/str).
MOVB R1, 0x1001(R2) // MOVB R1, 4097(R2) // 5b04409161070039
MOVB R1, 0xffffff(R2) // MOVB R1, 16777215(R2) // 5bfc7f9161ff3f39
MOVH R1, 0x2002(R2) // MOVH R1, 8194(R2) // 5b08409161070079
MOVH R1, 0x1000ffe(R2) // MOVH R1, 16781310(R2) // 5bfc7f9161ff3f79
MOVW R1, 0x4004(R2) // MOVW R1, 16388(R2) // 5b104091610700b9
MOVW R1, 0x1002ffc(R2) // MOVW R1, 16789500(R2) // 5bfc7f9161ff3fb9
MOVD R1, 0x8008(R2) // MOVD R1, 32776(R2) // 5b204091610700f9
MOVD R1, 0x1006ff8(R2) // MOVD R1, 16805880(R2) // 5bfc7f9161ff3ff9
FMOVS F1, 0x4004(R2) // FMOVS F1, 16388(R2) // 5b104091610700bd
FMOVS F1, 0x1002ffc(R2) // FMOVS F1, 16789500(R2) // 5bfc7f9161ff3fbd
FMOVD F1, 0x8008(R2) // FMOVD F1, 32776(R2) // 5b204091610700fd
FMOVD F1, 0x1006ff8(R2) // FMOVD F1, 16805880(R2) // 5bfc7f9161ff3ffd
MOVB 0x1001(R1), R2 // MOVB 4097(R1), R2 // 3b04409162078039
MOVB 0xffffff(R1), R2 // MOVB 16777215(R1), R2 // 3bfc7f9162ffbf39
MOVH 0x2002(R1), R2 // MOVH 8194(R1), R2 // 3b08409162078079
MOVH 0x1000ffe(R1), R2 // MOVH 16781310(R1), R2 // 3bfc7f9162ffbf79
MOVW 0x4004(R1), R2 // MOVW 16388(R1), R2 // 3b104091620780b9
MOVW 0x1002ffc(R1), R2 // MOVW 16789500(R1), R2 // 3bfc7f9162ffbfb9
MOVD 0x8008(R1), R2 // MOVD 32776(R1), R2 // 3b204091620740f9
MOVD 0x1006ff8(R1), R2 // MOVD 16805880(R1), R2 // 3bfc7f9162ff7ff9
FMOVS 0x4004(R1), F2 // FMOVS 16388(R1), F2 // 3b104091620740bd
FMOVS 0x1002ffc(R1), F2 // FMOVS 16789500(R1), F2 // 3bfc7f9162ff7fbd
FMOVD 0x8008(R1), F2 // FMOVD 32776(R1), F2 // 3b204091620740fd
FMOVD 0x1006ff8(R1), F2 // FMOVD 16805880(R1), F2 // 3bfc7f9162ff7ffd
MOVB 0x1001(R1), R2 // MOVB 4097(R1), R2 // 3b04409162078039
MOVH 0x2002(R1), R2 // MOVH 8194(R1), R2 // 3b08409162078079
MOVW 0x4004(R1), R2 // MOVW 16388(R1), R2 // 3b104091620780b9
MOVD 0x8008(R1), R2 // MOVD 32776(R1), R2 // 3b204091620740f9
FMOVS 0x4004(R1), F2 // FMOVS 16388(R1), F2 // 3b104091620740bd
FMOVD 0x8008(R1), F2 // FMOVD 32776(R1), F2 // 3b204091620740fd
// very large or unaligned offset uses constant pool.
// the encoding cannot be checked as the address of the constant pool is unknown.
// here we only test that they can be assembled.
MOVB R1, 0x1000000(R2) // MOVB R1, 16777216(R2)
MOVB R1, 0x44332211(R2) // MOVB R1, 1144201745(R2)
MOVH R1, 0x1001000(R2) // MOVH R1, 16781312(R2)
MOVH R1, 0x44332211(R2) // MOVH R1, 1144201745(R2)
MOVW R1, 0x1003000(R2) // MOVW R1, 16789504(R2)
MOVW R1, 0x44332211(R2) // MOVW R1, 1144201745(R2)
MOVD R1, 0x1007000(R2) // MOVD R1, 16805888(R2)
MOVD R1, 0x44332211(R2) // MOVD R1, 1144201745(R2)
FMOVS F1, 0x1003000(R2) // FMOVS F1, 16789504(R2)
FMOVS F1, 0x44332211(R2) // FMOVS F1, 1144201745(R2)
FMOVD F1, 0x1007000(R2) // FMOVD F1, 16805888(R2)
FMOVD F1, 0x44332211(R2) // FMOVD F1, 1144201745(R2)
MOVB R1, 0x44332211(R2) // MOVB R1, 1144201745(R2)
MOVH R1, 0x44332211(R2) // MOVH R1, 1144201745(R2)
MOVW R1, 0x44332211(R2) // MOVW R1, 1144201745(R2)
MOVD R1, 0x44332211(R2) // MOVD R1, 1144201745(R2)
FMOVS F1, 0x44332211(R2) // FMOVS F1, 1144201745(R2)
FMOVD F1, 0x44332211(R2) // FMOVD F1, 1144201745(R2)
MOVB 0x1000000(R1), R2 // MOVB 16777216(R1), R2
MOVB 0x44332211(R1), R2 // MOVB 1144201745(R1), R2
MOVH 0x1000000(R1), R2 // MOVH 16777216(R1), R2
MOVH 0x44332211(R1), R2 // MOVH 1144201745(R1), R2
MOVW 0x1000000(R1), R2 // MOVW 16777216(R1), R2
MOVW 0x44332211(R1), R2 // MOVW 1144201745(R1), R2
MOVD 0x1000000(R1), R2 // MOVD 16777216(R1), R2
MOVD 0x44332211(R1), R2 // MOVD 1144201745(R1), R2
FMOVS 0x1000000(R1), F2 // FMOVS 16777216(R1), F2
FMOVS 0x44332211(R1), F2 // FMOVS 1144201745(R1), F2
FMOVD 0x1000000(R1), F2 // FMOVD 16777216(R1), F2
FMOVD 0x44332211(R1), F2 // FMOVD 1144201745(R1), F2
MOVB 0x44332211(R1), R2 // MOVB 1144201745(R1), R2
MOVH 0x44332211(R1), R2 // MOVH 1144201745(R1), R2
MOVW 0x44332211(R1), R2 // MOVW 1144201745(R1), R2
MOVD 0x44332211(R1), R2 // MOVD 1144201745(R1), R2
FMOVS 0x44332211(R1), F2 // FMOVS 1144201745(R1), F2
FMOVD 0x44332211(R1), F2 // FMOVD 1144201745(R1), F2
// shifted or extended register offset.
MOVD (R2)(R6.SXTW), R4 // 44c866f8
@@ -650,7 +595,6 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
MOVD (R3)(R6*1), R5 // 656866f8
MOVD (R2)(R6), R4 // 446866f8
MOVWU (R19)(R20<<2), R20 // 747a74b8
MOVD (R2)(R3<<0), R1 // 416863f8
MOVD (R2)(R6<<3), R4 // 447866f8
MOVD (R3)(R7.SXTX<<3), R8 // 68f867f8
MOVWU (R5)(R4.UXTW), R10 // aa4864b8
@@ -660,7 +604,7 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
MOVHU (R1)(R2<<1), R5 // 25786278
MOVB (R9)(R3.UXTW), R6 // 2649a338
MOVB (R10)(R6), R15 // 4f69a638
MOVB (R29)(R30<<0), R14 // ae6bbe38
MOVB (R29)(R30<<0), R14 // ae7bbe38
MOVB (R29)(R30), R14 // ae6bbe38
MOVH (R5)(R7.SXTX<<1), R19 // b3f8a778
MOVH (R8)(R4<<1), R10 // 0a79a478
@@ -981,14 +925,6 @@ again:
ADR next, R11 // ADR R11 // 2b000010
next:
NOP
ADR -2(PC), R10 // 0a000010
ADR 2(PC), R16 // 10000010
ADR -26(PC), R1 // 01000010
ADR 12(PC), R2 // 02000010
ADRP -2(PC), R10 // 0a000090
ADRP 2(PC), R16 // 10000090
ADRP -26(PC), R1 // 01000090
ADRP 12(PC), R2 // 02000090
// LDP/STP
LDP (R0), (R0, R1) // 000440a9
@@ -1011,7 +947,6 @@ next:
LDP -8(R0), (R1, R2) // 01887fa9
LDP x(SB), (R1, R2)
LDP x+8(SB), (R1, R2)
LDP 8(R1), (ZR, R2) // 3f8840a9
LDPW -5(R0), (R1, R2) // 1b1400d1610b4029
LDPW (R0), (R1, R2) // 01084029
LDPW 4(R0), (R1, R2) // 01884029
@@ -1029,7 +964,6 @@ next:
LDPW 1024(RSP), (R1, R2) // fb031091610b4029
LDPW x(SB), (R1, R2)
LDPW x+8(SB), (R1, R2)
LDPW 8(R1), (ZR, R2) // 3f084129
LDPSW (R0), (R1, R2) // 01084069
LDPSW 4(R0), (R1, R2) // 01884069
LDPSW -4(R0), (R1, R2) // 01887f69
@@ -1046,7 +980,6 @@ next:
LDPSW 1024(RSP), (R1, R2) // fb031091610b4069
LDPSW x(SB), (R1, R2)
LDPSW x+8(SB), (R1, R2)
LDPSW 8(R1), (ZR, R2) // 3f084169
STP (R3, R4), (R5) // a31000a9
STP (R3, R4), 8(R5) // a39000a9
STP.W (R3, R4), 8(R5) // a39080a9

View File

@@ -186,7 +186,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$-8
MOVBU.P 42(R2), R12 // 4ca44238
MOVBU.W -27(R2), R14 // 4e5c5e38
MOVBU 2916(R24), R3 // 03936d39
MOVBU (R19)(R14<<0), R23 // 776a6e38
MOVBU (R19)(R14<<0), R23 // 777a6e38
MOVBU (R2)(R8.SXTX), R19 // 53e86838
MOVBU (R27)(R23), R14 // 6e6b7738
MOVHU.P 107(R14), R13 // cdb54678

View File

@@ -66,6 +66,7 @@ TEXT errors(SB),$0
LDP.W 8(R3), (R2, R3) // ERROR "constrained unpredictable behavior"
LDP (R1), (R2, R2) // ERROR "constrained unpredictable behavior"
LDP (R0), (F0, F1) // ERROR "invalid register pair"
LDP (R0), (R3, ZR) // ERROR "invalid register pair"
LDXPW (RSP), (R2, R2) // ERROR "constrained unpredictable behavior"
LDAXPW (R5), (R2, R2) // ERROR "constrained unpredictable behavior"
MOVD.P 300(R2), R3 // ERROR "offset out of range [-256,255]"
@@ -165,94 +166,94 @@ TEXT errors(SB),$0
FSTPD (R1, R2), (R0) // ERROR "invalid register pair"
FMOVS (F2), F0 // ERROR "illegal combination"
FMOVD F0, (F1) // ERROR "illegal combination"
LDADDAD R5, (R6), RSP // ERROR "illegal combination"
LDADDAW R5, (R6), RSP // ERROR "illegal combination"
LDADDAH R5, (R6), RSP // ERROR "illegal combination"
LDADDAB R5, (R6), RSP // ERROR "illegal combination"
LDADDALD R5, (R6), RSP // ERROR "illegal combination"
LDADDALW R5, (R6), RSP // ERROR "illegal combination"
LDADDALH R5, (R6), RSP // ERROR "illegal combination"
LDADDALB R5, (R6), RSP // ERROR "illegal combination"
LDADDD R5, (R6), RSP // ERROR "illegal combination"
LDADDW R5, (R6), RSP // ERROR "illegal combination"
LDADDH R5, (R6), RSP // ERROR "illegal combination"
LDADDB R5, (R6), RSP // ERROR "illegal combination"
LDADDLD R5, (R6), RSP // ERROR "illegal combination"
LDADDLW R5, (R6), RSP // ERROR "illegal combination"
LDADDLH R5, (R6), RSP // ERROR "illegal combination"
LDADDLB R5, (R6), RSP // ERROR "illegal combination"
LDCLRAD R5, (R6), RSP // ERROR "illegal combination"
LDCLRAW R5, (R6), RSP // ERROR "illegal combination"
LDCLRAH R5, (R6), RSP // ERROR "illegal combination"
LDCLRAB R5, (R6), RSP // ERROR "illegal combination"
LDCLRALD R5, (R6), RSP // ERROR "illegal combination"
LDCLRALW R5, (R6), RSP // ERROR "illegal combination"
LDCLRALH R5, (R6), RSP // ERROR "illegal combination"
LDCLRALB R5, (R6), RSP // ERROR "illegal combination"
LDCLRD R5, (R6), RSP // ERROR "illegal combination"
LDCLRW R5, (R6), RSP // ERROR "illegal combination"
LDCLRH R5, (R6), RSP // ERROR "illegal combination"
LDCLRB R5, (R6), RSP // ERROR "illegal combination"
LDCLRLD R5, (R6), RSP // ERROR "illegal combination"
LDCLRLW R5, (R6), RSP // ERROR "illegal combination"
LDCLRLH R5, (R6), RSP // ERROR "illegal combination"
LDCLRLB R5, (R6), RSP // ERROR "illegal combination"
LDEORAD R5, (R6), RSP // ERROR "illegal combination"
LDEORAW R5, (R6), RSP // ERROR "illegal combination"
LDEORAH R5, (R6), RSP // ERROR "illegal combination"
LDEORAB R5, (R6), RSP // ERROR "illegal combination"
LDEORALD R5, (R6), RSP // ERROR "illegal combination"
LDEORALW R5, (R6), RSP // ERROR "illegal combination"
LDEORALH R5, (R6), RSP // ERROR "illegal combination"
LDEORALB R5, (R6), RSP // ERROR "illegal combination"
LDEORD R5, (R6), RSP // ERROR "illegal combination"
LDEORW R5, (R6), RSP // ERROR "illegal combination"
LDEORH R5, (R6), RSP // ERROR "illegal combination"
LDEORB R5, (R6), RSP // ERROR "illegal combination"
LDEORLD R5, (R6), RSP // ERROR "illegal combination"
LDEORLW R5, (R6), RSP // ERROR "illegal combination"
LDEORLH R5, (R6), RSP // ERROR "illegal combination"
LDEORLB R5, (R6), RSP // ERROR "illegal combination"
LDORAD R5, (R6), RSP // ERROR "illegal combination"
LDORAW R5, (R6), RSP // ERROR "illegal combination"
LDORAH R5, (R6), RSP // ERROR "illegal combination"
LDORAB R5, (R6), RSP // ERROR "illegal combination"
LDORALD R5, (R6), RSP // ERROR "illegal combination"
LDORALW R5, (R6), RSP // ERROR "illegal combination"
LDORALH R5, (R6), RSP // ERROR "illegal combination"
LDORALB R5, (R6), RSP // ERROR "illegal combination"
LDORD R5, (R6), RSP // ERROR "illegal combination"
LDORW R5, (R6), RSP // ERROR "illegal combination"
LDORH R5, (R6), RSP // ERROR "illegal combination"
LDORB R5, (R6), RSP // ERROR "illegal combination"
LDORLD R5, (R6), RSP // ERROR "illegal combination"
LDORLW R5, (R6), RSP // ERROR "illegal combination"
LDORLH R5, (R6), RSP // ERROR "illegal combination"
LDORLB R5, (R6), RSP // ERROR "illegal combination"
SWPAD R5, (R6), RSP // ERROR "illegal combination"
SWPAW R5, (R6), RSP // ERROR "illegal combination"
SWPAH R5, (R6), RSP // ERROR "illegal combination"
SWPAB R5, (R6), RSP // ERROR "illegal combination"
SWPALD R5, (R6), RSP // ERROR "illegal combination"
SWPALW R5, (R6), RSP // ERROR "illegal combination"
SWPALH R5, (R6), RSP // ERROR "illegal combination"
SWPALB R5, (R6), RSP // ERROR "illegal combination"
SWPD R5, (R6), RSP // ERROR "illegal combination"
SWPW R5, (R6), RSP // ERROR "illegal combination"
SWPH R5, (R6), RSP // ERROR "illegal combination"
SWPB R5, (R6), RSP // ERROR "illegal combination"
SWPLD R5, (R6), RSP // ERROR "illegal combination"
SWPLW R5, (R6), RSP // ERROR "illegal combination"
SWPLH R5, (R6), RSP // ERROR "illegal combination"
SWPLB R5, (R6), RSP // ERROR "illegal combination"
STXR R5, (R6), RSP // ERROR "illegal combination"
STXRW R5, (R6), RSP // ERROR "illegal combination"
STLXR R5, (R6), RSP // ERROR "illegal combination"
STLXRW R5, (R6), RSP // ERROR "illegal combination"
STXP (R5, R7), (R6), RSP // ERROR "illegal combination"
STXPW (R5, R7), (R6), RSP // ERROR "illegal combination"
STLXP (R5, R7), (R6), RSP // ERROR "illegal combination"
STLXP (R5, R7), (R6), RSP // ERROR "illegal combination"
LDADDAD R5, (R6), RSP // ERROR "illegal destination register"
LDADDAW R5, (R6), RSP // ERROR "illegal destination register"
LDADDAH R5, (R6), RSP // ERROR "illegal destination register"
LDADDAB R5, (R6), RSP // ERROR "illegal destination register"
LDADDALD R5, (R6), RSP // ERROR "illegal destination register"
LDADDALW R5, (R6), RSP // ERROR "illegal destination register"
LDADDALH R5, (R6), RSP // ERROR "illegal destination register"
LDADDALB R5, (R6), RSP // ERROR "illegal destination register"
LDADDD R5, (R6), RSP // ERROR "illegal destination register"
LDADDW R5, (R6), RSP // ERROR "illegal destination register"
LDADDH R5, (R6), RSP // ERROR "illegal destination register"
LDADDB R5, (R6), RSP // ERROR "illegal destination register"
LDADDLD R5, (R6), RSP // ERROR "illegal destination register"
LDADDLW R5, (R6), RSP // ERROR "illegal destination register"
LDADDLH R5, (R6), RSP // ERROR "illegal destination register"
LDADDLB R5, (R6), RSP // ERROR "illegal destination register"
LDCLRAD R5, (R6), RSP // ERROR "illegal destination register"
LDCLRAW R5, (R6), RSP // ERROR "illegal destination register"
LDCLRAH R5, (R6), RSP // ERROR "illegal destination register"
LDCLRAB R5, (R6), RSP // ERROR "illegal destination register"
LDCLRALD R5, (R6), RSP // ERROR "illegal destination register"
LDCLRALW R5, (R6), RSP // ERROR "illegal destination register"
LDCLRALH R5, (R6), RSP // ERROR "illegal destination register"
LDCLRALB R5, (R6), RSP // ERROR "illegal destination register"
LDCLRD R5, (R6), RSP // ERROR "illegal destination register"
LDCLRW R5, (R6), RSP // ERROR "illegal destination register"
LDCLRH R5, (R6), RSP // ERROR "illegal destination register"
LDCLRB R5, (R6), RSP // ERROR "illegal destination register"
LDCLRLD R5, (R6), RSP // ERROR "illegal destination register"
LDCLRLW R5, (R6), RSP // ERROR "illegal destination register"
LDCLRLH R5, (R6), RSP // ERROR "illegal destination register"
LDCLRLB R5, (R6), RSP // ERROR "illegal destination register"
LDEORAD R5, (R6), RSP // ERROR "illegal destination register"
LDEORAW R5, (R6), RSP // ERROR "illegal destination register"
LDEORAH R5, (R6), RSP // ERROR "illegal destination register"
LDEORAB R5, (R6), RSP // ERROR "illegal destination register"
LDEORALD R5, (R6), RSP // ERROR "illegal destination register"
LDEORALW R5, (R6), RSP // ERROR "illegal destination register"
LDEORALH R5, (R6), RSP // ERROR "illegal destination register"
LDEORALB R5, (R6), RSP // ERROR "illegal destination register"
LDEORD R5, (R6), RSP // ERROR "illegal destination register"
LDEORW R5, (R6), RSP // ERROR "illegal destination register"
LDEORH R5, (R6), RSP // ERROR "illegal destination register"
LDEORB R5, (R6), RSP // ERROR "illegal destination register"
LDEORLD R5, (R6), RSP // ERROR "illegal destination register"
LDEORLW R5, (R6), RSP // ERROR "illegal destination register"
LDEORLH R5, (R6), RSP // ERROR "illegal destination register"
LDEORLB R5, (R6), RSP // ERROR "illegal destination register"
LDORAD R5, (R6), RSP // ERROR "illegal destination register"
LDORAW R5, (R6), RSP // ERROR "illegal destination register"
LDORAH R5, (R6), RSP // ERROR "illegal destination register"
LDORAB R5, (R6), RSP // ERROR "illegal destination register"
LDORALD R5, (R6), RSP // ERROR "illegal destination register"
LDORALW R5, (R6), RSP // ERROR "illegal destination register"
LDORALH R5, (R6), RSP // ERROR "illegal destination register"
LDORALB R5, (R6), RSP // ERROR "illegal destination register"
LDORD R5, (R6), RSP // ERROR "illegal destination register"
LDORW R5, (R6), RSP // ERROR "illegal destination register"
LDORH R5, (R6), RSP // ERROR "illegal destination register"
LDORB R5, (R6), RSP // ERROR "illegal destination register"
LDORLD R5, (R6), RSP // ERROR "illegal destination register"
LDORLW R5, (R6), RSP // ERROR "illegal destination register"
LDORLH R5, (R6), RSP // ERROR "illegal destination register"
LDORLB R5, (R6), RSP // ERROR "illegal destination register"
SWPAD R5, (R6), RSP // ERROR "illegal destination register"
SWPAW R5, (R6), RSP // ERROR "illegal destination register"
SWPAH R5, (R6), RSP // ERROR "illegal destination register"
SWPAB R5, (R6), RSP // ERROR "illegal destination register"
SWPALD R5, (R6), RSP // ERROR "illegal destination register"
SWPALW R5, (R6), RSP // ERROR "illegal destination register"
SWPALH R5, (R6), RSP // ERROR "illegal destination register"
SWPALB R5, (R6), RSP // ERROR "illegal destination register"
SWPD R5, (R6), RSP // ERROR "illegal destination register"
SWPW R5, (R6), RSP // ERROR "illegal destination register"
SWPH R5, (R6), RSP // ERROR "illegal destination register"
SWPB R5, (R6), RSP // ERROR "illegal destination register"
SWPLD R5, (R6), RSP // ERROR "illegal destination register"
SWPLW R5, (R6), RSP // ERROR "illegal destination register"
SWPLH R5, (R6), RSP // ERROR "illegal destination register"
SWPLB R5, (R6), RSP // ERROR "illegal destination register"
STXR R5, (R6), RSP // ERROR "illegal destination register"
STXRW R5, (R6), RSP // ERROR "illegal destination register"
STLXR R5, (R6), RSP // ERROR "illegal destination register"
STLXRW R5, (R6), RSP // ERROR "illegal destination register"
STXP (R5, R7), (R6), RSP // ERROR "illegal destination register"
STXPW (R5, R7), (R6), RSP // ERROR "illegal destination register"
STLXP (R5, R7), (R6), RSP // ERROR "illegal destination register"
STLXP (R5, R7), (R6), RSP // ERROR "illegal destination register"
MSR OSLAR_EL1, R5 // ERROR "illegal combination"
MRS R11, AIDR_EL1 // ERROR "illegal combination"
MSR R6, AIDR_EL1 // ERROR "system register is not writable"

View File

@@ -429,11 +429,6 @@ label4:
CLZ R1, R2 // 70221020
CLO R1, R2 // 70221021
WSBH R1, R2 // 7c0110a0
SEB R1, R2 // 7c011420
SEH R1, R2 // 7c011620
// to (Hi, Lo)
MADD R2, R1 // 70220000
MSUB R2, R1 // 70220004

View File

@@ -587,17 +587,8 @@ label4:
CALL foo(SB)
RET foo(SB)
// unary operation
NEGW R1, R2 // 00011023
NEGV R1, R2 // 0001102f
WSBH R1, R2 // 7c0110a0
DSBH R1, R2 // 7c0110a4
DSHD R1, R2 // 7c011164
SEB R1, R2 // 7c011420
SEH R1, R2 // 7c011620
RET
// MSA VMOVI

View File

@@ -17,14 +17,14 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
MOVD $1, R3 // 38600001
MOVD $-1, R4 // 3880ffff
MOVD $65535, R5 // 6005ffff
MOVD $65536, R6 // 3cc00001
MOVD $65536, R6 // 64060001
MOVD $-32767, R5 // 38a08001
MOVD $-32768, R6 // 38c08000
MOVD $1234567, R5 // 6405001260a5d687 or 0600001238a0d687
MOVW $1, R3 // 38600001
MOVW $-1, R4 // 3880ffff
MOVW $65535, R5 // 6005ffff
MOVW $65536, R6 // 3cc00001
MOVW $65536, R6 // 64060001
MOVW $-32767, R5 // 38a08001
MOVW $-32768, R6 // 38c08000
MOVW $1234567, R5 // 6405001260a5d687 or 0600001238a0d687
@@ -32,29 +32,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
MOVW $2147483649, R5 // 6405800060a50001 or 0600800038a00001
MOVD $2147483649, R5 // 6405800060a50001 or 0600800038a00001
// Hex constant 0xFFFFFFFF80000001
MOVD $-2147483647, R5 // 3ca0800060a50001 or 0603800038a00001
// Hex constant 0xFFFFFFFE00000002 (load of constant on < power10, pli on >= power10
MOVD $-8589934590, R5 // 3ca00000e8a50000 or 0602000038a00002
// For backwards compatibility, MOVW $const,Rx and MOVWZ $const,Rx assemble identically
// and accept the same constants.
MOVW $2147483648, R5 // 64058000
MOVWZ $-2147483648, R5 // 3ca08000
// TODO: These are preprocessed by the assembler into MOVD $const>>shift, R5; SLD $shift, R5.
// This only captures the MOVD. Should the SLD be appended to the encoding by the test?
// Hex constant 0x20004000000
MOVD $2199090364416, R5 // 60058001
// Hex constant 0xFFFFFE0004000000
MOVD $-2198956146688, R5 // 38a08001
// TODO: On GOPPC64={power8,power9}, this is preprocessed into MOVD $-1, R5; RLDC R5, $33, $63, R5.
// This only captures the MOVD. Should the RLDC be appended to the encoding by the test?
// Hex constant 0xFFFFFFFE00000001
MOVD $-8589934591, R5 // 38a0ffff or 0602000038a00001
// For #66955. Verify this opcode turns into a load and assembles.
MOVD $-6795364578871345152, R5 // 3ca00000e8a50000 or 04100000e4a00000
MOVD $-2147483647, R5 // 3ca0800060a50001 or 0603800038a00001
MOVD 8(R3), R4 // e8830008
MOVD (R3)(R4), R5 // 7ca4182a
MOVD (R3)(R0), R5 // 7ca0182a
@@ -93,7 +71,6 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
MOVHBR (R3)(R4), R5 // 7ca41e2c
MOVHBR (R3)(R0), R5 // 7ca01e2c
MOVHBR (R3), R5 // 7ca01e2c
OR $0, R0, R0
MOVD $foo+4009806848(FP), R5 // 3ca1ef0138a5cc40 or 0600ef0038a1cc40
MOVD $foo(SB), R5 // 3ca0000038a50000 or 0610000038a00000
@@ -187,10 +164,6 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
ADD $-32767, R5, R4 // 38858001
ADD $-32768, R6 // 38c68000
ADD $-32768, R6, R5 // 38a68000
// Hex constant 0xFFFFFFFE00000000
ADD $-8589934592, R5 // 3fe0fffe600000007bff83e4600000007cbf2a14 or 0602000038a50000
// Hex constant 0xFFFFFFFE00010001
ADD $-8589869055, R5 // 3fe0fffe63ff00017bff83e463ff00017cbf2a14 or 0602000138a50001
//TODO: this compiles to add r5,r6,r0. It should be addi r5,r6,0.
// this is OK since r0 == $0, but the latter is preferred.
@@ -201,7 +174,6 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
ADDEX R3, R5, $3, R6 // 7cc32f54
ADDEX R3, $3, R5, R6 // 7cc32f54
ADDIS $8, R3 // 3c630008
ADD $524288, R3 // 3c630008
ADDIS $1000, R3, R4 // 3c8303e8
ANDCC $1, R3 // 70630001
@@ -220,7 +192,6 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
ANDCC $1234567, R5, R6 // 641f001263ffd6877fe62839
ANDISCC $1, R3 // 74630001
ANDISCC $1000, R3, R4 // 746403e8
ANDCC $65536000, R3, R4 // 746403e8
OR $1, R3 // 60630001
OR $1, R3, R4 // 60640001
@@ -236,10 +207,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
OR $-32768, R6, R7 // 3be080007fe73378
OR $1234567, R5 // 641f001263ffd6877fe52b78
OR $1234567, R5, R3 // 641f001263ffd6877fe32b78
OR $2147483648, R5, R3 // 64a38000
OR $2147483649, R5, R3 // 641f800063ff00017fe32b78
ORIS $255, R3, R4 // 646400ff
OR $16711680, R3, R4 // 646400ff
ORIS $255, R3, R4
XOR $1, R3 // 68630001
XOR $1, R3, R4 // 68640001
@@ -255,8 +223,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
XOR $-32768, R6, R7 // 3be080007fe73278
XOR $1234567, R5 // 641f001263ffd6877fe52a78
XOR $1234567, R5, R3 // 641f001263ffd6877fe32a78
XORIS $15, R3, R4 // 6c64000f
XOR $983040, R3, R4 // 6c64000f
XORIS $15, R3, R4
// TODO: the order of CR operands don't match
CMP R3, R4 // 7c232000
@@ -266,6 +233,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
CMPB R3,R4,R4 // 7c6423f8
CMPEQB R3,R4,CR6 // 7f0321c0
// TODO: constants for ADDC?
ADD R3, R4 // 7c841a14
ADD R3, R4, R5 // 7ca41a14
ADDC R3, R4 // 7c841814
@@ -278,8 +246,6 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
ADDV R3, R4 // 7c841e14
ADDVCC R3, R4 // 7c841e15
ADDCCC R3, R4, R5 // 7ca41815
ADDCCC $65536, R4, R5 // 641f0001600000007cbf2015
ADDCCC $65537, R4, R5 // 641f000163ff00017cbf2015
ADDME R3, R4 // 7c8301d4
ADDMECC R3, R4 // 7c8301d5
ADDMEV R3, R4 // 7c8305d4
@@ -333,8 +299,6 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
SUBECC R3, R4, R5 // 7ca32111
SUBEV R3, R4, R5 // 7ca32510
SUBEVCC R3, R4, R5 // 7ca32511
SUBC R3, $65536, R4 // 3fe00001600000007c83f810
SUBC R3, $65537, R4 // 3fe0000163ff00017c83f810
MULLW R3, R4 // 7c8419d6
MULLW R3, R4, R5 // 7ca419d6
@@ -429,19 +393,12 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
EXTSHCC R3, R4 // 7c640735
EXTSW R3, R4 // 7c6407b4
EXTSWCC R3, R4 // 7c6407b5
RLWMI $7, R3, $4026531855, R6 // 50663f06
RLWMI $7, R3, $1, R6 // 50663ffe
RLWMI $7, R3, $2147483648, R6 // 50663800
RLWMI $7, R3, $65535, R6 // 50663c3e
RLWMI $7, R3, $16, $31, R6 // 50663c3e
RLWMICC $7, R3, $65535, R6 // 50663c3f
RLWMICC $7, R3, $16, $31, R6 // 50663c3f
RLWNM $3, R4, $7, R6 // 54861f7e
RLWNM $0, R4, $7, R6 // 5486077e
RLWNM R0, R4, $7, R6 // 5c86077e
RLWNM $3, R4, $29, $31, R6 // 54861f7e
RLWNM $0, R4, $29, $31, R6 // 5486077e
RLWNM R0, R4, $29, $31, R6 // 5c86077e
RLWNM R3, R4, $7, R6 // 5c861f7e
RLWNM R3, R4, $29, $31, R6 // 5c861f7e
RLWNMCC $3, R4, $7, R6 // 54861f7f
@@ -453,10 +410,6 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
RLDIMI $0, R4, $7, R6 // 788601cc
RLDIMICC $0, R4, $7, R6 // 788601cd
RLDC $0, R4, $15, R6 // 78860728
RLDC R3, $32, $12, R4 // 7864030a
RLDC R3, $8, $32, R4 // 78644028
RLDCCC R3, $32, $12, R4 // 7864030b
RLDCCC R3, $8, $32, R4 // 78644029
RLDCCC $0, R4, $15, R6 // 78860729
RLDCL $0, R4, $7, R6 // 78860770
RLDCLCC $0, R4, $15, R6 // 78860721

View File

@@ -94,10 +94,6 @@ start:
SUB X6, X5, X7 // b3836240
SUB X5, X6 // 33035340
SUB $-2047, X5, X6 // 1383f27f
SUB $2048, X5, X6 // 13830280
SUB $-2047, X5 // 9382f27f
SUB $2048, X5 // 93820280
SRA X6, X5, X7 // b3d36240
SRA X5, X6 // 33535340
@@ -161,7 +157,6 @@ start:
ADDW $1, X6 // 1b031300
SLLW $1, X6 // 1b131300
SRLW $1, X6 // 1b531300
SUBW $1, X6 // 1b03f3ff
SRAW $1, X6 // 1b531340
// 5.3: Load and Store Instructions (RV64I)
@@ -188,28 +183,28 @@ start:
// 8.2: Load-Reserved/Store-Conditional
LRW (X5), X6 // 2fa30214
LRD (X5), X6 // 2fb30214
SCW X5, (X6), X7 // af23531a
SCD X5, (X6), X7 // af33531a
SCW X5, (X6), X7 // af23531c
SCD X5, (X6), X7 // af33531c
// 8.3: Atomic Memory Operations
AMOSWAPW X5, (X6), X7 // af23530e
AMOSWAPD X5, (X6), X7 // af33530e
AMOADDW X5, (X6), X7 // af235306
AMOADDD X5, (X6), X7 // af335306
AMOANDW X5, (X6), X7 // af235366
AMOANDD X5, (X6), X7 // af335366
AMOORW X5, (X6), X7 // af235346
AMOORD X5, (X6), X7 // af335346
AMOXORW X5, (X6), X7 // af235326
AMOXORD X5, (X6), X7 // af335326
AMOMAXW X5, (X6), X7 // af2353a6
AMOMAXD X5, (X6), X7 // af3353a6
AMOMAXUW X5, (X6), X7 // af2353e6
AMOMAXUD X5, (X6), X7 // af3353e6
AMOMINW X5, (X6), X7 // af235386
AMOMIND X5, (X6), X7 // af335386
AMOMINUW X5, (X6), X7 // af2353c6
AMOMINUD X5, (X6), X7 // af3353c6
AMOSWAPW X5, (X6), X7 // af23530c
AMOSWAPD X5, (X6), X7 // af33530c
AMOADDW X5, (X6), X7 // af235304
AMOADDD X5, (X6), X7 // af335304
AMOANDW X5, (X6), X7 // af235364
AMOANDD X5, (X6), X7 // af335364
AMOORW X5, (X6), X7 // af235344
AMOORD X5, (X6), X7 // af335344
AMOXORW X5, (X6), X7 // af235324
AMOXORD X5, (X6), X7 // af335324
AMOMAXW X5, (X6), X7 // af2353a4
AMOMAXD X5, (X6), X7 // af3353a4
AMOMAXUW X5, (X6), X7 // af2353e4
AMOMAXUD X5, (X6), X7 // af3353e4
AMOMINW X5, (X6), X7 // af235384
AMOMIND X5, (X6), X7 // af335384
AMOMINUW X5, (X6), X7 // af2353c4
AMOMINUD X5, (X6), X7 // af3353c4
// 10.1: Base Counters and Timers
RDCYCLE X5 // f32200c0
@@ -359,14 +354,6 @@ start:
MOVD F0, 4(X5) // 27b20200
MOVD F0, F1 // d3000022
// TLS load with local-exec (LUI + ADDIW + ADD of TP + load)
MOV tls(SB), X5 // b70f00009b8f0f00b38f4f0083b20f00
MOVB tls(SB), X5 // b70f00009b8f0f00b38f4f0083820f00
// TLS store with local-exec (LUI + ADDIW + ADD of TP + store)
MOV X5, tls(SB) // b70f00009b8f0f00b38f4f0023b05f00
MOVB X5, tls(SB) // b70f00009b8f0f00b38f4f0023805f00
// NOT pseudo-instruction
NOT X5 // 93c2f2ff
NOT X5, X6 // 13c3f2ff
@@ -386,7 +373,7 @@ start:
JMP 4(X5) // 67804200
// CALL and JMP to symbol are encoded as JAL (using LR or ZERO
// respectively), with a R_RISCV_JAL relocation. The linker resolves
// respectively), with a R_RISCV_CALL relocation. The linker resolves
// the real address and updates the immediate, using a trampoline in
// the case where the address is not directly reachable.
CALL asmtest(SB) // ef000000
@@ -420,5 +407,3 @@ start:
FLTD F0, F1, X5 // d39200a2
FLED F0, F1, X5 // d38200a2
FEQD F0, F1, X5 // d3a200a2
GLOBL tls(SB), TLSBSS, $8

View File

@@ -38,8 +38,5 @@ TEXT errors(SB),$0
SLLIW $-1, X5, X6 // ERROR "shift amount out of range 0 to 31"
SRLIW $-1, X5, X6 // ERROR "shift amount out of range 0 to 31"
SRAIW $-1, X5, X6 // ERROR "shift amount out of range 0 to 31"
SD X5, 4294967296(X6) // ERROR "constant 4294967296 too large"
SRLI $1, X5, F1 // ERROR "expected integer register in rd position but got non-integer register F1"
SRLI $1, F1, X5 // ERROR "expected integer register in rs1 position but got non-integer register F1"
FNES F1, (X5) // ERROR "needs an integer register output"
RET

View File

@@ -415,14 +415,6 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
SYNC // 07e0
KM R2, R4 // b92e0024
KMC R2, R6 // b92f0026
KLMD R2, R8 // b93f0028
KIMD R0, R4 // b93e0004
KDSA R0, R8 // b93a0008
KMA R2, R6, R4 // b9296024
KMCTR R2, R6, R4 // b92d6024
// vector add and sub instructions
VAB V3, V4, V4 // e743400000f3
VAH V3, V4, V4 // e743400010f3

View File

@@ -16,16 +16,17 @@ import (
)
var (
Debug = flag.Bool("debug", false, "dump instructions as they are parsed")
OutputFile = flag.String("o", "", "output file; default foo.o for /a/b/c/foo.s as first argument")
TrimPath = flag.String("trimpath", "", "remove prefix from recorded source file paths")
Shared = flag.Bool("shared", false, "generate code that can be linked into a shared library")
Dynlink = flag.Bool("dynlink", false, "support references to Go symbols defined in other shared libraries")
Linkshared = flag.Bool("linkshared", false, "generate code that will be linked against Go shared libraries")
AllErrors = flag.Bool("e", false, "no limit on number of errors reported")
SymABIs = flag.Bool("gensymabis", false, "write symbol ABI information to output file, don't assemble")
Importpath = flag.String("p", obj.UnlinkablePkg, "set expected package import to path")
Spectre = flag.String("spectre", "", "enable spectre mitigations in `list` (all, ret)")
Debug = flag.Bool("debug", false, "dump instructions as they are parsed")
OutputFile = flag.String("o", "", "output file; default foo.o for /a/b/c/foo.s as first argument")
TrimPath = flag.String("trimpath", "", "remove prefix from recorded source file paths")
Shared = flag.Bool("shared", false, "generate code that can be linked into a shared library")
Dynlink = flag.Bool("dynlink", false, "support references to Go symbols defined in other shared libraries")
Linkshared = flag.Bool("linkshared", false, "generate code that will be linked against Go shared libraries")
AllErrors = flag.Bool("e", false, "no limit on number of errors reported")
SymABIs = flag.Bool("gensymabis", false, "write symbol ABI information to output file, don't assemble")
Importpath = flag.String("p", obj.UnlinkablePkg, "set expected package import to path")
Spectre = flag.String("spectre", "", "enable spectre mitigations in `list` (all, ret)")
CompilingRuntime = flag.Bool("compiling-runtime", false, "source to be compiled is part of the Go runtime")
)
var DebugFlags struct {

View File

@@ -6,6 +6,7 @@ package lex
import (
"fmt"
"internal/buildcfg"
"os"
"path/filepath"
"strconv"
@@ -45,6 +46,21 @@ func NewInput(name string) *Input {
// predefine installs the macros set by the -D flag on the command line.
func predefine(defines flags.MultiFlag) map[string]*Macro {
macros := make(map[string]*Macro)
// Set macros for GOEXPERIMENTs so we can easily switch
// runtime assembly code based on them.
if *flags.CompilingRuntime {
for _, exp := range buildcfg.Experiment.Enabled() {
// Define macro.
name := "GOEXPERIMENT_" + exp
macros[name] = &Macro{
name: name,
args: nil,
tokens: Tokenize("1"),
}
}
}
for _, name := range defines {
value := "1"
i := strings.IndexRune(name, '=')

View File

@@ -105,9 +105,13 @@ type Token struct {
// Make returns a Token with the given rune (ScanToken) and text representation.
func Make(token ScanToken, text string) Token {
// If the symbol starts with center dot, as in ·x, rewrite it as ""·x
if token == scanner.Ident && strings.HasPrefix(text, "\u00B7") {
text = `""` + text
}
// Substitute the substitutes for . and /.
text = strings.ReplaceAll(text, "\u00B7", ".")
text = strings.ReplaceAll(text, "\u2215", "/")
text = strings.Replace(text, "\u00B7", ".", -1)
text = strings.Replace(text, "\u2215", "/", -1)
return Token{ScanToken: token, text: text}
}

View File

@@ -35,6 +35,7 @@ func main() {
if architecture == nil {
log.Fatalf("unrecognized architecture %s", GOARCH)
}
ctxt := obj.Linknew(architecture.LinkArch)
ctxt.Debugasm = flags.PrintOut
ctxt.Debugvlog = flags.DebugV
@@ -75,19 +76,12 @@ func main() {
fmt.Fprintf(buf, "!\n")
}
// Set macros for GOEXPERIMENTs so we can easily switch
// runtime assembly code based on them.
if objabi.LookupPkgSpecial(ctxt.Pkgpath).AllowAsmABI {
for _, exp := range buildcfg.Experiment.Enabled() {
flags.D = append(flags.D, "GOEXPERIMENT_"+exp)
}
}
var ok, diag bool
var failedFile string
for _, f := range flag.Args() {
lexer := lex.NewLexer(f)
parser := asm.NewParser(ctxt, architecture, lexer)
parser := asm.NewParser(ctxt, architecture, lexer,
*flags.CompilingRuntime)
ctxt.DiagFunc = func(format string, args ...interface{}) {
diag = true
log.Printf(format, args...)
@@ -99,7 +93,7 @@ func main() {
pList.Firstpc, ok = parser.Parse()
// reports errors to parser.Errorf
if ok {
obj.Flushplist(ctxt, pList, nil)
obj.Flushplist(ctxt, pList, nil, *flags.Importpath)
}
}
if !ok {

View File

@@ -686,7 +686,7 @@ files:
_cgo_export.c # for gcc
_cgo_export.h # for gcc
_cgo_main.c # for gcc
_cgo_flags # for build tool (if -gccgo)
_cgo_flags # for alternative build tools
The file x.cgo1.go is a copy of x.go with the import "C" removed and
references to C.xxx replaced with names like _Cfunc_xxx or _Ctype_xxx.

View File

@@ -73,41 +73,27 @@ func cname(s string) string {
return s
}
// ProcessCgoDirectives processes the import C preamble:
// 1. discards all #cgo CFLAGS, LDFLAGS, nocallback and noescape directives,
// so they don't make their way into _cgo_export.h.
// 2. parse the nocallback and noescape directives.
func (f *File) ProcessCgoDirectives() {
// DiscardCgoDirectives processes the import C preamble, and discards
// all #cgo CFLAGS and LDFLAGS directives, so they don't make their
// way into _cgo_export.h.
func (f *File) DiscardCgoDirectives() {
linesIn := strings.Split(f.Preamble, "\n")
linesOut := make([]string, 0, len(linesIn))
f.NoCallbacks = make(map[string]bool)
f.NoEscapes = make(map[string]bool)
for _, line := range linesIn {
l := strings.TrimSpace(line)
if len(l) < 5 || l[:4] != "#cgo" || !unicode.IsSpace(rune(l[4])) {
linesOut = append(linesOut, line)
} else {
linesOut = append(linesOut, "")
// #cgo (nocallback|noescape) <function name>
if fields := strings.Fields(l); len(fields) == 3 {
directive := fields[1]
funcName := fields[2]
if directive == "nocallback" {
fatalf("#cgo nocallback disabled until Go 1.23")
f.NoCallbacks[funcName] = true
} else if directive == "noescape" {
fatalf("#cgo noescape disabled until Go 1.23")
f.NoEscapes[funcName] = true
}
}
}
}
f.Preamble = strings.Join(linesOut, "\n")
}
// addToFlag appends args to flag.
// addToFlag appends args to flag. All flags are later written out onto the
// _cgo_flags file for the build system to use.
func (p *Package) addToFlag(flag string, args []string) {
p.CgoFlags[flag] = append(p.CgoFlags[flag], args...)
if flag == "CFLAGS" {
// We'll also need these when preprocessing for dwarf information.
// However, discard any -g options: we need to be able
@@ -118,9 +104,6 @@ func (p *Package) addToFlag(flag string, args []string) {
}
}
}
if flag == "LDFLAGS" {
p.LdFlags = append(p.LdFlags, args...)
}
}
// splitQuoted splits the string s around each instance of one or more consecutive
@@ -598,7 +581,7 @@ func (p *Package) loadDWARF(f *File, conv *typeConv, names []*Name) {
// As of https://reviews.llvm.org/D123534, clang
// now emits DW_TAG_variable DIEs that have
// no name (so as to be able to describe the
// type and source locations of constant strings)
// type and source locations of constant strings
// like the second arg in the call below:
//
// myfunction(42, "foo")
@@ -2579,11 +2562,6 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
if dt.BitSize > 0 {
fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype)
}
if t.Align = t.Size; t.Align >= c.ptrSize {
t.Align = c.ptrSize
}
switch t.Size {
default:
fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype)
@@ -2600,8 +2578,9 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
Len: c.intExpr(t.Size),
Elt: c.uint8,
}
// t.Align is the alignment of the Go type.
t.Align = 1
}
if t.Align = t.Size; t.Align >= c.ptrSize {
t.Align = c.ptrSize
}
case *dwarf.PtrType:
@@ -2830,11 +2809,6 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
if dt.BitSize > 0 {
fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype)
}
if t.Align = t.Size; t.Align >= c.ptrSize {
t.Align = c.ptrSize
}
switch t.Size {
default:
fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype)
@@ -2851,8 +2825,9 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
Len: c.intExpr(t.Size),
Elt: c.uint8,
}
// t.Align is the alignment of the Go type.
t.Align = 1
}
if t.Align = t.Size; t.Align >= c.ptrSize {
t.Align = c.ptrSize
}
case *dwarf.VoidType:
@@ -3118,11 +3093,10 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
}
// Round off up to talign, assumed to be a power of 2.
origOff := off
off = (off + talign - 1) &^ (talign - 1)
if f.ByteOffset > off {
fld, sizes = c.pad(fld, sizes, f.ByteOffset-origOff)
fld, sizes = c.pad(fld, sizes, f.ByteOffset-off)
off = f.ByteOffset
}
if f.ByteOffset < off {

View File

@@ -44,18 +44,11 @@ func run(t *testing.T, dir string, lto bool, args ...string) {
cmd := exec.Command("go", runArgs...)
cmd.Dir = dir
if lto {
// On the builders we're using the default /usr/bin/ld, but
// that has problems when asking for LTO in particular. Force
// use of lld, which ships with our clang installation.
extraLDFlags := ""
if strings.Contains(testenv.Builder(), "clang") {
extraLDFlags += " -fuse-ld=lld"
}
const cflags = "-flto -Wno-lto-type-mismatch -Wno-unknown-warning-option"
cmd.Env = append(cmd.Environ(),
"CGO_CFLAGS="+cflags,
"CGO_CXXFLAGS="+cflags,
"CGO_LDFLAGS="+cflags+extraLDFlags)
"CGO_LDFLAGS="+cflags)
}
out, err := cmd.CombinedOutput()
if string(out) != "OK\n" {

View File

@@ -1,109 +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.
package cgotest
/*
#include <windows.h>
USHORT backtrace(ULONG FramesToCapture, PVOID *BackTrace) {
#ifdef _AMD64_
CONTEXT context;
RtlCaptureContext(&context);
ULONG64 ControlPc;
ControlPc = context.Rip;
int i;
for (i = 0; i < FramesToCapture; i++) {
PRUNTIME_FUNCTION FunctionEntry;
ULONG64 ImageBase;
VOID *HandlerData;
ULONG64 EstablisherFrame;
FunctionEntry = RtlLookupFunctionEntry(ControlPc, &ImageBase, NULL);
if (!FunctionEntry) {
// For simplicity, don't unwind leaf entries, which are not used in this test.
break;
} else {
RtlVirtualUnwind(0, ImageBase, ControlPc, FunctionEntry, &context, &HandlerData, &EstablisherFrame, NULL);
}
ControlPc = context.Rip;
// Check if we left the user range.
if (ControlPc < 0x10000) {
break;
}
BackTrace[i] = (PVOID)(ControlPc);
}
return i;
#else
return 0;
#endif
}
*/
import "C"
import (
"internal/testenv"
"reflect"
"runtime"
"strings"
"testing"
"unsafe"
)
// Test that the stack can be unwound through a call out and call back
// into Go.
func testCallbackCallersSEH(t *testing.T) {
testenv.SkipIfOptimizationOff(t) // This test requires inlining.
if runtime.Compiler != "gc" {
// The exact function names are not going to be the same.
t.Skip("skipping for non-gc toolchain")
}
if runtime.GOARCH != "amd64" {
// TODO: support SEH on other architectures.
t.Skip("skipping on non-amd64")
}
// Only frames in the test package are checked.
want := []string{
"test._Cfunc_backtrace",
"test.testCallbackCallersSEH.func1.1",
"test.testCallbackCallersSEH.func1",
"test.goCallback",
"test._Cfunc_callback",
"test.nestedCall.func1",
"test.nestedCall",
"test.testCallbackCallersSEH",
"test.TestCallbackCallersSEH",
}
pc := make([]uintptr, 100)
n := 0
nestedCall(func() {
n = int(C.backtrace(C.DWORD(len(pc)), (*C.PVOID)(unsafe.Pointer(&pc[0]))))
})
got := make([]string, 0, n)
for i := 0; i < n; i++ {
f := runtime.FuncForPC(pc[i] - 1)
if f == nil {
continue
}
fname := f.Name()
switch fname {
case "goCallback":
// TODO(qmuntal): investigate why this function doesn't appear
// when using the external linker.
continue
}
// In module mode, this package has a fully-qualified import path.
// Remove it if present.
fname = strings.TrimPrefix(fname, "cmd/cgo/internal/")
if !strings.HasPrefix(fname, "test.") {
continue
}
got = append(got, fname)
}
if !reflect.DeepEqual(want, got) {
t.Errorf("incorrect backtrace:\nwant:\t%v\ngot:\t%v", want, got)
}
}

View File

@@ -1,20 +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.
package cgotest
// extern int notoc_func(void);
// int TestPPC64Stubs(void) {
// return notoc_func();
// }
import "C"
import "testing"
func testPPC64CallStubs(t *testing.T) {
// Verify the trampolines run on the testing machine. If they
// do not, or are missing, a crash is expected.
if C.TestPPC64Stubs() != 0 {
t.Skipf("This test requires binutils 2.35 or newer.")
}
}

View File

@@ -70,7 +70,6 @@ func Test31891(t *testing.T) { test31891(t) }
func Test42018(t *testing.T) { test42018(t) }
func Test45451(t *testing.T) { test45451(t) }
func Test49633(t *testing.T) { test49633(t) }
func Test69086(t *testing.T) { test69086(t) }
func TestAlign(t *testing.T) { testAlign(t) }
func TestAtol(t *testing.T) { testAtol(t) }
func TestBlocking(t *testing.T) { testBlocking(t) }

View File

@@ -8,7 +8,6 @@ package cgotest
import (
"fmt"
"internal/testenv"
"os"
"runtime"
"sort"
@@ -146,13 +145,6 @@ func test1435(t *testing.T) {
if syscall.Getuid() != 0 {
t.Skip("skipping root only test")
}
if testing.Short() && testenv.Builder() != "" && os.Getenv("USER") == "swarming" {
// The Go build system's swarming user is known not to be root.
// Unfortunately, it sometimes appears as root due the current
// implementation of a no-network check using 'unshare -n -r'.
// Since this test does need root to work, we need to skip it.
t.Skip("skipping root only test on a non-root builder")
}
if runtime.GOOS == "linux" {
if _, err := os.Stat("/etc/alpine-release"); err == nil {
t.Skip("skipping failing test on alpine - go.dev/issue/19938")

View File

@@ -72,7 +72,7 @@ func test18146(t *testing.T) {
}()
}
runtime.GOMAXPROCS(threads)
argv := append(os.Args, "-test.run=^$")
argv := append(os.Args, "-test.run=NoSuchTestExists")
if err := syscall.Exec(os.Args[0], argv, os.Environ()); err != nil {
t.Fatal(err)
}
@@ -85,7 +85,7 @@ func test18146(t *testing.T) {
}
}()
args := append(append([]string(nil), os.Args[1:]...), "-test.run=^Test18146$")
args := append(append([]string(nil), os.Args[1:]...), "-test.run=Test18146")
for n := attempts; n > 0; n-- {
cmd := exec.Command(os.Args[0], args...)
cmd.Env = append(os.Environ(), "test18146=exec")

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !windows && !static && !(darwin && internal)
//go:build !windows && !static && (!darwin || (!internal_pie && !arm64))
#include <stdint.h>
#include <dlfcn.h>

View File

@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !windows && !static && !(darwin && internal)
//go:build !windows && !static && (!darwin || (!internal_pie && !arm64))
// Excluded in darwin internal linking PIE (which is the default) mode,
// as dynamic export is not supported.
// Excluded in darwin internal linking PIE mode, as dynamic export is not
// supported.
// Excluded in internal linking mode on darwin/arm64, as it is always PIE.
package cgotest

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build windows || static || (darwin && internal)
//go:build windows || static || (darwin && internal_pie) || (darwin && arm64)
package cgotest

View File

@@ -1,7 +1,3 @@
// Copyright 2013 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.
#include <stdio.h>
#include "issue4339.h"

View File

@@ -1,7 +1,3 @@
// Copyright 2013 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.
typedef struct Issue4339 Issue4339;
struct Issue4339 {

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