Compare commits

..

69 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
894d24d617 src/database/sql: run gofmt
Run gofmt on a source file.

Change-Id: I180d5cc7425fc5d8e9cf63005ac692f361beb1ed
Reviewed-on: https://go-review.googlesource.com/c/go/+/508497
Run-TryBot: Than McIntosh <thanm@google.com>
Reviewed-by: Eli Bendersky <eliben@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-07-07 20:48:55 +00:00
Robert Findley
ac9137f8d3 go/types, types2: do not mutate arguments in NewChecker
CL 507975 resulted in new data races (as reported in #61212), because
the pkg argument to NewChecker was mutated.

Fix this by deferring the recording of the goVersion in pkg until type
checking is actually initiated via a call to Checker.Files.
Additionally, modify types2/check.go to bring it in sync with the
changes in go/types/check.go, and generate the new version_test.go from
the types2 file.

Also move parsing the version into checkFiles, for simplicity.

Fixes #61212

Change-Id: I15edb6c2cff3085622fe7c6a3b0dab531d27bd04
Reviewed-on: https://go-review.googlesource.com/c/go/+/508439
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
2023-07-07 19:58:56 +00:00
Michael Munday
158d11196f math: add test that covers riscv64 fnm{add,sub} codegen
Adds a test that triggers the RISC-V fused multiply-add code
generation bug fixed by CL 506575.

Change-Id: Ia3a55a68b48c5cc6beac4e5235975dea31f3faf2
Reviewed-on: https://go-review.googlesource.com/c/go/+/507035
Auto-Submit: M Zhuo <mzh@golangcn.org>
Reviewed-by: M Zhuo <mzh@golangcn.org>
Run-TryBot: Michael Munday <mike.munday@lowrisc.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Joedian Reid <joedian@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2023-07-07 17:39:26 +00:00
Jonathan Amsterdam
d3d78b4bcc log/slog: handle recursively empty groups
Handlers should not display empty groups.

A group with no attributes is certainly empty. But we also want to
consider a group to be empty if all its attributes are empty groups.
The built-in handlers did not handle this second case properly.
This CL fixes that.

There are two places in the implementation that we need to consider.

For Values of KindGroup, we change the GroupValue constructor to omit
Attrs that are empty groups. A Group is then empty if and only if it
has no Attrs. This avoids a recursive check for emptiness.
It does require allocation, but that doesn't worry us because Group
values should be relatively rare.

For groups established by WithGroup, we avoid opening such groups
unless the Record contains non-empty groups. As we did for values, we
avoid adding empty groups to records in the first place, so we only
need to check that the record has at least one Attr.

We are doing extra work, so we need to make sure we aren't slowing
things down unduly. Benchmarks before and after this change show
minimal differences.

Fixes #61067.

Change-Id: I684c7ca834bbf69210516faecae04ee548846fb7
Reviewed-on: https://go-review.googlesource.com/c/go/+/508436
Run-TryBot: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-07-07 15:07:02 +00:00
Achille Roussel
39c5070712 os: do not skip directory entries with zero inodes on wasip1
When building programs to GOOS=wasip1, the program does not have the
guarantees that the underlying directories will come from a file system
where a zero inode value indicates that the entry was deleted but not
yet removed from the directory. The host runtime may be running on
windows or may be exposing virtual user-space file systems that do not
have the concept of inodes. In those setup, we assume that the host
runtime is in charge of dealing with edge cases such as skipping
directory entries with zero inodes when needed, and the guest
application should trust the list of entries that it sees;
therefore, we disable skipping over zero inodes on wasip1.

Change-Id: I99aa562441cdb4182965f270af054cf3cf7f8f20
Reviewed-on: https://go-review.googlesource.com/c/go/+/507915
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
2023-07-06 23:23:41 +00:00
Cherry Mui
e6ec2a34dc runtime: print output on failure in TestMemPprof
If running testprog fails, print the output.

For #60901.

Change-Id: Iee80fb09412ce13bae6ac3589779a8cdf7761765
Reviewed-on: https://go-review.googlesource.com/c/go/+/507978
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Cherry Mui <cherryyz@google.com>
2023-07-06 20:35:47 +00:00
Ian Lance Taylor
449ef3795d net: only build cgo_stub.go on unix or wasip1
We were building it for Windows, although Windows code never calls
any of these functions. When using -tags netgo that cause a multiple
definition of cgoAvailable.

Fixes #61153

Change-Id: Ib9e1de7720a8c0dacd6f12002917bf305dfa5405
Reviewed-on: https://go-review.googlesource.com/c/go/+/507655
Reviewed-by: Damien Neil <dneil@google.com>
Auto-Submit: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2023-07-06 19:37:13 +00:00
Russ Cox
6305d7fdd3 cmd/go: pass GoVersion in vet config
When invoking a vet tool with -vettool (or vet itself),
we need to pass the package's GoVersion to use when
analyzing the package.

The test of this behavior is in the x/tools/go/analysis CL 507880.

For #61176.

Change-Id: I3b5a90fcd19a0adc7fb29366e106e18f722fc061
Reviewed-on: https://go-review.googlesource.com/c/go/+/507976
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
2023-07-06 13:09:30 +00:00
Russ Cox
b490bdc27d go/types: record Config.GoVersion for reporting in Package.GoVersion method
Clients of go/types, such as analyzers, may need to know which
specific Go version a package is written for. Record that information
in the Package and expose it using the new GoVersion method.

Update parseGoVersion to handle the new Go versions that may
be passed around starting in Go 1.21.0: versions like "go1.21.0"
and "go1.21rc2". This is not strictly necessary today, but it adds some
valuable future-proofing.

While we are here, change NewChecker from panicking on invalid
version to saving an error for returning later from Files.
Go versions are now likely to be coming from a variety of sources,
not just hard-coded in calls to NewChecker, making a panic
inappropriate.

For #61174.
Fixes #61175.

Change-Id: Ibe41fe207c1b6e71064b1fe448ac55776089c541
Reviewed-on: https://go-review.googlesource.com/c/go/+/507975
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
2023-07-06 13:09:19 +00:00
Merrick Clay
36ea4f9680 log/slog: fix faulty test
Adds an optional close quote in the expected log message regex for TestConnections to prevent failing when the source filepath is surrounded in quotes due to it containing one or more spaces.

Fixes #61161

Change-Id: I0dd71fb4389bff963bbfdc668ef4e4dfe787eafc
Reviewed-on: https://go-review.googlesource.com/c/go/+/508055
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-07-06 00:01:44 +00:00
Meng Zhuo
3fce111535 cmd/compile: fix FMA negative commutativity of riscv64
According to RISCV manual 11.6:

FMADD x,y,z computes x*y+z and
FNMADD x,y,z => -x*y-z
FMSUB x,y,z => x*y-z
FNMSUB x,y,z => -x*y+z respectively

However our implement of SSA convert FMADD -x,y,z to FNMADD x,y,z which
is wrong and should be convert to FNMSUB according to manual.

Change-Id: Ib297bc83824e121fd7dda171ed56ea9694a4e575
Reviewed-on: https://go-review.googlesource.com/c/go/+/506575
Run-TryBot: M Zhuo <mzh@golangcn.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Joedian Reid <joedian@golang.org>
Reviewed-by: Michael Munday <mike.munday@lowrisc.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-07-05 22:05:44 +00:00
Michael Munday
c8dad424bf math: fix portable FMA when x*y < 0 and x*y == -z
When x*y == -z the portable implementation of FMA copied the sign
bit from x*y into the result. This meant that when x*y == -z and
x*y < 0 the result was -0 which is incorrect.

Fixes #61130.

Change-Id: Ib93a568b7bdb9031e2aedfa1bdfa9bddde90851d
Reviewed-on: https://go-review.googlesource.com/c/go/+/507376
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Michael Munday <mike.munday@lowrisc.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Joedian Reid <joedian@golang.org>
2023-07-05 22:05:30 +00:00
zikaeroh
cd6676126b database/sql: prevent internal context error from being returned from Rows.Err()
CL 497675 modified Rows such that context errors are propagated through
Rows.Err(). This caused an issue where calling Close meant that an
internal cancellation error would (eventually) be returned from Err:

1. A caller makes a query using a cancellable context.
2. initContextClose sees that either the query context or the
   transaction context can be canceled, so will need to spawn a
   goroutine to capture their errors.
3. initContextClose derives a context from the query context via
   WithCancel and sets rs.cancel.
4. When a user calls Close, rs.cancel is called. awaitDone's ctx is
   cancelled, which is good, since we don't want it to hang forever.
5. This internal cancellation (after CL 497675) has its error saved on
   contextDone.
6. Later, calling Err will return the error in contextDone if present.

This leads to a race condition depending on how quickly Err is called
after Close.

The docs for Close and Err state that calling Close should have no
affect on the return result for Err. So, a potential fix is to ensure
that awaitDone does not save the error when the cancellation comes from
a Close via rs.cancel.

This CL does that, using a new context not derived from the query
context, whose error is ignored as the query context's error used to be
before the original bugfix.

The included test fails before the CL, and passes afterward.

Fixes #60932

Change-Id: I2bf4c549efd83d62b86e298c9c45ebd06a3ad89a
Reviewed-on: https://go-review.googlesource.com/c/go/+/505397
Auto-Submit: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2023-07-05 17:10:36 +00:00
Michael Anthony Knyszek
b2215e49c7 runtime,runtime/metrics: clarify OS stack metrics
There are some subtle details here about measuring OS stacks in cgo
programs. There's also an expectation about magnitude in the MemStats
docs that isn't in the runtime/metrics docs. Fix both.

Fixes #54396.

Change-Id: I6b60a62a4a304e6688e7ab4d511d66193fc25321
Reviewed-on: https://go-review.googlesource.com/c/go/+/502156
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
2023-07-05 15:21:49 +00:00
Keith Randall
e126572f8a runtime: have ReadMemStats do a nil check before switching stacks
This gives the user a better stack trace experience. No need to
expose them to runtime.systemstack and friends.

Fixes #61158

Change-Id: I4f423f82e54b062773067c0ae64622e37cb3948b
Reviewed-on: https://go-review.googlesource.com/c/go/+/507755
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
2023-07-04 16:54:39 +00:00
Oleksandr Redko
e4ed92a355 os, syscall: update unreachable link about =C: envs
Change-Id: I185dec133599f9c69fda7563697bbc33e433fb78
Reviewed-on: https://go-review.googlesource.com/c/go/+/507135
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
2023-07-04 15:31:54 +00:00
Meng Zhuo
5c1a15df41 test/codegen: enable Mul2 DivPow2 test for riscv64
Change-Id: Ice0bb7a665599b334e927a1b00d1a5b400c15e3d
Reviewed-on: https://go-review.googlesource.com/c/go/+/506035
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
2023-07-04 13:33:45 +00:00
Michael Pratt
5b72f45dd1 runtime: check GOFLAGS not GCFLAGS
GCFLAGS doesn't have any defined meaning. cmd/dist enables
mayMoreStackPreempt with GOFLAGS.

For #55160.

Change-Id: I7ac71e4a1a983a56bd228ab5d24294db5cc595f7
Reviewed-on: https://go-review.googlesource.com/c/go/+/507359
Run-TryBot: Michael Pratt <mpratt@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
2023-06-30 22:02:00 +00:00
Chris O'Hara
18e17e2cb1 net: enable pure Go resolver for wasip1
Top-level functions in the net package that only read files,
for example LookupPort(...), or LookupIP(host) where host resides
in /etc/hosts, now work on wasip1.

If the application has the ability to create sockets (for example,
when using a sockets extension to WASI preview 1), it's now
possible to do name resolution by passing a custom Dial function
to a Resolver instance.

Change-Id: I923886f67e336820bc89f09ea1855387c8dac61a
Reviewed-on: https://go-review.googlesource.com/c/go/+/500579
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Randy Reddig <ydnar@shaderlab.com>
Reviewed-by: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2023-06-29 23:06:46 +00:00
Chris O'Hara
1e97c51536 syscall: stub Getrlimit on wasip1
This is a prerequisite to enabling the pure Go resolver for
wasip1.

Change-Id: Iecd8a18ce4c9eb69a697d29930bedb7175b4f0ce
Reviewed-on: https://go-review.googlesource.com/c/go/+/500577
Run-TryBot: Ian Lance Taylor <iant@google.com>
Reviewed-by: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-06-29 23:05:01 +00:00
Jes Cok
683f51d307 cmd/asm/internal/lex: fix comment, remove the first "has"
Change-Id: I429f0fa6c99ef576fe83c7bd0d1c1e176ecbb179
GitHub-Last-Rev: fb581b7f27
GitHub-Pull-Request: golang/go#61066
Reviewed-on: https://go-review.googlesource.com/c/go/+/507097
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
2023-06-29 22:49:50 +00:00
Robert Griesemer
2db31efdba cmd/compile/internal/types2: make TestIssue43124 match the go/types version
Replace the (flaky) types2.TestIssue43124 with the code of the
(stable) go/types version of this test.

While at it, replace a handful of syntax.Pos{} with the equivalent
nopos, to further reduce differences between the two versions of
the issues_test.go file.

For #61064.

Change-Id: I69f3e4627a48c9928e335d67736cb875ba3835fc
Reviewed-on: https://go-review.googlesource.com/c/go/+/507215
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
2023-06-29 18:29:51 +00: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
Damien Neil
499458f7ca net/http: validate Host header before sending
Verify that the Host header we send is valid.
Avoids surprising behavior such as a Host of "go.dev\r\nX-Evil:oops"
adding an X-Evil header to HTTP/1 requests.

Add a test, skip the test for HTTP/2. HTTP/2 is not vulnerable to
header injection in the way HTTP/1 is, but x/net/http2 doesn't validate
the header and will go into a retry loop when the server rejects it.
CL 506995 adds the necessary validation to x/net/http2.

For #60374

Change-Id: I05cb6866a9bead043101954dfded199258c6dd04
Reviewed-on: https://go-review.googlesource.com/c/go/+/506996
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Damien Neil <dneil@google.com>
2023-06-29 17:00:06 +00:00
Than McIntosh
fe73c186eb cmd/{go,compile}: run gofmt
Ran gofmt on a couple of Go source files that needed it.

Change-Id: I0e9f78831f531a728b892a63c6e0c517d92b11a8
Reviewed-on: https://go-review.googlesource.com/c/go/+/507156
Run-TryBot: Than McIntosh <thanm@google.com>
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-06-29 16:02:11 +00:00
Chris O'Hara
da5d8fdd0c runtime: run wasip1 tests with wazero
The latest wazero release supports non-blocking I/O and pre-opened
sockets. Unmask the relevant wasip1 tests so that there are multiple
WebAssembly runtimes exercising these code paths.

Change-Id: I8506ab35186f98fde2cd3ce84634d5fcb7b053f1
Reviewed-on: https://go-review.googlesource.com/c/go/+/503595
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Auto-Submit: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Run-TryBot: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
2023-06-29 15:35:27 +00:00
Ben Hoyt
411c99671a slices, maps: add examples; doc comment fixes
There are currently no examples in the new slices and maps package, so
add some. This adds examples for most functions in the slices package
except the very obvious ones, and adds examples for the DeleteFunc and
EqualFunc functions in the maps package.

Also clarify/correct a few doc comments:

* EqualFunc takes an "equality" function, not a "comparison" function
* It's confusing for Delete and DeleteFunc to say they "do not create a
  new slice", as they do return a new slice. They already say they
  "return the modified slice" which is enough.
* Similar for Compact, and mention that it returns the modified slice
  (and say why)
* Note that CompactFunc keeps the first element in equal runs
* Say what cmp is in SortStableFunc and IsSortedFunc
* Say that MinFunc and MaxFunc return the first value

Change-Id: I59c7bb1c7cabc4986d81018a5aaf5b712d3310f2
Reviewed-on: https://go-review.googlesource.com/c/go/+/505095
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-06-29 15:34:32 +00:00
Mark Ryan
03cd8a7b0e internal/bytealg: fix alignment code in equal_riscv64.s
The riscv64 implementation of equal has an optimization that is
applied when both pointers share the same alignment but that alignment
is not 8 bytes.  In this case it tries to align both pointers to an 8 byte boundaries,
by individually comparing the first few bytes of each buffer.  Unfortunately,
the existing code is incorrect.  It adjusts the pointers by the wrong number
of bytes resulting, in most cases, in pointers that are not 8 byte aligned.

This commit fixes the issue by individually comparing the first
(8 - (pointer & 7)) bytes of each buffer rather than the first
(pointer & 7) bytes.

This particular optimization is not covered by any of the existing
benchmarks so a new benchmark, BenchmarkEqualBothUnaligned,
is provided.  The benchmark tests the case where both pointers have
the same alignment but may not be 8 byte aligned.  Results of the
new benchmark along with some of the existing benchmarks generated on
a SiFive HiFive Unmatched A00 with 16GB of RAM running Ubuntu 23.04
are presented below.

Equal/0-4                                 3.356n ± 0%    3.357n ± 0%        ~ (p=0.840 n=10)
Equal/1-4                                 63.91n ± 7%    65.97n ± 5%   +3.22% (p=0.029 n=10)
Equal/6-4                                 72.94n ± 5%    76.09n ± 4%        ~ (p=0.075 n=10)
Equal/9-4                                 84.61n ± 7%    85.83n ± 3%        ~ (p=0.315 n=10)
Equal/15-4                                103.7n ± 2%    102.9n ± 4%        ~ (p=0.739 n=10)
Equal/16-4                                89.14n ± 3%   100.40n ± 4%  +12.64% (p=0.000 n=10)
Equal/20-4                                107.8n ± 3%    106.8n ± 3%        ~ (p=0.725 n=10)
Equal/32-4                                63.95n ± 8%    67.79n ± 7%        ~ (p=0.089 n=10)
Equal/4K-4                                1.256µ ± 1%    1.254µ ± 0%        ~ (p=0.925 n=10)
Equal/4M-4                                1.231m ± 0%    1.230m ± 0%   -0.04% (p=0.011 n=10)
Equal/64M-4                               19.77m ± 0%    19.78m ± 0%        ~ (p=0.052 n=10)
EqualBothUnaligned/64_0-4                 43.70n ± 4%    44.40n ± 5%        ~ (p=0.529 n=10)
EqualBothUnaligned/64_1-4                6957.5n ± 0%    105.9n ± 1%  -98.48% (p=0.000 n=10)
EqualBothUnaligned/64_4-4                 100.1n ± 2%    101.5n ± 4%        ~ (p=0.149 n=10)
EqualBothUnaligned/64_7-4               6965.00n ± 0%    95.60n ± 4%  -98.63% (p=0.000 n=10)
EqualBothUnaligned/4096_0-4               1.233µ ± 1%    1.225µ ± 0%   -0.65% (p=0.015 n=10)
EqualBothUnaligned/4096_1-4             584.226µ ± 0%    1.277µ ± 0%  -99.78% (p=0.000 n=10)
EqualBothUnaligned/4096_4-4               1.270µ ± 1%    1.268µ ± 0%        ~ (p=0.105 n=10)
EqualBothUnaligned/4096_7-4             584.944µ ± 0%    1.266µ ± 1%  -99.78% (p=0.000 n=10)
EqualBothUnaligned/4194304_0-4            1.241m ± 0%    1.236m ± 0%   -0.38% (p=0.035 n=10)
EqualBothUnaligned/4194304_1-4          600.956m ± 0%    1.238m ± 0%  -99.79% (p=0.000 n=10)
EqualBothUnaligned/4194304_4-4            1.239m ± 0%    1.241m ± 0%   +0.22% (p=0.007 n=10)
EqualBothUnaligned/4194304_7-4          601.036m ± 0%    1.239m ± 0%  -99.79% (p=0.000 n=10)
EqualBothUnaligned/67108864_0-4           19.79m ± 0%    19.78m ± 0%        ~ (p=0.393 n=10)
EqualBothUnaligned/67108864_1-4         9616.61m ± 0%    19.82m ± 0%  -99.79% (p=0.000 n=10)
EqualBothUnaligned/67108864_4-4           19.82m ± 0%    19.82m ± 0%        ~ (p=0.971 n=10)
EqualBothUnaligned/67108864_7-4         9616.34m ± 0%    19.86m ± 0%  -99.79% (p=0.000 n=10)
geomean                                   38.38µ         7.194µ       -81.26%

Change-Id: I4caab6c3450bd7e2773426b08b70bbc37fbe4e5f
Reviewed-on: https://go-review.googlesource.com/c/go/+/500855
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
2023-06-29 02:34:59 +00:00
Cuong Manh Le
8b5fe5980c cmd/compile: handle min/max correctly in mayCall
CL 500575 changed mayCall to return "false" for min/max builtin.

However, with string or float, min/max requires runtime call, so mayCall
should return true instead. This's probably not a big problem, because
CL 506115 makes order pass handle min/max correctly. But it's still
better to do it the right way.

Updates #60582

Change-Id: I9779ca62bebd0f95e52ad5fa55b9160dc35b33aa
Reviewed-on: https://go-review.googlesource.com/c/go/+/506855
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-06-28 21:18:31 +00:00
Matthew Dempsky
79d4defa75 cmd/compile/internal/ssagen: fix min/max codegen, again
The large-function phi placement algorithm evidently doesn't like the
same pseudo-variable being used to represent expressions of varying
types.

Instead, use the same tactic as used for "valVar" (ssa.go:6585--6587),
which is to just generate a fresh marker node each time.

Maybe we could just use the OMIN/OMAX nodes themselves as the key
(like we do for OANDAND/OOROR), but that just seems needlessly risky
for negligible memory savings. Using fresh marker values each time
seems obviously safe by comparison.

Fixes #61041.

Change-Id: Ie2600c9c37b599c2e26ae01f5f8a433025d7fd08
Reviewed-on: https://go-review.googlesource.com/c/go/+/506679
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2023-06-28 16:07:47 +00:00
Russ Cox
a3093eca64 cmd/go: enable slog vet check during 'go test'
The slog check is new and no existing code uses slog (it's new too),
so there are no concerns about false positives in existing code.
Enable it by default.

Change-Id: I4fc1480eeb5a3acc9e5e095e9d5428f5ce04b121
Reviewed-on: https://go-review.googlesource.com/c/go/+/505915
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-06-28 02:41:38 +00:00
Ian Lance Taylor
6691f438c3 cmd/dist, internal/abi: support bootstrapping with gccgo
The required gc bootstrap compiler, 1.17, has an internal/lazyregexp
package. It permits that package to be imported by internal/profile
while bootstrapping. The gccgo compiler also has an internal/lazyregexp
package, but it does not permit the gc compiler to import it.

Permit bootstrapping with gccgo by adding internal/lazyregexp to the
list of bootstrap directories.

The gccgo compiler recognizes the magic functions internal/abi.FuncPCABI0
and FuncPCABIInternal, but only in the internal/abi package, not
in the bootstrapping internal/abi package.

Permit bootstrapping with gccgo by adding definitions of those functions
with build tags so that they are only used by gccgo.

Fixes #60913

Change-Id: I3a78848d545db13314409d170d63f4cc737ca12e
Reviewed-on: https://go-review.googlesource.com/c/go/+/505036
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
2023-06-27 21:15:37 +00:00
Hiro
942c1c12d8 runtime: fix trace.Stop deadlock when built with faketime
For #60806

Change-Id: I1ac18a6c7c703a1d6c4cd80f220059ba0be51e09
GitHub-Last-Rev: d300ca3f31
GitHub-Pull-Request: golang/go#60834
Reviewed-on: https://go-review.googlesource.com/c/go/+/503356
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-06-27 18:21:24 +00:00
Cuong Manh Le
4ad4128d3c cmd/compile: fix bad order of evaluation for min/max builtin
For float or string, min/max builtin performs a runtime call, so we need
to save its result to temporary variable. Otherwise, the runtime call
will clobber closure's arguments currently on the stack when passing
min/max as argument to closures.

Fixes #60990

Change-Id: I1397800f815ec7853182868678d0f760b22afff2
Reviewed-on: https://go-review.googlesource.com/c/go/+/506115
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
2023-06-27 18:18:23 +00:00
Joe Tsai
4f36f7e4dd encoding: document that base32 and base64 do not use UTF-8
The invention of base32 and base64 predates the invention of UTF-8
and was never meant to output valid UTF-8.
By default, the output is always valid ASCII (and thus valid UTF-8)
except when the user specifies an alphabet or padding value
that is larger than '\x7f'. If that is done,
then the exact byte symbol is used rather than the UTF-8 encoding.

Fixes #60689

Change-Id: I4ec88d974ec0658ad1a578bbd65a809e27c73ea7
Reviewed-on: https://go-review.googlesource.com/c/go/+/505237
Run-TryBot: Joseph Tsai <joetsai@digital-static.net>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-06-27 17:27:30 +00:00
qmuntal
8008c0840f syscall: clarify which handles are affected by SysProcAttr.NoInheritHandles
SysProcAttr.NoInheritHandles doc comment is not clear about which
handles are affected by it. This CL clarifies that it not only affects
the ones passed in AdditionalInheritedHandles, but also the ones
passed in ProcAttr.Files, which are required to be stderr, stdin and
stdout when calling syscall.StartProcess.

Updates #60942

Change-Id: I5bc5b3604b6db04b83f6764d5c5ffbdafeeb22fb
Reviewed-on: https://go-review.googlesource.com/c/go/+/505515
Run-TryBot: Quim Muntal <quimmuntal@gmail.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-06-27 16:16:24 +00:00
Chris O'Hara
13529cc5f4 syscall: try non-blocking stdio on wasip1
Try to set stdio to non-blocking mode before the os package
calls NewFile for each fd. NewFile queries the non-blocking flag
but doesn't change it, even if the runtime supports non-blocking
stdio. Since WebAssembly modules are single-threaded, blocking
system calls temporarily halt execution of the module. If the
runtime supports non-blocking stdio, the Go runtime is able to
use the WASI net poller to poll for read/write readiness and is
able to schedule goroutines while waiting.

Change-Id: I1e3ce68a414e3c5960ce6a27fbfd38556e59c3dc
Reviewed-on: https://go-review.googlesource.com/c/go/+/498196
Reviewed-by: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Auto-Submit: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Reviewed-by: Achille Roussel <achille.roussel@gmail.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Run-TryBot: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
2023-06-27 01:09:18 +00:00
Robert Griesemer
1dbbafc70f go/types, types2: replace TODO with clarifying comment
This resolves an open question.
No non-comment code changes.

Change-Id: Idc92794090b2dde694394d1fcd916f6ea61f03e7
Reviewed-on: https://go-review.googlesource.com/c/go/+/506395
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
2023-06-26 21:06:37 +00:00
Tobias Klauser
7cc0740596 slices: add godoc links
Change-Id: I79d2bab2275f123636b63e87533ae9dad69ee00f
Reviewed-on: https://go-review.googlesource.com/c/go/+/506135
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
Auto-Submit: Tobias Klauser <tobias.klauser@gmail.com>
Reviewed-by: Eli Bendersky <eliben@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
2023-06-26 19:11:18 +00:00
Robert Griesemer
d49017a7c3 go/types, types2: fix interface unification
When unification of two types succeeds and at least one of them
is an interface, we must be more cautious about when to accept
the unification, to avoid order dependencies and unexpected
inference results.

The changes are localized and only affect matching against
interfaces; they further restrict what are valid unifications
(rather than allowing more code to pass). We may be able to
remove some of the restriotions in a future release.

See comments in code for a detailed description of the changes.

Also, factored out "asInterface" functionality into a function
to avoid needless repetition in the code.

Fixes #60933.
Fixes #60946.

Change-Id: I923f7a7c1a22e0f4fd29e441e016e7154429fc5e
Reviewed-on: https://go-review.googlesource.com/c/go/+/505396
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
2023-06-26 18:33:36 +00:00
Cuong Manh Le
b3ca8d2b3c types2, go/types: record final type for min/max arguments
Fixes #60991

Change-Id: I6130ccecbdc209996dbb376491be9df3b8988327
Reviewed-on: https://go-review.googlesource.com/c/go/+/506055
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-06-26 17:08:05 +00:00
Robert Griesemer
ee361ce66c go/types, types2: more readable inference trace
Print the unification mode in human-readable form.
Use a tab and // instead of ()'s to show unification mode
and whether operands where swapped.

These changes only affect inference trace output, which is
disabled by default. For easier debugging.

For #60933.

Change-Id: I95299c6e09b90670fc45addc4f9196b6cdd3b59f
Reviewed-on: https://go-review.googlesource.com/c/go/+/505395
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
2023-06-26 15:43:55 +00:00
Kota
9f6e87ff74 doc/go1.21: document changes in crypto/x509
RevocationList.RevokedCertificates has been deprecated and
replaced with the new RevocationList.RevokedCertificateEntries field,
not RevocationList.Entries.

Change-Id: I36053e0d67a9997264483d1e04e31774fbab8702
GitHub-Last-Rev: a9f6949b05
GitHub-Pull-Request: golang/go#60984
Reviewed-on: https://go-review.googlesource.com/c/go/+/505935
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Bypass: Dmitri Shuralyov <dmitshur@golang.org>
2023-06-26 14:53:03 +00:00
Ian Lance Taylor
f5015b5164 doc/go1.21: context.Background and TODO may now appear equal
Fixes #60978

Change-Id: I3e4bd366dc30ac435698b8f17170695330034683
Reviewed-on: https://go-review.googlesource.com/c/go/+/505795
TryBot-Bypass: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Sameer Ajmani <sameer@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
2023-06-26 12:57:55 +00:00
Keith Randall
a031f4ef83 cmd/compile: fix min/max builtin code generation
Our large-function phi placement algorithm is incompatible with phi
opcodes already existing in the SSA representation. Instead, use simple
variable assignments and have the phi placement algorithm place the phis
we need for min/max.

Turns out the small-function phi placement algorithm doesn't have this
sensitivity, so this bug only occurs in large functions (>500 basic blocks).

Maybe we should document/check that no phis are present when we start
phi placement (regardless of size).  Leaving for a potential separate CL.

We should probably also fix the placement algorithm to handle existing
phis correctly.  But this CL is probably a lot smaller/safer than
messing with phi placement.

Fixes #60982

Change-Id: I59ba7f506c72b22bc1485099a335d96315ebef67
Reviewed-on: https://go-review.googlesource.com/c/go/+/505756
Reviewed-by: Keith Randall <khr@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2023-06-24 05:24:25 +00:00
Ian Lance Taylor
ea927e560d slices: clarify MinFunc/MaxFunc result for equal elements
They should return the first of equal elements. No such clarification
is required for Min/Max as for them equal elements are indistinguishable.

For #60091

Change-Id: Iad58115d482add852c811e993131702b5b3bec5e
Reviewed-on: https://go-review.googlesource.com/c/go/+/505796
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Eli Bendersky <eliben@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Ian Lance Taylor <iant@google.com>
2023-06-24 00:50:42 +00:00
Roland Shoemaker
3619255777 crypto/x509: rename duplicated test
Rename the old TestPlatformVerifier to TestPlatformVerifierLegacy, and
add TODO about removing it once the synthetic root is widely deployed on
builders.

Updates #52108

Change-Id: I6cdba268e4738804c7f76ea18c354470b3e0318c
Reviewed-on: https://go-review.googlesource.com/c/go/+/505755
Run-TryBot: Roland Shoemaker <roland@golang.org>
Auto-Submit: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
2023-06-23 19:48:23 +00:00
Jelle van den Hooff
48dbb6227a runtime: set raceignore to zero when starting a new goroutine
When reusing a g struct the runtime did not reset
g.raceignore. Initialize raceignore to zero when initially
setting racectx.

A goroutine can end with a non-zero raceignore if it exits
after calling runtime.RaceDisable without a matching
runtime.RaceEnable. If that goroutine's g is later reused
the race detector is in a weird state: the underlying
g.racectx is active, yet g.raceignore is non-zero, and
raceacquire/racerelease which check g.raceignore become
no-ops. This causes the race detector to report races when
there are none.

Fixes #60934

Change-Id: Ib8e412f11badbaf69a480f03740da70891f4093f
Reviewed-on: https://go-review.googlesource.com/c/go/+/505055
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
2023-06-23 16:46:25 +00:00
Filippo Valsorda
3adcce5ae7 crypto: document non-determinism of GenerateKey
Fixes #58637

Change-Id: I9eb3905d5b35ea22e22e1d8eb8c33594eac487fc
Reviewed-on: https://go-review.googlesource.com/c/go/+/505155
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
2023-06-23 16:12:46 +00:00
Cuong Manh Le
6dce882b3a cmd/compile: scanning closures body when visiting wrapper function
CL 410344 fixed missing method value wrapper, by visiting body of
wrapper function after applying inlining pass.

CL 492017 allow more inlining of functions that construct closures,
which ends up making the wrapper function now inlineable, but can
contain closure nodes that couldn't be inlined. These closures body may
contain OMETHVALUE nodes that we never seen, thus we need to scan
closures body for finding them.

Fixes #60945

Change-Id: Ia1e31420bb172ff87d7321d2da2989ef23e6ebb6
Reviewed-on: https://go-review.googlesource.com/c/go/+/505255
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2023-06-23 14:29:16 +00:00
Cuong Manh Le
164aceea08 log/slog: fix broken link to AnyValue in comment
Change-Id: Ida52a2bf6a415017942bf9ccd74a1ea9ed02bc46
Reviewed-on: https://go-review.googlesource.com/c/go/+/505535
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2023-06-23 12:15:52 +00:00
Christopher Taylor
82e17c4d11 log/slog: fix broken link to Record.Clone in package docs
Change-Id: If8b937fa9db89a537ad7d4ccb8c04f84d2cff3db
GitHub-Last-Rev: fdd4338118
GitHub-Pull-Request: golang/go#60938
Reviewed-on: https://go-review.googlesource.com/c/go/+/505075
TryBot-Bypass: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2023-06-23 12:15:01 +00:00
Bryan C. Mills
25e46693a1 cmd/go: impersonate 'go tool dist list' if 'go tool dist' is not present
Fixes #60939.

Change-Id: I6a15db558a8e80e242818cccd642899aba47e596
Reviewed-on: https://go-review.googlesource.com/c/go/+/505176
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Bryan Mills <bcmills@google.com>
2023-06-22 19:52:13 +00:00
Bryan C. Mills
f8616b8484 internal/platform,cmd/dist: export the list of supported platforms
Also switch internal/platform to commit the generated code instead of
regenerating it in cmd/dist. Nothing in the generated code depends on
the target configuration, and committing the source file makes it
more amenable to searching and indexing (particularly on
https://cs.opensource.google/go/go).

For #60939.

Change-Id: I9133dfd5129b3c4d7457267589dfac5e7ecbef65
Reviewed-on: https://go-review.googlesource.com/c/go/+/505175
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Bryan Mills <bcmills@google.com>
Reviewed-by: Austin Clements <austin@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
2023-06-22 19:44:52 +00:00
Than McIntosh
51885c1fa2 cmd/{go,cover}: enable response file args for cmd/cover
Change the cover command to accept arguments via response files, using
the same mechanism employed for the compiler and the assembler. This
is needed now that the cover tool accepts a list of all source files
in a package, as opposed to just a single source file, and as a result
can run into system-dependent command line length limits.

Fixes #60785.

Change-Id: I67dbc96ad9fc5c6f43d5c1e4e903e4b8589b154f
Reviewed-on: https://go-review.googlesource.com/c/go/+/503735
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
2023-06-22 18:36:44 +00:00
Oleksandr Redko
3479e1e543 internal/fuzz: fix typo in comment
Change-Id: I04f0aa2730cd7d60027a36a3b81289e4972d4a9c
Reviewed-on: https://go-review.googlesource.com/c/go/+/505115
Reviewed-by: Roland Shoemaker <roland@golang.org>
Auto-Submit: Roland Shoemaker <roland@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-06-22 17:10:57 +00:00
Roland Shoemaker
20313660f5 crypto/x509: tolerate multiple matching chains in testVerify
Due to the semantics of roots, a root store may contain two valid roots
that have the same subject (but different SPKIs) at the asme time. As
such in testVerify it is possible that when we verify a certificate we
may get two chains that has the same stringified representation.

Rather than doing something fancy to include keys (which is just overly
complicated), tolerate multiple matches.

Fixes #60925

Change-Id: I5f51f7635801762865a536bcb20ec75f217a36ea
Reviewed-on: https://go-review.googlesource.com/c/go/+/505035
Reviewed-by: Heschi Kreinick <heschi@google.com>
Run-TryBot: Roland Shoemaker <roland@golang.org>
Auto-Submit: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-06-22 16:47:24 +00:00
Ian Lance Taylor
78c3aba470 net/mail: permit more characters in mail headers
We parse mail messages using net/textproto. For #53188, we tightened
up the bytes permitted by net/textproto to match RFC 7230.
However, this package uses RFC 5322 which is more permissive.
Restore the permisiveness we used to have, so that older code
continues to work.

Fixes #58862
Fixes #60332

Change-Id: I5437f5e18a756f6ca61c13c4d8ba727be73eff9a
Reviewed-on: https://go-review.googlesource.com/c/go/+/504416
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
2023-06-21 21:39:08 +00:00
Ian Lance Taylor
633b742ae0 test: add test that caused a gofrontend crash
Change-Id: Idd872c5b90dbca564ed8a37bb3683e642142ae63
Reviewed-on: https://go-review.googlesource.com/c/go/+/505015
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Ian Lance Taylor <iant@google.com>
2023-06-21 21:30:46 +00:00
Ian Lance Taylor
ad2c517708 doc/go1.21: correct GOOS to GOARCH (another location)
Change-Id: Ie71bc41bd7f1aecf6ce69a8b310668fdd03da42b
Reviewed-on: https://go-review.googlesource.com/c/go/+/504880
TryBot-Bypass: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Rhys Hiltner <rhys@justin.tv>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Eli Bendersky <eliben@google.com>
2023-06-21 20:42:55 +00:00
Ian Lance Taylor
b23cae8095 doc/go1.21: correct GOOS to GOARCH
For #57752
Fixes #60924

Change-Id: Ie1e16c041885abb51dd6c2f0b7dfa03091cfb338
Reviewed-on: https://go-review.googlesource.com/c/go/+/504879
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Eli Bendersky <eliben@google.com>
TryBot-Bypass: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
2023-06-21 19:47:51 +00:00
Robert Griesemer
b1f1fb2950 go/types, types2: avoid spurious "declared and not used" error
Fixes #60906.

Change-Id: Iba117b36041f72a54ce82cc914f8fa3b07a6fb2e
Reviewed-on: https://go-review.googlesource.com/c/go/+/504877
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
2023-06-21 18:32:13 +00:00
Michael Anthony Knyszek
e45202f215 runtime: relate GODEBUG=gctrace output to runtime/metrics
There's more I could list here, but the mapping becomes more complicated
and more fragile. I think this is sufficient to start with.

Fixes #46846.

Change-Id: I6803486a64888b2f38e244b8e2175ad064d648ed
Reviewed-on: https://go-review.googlesource.com/c/go/+/504115
Reviewed-by: Michael Pratt <mpratt@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
2023-06-21 15:57:28 +00:00
Russ Cox
36edde9d9f cmd/go: shorten longest 5 tests
Running go test -parallel=1 -v, these are the top 10 tests:

PASS: TestScript/mod_invalid_version 40.14s
PASS: TestScript/build_cache_output 46.82s
PASS: TestScript/get_legacy 48.69s
PASS: TestTestCache 58.44s
PASS: TestScript/mod_get_direct 62.88s
PASS: TestScript/build_pgo_auto_multi 63.49s
PASS: TestScript/build_pgo_auto 70.69s
PASS: TestScript/gcflags_patterns 95.17s
PASS: TestScript/mod_list_compiled_concurrent 124.31s
PASS: TestScript/vet_flags 202.85s

Change the top 5 not to run builds at all, so they don't
have to use -a or clear the go build cache.

mod_get_direct should be replaced with a vcs-test test.
mod_invalid_version should be replaced with a vcs-test test.
get_legacy should be deleted eventually.

Change-Id: Id67c458b1a96c912d89cbece341372c2ef5ee082
Reviewed-on: https://go-review.googlesource.com/c/go/+/504536
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-06-21 14:58:44 +00:00
cuiweixie
413e6c0499 cmd/compile/internal/ir: typo
n.TypeCheck() == 3 is never true now, in n.SetTypecheck(x), when x > 2,
it panic.

Change-Id: Ic876680435d4536eb63dcedee20a07ccdf918b91
Reviewed-on: https://go-review.googlesource.com/c/go/+/504435
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
2023-06-21 11:12:48 +00:00
Jonathan Amsterdam
f3bf18117b log/slog: fix HandlerOptions.ReplaceAttr doc
It said that Attrs with an empty key are ignored.
In fact, zero Attrs are ignored.

Fixes #60870.

Change-Id: I221d3a25b0f0cc9001e06e9cc76bab29292c0741
Reviewed-on: https://go-review.googlesource.com/c/go/+/504535
Run-TryBot: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-06-20 23:57:50 +00:00
Ian Lance Taylor
e122ebabb6 encoding/binary: on invalid type return -1 from Size
Size is defined as returning -1 if the type is not fixed-size.
Before this CL cases like Size((*[]int)(nil)) would crash.

Fixes #60892

Change-Id: Iee8e20a0aee24b542b78cb4160c3b2c5a3eb02c2
Reviewed-on: https://go-review.googlesource.com/c/go/+/504575
Auto-Submit: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
2023-06-20 18:28:44 +00:00
Ian Lance Taylor
8484f2fe02 cmd/go: add comment for intentional misspelling
Try to avoid fixes from automatic spell checkers.

Change-Id: I1d134fb2721decffa865a3f4d78bca4fce8e8fee
Reviewed-on: https://go-review.googlesource.com/c/go/+/502658
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
2023-06-20 18:25:35 +00:00
140 changed files with 4228 additions and 481 deletions

2
.gitignore vendored
View File

@@ -33,12 +33,10 @@ _testmain.go
/src/cmd/cgo/zdefaultcc.go
/src/cmd/dist/dist
/src/cmd/go/internal/cfg/zdefaultcc.go
/src/cmd/go/internal/cfg/zosarch.go
/src/cmd/internal/objabi/zbootstrap.go
/src/go/build/zcgo.go
/src/go/doc/headscan
/src/internal/buildcfg/zbootstrap.go
/src/internal/platform/zosarch.go
/src/runtime/internal/sys/zversion.go
/src/unicode/maketables
/src/time/tzdata/zzipdata.go

View File

@@ -1,2 +0,0 @@
go1.21rc2
time 2023-06-21T02:00:01Z

View File

@@ -174,6 +174,7 @@ pkg go/build, type Package struct, Directives []Directive #56986
pkg go/build, type Package struct, TestDirectives []Directive #56986
pkg go/build, type Package struct, XTestDirectives []Directive #56986
pkg go/token, method (*File) Lines() []int #57708
pkg go/types, method (*Package) GoVersion() string #61175
pkg html/template, const ErrJSTemplate = 12 #59584
pkg html/template, const ErrJSTemplate ErrorCode #59584
pkg io/fs, func FormatDirEntry(DirEntry) string #54451

View File

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

View File

@@ -473,6 +473,16 @@ Do not send CLs removing the interior tags from such phrases.
The new <a href="/pkg/context/#AfterFunc"><code>AfterFunc</code></a>
function registers a function to run after a context has been cancelled.
</p>
<p><!-- CL 455455 -->
An optimization means that the results of calling
<a href="/pkg/context/#Background"><code>Background</code></a>
and <a href="/pkg/context/#TODO"><code>TODO</code></a> and
converting them to a shared type can be considered equal.
In previous releases they were always different. Comparing
<a href="/pkg/context/#Context"><code>Context</code></a> values
for equality has never been well-defined, so this is not
considered to be an incompatible change.
</dd>
</dl>
@@ -495,7 +505,7 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="crypto/rsa"><dt><a href="/pkg/crypto/rsa/">crypto/rsa</a></dt>
<dd>
<p><!-- CL 471259, CL 492935 -->
The performance of private RSA operations (decryption and signing) is now better than Go 1.19 for <code>GOOS=amd64</code> and <code>GOOS=arm64</code>. It had regressed in Go 1.20.
The performance of private RSA operations (decryption and signing) is now better than Go 1.19 for <code>GOARCH=amd64</code> and <code>GOARCH=arm64</code>. It had regressed in Go 1.20.
</p>
<p>
Due to the addition of private fields to <a href="/pkg/crypto/rsa/#PrecomputedValues"><code>PrecomputedValues</code></a>, <a href="/pkg/crypto/rsa/#PrivateKey.Precompute"><code>PrivateKey.Precompute</code></a> must be called for optimal performance even if deserializing (for example from JSON) a previously-precomputed private key.
@@ -511,7 +521,7 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="crypto/sha256"><dt><a href="/pkg/crypto/sha256/">crypto/sha256</a></dt>
<dd>
<p><!-- https://go.dev/issue/50543, CL 408795 -->
SHA-224 and SHA-256 operations now use native instructions when available when <code>GOOS=amd64</code>, providing a performance improvement on the order of 3-4x.
SHA-224 and SHA-256 operations now use native instructions when available when <code>GOARCH=amd64</code>, providing a performance improvement on the order of 3-4x.
</p>
</dd>
</dl><!-- crypto/sha256 -->
@@ -579,7 +589,7 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="crypto/x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt>
<dd>
<p><!-- https://go.dev/issue/53573, CL 468875 -->
<a href="/pkg/crypto/x509/#RevocationList.RevokedCertificates"><code>RevocationList.RevokedCertificates</code></a> has been deprecated and replaced with the new <a href="/pkg/crypto/x509/#RevocationList.Entries"><code>RevocationList.Entries</code></a> field, which is a slice of <a href="/pkg/crypto/x509/#RevocationListEntry"><code>RevocationListEntry</code></a>. <a href="/pkg/crypto/x509/#RevocationListEntry"><code>RevocationListEntry</code></a> contains all of the fields in <a href="/pkg/crypto/x509/#pkix.RevokedCertificate"><code>pkix.RevokedCertificate</code></a>, as well as the revocation reason code.
<a href="/pkg/crypto/x509/#RevocationList.RevokedCertificates"><code>RevocationList.RevokedCertificates</code></a> has been deprecated and replaced with the new <a href="/pkg/crypto/x509/#RevocationList.RevokedCertificateEntries"><code>RevokedCertificateEntries</code></a> field, which is a slice of <a href="/pkg/crypto/x509/#RevocationListEntry"><code>RevocationListEntry</code></a>. <a href="/pkg/crypto/x509/#RevocationListEntry"><code>RevocationListEntry</code></a> contains all of the fields in <a href="/pkg/crypto/x509/pkix#RevokedCertificate"><code>pkix.RevokedCertificate</code></a>, as well as the revocation reason code.
</p>
</dd>
</dl><!-- crypto/x509 -->

View File

@@ -652,6 +652,38 @@ func bmEqual(equal func([]byte, []byte) bool) func(b *testing.B, n int) {
}
}
func BenchmarkEqualBothUnaligned(b *testing.B) {
sizes := []int{64, 4 << 10}
if !isRaceBuilder {
sizes = append(sizes, []int{4 << 20, 64 << 20}...)
}
maxSize := 2 * (sizes[len(sizes)-1] + 8)
if len(bmbuf) < maxSize {
bmbuf = make([]byte, maxSize)
}
for _, n := range sizes {
for _, off := range []int{0, 1, 4, 7} {
buf1 := bmbuf[off : off+n]
buf2Start := (len(bmbuf) / 2) + off
buf2 := bmbuf[buf2Start : buf2Start+n]
buf1[n-1] = 'x'
buf2[n-1] = 'x'
b.Run(fmt.Sprint(n, off), func(b *testing.B) {
b.SetBytes(int64(n))
for i := 0; i < b.N; i++ {
eq := Equal(buf1, buf2)
if !eq {
b.Fatal("bad equal")
}
}
})
buf1[n-1] = '\x00'
buf2[n-1] = '\x00'
}
}
}
func BenchmarkIndex(b *testing.B) {
benchBytes(b, indexSizes, func(b *testing.B, n int) {
buf := bmbuf[0:n]

View File

@@ -65,7 +65,7 @@ func (s *Slice) Col() int {
// #define A #define B(x) x
// and
// #define A #define B (x) x
// The first has definition of B has an argument, the second doesn't. Because we let
// The first definition of B has an argument, the second doesn't. Because we let
// text/scanner strip the blanks for us, this is extremely rare, hard to fix, and not worth it.
return s.pos
}

View File

@@ -4,11 +4,11 @@
// Package devirtualize implements two "devirtualization" optimization passes:
//
// - "Static" devirtualization which replaces interface method calls with
// direct concrete-type method calls where possible.
// - "Profile-guided" devirtualization which replaces indirect calls with a
// conditional direct call to the hottest concrete callee from a profile, as
// well as a fallback using the original indirect call.
// - "Static" devirtualization which replaces interface method calls with
// direct concrete-type method calls where possible.
// - "Profile-guided" devirtualization which replaces indirect calls with a
// conditional direct call to the hottest concrete callee from a profile, as
// well as a fallback using the original indirect call.
package devirtualize
import (

View File

@@ -52,7 +52,6 @@ type Node interface {
// 0 means the node is not typechecked
// 1 means the node is completely typechecked
// 2 means typechecking of the node is in progress
// 3 means the node has its type from types2, but may need transformation
Typecheck() uint8
SetTypecheck(x uint8)
NonNil() bool

View File

@@ -115,6 +115,17 @@ func VisitList(list Nodes, visit func(Node)) {
}
}
// VisitFuncAndClosures calls visit on each non-nil node in fn.Body,
// including any nested closure bodies.
func VisitFuncAndClosures(fn *Func, visit func(n Node)) {
VisitList(fn.Body, func(n Node) {
visit(n)
if n, ok := n.(*ClosureExpr); ok && n.Op() == OCLOSURE {
VisitFuncAndClosures(n.Func, visit)
}
})
}
// Any looks for a non-nil node x in the IR tree rooted at n
// for which cond(x) returns true.
// Any considers nodes in a depth-first, preorder traversal.

View File

@@ -3919,7 +3919,11 @@ func finishWrapperFunc(fn *ir.Func, target *ir.Package) {
// The body of wrapper function after inlining may reveal new ir.OMETHVALUE node,
// we don't know whether wrapper function has been generated for it or not, so
// generate one immediately here.
ir.VisitList(fn.Body, func(n ir.Node) {
//
// Further, after CL 492017, function that construct closures is allowed to be inlined,
// even though the closure itself can't be inline. So we also need to visit body of any
// closure that we see when visiting body of the wrapper function.
ir.VisitFuncAndClosures(fn, func(n ir.Node) {
if n, ok := n.(*ir.SelectorExpr); ok && n.Op() == ir.OMETHVALUE {
wrapMethodValue(n.X.Type(), n.Selection, target, true)
}

View File

@@ -836,11 +836,11 @@
//
// Key:
//
// [+ -](x * y) [+ -] z.
// _ N A S
// D U
// D B
// [+ -](x * y [+ -] z).
// _ N A S
// D U
// D B
//
// Note: multiplication commutativity handled by rule generator.
(F(MADD|NMADD|MSUB|NMSUB)D neg:(FNEGD x) y z) && neg.Uses == 1 => (F(NMADD|MADD|NMSUB|MSUB)D x y z)
(F(MADD|NMADD|MSUB|NMSUB)D neg:(FNEGD x) y z) && neg.Uses == 1 => (F(NMSUB|MSUB|NMADD|MADD)D x y z)
(F(MADD|NMADD|MSUB|NMSUB)D x y neg:(FNEGD z)) && neg.Uses == 1 => (F(MSUB|NMSUB|MADD|NMADD)D x y z)

View File

@@ -3322,7 +3322,7 @@ func rewriteValueRISCV64_OpRISCV64FMADDD(v *Value) bool {
v_0 := v.Args[0]
// match: (FMADDD neg:(FNEGD x) y z)
// cond: neg.Uses == 1
// result: (FNMADDD x y z)
// result: (FNMSUBD x y z)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
neg := v_0
@@ -3335,7 +3335,7 @@ func rewriteValueRISCV64_OpRISCV64FMADDD(v *Value) bool {
if !(neg.Uses == 1) {
continue
}
v.reset(OpRISCV64FNMADDD)
v.reset(OpRISCV64FNMSUBD)
v.AddArg3(x, y, z)
return true
}
@@ -3367,7 +3367,7 @@ func rewriteValueRISCV64_OpRISCV64FMSUBD(v *Value) bool {
v_0 := v.Args[0]
// match: (FMSUBD neg:(FNEGD x) y z)
// cond: neg.Uses == 1
// result: (FNMSUBD x y z)
// result: (FNMADDD x y z)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
neg := v_0
@@ -3380,7 +3380,7 @@ func rewriteValueRISCV64_OpRISCV64FMSUBD(v *Value) bool {
if !(neg.Uses == 1) {
continue
}
v.reset(OpRISCV64FNMSUBD)
v.reset(OpRISCV64FNMADDD)
v.AddArg3(x, y, z)
return true
}
@@ -3412,7 +3412,7 @@ func rewriteValueRISCV64_OpRISCV64FNMADDD(v *Value) bool {
v_0 := v.Args[0]
// match: (FNMADDD neg:(FNEGD x) y z)
// cond: neg.Uses == 1
// result: (FMADDD x y z)
// result: (FMSUBD x y z)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
neg := v_0
@@ -3425,7 +3425,7 @@ func rewriteValueRISCV64_OpRISCV64FNMADDD(v *Value) bool {
if !(neg.Uses == 1) {
continue
}
v.reset(OpRISCV64FMADDD)
v.reset(OpRISCV64FMSUBD)
v.AddArg3(x, y, z)
return true
}
@@ -3457,7 +3457,7 @@ func rewriteValueRISCV64_OpRISCV64FNMSUBD(v *Value) bool {
v_0 := v.Args[0]
// match: (FNMSUBD neg:(FNEGD x) y z)
// cond: neg.Uses == 1
// result: (FMSUBD x y z)
// result: (FMADDD x y z)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
neg := v_0
@@ -3470,7 +3470,7 @@ func rewriteValueRISCV64_OpRISCV64FNMSUBD(v *Value) bool {
if !(neg.Uses == 1) {
continue
}
v.reset(OpRISCV64FMSUBD)
v.reset(OpRISCV64FMADDD)
v.AddArg3(x, y, z)
return true
}

View File

@@ -3620,8 +3620,13 @@ func (s *state) minMax(n *ir.CallExpr) *ssa.Value {
// ternary emits code to evaluate cond ? x : y.
func (s *state) ternary(cond, x, y *ssa.Value) *ssa.Value {
// Note that we need a new ternaryVar each time (unlike okVar where we can
// reuse the variable) because it might have a different type every time.
ternaryVar := ssaMarker("ternary")
bThen := s.f.NewBlock(ssa.BlockPlain)
bElse := s.f.NewBlock(ssa.BlockPlain)
bEnd := s.f.NewBlock(ssa.BlockPlain)
b := s.endBlock()
b.Kind = ssa.BlockIf
@@ -3629,11 +3634,18 @@ func (s *state) ternary(cond, x, y *ssa.Value) *ssa.Value {
b.AddEdgeTo(bThen)
b.AddEdgeTo(bElse)
s.startBlock(bElse)
s.endBlock().AddEdgeTo(bThen)
s.startBlock(bThen)
return s.newValue2(ssa.OpPhi, x.Type, x, y)
s.vars[ternaryVar] = x
s.endBlock().AddEdgeTo(bEnd)
s.startBlock(bElse)
s.vars[ternaryVar] = y
s.endBlock().AddEdgeTo(bEnd)
s.startBlock(bEnd)
r := s.variable(ternaryVar, x.Type)
delete(s.vars, ternaryVar)
return r
}
// condBranch evaluates the boolean expression cond and branches to yes

View File

@@ -607,7 +607,7 @@ func tcSwitchType(n *ir.SwitchStmt) {
if !n1.Type().IsInterface() {
why := ImplementsExplain(n1.Type(), t)
if why != "" {
base.ErrorfAt(ncase.Pos(), errors.ImpossibleAssert, "impossible type switch case: %L cannot have dynamic type %v (%s)" , guard.X, n1.Type(), why)
base.ErrorfAt(ncase.Pos(), errors.ImpossibleAssert, "impossible type switch case: %L cannot have dynamic type %v (%s)", guard.X, n1.Type(), why)
}
continue
}

View File

@@ -713,12 +713,12 @@ func ImplementsExplain(t, iface *types.Type) string {
return fmt.Sprintf("%v does not implement %v (%v method is marked 'nointerface')", t, iface, missing.Sym)
} else if have != nil && have.Sym == missing.Sym {
return fmt.Sprintf("%v does not implement %v (wrong type for %v method)\n"+
"\t\thave %v%S\n\t\twant %v%S", t, iface, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
"\t\thave %v%S\n\t\twant %v%S", t, iface, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
} else if ptr != 0 {
return fmt.Sprintf("%v does not implement %v (%v method has pointer receiver)", t, iface, missing.Sym)
} else if have != nil {
return fmt.Sprintf("%v does not implement %v (missing %v method)\n"+
"\t\thave %v%S\n\t\twant %v%S", t, iface, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
"\t\thave %v%S\n\t\twant %v%S", t, iface, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
}
return fmt.Sprintf("%v does not implement %v (missing %v method)", t, iface, missing.Sym)
}

View File

@@ -578,6 +578,11 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
x.mode = value
}
// Use the final type computed above for all arguments.
for _, a := range args {
check.updateExprType(a.expr, x.typ, true)
}
if check.recordTypes() && x.mode != constant_ {
types := make([]Type, nargs)
for i := range types {

View File

@@ -11,6 +11,7 @@ import (
"errors"
"fmt"
"go/constant"
"internal/goversion"
. "internal/types/errors"
)
@@ -231,19 +232,19 @@ func NewChecker(conf *Config, pkg *Package, info *Info) *Checker {
info = new(Info)
}
version, err := parseGoVersion(conf.GoVersion)
if err != nil {
panic(fmt.Sprintf("invalid Go version %q (%v)", conf.GoVersion, err))
}
// Note: clients may call NewChecker with the Unsafe package, which is
// globally shared and must not be mutated. Therefore NewChecker must not
// mutate *pkg.
//
// (previously, pkg.goVersion was mutated here: go.dev/issue/61212)
return &Checker{
conf: conf,
ctxt: conf.Context,
pkg: pkg,
Info: info,
version: version,
objMap: make(map[Object]*declInfo),
impMap: make(map[importKey]*Package),
conf: conf,
ctxt: conf.Context,
pkg: pkg,
Info: info,
objMap: make(map[Object]*declInfo),
impMap: make(map[importKey]*Package),
}
}
@@ -333,6 +334,20 @@ func (check *Checker) Files(files []*syntax.File) error { return check.checkFile
var errBadCgo = errors.New("cannot use FakeImportC and go115UsesCgo together")
func (check *Checker) checkFiles(files []*syntax.File) (err error) {
if check.pkg == Unsafe {
// Defensive handling for Unsafe, which cannot be type checked, and must
// not be mutated. See https://go.dev/issue/61212 for an example of where
// Unsafe is passed to NewChecker.
return nil
}
check.version, err = parseGoVersion(check.conf.GoVersion)
if err != nil {
return err
}
if check.version.after(version{1, goversion.Version}) {
return fmt.Errorf("package requires newer Go version %v", check.version)
}
if check.conf.FakeImportC && check.conf.go115UsesCgo {
return errBadCgo
}
@@ -377,6 +392,7 @@ func (check *Checker) checkFiles(files []*syntax.File) (err error) {
check.monomorph()
}
check.pkg.goVersion = check.conf.GoVersion
check.pkg.complete = true
// no longer needed - release memory

View File

@@ -184,6 +184,7 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
if !valid {
check.errorf(e.Pos(), NonSliceableOperand, invalidOp+"cannot index %s", x)
check.use(e.Index)
x.mode = invalid
return false
}

View File

@@ -497,14 +497,14 @@ func TestIssue43088(t *testing.T) {
// _ T2
// }
// }
n1 := NewTypeName(syntax.Pos{}, nil, "T1", nil)
n1 := NewTypeName(nopos, nil, "T1", nil)
T1 := NewNamed(n1, nil, nil)
n2 := NewTypeName(syntax.Pos{}, nil, "T2", nil)
n2 := NewTypeName(nopos, nil, "T2", nil)
T2 := NewNamed(n2, nil, nil)
s1 := NewStruct([]*Var{NewField(syntax.Pos{}, nil, "_", T2, false)}, nil)
s1 := NewStruct([]*Var{NewField(nopos, nil, "_", T2, false)}, nil)
T1.SetUnderlying(s1)
s2 := NewStruct([]*Var{NewField(syntax.Pos{}, nil, "_", T2, false)}, nil)
s3 := NewStruct([]*Var{NewField(syntax.Pos{}, nil, "_", s2, false)}, nil)
s2 := NewStruct([]*Var{NewField(nopos, nil, "_", T2, false)}, nil)
s3 := NewStruct([]*Var{NewField(nopos, nil, "_", s2, false)}, nil)
T2.SetUnderlying(s3)
// These calls must terminate (no endless recursion).
@@ -535,38 +535,69 @@ func TestIssue44515(t *testing.T) {
}
func TestIssue43124(t *testing.T) {
testenv.MustHaveGoBuild(t)
// TODO(rFindley) move this to testdata by enhancing support for importing.
testenv.MustHaveGoBuild(t) // The go command is needed for the importer to determine the locations of stdlib .a files.
// All involved packages have the same name (template). Error messages should
// disambiguate between text/template and html/template by printing the full
// path.
const (
asrc = `package a; import "text/template"; func F(template.Template) {}; func G(int) {}`
bsrc = `package b; import ("a"; "html/template"); func _() { a.F(template.Template{}) }`
csrc = `package c; import ("a"; "html/template"); func _() { a.G(template.Template{}) }`
bsrc = `
package b
import (
"a"
"html/template"
)
func _() {
// Packages should be fully qualified when there is ambiguity within the
// error string itself.
a.F(template /* ERRORx "cannot use.*html/template.* as .*text/template" */ .Template{})
}
`
csrc = `
package c
import (
"a"
"fmt"
"html/template"
)
// go.dev/issue/46905: make sure template is not the first package qualified.
var _ fmt.Stringer = 1 // ERRORx "cannot use 1.*as fmt\\.Stringer"
// Packages should be fully qualified when there is ambiguity in reachable
// packages. In this case both a (and for that matter html/template) import
// text/template.
func _() { a.G(template /* ERRORx "cannot use .*html/template.*Template" */ .Template{}) }
`
tsrc = `
package template
import "text/template"
type T int
// Verify that the current package name also causes disambiguation.
var _ T = template /* ERRORx "cannot use.*text/template.* as T value" */.Template{}
`
)
a := mustTypecheck(asrc, nil, nil)
conf := Config{Importer: importHelper{pkg: a, fallback: defaultImporter()}}
imp := importHelper{pkg: a, fallback: defaultImporter()}
// Packages should be fully qualified when there is ambiguity within the
// error string itself.
_, err := typecheck(bsrc, &conf, nil)
if err == nil {
t.Fatal("package b had no errors")
}
if !strings.Contains(err.Error(), "text/template") || !strings.Contains(err.Error(), "html/template") {
t.Errorf("type checking error for b does not disambiguate package template: %q", err)
withImporter := func(cfg *Config) {
cfg.Importer = imp
}
// ...and also when there is any ambiguity in reachable packages.
_, err = typecheck(csrc, &conf, nil)
if err == nil {
t.Fatal("package c had no errors")
}
if !strings.Contains(err.Error(), "html/template") {
t.Errorf("type checking error for c does not disambiguate package template: %q", err)
}
testFiles(t, []string{"b.go"}, [][]byte{[]byte(bsrc)}, 0, false, withImporter)
testFiles(t, []string{"c.go"}, [][]byte{[]byte(csrc)}, 0, false, withImporter)
testFiles(t, []string{"t.go"}, [][]byte{[]byte(tsrc)}, 0, false, withImporter)
}
func TestIssue50646(t *testing.T) {

View File

@@ -10,13 +10,14 @@ import (
// A Package describes a Go package.
type Package struct {
path string
name string
scope *Scope
imports []*Package
complete bool
fake bool // scope lookup errors are silently dropped if package is fake (internal use only)
cgo bool // uses of this package will be rewritten into uses of declarations from _cgo_gotypes.go
path string
name string
scope *Scope
imports []*Package
complete bool
fake bool // scope lookup errors are silently dropped if package is fake (internal use only)
cgo bool // uses of this package will be rewritten into uses of declarations from _cgo_gotypes.go
goVersion string // minimum Go version required for package (by Config.GoVersion, typically from go.mod)
}
// NewPackage returns a new Package for the given package path and name.
@@ -35,6 +36,12 @@ func (pkg *Package) Name() string { return pkg.name }
// SetName sets the package name.
func (pkg *Package) SetName(name string) { pkg.name = name }
// GoVersion returns the minimum Go version required by this package.
// If the minimum version is unknown, GoVersion returns the empty string.
// Individual source files may specify a different minimum Go version,
// as reported in the [go/ast.File.GoVersion] field.
func (pkg *Package) GoVersion() string { return pkg.goVersion }
// Scope returns the (complete or incomplete) package scope
// holding the objects declared at package level (TypeNames,
// Consts, Vars, and Funcs).

View File

@@ -47,7 +47,7 @@ func TestSizeof(t *testing.T) {
// Misc
{Scope{}, 60, 104},
{Package{}, 36, 72},
{Package{}, 44, 88},
{_TypeSet{}, 28, 56},
}

View File

@@ -124,6 +124,20 @@ const (
exact
)
func (m unifyMode) String() string {
switch m {
case 0:
return "inexact"
case assign:
return "assign"
case exact:
return "exact"
case assign | exact:
return "assign, exact"
}
return fmt.Sprintf("mode %d", m)
}
// unify attempts to unify x and y and reports whether it succeeded.
// As a side-effect, types may be inferred for type parameters.
// The mode parameter controls how types are compared.
@@ -256,6 +270,15 @@ func (u *unifier) inferred(tparams []*TypeParam) []Type {
return list
}
// asInterface returns the underlying type of x as an interface if
// it is a non-type parameter interface. Otherwise it returns nil.
func asInterface(x Type) (i *Interface) {
if _, ok := x.(*TypeParam); !ok {
i, _ = under(x).(*Interface)
}
return i
}
// nify implements the core unification algorithm which is an
// adapted version of Checker.identical. For changes to that
// code the corresponding changes should be made here.
@@ -263,7 +286,7 @@ func (u *unifier) inferred(tparams []*TypeParam) []Type {
func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) {
u.depth++
if traceInference {
u.tracef("%s ≡ %s (mode %d)", x, y, mode)
u.tracef("%s ≡ %s\t// %s", x, y, mode)
}
defer func() {
if traceInference && !result {
@@ -294,7 +317,7 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) {
// - type parameter recorded with u, make sure one is in x
if _, ok := x.(*Named); ok || u.asTypeParam(y) != nil {
if traceInference {
u.tracef("%s ≡ %s (swap)", y, x)
u.tracef("%s ≡ %s\t// swap", y, x)
}
x, y = y, x
}
@@ -350,11 +373,49 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) {
if x := u.at(px); x != nil {
// x has an inferred type which must match y
if u.nify(x, y, mode, p) {
// If we have a match, possibly through underlying types,
// and y is a defined type, make sure we record that type
// We have a match, possibly through underlying types.
xi := asInterface(x)
yi := asInterface(y)
_, xn := x.(*Named)
_, yn := y.(*Named)
// If we have two interfaces, what to do depends on
// whether they are named and their method sets.
if xi != nil && yi != nil {
// Both types are interfaces.
// If both types are defined types, they must be identical
// because unification doesn't know which type has the "right" name.
if xn && yn {
return Identical(x, y)
}
// In all other cases, the method sets must match.
// The types unified so we know that corresponding methods
// match and we can simply compare the number of methods.
// TODO(gri) We may be able to relax this rule and select
// the more general interface. But if one of them is a defined
// type, it's not clear how to choose and whether we introduce
// an order dependency or not. Requiring the same method set
// is conservative.
if len(xi.typeSet().methods) != len(yi.typeSet().methods) {
return false
}
} else if xi != nil || yi != nil {
// One but not both of them are interfaces.
// In this case, either x or y could be viable matches for the corresponding
// type parameter, which means choosing either introduces an order dependence.
// Therefore, we must fail unification (go.dev/issue/60933).
return false
}
// If y is a defined type, make sure we record that type
// for type parameter x, which may have until now only
// recorded an underlying type (go.dev/issue/43056).
if _, ok := y.(*Named); ok {
// Either both types are interfaces, or neither type is.
// If both are interfaces, they have the same methods.
//
// Note: Changing the recorded type for a type parameter to
// a defined type is only ok when unification is inexact.
// But in exact unification, if we have a match, x and y must
// be identical, so changing the recorded type for x is a no-op.
if yn {
u.set(px, y)
}
return true
@@ -384,14 +445,8 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) {
if enableInterfaceInference && mode&exact == 0 {
// One or both interfaces may be defined types.
// Look under the name, but not under type parameters (go.dev/issue/60564).
var xi *Interface
if _, ok := x.(*TypeParam); !ok {
xi, _ = under(x).(*Interface)
}
var yi *Interface
if _, ok := y.(*TypeParam); !ok {
yi, _ = under(y).(*Interface)
}
xi := asInterface(x)
yi := asInterface(y)
// If we have two interfaces, check the type terms for equivalence,
// and unify common methods if possible.
if xi != nil && yi != nil {
@@ -492,7 +547,7 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) {
// TODO(gri) Factor out type parameter handling from the switch.
if isTypeParam(y) {
if traceInference {
u.tracef("%s ≡ %s (swap)", y, x)
u.tracef("%s ≡ %s\t// swap", y, x)
}
x, y = y, x
}

View File

@@ -6,7 +6,6 @@ package types2
import (
"cmd/compile/internal/syntax"
"errors"
"fmt"
"strings"
)
@@ -44,23 +43,24 @@ var (
go1_21 = version{1, 21}
)
var errVersionSyntax = errors.New("invalid Go version syntax")
// parseGoVersion parses a Go version string (such as "go1.12")
// and returns the version, or an error. If s is the empty
// string, the version is 0.0.
func parseGoVersion(s string) (v version, err error) {
bad := func() (version, error) {
return version{}, fmt.Errorf("invalid Go version syntax %q", s)
}
if s == "" {
return
}
if !strings.HasPrefix(s, "go") {
return version{}, errVersionSyntax
return bad()
}
s = s[len("go"):]
i := 0
for ; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
if i >= 10 || i == 0 && s[i] == '0' {
return version{}, errVersionSyntax
return bad()
}
v.major = 10*v.major + int(s[i]) - '0'
}
@@ -68,7 +68,7 @@ func parseGoVersion(s string) (v version, err error) {
return
}
if i == 0 || s[i] != '.' {
return version{}, errVersionSyntax
return bad()
}
s = s[i+1:]
if s == "0" {
@@ -81,14 +81,15 @@ func parseGoVersion(s string) (v version, err error) {
i = 0
for ; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
if i >= 10 || i == 0 && s[i] == '0' {
return version{}, errVersionSyntax
return bad()
}
v.minor = 10*v.minor + int(s[i]) - '0'
}
if i > 0 && i == len(s) {
return
}
return version{}, errVersionSyntax
// Accept any suffix after the minor number.
// We are only looking for the language version (major.minor)
// but want to accept any valid Go version, like go1.21.0
// and go1.21rc2.
return
}
// langCompat reports an error if the representation of a numeric

View File

@@ -0,0 +1,24 @@
// 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 types2
import "testing"
var parseGoVersionTests = []struct {
in string
out version
}{
{"go1.21", version{1, 21}},
{"go1.21.0", version{1, 21}},
{"go1.21rc2", version{1, 21}},
}
func TestParseGoVersion(t *testing.T) {
for _, tt := range parseGoVersionTests {
if out, err := parseGoVersion(tt.in); out != tt.out || err != nil {
t.Errorf("parseGoVersion(%q) = %v, %v, want %v, nil", tt.in, out, err, tt.out)
}
}
}

View File

@@ -755,7 +755,7 @@ func (o *orderState) stmt(n ir.Node) {
o.out = append(o.out, n)
o.popTemp(t)
case ir.OMAX, ir.OMIN, ir.OPRINT, ir.OPRINTN, ir.ORECOVERFP:
case ir.OPRINT, ir.OPRINTN, ir.ORECOVERFP:
n := n.(*ir.CallExpr)
t := o.markTemp()
o.call(n)
@@ -1247,6 +1247,8 @@ func (o *orderState) expr1(n, lhs ir.Node) ir.Node {
ir.OMAKEMAP,
ir.OMAKESLICE,
ir.OMAKESLICECOPY,
ir.OMAX,
ir.OMIN,
ir.ONEW,
ir.OREAL,
ir.ORECOVERFP,

View File

@@ -337,10 +337,14 @@ func mayCall(n ir.Node) bool {
n := n.(*ir.ConvExpr)
return ssagen.Arch.SoftFloat && (isSoftFloat(n.Type()) || isSoftFloat(n.X.Type()))
case ir.OMIN, ir.OMAX:
// string or float requires runtime call, see (*ssagen.state).minmax method.
return n.Type().IsString() || n.Type().IsFloat()
case ir.OLITERAL, ir.ONIL, ir.ONAME, ir.OLINKSYMOFFSET, ir.OMETHEXPR,
ir.OAND, ir.OANDNOT, ir.OLSH, ir.OOR, ir.ORSH, ir.OXOR, ir.OCOMPLEX, ir.OEFACE,
ir.OADDR, ir.OBITNOT, ir.ONOT, ir.OPLUS,
ir.OCAP, ir.OIMAG, ir.OLEN, ir.OREAL, ir.OMIN, ir.OMAX,
ir.OCAP, ir.OIMAG, ir.OLEN, ir.OREAL,
ir.OCONVNOP, ir.ODOT,
ir.OCFUNC, ir.OIDATA, ir.OITAB, ir.OSPTR,
ir.OBYTES2STRTMP, ir.OGETG, ir.OGETCALLERPC, ir.OGETCALLERSP, ir.OSLICEHEADER, ir.OSTRINGHEADER:

View File

@@ -95,7 +95,7 @@ const (
func main() {
objabi.AddVersionFlag()
flag.Usage = usage
flag.Parse()
objabi.Flagparse(usage)
// Usage information when no arguments.
if flag.NFlag() == 0 && flag.NArg() == 0 {

View File

@@ -631,7 +631,6 @@ var gentab = []struct {
}{
{"go/build", "zcgo.go", mkzcgo},
{"cmd/go/internal/cfg", "zdefaultcc.go", mkzdefaultcc},
{"internal/platform", "zosarch.go", mkzosarch},
{"runtime/internal/sys", "zversion.go", mkzversion},
{"time/tzdata", "zzipdata.go", mktzdata},
}
@@ -1899,11 +1898,12 @@ func cmdversion() {
// cmdlist lists all supported platforms.
func cmdlist() {
jsonFlag := flag.Bool("json", false, "produce JSON output")
brokenFlag := flag.Bool("broken", false, "include broken ports")
xflagparse(0)
var plats []string
for p := range cgoEnabled {
if broken[p] {
if broken[p] && !*brokenFlag {
continue
}
plats = append(plats, p)
@@ -1922,6 +1922,7 @@ func cmdlist() {
GOARCH string
CgoSupported bool
FirstClass bool
Broken bool `json:",omitempty"`
}
var results []jsonResult
for _, p := range plats {
@@ -1930,7 +1931,9 @@ func cmdlist() {
GOOS: fields[0],
GOARCH: fields[1],
CgoSupported: cgoEnabled[p],
FirstClass: firstClass[p]})
FirstClass: firstClass[p],
Broken: broken[p],
})
}
out, err := json.MarshalIndent(results, "", "\t")
if err != nil {

View File

@@ -6,7 +6,6 @@ package main
import (
"fmt"
"sort"
"strings"
)
@@ -80,25 +79,3 @@ func mkobjabi(file string) {
writefile(buf.String(), file, writeSkipSame)
}
// mkzosarch writes zosarch.go for internal/platform.
func mkzosarch(dir, file string) {
// sort for deterministic file contents.
var list []string
for plat := range cgoEnabled {
list = append(list, plat)
}
sort.Strings(list)
var buf strings.Builder
writeHeader(&buf)
fmt.Fprintf(&buf, "package platform\n")
fmt.Fprintln(&buf)
fmt.Fprintf(&buf, "var osArchSupportsCgo = map[string]bool{\n")
for _, plat := range list {
fmt.Fprintf(&buf, "\t\t%s: %v,\n", quote(plat), cgoEnabled[plat])
}
fmt.Fprintf(&buf, "}\n")
writefile(buf.String(), file, writeSkipSame)
}

View File

@@ -70,6 +70,11 @@ var bootstrapDirs = []string{
"internal/goexperiment",
"internal/goroot",
"internal/goversion",
// internal/lazyregexp is provided by Go 1.17, which permits it to
// be imported by other packages in this list, but is not provided
// by the Go 1.17 version of gccgo. It's on this list only to
// support gccgo, and can be removed if we require gccgo 14 or later.
"internal/lazyregexp",
"internal/pkgbits",
"internal/platform",
"internal/profile",
@@ -126,7 +131,6 @@ func bootstrapBuildTools() {
mkbuildcfg(pathf("%s/src/internal/buildcfg/zbootstrap.go", goroot))
mkobjabi(pathf("%s/src/cmd/internal/objabi/zbootstrap.go", goroot))
mkzosarch("", pathf("%s/src/internal/platform/zosarch.go", goroot))
// Use $GOROOT/pkg/bootstrap as the bootstrap workspace root.
// We use a subdirectory of $GOROOT/pkg because that's the

16
src/cmd/dist/main.go vendored
View File

@@ -16,14 +16,14 @@ func usage() {
xprintf(`usage: go tool dist [command]
Commands are:
banner print installation banner
bootstrap rebuild everything
clean deletes all built files
env [-p] print environment (-p: include $PATH)
install [dir] install individual directory
list [-json] list all supported platforms
test [-h] run Go test(s)
version print Go version
banner print installation banner
bootstrap rebuild everything
clean deletes all built files
env [-p] print environment (-p: include $PATH)
install [dir] install individual directory
list [-json] [-broken] list all supported platforms
test [-h] run Go test(s)
version print Go version
All commands take -v flags to emit extra information.
`)

View File

@@ -127,7 +127,6 @@ func main() {
// Generated during cmd/dist. See ../dist/build.go:/gentab.
"src/cmd/go/internal/cfg/zdefaultcc.go",
"src/go/build/zcgo.go",
"src/internal/platform/zosarch.go",
"src/runtime/internal/sys/zversion.go",
"src/time/tzdata/zzipdata.go",

View File

@@ -11,20 +11,31 @@ import (
"path/filepath"
"cmd/go/internal/cfg"
"cmd/go/internal/par"
)
// Tool returns the path to the named tool (for example, "vet").
// If the tool cannot be found, Tool exits the process.
func Tool(toolName string) string {
toolPath := filepath.Join(build.ToolDir, toolName) + cfg.ToolExeSuffix()
if len(cfg.BuildToolexec) > 0 {
return toolPath
}
// Give a nice message if there is no tool with that name.
if _, err := os.Stat(toolPath); err != nil {
toolPath, err := ToolPath(toolName)
if err != nil && len(cfg.BuildToolexec) == 0 {
// Give a nice message if there is no tool with that name.
fmt.Fprintf(os.Stderr, "go: no such tool %q\n", toolName)
SetExitStatus(2)
Exit()
}
return toolPath
}
// Tool returns the path at which we expect to find the named tool
// (for example, "vet"), and the error (if any) from statting that path.
func ToolPath(toolName string) (string, error) {
toolPath := filepath.Join(build.ToolDir, toolName) + cfg.ToolExeSuffix()
err := toolStatCache.Do(toolPath, func() error {
_, err := os.Stat(toolPath)
return err
})
return toolPath, err
}
var toolStatCache par.Cache[string, error]

View File

@@ -111,7 +111,6 @@ func IsPrerelease(x string) bool {
//
// Prev("1.2") = "1.1"
// Prev("1.3rc4") = "1.2"
//
func Prev(x string) string {
v := parse(x)
if cmpInt(v.minor, "1") <= 0 {

View File

@@ -660,6 +660,7 @@ var defaultVetFlags = []string{
"-printf",
// "-rangeloops",
// "-shift",
"-slog",
"-stringintconv",
// "-structtags",
// "-tests",

View File

@@ -7,8 +7,11 @@ package tool
import (
"context"
"encoding/json"
"flag"
"fmt"
"go/build"
"internal/platform"
"os"
"os/exec"
"os/signal"
@@ -68,10 +71,25 @@ func runTool(ctx context.Context, cmd *base.Command, args []string) {
return
}
}
toolPath := base.Tool(toolName)
if toolPath == "" {
return
toolPath, err := base.ToolPath(toolName)
if err != nil {
if toolName == "dist" && len(args) > 1 && args[1] == "list" {
// cmd/distpack removes the 'dist' tool from the toolchain to save space,
// since it is normally only used for building the toolchain in the first
// place. However, 'go tool dist list' is useful for listing all supported
// platforms.
//
// If the dist tool does not exist, impersonate this command.
if impersonateDistList(args[2:]) {
return
}
}
// Emit the usual error for the missing tool.
_ = base.Tool(toolName)
}
if toolN {
cmd := toolPath
if len(args) > 1 {
@@ -88,7 +106,7 @@ func runTool(ctx context.Context, cmd *base.Command, args []string) {
Stdout: os.Stdout,
Stderr: os.Stderr,
}
err := toolCmd.Start()
err = toolCmd.Start()
if err == nil {
c := make(chan os.Signal, 100)
signal.Notify(c)
@@ -145,3 +163,62 @@ func listTools() {
fmt.Println(name)
}
}
func impersonateDistList(args []string) (handled bool) {
fs := flag.NewFlagSet("go tool dist list", flag.ContinueOnError)
jsonFlag := fs.Bool("json", false, "produce JSON output")
brokenFlag := fs.Bool("broken", false, "include broken ports")
// The usage for 'go tool dist' claims that
// “All commands take -v flags to emit extra information”,
// but list -v appears not to have any effect.
_ = fs.Bool("v", false, "emit extra information")
if err := fs.Parse(args); err != nil || len(fs.Args()) > 0 {
// Unrecognized flag or argument.
// Force fallback to the real 'go tool dist'.
return false
}
if !*jsonFlag {
for _, p := range platform.List {
if !*brokenFlag && platform.Broken(p.GOOS, p.GOARCH) {
continue
}
fmt.Println(p)
}
return true
}
type jsonResult struct {
GOOS string
GOARCH string
CgoSupported bool
FirstClass bool
Broken bool `json:",omitempty"`
}
var results []jsonResult
for _, p := range platform.List {
broken := platform.Broken(p.GOOS, p.GOARCH)
if broken && !*brokenFlag {
continue
}
if *jsonFlag {
results = append(results, jsonResult{
GOOS: p.GOOS,
GOARCH: p.GOARCH,
CgoSupported: platform.CgoSupported(p.GOOS, p.GOARCH),
FirstClass: platform.FirstClass(p.GOOS, p.GOARCH),
Broken: broken,
})
}
}
out, err := json.MarshalIndent(results, "", "\t")
if err != nil {
return false
}
os.Stdout.Write(out)
return true
}

View File

@@ -1115,6 +1115,7 @@ type vetConfig struct {
PackageVetx map[string]string // map package path to vetx data from earlier vet run
VetxOnly bool // only compute vetx data; don't report detected problems
VetxOutput string // write vetx data to this output file
GoVersion string // Go version for package
SucceedOnTypecheckFailure bool // awful hack; see #18395 and below
}
@@ -1149,6 +1150,13 @@ func buildVetConfig(a *Action, srcfiles []string) {
PackageFile: make(map[string]string),
Standard: make(map[string]bool),
}
if a.Package.Module != nil {
v := a.Package.Module.GoVersion
if v == "" {
v = gover.DefaultGoModVersion
}
vcfg.GoVersion = "go" + v
}
a.vetCfg = vcfg
for i, raw := range a.Package.Internal.RawImports {
final := a.Package.Imports[i]
@@ -3886,7 +3894,7 @@ func useResponseFile(path string, argLen int) bool {
// TODO: Note that other toolchains like CC are missing here for now.
prog := strings.TrimSuffix(filepath.Base(path), ".exe")
switch prog {
case "compile", "link", "cgo", "asm":
case "compile", "link", "cgo", "asm", "cover":
default:
return false
}

View File

@@ -85,19 +85,7 @@ func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg, embedcfg
if p.Module != nil {
v := p.Module.GoVersion
if v == "" {
// We started adding a 'go' directive to the go.mod file unconditionally
// as of Go 1.12, so any module that still lacks such a directive must
// either have been authored before then, or have a hand-edited go.mod
// file that hasn't been updated by cmd/go since that edit.
//
// Unfortunately, through at least Go 1.16 we didn't add versions to
// vendor/modules.txt. So this could also be a vendored 1.16 dependency.
//
// Fortunately, there were no breaking changes to the language between Go
// 1.11 and 1.16, so if we assume Go 1.16 semantics we will not introduce
// any spurious errors — we will only mask errors, and not particularly
// important ones at that.
v = "1.16"
v = gover.DefaultGoModVersion
}
if allowedVersion(v) {
defaultGcFlags = append(defaultGcFlags, "-lang=go"+gover.Lang(v))

View File

@@ -300,10 +300,10 @@ func maybeStartTrace(pctx context.Context) context.Context {
//
// We have to handle the -C flag this way for two reasons:
//
// 1. Toolchain selection needs to be in the right directory to look for go.mod and go.work.
// 1. Toolchain selection needs to be in the right directory to look for go.mod and go.work.
//
// 2. A toolchain switch later on reinvokes the new go command with the same arguments.
// The parent toolchain has already done the chdir; the child must not try to do it again.
// 2. A toolchain switch later on reinvokes the new go command with the same arguments.
// The parent toolchain has already done the chdir; the child must not try to do it again.
func handleChdirFlag() {
_, used := lookupCmd(os.Args[1:])
used++ // because of [1:]

View File

@@ -3,7 +3,7 @@
[short] skip 'compiles and links executables'
# use default.pgo for a single main package
go build -a -x -pgo=auto -o a1.exe ./a/a1
go build -n -pgo=auto -o a1.exe ./a/a1
stderr 'compile.*-pgoprofile=.*default\.pgo.*a1.go'
# check that pgo applied to dependencies
@@ -12,25 +12,22 @@ stderr 'compile.*-p test/dep.*-pgoprofile=.*default\.pgo'
# check that pgo appears in build info
# N.B. we can't start the stdout check with -pgo because the script assumes that
# if the first arg starts with - it is a grep flag.
go version -m a1.exe
stdout 'build\s+-pgo=.*default\.pgo'
stderr 'build\\t-pgo=.*default\.pgo'
# use default.pgo for ... with a single main package
go build -a -x -pgo=auto ./a/...
go build -n -pgo=auto ./a/...
stderr 'compile.*-pgoprofile=.*default\.pgo.*a1.go'
# check that pgo appears in build info
go version -m a1$GOEXE
stdout 'build\s+-pgo=.*default\.pgo'
stderr 'build\\t-pgo=.*default\.pgo'
# build succeeds without PGO when default.pgo file is absent
go build -a -x -pgo=auto -o nopgo.exe ./nopgo
go build -n -pgo=auto -o nopgo.exe ./nopgo
stderr 'compile.*nopgo.go'
! stderr 'compile.*-pgoprofile'
# check that pgo doesn't appear in build info
go version -m nopgo.exe
! stdout 'build\s+-pgo='
! stderr 'build\\t-pgo='
# other build-related commands
go install -a -n -pgo=auto ./a/a1
@@ -52,30 +49,27 @@ go list -deps -pgo=auto ./a/a1
# -pgo=auto is the default. Commands without explicit -pgo=auto
# should work as -pgo=auto.
go build -a -x -o a1.exe ./a/a1
go build -a -n -o a1.exe ./a/a1
stderr 'compile.*-pgoprofile=.*default\.pgo.*a1.go'
stderr 'compile.*-p test/dep.*-pgoprofile=.*default\.pgo'
# check that pgo appears in build info
go version -m a1.exe
stdout 'build\s+-pgo=.*default\.pgo'
stderr 'build\\t-pgo=.*default\.pgo'
go build -a -x -o nopgo.exe ./nopgo
go build -a -n -o nopgo.exe ./nopgo
stderr 'compile.*nopgo.go'
! stderr 'compile.*-pgoprofile'
# check that pgo doesn't appear in build info
go version -m nopgo.exe
! stdout 'build\s+-pgo='
! stderr 'build\\t-pgo='
# -pgo=off should turn off PGO.
go build -a -x -pgo=off -o a1.exe ./a/a1
go build -a -n -pgo=off -o a1.exe ./a/a1
stderr 'compile.*a1.go'
! stderr 'compile.*-pgoprofile'
# check that pgo doesn't appear in build info
go version -m a1.exe
! stdout 'build\s+-pgo='
! stderr 'build\\t-pgo='
-- go.mod --
module test

View File

@@ -1,9 +1,6 @@
# Test go build -pgo=auto flag with multiple main packages.
[short] skip 'compiles and links executables'
env GOBIN=$WORK/bin
go install -a -x -pgo=auto ./a ./b ./nopgo
go install -a -n -pgo=auto ./a ./b ./nopgo
# a/default.pgo applies to package a and (transitive)
# dependencies.
@@ -36,16 +33,9 @@ stderr -count=3 'compile.*dep3(/|\\\\)dep3.go'
stderr -count=2 'compile.*-pgoprofile=.*dep3(/|\\\\)dep3\.go'
# check that pgo appears or not in build info as expected
# N.B. we can't start the stdout check with -pgo because the script assumes that
# if the first arg starts with - it is a grep flag.
go version -m $GOBIN/a$GOEXE
stdout 'build\s+-pgo=.*a'${/}'default\.pgo'
go version -m $GOBIN/b$GOEXE
stdout 'build\s+-pgo=.*b'${/}'default\.pgo'
go version -m $GOBIN/nopgo$GOEXE
! stdout 'build\s+-pgo='
stderr 'path\\ttest/a\\n.*build\\t-pgo=.*a(/|\\\\)default\.pgo'
stderr 'path\\ttest/b\\n.*build\\t-pgo=.*b(/|\\\\)default\.pgo'
! stderr 'path\\ttest/nopgo\\n.*build\\t-pgo='
# go test works the same way
go test -a -n -pgo=auto ./a ./b ./nopgo

View File

@@ -1,6 +1,6 @@
[compiler:gccgo] skip # gccgo assumes cross-compilation is always possible
env GOOS=windwos
env GOOS=windwos # intentional misspelling of windows
! go build -n exclude
stderr 'unsupported GOOS/GOARCH pair'
stderr 'unsupported GOOS/GOARCH pair'

View File

@@ -0,0 +1,57 @@
# Regression test for #60939: when 'go tool dist' is missing,
# 'go tool dist list' should inject its output.
# Set GOROOT to a directory that definitely does not include
# a compiled 'dist' tool. 'go tool dist list' should still
# work, because 'cmd/go' itself can impersonate this command.
mkdir $WORK/goroot/bin
mkdir $WORK/goroot/pkg/tool/${GOOS}_${GOARCH}
env GOROOT=$WORK/goroot
! go tool -n dist
stderr 'go: no such tool "dist"'
go tool dist list
stdout linux/amd64
cp stdout tool.txt
go tool dist list -v
stdout linux/amd64
cp stdout tool-v.txt
go tool dist list -broken
stdout $GOOS/$GOARCH
cp stdout tool-broken.txt
go tool dist list -json
stdout '"GOOS": "linux",\n\s*"GOARCH": "amd64",\n'
cp stdout tool-json.txt
go tool dist list -json -broken
stdout '"GOOS": "'$GOOS'",\n\s*"GOARCH": "'$GOARCH'",\n'
cp stdout tool-json-broken.txt
[short] stop
# Check against the real cmd/dist as the source of truth.
env GOROOT=$TESTGO_GOROOT
go build -o dist.exe cmd/dist
exec ./dist.exe list
cmp stdout tool.txt
exec ./dist.exe list -v
cmp stdout tool-v.txt
exec ./dist.exe list -broken
cmp stdout tool-broken.txt
exec ./dist.exe list -json
cmp stdout tool-json.txt
exec ./dist.exe list -json -broken
cmp stdout tool-json-broken.txt

View File

@@ -3,17 +3,15 @@ env GO111MODULE=off
[!compiler:gc] skip 'using -gcflags and -ldflags'
[short] skip
env GOCACHE=$WORK/gocache # Looking for compile commands, so need a clean cache.
# -gcflags=-e applies to named packages, not dependencies
go build -n -v -gcflags=-e z1 z2
go build -a -n -v -gcflags=-e z1 z2
stderr 'compile.* -p z1.* -e '
stderr 'compile.* -p z2.* -e '
stderr 'compile.* -p y'
! stderr 'compile.* -p [^z].* -e '
# -gcflags can specify package=flags, and can be repeated; last match wins
go build -n -v -gcflags=-e -gcflags=z1=-N z1 z2
go build -a -n -v -gcflags=-e -gcflags=z1=-N z1 z2
stderr 'compile.* -p z1.* -N '
! stderr 'compile.* -p z1.* -e '
! stderr 'compile.* -p z2.* -N '
@@ -23,11 +21,11 @@ stderr 'compile.* -p y'
! stderr 'compile.* -p [^z].* -N '
# -gcflags can have arbitrary spaces around the flags
go build -n -v -gcflags=' z1 = -e ' z1
go build -a -n -v -gcflags=' z1 = -e ' z1
stderr 'compile.* -p z1.* -e '
# -gcflags='all=-e' should apply to all packages, even with go test
go test -c -n -gcflags='all=-e' z1
go test -a -c -n -gcflags='all=-e' z1
stderr 'compile.* -p z3.* -e '
# this particular -gcflags argument made the compiler crash
@@ -39,31 +37,31 @@ stderr 'PhaseOptions usage'
stderr 'invalid value'
# -ldflags for implicit test package applies to test binary
go test -c -n -gcflags=-N -ldflags=-X=x.y=z z1
go test -a -c -n -gcflags=-N -ldflags=-X=x.y=z z1
stderr 'compile.* -N .*z_test.go'
stderr 'link.* -X=x.y=z'
# -ldflags for explicit test package applies to test binary
go test -c -n -gcflags=z1=-N -ldflags=z1=-X=x.y=z z1
go test -a -c -n -gcflags=z1=-N -ldflags=z1=-X=x.y=z z1
stderr 'compile.* -N .*z_test.go'
stderr 'link.* -X=x.y=z'
# -ldflags applies to link of command
go build -n -ldflags=-X=math.pi=3 my/cmd/prog
go build -a -n -ldflags=-X=math.pi=3 my/cmd/prog
stderr 'link.* -X=math.pi=3'
# -ldflags applies to link of command even with strange directory name
go build -n -ldflags=-X=math.pi=3 my/cmd/prog/
go build -a -n -ldflags=-X=math.pi=3 my/cmd/prog/
stderr 'link.* -X=math.pi=3'
# -ldflags applies to current directory
cd my/cmd/prog
go build -n -ldflags=-X=math.pi=3
go build -a -n -ldflags=-X=math.pi=3
stderr 'link.* -X=math.pi=3'
# -ldflags applies to current directory even if GOPATH is funny
[!case-sensitive] cd $WORK/GoPath/src/my/cmd/prog
go build -n -ldflags=-X=math.pi=3
go build -a -n -ldflags=-X=math.pi=3
stderr 'link.* -X=math.pi=3'
# cgo.a should not be a dependency of internally-linked go package

View File

@@ -5,33 +5,12 @@ env GO111MODULE=on
# Regression test for golang.org/issue/29667:
# spurious 'failed to cache compiled Go files' errors.
# This test failed reliably when run with -count=10
# on a Linux workstation.
env GOCACHE=$WORK/gocache
mkdir $GOCACHE
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
go list -json -compiled -test=false -export=false -deps=true -- . &
wait
-- go.mod --

View File

@@ -52,27 +52,25 @@ env GOFLAGS='-unsafeptr'
stderr 'go: parsing \$GOFLAGS: unknown flag -unsafeptr'
env GOFLAGS=
env GOCACHE=$WORK/gocache
# "go test" on a user package should by default enable an explicit list of analyzers.
go test -x -run=none .
go test -n -run=none .
stderr '[/\\]vet'$GOEXE'["]? .* -errorsas .* ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg'
# An explicitly-empty -vet argument should imply the default analyzers.
go test -x -vet= -run=none .
go test -n -vet= -run=none .
stderr '[/\\]vet'$GOEXE'["]? .* -errorsas .* ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg'
# "go test" on a standard package should by default disable an explicit list.
go test -x -run=none encoding/binary
go test -n -run=none encoding/binary
stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false -unreachable=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg'
go test -x -vet= -run=none encoding/binary
go test -n -vet= -run=none encoding/binary
stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false -unreachable=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg'
# Both should allow users to override via the -vet flag.
go test -x -vet=unreachable -run=none .
go test -n -vet=unreachable -run=none .
stderr '[/\\]vet'$GOEXE'["]? -unreachable ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg'
go test -x -vet=unreachable -run=none encoding/binary
go test -n -vet=unreachable -run=none encoding/binary
stderr '[/\\]vet'$GOEXE'["]? -unreachable ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg'
-- go.mod --

View File

@@ -16,7 +16,11 @@ import (
)
type Curve interface {
// GenerateKey generates a new PrivateKey from rand.
// GenerateKey generates a random PrivateKey.
//
// Most applications should use [crypto/rand.Reader] as rand. Note that the
// returned key does not depend deterministically on the bytes read from rand,
// and may change between calls and/or between versions.
GenerateKey(rand io.Reader) (*PrivateKey, error)
// NewPrivateKey checks that key is valid and returns a PrivateKey.

View File

@@ -150,7 +150,11 @@ func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOp
return SignASN1(rand, priv, digest)
}
// GenerateKey generates a public and private key pair.
// GenerateKey generates a new ECDSA private key for the specified curve.
//
// Most applications should use [crypto/rand.Reader] as rand. Note that the
// returned key does not depend deterministically on the bytes read from rand,
// and may change between calls and/or between versions.
func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) {
randutil.MaybeReadByte(rand)
@@ -245,6 +249,10 @@ var errNoAsm = errors.New("no assembly implementation available")
// using the private key, priv. If the hash is longer than the bit-length of the
// private key's curve order, the hash will be truncated to that length. It
// returns the ASN.1 encoded signature.
//
// The signature is randomized. Most applications should use [crypto/rand.Reader]
// as rand. Note that the returned signature does not depend deterministically on
// the bytes read from rand, and may change between calls and/or between versions.
func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) {
randutil.MaybeReadByte(rand)

View File

@@ -76,7 +76,7 @@ func (priv PrivateKey) Seed() []byte {
return bytes.Clone(priv[:SeedSize])
}
// Sign signs the given message with priv. rand is ignored.
// Sign signs the given message with priv. rand is ignored and can be nil.
//
// If opts.HashFunc() is [crypto.SHA512], the pre-hashed variant Ed25519ph is used
// and message is expected to be a SHA-512 hash, otherwise opts.HashFunc() must
@@ -132,6 +132,9 @@ func (o *Options) HashFunc() crypto.Hash { return o.Hash }
// GenerateKey generates a public/private key pair using entropy from rand.
// If rand is nil, [crypto/rand.Reader] will be used.
//
// The output of this function is deterministic, and equivalent to reading
// [SeedSize] bytes from rand, and passing them to [NewKeyFromSeed].
func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
if rand == nil {
rand = cryptorand.Reader

View File

@@ -31,7 +31,10 @@ type PKCS1v15DecryptOptions struct {
//
// The random parameter is used as a source of entropy to ensure that
// encrypting the same message twice doesn't result in the same
// ciphertext.
// ciphertext. Most applications should use [crypto/rand.Reader]
// as random. Note that the returned ciphertext does not depend
// deterministically on the bytes read from random, and may change
// between calls and/or between versions.
//
// WARNING: use of this function to encrypt plaintexts other than
// session keys is dangerous. Use RSA OAEP in new protocols.
@@ -79,7 +82,7 @@ func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, erro
}
// DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from PKCS #1 v1.5.
// The random parameter is legacy and ignored, and it can be as nil.
// The random parameter is legacy and ignored, and it can be nil.
//
// Note that whether this function returns an error or not discloses secret
// information. If an attacker can cause this function to run repeatedly and
@@ -275,7 +278,7 @@ var hashPrefixes = map[crypto.Hash][]byte{
// function. If hash is zero, hashed is signed directly. This isn't
// advisable except for interoperability.
//
// The random parameter is legacy and ignored, and it can be as nil.
// The random parameter is legacy and ignored, and it can be nil.
//
// This function is deterministic. Thus, if the set of possible
// messages is small, an attacker may be able to build a map from

View File

@@ -285,7 +285,17 @@ var invalidSaltLenErr = errors.New("crypto/rsa: PSSOptions.SaltLength cannot be
// digest must be the result of hashing the input message using the given hash
// function. The opts argument may be nil, in which case sensible defaults are
// used. If opts.Hash is set, it overrides hash.
//
// The signature is randomized depending on the message, key, and salt size,
// using bytes from rand. Most applications should use [crypto/rand.Reader] as
// rand.
func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, opts *PSSOptions) ([]byte, error) {
// Note that while we don't commit to deterministic execution with respect
// to the rand stream, we also don't apply MaybeReadByte, so per Hyrum's Law
// it's probably relied upon by some. It's a tolerable promise because a
// well-specified number of random bytes is included in the signature, in a
// well-specified way.
if boring.Enabled && rand == boring.RandReader {
bkey, err := boringPrivateKey(priv)
if err != nil {

View File

@@ -263,8 +263,11 @@ func (priv *PrivateKey) Validate() error {
return nil
}
// GenerateKey generates an RSA keypair of the given bit size using the
// random source random (for example, crypto/rand.Reader).
// GenerateKey generates a random RSA private key of the given bit size.
//
// Most applications should use [crypto/rand.Reader] as rand. Note that the
// returned key does not depend deterministically on the bytes read from rand,
// and may change between calls and/or between versions.
func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) {
return GenerateMultiPrimeKey(random, 2, bits)
}
@@ -500,6 +503,7 @@ func encrypt(pub *PublicKey, plaintext []byte) ([]byte, error) {
//
// The random parameter is used as a source of entropy to ensure that
// encrypting the same message twice doesn't result in the same ciphertext.
// Most applications should use [crypto/rand.Reader] as random.
//
// The label parameter may contain arbitrary data that will not be encrypted,
// but which gives important context to the message. For example, if a given
@@ -510,6 +514,12 @@ func encrypt(pub *PublicKey, plaintext []byte) ([]byte, error) {
// The message must be no longer than the length of the public modulus minus
// twice the hash length, minus a further 2.
func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) ([]byte, error) {
// Note that while we don't commit to deterministic execution with respect
// to the random stream, we also don't apply MaybeReadByte, so per Hyrum's
// Law it's probably relied upon by some. It's a tolerable promise because a
// well-specified number of random bytes is included in the ciphertext, in a
// well-specified way.
if err := checkPub(pub); err != nil {
return nil, err
}
@@ -691,7 +701,7 @@ func decrypt(priv *PrivateKey, ciphertext []byte, check bool) ([]byte, error) {
// Encryption and decryption of a given message must use the same hash function
// and sha256.New() is a reasonable choice.
//
// The random parameter is legacy and ignored, and it can be as nil.
// The random parameter is legacy and ignored, and it can be nil.
//
// The label parameter must match the value given when encrypting. See
// EncryptOAEP for details.

View File

@@ -12,7 +12,9 @@ import (
"time"
)
func TestPlatformVerifier(t *testing.T) {
func TestPlatformVerifierLegacy(t *testing.T) {
// TODO(#52108): This can be removed once the synthetic test root is deployed on
// builders.
if !testenv.HasExternalNetwork() {
t.Skip()
}

View File

@@ -16,7 +16,9 @@ import (
"time"
)
func TestPlatformVerifier(t *testing.T) {
func TestPlatformVerifierLegacy(t *testing.T) {
// TODO(#52108): This can be removed once the synthetic test root is deployed on
// builders.
if !testenv.HasExternalNetwork() {
t.Skip()
}

View File

@@ -512,22 +512,21 @@ func testVerify(t *testing.T, test verifyTest, useSystemRoots bool) {
return true
}
// Every expected chain should match 1 returned chain
// Every expected chain should match one (or more) returned chain. We tolerate multiple
// matches, as due to root store semantics it is plausible that (at least on the system
// verifiers) multiple identical (looking) chains may be returned when two roots with the
// same subject are present.
for _, expectedChain := range test.expectedChains {
nChainMatched := 0
var match bool
for _, chain := range chains {
if doesMatch(expectedChain, chain) {
nChainMatched++
match = true
break
}
}
if nChainMatched != 1 {
t.Errorf("Got %v matches instead of %v for expected chain %v", nChainMatched, 1, expectedChain)
for _, chain := range chains {
if doesMatch(expectedChain, chain) {
t.Errorf("\t matched %v", chainToDebugString(chain))
}
}
if !match {
t.Errorf("No match found for %v", expectedChain)
}
}

View File

@@ -2944,15 +2944,17 @@ func (rs *Rows) initContextClose(ctx, txctx context.Context) {
if bypassRowsAwaitDone {
return
}
ctx, rs.cancel = context.WithCancel(ctx)
go rs.awaitDone(ctx, txctx)
closectx, cancel := context.WithCancel(ctx)
rs.cancel = cancel
go rs.awaitDone(ctx, txctx, closectx)
}
// awaitDone blocks until either ctx or txctx is canceled. The ctx is provided
// from the query context and is canceled when the query Rows is closed.
// awaitDone blocks until ctx, txctx, or closectx is canceled.
// The ctx is provided from the query context.
// If the query was issued in a transaction, the transaction's context
// is also provided in txctx to ensure Rows is closed if the Tx is closed.
func (rs *Rows) awaitDone(ctx, txctx context.Context) {
// is also provided in txctx, to ensure Rows is closed if the Tx is closed.
// The closectx is closed by an explicit call to rs.Close.
func (rs *Rows) awaitDone(ctx, txctx, closectx context.Context) {
var txctxDone <-chan struct{}
if txctx != nil {
txctxDone = txctx.Done()
@@ -2964,6 +2966,9 @@ func (rs *Rows) awaitDone(ctx, txctx context.Context) {
case <-txctxDone:
err := txctx.Err()
rs.contextDone.Store(&err)
case <-closectx.Done():
// rs.cancel was called via Close(); don't store this into contextDone
// to ensure Err() is unaffected.
}
rs.close(ctx.Err())
}

View File

@@ -4493,6 +4493,31 @@ func TestContextCancelBetweenNextAndErr(t *testing.T) {
}
}
func TestNilErrorAfterClose(t *testing.T) {
db := newTestDB(t, "people")
defer closeDB(t, db)
// This WithCancel is important; Rows contains an optimization to avoid
// spawning a goroutine when the query/transaction context cannot be
// canceled, but this test tests a bug which is caused by said goroutine.
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
r, err := db.QueryContext(ctx, "SELECT|people|name|")
if err != nil {
t.Fatal(err)
}
if err := r.Close(); err != nil {
t.Fatal(err)
}
time.Sleep(10 * time.Millisecond) // increase odds of seeing failure
if err := r.Err(); err != nil {
t.Fatal(err)
}
}
// badConn implements a bad driver.Conn, for TestBadDriver.
// The Exec method panics.
type badConn struct{}

View File

@@ -50,7 +50,8 @@ const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
const encodeHex = "0123456789ABCDEFGHIJKLMNOPQRSTUV"
// NewEncoding returns a new Encoding defined by the given alphabet,
// which must be a 32-byte string.
// which must be a 32-byte string. The alphabet is treated as sequence
// of byte values without any special treatment for multi-byte UTF-8.
func NewEncoding(encoder string) *Encoding {
if len(encoder) != 32 {
panic("encoding alphabet is not 32-bytes long")
@@ -80,6 +81,8 @@ var HexEncoding = NewEncoding(encodeHex)
// The padding character must not be '\r' or '\n', must not
// be contained in the encoding's alphabet and must be a rune equal or
// below '\xff'.
// Padding characters above '\x7f' are encoded as their exact byte value
// rather than using the UTF-8 representation of the codepoint.
func (enc Encoding) WithPadding(padding rune) *Encoding {
if padding == '\r' || padding == '\n' || padding > 0xff {
panic("invalid padding")

View File

@@ -54,7 +54,8 @@ const encodeURL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678
// NewEncoding returns a new padded Encoding defined by the given alphabet,
// which must be a 64-byte string that does not contain the padding character
// or CR / LF ('\r', '\n').
// or CR / LF ('\r', '\n'). The alphabet is treated as sequence of byte values
// without any special treatment for multi-byte UTF-8.
// The resulting Encoding uses the default padding character ('='),
// which may be changed or disabled via WithPadding.
func NewEncoding(encoder string) *Encoding {
@@ -83,6 +84,8 @@ func NewEncoding(encoder string) *Encoding {
// The padding character must not be '\r' or '\n', must not
// be contained in the encoding's alphabet and must be a rune equal or
// below '\xff'.
// Padding characters above '\x7f' are encoded as their exact byte value
// rather than using the UTF-8 representation of the codepoint.
func (enc Encoding) WithPadding(padding rune) *Encoding {
if padding == '\r' || padding == '\n' || padding > 0xff {
panic("invalid padding")

View File

@@ -479,7 +479,6 @@ func dataSize(v reflect.Value) int {
if s := sizeof(v.Type().Elem()); s >= 0 {
return s * v.Len()
}
return -1
case reflect.Struct:
t := v.Type()
@@ -491,8 +490,12 @@ func dataSize(v reflect.Value) int {
return size
default:
return sizeof(v.Type())
if v.IsValid() {
return sizeof(v.Type())
}
}
return -1
}
// sizeof returns the size >= 0 of variables for the given type or -1 if the type is not acceptable.

View File

@@ -351,6 +351,26 @@ func TestSizeStructCache(t *testing.T) {
}
}
func TestSizeInvalid(t *testing.T) {
testcases := []any{
int(0),
new(int),
(*int)(nil),
[1]uint{},
new([1]uint),
(*[1]uint)(nil),
[]int{},
[]int(nil),
new([]int),
(*[]int)(nil),
}
for _, tc := range testcases {
if got := Size(tc); got != -1 {
t.Errorf("Size(%T) = %d, want -1", tc, got)
}
}
}
// An attempt to read into a struct with an unexported field will
// panic. This is probably not the best choice, but at this point
// anything else would be an API change.

View File

@@ -286,7 +286,7 @@ var depsRules = `
math/big, go/token
< go/constant;
container/heap, go/constant, go/parser, internal/types/errors
container/heap, go/constant, go/parser, internal/goversion, internal/types/errors
< go/types;
# The vast majority of standard library packages should not be resorting to regexp.

View File

@@ -577,6 +577,11 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
x.mode = value
}
// Use the final type computed above for all arguments.
for _, a := range args {
check.updateExprType(a.expr, x.typ, true)
}
if check.recordTypes() && x.mode != constant_ {
types := make([]Type, nargs)
for i := range types {

View File

@@ -12,6 +12,7 @@ import (
"go/ast"
"go/constant"
"go/token"
"internal/goversion"
. "internal/types/errors"
)
@@ -233,20 +234,20 @@ func NewChecker(conf *Config, fset *token.FileSet, pkg *Package, info *Info) *Ch
info = new(Info)
}
version, err := parseGoVersion(conf.GoVersion)
if err != nil {
panic(fmt.Sprintf("invalid Go version %q (%v)", conf.GoVersion, err))
}
// Note: clients may call NewChecker with the Unsafe package, which is
// globally shared and must not be mutated. Therefore NewChecker must not
// mutate *pkg.
//
// (previously, pkg.goVersion was mutated here: go.dev/issue/61212)
return &Checker{
conf: conf,
ctxt: conf.Context,
fset: fset,
pkg: pkg,
Info: info,
version: version,
objMap: make(map[Object]*declInfo),
impMap: make(map[importKey]*Package),
conf: conf,
ctxt: conf.Context,
fset: fset,
pkg: pkg,
Info: info,
objMap: make(map[Object]*declInfo),
impMap: make(map[importKey]*Package),
}
}
@@ -342,6 +343,20 @@ func (check *Checker) Files(files []*ast.File) error { return check.checkFiles(f
var errBadCgo = errors.New("cannot use FakeImportC and go115UsesCgo together")
func (check *Checker) checkFiles(files []*ast.File) (err error) {
if check.pkg == Unsafe {
// Defensive handling for Unsafe, which cannot be type checked, and must
// not be mutated. See https://go.dev/issue/61212 for an example of where
// Unsafe is passed to NewChecker.
return nil
}
check.version, err = parseGoVersion(check.conf.GoVersion)
if err != nil {
return err
}
if check.version.after(version{1, goversion.Version}) {
return fmt.Errorf("package requires newer Go version %v", check.version)
}
if check.conf.FakeImportC && check.conf.go115UsesCgo {
return errBadCgo
}
@@ -386,6 +401,7 @@ func (check *Checker) checkFiles(files []*ast.File) (err error) {
check.monomorph()
}
check.pkg.goVersion = check.conf.GoVersion
check.pkg.complete = true
// no longer needed - release memory

View File

@@ -141,6 +141,7 @@ var filemap = map[string]action{
"universe.go": fixGlobalTypVarDecl,
"util_test.go": fixTokenPos,
"validtype.go": nil,
"version_test.go": nil,
}
// TODO(gri) We should be able to make these rewriters more configurable/composable.

View File

@@ -186,6 +186,7 @@ func (check *Checker) indexExpr(x *operand, e *typeparams.IndexExpr) (isFuncInst
if !valid {
// types2 uses the position of '[' for the error
check.errorf(x, NonIndexableOperand, invalidOp+"cannot index %s", x)
check.use(e.Indices...)
x.mode = invalid
return false
}

View File

@@ -12,13 +12,14 @@ import (
// A Package describes a Go package.
type Package struct {
path string
name string
scope *Scope
imports []*Package
complete bool
fake bool // scope lookup errors are silently dropped if package is fake (internal use only)
cgo bool // uses of this package will be rewritten into uses of declarations from _cgo_gotypes.go
path string
name string
scope *Scope
imports []*Package
complete bool
fake bool // scope lookup errors are silently dropped if package is fake (internal use only)
cgo bool // uses of this package will be rewritten into uses of declarations from _cgo_gotypes.go
goVersion string // minimum Go version required for package (by Config.GoVersion, typically from go.mod)
}
// NewPackage returns a new Package for the given package path and name.
@@ -37,6 +38,12 @@ func (pkg *Package) Name() string { return pkg.name }
// SetName sets the package name.
func (pkg *Package) SetName(name string) { pkg.name = name }
// GoVersion returns the minimum Go version required by this package.
// If the minimum version is unknown, GoVersion returns the empty string.
// Individual source files may specify a different minimum Go version,
// as reported in the [go/ast.File.GoVersion] field.
func (pkg *Package) GoVersion() string { return pkg.goVersion }
// Scope returns the (complete or incomplete) package scope
// holding the objects declared at package level (TypeNames,
// Consts, Vars, and Funcs).

View File

@@ -46,7 +46,7 @@ func TestSizeof(t *testing.T) {
// Misc
{Scope{}, 44, 88},
{Package{}, 36, 72},
{Package{}, 44, 88},
{_TypeSet{}, 28, 56},
}
for _, test := range tests {

View File

@@ -126,6 +126,20 @@ const (
exact
)
func (m unifyMode) String() string {
switch m {
case 0:
return "inexact"
case assign:
return "assign"
case exact:
return "exact"
case assign | exact:
return "assign, exact"
}
return fmt.Sprintf("mode %d", m)
}
// unify attempts to unify x and y and reports whether it succeeded.
// As a side-effect, types may be inferred for type parameters.
// The mode parameter controls how types are compared.
@@ -258,6 +272,15 @@ func (u *unifier) inferred(tparams []*TypeParam) []Type {
return list
}
// asInterface returns the underlying type of x as an interface if
// it is a non-type parameter interface. Otherwise it returns nil.
func asInterface(x Type) (i *Interface) {
if _, ok := x.(*TypeParam); !ok {
i, _ = under(x).(*Interface)
}
return i
}
// nify implements the core unification algorithm which is an
// adapted version of Checker.identical. For changes to that
// code the corresponding changes should be made here.
@@ -265,7 +288,7 @@ func (u *unifier) inferred(tparams []*TypeParam) []Type {
func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) {
u.depth++
if traceInference {
u.tracef("%s ≡ %s (mode %d)", x, y, mode)
u.tracef("%s ≡ %s\t// %s", x, y, mode)
}
defer func() {
if traceInference && !result {
@@ -296,7 +319,7 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) {
// - type parameter recorded with u, make sure one is in x
if _, ok := x.(*Named); ok || u.asTypeParam(y) != nil {
if traceInference {
u.tracef("%s ≡ %s (swap)", y, x)
u.tracef("%s ≡ %s\t// swap", y, x)
}
x, y = y, x
}
@@ -352,11 +375,49 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) {
if x := u.at(px); x != nil {
// x has an inferred type which must match y
if u.nify(x, y, mode, p) {
// If we have a match, possibly through underlying types,
// and y is a defined type, make sure we record that type
// We have a match, possibly through underlying types.
xi := asInterface(x)
yi := asInterface(y)
_, xn := x.(*Named)
_, yn := y.(*Named)
// If we have two interfaces, what to do depends on
// whether they are named and their method sets.
if xi != nil && yi != nil {
// Both types are interfaces.
// If both types are defined types, they must be identical
// because unification doesn't know which type has the "right" name.
if xn && yn {
return Identical(x, y)
}
// In all other cases, the method sets must match.
// The types unified so we know that corresponding methods
// match and we can simply compare the number of methods.
// TODO(gri) We may be able to relax this rule and select
// the more general interface. But if one of them is a defined
// type, it's not clear how to choose and whether we introduce
// an order dependency or not. Requiring the same method set
// is conservative.
if len(xi.typeSet().methods) != len(yi.typeSet().methods) {
return false
}
} else if xi != nil || yi != nil {
// One but not both of them are interfaces.
// In this case, either x or y could be viable matches for the corresponding
// type parameter, which means choosing either introduces an order dependence.
// Therefore, we must fail unification (go.dev/issue/60933).
return false
}
// If y is a defined type, make sure we record that type
// for type parameter x, which may have until now only
// recorded an underlying type (go.dev/issue/43056).
if _, ok := y.(*Named); ok {
// Either both types are interfaces, or neither type is.
// If both are interfaces, they have the same methods.
//
// Note: Changing the recorded type for a type parameter to
// a defined type is only ok when unification is inexact.
// But in exact unification, if we have a match, x and y must
// be identical, so changing the recorded type for x is a no-op.
if yn {
u.set(px, y)
}
return true
@@ -386,14 +447,8 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) {
if enableInterfaceInference && mode&exact == 0 {
// One or both interfaces may be defined types.
// Look under the name, but not under type parameters (go.dev/issue/60564).
var xi *Interface
if _, ok := x.(*TypeParam); !ok {
xi, _ = under(x).(*Interface)
}
var yi *Interface
if _, ok := y.(*TypeParam); !ok {
yi, _ = under(y).(*Interface)
}
xi := asInterface(x)
yi := asInterface(y)
// If we have two interfaces, check the type terms for equivalence,
// and unify common methods if possible.
if xi != nil && yi != nil {
@@ -494,7 +549,7 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) {
// TODO(gri) Factor out type parameter handling from the switch.
if isTypeParam(y) {
if traceInference {
u.tracef("%s ≡ %s (swap)", y, x)
u.tracef("%s ≡ %s\t// swap", y, x)
}
x, y = y, x
}

View File

@@ -5,7 +5,6 @@
package types
import (
"errors"
"fmt"
"go/ast"
"go/token"
@@ -45,23 +44,24 @@ var (
go1_21 = version{1, 21}
)
var errVersionSyntax = errors.New("invalid Go version syntax")
// parseGoVersion parses a Go version string (such as "go1.12")
// and returns the version, or an error. If s is the empty
// string, the version is 0.0.
func parseGoVersion(s string) (v version, err error) {
bad := func() (version, error) {
return version{}, fmt.Errorf("invalid Go version syntax %q", s)
}
if s == "" {
return
}
if !strings.HasPrefix(s, "go") {
return version{}, errVersionSyntax
return bad()
}
s = s[len("go"):]
i := 0
for ; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
if i >= 10 || i == 0 && s[i] == '0' {
return version{}, errVersionSyntax
return bad()
}
v.major = 10*v.major + int(s[i]) - '0'
}
@@ -69,7 +69,7 @@ func parseGoVersion(s string) (v version, err error) {
return
}
if i == 0 || s[i] != '.' {
return version{}, errVersionSyntax
return bad()
}
s = s[i+1:]
if s == "0" {
@@ -82,14 +82,15 @@ func parseGoVersion(s string) (v version, err error) {
i = 0
for ; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
if i >= 10 || i == 0 && s[i] == '0' {
return version{}, errVersionSyntax
return bad()
}
v.minor = 10*v.minor + int(s[i]) - '0'
}
if i > 0 && i == len(s) {
return
}
return version{}, errVersionSyntax
// Accept any suffix after the minor number.
// We are only looking for the language version (major.minor)
// but want to accept any valid Go version, like go1.21.0
// and go1.21rc2.
return
}
// langCompat reports an error if the representation of a numeric

View File

@@ -0,0 +1,26 @@
// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
// 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 types
import "testing"
var parseGoVersionTests = []struct {
in string
out version
}{
{"go1.21", version{1, 21}},
{"go1.21.0", version{1, 21}},
{"go1.21rc2", version{1, 21}},
}
func TestParseGoVersion(t *testing.T) {
for _, tt := range parseGoVersionTests {
if out, err := parseGoVersion(tt.in); out != tt.out || err != nil {
t.Errorf("parseGoVersion(%q) = %v, %v, want %v, nil", tt.in, out, err, tt.out)
}
}
}

View File

@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !gccgo
package abi
// FuncPC* intrinsics.

View File

@@ -0,0 +1,21 @@
// 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.
// For bootstrapping with gccgo.
//go:build gccgo
package abi
import "unsafe"
func FuncPCABI0(f interface{}) uintptr {
words := (*[2]unsafe.Pointer)(unsafe.Pointer(&f))
return *(*uintptr)(unsafe.Pointer(words[1]))
}
func FuncPCABIInternal(f interface{}) uintptr {
words := (*[2]unsafe.Pointer)(unsafe.Pointer(&f))
return *(*uintptr)(unsafe.Pointer(words[1]))
}

View File

@@ -37,6 +37,8 @@ TEXT memequal<>(SB),NOSPLIT|NOFRAME,$0
BEQZ X9, loop32_check
// Check one byte at a time until we reach 8 byte alignment.
SUB X9, X0, X9
ADD $8, X9, X9
SUB X9, X12, X12
align:
ADD $-1, X9

View File

@@ -6,7 +6,7 @@
// the instrumentation is OS specific, but only amd64 and arm64 are
// supported in the runtime. See src/runtime/libfuzzer*.
//
// If you update this constraint, also update internal/platform.FuzzInstrumeted.
// If you update this constraint, also update internal/platform.FuzzInstrumented.
//
//go:build !((darwin || linux || windows || freebsd) && (amd64 || arm64))

View File

@@ -2,8 +2,19 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:generate go test . -run=TestGenerated -fix
package platform
// An OSArch is a pair of GOOS and GOARCH values indicating a platform.
type OSArch struct {
GOOS, GOARCH string
}
func (p OSArch) String() string {
return p.GOOS + "/" + p.GOARCH
}
// RaceDetectorSupported reports whether goos/goarch supports the race
// detector. There is a copy of this function in cmd/dist/test.go.
// Race detector only supports 48-bit VMA on arm64. But it will always
@@ -123,11 +134,11 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool {
return true
}
platform := goos + "/" + goarch
if _, ok := osArchSupportsCgo[platform]; !ok {
if _, ok := distInfo[OSArch{goos, goarch}]; !ok {
return false // platform unrecognized
}
platform := goos + "/" + goarch
switch buildmode {
case "archive":
return true
@@ -239,11 +250,6 @@ func DefaultPIE(goos, goarch string, isRace bool) bool {
return false
}
// CgoSupported reports whether goos/goarch supports cgo.
func CgoSupported(goos, goarch string) bool {
return osArchSupportsCgo[goos+"/"+goarch]
}
// ExecutableHasDWARF reports whether the linked executable includes DWARF
// symbols on goos/goarch.
func ExecutableHasDWARF(goos, goarch string) bool {
@@ -253,3 +259,28 @@ func ExecutableHasDWARF(goos, goarch string) bool {
}
return true
}
// osArchInfo describes information about an OSArch extracted from cmd/dist and
// stored in the generated distInfo map.
type osArchInfo struct {
CgoSupported bool
FirstClass bool
Broken bool
}
// CgoSupported reports whether goos/goarch supports cgo.
func CgoSupported(goos, goarch string) bool {
return distInfo[OSArch{goos, goarch}].CgoSupported
}
// FirstClass reports whether goos/goarch is considered a “first class” port.
// (See https://go.dev/wiki/PortingPolicy#first-class-ports.)
func FirstClass(goos, goarch string) bool {
return distInfo[OSArch{goos, goarch}].FirstClass
}
// Broken reportsr whether goos/goarch is considered a broken port.
// (See https://go.dev/wiki/PortingPolicy#broken-ports.)
func Broken(goos, goarch string) bool {
return distInfo[OSArch{goos, goarch}].Broken
}

View File

@@ -0,0 +1,114 @@
// Code generated by go test internal/platform -fix. DO NOT EDIT.
// To change the information in this file, edit the cgoEnabled and/or firstClass
// maps in cmd/dist/build.go, then run 'go generate internal/platform'.
package platform
// List is the list of all valid GOOS/GOARCH combinations,
// including known-broken ports.
var List = []OSArch{
{"aix", "ppc64"},
{"android", "386"},
{"android", "amd64"},
{"android", "arm"},
{"android", "arm64"},
{"darwin", "amd64"},
{"darwin", "arm64"},
{"dragonfly", "amd64"},
{"freebsd", "386"},
{"freebsd", "amd64"},
{"freebsd", "arm"},
{"freebsd", "arm64"},
{"freebsd", "riscv64"},
{"illumos", "amd64"},
{"ios", "amd64"},
{"ios", "arm64"},
{"js", "wasm"},
{"linux", "386"},
{"linux", "amd64"},
{"linux", "arm"},
{"linux", "arm64"},
{"linux", "loong64"},
{"linux", "mips"},
{"linux", "mips64"},
{"linux", "mips64le"},
{"linux", "mipsle"},
{"linux", "ppc64"},
{"linux", "ppc64le"},
{"linux", "riscv64"},
{"linux", "s390x"},
{"linux", "sparc64"},
{"netbsd", "386"},
{"netbsd", "amd64"},
{"netbsd", "arm"},
{"netbsd", "arm64"},
{"openbsd", "386"},
{"openbsd", "amd64"},
{"openbsd", "arm"},
{"openbsd", "arm64"},
{"openbsd", "mips64"},
{"openbsd", "ppc64"},
{"plan9", "386"},
{"plan9", "amd64"},
{"plan9", "arm"},
{"solaris", "amd64"},
{"wasip1", "wasm"},
{"windows", "386"},
{"windows", "amd64"},
{"windows", "arm"},
{"windows", "arm64"},
}
var distInfo = map[OSArch]osArchInfo{
{"aix", "ppc64"}: {CgoSupported: true},
{"android", "386"}: {CgoSupported: true},
{"android", "amd64"}: {CgoSupported: true},
{"android", "arm"}: {CgoSupported: true},
{"android", "arm64"}: {CgoSupported: true},
{"darwin", "amd64"}: {CgoSupported: true, FirstClass: true},
{"darwin", "arm64"}: {CgoSupported: true, FirstClass: true},
{"dragonfly", "amd64"}: {CgoSupported: true},
{"freebsd", "386"}: {CgoSupported: true},
{"freebsd", "amd64"}: {CgoSupported: true},
{"freebsd", "arm"}: {CgoSupported: true},
{"freebsd", "arm64"}: {CgoSupported: true},
{"freebsd", "riscv64"}: {CgoSupported: true},
{"illumos", "amd64"}: {CgoSupported: true},
{"ios", "amd64"}: {CgoSupported: true},
{"ios", "arm64"}: {CgoSupported: true},
{"js", "wasm"}: {},
{"linux", "386"}: {CgoSupported: true, FirstClass: true},
{"linux", "amd64"}: {CgoSupported: true, FirstClass: true},
{"linux", "arm"}: {CgoSupported: true, FirstClass: true},
{"linux", "arm64"}: {CgoSupported: true, FirstClass: true},
{"linux", "loong64"}: {CgoSupported: true},
{"linux", "mips"}: {CgoSupported: true},
{"linux", "mips64"}: {CgoSupported: true},
{"linux", "mips64le"}: {CgoSupported: true},
{"linux", "mipsle"}: {CgoSupported: true},
{"linux", "ppc64"}: {},
{"linux", "ppc64le"}: {CgoSupported: true},
{"linux", "riscv64"}: {CgoSupported: true},
{"linux", "s390x"}: {CgoSupported: true},
{"linux", "sparc64"}: {CgoSupported: true, Broken: true},
{"netbsd", "386"}: {CgoSupported: true},
{"netbsd", "amd64"}: {CgoSupported: true},
{"netbsd", "arm"}: {CgoSupported: true},
{"netbsd", "arm64"}: {CgoSupported: true},
{"openbsd", "386"}: {CgoSupported: true},
{"openbsd", "amd64"}: {CgoSupported: true},
{"openbsd", "arm"}: {CgoSupported: true},
{"openbsd", "arm64"}: {CgoSupported: true},
{"openbsd", "mips64"}: {CgoSupported: true, Broken: true},
{"openbsd", "ppc64"}: {Broken: true},
{"plan9", "386"}: {},
{"plan9", "amd64"}: {},
{"plan9", "arm"}: {},
{"solaris", "amd64"}: {CgoSupported: true},
{"wasip1", "wasm"}: {},
{"windows", "386"}: {CgoSupported: true, FirstClass: true},
{"windows", "amd64"}: {CgoSupported: true, FirstClass: true},
{"windows", "arm"}: {},
{"windows", "arm64"}: {CgoSupported: true},
}

View File

@@ -0,0 +1,109 @@
// 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 platform_test
import (
"bytes"
"encoding/json"
"flag"
"internal/diff"
"internal/testenv"
"os"
"os/exec"
"testing"
"text/template"
)
var flagFix = flag.Bool("fix", false, "if true, fix out-of-date generated files")
// TestGenerated verifies that zosarch.go is up to date,
// or regenerates it if the -fix flag is set.
func TestGenerated(t *testing.T) {
testenv.MustHaveGoRun(t)
// Here we use 'go run cmd/dist' instead of 'go tool dist' in case the
// installed cmd/dist is stale or missing. We don't want to miss a
// skew in the data due to a stale binary.
cmd := testenv.Command(t, "go", "run", "cmd/dist", "list", "-json", "-broken")
// cmd/dist requires GOROOT to be set explicitly in the environment.
cmd.Env = append(cmd.Environ(), "GOROOT="+testenv.GOROOT(t))
out, err := cmd.Output()
if err != nil {
if ee, ok := err.(*exec.ExitError); ok && len(ee.Stderr) > 0 {
t.Logf("stderr:\n%s", ee.Stderr)
}
t.Fatalf("%v: %v", cmd, err)
}
type listEntry struct {
GOOS, GOARCH string
CgoSupported bool
FirstClass bool
Broken bool
}
var entries []listEntry
if err := json.Unmarshal(out, &entries); err != nil {
t.Fatal(err)
}
tmplOut := new(bytes.Buffer)
tmpl := template.Must(template.New("zosarch").Parse(zosarchTmpl))
err = tmpl.Execute(tmplOut, entries)
if err != nil {
t.Fatal(err)
}
cmd = testenv.Command(t, "gofmt")
cmd.Stdin = bytes.NewReader(tmplOut.Bytes())
want, err := cmd.Output()
if err != nil {
t.Logf("stdin:\n%s", tmplOut.Bytes())
if ee, ok := err.(*exec.ExitError); ok && len(ee.Stderr) > 0 {
t.Logf("stderr:\n%s", ee.Stderr)
}
t.Fatalf("%v: %v", cmd, err)
}
got, err := os.ReadFile("zosarch.go")
if err == nil && bytes.Equal(got, want) {
return
}
if !*flagFix {
if err != nil {
t.Log(err)
} else {
t.Logf("diff:\n%s", diff.Diff("zosarch.go", got, "want", want))
}
t.Fatalf("zosarch.go is missing or out of date; to regenerate, run\ngo generate internal/platform")
}
if err := os.WriteFile("zosarch.go", want, 0666); err != nil {
t.Fatal(err)
}
}
const zosarchTmpl = `// Code generated by go test internal/platform -fix. DO NOT EDIT.
// To change the information in this file, edit the cgoEnabled and/or firstClass
// maps in cmd/dist/build.go, then run 'go generate internal/platform'.
package platform
// List is the list of all valid GOOS/GOARCH combinations,
// including known-broken ports.
var List = []OSArch{
{{range .}} { {{ printf "%q" .GOOS }}, {{ printf "%q" .GOARCH }} },
{{end}}
}
var distInfo = map[OSArch]osArchInfo {
{{range .}} { {{ printf "%q" .GOOS }}, {{ printf "%q" .GOARCH }} }:
{ {{if .CgoSupported}}CgoSupported: true, {{end}}{{if .FirstClass}}FirstClass: true, {{end}}{{if .Broken}} Broken: true, {{end}} },
{{end}}
}
`

View File

@@ -0,0 +1,11 @@
// 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 p
func _() {
var x int
var f func() []int
_ = f /* ERROR "cannot index f" */ [x]
}

View File

@@ -0,0 +1,67 @@
// 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 p
import (
"io"
"os"
)
func g[T any](...T) {}
// Interface and non-interface types do not match.
func _() {
var file *os.File
g(file, io /* ERROR "type io.Writer of io.Discard does not match inferred type *os.File for T" */ .Discard)
g(file, os.Stdout)
}
func _() {
var a *os.File
var b any
g(a, a)
g(a, b /* ERROR "type any of b does not match inferred type *os.File for T" */)
}
var writer interface {
Write(p []byte) (n int, err error)
}
func _() {
var file *os.File
g(file, writer /* ERROR "type interface{Write(p []byte) (n int, err error)} of writer does not match inferred type *os.File for T" */)
g(writer, file /* ERROR "type *os.File of file does not match inferred type interface{Write(p []byte) (n int, err error)} for T" */)
}
// Different named interface types do not match.
func _() {
g(io.ReadWriter(nil), io.ReadWriter(nil))
g(io.ReadWriter(nil), io /* ERROR "does not match" */ .Writer(nil))
g(io.Writer(nil), io /* ERROR "does not match" */ .ReadWriter(nil))
}
// Named and unnamed interface types match if they have the same methods.
func _() {
g(io.Writer(nil), writer)
g(io.ReadWriter(nil), writer /* ERROR "does not match" */ )
}
// There must be no order dependency for named and unnamed interfaces.
func f[T interface{ m(T) }](a, b T) {}
type F interface {
m(F)
}
func _() {
var i F
var j interface {
m(F)
}
// order doesn't matter
f(i, j)
f(j, i)
}

View File

@@ -0,0 +1,38 @@
// 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 p
type Tn interface{ m() }
type T1 struct{}
type T2 struct{}
func (*T1) m() {}
func (*T2) m() {}
func g[P any](...P) {}
func _() {
var t interface{ m() }
var tn Tn
var t1 *T1
var t2 *T2
// these are ok (interface types only)
g(t, t)
g(t, tn)
g(tn, t)
g(tn, tn)
// these are not ok (interface and non-interface types)
g(t, t1 /* ERROR "does not match" */)
g(t1, t /* ERROR "does not match" */)
g(tn, t1 /* ERROR "does not match" */)
g(t1, tn /* ERROR "does not match" */)
g(t, t1 /* ERROR "does not match" */, t2)
g(t1, t2 /* ERROR "does not match" */, t)
g(tn, t1 /* ERROR "does not match" */, t2)
g(t1, t2 /* ERROR "does not match" */, tn)
}

View File

@@ -81,7 +81,7 @@ func argsToAttrSlice(args []any) []Attr {
}
// Any returns an Attr for the supplied value.
// See [Value.AnyValue] for how values are treated.
// See [AnyValue] for how values are treated.
func Any(key string, value any) Attr {
return Attr{key, AnyValue(value)}
}

View File

@@ -255,7 +255,7 @@ and hidden fields that refer to state (such as attributes) indirectly. This
means that modifying a simple copy of a Record (e.g. by calling
[Record.Add] or [Record.AddAttrs] to add attributes)
may have unexpected effects on the original.
Before modifying a Record, use [Clone] to
Before modifying a Record, use [Record.Clone] to
create a copy that shares no state with the original,
or create a new Record with [NewRecord]
and build up its Attrs by traversing the old ones with [Record.Attrs].

View File

@@ -140,7 +140,7 @@ type HandlerOptions struct {
// ReplaceAttr is called to rewrite each non-group attribute before it is logged.
// The attribute's value has been resolved (see [Value.Resolve]).
// If ReplaceAttr returns an Attr with Key == "", the attribute is discarded.
// If ReplaceAttr returns a zero Attr, the attribute is discarded.
//
// The built-in attributes with keys "time", "level", "source", and "msg"
// are passed to this function, except that time is omitted
@@ -221,6 +221,11 @@ func (h *commonHandler) enabled(l Level) bool {
}
func (h *commonHandler) withAttrs(as []Attr) *commonHandler {
// We are going to ignore empty groups, so if the entire slice consists of
// them, there is nothing to do.
if countEmptyGroups(as) == len(as) {
return h
}
h2 := h.clone()
// Pre-format the attributes as an optimization.
state := h2.newHandleState((*buffer.Buffer)(&h2.preformattedAttrs), false, "")
@@ -308,15 +313,20 @@ func (s *handleState) appendNonBuiltIns(r Record) {
}
// Attrs in Record -- unlike the built-in ones, they are in groups started
// from WithGroup.
s.prefix.WriteString(s.h.groupPrefix)
s.openGroups()
r.Attrs(func(a Attr) bool {
s.appendAttr(a)
return true
})
// If the record has no Attrs, don't output any groups.
nOpenGroups := s.h.nOpenGroups
if r.NumAttrs() > 0 {
s.prefix.WriteString(s.h.groupPrefix)
s.openGroups()
nOpenGroups = len(s.h.groups)
r.Attrs(func(a Attr) bool {
s.appendAttr(a)
return true
})
}
if s.h.json {
// Close all open groups.
for range s.h.groups {
for range s.h.groups[:nOpenGroups] {
s.buf.WriteByte('}')
}
// Close the top-level object.

View File

@@ -214,6 +214,28 @@ func TestJSONAndTextHandlers(t *testing.T) {
wantText: "msg=message h.a=1",
wantJSON: `{"msg":"message","h":{"a":1}}`,
},
{
name: "nested empty group",
replace: removeKeys(TimeKey, LevelKey),
attrs: []Attr{
Group("g",
Group("h",
Group("i"), Group("j"))),
},
wantText: `msg=message`,
wantJSON: `{"msg":"message"}`,
},
{
name: "nested non-empty group",
replace: removeKeys(TimeKey, LevelKey),
attrs: []Attr{
Group("g",
Group("h",
Group("i"), Group("j", Int("a", 1)))),
},
wantText: `msg=message g.h.j.a=1`,
wantJSON: `{"msg":"message","g":{"h":{"j":{"a":1}}}}`,
},
{
name: "escapes",
replace: removeKeys(TimeKey, LevelKey),
@@ -281,6 +303,34 @@ func TestJSONAndTextHandlers(t *testing.T) {
wantText: "msg=message p1=1 s1.s2.a=one s1.s2.b=2",
wantJSON: `{"msg":"message","p1":1,"s1":{"s2":{"a":"one","b":2}}}`,
},
{
name: "empty with-groups",
replace: removeKeys(TimeKey, LevelKey),
with: func(h Handler) Handler {
return h.WithGroup("x").WithGroup("y")
},
wantText: "msg=message",
wantJSON: `{"msg":"message"}`,
},
{
name: "empty with-groups, no non-empty attrs",
replace: removeKeys(TimeKey, LevelKey),
with: func(h Handler) Handler {
return h.WithGroup("x").WithAttrs([]Attr{Group("g")}).WithGroup("y")
},
wantText: "msg=message",
wantJSON: `{"msg":"message"}`,
},
{
name: "one empty with-group",
replace: removeKeys(TimeKey, LevelKey),
with: func(h Handler) Handler {
return h.WithGroup("x").WithAttrs([]Attr{Int("a", 1)}).WithGroup("y")
},
attrs: []Attr{Group("g", Group("h"))},
wantText: "msg=message x.a=1",
wantJSON: `{"msg":"message","x":{"a":1}}`,
},
{
name: "GroupValue as Attr value",
replace: removeKeys(TimeKey, LevelKey),

View File

@@ -106,7 +106,7 @@ func TestConnections(t *testing.T) {
// log.Logger's output goes through the handler.
SetDefault(New(NewTextHandler(&slogbuf, &HandlerOptions{AddSource: true})))
log.Print("msg2")
checkLogOutput(t, slogbuf.String(), "time="+timeRE+` level=INFO source=.*logger_test.go:\d{3} msg=msg2`)
checkLogOutput(t, slogbuf.String(), "time="+timeRE+` level=INFO source=.*logger_test.go:\d{3}"? msg=msg2`)
// The default log.Logger always outputs at Info level.
slogbuf.Reset()

View File

@@ -93,9 +93,17 @@ func (r Record) Attrs(f func(Attr) bool) {
}
// AddAttrs appends the given Attrs to the Record's list of Attrs.
// It omits empty groups.
func (r *Record) AddAttrs(attrs ...Attr) {
n := copy(r.front[r.nFront:], attrs)
r.nFront += n
var i int
for i = 0; i < len(attrs) && r.nFront < len(r.front); i++ {
a := attrs[i]
if a.Value.isEmptyGroup() {
continue
}
r.front[r.nFront] = a
r.nFront++
}
// Check if a copy was modified by slicing past the end
// and seeing if the Attr there is non-zero.
if cap(r.back) > len(r.back) {
@@ -104,15 +112,25 @@ func (r *Record) AddAttrs(attrs ...Attr) {
panic("copies of a slog.Record were both modified")
}
}
r.back = append(r.back, attrs[n:]...)
ne := countEmptyGroups(attrs[i:])
r.back = slices.Grow(r.back, len(attrs[i:])-ne)
for _, a := range attrs[i:] {
if !a.Value.isEmptyGroup() {
r.back = append(r.back, a)
}
}
}
// Add converts the args to Attrs as described in [Logger.Log],
// then appends the Attrs to the Record's list of Attrs.
// It omits empty groups.
func (r *Record) Add(args ...any) {
var a Attr
for len(args) > 0 {
a, args = argsToAttr(args)
if a.Value.isEmptyGroup() {
continue
}
if r.nFront < len(r.front) {
r.front[r.nFront] = a
r.nFront++

View File

@@ -164,9 +164,32 @@ func DurationValue(v time.Duration) Value {
// GroupValue returns a new Value for a list of Attrs.
// The caller must not subsequently mutate the argument slice.
func GroupValue(as ...Attr) Value {
// Remove empty groups.
// It is simpler overall to do this at construction than
// to check each Group recursively for emptiness.
if n := countEmptyGroups(as); n > 0 {
as2 := make([]Attr, 0, len(as)-n)
for _, a := range as {
if !a.Value.isEmptyGroup() {
as2 = append(as2, a)
}
}
as = as2
}
return Value{num: uint64(len(as)), any: groupptr(unsafe.SliceData(as))}
}
// countEmptyGroups returns the number of empty group values in its argument.
func countEmptyGroups(as []Attr) int {
n := 0
for _, a := range as {
if a.Value.isEmptyGroup() {
n++
}
}
return n
}
// AnyValue returns a Value for the supplied value.
//
// If the supplied value is of type Value, it is returned
@@ -399,6 +422,17 @@ func (v Value) Equal(w Value) bool {
}
}
// isEmptyGroup reports whether v is a group that has no attributes.
func (v Value) isEmptyGroup() bool {
if v.Kind() != KindGroup {
return false
}
// We do not need to recursively examine the group's Attrs for emptiness,
// because GroupValue removed them when the group was constructed, and
// groups are immutable.
return len(v.group()) == 0
}
// append appends a text representation of v to dst.
// v is formatted as with fmt.Sprint.
func (v Value) append(dst []byte) []byte {

View File

@@ -229,6 +229,18 @@ func TestZeroTime(t *testing.T) {
}
}
func TestEmptyGroup(t *testing.T) {
g := GroupValue(
Int("a", 1),
Group("g1", Group("g2")),
Group("g3", Group("g4", Int("b", 2))))
got := g.Group()
want := []Attr{Int("a", 1), Group("g3", Group("g4", Int("b", 2)))}
if !attrsEqual(got, want) {
t.Errorf("\ngot %v\nwant %v", got, want)
}
}
type replace struct {
v Value
}

45
src/maps/example_test.go Normal file
View File

@@ -0,0 +1,45 @@
// 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 maps_test
import (
"fmt"
"maps"
"strings"
)
func ExampleDeleteFunc() {
m := map[string]int{
"one": 1,
"two": 2,
"three": 3,
"four": 4,
}
maps.DeleteFunc(m, func(k string, v int) bool {
return v%2 != 0 // delete odd values
})
fmt.Println(m)
// Output:
// map[four:4 two:2]
}
func ExampleEqualFunc() {
m1 := map[int]string{
1: "one",
10: "Ten",
1000: "THOUSAND",
}
m2 := map[int][]byte{
1: []byte("One"),
10: []byte("Ten"),
1000: []byte("Thousand"),
}
eq := maps.EqualFunc(m1, m2, func(v1 string, v2 []byte) bool {
return strings.ToLower(v1) == strings.ToLower(string(v2))
})
fmt.Println(eq)
// Output:
// true
}

View File

@@ -2059,6 +2059,9 @@ var fmaC = []struct{ x, y, z, want float64 }{
// Special
{0, 0, 0, 0},
{Copysign(0, -1), 0, 0, 0},
{0, 0, Copysign(0, -1), 0},
{Copysign(0, -1), 0, Copysign(0, -1), Copysign(0, -1)},
{-1.1754226043408471e-38, NaN(), Inf(0), NaN()},
{0, 0, 2.22507385643494e-308, 2.22507385643494e-308},
{-8.65697792e+09, NaN(), -7.516192799999999e+09, NaN()},
@@ -2077,6 +2080,10 @@ var fmaC = []struct{ x, y, z, want float64 }{
{4.612811918325842e+18, 1.4901161193847641e-08, 2.6077032311277997e-08, 6.873625395187494e+10},
{-9.094947033611148e-13, 4.450691014249257e-308, 2.086006742350485e-308, 2.086006742346437e-308},
{-7.751454006381804e-05, 5.588653777189071e-308, -2.2207280111272877e-308, -2.2211612130544025e-308},
// Issue #61130
{-1, 1, 1, 0},
{1, 1, -1, 0},
}
var sqrt32 = []float32{
@@ -3099,6 +3106,45 @@ func TestFMA(t *testing.T) {
}
}
//go:noinline
func fmsub(x, y, z float64) float64 {
return FMA(x, y, -z)
}
//go:noinline
func fnmsub(x, y, z float64) float64 {
return FMA(-x, y, z)
}
//go:noinline
func fnmadd(x, y, z float64) float64 {
return FMA(-x, y, -z)
}
func TestFMANegativeArgs(t *testing.T) {
// Some architectures have instructions for fused multiply-subtract and
// also negated variants of fused multiply-add and subtract. This test
// aims to check that the optimizations that generate those instructions
// are applied correctly, if they exist.
for _, c := range fmaC {
want := PortableFMA(c.x, c.y, -c.z)
got := fmsub(c.x, c.y, c.z)
if !alike(got, want) {
t.Errorf("FMA(%g, %g, -(%g)) == %g, want %g", c.x, c.y, c.z, got, want)
}
want = PortableFMA(-c.x, c.y, c.z)
got = fnmsub(c.x, c.y, c.z)
if !alike(got, want) {
t.Errorf("FMA(-(%g), %g, %g) == %g, want %g", c.x, c.y, c.z, got, want)
}
want = PortableFMA(-c.x, c.y, -c.z)
got = fnmadd(c.x, c.y, c.z)
if !alike(got, want) {
t.Errorf("FMA(-(%g), %g, -(%g)) == %g, want %g", c.x, c.y, c.z, got, want)
}
}
}
// Check that math functions of high angle values
// return accurate results. [Since (vf[i] + large) - large != vf[i],
// testing for Trig(vf[i] + large) == Trig(vf[i]), where large is

View File

@@ -132,6 +132,11 @@ func FMA(x, y, z float64) float64 {
ps, pe, pm1, pm2, zs, ze, zm1, zm2 = zs, ze, zm1, zm2, ps, pe, pm1, pm2
}
// Special case: if p == -z the result is always +0 since neither operand is zero.
if ps != zs && pe == ze && pm1 == zm1 && pm2 == zm2 {
return 0
}
// Align significands
zm1, zm2 = shrcompress(zm1, zm2, uint(pe-ze))

View File

@@ -3,12 +3,13 @@
// license that can be found in the LICENSE file.
// This file holds stub versions of the cgo functions called on Unix systems.
// We build this file if using the netgo build tag, or if cgo is not
// enabled and we are using a Unix system other than Darwin.
// Darwin is exempted because it always provides the cgo routines,
// in cgo_unix_syscall.go.
// We build this file:
// - if using the netgo build tag on a Unix system
// - on a Unix system without the cgo resolver functions
// (Darwin always provides the cgo functions, in cgo_unix_syscall.go)
// - on wasip1, where cgo is never available
//go:build netgo || (!cgo && unix && !darwin)
//go:build (netgo && unix) || (unix && !cgo && !darwin) || wasip1
package net

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 !js && !wasip1
//go:build !js
package net

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 !js && !wasip1
//go:build !js
// DNS client: see RFC 1035.
// Has to be linked into package net for Dial.

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 !js && !wasip1 && !windows
//go:build !js && !windows
// Read system DNS config from /etc/resolv.conf

View File

@@ -48,35 +48,6 @@ func TestForeachHeaderElement(t *testing.T) {
}
}
func TestCleanHost(t *testing.T) {
tests := []struct {
in, want string
}{
{"www.google.com", "www.google.com"},
{"www.google.com foo", "www.google.com"},
{"www.google.com/foo", "www.google.com"},
{" first character is a space", ""},
{"[1::6]:8080", "[1::6]:8080"},
// Punycode:
{"гофер.рф/foo", "xn--c1ae0ajs.xn--p1ai"},
{"bücher.de", "xn--bcher-kva.de"},
{"bücher.de:8080", "xn--bcher-kva.de:8080"},
// Verify we convert to lowercase before punycode:
{"BÜCHER.de", "xn--bcher-kva.de"},
{"BÜCHER.de:8080", "xn--bcher-kva.de:8080"},
// Verify we normalize to NFC before punycode:
{"gophér.nfc", "xn--gophr-esa.nfc"}, // NFC input; no work needed
{"goph\u0065\u0301r.nfd", "xn--gophr-esa.nfd"}, // NFD input
}
for _, tt := range tests {
got := cleanHost(tt.in)
if tt.want != got {
t.Errorf("cleanHost(%q) = %q, want %q", tt.in, got, tt.want)
}
}
}
// Test that cmd/go doesn't link in the HTTP server.
//
// This catches accidental dependencies between the HTTP transport and

View File

@@ -17,7 +17,6 @@ import (
"io"
"mime"
"mime/multipart"
"net"
"net/http/httptrace"
"net/http/internal/ascii"
"net/textproto"
@@ -27,6 +26,7 @@ import (
"strings"
"sync"
"golang.org/x/net/http/httpguts"
"golang.org/x/net/idna"
)
@@ -580,12 +580,19 @@ func (r *Request) write(w io.Writer, usingProxy bool, extraHeaders Header, waitF
// is not given, use the host from the request URL.
//
// Clean the host, in case it arrives with unexpected stuff in it.
host := cleanHost(r.Host)
host := r.Host
if host == "" {
if r.URL == nil {
return errMissingHost
}
host = cleanHost(r.URL.Host)
host = r.URL.Host
}
host, err = httpguts.PunycodeHostPort(host)
if err != nil {
return err
}
if !httpguts.ValidHostHeader(host) {
return errors.New("http: invalid Host header")
}
// According to RFC 6874, an HTTP client, proxy, or other
@@ -742,40 +749,6 @@ func idnaASCII(v string) (string, error) {
return idna.Lookup.ToASCII(v)
}
// cleanHost cleans up the host sent in request's Host header.
//
// It both strips anything after '/' or ' ', and puts the value
// into Punycode form, if necessary.
//
// Ideally we'd clean the Host header according to the spec:
//
// https://tools.ietf.org/html/rfc7230#section-5.4 (Host = uri-host [ ":" port ]")
// https://tools.ietf.org/html/rfc7230#section-2.7 (uri-host -> rfc3986's host)
// https://tools.ietf.org/html/rfc3986#section-3.2.2 (definition of host)
//
// But practically, what we are trying to avoid is the situation in
// issue 11206, where a malformed Host header used in the proxy context
// would create a bad request. So it is enough to just truncate at the
// first offending character.
func cleanHost(in string) string {
if i := strings.IndexAny(in, " /"); i != -1 {
in = in[:i]
}
host, port, err := net.SplitHostPort(in)
if err != nil { // input was just a host
a, err := idnaASCII(in)
if err != nil {
return in // garbage in, garbage out
}
return a
}
a, err := idnaASCII(host)
if err != nil {
return in // garbage in, garbage out
}
return net.JoinHostPort(a, port)
}
// removeZone removes IPv6 zone identifier from host.
// E.g., "[fe80::1%en0]:8080" to "[fe80::1]:8080"
func removeZone(host string) string {

View File

@@ -775,15 +775,8 @@ func TestRequestBadHost(t *testing.T) {
}
req.Host = "foo.com with spaces"
req.URL.Host = "foo.com with spaces"
req.Write(logWrites{t, &got})
want := []string{
"GET /after HTTP/1.1\r\n",
"Host: foo.com\r\n",
"User-Agent: " + DefaultUserAgent + "\r\n",
"\r\n",
}
if !reflect.DeepEqual(got, want) {
t.Errorf("Writes = %q\n Want = %q", got, want)
if err := req.Write(logWrites{t, &got}); err == nil {
t.Errorf("Writing request with invalid Host: succeded, want error")
}
}

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