Compare commits

...

138 Commits

Author SHA1 Message Date
Gopher Robot
d5b8518043 [release-branch.go1.20] go1.20.8
Change-Id: Iac628daa970d01c5958839fcf668106e93bce8b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/526037
Reviewed-by: Joedian Reid <joedian@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Gopher Robot <gobot@golang.org>
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
2023-09-06 15:31:47 +00:00
Roland Shoemaker
2070531d2f [release-branch.go1.20] html/template: properly handle special tags within the script context
The HTML specification has incredibly complex rules for how to handle
"<!--", "<script", and "</script" when they appear within literals in
the script context. Rather than attempting to apply these restrictions
(which require a significantly more complex state machine) we apply
the workaround suggested in section 4.12.1.3 of the HTML specification [1].

More precisely, when "<!--", "<script", and "</script" appear within
literals (strings and regular expressions, ignoring comments since we
already elide their content) we replace the "<" with "\x3C". This avoids
the unintuitive behavior that using these tags within literals can cause,
by simply preventing the rendered content from triggering it. This may
break some correct usages of these tags, but on balance is more likely
to prevent XSS attacks where users are unknowingly either closing or not
closing the script blocks where they think they are.

Thanks to Takeshi Kaneko (GMO Cybersecurity by Ierae, Inc.) for
reporting this issue.

Fixes #62197
Fixes #62397
Fixes CVE-2023-39319

[1] https://html.spec.whatwg.org/#restrictions-for-contents-of-script-elements

Change-Id: Iab57b0532694827e3eddf57a7497ba1fab1746dc
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1976594
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/2014621
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/526099
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Cherry Mui <cherryyz@google.com>
2023-09-06 14:22:36 +00:00
Roland Shoemaker
023b542edf [release-branch.go1.20] html/template: support HTML-like comments in script contexts
Per Appendix B.1.1 of the ECMAScript specification, support HTML-like
comments in script contexts. Also per section 12.5, support hashbang
comments. This brings our parsing in-line with how browsers treat these
comment types.

Thanks to Takeshi Kaneko (GMO Cybersecurity by Ierae, Inc.) for
reporting this issue.

Fixes #62196
Fixes #62395
Fixes CVE-2023-39318

Change-Id: Id512702c5de3ae46cf648e268cb10e1eb392a181
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1976593
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/2014620
Reviewed-on: https://go-review.googlesource.com/c/go/+/526098
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-09-06 14:22:29 +00:00
David Chase
612da32fb5 [release-branch.go1.20] cmd/compile: in expandCalls, move all arg marshalling into call block
For aggregate-typed arguments passed to a call, expandCalls
decomposed them into parts in the same block where the value
was created.  This is not necessarily the call block, and in
the case where stores are involved, can change the memory
leaving that block, and getting that right is problematic.

Instead, do all the expanding in the same block as the call,
which avoids the problems of (1) not being able to reorder
loads/stores across a block boundary to conform to memory
order and (2) (incorrectly, not) exposing the new memory to
consumers in other blocks.  Putting it all in the same block
as the call allows reordering, and the call creates its own
new memory (which is already dealt with correctly).

Fixes #62056.
Updates #61992.

Change-Id: Icc7918f0d2dd3c480cc7f496cdcd78edeca7f297
Reviewed-on: https://go-review.googlesource.com/c/go/+/519276
Reviewed-by: Keith Randall <khr@google.com>
Run-TryBot: David Chase <drchase@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit e72ecc6a6b)
Reviewed-on: https://go-review.googlesource.com/c/go/+/520059
2023-08-24 21:11:06 +00:00
Damien Neil
f0b8768dbc [release-branch.go1.20] path/filepath: don't drop .. elements when cleaning invalid Windows paths
Fix a bug where Clean could improperly drop .. elements from a
path on Windows, when the path contains elements containing a ':'.

For example, Clean("a/../b:/../../c") now correctly returns "..\c"
rather than "c".

For #61866.
Fixes #61867.

Change-Id: I97b0238953c183b2ce19ca89c14f26700008ea72
Reviewed-on: https://go-review.googlesource.com/c/go/+/517216
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Quim Muntal <quimmuntal@gmail.com>
(cherry picked from commit 6e43407931)
Reviewed-on: https://go-review.googlesource.com/c/go/+/519636
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
2023-08-23 17:53:16 +00:00
David Chase
b463668275 [release-branch.go1.20] runtime: profiling on Darwin cannot use blocking reads
On Darwin (and assume also on iOS but not sure), notetsleepg
cannot be called in a signal-handling context.  Avoid this
by disabling block reads on Darwin.

An alternate approach was to add "sigNote" with a pipe-based
implementation on Darwin, but that ultimately would have required
at least one more linkname between runtime and syscall to avoid
racing with fork and opening the pipe, so, not.

Fixes #62018.
Updates #61768.

Change-Id: I0e8dd4abf9a606a3ff73fc37c3bd75f55924e07e
Reviewed-on: https://go-review.googlesource.com/c/go/+/518836
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
(cherry picked from commit c6ee8e31e3)
Reviewed-on: https://go-review.googlesource.com/c/go/+/518677
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Austin Clements <austin@google.com>
2023-08-17 21:10:05 +00:00
Robert Findley
974a3c9af7 [release-branch.go1.20] go/types, types2: don't panic during interface completion
It should be possible for the importer to construct an invalid
interface, as would have been produced by type checking.

Updates #61737
Fixes #61744

Change-Id: I72e063f4f1a6205d273a623acce2ec08c34c3cc2
Reviewed-on: https://go-review.googlesource.com/c/go/+/515555
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Findley <rfindley@google.com>
Reviewed-by: Olif Oftimis <oftimisolif@gmail.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit d2ee7821d3)
Reviewed-on: https://go-review.googlesource.com/c/go/+/515638
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2023-08-17 21:06:30 +00:00
Russ Cox
14e3c7338d [release-branch.go1.20] cmd/api: rename api.go to main_test.go
This makes cmd/api no longer an importable package.
In CL 453258 I forgot that there was no direct prohibition
on importing packages from cmd - we just rely on the
fact that cmd/* is all package main and everything else
is cmd/internal.

Fixes #62069.
Fixes #62070.

Change-Id: Ifed738d333b40663f85eca8f83025fcea5df89a9
Reviewed-on: https://go-review.googlesource.com/c/go/+/520038
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/c/go/+/520060
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2023-08-17 20:58:04 +00:00
Roland Shoemaker
095cfba86b [release-branch.go1.20] crypto/tls: add GODEBUG to control max RSA key size
Add a new GODEBUG setting, tlsmaxrsasize, which allows controlling the
maximum RSA key size we will accept during TLS handshakes.

Fixes #61966

Change-Id: I52f060be132014d219f4cd438f59990011a35c96
Reviewed-on: https://go-review.googlesource.com/c/go/+/517495
Auto-Submit: Roland Shoemaker <roland@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/c/go/+/518555
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2023-08-16 17:16:34 +00:00
Russ Cox
1a91bb94b0 [release-branch.go1.20] cmd/go: do not index std as a module in modcache
We do not index std as a whole module ever.

When working in the main Go repo, files in package change often,
so we don't want to pay the cost of reindexing all of std when what
we really need is just to reindex strings. Per-package indexing
works better for that case.

When using a released Go toolchain, we don't have to worry about
the whole module changing, but if we switch to whole-module indexing
at that point, we have the potential for bugs that only happen in
released toolchains. Probably not worth the risk.

For similar reasons, we don't index the current work module as
a whole module (individual packages are changing), so we use the heuristic
that we only do whole-module indexing in the module cache.

The new toolchain modules live in the module cache, though, and
our heuristic was causing whole-module indexing for them.
As predicted, enabling whole-module indexing for std when it's
completely untested does in fact lead to bugs (a very minor one).

This CL turns off whole-module indexing for std even when it is
in the module cache, to bring toolchain module behavior back in
line with the other ways to run toolchains.

Updates #57001.
For #61873.

Change-Id: I5012dc713f566846eb4b2848facc7f75bc956eb9
Reviewed-on: https://go-review.googlesource.com/c/go/+/504119
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Auto-Submit: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
(cherry picked from commit a7b1793701)
Reviewed-on: https://go-review.googlesource.com/c/go/+/518415
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Bryan Mills <bcmills@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2023-08-14 22:05:13 +00:00
Damien Neil
ede3e278ae [release-branch.go1.20] net/http: permit requests with invalid Host headers
Historically, the Transport has silently truncated invalid
Host headers at the first '/' or ' ' character. CL 506996 changed
this behavior to reject invalid Host headers entirely.
Unfortunately, Docker appears to rely on the previous behavior.

When sending a HTTP/1 request with an invalid Host, send an empty
Host header. This is safer than truncation: If you care about the
Host, then you should get the one you set; if you don't care,
then an empty Host should be fine.

Continue to fully validate Host headers sent to a proxy,
since proxies generally can't productively forward requests
without a Host.

For #60374
Fixes #61431
Fixes #61826

Change-Id: If170c7dd860aa20eb58fe32990fc93af832742b6
Reviewed-on: https://go-review.googlesource.com/c/go/+/511155
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Run-TryBot: Damien Neil <dneil@google.com>
(cherry picked from commit b9153f6ef3)
Reviewed-on: https://go-review.googlesource.com/c/go/+/518756
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Roland Shoemaker <roland@golang.org>
2023-08-14 21:56:57 +00:00
Russ Cox
201f8b40dc [release-branch.go1.20] cmd/go: refuse to build Go 1.22 code
With #60078 accepted, we expect Go 1.22 will have different
for loop semantics than Go 1.20 did. Once Go 1.22 is released,
Go 1.20 will be unsupported, but add a check anyway, just to
help catch some mistakes and usage of old Go toolchains
beyond their end-of-support.

Note that Go 1.20 can keep being used indefinitely with pre-Go 1.22 code.
This change only makes it refuse to build code that says it needs
Go 1.22 semantics, because Go 1.20 does not provide those.

For #60078.

Change-Id: I75118d6fbd0cc08a6bc309aca54c389a255ba7dc
Reviewed-on: https://go-review.googlesource.com/c/go/+/518675
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-08-11 17:11:34 +00:00
Gopher Robot
adb775e309 [release-branch.go1.20] go1.20.7
Change-Id: I5138f0e0b686f7c28c120f464b66736f43048e46
Reviewed-on: https://go-review.googlesource.com/c/go/+/514936
Run-TryBot: Gopher Robot <gobot@golang.org>
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2023-08-01 19:34:15 +00:00
Roland Shoemaker
659f2a2207 [release-branch.go1.20] crypto/tls: restrict RSA keys in certificates to <= 8192 bits
Extremely large RSA keys in certificate chains can cause a client/server
to expend significant CPU time verifying signatures. Limit this by
restricting the size of RSA keys transmitted during handshakes to <=
8192 bits.

Based on a survey of publicly trusted RSA keys, there are currently only
three certificates in circulation with keys larger than this, and all
three appear to be test certificates that are not actively deployed. It
is possible there are larger keys in use in private PKIs, but we target
the web PKI, so causing breakage here in the interests of increasing the
default safety of users of crypto/tls seems reasonable.

Thanks to Mateusz Poliwczak for reporting this issue.

Updates #61460
Fixes #61580
Fixes CVE-2023-29409

Change-Id: Ie35038515a649199a36a12fc2c5df3af855dca6c
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1912161
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Run-TryBot: Roland Shoemaker <bracewell@google.com>
(cherry picked from commit d865c715d92887361e4bd5596e19e513f27781b7)
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1965747
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/514900
Run-TryBot: David Chase <drchase@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-08-01 19:03:48 +00:00
Meng Zhuo
10d85fa0f6 [release-branch.go1.20] cmd/asm, cmd/internal/obj: generate proper atomic ops for riscv64
Go's memory model closely follows the approach C++ concurrency memory
model (https://go.dev/ref/mem) and Go atomic "has the same semantics as C++'s
sequentially consistent atomics".

Meanwhile according to RISCV manual A.6 "Mappings from C/C++ primitives to RISC-V primitives".
C/C++ atomic operations (memory_order_acq_rel) should be map to "amo<op>.{w|d}.aqrl"
LR/SC (memory_order_acq_rel) should map to "lr.{w|d}.aq; <op>; sc.{w|d}.rl"

goos: linux
goarch: riscv64
pkg: runtime/internal/atomic
                │ atomic.old.bench │          atomic.new.bench           │
                │      sec/op      │   sec/op     vs base                │
AtomicLoad64-4         4.216n ± 1%   4.202n ± 0%        ~ (p=0.127 n=10)
AtomicStore64-4        5.040n ± 0%   6.718n ± 0%  +33.30% (p=0.000 n=10)
AtomicLoad-4           4.217n ± 0%   4.213n ± 0%        ~ (p=0.145 n=10)
AtomicStore-4          5.040n ± 0%   6.718n ± 0%  +33.30% (p=0.000 n=10)
And8-4                 9.237n ± 0%   9.240n ± 0%        ~ (p=0.582 n=10)
And-4                  5.878n ± 0%   6.719n ± 0%  +14.31% (p=0.000 n=10)
And8Parallel-4         28.44n ± 0%   28.46n ± 0%   +0.07% (p=0.000 n=10)
AndParallel-4          28.40n ± 0%   28.43n ± 0%   +0.11% (p=0.000 n=10)
Or8-4                  8.399n ± 0%   8.398n ± 0%        ~ (p=0.357 n=10)
Or-4                   5.879n ± 0%   6.718n ± 0%  +14.27% (p=0.000 n=10)
Or8Parallel-4          28.43n ± 0%   28.45n ± 0%   +0.09% (p=0.000 n=10)
OrParallel-4           28.40n ± 0%   28.43n ± 0%   +0.11% (p=0.000 n=10)
Xadd-4                 30.05n ± 0%   30.10n ± 0%   +0.18% (p=0.000 n=10)
Xadd64-4               30.05n ± 0%   30.09n ± 0%   +0.12% (p=0.000 n=10)
Cas-4                  60.48n ± 0%   61.13n ± 0%   +1.08% (p=0.000 n=10)
Cas64-4                62.28n ± 0%   62.34n ± 0%        ~ (p=0.810 n=10)
Xchg-4                 30.05n ± 0%   30.09n ± 0%   +0.15% (p=0.000 n=10)
Xchg64-4               30.05n ± 0%   30.09n ± 0%   +0.13% (p=0.000 n=10)
geomean                15.42n        16.17n        +4.89%

Fixes #61471

Change-Id: I97b5325db50467eeec36fb079bded7b09a32330f
Reviewed-on: https://go-review.googlesource.com/c/go/+/508715
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Joel Sing <joel@sing.id.au>
Run-TryBot: M Zhuo <mzh@golangcn.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit 890b96f7ab)
Reviewed-on: https://go-review.googlesource.com/c/go/+/511515
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: M Zhuo <mzh@golangcn.org>
2023-07-26 16:23:04 +00:00
Heschi Kreinick
bd3a1f24e7 [release-branch.go1.20] net: tolerate permission errors in interface tests
On our linux-arm64 builders, we're getting permission errors despite
running as root. Detect those errors and skip the test.

For #61414.
Fixes #61449

Change-Id: I5d7c45789337bee3860b19335bbb9eb884c48986
Reviewed-on: https://go-review.googlesource.com/c/go/+/510737
Auto-Submit: Heschi Kreinick <heschi@google.com>
Run-TryBot: Heschi Kreinick <heschi@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit 8e1ec1cb93)
Reviewed-on: https://go-review.googlesource.com/c/go/+/511137
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2023-07-19 20:35:36 +00:00
Paul E. Murphy
6211a024b4 [release-branch.go1.20] cmd/compile: on PPC64, fix sign/zero extension when masking
(ANDCCconst [y] (MOV.*reg x)) should only be merged when zero
extending. Otherwise, sign bits are lost on negative values.

(ANDCCconst [0xFF] (MOVBreg x)) should be simplified to a zero
extension of x. Likewise for the MOVHreg variant.

Fixes #61320

Change-Id: I04e4fd7dc6a826e870681f37506620d48393698b
Reviewed-on: https://go-review.googlesource.com/c/go/+/508775
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Paul Murphy <murp@ibm.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/509195
Auto-Submit: Heschi Kreinick <heschi@google.com>
2023-07-19 19:10:08 +00:00
Gopher Robot
2c358ffe97 [release-branch.go1.20] go1.20.6
Change-Id: I9dc89e8bca8cd6262f85be1266c53f53ab8c55a8
Reviewed-on: https://go-review.googlesource.com/c/go/+/508838
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Joedian Reid <joedian@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Gopher Robot <gobot@golang.org>
Auto-Submit: Gopher Robot <gobot@golang.org>
2023-07-11 15:58:20 +00:00
Damien Neil
312920c00a [release-branch.go1.20] 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
Fixes #61076
For CVE-2023-29406

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>
(cherry picked from commit 499458f7ca)
Reviewed-on: https://go-review.googlesource.com/c/go/+/507357
Reviewed-by: Damien Neil <dneil@google.com>
Run-TryBot: Tatiana Bradley <tatianabradley@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
2023-07-06 19:41:17 +00:00
Jelle van den Hooff
4db13d762b [release-branch.go1.20] 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.

For #60934
Fixes #60949

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>
(cherry picked from commit 48dbb6227a)
Reviewed-on: https://go-review.googlesource.com/c/go/+/505676
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
2023-06-29 15:53:20 +00:00
Alex Brainman
08a58dd8b6 [release-branch.go1.20] runtime: allow for 5 more threads in TestWindowsStackMemory*
Original version of TestWindowsStackMemory did not consider sysmon and
other threads running during the test. Allow for 5 extra threads in this
test - this should cover any new threads in the future.

For #58570

Change-Id: I215790f9b94ff40a32ddd7aa54af715d1dc391c6
Reviewed-on: https://go-review.googlesource.com/c/go/+/473415
Reviewed-by: Michael Pratt <mpratt@google.com>
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
(cherry picked from commit f6cbc1da05)
Reviewed-on: https://go-review.googlesource.com/c/go/+/506975
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
2023-06-28 20:21:58 +00:00
Cuong Manh Le
65092835c5 [release-branch.go1.20] cmd/go: skip TestScript/gccgo_link_ldflags on aix/ppc64
The gccgo on the builder is not updated to support runtime/cgo

For #60306.
For #60514.

Change-Id: If0fb1ccdf589cc9741f6a065bacfa4f06e64ec15
Reviewed-on: https://go-review.googlesource.com/c/go/+/501435
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Benny Siegert <bsiegert@gmail.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
(cherry picked from commit 688d75b14f)
Reviewed-on: https://go-review.googlesource.com/c/go/+/505595
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
2023-06-24 02:06:39 +00:00
Roland Shoemaker
bca817594c [release-branch.go1.20] 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.

Updates #60925
Fixes #60947

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>
(cherry picked from commit 20313660f5)
Reviewed-on: https://go-review.googlesource.com/c/go/+/505275
Run-TryBot: Heschi Kreinick <heschi@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Auto-Submit: Heschi Kreinick <heschi@google.com>
2023-06-22 18:46:41 +00:00
Bryan C. Mills
b8e67d1ddd [release-branch.go1.20] cmd/go/internal/test: don't wait for previous test actions when interrupted
Fixes #60849.
Updates #60203.

Change-Id: I59a3320ede1eb3cf4443d7ea37b8cb39d01f222a
Reviewed-on: https://go-review.googlesource.com/c/go/+/503936
Auto-Submit: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
(cherry picked from commit 60876717b4)
Reviewed-on: https://go-review.googlesource.com/c/go/+/504062
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2023-06-22 15:41:22 +00:00
Lucien Coffe
3db4f8146c [release-branch.go1.20] runtime: resolve checkdead panic by refining startm lock handling in caller context
This change addresses a `checkdead` panic caused by a race condition between
`sysmon->startm` and `checkdead` callers, due to prematurely releasing the
scheduler lock. The solution involves allowing a `startm` caller to acquire the
scheduler lock and call `startm` in this context. A new `lockheld` bool
argument is added to `startm`, which manages all lock and unlock calls within
the function. The`startIdle` function variable in `injectglist` is updated to
call `startm` with the lock held, ensuring proper lock handling in this
specific case. This refined lock handling resolves the observed race condition
issue.

For #59600.
Fixes #60760.

Change-Id: I11663a15536c10c773fc2fde291d959099aa71be
Reviewed-on: https://go-review.googlesource.com/c/go/+/487316
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Michael Pratt <mpratt@google.com>
(cherry picked from commit ff059add10)
Reviewed-on: https://go-review.googlesource.com/c/go/+/504395
Reviewed-by: Lucien Coffe <lucien.coffe@botify.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
2023-06-22 15:28:32 +00:00
qmuntal
6b45fb7b73 [release-branch.go1.20] runtime: fallback to TEB arbitrary pointer when TLS slots are full
Note: This CL is cherry-picked from CL 486816 omitting the changes
in sys_windows_386.s, which don't apply to go1.20 release branch
because windows/386 started using the TEB TLS slot in go1.21 (CL 454675).

The Go runtime allocates the TLS slot in the TEB TLS slots instead of
using the TEB arbitrary pointer. See CL 431775 for more context.

The problem is that the TEB TLS slots array only has capacity for 64
indices, allocating more requires some complex logic that we don't
support yet.

Although the Go runtime only allocates one index, a Go DLL can be
loaded in a process with more than 64 TLS slots allocated,
in which case it abort.

This CL avoids aborting by falling back to the older behavior, that
is to use the TEB arbitrary pointer.

Fixes #60535
Updates #59213

Change-Id: I39c73286fe2da95aa9c5ec5657ee0979ecbec533
Reviewed-on: https://go-review.googlesource.com/c/go/+/486816
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Quim Muntal <quimmuntal@gmail.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit 715d53c090)
Reviewed-on: https://go-review.googlesource.com/c/go/+/504475
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2023-06-22 15:27:07 +00:00
Cherry Mui
be30960e58 [release-branch.go1.20] runtime: use 1-byte load for address checking in racecallatomic
In racecallatomic, we do a load before calling into TSAN, so if
the address is invalid we fault on the Go stack. We currently use
a 8-byte load instruction, regardless of the data size that the
atomic operation is performed on. So if, say, we are doing a
LoadUint32 at an address that is the last 4 bytes of a memory
mapping, we may fault unexpectedly. Do a 1-byte load instead.
(Ideally we should do a load with the right size, so we fault
correctly if we're given an unaligned address for a wide load
across a page boundary. Leave that for another CL.)

Fix AMD64, ARM64, and PPC64. The code already uses 1-byte load
on S390X.

Fixes #60845.
Updates #60825.

Change-Id: I3dee93eb08ba180c85e86a9d2e71b5b520e8dcf0
Reviewed-on: https://go-review.googlesource.com/c/go/+/503937
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: David Chase <drchase@google.com>
(cherry picked from commit 1a7709d6af)
Reviewed-on: https://go-review.googlesource.com/c/go/+/503976
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Austin Clements <austin@google.com>
2023-06-22 15:14:44 +00:00
Ian Lance Taylor
b59efe6c34 [release-branch.go1.20] 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.

For #58862
For #60332
Fixes #60874
Fixes #60875

Change-Id: I5437f5e18a756f6ca61c13c4d8ba727be73eff9a
Reviewed-on: https://go-review.googlesource.com/c/go/+/504881
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
2023-06-21 22:17:05 +00:00
Heschi Kreinick
c32f1afb41 [release-branch.go1.20] all: make safe for new vet analyzer
The unused analyzer handles dot imports now, so a few tests
have picked up vet errors. This CL errors like:

context/x_test.go:524:47: result of context.WithValue call not used

This is a manual cherry-pick of CL 493598.

Updates #60058
Fixes #60927

Change-Id: I92906ef7967e14a85fa974e6307fd689e3ff3dba
Reviewed-on: https://go-review.googlesource.com/c/go/+/504977
Auto-Submit: Heschi Kreinick <heschi@google.com>
TryBot-Bypass: Heschi Kreinick <heschi@google.com>
Run-TryBot: Heschi Kreinick <heschi@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
2023-06-21 21:25:57 +00:00
Heschi Kreinick
c7b145655b [release-branch.go1.20] cmd/go: fix tests for new builder environment
Fix two long tests that fail in the builders we're trying out:

- TestQueryImport was failing with:
  open /nonexist-gopath/pkg/sumdb/sum.golang.org/latest: no such file or directory
  which eventually turns out to be because it couldn't create
  /nonexist-gopath because it wasn't running as root. The test already
  uses a temporary GOPATH, but missed overriding a configuration
  variable set at init time.
- test_flags fails if the working directory has /x/ in it, which it now
  happens to.

Change-Id: Ideef0f318157b42987539e3a20f9fba6a3d3bdd0
Reviewed-on: https://go-review.googlesource.com/c/go/+/480255
Run-TryBot: Heschi Kreinick <heschi@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit 4526fa790e)
Reviewed-on: https://go-review.googlesource.com/c/go/+/504975
Auto-Submit: Heschi Kreinick <heschi@google.com>
2023-06-21 20:26:26 +00:00
Ian Lance Taylor
03063101a2 [release-branch.go1.20] text/template: set variables correctly in range assignment
I unintentionally flipped them in CL 446795.

For #56490
For #60801
Fixes #60802

Change-Id: I57586bec052e1b2cc61513870ce24dd6ce17e56b
Reviewed-on: https://go-review.googlesource.com/c/go/+/503576
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
2023-06-21 16:11:26 +00:00
Bryan C. Mills
d51e322a3f [release-branch.go1.20] go/printer: error out of Fprint when it would write a '//line' directive with a multiline file path
Line directives do not provide a way to escape newline characters, so
source file paths containing newlines must not be written in them.

Updates #60516.
Updates #60167.

Change-Id: I30f8b381cc7d1df6914c27591544edf424a4b634
Reviewed-on: https://go-review.googlesource.com/c/go/+/501578
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit d1087efa42ea0b0f011283a87d7a732cba51e4ad)
Reviewed-on: https://go-review.googlesource.com/c/go/+/501819
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
2023-06-20 00:36:19 +00:00
Bryan C. Mills
49594244d3 [release-branch.go1.20] cmd/cover: error out if a requested source file contains a newline
cmd/cover uses '//line' directives to map instrumented source files
back to the original source file and line numbers.
Line directives have no way to escape newline characters, so cmd/cover
must not be used with source file paths that contain such characters.

Updates #60516.
Updates #60167.

Change-Id: I6dc039392d59fc3a5a6121ef6ca97b0ab0da5288
Reviewed-on: https://go-review.googlesource.com/c/go/+/501577
Auto-Submit: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit 3d78c735fc)
Reviewed-on: https://go-review.googlesource.com/c/go/+/501818
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2023-06-20 00:36:17 +00:00
Bryan C. Mills
4719048211 [release-branch.go1.20] cmd/cgo: error out if the source path used in line directives would contain a newline
cmd/cgo uses '//line' directives to map generated source
files back to the original source file and line nmubers.

The line directives have no way to escape newline characters,
so cmd/cgo must not be used if the line directives would contain
such characters.

Updates #60516.
Updates #60167.

Change-Id: I8581cea74d6c08f82e86ed87127e81252e1bf78c
Reviewed-on: https://go-review.googlesource.com/c/go/+/501576
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Bryan Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
(cherry picked from commit c48228312e)
Reviewed-on: https://go-review.googlesource.com/c/go/+/501817
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2023-06-20 00:34:48 +00:00
Bryan C. Mills
6c606fc191 [release-branch.go1.20] cmd/go: fix TestScript/build_cwd_newline with CGO_ENABLED=0
Updates #60516.
Updates #60167.

Change-Id: I3792682e80a3c48d78a3b9e647cc968a1d5c8f2b
Reviewed-on: https://go-review.googlesource.com/c/go/+/501575
Auto-Submit: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
(cherry picked from commit e2b1c0baa6)
Reviewed-on: https://go-review.googlesource.com/c/go/+/501816
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2023-06-20 00:31:39 +00:00
Cuong Manh Le
63ad2b5811 [release-branch.go1.20] cmd/compile: do not report division by error during typecheck
types2 have already errored about any spec-required overflows, and
division by zero. CL 469595 unintentionally fixed typecheck not to error
about overflows, but zero division is still be checked during tcArith.
This causes unsafe operations with variable size failed to compile,
instead of raising runtime error.

This CL also making change to typecheck.EvalConst, to stop evaluating
literal shifts or binary operators where {over,under}flows can happen.
For go1.21, typecheck.EvalConst is removed entirely, but that change is
too large to backport.

See discussion in CL 501735 for more details.

Fixes #60675

Change-Id: I7bea2821099556835c920713397f7c5d8a4025ac
Reviewed-on: https://go-review.googlesource.com/c/go/+/501735
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/503855
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2023-06-19 23:11:17 +00:00
Bryan C. Mills
95f377daad [release-branch.go1.20] cmd/go: retain extra roots to disambiguate imports in 'go mod tidy'
We don't normally keep explicit requirements for test dependencies of
packages loaded from other modules when the required version is
already the selected version in the module graph. However, in some
cases we may need to keep an explicit requirement in order to make use
of lazy module loading to disambiguate an otherwise-ambiguous import.

Note that there is no Go version guard for this change: in the cases
where the behavior of 'go mod tidy' has changed, previous versions of
Go would produce go.mod files that break successive calls to
'go mod tidy'. Given that, I suspect that any existing user in the
wild affected by this bug either already has a workaround in place
using redundant import statements (in which case the change does not
affect them) or is running 'go mod tidy -e' to force past the error
(in which case a change in behavior to a non-error should not be
surprising).

Updates #60313.
Fixes #60352.

Change-Id: Idf294f72cbe3904b871290d79e4493595a0c7bfc
Reviewed-on: https://go-review.googlesource.com/c/go/+/496635
Auto-Submit: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit 2ed6a54a39)
Reviewed-on: https://go-review.googlesource.com/c/go/+/499635
Reviewed-by: Michael Matloob <matloob@golang.org>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2023-06-19 22:56:03 +00:00
Filippo Valsorda
a7a48fad7e [release-branch.go1.20] crypto/ecdsa: properly truncate P-521 hashes
Before, if a hash was exactly 66 bytes long, we weren't truncating it
for use with P-521, because the byte length was not overflowing.
However, the bit length could still overflow.

Fixes #60744
Updates #60741

Change-Id: I37a0ee210add0eb566e6dc1c141e83e992983eb6
Reviewed-on: https://go-review.googlesource.com/c/go/+/502478
Auto-Submit: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
(cherry picked from commit 886fba5871)
Reviewed-on: https://go-review.googlesource.com/c/go/+/502915
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2023-06-19 16:08:25 +00:00
Michael Matloob
f5172dcd38 [release-branch.go1.20] go/build: check for invalid import paths again
The go parser previously checked for invalid import paths, go/build,
seeing the parse error would put files with invalid import paths into
InvalidGoFiles. golang.org/cl/424855 removed that check from the
parser, which meant files with invalid import paths not have any parse
errors on them and not be put into InvalidGoFiles. Do a check for
invalid import paths in go/build soon after parsing so we can make
sure files with invalid import paths go into InvalidGoFiles.

This fixes an issue where the Go command assumed that if a file wasn't
invalid it had non empty import paths, leading to a panic.

Fixes #60754
Updates #60230
Updates #60686

Change-Id: I33c1dc9304649536834939cef7c689940236ee20
Reviewed-on: https://go-review.googlesource.com/c/go/+/502615
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
Run-TryBot: Michael Matloob <matloob@golang.org>
(cherry picked from commit 962753b015)
Reviewed-on: https://go-review.googlesource.com/c/go/+/502697
2023-06-13 19:34:05 +00:00
Bryan C. Mills
8b3acefcbe [release-branch.go1.20] cmd/go: omit checksums for go.mod files needed for go version lines more often in pre-1.21 modules
This updates the logic from CL 489075 to avoid trying to save extra
sums if they aren't already expected to be present
and cfg.BuildMod != "mod" (as in the case of "go list -m -u all" with
a go.mod file that specifies go < 1.21).

Fixes #60698.
Updates #60667.
Updates #56222.

Change-Id: Ied6ed3e80a62f9cd9a328b43a415a42d14481056
Reviewed-on: https://go-review.googlesource.com/c/go/+/502016
Reviewed-by: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
Run-TryBot: Bryan Mills <bcmills@google.com>
2023-06-13 19:31:43 +00:00
Ian Lance Taylor
1008486a9f [release-branch.go1.20] cmd/cgo: correct _cgo_flags output
For #60306
For #60514

Change-Id: I3f5d14aee7d7195030e8872e42b1d97aa11d3582
Reviewed-on: https://go-review.googlesource.com/c/go/+/501298
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2023-06-06 21:43:55 +00:00
Gopher Robot
e827d41c0a [release-branch.go1.20] go1.20.5
Change-Id: I8c6b2a71eef157558ef428782211c3feba4fd03a
Reviewed-on: https://go-review.googlesource.com/c/go/+/501238
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-06-06 17:39:34 +00:00
Bryan C. Mills
c0ed873cd8 [release-branch.go1.20] cmd/go: disallow package directories containing newlines
Directory or file paths containing newlines may cause tools (such as
cmd/cgo) that emit "//line" or "#line" -directives to write part of
the path into non-comment lines in generated source code. If those
lines contain valid Go code, it may be injected into the resulting
binary.

(Note that Go import paths and file paths within module zip files
already could not contain newlines.)

Thanks to Juho Nurminen of Mattermost for reporting this issue.

Updates #60167.
Fixes #60516.
Fixes CVE-2023-29402.

Change-Id: Ic3c7d8d1f6460993bd93a27035d61bff7dd68832
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1882606
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Russ Cox <rsc@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
(cherry picked from commit 41f9046495564fc728d6f98384ab7276450ac7e2)
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1902230
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1904347
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/501222
Run-TryBot: David Chase <drchase@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-06-06 17:03:01 +00:00
Roland Shoemaker
356a419e2f [release-branch.go1.20] cmd/go: enforce flags with non-optional arguments
Enforce that linker flags which expect arguments get them, otherwise it
may be possible to smuggle unexpected flags through as the linker can
consume what looks like a flag as an argument to a preceding flag (i.e.
"-Wl,-O -Wl,-R,-bad-flag" is interpreted as "-O=-R -bad-flag"). Also be
somewhat more restrictive in the general format of some flags.

Thanks to Juho Nurminen of Mattermost for reporting this issue.

Updates #60305
Fixes #60512
Fixes CVE-2023-29404

Change-Id: I5989f68d21a8851d8edd47f08550850524ee9180
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1876275
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
(cherry picked from commit 896779503cf754cbdac24b61d4cc953b50fe2dde)
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1902226
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1904346
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/501221
Run-TryBot: David Chase <drchase@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-06-06 17:03:00 +00:00
Ian Lance Taylor
fa60c381ed [release-branch.go1.20] cmd/go,cmd/cgo: in _cgo_flags use one line per flag
The flags that we recorded in _cgo_flags did not use any quoting,
so a flag containing embedded spaces was mishandled.
Change the _cgo_flags format to put each flag on a separate line.
That is a simple format that does not require any quoting.

As far as I can tell only cmd/go uses _cgo_flags, and it is only
used for gccgo. If this patch doesn't cause any trouble, then
in the next release we can change to only using _cgo_flags for gccgo.

Thanks to Juho Nurminen of Mattermost for reporting this issue.

Updates #60306
Fixes #60514
Fixes CVE-2023-29405

Change-Id: I36b6e188a44c80d7b9573efa577c386770bd2ba3
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1875094
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Roland Shoemaker <bracewell@google.com>
(cherry picked from commit bcdfcadd5612212089d958bc352a6f6c90742dcc)
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1902228
Run-TryBot: Roland Shoemaker <bracewell@google.com>
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1904345
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/501220
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: David Chase <drchase@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
2023-06-06 17:02:02 +00:00
Roland Shoemaker
36144ba429 [release-branch.go1.20] runtime: implement SUID/SGID protections
On Unix platforms, the runtime previously did nothing special when a
program was run with either the SUID or SGID bits set. This can be
dangerous in certain cases, such as when dumping memory state, or
assuming the status of standard i/o file descriptors.

Taking cues from glibc, this change implements a set of protections when
a binary is run with SUID or SGID bits set (or is SUID/SGID-like). On
Linux, whether to enable these protections is determined by whether the
AT_SECURE flag is passed in the auxiliary vector. On platforms which
have the issetugid syscall (the BSDs, darwin, and Solaris/Illumos), that
is used. On the remaining platforms (currently only AIX) we check
!(getuid() == geteuid() && getgid == getegid()).

Currently when we determine a binary is "tainted" (using the glibc
terminology), we implement two specific protections:
  1. we check if the file descriptors 0, 1, and 2 are open, and if they
     are not, we open them, pointing at /dev/null (or fail).
  2. we force GOTRACKBACK=none, and generally prevent dumping of
     trackbacks and registers when a program panics/aborts.

In the future we may add additional protections.

This change requires implementing issetugid on the platforms which
support it, and implementing getuid, geteuid, getgid, and getegid on
AIX.

Thanks to Vincent Dehors from Synacktiv for reporting this issue.

Updates #60272
Fixes #60518
Fixes CVE-2023-29403

Change-Id: Icb620f3f8755791d51b02b5c07fb24f40e19cb80
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1878434
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Russ Cox <rsc@google.com>
(cherry picked from commit 87065663ea6d89cd54f65a515d8f2ed0ef285c19)
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1902232
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1904344
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/501227
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: David Chase <drchase@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
2023-06-06 17:01:31 +00:00
Bryan C. Mills
5036ba77eb [release-branch.go1.20] net: skip TestFileFdBlocks if the "unix" network is not supported
This may fix the android failures observed starting at CL 496715, such
as the one in
https://build.golang.org/log/a92cc6d5fa36bc31858631bacf2d8eacd93709a6.

For #60217.

Change-Id: I4e8eaf9890da269bd1758f59a29fa2a8131d8ae6
Reviewed-on: https://go-review.googlesource.com/c/go/+/496955
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
Auto-Submit: Bryan Mills <bcmills@google.com>
(cherry picked from commit 10fbd925d6)
Reviewed-on: https://go-review.googlesource.com/c/go/+/499297
Reviewed-by: Bryan Mills <bcmills@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Dmitri Shuralyov <dmitshur@google.com>
2023-05-30 19:39:43 +00:00
Shogo Hida
b249ec5655 [release-branch.go1.20] cmd/go/internal: update documentation of go test and go generate
For #57050.
Fixes #60458.

Change-Id: I46cac667ff78ac171c878f4366f8f01f58f1d27d
GitHub-Last-Rev: 697c255ece
GitHub-Pull-Request: golang/go#57814
Reviewed-on: https://go-review.googlesource.com/c/go/+/461683
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
(cherry picked from commit 93d9035c9e)
Reviewed-on: https://go-review.googlesource.com/c/go/+/499218
Run-TryBot: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2023-05-30 18:12:39 +00:00
Bryan C. Mills
4b95fc1e6c [release-branch.go1.20] cmd/go: save checksums for go.mod files needed for go version lines
When we load a package from a module, we need the go version line from
that module's go.mod file to know what language semantics to use for
the package. We need to save a checksum for the go.mod file even if
the module's requirements are pruned out of the module graph.
Previously, we were missing checksums for test dependencies of
packages in 'all' and packages passed to 'go get -t'.

This change preserves the existing bug for 'go mod tidy',
but fixes it for 'go get -t' and flags the missing checksum
with a clearer error in other cases.

Fixes #60001.
Updates #56222.

Change-Id: Icd6acce348907621ae0b02dbeac04fb180353dcf
(cherry picked from CL 489075 and CL 492741)
Reviewed-on: https://go-review.googlesource.com/c/go/+/493015
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
Run-TryBot: Bryan Mills <bcmills@google.com>
2023-05-30 16:25:12 +00:00
Ian Lance Taylor
31a1e19a59 [release-branch.go1.20] net, os: net.Conn.File.Fd should return a blocking descriptor
Historically net.Conn.File.Fd has returned a descriptor in blocking mode.
That was broken by CL 495079, which changed the behavior for os.OpenFile
and os.NewFile without intending to affect net.Conn.File.Fd.
Use a hidden os entry point to preserve the historical behavior,
to ensure backward compatibility.

For #58408
For #60211
For #60217

Change-Id: I8d14b9296070ddd52bb8940cb88c6a8b2dc28c27
Reviewed-on: https://go-review.googlesource.com/c/go/+/496080
Run-TryBot: Ian Lance Taylor <iant@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Auto-Submit: Ian Lance Taylor <iant@google.com>
(cherry picked from commit b950cc8f11)
Reviewed-on: https://go-review.googlesource.com/c/go/+/496715
2023-05-23 00:35:33 +00:00
Ian Lance Taylor
450c8021a5 [release-branch.go1.20] runtime: change fcntl to return two values
Separate the result and the errno value, rather than assuming
that the result can never be negative.

Change-Id: Ib01a70a3d46285aa77e95371cdde74e1504e7c12
Reviewed-on: https://go-review.googlesource.com/c/go/+/496416
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: Ian Lance Taylor <iant@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/497116
Run-TryBot: Roland Shoemaker <roland@golang.org>
Auto-Submit: Heschi Kreinick <heschi@google.com>
2023-05-22 21:48:39 +00:00
Ian Lance Taylor
22741120ee [release-branch.go1.20] runtime: consistently define fcntl
Clean up and consolidate on a single consistent definition of fcntl,
which takes three int32 arguments and returns either a positive result
or a negative errno value.

Change-Id: Id9505492712db4b0aab469c6bd15e4fce3c9ff6e
Reviewed-on: https://go-review.googlesource.com/c/go/+/495075
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/497115
Run-TryBot: Roland Shoemaker <roland@golang.org>
Auto-Submit: Heschi Kreinick <heschi@google.com>
2023-05-22 21:48:37 +00:00
Ian Lance Taylor
9270e3be8f [release-branch.go1.20] os: if descriptor is non-blocking, retain that in Fd method
For #58408
For #60211
Fixes #60217

Change-Id: I30f5678b46e15121865b19d1c0f82698493fad4e
Reviewed-on: https://go-review.googlesource.com/c/go/+/495079
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
(cherry picked from commit f777726ff0)
Reviewed-on: https://go-review.googlesource.com/c/go/+/496015
Reviewed-by: Heschi Kreinick <heschi@google.com>
Auto-Submit: Heschi Kreinick <heschi@google.com>
2023-05-18 19:37:57 +00:00
Filippo Valsorda
600636e931 [release-branch.go1.20] crypto/rsa: use BoringCrypto for 4096 bit keys
Updates #58803
Fixes #58927

Change-Id: I097938ff61dae2b65214f8d0126d68de63525f5b
Reviewed-on: https://go-review.googlesource.com/c/go/+/474515
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
(cherry picked from commit 7bc3281747)
Reviewed-on: https://go-review.googlesource.com/c/go/+/495735
Reviewed-by: Heschi Kreinick <heschi@google.com>
2023-05-17 14:38:17 +00:00
Keith Randall
afbe101950 [release-branch.go1.20] cmd/compile: fix bswap/load rewrite rules
When combining a byteswap and a load, the resulting combined op
must go in the load's block, not the byteswap's block, as the load
has a memory argument that might only be valid in its original block.

Fixes #59975

Change-Id: Icd84863ef3a9ca1fc22f2bb794a003f2808c746f
Reviewed-on: https://go-review.googlesource.com/c/go/+/492616
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Wayne Zuo <wdvxdr@golangcn.org>
Reviewed-by: Keith Randall <khr@google.com>
(cherry picked from commit 10141676d1)
Reviewed-on: https://go-review.googlesource.com/c/go/+/492696
2023-05-11 14:16:07 +00:00
Gopher Robot
324c3ace2d [release-branch.go1.20] go1.20.4
Change-Id: I12cd69dd6b1c7c9620738a0d89b10e0a330a3004
Reviewed-on: https://go-review.googlesource.com/c/go/+/491435
Run-TryBot: Gopher Robot <gobot@golang.org>
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Carlos Amedee <carlos@golang.org>
2023-05-02 17:21:02 +00:00
Roland Shoemaker
337dd75343 [release-branch.go1.20] html/template: emit filterFailsafe for empty unquoted attr value
An unquoted action used as an attribute value can result in unsafe
behavior if it is empty, as HTML normalization will result in unexpected
attributes, and may allow attribute injection. If executing a template
results in a empty unquoted attribute value, emit filterFailsafe
instead.

Thanks to Juho Nurminen of Mattermost for reporting this issue.

For #59722
Fixes #59816
Fixes CVE-2023-29400

Change-Id: Ia38d1b536ae2b4af5323a6c6d861e3c057c2570a
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1826631
Reviewed-by: Julie Qiu <julieqiu@google.com>
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1851494
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Roland Shoemaker <bracewell@google.com>
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/491358
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Carlos Amedee <carlos@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-05-02 16:36:15 +00:00
Roland Shoemaker
4a28cad666 [release-branch.go1.20] html/template: handle all JS whitespace characters
Rather than just a small set. Character class as defined by \s [0].

Thanks to Juho Nurminen of Mattermost for reporting this.

For #59721
Fixes #59814
Fixes CVE-2023-24540

[0] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes

Change-Id: I56d4fa1ef08125b417106ee7dbfb5b0923b901ba
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1821459
Reviewed-by: Julie Qiu <julieqiu@google.com>
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1851493
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/491356
Run-TryBot: Carlos Amedee <carlos@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-05-02 16:35:35 +00:00
Roland Shoemaker
090590fdcc [release-branch.go1.20] html/template: disallow angle brackets in CSS values
Angle brackets should not appear in CSS contexts, as they may affect
token boundaries (such as closing a <style> tag, resulting in
injection). Instead emit filterFailsafe, matching the behavior for other
dangerous characters.

Thanks to Juho Nurminen of Mattermost for reporting this issue.

For #59720
Fixes #59812
Fixes CVE-2023-24539

Change-Id: Iccc659c9a18415992b0c05c178792228e3a7bae4
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1826636
Reviewed-by: Julie Qiu <julieqiu@google.com>
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1851492
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Roland Shoemaker <bracewell@google.com>
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/491336
Run-TryBot: Carlos Amedee <carlos@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2023-05-02 16:32:02 +00:00
Damien Neil
25b4f40625 [release-branch.go1.20] Revert "net/http: FileServer method check + minimal OPTIONS implementation"
This reverts https://go.dev/cl/413554

Reason for revert: Backwards-incompatible change in behavior.

For #53501
For #59375
Fixes #59469

Change-Id: Ic3f63b378f9c819599b32e5e6e410f6163849317
Reviewed-on: https://go-review.googlesource.com/c/go/+/482635
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit c02fa75086)
Reviewed-on: https://go-review.googlesource.com/c/go/+/488635
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2023-04-25 15:50:56 +00:00
Bryan C. Mills
484535e67b cmd/compile/internal/importer,go/internal/gcimporter: use the 'go' command from build.Default.GOROOT in lookupGorootExport
Also set GOROOT explicitly in case it is set to something else in the
caller's environment.

Updates #59598.
Fixes #59637.

Change-Id: I5599ed1183b23187fc3b976786f3c320d42ef4f3
Reviewed-on: https://go-review.googlesource.com/c/go/+/484756
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Bryan Mills <bcmills@google.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
(cherry picked from commit 750e91152b)
Reviewed-on: https://go-review.googlesource.com/c/go/+/484758
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2023-04-24 18:46:00 +00:00
Tero Saarni
813a811d33 [release-branch.go1.20] crypto/tls: fix PSK binder calculation
When server and client have mismatch in curve preference, the server will
send HelloRetryRequest during TLSv1.3 PSK resumption. There was a bug
introduced by Go1.19.6 or later and Go1.20.1 or later, that makes the client
calculate the PSK binder hash incorrectly. Server will reject the TLS
handshake by sending alert: invalid PSK binder.

For #59424.
Fixes #59540.

Change-Id: I2ca8948474275740a36d991c057b62a13392dbb9
GitHub-Last-Rev: 1aad9bcf27
GitHub-Pull-Request: golang/go#59425
Reviewed-on: https://go-review.googlesource.com/c/go/+/481955
Reviewed-by: 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>
Auto-Submit: Roland Shoemaker <roland@golang.org>
(cherry picked from commit 2c70690451)
Reviewed-on: https://go-review.googlesource.com/c/go/+/488055
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
2023-04-24 18:25:14 +00:00
Matthew Dempsky
ee42d468f5 [release-branch.go1.20] cmd/compile: fix reproducible build of aliased generic types
Due to a missing "&& !alias" check, the unified linker was treating
type aliases the same as defined types for the purpose of exporting
method bodies. The methods will get exported anyway alongside the
aliased type, so this mistake is normally harmless.

However, if multiple type aliases instantiated the same generic type
but with different type arguments, this could result in the
same (generic) method body being exported multiple times under
different symbol names. Further, because bodies aren't expected to be
exported multiple times, we were sorting them simply based on index.
And consequently, the sort wasn't total and is sensitive to the map
iteration order used while ranging over linker.bodies.

The fix is simply to add the missing "&& !alias" check, so that we
don't end up with duplicate bodies in the first place.

Thanks rsc@ for providing a minimal repro case.

Fixes #59585.

Change-Id: Iaa55968cc7110b601e2f0f9b620901c2d55f7014
Reviewed-on: https://go-review.googlesource.com/c/go/+/484155
Reviewed-by: Keith Randall <khr@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
(cherry picked from commit f58c6cccc4)
Reviewed-on: https://go-review.googlesource.com/c/go/+/484160
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2023-04-24 14:06:53 +00:00
David Chase
446493f5b8 [release-branch.go1.20] cmd/compile: remove broken LEA "optimization"
CL 440035 added rewrite rules to simplify "costly" LEA
instructions, but the types in the rewrites were wrong and
the code would go bad if the wrong-typed register was spilled.

CL 482536 attempted to fix this by correcting the type in the
rewrite, but that "fix" broke something on windows-amd64-race.

Instead / for-now, remove the offending rewrite rules.

Updates #21735.
Updates #59432.
Fixes #59468.

Change-Id: I0497c42db414f2055e1378e0a53e2bceee9cd5d9
Reviewed-on: https://go-review.googlesource.com/c/go/+/482820
Run-TryBot: David Chase <drchase@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit 6a97a60b4b)
Reviewed-on: https://go-review.googlesource.com/c/go/+/482164
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
2023-04-24 13:53:18 +00:00
Keith Randall
0684cecad5 [release-branch.go1.20] cmd/compile: use correct type for byteswaps on multi-byte stores
Use the type of the store for the byteswap, not the type of the
store's value argument.

Normally when we're storing a 16-bit value, the value being stored is
also typed as 16 bits. But sometimes it is typed as something smaller,
usually because it is the result of an upcast from a smaller value,
and that upcast needs no instructions.

If the type of the store's arg is thinner than the type being stored,
and the byteswap'd value uses that thinner type, and the byteswap'd
value needs to be spilled & restored, that spill/restore happens using
the thinner type, which causes us to lose some of the top bits of the
value.

Fixes #59374

Change-Id: If6ce1e8a76f18bf8e9d79871b6caa438bc3cce4d
Reviewed-on: https://go-review.googlesource.com/c/go/+/481395
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit b3bc8620f8)
Reviewed-on: https://go-review.googlesource.com/c/go/+/483176
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2023-04-24 13:44:00 +00:00
Ian Lance Taylor
ecf7e00db8 [release-branch.go1.20] syscall: restore original NOFILE rlimit in child process
If we increased the NOFILE rlimit when starting the program,
restore the original rlimit when forking a child process.

In CL 393354 the os package was changed to raise the open file rlimit
at program start. That code is not inherently tied to the os package.
This CL moves it into the syscall package.

This is a backport of CLs 476096 and 476097 from trunk.

For #46279
Fixes #59064

Change-Id: Ib813de896de0a5d28fa2b29afdf414a89fbe7b2a
Reviewed-on: https://go-review.googlesource.com/c/go/+/478659
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
2023-04-14 17:58:41 +00:00
Junwei Zuo
1dbbac7d79 [release-branch.go1.20] cmd/compile: fix ir.StaticValue for ORANGE
Range statement will mutate the key and value, so we should treat them as reassigned.

Fixes #59580

Change-Id: I9c6b67d938760a0c6a1d9739f2737c67af4a3a10
Reviewed-on: https://go-review.googlesource.com/c/go/+/483855
Run-TryBot: Wayne Zuo <wdvxdr@golangcn.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
(cherry picked from commit 89567a35c1)
Reviewed-on: https://go-review.googlesource.com/c/go/+/484136
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
2023-04-12 20:25:12 +00:00
Cuong Manh Le
99001c460e [release-branch.go1.20] cmd/compile: don't set range expr key/value type if already set
Unified IR already records the correct type for them.

Fixes #59450

Change-Id: I275c45b48f67bde55c8e2079d60b5868d0acde7f
Reviewed-on: https://go-review.googlesource.com/c/go/+/481555
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/482655
Auto-Submit: Michael Knyszek <mknyszek@google.com>
2023-04-05 20:55:31 +00:00
Keith Randall
dcc9bdf380 [release-branch.go1.20] crypto/subtle: don't cast to *uintptr when word size is 0
Casting to a *uintptr is not ok if there isn't at least 8 bytes of
data backing that pointer (on 64-bit archs).
So although we end up making a slice of 0 length with that pointer,
the cast itself doesn't know that.
Instead, bail early if the result is going to be 0 length.

Fixes #59336

Change-Id: Id3c0e09d341d838835c0382cccfb0f71dc3dc7e6
Reviewed-on: https://go-review.googlesource.com/c/go/+/480575
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
(cherry picked from commit 297cf6dd31bd99fc4ccda320aa3d4faf290ab278)
Reviewed-on: https://go-review.googlesource.com/c/go/+/481238
Reviewed-by: Keith Randall <khr@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
2023-04-05 16:51:32 +00:00
Michael Anthony Knyszek
5c7c20e262 [release-branch.go1.20] html/template,mime/multipart: document new GODEBUG settings
This change documents the new GODEBUG settings introduced for
html/template and mime/multipart, released with Go 1.19.8 and Go 1.20.3
as part of a security fix.

Updates #59153.
For #59270.
Updates #59234.
For #59272.

Change-Id: I25f4d8245da3301dccccfb44da8ff1a5985392a4
Reviewed-on: https://go-review.googlesource.com/c/go/+/482555
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
2023-04-05 16:19:16 +00:00
Gopher Robot
7c47a6b157 [release-branch.go1.20] go1.20.3
Change-Id: I1ca3074262203c6f250c902ca087d244edf9eb96
Reviewed-on: https://go-review.googlesource.com/c/go/+/482097
TryBot-Bypass: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Gopher Robot <gobot@golang.org>
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2023-04-04 17:30:09 +00:00
Roland Shoemaker
20374d1d75 [release-branch.go1.20] html/template: disallow actions in JS template literals
ECMAScript 6 introduced template literals[0][1] which are delimited with
backticks. These need to be escaped in a similar fashion to the
delimiters for other string literals. Additionally template literals can
contain special syntax for string interpolation.

There is no clear way to allow safe insertion of actions within JS
template literals, as handling (JS) string interpolation inside of these
literals is rather complex. As such we've chosen to simply disallow
template actions within these template literals.

A new error code is added for this parsing failure case, errJsTmplLit,
but it is unexported as it is not backwards compatible with other minor
release versions to introduce an API change in a minor release. We will
export this code in the next major release.

The previous behavior (with the cavet that backticks are now escaped
properly) can be re-enabled with GODEBUG=jstmpllitinterp=1.

This change subsumes CL471455.

Thanks to Sohom Datta, Manipal Institute of Technology, for reporting
this issue.

Fixes CVE-2023-24538
For #59234
Fixes #59272

[0] https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-template-literals
[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals

Change-Id: Idff74ec386e9b73d6e9a3c9f71990eabc0ce7506
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1802457
Reviewed-by: Damien Neil <dneil@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Julie Qiu <julieqiu@google.com>
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1802688
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/481993
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
TryBot-Bypass: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2023-04-04 16:59:18 +00:00
Damien Neil
e7c4b07ecf [release-branch.go1.20] go/scanner: reject large line and column numbers in //line directives
Setting a large line or column number using a //line directive can cause
integer overflow even in small source files.

Limit line and column numbers in //line directives to 2^30-1, which
is small enough to avoid int32 overflow on all reasonbly-sized files.

Fixes CVE-2023-24537
For #59180
Fixes #59274

Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1802456
Reviewed-by: Julie Qiu <julieqiu@google.com>
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
Change-Id: Ib9c5cb38428ed34ab129d451b00a2998e72c861c
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1802401
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/481992
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
TryBot-Bypass: Michael Knyszek <mknyszek@google.com>
2023-04-04 16:59:15 +00:00
Damien Neil
bf8c7c575c [release-branch.go1.20] mime/multipart: limit parsed mime message sizes
The parsed forms of MIME headers and multipart forms can consume
substantially more memory than the size of the input data.
A malicious input containing a very large number of headers or
form parts can cause excessively large memory allocations.

Set limits on the size of MIME data:

Reader.NextPart and Reader.NextRawPart limit the the number
of headers in a part to 10000.

Reader.ReadForm limits the total number of headers in all
FileHeaders to 10000.

Both of these limits may be set with with
GODEBUG=multipartmaxheaders=<values>.

Reader.ReadForm limits the number of parts in a form to 1000.
This limit may be set with GODEBUG=multipartmaxparts=<value>.

Thanks for Jakob Ackermann (@das7pad) for reporting this issue.

For CVE-2023-24536
For #59153
For #59270

Change-Id: I36ddceead7f8292c327286fd8694e6113d3b4977
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1802455
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Julie Qiu <julieqiu@google.com>
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1802608
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/481991
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
TryBot-Bypass: Michael Knyszek <mknyszek@google.com>
2023-04-04 16:58:39 +00:00
Damien Neil
ec18f62df5 [release-branch.go1.20] net/textproto, mime/multipart: improve accounting of non-file data
For requests containing large numbers of small parts,
memory consumption of a parsed form could be about 250%
over the estimated size.

When considering the size of parsed forms, account for the size of
FileHeader structs and increase the estimate of memory consumed by
map entries.

Thanks to Jakob Ackermann (@das7pad) for reporting this issue.

For CVE-2023-24536
For #59153
For #59270

Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1802454
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Julie Qiu <julieqiu@google.com>
Change-Id: I9753aa1f8a1b1479c160f870def3b7081b6847ac
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1802399
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/481990
TryBot-Bypass: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
2023-04-04 16:58:38 +00:00
Damien Neil
ea6b5a64dd [release-branch.go1.20] mime/multipart: avoid excessive copy buffer allocations in ReadForm
When copying form data to disk with io.Copy,
allocate only one copy buffer and reuse it rather than
creating two buffers per file (one from io.multiReader.WriteTo,
and a second one from os.File.ReadFrom).

Thanks to Jakob Ackermann (@das7pad) for reporting this issue.

For CVE-2023-24536
For #59153
For #59270

Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1802453
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Julie Qiu <julieqiu@google.com>
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Change-Id: I44ef17c4b4964cdac2858317275594194801fee3
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1802398
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/481989
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2023-04-04 16:58:11 +00:00
Damien Neil
3991f6c41c [release-branch.go1.20] net/textproto: avoid overpredicting the number of MIME header keys
A parsed MIME header is a map[string][]string. In the common case,
a header contains many one-element []string slices. To avoid
allocating a separate slice for each key, ReadMIMEHeader looks
ahead in the input to predict the number of keys that will be
parsed, and allocates a single []string of that length.
The individual slices are then allocated out of the larger one.

The prediction of the number of header keys was done by counting
newlines in the input buffer, which does not take into account
header continuation lines (where a header key/value spans multiple
lines) or the end of the header block and the start of the body.
This could lead to a substantial amount of overallocation, for
example when the body consists of nothing but a large block of
newlines.

Fix header key count prediction to take into account the end of
the headers (indicated by a blank line) and continuation lines
(starting with whitespace).

Thanks to Jakob Ackermann (@das7pad) for reporting this issue.

Fixes CVE-2023-24534
For #58975
Fixes #59268

Change-Id: I0591593e67b6fdba22a32dcc3334fad797727f5c
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1802452
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Julie Qiu <julieqiu@google.com>
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1802397
Run-TryBot: Roland Shoemaker <bracewell@google.com>
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/481988
Run-TryBot: Michael Knyszek <mknyszek@google.com>
TryBot-Bypass: Michael Knyszek <mknyszek@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2023-04-04 16:58:09 +00:00
Lynn Boger
9a164d1c41 [release-branch.go1.20] cmd/internal/obj/ppc64: fix incorrect base reg causing segv
This fixes a segv that was reported due to building minio. The
problem occurred because of an incorrect selection of the
base register, which was introduced by CL 306369.

Fixes #59220

Change-Id: Ieb77b2afa8fb4e6f3943df5ce138679f6750d376
Reviewed-on: https://go-review.googlesource.com/c/go/+/479475
Reviewed-by: Archana Ravindar <aravind5@in.ibm.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Lynn Boger <laboger@linux.vnet.ibm.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
2023-03-29 19:20:02 +00:00
Keith Randall
8dce4ca8df [release-branch.go1.20] cmd/compile: don't assume pointer of a slice is non-nil
unsafe.SliceData can return pointers which are nil. That function gets
lowered to the SSA OpSlicePtr, which the compiler assumes is non-nil.
This used to be the case as OpSlicePtr was only used in situations
where the bounds check already passed. But with unsafe.SliceData that
is no longer the case.

There are situations where we know it is nil. Use Bounded() to
indicate that.

I looked through all the uses of OSPTR and added SetBounded where it
made sense. Most OSPTR results are passed directly to runtime calls
(e.g. memmove), so even if we know they are non-nil that info isn't
helpful.

Fixes #59296

Change-Id: I437a15330db48e0082acfb1f89caf8c56723fc51
Reviewed-on: https://go-review.googlesource.com/c/go/+/479896
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
(cherry picked from commit b899641ecea7d07c997282e985beb295c31d1097)
Reviewed-on: https://go-review.googlesource.com/c/go/+/479899
Run-TryBot: Keith Randall <khr@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2023-03-29 19:07:23 +00:00
Cuong Manh Le
94c02a3cc4 [release-branch.go1.20] cmd/compile: re-compile instantiated generic methods in linkshared mode
For G[T] that was seen and compiled in imported package, it is not added
to typecheck.Target.Decls, prevent wasting compile time re-creating
DUPOKS symbols. However, the linker do not support a type symbol
referencing a method symbol across DSO boundary. That causes unreachable
sym error when building under -linkshared mode.

To fix it, always re-compile generic methods in linkshared mode.

Fixes #59236

Change-Id: I894b417cfe8234ae1fe809cc975889345df22cef
Reviewed-on: https://go-review.googlesource.com/c/go/+/477375
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/c/go/+/479355
2023-03-29 18:40:30 +00:00
Geon Kim
65fa8a6931 [release-branch.go1.20] time: fix timezone lookup logic for non-DST zones
This change fixes time.LoadLocationFromTZData and time.Location.lookup logic if the given time is after the last transition and the extend string doesn't have the DST rule.

For #58682
Fixes #59075

Change-Id: Ie34a6d658d14c2b33098b29ab83c041ef0d34266
GitHub-Last-Rev: f6681eb44c
GitHub-Pull-Request: golang/go#58684
Reviewed-on: https://go-review.googlesource.com/c/go/+/471020
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@google.com>
(cherry picked from commit 90dde5dec1)
Reviewed-on: https://go-review.googlesource.com/c/go/+/478658
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Auto-Submit: Heschi Kreinick <heschi@google.com>
2023-03-23 17:51:16 +00:00
Than McIntosh
b52a6963bf [release-branch.go1.20] cmd/link/internal/arm: fix off-by-1 in trampoline reachability computation
Tweak the code in trampoline generation that determines if a given
call branch will reach, changing the lower limit guard from "x <
-0x800000" to "x <= -0x800000". This is to resolve linking failures
when the computed displacement is exactly -0x800000, which results in
errors of the form

  .../ld.gold: internal error in arm_branch_common, at ../../gold/arm.cc:4079

when using the Gold linker, and

  ...:(.text+0x...): relocation truncated to fit: R_ARM_CALL against `runtime.morestack_noctxt'

when using the bfd linker.

Fixes #59059.
Updates #59034.
Updates #58425.

Change-Id: I8a76986b38727df1b961654824c2af23f06b9fcf
Reviewed-on: https://go-review.googlesource.com/c/go/+/475957
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
(cherry picked from commit f26bf203ac)
Reviewed-on: https://go-review.googlesource.com/c/go/+/476936
2023-03-22 17:41:43 +00:00
Than McIntosh
3ff6dbdf5b [release-branch.go1.20] cmd/go,cmd/link: prefer external linking when strange cgo flags seen
This patch changes the Go command to examine the set of compiler
flags feeding into the C compiler when packages that use cgo are built.
If any of a specific set of strange/dangerous flags are in use,
then the Go command generates a token file ("preferlinkext") and
embeds it into the compiled package's archive.

When the Go linker reads the archives of the packages feeding into the
link and detects a "preferlinkext" token, it will then use external
linking for the program by default (although this default can be
overridden with an explicit "-linkmode" flag).

The intent here is to avoid having to teach the Go linker's host object
reader to grok/understand the various odd symbols/sections/types that
can result from boutique flag use, but rather to just boot the objects
in question over to the C linker instead.

Fixes #59051.
Updates #58619.
Updates #58620.
Updates #58848.

Change-Id: I56382dd305de8dac3841a7a7e664277826061eaa
Reviewed-on: https://go-review.googlesource.com/c/go/+/475375
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit 035db07d7c)
Reviewed-on: https://go-review.googlesource.com/c/go/+/476577
2023-03-17 19:45:27 +00:00
Cherry Mui
fa42da156a [release-branch.go1.20] cmd/link: use label symbols for Duff's devices on darwin/arm64
On darwin, the external linker generally supports CALL relocations
with addend. One exception is that for a very large binary when it
decides to insert a trampoline, instead of applying the addend to
the call target (in the trampoline), it applies the addend to the
CALL instruction in the caller, i.e. generating a call to
trampoline+addend, which is not the correct address and usually
points to unreloated functions.

To work around this, we use label symbols so the CALL is targeting
a label symbol without addend. To make things simple we always use
label symbols for CALLs with addend (in external linking mode on
darwin/arm64), even for small binaries.

Updates #58935.
Fixes #58954.

Change-Id: I38aed6b62a0496c277c589b5accbbef6aace8dd5
Reviewed-on: https://go-review.googlesource.com/c/go/+/474620
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
(cherry picked from commit 7dbd6de7d4)
Reviewed-on: https://go-review.googlesource.com/c/go/+/475175
2023-03-15 20:12:19 +00:00
Cherry Mui
5c7cc468a8 [release-branch.go1.20] Revert "cmd/compile: enable address folding for global symbols of shared library"
This reverts CL 445535.

Reason for revert: see issue #58826. It doesn't handle large offset well.

Updates #58826.
Fixes #58920.

Change-Id: Ic4a33f4c510c88628ea7e16207a60977a04cf798
Reviewed-on: https://go-review.googlesource.com/c/go/+/474175
Reviewed-by: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Keith Randall <khr@google.com>
(cherry picked from commit a4cf4fde46)
Reviewed-on: https://go-review.googlesource.com/c/go/+/474235
Reviewed-by: Keith Randall <khr@golang.org>
2023-03-15 20:11:23 +00:00
Bryan C. Mills
b852f39511 [release-branch.go1.20] cmd/go: avoid running slow tests on non-longtest builders
Also annotate calls to tooSlow with specific reasons.

This will somewhat reduce test coverage on the 'darwin' builders until
we have darwin 'longtest' builders (#35678,#49055), but still seems
worthwhile to avoid alert fatigue from tests that really shouldn't be
running in the short configurations.

Updates #58918.
Updates #58919.
Fixes #58938.

Change-Id: I0000f0084b262beeec3eca3e9b8a45d61fab4313
Reviewed-on: https://go-review.googlesource.com/c/go/+/474137
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit 9f532dd0de)
Reviewed-on: https://go-review.googlesource.com/c/go/+/474580
2023-03-09 22:48:51 +00:00
Heschi Kreinick
4df95d5145 [release-branch.go1.20] internal/testpty: fix error handling
When calling a c library function, you discover that an error has
occurred, typically by looking at the return value of the function. Only
after that can you use errno to figure out the cause of the error.

Nothing about cgo changes that story -- you still have to look at the
result before checking the error that represents errno. If not you can
get false errors if the function happens to leak a non-zero errno.

Fix testpty to check errors correctly.

Fixes #58942.

Change-Id: Idb95f8dd6a8ed63f653190c2e722e742cf50542b
Reviewed-on: https://go-review.googlesource.com/c/go/+/463397
Run-TryBot: Heschi Kreinick <heschi@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Auto-Submit: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit f85c282a18)
Reviewed-on: https://go-review.googlesource.com/c/go/+/474616
Reviewed-by: Carlos Amedee <carlos@golang.org>
2023-03-08 21:46:57 +00:00
Gopher Robot
aee9a19c55 [release-branch.go1.20] go1.20.2
Change-Id: Ib993bfea994a3e885a6068860d2e1f6705f8cf40
Reviewed-on: https://go-review.googlesource.com/c/go/+/474037
Auto-Submit: Gopher Robot <gobot@golang.org>
Run-TryBot: Gopher Robot <gobot@golang.org>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-03-07 16:47:18 +00:00
Matthew Dempsky
26eeaec89c [release-branch.go1.20] cmd/compile: relax overly strict assertion
The assertion here was to make sure the newly constructed and
typechecked expression selected the same receiver-qualified method,
but in the case of anonymous receiver types we can actually end up
with separate types.Field instances corresponding to each types.Type
instance. In that case, the assertion spuriously failed.

The fix here is to relax and assertion and just compare the method's
name and type (including receiver type).

Fixes #58776.

Change-Id: I67d51ddb020e6ed52671473c93fc08f283a40886
Reviewed-on: https://go-review.googlesource.com/c/go/+/471676
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit 37a2004b43)
Reviewed-on: https://go-review.googlesource.com/c/go/+/472620
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Bypass: Dmitri Shuralyov <dmitshur@google.com>
2023-03-01 22:03:12 +00:00
Roland Shoemaker
9629fa1874 [release-branch.go1.20] crypto/x509: fix broken tests
Convert TestUnknownAuthorityError to use subtests, avoiding continuing
the test after an unrecoverable failure.

Skip TestIssue51759 on pre-macOS 11 builders, which don't enforce the
behavior we were testing for. Also only enable the test on builders.

Updates #58791
Updates #58812
Fixes #58811

Change-Id: I4e3e5bc371aa139d38052184c8232f8cb564138f
Reviewed-on: https://go-review.googlesource.com/c/go/+/472496
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Roland Shoemaker <roland@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
(cherry picked from commit cf3d0655f8)
Reviewed-on: https://go-review.googlesource.com/c/go/+/472618
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2023-03-01 21:50:30 +00:00
Roland Shoemaker
3243f93747 [release-branch.go1.20] crypto/x509: fix system root tests + darwin intermediate handling
On Windows, replace tests which rely on a root that expired last year.
On Darwin fix an test which wasn't testing the expected behavior, and
fix the behavior which was broken.

Updates #58791
Fixes #58811

Change-Id: I771175b9e123b8bb0e4efdf58cc2bb93aa94fbae
Reviewed-on: https://go-review.googlesource.com/c/go/+/472295
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Roland Shoemaker <roland@golang.org>
(cherry picked from commit bb8f9a6ae6)
Reviewed-on: https://go-review.googlesource.com/c/go/+/472616
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2023-03-01 21:50:27 +00:00
Cuong Manh Le
d2d0ee2049 [release-branch.go1.20] syscall: fix invalid unsafe.Pointer conversion on Windows
Updates #58714
Fixes #58774

Change-Id: Ifa5c059ed5e358ed98aee7e83b95dd1806b535f7
Reviewed-on: https://go-review.googlesource.com/c/go/+/471335
Reviewed-by: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
(cherry picked from commit de8c999159)
Reviewed-on: https://go-review.googlesource.com/c/go/+/471599
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
2023-03-01 18:06:43 +00:00
Bryan C. Mills
230765a11a [release-branch.go1.20] net: delete TestTCPSelfConnect
This test is flaky, apparently due to a typo'd operator in CL 21447
that causes it to compare “same port OR IP” instead of
“same port AND IP”.

If we merely fixed the comparison, the test would hopefully stop being
flaky itself, but we would still be left with another problem:
repeatedly dialing a port that we believe to be unused can interfere
with other tests, which may open the previously-unused port and then
attempt a single Dial and expect it to succeed. Arbitrary other Dial
calls for that port may cause the wrong connection to be accepted,
leading to spurious test failures.

Moreover, the test can be extremely expensive for the amount of data
we hope to get from it, depending on the system's port-reuse
algorithms and dial implementations. It is already scaled back by up
to 1000x on a huge number of platforms due to latency, and may even be
ineffective on those platforms because of the arbitrary 1ms Dial
timeout. And the incremental value from it is quite low, too: it tests
the workaround for what is arguably a bug in the Linux kernel, which
ought to be fixed (and tested) upstream instead of worked around in
every open-source project that dials local ports.

Instead of trying to deflake this test, let's just get rid of it.

Updates #18290.
Fixes #58717.

Change-Id: I8a58b93d67916a33741c9ab29ef99c49c46b32c4
Reviewed-on: https://go-review.googlesource.com/c/go/+/460657
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Bryan Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
(cherry picked from commit e08642cae1)
Reviewed-on: https://go-review.googlesource.com/c/go/+/471155
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2023-03-01 18:01:03 +00:00
Roland Shoemaker
bdd86bda09 [release-branch.go1.20] crypto/x509: fix ParsePKCS8PrivateKey comment
Updates #58789.
Fixes #58793.

Change-Id: I91cdd20c6d4f05baaacd6a38717aa7bed6682573
Reviewed-on: https://go-review.googlesource.com/c/go/+/472155
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Roland Shoemaker <roland@golang.org>
Auto-Submit: Roland Shoemaker <roland@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
(cherry picked from commit ec26277aec)
Reviewed-on: https://go-review.googlesource.com/c/go/+/472415
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Bypass: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2023-03-01 17:28:55 +00:00
Kir Kolyshkin
aef8a8cd42 [release-branch.go1.20] syscall: Faccessat: check for CAP_DAC_OVERRIDE on Linux
CL 416115 added using faccessat2(2) from syscall.Faccessat on Linux
(which is the only true way to implement AT_EACCESS flag handing),
if available. If not available, it uses some heuristics to mimic the
kernel behavior, mostly taken from glibc (see CL 126415).

Next, CL 414824 added using the above call (via unix.Eaccess) to
exec.LookPath in order to check if the binary can really be executed.

As a result, in a very specific scenario, described below,
syscall.Faccessat (and thus exec.LookPath) mistakenly tells that the
binary can not be executed, while in reality it can be. This makes
this bug a regression in Go 1.20.

This scenario involves all these conditions:
 - no faccessat2 support available (i.e. either Linux kernel < 5.8,
   or a seccomp set up to disable faccessat2);
 - the current user is not root (i.e. geteuid() != 0);
 - CAP_DAC_OVERRIDE capability is set for the current process;
 - the file to be executed does not have executable permission
   bit set for either the current EUID or EGID;
 - the file to be executed have at least one executable bit set.

Unfortunately, this set of conditions was observed in the wild -- a
container run as a non-root user with the binary file owned by root with
executable permission set for a user only [1]. Essentially it means it
is not as rare as it may seem.

Now, CAP_DAC_OVERRIDE essentially makes the kernel bypass most of the
checks, so execve(2) and friends work the same was as for root user,
i.e. if at least one executable bit it set, the permission to execute
is granted (see generic_permission() function in the Linux kernel).

Modify the code to check for CAP_DAC_OVERRIDE and mimic the kernel
behavior for permission checks.

[1] https://github.com/opencontainers/runc/issues/3715

For #58552.
Fixes #58624.

Change-Id: I82a7e757ab3fd3d0193690a65c3b48fee46ff067
Reviewed-on: https://go-review.googlesource.com/c/go/+/468735
Reviewed-by: Damien Neil <dneil@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>
Reviewed-by: Ian Lance Taylor <iant@google.com>
(cherry picked from commit 031401a790)
Reviewed-on: https://go-review.googlesource.com/c/go/+/469956
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2023-02-28 12:45:13 +00:00
Filippo Valsorda
ef793801f8 [release-branch.go1.20] crypto/internal/bigmod: flag amd64 assembly as noescape
I had forgotten, which caused amd64 allocations to go back up
significantly. Added an allocations test.

name                    old time/op    new time/op    delta
DecryptPKCS1v15/2048-8    1.50ms ± 0%    1.48ms ± 0%   -0.95%  (p=0.000 n=9+10)
DecryptPKCS1v15/3072-8    4.64ms ± 1%    4.60ms ± 0%   -0.82%  (p=0.000 n=8+10)
DecryptPKCS1v15/4096-8    10.7ms ± 0%    10.6ms ± 1%   -0.99%  (p=0.000 n=10+10)
EncryptPKCS1v15/2048-8     158µs ± 0%     157µs ± 0%   -0.63%  (p=0.000 n=10+10)
DecryptOAEP/2048-8        1.50ms ± 0%    1.48ms ± 0%   -1.09%  (p=0.000 n=9+10)
EncryptOAEP/2048-8         161µs ± 0%     160µs ± 0%   -0.34%  (p=0.000 n=9+10)
SignPKCS1v15/2048-8       1.55ms ± 0%    1.53ms ± 1%   -1.32%  (p=0.000 n=10+10)
VerifyPKCS1v15/2048-8      157µs ± 0%     157µs ± 0%   -0.33%  (p=0.004 n=9+10)
SignPSS/2048-8            1.55ms ± 0%    1.54ms ± 0%   -1.14%  (p=0.000 n=10+10)
VerifyPSS/2048-8           160µs ± 0%     160µs ± 0%   -0.32%  (p=0.000 n=10+10)

name                    old alloc/op   new alloc/op   delta
DecryptPKCS1v15/2048-8    15.0kB ± 0%     0.6kB ± 0%  -95.74%  (p=0.000 n=10+10)
DecryptPKCS1v15/3072-8    17.9kB ± 0%     3.5kB ± 0%  -80.65%  (p=0.000 n=10+10)
DecryptPKCS1v15/4096-8    19.1kB ± 0%     4.7kB ± 0%  -75.25%  (p=0.000 n=10+10)
EncryptPKCS1v15/2048-8    7.51kB ± 0%    1.17kB ± 0%  -84.39%  (p=0.000 n=10+10)
DecryptOAEP/2048-8        15.3kB ± 0%     0.9kB ± 0%  -94.29%  (p=0.000 n=10+10)
EncryptOAEP/2048-8        7.74kB ± 0%    1.40kB ± 0%  -81.86%  (p=0.000 n=10+10)
SignPKCS1v15/2048-8       21.6kB ± 0%     0.9kB ± 0%  -95.86%  (p=0.000 n=10+10)
VerifyPKCS1v15/2048-8     7.25kB ± 0%    0.91kB ± 0%  -87.42%  (p=0.000 n=10+10)
SignPSS/2048-8            22.0kB ± 0%     1.3kB ± 0%  -94.12%  (p=0.000 n=10+10)
VerifyPSS/2048-8          7.46kB ± 0%    1.12kB ± 0%  -84.98%  (p=0.000 n=10+10)

name                    old allocs/op  new allocs/op  delta
DecryptPKCS1v15/2048-8      54.0 ± 0%       4.0 ± 0%  -92.59%  (p=0.000 n=10+10)
DecryptPKCS1v15/3072-8      60.0 ± 0%      10.0 ± 0%  -83.33%  (p=0.000 n=10+10)
DecryptPKCS1v15/4096-8      60.0 ± 0%      10.0 ± 0%  -83.33%  (p=0.000 n=10+10)
EncryptPKCS1v15/2048-8      29.0 ± 0%       7.0 ± 0%  -75.86%  (p=0.000 n=10+10)
DecryptOAEP/2048-8          60.0 ± 0%      10.0 ± 0%  -83.33%  (p=0.000 n=10+10)
EncryptOAEP/2048-8          35.0 ± 0%      13.0 ± 0%  -62.86%  (p=0.000 n=10+10)
SignPKCS1v15/2048-8         77.0 ± 0%       5.0 ± 0%  -93.51%  (p=0.000 n=10+10)
VerifyPKCS1v15/2048-8       28.0 ± 0%       6.0 ± 0%  -78.57%  (p=0.000 n=10+10)
SignPSS/2048-8              82.0 ± 0%      10.0 ± 0%  -87.80%  (p=0.000 n=10+10)
VerifyPSS/2048-8            33.0 ± 0%      11.0 ± 0%  -66.67%  (p=0.000 n=10+10)

Updates #58501.
Fixes #58505.

Change-Id: I418c5152833787b80220b556336ec284674c2493
Reviewed-on: https://go-review.googlesource.com/c/go/+/460542
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
(cherry picked from commit ed370d8720)
Reviewed-on: https://go-review.googlesource.com/c/go/+/471855
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2023-02-28 01:46:28 +00:00
Roland Shoemaker
aaace6dda7 [release-branch.go1.20] crypto/ecdh: explicitly reject mismatched curves in ECDH
Return an explicit error when PrivateKey.ECDH is called with a PublicKey
which uses a different Curve. Also document this requirement, even
though it is perhaps obvious.

Updates #58131.
Fixes #58498.

Change-Id: I739181a3f1283bed14fb5ee7eb78658b854d28d8
Reviewed-on: https://go-review.googlesource.com/c/go/+/464335
Reviewed-by: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Auto-Submit: Roland Shoemaker <roland@golang.org>
Run-TryBot: Roland Shoemaker <roland@golang.org>
(cherry picked from commit 67d8916d55)
Reviewed-on: https://go-review.googlesource.com/c/go/+/471602
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
2023-02-28 01:46:26 +00:00
Matthew Dempsky
0f4483cfdc [release-branch.go1.20] cmd/compile/internal/noder: correct positions for synthetic closures
When inlining functions that contain function literals, we need to be
careful about position information. The OCLOSURE node should use the
inline-adjusted position, but the ODCLFUNC and its body should use the
original positions.

However, the same problem can arise with certain generic constructs,
which require the compiler to synthesize function literals to insert
dictionary arguments.

go.dev/cl/425395 fixed the issue with user-written function literals
in a somewhat kludgy way; this CL extends the same solution to
synthetic function literals.

This is all quite subtle and the solutions aren't terribly robust, so
longer term it's probably desirable to revisit how we track inlining
context for positions. But for now, this seems to be the least bad
solution, esp. for backporting to 1.20.

Updates #54625.
Fixes #58531.

Change-Id: Icc43a70dbb11a0e665cbc9e6a64ef274ad8253d1
Reviewed-on: https://go-review.googlesource.com/c/go/+/468415
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
(cherry picked from commit 873c14cec730ee278848f7cc58d2b4d89ab52288)
Reviewed-on: https://go-review.googlesource.com/c/go/+/471677
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2023-02-28 00:07:00 +00:00
Than McIntosh
1362737f50 [release-branch.go1.20] cmd/link: better fix for arm32 trampgen problem with duff routines
This patch provides a fix for a problem linking large arm32 binaries
with external linking, specifically R_CALLARM relocations against
runtime.duff* routines being flagged by the external linker as not
reaching.

What appears to be happening in the bug in question is that the Go
linker and the external linker are using slightly different recipes to
decide whether a given R_CALLARM relocation will "fit" (e.g. will not
require a trampoline). The Go linker is taking into account the addend
on the call reloc (which for calls to runtime.duffcopy or
runtime.duffzero is nonzero), whereas the external linker appears to
be ignoring the addend.

Example to illustrate:

   Addr      Size   Func
   -----     -----  -----
   ...
   XYZ       1024   runtime.duffcopy
   ...
   ABC       ...    mypackge.MyFunc
     + R0: R_CALLARM  o=8 a=848 tgt=runtime.duffcopy<0>

Let's say that the distance between ABC (start address of
runtime.duffcopy) and XYZ (start of MyFunc) is just over the
architected 24-bit maximum displacement for an R_CALLARM (let's say
that ABC-XYZ is just over the architected limit by some small value,
say 36). Because we're calling into runtime.duffcopy at offset 848,
however, the relocation does in fact fit, but if the external linker
isn't taking into account the addend (assuming that all calls target
the first instruction of the called routine), then we'll get a
"doesn't fit" error from the linker.

To work around this problem, revise the ARM trampoline generation code
in the Go linker that computes the trampoline threshold to ignore the
addend on R_CALLARM relocations, so as to harmonize the two linkers.

Fixes #58503.
Updates #58428.
Updates #58425.

Change-Id: I56e580c05b7b47bbe8edf5532a1770bbd700fbe5
Reviewed-on: https://go-review.googlesource.com/c/go/+/469275
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
(cherry picked from commit 0b5affb193)
Reviewed-on: https://go-review.googlesource.com/c/go/+/471597
2023-02-27 19:59:34 +00:00
Filippo Valsorda
602eeaab38 [release-branch.go1.20] crypto/internal/nistec: reduce P-256 scalar
Unlike the rest of nistec, the P-256 assembly doesn't use complete
addition formulas, meaning that p256PointAdd[Affine]Asm won't return the
correct value if the two inputs are equal.

This was (undocumentedly) ignored in the scalar multiplication loops
because as long as the input point is not the identity and the scalar is
lower than the order of the group, the addition inputs can't be the same.

As part of the math/big rewrite, we went however from always reducing
the scalar to only checking its length, under the incorrect assumption
that the scalar multiplication loop didn't require reduction.

Added a reduction, and while at it added it in P256OrdInverse, too, to
enforce a universal reduction invariant on p256OrdElement values.

Note that if the input point is the infinity, the code currently still
relies on undefined behavior, but that's easily tested to behave
acceptably, and will be addressed in a future CL.

Updates #58647
Fixes #58720
Fixes CVE-2023-24532

(Filed with the "safe APIs like complete addition formulas are good" dept.)

Change-Id: I7b2c75238440e6852be2710fad66ff1fdc4e2b24
Reviewed-on: https://go-review.googlesource.com/c/go/+/471255
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
(cherry picked from commit 203e59ad41)
Reviewed-on: https://go-review.googlesource.com/c/go/+/471695
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Roland Shoemaker <roland@golang.org>
2023-02-27 18:47:07 +00:00
Than McIntosh
ac556f35a2 [release-branch.go1.20] cmd/internal/cov: fix misuse of bufio.Reader.Read in read helper
Fix a misuse of bufio.Reader.Read in the helper class
cmd/internal/cov.MReader; the MReader method in question should have
been using io.ReadFull (passing the bufio.Reader) instead of directly
calling Read.

Using the Read method instead of io.ReadFull will result in a "short"
read when processing a specific subset of counter data files, e.g.
those that are short enough to not trigger the mmap-based scheme we
use for larger files, but also with a large args section (something
large enough to exceed the default 4k buffer size used by
bufio.Reader).

Along the way, add some additional defered Close() calls for files
opened by the CovDataReader.visitPod, to enure we don't leave any open
file descriptor following a call to CovDataReader.Visit.

Fixes #58427.
Updates #58411.

Change-Id: Iea48dc25c0081be1ade29f3a633df02a681fd941
Reviewed-on: https://go-review.googlesource.com/c/go/+/466677
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
(cherry picked from commit a7fe9ada10)
Reviewed-on: https://go-review.googlesource.com/c/go/+/468536
Reviewed-by: Cherry Mui <cherryyz@google.com>
2023-02-22 20:38:53 +00:00
Ian Lance Taylor
1acd39cc92 [release-branch.go1.20] Revert "internal/poll: drop redundant ENOSYS in CopyFileRange"
This reverts CL 428555.

Reason for revert: It appears that even a newer kernel can get
ENOSYS from copy_file_range.

For #58592
Fixes #58627

Change-Id: Ib8dd1be61544f54bf652a99dc0b449109f8f50ed
Reviewed-on: https://go-review.googlesource.com/c/go/+/470316
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-02-22 20:35:23 +00:00
Michael Anthony Knyszek
7b398b1ff7 [release-branch.go1.20] runtime: check for overflow in sweep assist
The sweep assist computation is intentionally racy for performance,
since the specifics of sweep assist aren't super sensitive to error.
However, if overflow occurs when computing the live heap delta, we can
end up with a massive sweep target that causes the sweep assist to sweep
until sweep termination, causing severe latency issues. In fact, because
heapLive doesn't always increase monotonically then anything that
flushes mcaches will cause _all_ allocating goroutines to inevitably get
stuck in sweeping.

Consider the following scenario:
1. SetGCPercent is called, updating sweepHeapLiveBasis to heapLive.
2. Very shortly after, ReadMemStats is called, flushing mcaches and
   decreasing heapLive below the value sweepHeapLiveBasis was set to.
3. Every allocating goroutine goes to refill its mcache, calls into
   deductSweepCredit for sweep assist, and gets stuck sweeping until
   the sweep phase ends.

Fix this by just checking for overflow in the delta live heap calculation
and if it would overflow, pick a small delta live heap. This probably
means that no sweeping will happen at all, but that's OK. This is a
transient state and the runtime will recover as soon as heapLive
increases again.

Note that deductSweepCredit doesn't check overflow on other operations
but that's OK: those operations are signed and extremely unlikely to
overflow. The subtraction targeted by this CL is only a problem because
it's unsigned. An alternative fix would be to make the operation signed,
but being explicit about the overflow situation seems worthwhile.

For #57523.
Fixes #58536.

Change-Id: Ib18f71f53468e913548aac6e5358830c72ef0215
Reviewed-on: https://go-review.googlesource.com/c/go/+/468375
Reviewed-by: Michael Pratt <mpratt@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-02-15 21:52:31 +00:00
Cuong Manh Le
2d01f3695b [release-branch.go1.20] cmd/compile: fix wrong escape analysis for go/defer generic calls
For go/defer calls like "defer f(x, y)", the compiler rewrites it to:

	x1, y1 := x, y
	defer func() { f(x1, y1) }()

However, if "f" needs runtime type information, the "RType" field will
refer to the outer ".dict" param, causing wrong liveness analysis.

To fix this, if "f" refers to outer ".dict", the dict param will be
copied to an autotmp, and "f" will refer to this autotmp instead.

Fixes #58467

Change-Id: I238b6e75441442b5540d39bc818205398e80c94d
Reviewed-on: https://go-review.googlesource.com/c/go/+/466035
Reviewed-by: David Chase <drchase@google.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/c/go/+/467935
Reviewed-by: Michael Pratt <mpratt@google.com>
2023-02-15 21:46:55 +00:00
Cuong Manh Le
965e9ba0fb [release-branch.go1.20] cmd/compile: disable inline static init optimization
There are a plenty of regression in 1.20 with this optimization. This CL
disable inline static init, so it's safer to backport to 1.20 branch.

The optimization will be enabled again during 1.21 cycle.

Fixes #58444

Change-Id: If5916008597b46146b4dc7108c6b389d53f35e95
Reviewed-on: https://go-review.googlesource.com/c/go/+/467015
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/467035
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
2023-02-15 21:45:58 +00:00
Adin Scannell
85ded85b78 [release-branch.go1.20] runtime: fix signature for linked functions
These functions are linked using go:linkname, but do not match the
original declarations. This change brings these in sync.

For #58442.

Change-Id: I16651304c3dba2f9897c2c42e30555d2f7805c2a
Reviewed-on: https://go-review.googlesource.com/c/go/+/466615
Reviewed-by: Michael Pratt <mpratt@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Michael Pratt <mpratt@google.com>
(cherry picked from commit 8fb9565832)
Reviewed-on: https://go-review.googlesource.com/c/go/+/466859
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Austin Clements <austin@google.com>
2023-02-15 21:45:24 +00:00
Michael Pratt
828b05cc64 [release-branch.go1.20] all: update vendored golang.org/x/net
Update golang.org/x/net to the tip of internal-branch.go1.20-vendor to
include CL 468336.

The contents of that CL were already merged into this branch in CL
468122, so this CL just brings go.mod back in line to matching the
actual vendored content.

For #58356
For #57855

Change-Id: I6ee9483077630c11c725927f38f6b69a784106db
Reviewed-on: https://go-review.googlesource.com/c/go/+/468302
Run-TryBot: Michael Pratt <mpratt@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
2023-02-14 20:55:09 +00:00
Gopher Robot
202a1a5706 [release-branch.go1.20] go1.20.1
Change-Id: I6a40cdd44d7bc7e4bf95a5169ecad16757eb41d3
Reviewed-on: https://go-review.googlesource.com/c/go/+/468238
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
Run-TryBot: Gopher Robot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-02-14 18:12:19 +00:00
Roland Shoemaker
8e02cffd8e [release-branch.go1.20] net/http: update bundled golang.org/x/net/http2
Disable cmd/internal/moddeps test, since this update includes PRIVATE
track fixes.

Fixes CVE-2022-41723
Fixes #58356
Updates #57855

Change-Id: I603886b5b76c16303dab1420d4ec8b7c7cdcf330
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1728940
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Julie Qiu <julieqiu@google.com>
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/468122
Auto-Submit: Michael Pratt <mpratt@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Michael Pratt <mpratt@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
2023-02-14 17:25:55 +00:00
Roland Shoemaker
5286ac4ed8 [release-branch.go1.20] crypto/tls: replace all usages of BytesOrPanic
Message marshalling makes use of BytesOrPanic a lot, under the
assumption that it will never panic. This assumption was incorrect, and
specifically crafted handshakes could trigger panics. Rather than just
surgically replacing the usages of BytesOrPanic in paths that could
panic, replace all usages of it with proper error returns in case there
are other ways of triggering panics which we didn't find.

In one specific case, the tree routed by expandLabel, we replace the
usage of BytesOrPanic, but retain a panic. This function already
explicitly panicked elsewhere, and returning an error from it becomes
rather painful because it requires changing a large number of APIs.
The marshalling is unlikely to ever panic, as the inputs are all either
fixed length, or already limited to the sizes required. If it were to
panic, it'd likely only be during development. A close inspection shows
no paths for a user to cause a panic currently.

This patches ends up being rather large, since it requires routing
errors back through functions which previously had no error returns.
Where possible I've tried to use helpers that reduce the verbosity
of frequently repeated stanzas, and to make the diffs as minimal as
possible.

Thanks to Marten Seemann for reporting this issue.

Updates #58001
Fixes #58359
Fixes CVE-2022-41724

Change-Id: Ieb55867ef0a3e1e867b33f09421932510cb58851
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1679436
Reviewed-by: Julie Qiu <julieqiu@google.com>
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
(cherry picked from commit 1d4e6ca9454f6cf81d30c5361146fb5988f1b5f6)
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1728205
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/468121
Reviewed-by: Than McIntosh <thanm@google.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
TryBot-Bypass: Michael Pratt <mpratt@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
2023-02-14 17:25:50 +00:00
Damien Neil
53b43607d9 [release-branch.go1.20] mime/multipart: limit memory/inode consumption of ReadForm
Reader.ReadForm is documented as storing "up to maxMemory bytes + 10MB"
in memory. Parsed forms can consume substantially more memory than
this limit, since ReadForm does not account for map entry overhead
and MIME headers.

In addition, while the amount of disk memory consumed by ReadForm can
be constrained by limiting the size of the parsed input, ReadForm will
create one temporary file per form part stored on disk, potentially
consuming a large number of inodes.

Update ReadForm's memory accounting to include part names,
MIME headers, and map entry overhead.

Update ReadForm to store all on-disk file parts in a single
temporary file.

Files returned by FileHeader.Open are documented as having a concrete
type of *os.File when a file is stored on disk. The change to use a
single temporary file for all parts means that this is no longer the
case when a form contains more than a single file part stored on disk.

The previous behavior of storing each file part in a separate disk
file may be reenabled with GODEBUG=multipartfiles=distinct.

Update Reader.NextPart and Reader.NextRawPart to set a 10MiB cap
on the size of MIME headers.

Thanks to Jakob Ackermann (@das7pad) for reporting this issue.

Updates #58006
Fixes #58363
Fixes CVE-2022-41725

Change-Id: Ibd780a6c4c83ac8bcfd3cbe344f042e9940f2eab
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1714276
Reviewed-by: Julie Qiu <julieqiu@google.com>
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
(cherry picked from commit 7d0da0029bfbe3228cc5216ced8c7b3184eb517d)
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1728950
Reviewed-by: Damien Neil <dneil@google.com>
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/468120
Auto-Submit: Michael Pratt <mpratt@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-02-14 16:58:51 +00:00
Damien Neil
bdf07c2e16 [release-branch.go1.20] path/filepath: do not Clean("a/../c:/b") into c:\b on Windows
Do not permit Clean to convert a relative path into one starting
with a drive reference. This change causes Clean to insert a .
path element at the start of a path when the original path does not
start with a volume name, and the first path element would contain
a colon.

This may introduce a spurious but harmless . path element under
some circumstances. For example, Clean("a/../b:/../c") becomes `.\c`.

This reverts CL 401595, since the change here supersedes the one
in that CL.

Thanks to RyotaK (https://twitter.com/ryotkak) for reporting this issue.

Updates #57274
Fixes #57276
Fixes CVE-2022-41722

Change-Id: I837446285a03aa74c79d7642720e01f354c2ca17
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1675249
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Julie Qiu <julieqiu@google.com>
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
(cherry picked from commit 8ca37f4813ef2f64600c92b83f17c9f3ca6c03a5)
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1728944
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/468119
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Michael Pratt <mpratt@google.com>
2023-02-14 16:58:49 +00:00
Frederic Branczyk
3a04b6e12e [release-branch.go1.20] cmd/compile/internal/pgo: fix hard-coded PGO sample data position
This patch detects at which index position profiling samples that have
the value-type samples count are, instead of the previously hard-coded
position of index 1. Runtime generated profiles always generate CPU
profiling data with the 0 index being CPU nanoseconds, and samples count
at index 1, which is why this previously hasn't come up.

This is a redo of CL 465135, now allowing empty profiles. Note that
preprocessProfileGraph will already cause pgo.New to return nil for
empty profiles.

For #58292
For #58309

Change-Id: Ia6c94f0793f6ca9b0882b5e2c4d34f38e600c1e3
Reviewed-on: https://go-review.googlesource.com/c/go/+/467375
Run-TryBot: Michael Pratt <mpratt@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
2023-02-10 19:24:45 +00:00
Bryan C. Mills
00f5d3001a [release-branch.go1.20] cmd/go/internal/script: retry ETXTBSY errors in scripts
Fixes #58431.
Updates #58019.

Change-Id: Ib25d668bfede6e87a3786f44bdc0db1027e3ebec
Reviewed-on: https://go-review.googlesource.com/c/go/+/463748
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
(cherry picked from commit 23c0121e4e)
Reviewed-on: https://go-review.googlesource.com/c/go/+/466856
Reviewed-by: David Chase <drchase@google.com>
2023-02-10 17:48:14 +00:00
Bryan C. Mills
7628627cb2 [release-branch.go1.20] cmd/go/internal/test: refresh flagdefs.go and fix test
The tests for cmd/go/internal/test were not running at all due to a
missed call to m.Run in TestMain. That masked a missing vet analyzer
("timeformat") and a missed update to the generator script in
CL 355452.

Fixes #58421.
Updates #58415.

Change-Id: I7b0315952967ca07a866cdaa5903478b2873eb7a
Reviewed-on: https://go-review.googlesource.com/c/go/+/466635
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
(cherry picked from commit 910f041ff0)
Reviewed-on: https://go-review.googlesource.com/c/go/+/466855
2023-02-10 17:41:09 +00:00
Bryan C. Mills
1fa2deb1b1 [release-branch.go1.20] cmd/go: remove tests that assume lack of new versions of external modules
In general it seems ok to assume that an open-source module that did
exist will continue to do so — after all, users of open-source modules
already do that all the time. However, we should not assume that those
modules do not publish new versions — that's really up to their
maintainers to decide.

Two existing tests did make that assumption for the module
gopkg.in/natefinch/lumberjack.v2. Let's remove those two tests.
If we need to replace them at some point, we can replace them with
hermetic test-only modules (#54503) or perhaps modules owned by the Go
project.

Updates #58445.
Fixes #58450.

Change-Id: Ica8fe587d86fc41f3d8445a4cd2b8820455ae45f
Reviewed-on: https://go-review.googlesource.com/c/go/+/466861
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: David Chase <drchase@google.com>
2023-02-10 17:29:40 +00:00
Russ Cox
a943fd0ccc [release-branch.go1.20] runtime: skip darwin osinit_hack on ios
Darwin needs the osinit_hack call to fix some bugs in the Apple libc
that surface when Go programs call exec. On iOS, the functions that
osinit_hack uses are not available, so signing fails. But on iOS exec
is also unavailable, so the hack is not needed. Disable it there,
which makes signing work again.

Fixes #58323.
Fixes #58419.

Change-Id: I3f1472f852bb36c06854fe1f14aa27ad450c5945
Reviewed-on: https://go-review.googlesource.com/c/go/+/466516
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Dave Anderson <danderson@tailscale.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Russ Cox <rsc@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/467316
2023-02-10 17:19:24 +00:00
Russ Cox
fbba58a0a4 [release-branch.go1.20] cmd/link: keep go.buildinfo even with --gc-sections
If you use an external linker with --gc-sections, nothing refers
to .go.buildinfo, so the section is deleted, which in turns makes
'go version' fail on the binary. It is important for vulnerability
scanning and the like to be able to run 'go version' on any binary.

Fix this by inserting a reference to .go.buildinfo from the rodata
section, which will not be GC'ed.

Fixes #58222.
Fixes #58224.

Change-Id: I1e13e9464acaf2f5cc5e0b70476fa52b43651123
Reviewed-on: https://go-review.googlesource.com/c/go/+/464435
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Auto-Submit: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/c/go/+/464796
2023-02-10 17:19:20 +00:00
qmuntal
9987cb6cf3 [release-branch.go1.20] time: update windows zoneinfo_abbrs
zoneinfo_abbrs hasn't been updated since go 1.14, it's time to
regenerate it.

Fixes #58117.

Change-Id: Ic156ae607c46f1f5a9408b1fc0b56de6c14a4ed4
Reviewed-on: https://go-review.googlesource.com/c/go/+/463838
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Run-TryBot: Quim Muntal <quimmuntal@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
(cherry picked from commit 007d8f4db1)
Reviewed-on: https://go-review.googlesource.com/c/go/+/466436
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Quim Muntal <quimmuntal@gmail.com>
Run-TryBot: David Chase <drchase@google.com>
2023-02-09 18:01:32 +00:00
Matthew Dempsky
90b06002c4 [release-branch.go1.20] cmd/compile/internal/noder: stop creating TUNION types
In the types1 universe under the unified frontend, we never need to
worry about type parameter constraints, so we only see pure
interfaces. However, we might still see interfaces that contain union
types, because of interfaces like "interface{ any | int }" (equivalent
to just "any").

We can handle these without needing to actually represent type unions
within types1 by simply mapping any union to "any".

Fixes #58413.

Change-Id: I5e4efcf0339edbb01f4035c54fb6fb1f9ddc0c65
Reviewed-on: https://go-review.googlesource.com/c/go/+/458619
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
(cherry picked from commit a7de684e1b)
Reviewed-on: https://go-review.googlesource.com/c/go/+/466435
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: David Chase <drchase@google.com>
2023-02-09 18:01:12 +00:00
Cuong Manh Le
487be3f90b [release-branch.go1.20] cmd/compile: fix inline static init arguments substitued tree
Blank node must be ignored when building arguments substitued tree.
Otherwise, it could be used to replace other blank node in left hand
side of an assignment, causing an invalid IR node.

Consider the following code:

	type S1 struct {
		s2 S2
	}

	type S2 struct{}

	func (S2) Make() S2 {
		return S2{}
	}

	func (S1) Make() S1 {
		return S1{s2: S2{}.Make()}
	}

	var _ = S1{}.Make()

After staticAssignInlinedCall, the assignment becomes:

	var _ = S1{s2: S2{}.Make()}

and the arg substitued tree is "map[*ir.Name]ir.Node{_: S1{}}". Now,
when doing static assignment, if there is any assignment to blank node,
for example:

	_ := S2{}

That blank node will be replaced with "S1{}":

	S1{} := S2{}

So constructing an invalid IR which causes the ICE.

Fixes #58335

Change-Id: I21b48357f669a7e02a7eb4325246aadc31f78fb9
Reviewed-on: https://go-review.googlesource.com/c/go/+/465098
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/466275
Reviewed-by: Than McIntosh <thanm@google.com>
2023-02-09 17:29:22 +00:00
Cuong Manh Le
7302f83d87 [release-branch.go1.20] cmd/compile: remove constant arithmetic overflows during typecheck
Since go1.19, these errors are already reported by types2 for any user's
Go code. Compiler generated code, which looks like constant expression
should be evaluated as non-constant semantic, which allows overflows.

Fixes #58319

Change-Id: I6f0049a69bdb0a8d0d7a0db49c7badaa92598ea2
Reviewed-on: https://go-review.googlesource.com/c/go/+/466676
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
2023-02-09 17:09:03 +00:00
Gopher Robot
de4748c47c [release-branch.go1.20] go1.20
Change-Id: I156873d216ccb7d91e716b4348069df246b527b3
Reviewed-on: https://go-review.googlesource.com/c/go/+/464496
Run-TryBot: Gopher Robot <gobot@golang.org>
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
2023-02-01 19:03:46 +00:00
Than McIntosh
52bd3b186b [release-branch.go1.20] internal/coverage/decodemeta: fix coding error in func literal handling
Fix a coding error in coverage meta-data decoding in the method
decodemeta.CoverageMetaDataDecoder.ReadFunc. The code was not
unconditionally assigning the "function literal" field of the
coverage.FuncDesc object passed in, resulting in bad values depending
on what the state of the field happened to be in the object.

Fixes #57942.

Change-Id: I6dfd7d7f7af6004f05c622f9a7116e9f6018cf4f
Reviewed-on: https://go-review.googlesource.com/c/go/+/462955
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
(cherry picked from commit 620399ef0d)
Reviewed-on: https://go-review.googlesource.com/c/go/+/463418
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
2023-01-26 23:27:53 +00:00
Than McIntosh
be7e4fee4b [release-branch.go1.20] runtime/coverage: avoid non-test coverage profiles in test report helper
When walking through the set of coverage data files generated from a
"go test -cover" run, it's possible to encounter pods (clumps of data
files) that were generated by a run from an instrumented Go tool (for
example, cmd/compile). Add a guard to the test reporting code to
ensure that it only processes files created by the currently running
test.

Fixes #57924.

Change-Id: I1bb7dce88305e1088162e3cb1df628486ecee1c1
Reviewed-on: https://go-review.googlesource.com/c/go/+/462756
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
(cherry picked from commit cf70d37967)
Reviewed-on: https://go-review.googlesource.com/c/go/+/463417
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
2023-01-26 23:27:43 +00:00
Changkun Ou
b68d699aa7 [release-branch.go1.20] sync: document memory model for Swap/CompareAnd{Swap,Delete} in Map
CL 381316 documented the memory model of Map's APIs. However, the newly
introduced Swap, CompareAndSwap, and CompareAndDelete are missing from
this documentation as CL 399094 did not add this info.

This CL specifies the defined read/write operations of the new Map APIs.

For #51972

Change-Id: I519a04040a0b429a3f978823a183cd62e42c90ae
Reviewed-on: https://go-review.googlesource.com/c/go/+/459715
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Changkun Ou <mail@changkun.de>
Auto-Submit: Bryan Mills <bcmills@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
(cherry picked from commit f07910bd57)
Reviewed-on: https://go-review.googlesource.com/c/go/+/463416
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Changkun Ou <mail@changkun.de>
2023-01-25 19:53:59 +00:00
Keith Randall
10124c2631 [release-branch.go1.20] Revert "cmd/compile: teach prove about bitwise OR operation"
This reverts commit 3680b5e9c4.

Reason for revert: causes long compile times on certain functions. See issue #57959

Change-Id: Ie9e881ca8abbc79a46de2bfeaed0b9d6c416ed42
Reviewed-on: https://go-review.googlesource.com/c/go/+/463295
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
(cherry picked from commit a6ddb15f8f)
Reviewed-on: https://go-review.googlesource.com/c/go/+/463415
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@google.com>
2023-01-25 18:41:55 +00:00
Joe Tsai
5adb0ca8e9 [release-branch.go1.20] time: revert strict parsing of RFC 3339
CL 444277 fixed Time.UnmarshalText and Time.UnmarshalJSON to properly
unmarshal timestamps according to RFC 3339 instead of according
to Go's bespoke time syntax that is a superset of RFC 3339.

However, this change seems to have broken an AWS S3 unit test
that relies on parsing timestamps with single digit hours.
It is unclear whether S3 emits these timestamps in production or
whether this is simply a testing artifact that has been cargo culted
across many code bases. Either way, disable strict parsing for now
and re-enable later with better GODEBUG support.

Updates #54580

Change-Id: Icced2c7f9a6b2fc06bbd9c7e90f90edce24c2306
Reviewed-on: https://go-review.googlesource.com/c/go/+/462286
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Joseph Tsai <joetsai@digital-static.net>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Russ Cox <rsc@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-on: https://go-review.googlesource.com/c/go/+/462675
Reviewed-by: Joseph Tsai <joetsai@digital-static.net>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
2023-01-18 20:42:20 +00:00
Russ Cox
8b34676710 [release-branch.go1.20] cmd: update x/tools to latest internal Go 1.20 branch
Import x/tools as of CL 462596 (070db2996ebe, Jan 18 2022),
to bring in two vet analysis fixes (printf and loopclosure).

For #57911.
Fixes #57903.
Fixes #57904.

Change-Id: I82fe4e9bd56fb8e64394ee8618c155316942a517
Reviewed-on: https://go-review.googlesource.com/c/go/+/462555
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
Auto-Submit: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/c/go/+/462695
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
2023-01-18 20:41:57 +00:00
Cuong Manh Le
d7c6da8bac [release-branch.go1.20] cmd/compile: fix unsafe.{SliceData,StringData} escape analysis memory corruption
Updates #57823
Updates #57854

Change-Id: I54654d3ecb20b75afa9052c5c9db2072a86188d4
Reviewed-on: https://go-review.googlesource.com/c/go/+/461759
Reviewed-by: Cherry Mui <cherryyz@google.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/461760
2023-01-18 18:32:01 +00:00
Matthew Dempsky
9eed826bf9 [release-branch.go1.20] cmd/compile: fix static init inlining for hidden node fields
Unified IR added several new IR fields for holding *runtime._type
expressions. To avoid throwing off any frontend semantics
(particularly inlining cost heuristics), they were marked as
`mknode:"-"` so that code wouldn't visit them.

Unfortunately, this has a bad interaction with the static init
inlining optimization, because the latter relies on ir.EditChildren to
substitute all parameters. This potentially includes dictionary
parameters, which can appear within the new RType fields.

This CL adds a new ir.EditChildrenWithHidden function that also edits
these fields, and switches staticinit to use it. Longer term, we
should unhide the RType fields so that ir.EditChildren visits them
normally, but that's scarier so late in the release cycle.

Updates #57778.
Updates #57854.

Change-Id: I98c1e8cf366156dc0c81a0cb79029cc5e59c476f
Reviewed-on: https://go-review.googlesource.com/c/go/+/461686
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
(cherry picked from commit 9f2fbedf010d59c3ecaa8c25b07a5f68fcb2e3d5)
Reviewed-on: https://go-review.googlesource.com/c/go/+/462535
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
2023-01-17 23:46:00 +00:00
Cherry Mui
670ce9b8a8 [release-branch.go1.20] all: merge master (9088c69) into release-branch.go1.20
Merge List:

+ 2023-01-17 9088c691da cmd/compile: ensure temp register mask isn't empty
+ 2023-01-17 c0799f7015 os: document that Rename is not atomic on non-Unix platforms
+ 2023-01-17 d74c31f0ba doc/go1.20: update cryptography release notes
+ 2023-01-17 8e19929436 strings: remove redundant symbols
+ 2023-01-17 6cb8c43b84 cmd/go: include coverage build flags for "go list"
+ 2023-01-17 02ed0e5e67 crypto/ed25519: improve Ed25519ctx docs and add example
+ 2023-01-17 f375b305c8 crypto/x509: clarify that CheckSignatureFrom and CheckSignature are low-level APIs
+ 2023-01-17 8409251e10 cmd/go: document GODEBUG=installgoroot=all
+ 2023-01-17 66689c7d46 doc/go1.20: remove mention of arena goexperiment
+ 2023-01-17 145dd38471 archive/tar, archive/zip: document ErrInsecurePath and GODEBUG setting
+ 2023-01-16 1c65b69bd1 runtime: fix performance regression in morestack_noctxt on ppc64
+ 2023-01-13 ebb572d82f Revert "internal/fsys: follow root symlink in fsys.Walk"
+ 2023-01-13 16cec4e7a0 doc/go1.20: mention build speed improvements
+ 2023-01-13 643f463186 cmd/cover: remove go.mod from testdata subdir

Change-Id: I4d56c9353d423f7e7169db7e30cb59515d422a56
2023-01-17 13:45:09 -05:00
Gopher Robot
b3160e8bce [release-branch.go1.20] go1.20rc3
Change-Id: I87007947c075e8b90dd74bdf164b59e81487f6de
Reviewed-on: https://go-review.googlesource.com/c/go/+/461836
Reviewed-by: Heschi Kreinick <heschi@google.com>
Auto-Submit: Gopher Robot <gobot@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Run-TryBot: Gopher Robot <gobot@golang.org>
2023-01-12 17:16:08 +00:00
Carlos Amedee
9efc2e7f95 [release-branch.go1.20] all: merge master (245e95d) into release-branch.go1.20
Merge List:

+ 2023-01-11 245e95dfab go/types, types2: don't look up fields or methods when expecting a type
+ 2023-01-11 18625d9bec runtime: fix incorrect comment
+ 2023-01-11 6ad27161f8 cmd/compile: better error message for when a type is in a constraint but not the type set
+ 2023-01-10 76d39ae349 cmd/link, runtime: Apple libc atfork workaround take 3
+ 2023-01-10 0a0de0fc42 runtime: revert use of __fork to work around Apple atfork bugs
+ 2023-01-10 82f09b75ca os/exec: avoid leaking an exec.Cmd in TestWaitInterrupt
+ 2023-01-09 0202ad0b3a cmd/compile: prevent IsNewObject from taking quadratic time
+ 2023-01-09 64519baf38 cmd/compile/internal/pgo: add hint to missing start_line error
+ 2023-01-09 376076f3c6 runtime: skip TestCgoPprofCallback in short mode, don't run in parallel
+ 2023-01-09 0bbd67e52f runtime/pprof: document possibility of empty stacks
+ 2023-01-09 d9f23cfe78 runtime/pprof: improve output of TestLabelSystemstack
+ 2023-01-09 8232a09e3e sync/atomic: fix the note of atomic.Store
+ 2023-01-09 841c3eb166 all: fix typos in go file comments
+ 2023-01-06 f721fa3be9 syscall: skip TestUseCgroupFD if cgroupfs not mounted
+ 2023-01-06 76ec919237 net: fix typo in hosts.go
+ 2023-01-06 660d4815ea cmd/compile: describe how Go maps to wasm implementation
+ 2023-01-05 119f679a3b crypto/tls: fix typo in cacheEntry godoc
+ 2023-01-05 d50ea217f6 cmd/cover: fix problems with "go test -covermode=atomic sync/atomic"
+ 2023-01-04 bae7d772e8 doc/go1.20: fix links to new strings functions
+ 2023-01-04 4e7c838483 crypto/internal/boring: add dev.boringcrypto README.md text
+ 2023-01-04 46e3d9d12a cmd/compile: use "satisfies" (not "implements") for constraint errors
+ 2023-01-04 79cdecc852 cmd/gofmt: fix a typo in a comment
+ 2023-01-03 9955a7e9bb README.vendor: minor updates
+ 2023-01-03 d03231d9ce doc/go1.20: fix http.ResponseController example
+ 2023-01-03 cdc73f0679 .github: suggest using private browsing in pkgsite template

Change-Id: I73be496aa4163ad1d3a6cc8114f1a612968d4b10
2023-01-11 18:01:18 -05:00
Gopher Robot
32593a9192 [release-branch.go1.20] go1.20rc2
Change-Id: Ieb30cc96008bd705677e44983c68d4581706cc05
Reviewed-on: https://go-review.googlesource.com/c/go/+/460498
Auto-Submit: Gopher Robot <gobot@golang.org>
Run-TryBot: Gopher Robot <gobot@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2023-01-04 16:02:35 +00:00
Heschi Kreinick
eb598248ba [release-branch.go1.20] all: merge master (db36eca) into release-branch.go1.20
Merge List:

+ 2022-12-29 db36eca33c doc/go1.20: fix typos
+ 2022-12-29 642fd5f7ce go/types, types2: use strict comparability for type set intersection
+ 2022-12-28 9123221ccf misc/cgo/testsanitizers: run libfuzzer tests in temp directory
+ 2022-12-27 e870de9936 misc/cgo/testsanitizers: add libfuzzer tests
+ 2022-12-23 38cfb3be9d testing: rephrase the sentence about naming test files
+ 2022-12-23 1ba7341cb2 cmd/link, runtime: use a different section for Go libfuzzer counters
+ 2022-12-22 c61d322d5f runtime: call __fork instead of fork on darwin
+ 2022-12-22 6c9b661867 runtime: revert Apple libc atfork workaround
+ 2022-12-22 6d3139b203 misc/cgo/testshared: test build std in shared mode
+ 2022-12-22 de6abd7889 runtime/internal/startlinetest: work around shared buildmode linking issue
+ 2022-12-22 18baca6765 runtime/race: add build tag to internal amd64vN packages
+ 2022-12-22 13ed4f42f0 doc/go1.20: fix typo
+ 2022-12-21 fadd77c05b runtime/coverage: add missing file close in test support helper
+ 2022-12-21 c9a10d48a8 crypto/x509: return typed verification errors on macOS
+ 2022-12-21 2321abc5e9 archive/tar, archive/zip: revert documentation of ErrInsecurePath
+ 2022-12-21 458241f981 net/http/httputil: don't add X-Forwarded-{Host,Proto} after invoking Director funcs
+ 2022-12-21 58f6022eee syscall: don't use faccessat2 on android
+ 2022-12-21 78fc81070a net: use correct dns msg size
+ 2022-12-19 a5a4744250 os: reenable TestReaddirSmallSeek on windows
+ 2022-12-17 0b2ad1d815 cmd/compile: sign-extend the 2nd argument of the LoweredAtomicCas32 on loong64,mips64x,riscv64
+ 2022-12-16 8bcc490667 os/user,net: add -fno-stack-protector to CFLAGS
+ 2022-12-16 f4b42f5cb8 net/http: improve errors in TestCancelRequestWhenSharingConnection
+ 2022-12-16 24ac659a39 syscall, internal/poll: fall back to accept on linux-arm
+ 2022-12-16 3323dab1f4 os/exec: retry ETXTBSY errors in TestFindExecutableVsNoexec
+ 2022-12-15 628a1e7d3a doc/go1.20: fix typo
+ 2022-12-15 357ea85892 spec: fix typo
+ 2022-12-14 ea14d1b6e1 spec: document which recursive arrays and structs are valid/invalid
+ 2022-12-14 0b8add46ce doc/go1.20.html: pre-announce dropping Windows 7, 8, and friends
+ 2022-12-14 4f8bc6224b cmd/compile: desugar OCALLMETH->OCALLFUNC within devirtualization
+ 2022-12-14 5c682f94c6 spec: document illegal recursive type parameter lists
+ 2022-12-14 bd42aa86d3 spec: describe new semantics for comparable and constraint satisfaction
+ 2022-12-14 ffefcd360b spec: introduce notion of strict comparability
+ 2022-12-13 cb07765045 syscall: fix closing of reordered FDs in plan9 ForkExec
+ 2022-12-13 5ba98b9756 go/types, types2: report type mismatch error when conversion is impossible
+ 2022-12-13 61e2b8ec59 cmd/gc: test temp string comparison with all ops
+ 2022-12-12 b16e94d13d syscall: skip TestUseCgroupFD if cgroupfs mounted RO
+ 2022-12-12 27301e8247 syscall: fix shadowing bugs in forkAndExecInChild
+ 2022-12-12 6f7a95d25e sync: remove unused const
+ 2022-12-12 6b895d9eaa doc/go1.20: fix typo
+ 2022-12-12 c6ad9dc9b5 debug/buildinfo: check pointer size on buildinfo.Read
+ 2022-12-12 5dca7ed66f doc/go1.20: fix URL anchor
+ 2022-12-11 888047c310 cmd/compile: fix conditional move rule on PPC64
+ 2022-12-10 9b8750f53e os: skip size test in TestLstat if the file is a symlink
+ 2022-12-09 e8f78cb60c cmd/compile: fix conditional select rule
+ 2022-12-09 e76c87b191 doc: fix typo in 1.20 release notes
+ 2022-12-09 80f7484af7 os/user: zero-initialize C structs returned to Go
+ 2022-12-08 e738a2f19b go/types, types2: always rename type parameters during inference
+ 2022-12-08 8247b9f17a doc: fix typo
+ 2022-12-08 f368abb46e doc/go1.20: correct test binary -v flag value for test2json
+ 2022-12-08 7973b0e508 cmd/{go,cover,covdata}: fix 'package main' inconsistent handling
+ 2022-12-08 0aad4d3257 cmd/link: fix dynamic interpreter path for musl-based linux amd64
+ 2022-12-08 eaf0e3d465 runtime: remove arbitrary timeouts in finalizer tests
+ 2022-12-08 c8313d4fa8 cmd/go: deflake TestScript/test2json_interrupt
+ 2022-12-08 b9747e0e6b os/user: on AIX getpwuid_r seems to return -1 on overflow
+ 2022-12-07 9431237d77 internal/safefilepath: fix TestFromFS on Plan 9
+ 2022-12-07 7c7cd56870 cmd/go: in TestTerminalPassthrough, delay subprocess exit until the PTY has been read

Change-Id: I037343df0fe5b171b5f5726fcc55c01108d2563e
2023-01-03 12:21:39 -05:00
Gopher Robot
9f02342144 [release-branch.go1.20] go1.20rc1
Change-Id: I26470f8bcd902f9e1c7877763e360cb3c6255f3a
Reviewed-on: https://go-review.googlesource.com/c/go/+/456096
Reviewed-by: Heschi Kreinick <heschi@google.com>
Run-TryBot: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
TryBot-Bypass: Michael Pratt <mpratt@google.com>
Auto-Submit: Gopher Robot <gobot@golang.org>
2022-12-07 22:00:46 +00:00
Michael Pratt
0480336414 [release-branch.go1.20] update codereview.cfg for release-branch.go1.20
Following go.dev/cl/334376.

Change-Id: I96be6379566b5bcc31e41bdd5f30946b06001153
Reviewed-on: https://go-review.googlesource.com/c/go/+/455896
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Michael Pratt <mpratt@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
2022-12-07 18:00:33 +00:00
368 changed files with 7575 additions and 2660 deletions

1
VERSION Normal file
View File

@@ -0,0 +1 @@
go1.20.8

View File

@@ -1 +1,2 @@
branch: master
branch: release-branch.go1.20
parent-branch: master

View File

@@ -1200,9 +1200,8 @@ proxyHandler := &httputil.ReverseProxy{
</p>
<p><!-- CL 444277 -->
The <a href="/pkg/time/#Time.MarshalJSON"><code>Time.MarshalJSON</code></a> and
<a href="/pkg/time/#Time.UnmarshalJSON"><code>Time.UnmarshalJSON</code></a> methods
are now more strict about adherence to RFC 3339.
The <a href="/pkg/time/#Time.MarshalJSON"><code>Time.MarshalJSON</code></a> method
is now more strict about adherence to RFC 3339.
</p>
</dd>
</dl><!-- time -->

View File

@@ -1112,8 +1112,13 @@ func TestStd(t *testing.T) {
t.Skip("skip in short mode")
}
t.Parallel()
tmpDir := t.TempDir()
// Use a temporary pkgdir to not interfere with other tests, and not write to GOROOT.
// Cannot use goCmd as it runs with cloned GOROOT which is incomplete.
runWithEnv(t, "building std", []string{"GOROOT=" + oldGOROOT},
filepath.Join(oldGOROOT, "bin", "go"), "install", "-buildmode=shared", "-pkgdir="+t.TempDir(), "std")
filepath.Join(oldGOROOT, "bin", "go"), "install", "-buildmode=shared", "-pkgdir="+tmpDir, "std")
// Issue #58966.
runWithEnv(t, "testing issue #58966", []string{"GOROOT=" + oldGOROOT},
filepath.Join(oldGOROOT, "bin", "go"), "run", "-linkshared", "-pkgdir="+tmpDir, "./issue58966/main.go")
}

View File

@@ -0,0 +1,15 @@
// 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 main
import "crypto/elliptic"
var curve elliptic.Curve
func main() {
switch curve {
case elliptic.P224():
}
}

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package api
package main
import (
"flag"

View File

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

View File

@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package api computes the exported API of a set of Go packages.
// This package computes the exported API of a set of Go packages.
// It is only a test, not a command, nor a usefully importable package.
package api
package main
import (
"bufio"

View File

@@ -183,28 +183,28 @@ start:
// 8.2: Load-Reserved/Store-Conditional
LRW (X5), X6 // 2fa30214
LRD (X5), X6 // 2fb30214
SCW X5, (X6), X7 // af23531c
SCD X5, (X6), X7 // af33531c
SCW X5, (X6), X7 // af23531a
SCD X5, (X6), X7 // af33531a
// 8.3: Atomic Memory Operations
AMOSWAPW X5, (X6), X7 // af23530c
AMOSWAPD X5, (X6), X7 // af33530c
AMOADDW X5, (X6), X7 // af235304
AMOADDD X5, (X6), X7 // af335304
AMOANDW X5, (X6), X7 // af235364
AMOANDD X5, (X6), X7 // af335364
AMOORW X5, (X6), X7 // af235344
AMOORD X5, (X6), X7 // af335344
AMOXORW X5, (X6), X7 // af235324
AMOXORD X5, (X6), X7 // af335324
AMOMAXW X5, (X6), X7 // af2353a4
AMOMAXD X5, (X6), X7 // af3353a4
AMOMAXUW X5, (X6), X7 // af2353e4
AMOMAXUD X5, (X6), X7 // af3353e4
AMOMINW X5, (X6), X7 // af235384
AMOMIND X5, (X6), X7 // af335384
AMOMINUW X5, (X6), X7 // af2353c4
AMOMINUD X5, (X6), X7 // af3353c4
AMOSWAPW X5, (X6), X7 // af23530e
AMOSWAPD X5, (X6), X7 // af33530e
AMOADDW X5, (X6), X7 // af235306
AMOADDD X5, (X6), X7 // af335306
AMOANDW X5, (X6), X7 // af235366
AMOANDD X5, (X6), X7 // af335366
AMOORW X5, (X6), X7 // af235346
AMOORD X5, (X6), X7 // af335346
AMOXORW X5, (X6), X7 // af235326
AMOXORD X5, (X6), X7 // af335326
AMOMAXW X5, (X6), X7 // af2353a6
AMOMAXD X5, (X6), X7 // af3353a6
AMOMAXUW X5, (X6), X7 // af2353e6
AMOMAXUD X5, (X6), X7 // af3353e6
AMOMINW X5, (X6), X7 // af235386
AMOMIND X5, (X6), X7 // af335386
AMOMINUW X5, (X6), X7 // af2353c6
AMOMINUD X5, (X6), X7 // af3353c6
// 10.1: Base Counters and Timers
RDCYCLE X5 // f32200c0

View File

@@ -80,6 +80,11 @@ func (f *File) ParseGo(abspath string, src []byte) {
cg = d.Doc
}
if cg != nil {
if strings.ContainsAny(abspath, "\r\n") {
// This should have been checked when the file path was first resolved,
// but we double check here just to be sure.
fatalf("internal error: ParseGo: abspath contains unexpected newline character: %q", abspath)
}
f.Preamble += fmt.Sprintf("#line %d %q\n", sourceLine(cg), abspath)
f.Preamble += commentText(cg) + "\n"
f.Preamble += "#line 1 \"cgo-generated-wrapper\"\n"

View File

@@ -363,6 +363,12 @@ func main() {
// Apply trimpath to the file path. The path won't be read from after this point.
input, _ = objabi.ApplyRewrites(input, *trimpath)
if strings.ContainsAny(input, "\r\n") {
// ParseGo, (*Package).writeOutput, and printer.Fprint in SourcePos mode
// all emit line directives, which don't permit newlines in the file path.
// Bail early if we see anything newline-like in the trimmed path.
fatalf("input path contains newline character: %q", input)
}
goFiles[i] = input
f := new(File)

View File

@@ -47,7 +47,9 @@ func (p *Package) writeDefs() {
fflg := creat(*objDir + "_cgo_flags")
for k, v := range p.CgoFlags {
fmt.Fprintf(fflg, "_CGO_%s=%s\n", k, strings.Join(v, " "))
for _, arg := range v {
fmt.Fprintf(fflg, "_CGO_%s=%s\n", k, arg)
}
if k == "LDFLAGS" && !*gccgo {
for _, arg := range v {
fmt.Fprintf(fgo2, "//go:cgo_ldflag %q\n", arg)
@@ -642,6 +644,11 @@ func (p *Package) writeOutput(f *File, srcfile string) {
// Write Go output: Go input with rewrites of C.xxx to _C_xxx.
fmt.Fprintf(fgo1, "// Code generated by cmd/cgo; DO NOT EDIT.\n\n")
if strings.ContainsAny(srcfile, "\r\n") {
// This should have been checked when the file path was first resolved,
// but we double check here just to be sure.
fatalf("internal error: writeOutput: srcfile contains unexpected newline character: %q", srcfile)
}
fmt.Fprintf(fgo1, "//line %s:1:1\n", srcfile)
fgo1.Write(f.Edit.Bytes())

View File

@@ -167,7 +167,7 @@ func ParseFlags() {
Debug.ConcurrentOk = true
Debug.InlFuncsWithClosures = 1
Debug.InlStaticInit = 1
Debug.InlStaticInit = 0
if buildcfg.Experiment.Unified {
Debug.Unified = 1
}

View File

@@ -19,7 +19,7 @@ func (e *escape) call(ks []hole, call ir.Node) {
var init ir.Nodes
e.callCommon(ks, call, &init, nil)
if len(init) != 0 {
call.(*ir.CallExpr).PtrInit().Append(init...)
call.(ir.InitNode).PtrInit().Append(init...)
}
}
@@ -38,6 +38,18 @@ func (e *escape) callCommon(ks []hole, call ir.Node, init *ir.Nodes, wrapper *ir
argumentFunc(nil, k, argp)
}
argumentRType := func(rtypep *ir.Node) {
rtype := *rtypep
if rtype == nil {
return
}
// common case: static rtype/itab argument, which can be evaluated within the wrapper instead.
if addr, ok := rtype.(*ir.AddrExpr); ok && addr.Op() == ir.OADDR && addr.X.Op() == ir.OLINKSYMOFFSET {
return
}
e.wrapExpr(rtype.Pos(), rtypep, init, call, wrapper)
}
switch call.Op() {
default:
ir.Dump("esc", call)
@@ -153,6 +165,7 @@ func (e *escape) callCommon(ks []hole, call ir.Node, init *ir.Nodes, wrapper *ir
argument(e.heapHole(), &args[i])
}
}
argumentRType(&call.RType)
case ir.OCOPY:
call := call.(*ir.BinaryExpr)
@@ -163,6 +176,7 @@ func (e *escape) callCommon(ks []hole, call ir.Node, init *ir.Nodes, wrapper *ir
copiedK = e.heapHole().deref(call, "copied slice")
}
argument(copiedK, &call.Y)
argumentRType(&call.RType)
case ir.OPANIC:
call := call.(*ir.UnaryExpr)
@@ -179,15 +193,21 @@ func (e *escape) callCommon(ks []hole, call ir.Node, init *ir.Nodes, wrapper *ir
for i := range call.Args {
argument(e.discardHole(), &call.Args[i])
}
argumentRType(&call.RType)
case ir.OLEN, ir.OCAP, ir.OREAL, ir.OIMAG, ir.OCLOSE, ir.OUNSAFESTRINGDATA, ir.OUNSAFESLICEDATA:
case ir.OLEN, ir.OCAP, ir.OREAL, ir.OIMAG, ir.OCLOSE:
call := call.(*ir.UnaryExpr)
argument(e.discardHole(), &call.X)
case ir.OUNSAFESTRINGDATA, ir.OUNSAFESLICEDATA:
call := call.(*ir.UnaryExpr)
argument(ks[0], &call.X)
case ir.OUNSAFEADD, ir.OUNSAFESLICE, ir.OUNSAFESTRING:
call := call.(*ir.BinaryExpr)
argument(ks[0], &call.X)
argument(e.discardHole(), &call.Y)
argumentRType(&call.RType)
}
}

View File

@@ -39,8 +39,9 @@ func lookupGorootExport(pkgDir string) (string, bool) {
)
f, _ = exportMap.LoadOrStore(pkgDir, func() (string, bool) {
listOnce.Do(func() {
cmd := exec.Command("go", "list", "-export", "-f", "{{.Export}}", pkgDir)
cmd := exec.Command(filepath.Join(build.Default.GOROOT, "bin", "go"), "list", "-export", "-f", "{{.Export}}", pkgDir)
cmd.Dir = build.Default.GOROOT
cmd.Env = append(os.Environ(), "PWD="+cmd.Dir, "GOROOT="+build.Default.GOROOT)
var output []byte
output, err := cmd.Output()
if err != nil {

View File

@@ -959,6 +959,11 @@ func reassigned(name *Name) bool {
if isName(OuterValue(n.X)) {
return true
}
case ORANGE:
n := n.(*RangeStmt)
if isName(n.Key) || isName(n.Value) {
return true
}
case OCLOSURE:
n := n.(*ClosureExpr)
if Any(n.Func, do) {

View File

@@ -147,9 +147,10 @@ func NewFunc(pos src.XPos) *Func {
func (f *Func) isStmt() {}
func (n *Func) copy() Node { panic(n.no("copy")) }
func (n *Func) doChildren(do func(Node) bool) bool { return doNodes(n.Body, do) }
func (n *Func) editChildren(edit func(Node) Node) { editNodes(n.Body, edit) }
func (n *Func) copy() Node { panic(n.no("copy")) }
func (n *Func) doChildren(do func(Node) bool) bool { return doNodes(n.Body, do) }
func (n *Func) editChildren(edit func(Node) Node) { editNodes(n.Body, edit) }
func (n *Func) editChildrenWithHidden(edit func(Node) Node) { editNodes(n.Body, edit) }
func (f *Func) Type() *types.Type { return f.Nname.Type() }
func (f *Func) Sym() *types.Sym { return f.Nname.Sym() }

View File

@@ -256,18 +256,24 @@ func processType(t *ast.TypeSpec) {
var copyBody strings.Builder
var doChildrenBody strings.Builder
var editChildrenBody strings.Builder
var editChildrenWithHiddenBody strings.Builder
for _, f := range fields {
names := f.Names
ft := f.Type
hidden := false
if f.Tag != nil {
tag := f.Tag.Value[1 : len(f.Tag.Value)-1]
if strings.HasPrefix(tag, "mknode:") {
if tag[7:] == "\"-\"" {
continue
if !isNamedType(ft, "Node") {
continue
}
hidden = true
} else {
panic(fmt.Sprintf("unexpected tag value: %s", tag))
}
panic(fmt.Sprintf("unexpected tag value: %s", tag))
}
}
names := f.Names
ft := f.Type
if isNamedType(ft, "Nodes") {
// Nodes == []Node
ft = &ast.ArrayType{Elt: &ast.Ident{Name: "Node"}}
@@ -286,6 +292,20 @@ func processType(t *ast.TypeSpec) {
continue
}
for _, name := range names {
ptr := ""
if isPtr {
ptr = "*"
}
if isSlice {
fmt.Fprintf(&editChildrenWithHiddenBody,
"edit%ss(n.%s, edit)\n", ft, name)
} else {
fmt.Fprintf(&editChildrenWithHiddenBody,
"if n.%s != nil {\nn.%s = edit(n.%s).(%s%s)\n}\n", name, name, name, ptr, ft)
}
if hidden {
continue
}
if isSlice {
fmt.Fprintf(&copyBody, "c.%s = copy%ss(c.%s)\n", name, ft, name)
fmt.Fprintf(&doChildrenBody,
@@ -295,10 +315,6 @@ func processType(t *ast.TypeSpec) {
} else {
fmt.Fprintf(&doChildrenBody,
"if n.%s != nil && do(n.%s) {\nreturn true\n}\n", name, name)
ptr := ""
if isPtr {
ptr = "*"
}
fmt.Fprintf(&editChildrenBody,
"if n.%s != nil {\nn.%s = edit(n.%s).(%s%s)\n}\n", name, name, name, ptr, ft)
}
@@ -313,6 +329,9 @@ func processType(t *ast.TypeSpec) {
fmt.Fprintf(&buf, "func (n *%s) editChildren(edit func(Node) Node) {\n", name)
buf.WriteString(editChildrenBody.String())
fmt.Fprintf(&buf, "}\n")
fmt.Fprintf(&buf, "func (n *%s) editChildrenWithHidden(edit func(Node) Node) {\n", name)
buf.WriteString(editChildrenWithHiddenBody.String())
fmt.Fprintf(&buf, "}\n")
}
func generateHelpers() {

View File

@@ -134,9 +134,10 @@ type Name struct {
func (n *Name) isExpr() {}
func (n *Name) copy() Node { panic(n.no("copy")) }
func (n *Name) doChildren(do func(Node) bool) bool { return false }
func (n *Name) editChildren(edit func(Node) Node) {}
func (n *Name) copy() Node { panic(n.no("copy")) }
func (n *Name) doChildren(do func(Node) bool) bool { return false }
func (n *Name) editChildren(edit func(Node) Node) {}
func (n *Name) editChildrenWithHidden(edit func(Node) Node) {}
// RecordFrameOffset records the frame offset for the name.
// It is used by package types when laying out function arguments.

View File

@@ -30,6 +30,7 @@ type Node interface {
doChildren(func(Node) bool) bool
editChildren(func(Node) Node)
editChildrenWithHidden(func(Node) Node)
// Abstract graph structure, for generic traversals.
Op() Op
@@ -290,7 +291,7 @@ const (
OEFACE // itable and data words of an empty-interface value.
OITAB // itable word of an interface value.
OIDATA // data word of an interface value in X
OSPTR // base pointer of a slice or string.
OSPTR // base pointer of a slice or string. Bounded==1 means known non-nil.
OCFUNC // reference to c function pointer (not go func value)
OCHECKNIL // emit code to ensure pointer/interface not nil
ORESULT // result of a function call; Xoffset is stack offset

View File

@@ -30,6 +30,13 @@ func (n *AddStringExpr) editChildren(edit func(Node) Node) {
n.Prealloc = edit(n.Prealloc).(*Name)
}
}
func (n *AddStringExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
editNodes(n.List, edit)
if n.Prealloc != nil {
n.Prealloc = edit(n.Prealloc).(*Name)
}
}
func (n *AddrExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *AddrExpr) copy() Node {
@@ -58,6 +65,15 @@ func (n *AddrExpr) editChildren(edit func(Node) Node) {
n.Prealloc = edit(n.Prealloc).(*Name)
}
}
func (n *AddrExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.X != nil {
n.X = edit(n.X).(Node)
}
if n.Prealloc != nil {
n.Prealloc = edit(n.Prealloc).(*Name)
}
}
func (n *AssignListStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *AssignListStmt) copy() Node {
@@ -84,6 +100,11 @@ func (n *AssignListStmt) editChildren(edit func(Node) Node) {
editNodes(n.Lhs, edit)
editNodes(n.Rhs, edit)
}
func (n *AssignListStmt) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
editNodes(n.Lhs, edit)
editNodes(n.Rhs, edit)
}
func (n *AssignOpStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *AssignOpStmt) copy() Node {
@@ -112,6 +133,15 @@ func (n *AssignOpStmt) editChildren(edit func(Node) Node) {
n.Y = edit(n.Y).(Node)
}
}
func (n *AssignOpStmt) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.X != nil {
n.X = edit(n.X).(Node)
}
if n.Y != nil {
n.Y = edit(n.Y).(Node)
}
}
func (n *AssignStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *AssignStmt) copy() Node {
@@ -140,6 +170,15 @@ func (n *AssignStmt) editChildren(edit func(Node) Node) {
n.Y = edit(n.Y).(Node)
}
}
func (n *AssignStmt) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.X != nil {
n.X = edit(n.X).(Node)
}
if n.Y != nil {
n.Y = edit(n.Y).(Node)
}
}
func (n *BasicLit) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *BasicLit) copy() Node {
@@ -156,6 +195,9 @@ func (n *BasicLit) doChildren(do func(Node) bool) bool {
func (n *BasicLit) editChildren(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *BasicLit) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *BinaryExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *BinaryExpr) copy() Node {
@@ -184,6 +226,18 @@ func (n *BinaryExpr) editChildren(edit func(Node) Node) {
n.Y = edit(n.Y).(Node)
}
}
func (n *BinaryExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.X != nil {
n.X = edit(n.X).(Node)
}
if n.Y != nil {
n.Y = edit(n.Y).(Node)
}
if n.RType != nil {
n.RType = edit(n.RType).(Node)
}
}
func (n *BlockStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *BlockStmt) copy() Node {
@@ -205,6 +259,10 @@ func (n *BlockStmt) editChildren(edit func(Node) Node) {
editNodes(n.init, edit)
editNodes(n.List, edit)
}
func (n *BlockStmt) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
editNodes(n.List, edit)
}
func (n *BranchStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *BranchStmt) copy() Node {
@@ -221,6 +279,9 @@ func (n *BranchStmt) doChildren(do func(Node) bool) bool {
func (n *BranchStmt) editChildren(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *BranchStmt) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *CallExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *CallExpr) copy() Node {
@@ -253,6 +314,17 @@ func (n *CallExpr) editChildren(edit func(Node) Node) {
editNodes(n.Args, edit)
editNames(n.KeepAlive, edit)
}
func (n *CallExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.X != nil {
n.X = edit(n.X).(Node)
}
editNodes(n.Args, edit)
if n.RType != nil {
n.RType = edit(n.RType).(Node)
}
editNames(n.KeepAlive, edit)
}
func (n *CaseClause) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *CaseClause) copy() Node {
@@ -290,6 +362,15 @@ func (n *CaseClause) editChildren(edit func(Node) Node) {
editNodes(n.RTypes, edit)
editNodes(n.Body, edit)
}
func (n *CaseClause) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.Var != nil {
n.Var = edit(n.Var).(*Name)
}
editNodes(n.List, edit)
editNodes(n.RTypes, edit)
editNodes(n.Body, edit)
}
func (n *ClosureExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *ClosureExpr) copy() Node {
@@ -312,6 +393,12 @@ func (n *ClosureExpr) editChildren(edit func(Node) Node) {
n.Prealloc = edit(n.Prealloc).(*Name)
}
}
func (n *ClosureExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.Prealloc != nil {
n.Prealloc = edit(n.Prealloc).(*Name)
}
}
func (n *CommClause) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *CommClause) copy() Node {
@@ -339,6 +426,13 @@ func (n *CommClause) editChildren(edit func(Node) Node) {
}
editNodes(n.Body, edit)
}
func (n *CommClause) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.Comm != nil {
n.Comm = edit(n.Comm).(Node)
}
editNodes(n.Body, edit)
}
func (n *CompLitExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *CompLitExpr) copy() Node {
@@ -366,6 +460,16 @@ func (n *CompLitExpr) editChildren(edit func(Node) Node) {
n.Prealloc = edit(n.Prealloc).(*Name)
}
}
func (n *CompLitExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
editNodes(n.List, edit)
if n.RType != nil {
n.RType = edit(n.RType).(Node)
}
if n.Prealloc != nil {
n.Prealloc = edit(n.Prealloc).(*Name)
}
}
func (n *ConstExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *ConstExpr) copy() Node {
@@ -382,6 +486,9 @@ func (n *ConstExpr) doChildren(do func(Node) bool) bool {
func (n *ConstExpr) editChildren(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *ConstExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *ConvExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *ConvExpr) copy() Node {
@@ -404,6 +511,24 @@ func (n *ConvExpr) editChildren(edit func(Node) Node) {
n.X = edit(n.X).(Node)
}
}
func (n *ConvExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.X != nil {
n.X = edit(n.X).(Node)
}
if n.TypeWord != nil {
n.TypeWord = edit(n.TypeWord).(Node)
}
if n.SrcRType != nil {
n.SrcRType = edit(n.SrcRType).(Node)
}
if n.ElemRType != nil {
n.ElemRType = edit(n.ElemRType).(Node)
}
if n.ElemElemRType != nil {
n.ElemElemRType = edit(n.ElemElemRType).(Node)
}
}
func (n *Decl) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *Decl) copy() Node {
@@ -421,6 +546,11 @@ func (n *Decl) editChildren(edit func(Node) Node) {
n.X = edit(n.X).(*Name)
}
}
func (n *Decl) editChildrenWithHidden(edit func(Node) Node) {
if n.X != nil {
n.X = edit(n.X).(*Name)
}
}
func (n *DynamicType) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *DynamicType) copy() Node {
@@ -449,6 +579,15 @@ func (n *DynamicType) editChildren(edit func(Node) Node) {
n.ITab = edit(n.ITab).(Node)
}
}
func (n *DynamicType) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.RType != nil {
n.RType = edit(n.RType).(Node)
}
if n.ITab != nil {
n.ITab = edit(n.ITab).(Node)
}
}
func (n *DynamicTypeAssertExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *DynamicTypeAssertExpr) copy() Node {
@@ -489,6 +628,21 @@ func (n *DynamicTypeAssertExpr) editChildren(edit func(Node) Node) {
n.ITab = edit(n.ITab).(Node)
}
}
func (n *DynamicTypeAssertExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.X != nil {
n.X = edit(n.X).(Node)
}
if n.SrcRType != nil {
n.SrcRType = edit(n.SrcRType).(Node)
}
if n.RType != nil {
n.RType = edit(n.RType).(Node)
}
if n.ITab != nil {
n.ITab = edit(n.ITab).(Node)
}
}
func (n *ForStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *ForStmt) copy() Node {
@@ -522,6 +676,16 @@ func (n *ForStmt) editChildren(edit func(Node) Node) {
}
editNodes(n.Body, edit)
}
func (n *ForStmt) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.Cond != nil {
n.Cond = edit(n.Cond).(Node)
}
if n.Post != nil {
n.Post = edit(n.Post).(Node)
}
editNodes(n.Body, edit)
}
func (n *Func) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
@@ -546,6 +710,12 @@ func (n *GoDeferStmt) editChildren(edit func(Node) Node) {
n.Call = edit(n.Call).(Node)
}
}
func (n *GoDeferStmt) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.Call != nil {
n.Call = edit(n.Call).(Node)
}
}
func (n *Ident) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *Ident) copy() Node {
@@ -562,6 +732,9 @@ func (n *Ident) doChildren(do func(Node) bool) bool {
func (n *Ident) editChildren(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *Ident) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *IfStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *IfStmt) copy() Node {
@@ -594,6 +767,14 @@ func (n *IfStmt) editChildren(edit func(Node) Node) {
editNodes(n.Body, edit)
editNodes(n.Else, edit)
}
func (n *IfStmt) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.Cond != nil {
n.Cond = edit(n.Cond).(Node)
}
editNodes(n.Body, edit)
editNodes(n.Else, edit)
}
func (n *IndexExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *IndexExpr) copy() Node {
@@ -622,6 +803,18 @@ func (n *IndexExpr) editChildren(edit func(Node) Node) {
n.Index = edit(n.Index).(Node)
}
}
func (n *IndexExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.X != nil {
n.X = edit(n.X).(Node)
}
if n.Index != nil {
n.Index = edit(n.Index).(Node)
}
if n.RType != nil {
n.RType = edit(n.RType).(Node)
}
}
func (n *InlineMarkStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *InlineMarkStmt) copy() Node {
@@ -638,6 +831,9 @@ func (n *InlineMarkStmt) doChildren(do func(Node) bool) bool {
func (n *InlineMarkStmt) editChildren(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *InlineMarkStmt) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *InlinedCallExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *InlinedCallExpr) copy() Node {
@@ -664,6 +860,11 @@ func (n *InlinedCallExpr) editChildren(edit func(Node) Node) {
editNodes(n.Body, edit)
editNodes(n.ReturnVars, edit)
}
func (n *InlinedCallExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
editNodes(n.Body, edit)
editNodes(n.ReturnVars, edit)
}
func (n *InstExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *InstExpr) copy() Node {
@@ -691,6 +892,13 @@ func (n *InstExpr) editChildren(edit func(Node) Node) {
}
editNtypes(n.Targs, edit)
}
func (n *InstExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.X != nil {
n.X = edit(n.X).(Node)
}
editNtypes(n.Targs, edit)
}
func (n *JumpTableStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *JumpTableStmt) copy() Node {
@@ -713,6 +921,12 @@ func (n *JumpTableStmt) editChildren(edit func(Node) Node) {
n.Idx = edit(n.Idx).(Node)
}
}
func (n *JumpTableStmt) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.Idx != nil {
n.Idx = edit(n.Idx).(Node)
}
}
func (n *KeyExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *KeyExpr) copy() Node {
@@ -741,6 +955,15 @@ func (n *KeyExpr) editChildren(edit func(Node) Node) {
n.Value = edit(n.Value).(Node)
}
}
func (n *KeyExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.Key != nil {
n.Key = edit(n.Key).(Node)
}
if n.Value != nil {
n.Value = edit(n.Value).(Node)
}
}
func (n *LabelStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *LabelStmt) copy() Node {
@@ -757,6 +980,9 @@ func (n *LabelStmt) doChildren(do func(Node) bool) bool {
func (n *LabelStmt) editChildren(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *LabelStmt) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *LinksymOffsetExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *LinksymOffsetExpr) copy() Node {
@@ -773,6 +999,9 @@ func (n *LinksymOffsetExpr) doChildren(do func(Node) bool) bool {
func (n *LinksymOffsetExpr) editChildren(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *LinksymOffsetExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *LogicalExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *LogicalExpr) copy() Node {
@@ -801,6 +1030,15 @@ func (n *LogicalExpr) editChildren(edit func(Node) Node) {
n.Y = edit(n.Y).(Node)
}
}
func (n *LogicalExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.X != nil {
n.X = edit(n.X).(Node)
}
if n.Y != nil {
n.Y = edit(n.Y).(Node)
}
}
func (n *MakeExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *MakeExpr) copy() Node {
@@ -829,6 +1067,18 @@ func (n *MakeExpr) editChildren(edit func(Node) Node) {
n.Cap = edit(n.Cap).(Node)
}
}
func (n *MakeExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.RType != nil {
n.RType = edit(n.RType).(Node)
}
if n.Len != nil {
n.Len = edit(n.Len).(Node)
}
if n.Cap != nil {
n.Cap = edit(n.Cap).(Node)
}
}
func (n *Name) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
@@ -847,6 +1097,9 @@ func (n *NilExpr) doChildren(do func(Node) bool) bool {
func (n *NilExpr) editChildren(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *NilExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *ParenExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *ParenExpr) copy() Node {
@@ -869,6 +1122,12 @@ func (n *ParenExpr) editChildren(edit func(Node) Node) {
n.X = edit(n.X).(Node)
}
}
func (n *ParenExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.X != nil {
n.X = edit(n.X).(Node)
}
}
func (n *RangeStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *RangeStmt) copy() Node {
@@ -914,6 +1173,37 @@ func (n *RangeStmt) editChildren(edit func(Node) Node) {
n.Prealloc = edit(n.Prealloc).(*Name)
}
}
func (n *RangeStmt) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.X != nil {
n.X = edit(n.X).(Node)
}
if n.RType != nil {
n.RType = edit(n.RType).(Node)
}
if n.Key != nil {
n.Key = edit(n.Key).(Node)
}
if n.Value != nil {
n.Value = edit(n.Value).(Node)
}
editNodes(n.Body, edit)
if n.Prealloc != nil {
n.Prealloc = edit(n.Prealloc).(*Name)
}
if n.KeyTypeWord != nil {
n.KeyTypeWord = edit(n.KeyTypeWord).(Node)
}
if n.KeySrcRType != nil {
n.KeySrcRType = edit(n.KeySrcRType).(Node)
}
if n.ValueTypeWord != nil {
n.ValueTypeWord = edit(n.ValueTypeWord).(Node)
}
if n.ValueSrcRType != nil {
n.ValueSrcRType = edit(n.ValueSrcRType).(Node)
}
}
func (n *RawOrigExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *RawOrigExpr) copy() Node {
@@ -930,6 +1220,9 @@ func (n *RawOrigExpr) doChildren(do func(Node) bool) bool {
func (n *RawOrigExpr) editChildren(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *RawOrigExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *ResultExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *ResultExpr) copy() Node {
@@ -946,6 +1239,9 @@ func (n *ResultExpr) doChildren(do func(Node) bool) bool {
func (n *ResultExpr) editChildren(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *ResultExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *ReturnStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *ReturnStmt) copy() Node {
@@ -967,6 +1263,10 @@ func (n *ReturnStmt) editChildren(edit func(Node) Node) {
editNodes(n.init, edit)
editNodes(n.Results, edit)
}
func (n *ReturnStmt) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
editNodes(n.Results, edit)
}
func (n *SelectStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *SelectStmt) copy() Node {
@@ -993,6 +1293,11 @@ func (n *SelectStmt) editChildren(edit func(Node) Node) {
editCommClauses(n.Cases, edit)
editNodes(n.Compiled, edit)
}
func (n *SelectStmt) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
editCommClauses(n.Cases, edit)
editNodes(n.Compiled, edit)
}
func (n *SelectorExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *SelectorExpr) copy() Node {
@@ -1021,6 +1326,15 @@ func (n *SelectorExpr) editChildren(edit func(Node) Node) {
n.Prealloc = edit(n.Prealloc).(*Name)
}
}
func (n *SelectorExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.X != nil {
n.X = edit(n.X).(Node)
}
if n.Prealloc != nil {
n.Prealloc = edit(n.Prealloc).(*Name)
}
}
func (n *SendStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *SendStmt) copy() Node {
@@ -1049,6 +1363,15 @@ func (n *SendStmt) editChildren(edit func(Node) Node) {
n.Value = edit(n.Value).(Node)
}
}
func (n *SendStmt) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.Chan != nil {
n.Chan = edit(n.Chan).(Node)
}
if n.Value != nil {
n.Value = edit(n.Value).(Node)
}
}
func (n *SliceExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *SliceExpr) copy() Node {
@@ -1089,6 +1412,21 @@ func (n *SliceExpr) editChildren(edit func(Node) Node) {
n.Max = edit(n.Max).(Node)
}
}
func (n *SliceExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.X != nil {
n.X = edit(n.X).(Node)
}
if n.Low != nil {
n.Low = edit(n.Low).(Node)
}
if n.High != nil {
n.High = edit(n.High).(Node)
}
if n.Max != nil {
n.Max = edit(n.Max).(Node)
}
}
func (n *SliceHeaderExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *SliceHeaderExpr) copy() Node {
@@ -1123,6 +1461,18 @@ func (n *SliceHeaderExpr) editChildren(edit func(Node) Node) {
n.Cap = edit(n.Cap).(Node)
}
}
func (n *SliceHeaderExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.Ptr != nil {
n.Ptr = edit(n.Ptr).(Node)
}
if n.Len != nil {
n.Len = edit(n.Len).(Node)
}
if n.Cap != nil {
n.Cap = edit(n.Cap).(Node)
}
}
func (n *StarExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *StarExpr) copy() Node {
@@ -1145,6 +1495,12 @@ func (n *StarExpr) editChildren(edit func(Node) Node) {
n.X = edit(n.X).(Node)
}
}
func (n *StarExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.X != nil {
n.X = edit(n.X).(Node)
}
}
func (n *StringHeaderExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *StringHeaderExpr) copy() Node {
@@ -1173,6 +1529,15 @@ func (n *StringHeaderExpr) editChildren(edit func(Node) Node) {
n.Len = edit(n.Len).(Node)
}
}
func (n *StringHeaderExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.Ptr != nil {
n.Ptr = edit(n.Ptr).(Node)
}
if n.Len != nil {
n.Len = edit(n.Len).(Node)
}
}
func (n *StructKeyExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *StructKeyExpr) copy() Node {
@@ -1195,6 +1560,12 @@ func (n *StructKeyExpr) editChildren(edit func(Node) Node) {
n.Value = edit(n.Value).(Node)
}
}
func (n *StructKeyExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.Value != nil {
n.Value = edit(n.Value).(Node)
}
}
func (n *SwitchStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *SwitchStmt) copy() Node {
@@ -1227,6 +1598,14 @@ func (n *SwitchStmt) editChildren(edit func(Node) Node) {
editCaseClauses(n.Cases, edit)
editNodes(n.Compiled, edit)
}
func (n *SwitchStmt) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.Tag != nil {
n.Tag = edit(n.Tag).(Node)
}
editCaseClauses(n.Cases, edit)
editNodes(n.Compiled, edit)
}
func (n *TailCallStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *TailCallStmt) copy() Node {
@@ -1249,6 +1628,12 @@ func (n *TailCallStmt) editChildren(edit func(Node) Node) {
n.Call = edit(n.Call).(*CallExpr)
}
}
func (n *TailCallStmt) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.Call != nil {
n.Call = edit(n.Call).(*CallExpr)
}
}
func (n *TypeAssertExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *TypeAssertExpr) copy() Node {
@@ -1271,6 +1656,15 @@ func (n *TypeAssertExpr) editChildren(edit func(Node) Node) {
n.X = edit(n.X).(Node)
}
}
func (n *TypeAssertExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.X != nil {
n.X = edit(n.X).(Node)
}
if n.ITab != nil {
n.ITab = edit(n.ITab).(Node)
}
}
func (n *TypeSwitchGuard) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *TypeSwitchGuard) copy() Node {
@@ -1294,6 +1688,14 @@ func (n *TypeSwitchGuard) editChildren(edit func(Node) Node) {
n.X = edit(n.X).(Node)
}
}
func (n *TypeSwitchGuard) editChildrenWithHidden(edit func(Node) Node) {
if n.Tag != nil {
n.Tag = edit(n.Tag).(*Ident)
}
if n.X != nil {
n.X = edit(n.X).(Node)
}
}
func (n *UnaryExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *UnaryExpr) copy() Node {
@@ -1316,6 +1718,12 @@ func (n *UnaryExpr) editChildren(edit func(Node) Node) {
n.X = edit(n.X).(Node)
}
}
func (n *UnaryExpr) editChildrenWithHidden(edit func(Node) Node) {
editNodes(n.init, edit)
if n.X != nil {
n.X = edit(n.X).(Node)
}
}
func (n *typeNode) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *typeNode) copy() Node {
@@ -1327,6 +1735,8 @@ func (n *typeNode) doChildren(do func(Node) bool) bool {
}
func (n *typeNode) editChildren(edit func(Node) Node) {
}
func (n *typeNode) editChildrenWithHidden(edit func(Node) Node) {
}
func copyCaseClauses(list []*CaseClause) []*CaseClause {
if list == nil {

View File

@@ -184,3 +184,15 @@ func EditChildren(n Node, edit func(Node) Node) {
}
n.editChildren(edit)
}
// EditChildrenWithHidden is like EditChildren, but also edits
// Node-typed fields tagged with `mknode:"-"`.
//
// TODO(mdempsky): Remove the `mknode:"-"` tags so this function can
// go away.
func EditChildrenWithHidden(n Node, edit func(Node) Node) {
if n == nil {
return
}
n.editChildrenWithHidden(edit)
}

View File

@@ -198,7 +198,7 @@ func (l *linker) relocObj(pr *pkgReader, idx pkgbits.Index) pkgbits.Index {
l.exportBody(obj, local)
}
if obj.Op() == ir.OTYPE {
if obj.Op() == ir.OTYPE && !obj.Alias() {
if typ := obj.Type(); !typ.IsInterface() {
for _, method := range typ.Methods().Slice() {
l.exportBody(method.Nname.(*ir.Name), local)

View File

@@ -231,6 +231,16 @@ func (r *reader) pos() src.XPos {
return base.Ctxt.PosTable.XPos(r.pos0())
}
// origPos reads a position from the bitstream, and returns both the
// original raw position and an inlining-adjusted position.
func (r *reader) origPos() (origPos, inlPos src.XPos) {
r.suppressInlPos++
origPos = r.pos()
r.suppressInlPos--
inlPos = r.inlPos(origPos)
return
}
func (r *reader) pos0() src.Pos {
r.Sync(pkgbits.SyncPos)
if !r.Bool() {
@@ -517,13 +527,33 @@ func (r *reader) doTyp() *types.Type {
}
func (r *reader) unionType() *types.Type {
terms := make([]*types.Type, r.Len())
tildes := make([]bool, len(terms))
for i := range terms {
tildes[i] = r.Bool()
terms[i] = r.typ()
// In the types1 universe, we only need to handle value types.
// Impure interfaces (i.e., interfaces with non-trivial type sets
// like "int | string") can only appear as type parameter bounds,
// and this is enforced by the types2 type checker.
//
// However, type unions can still appear in pure interfaces if the
// type union is equivalent to "any". E.g., typeparam/issue52124.go
// declares variables with the type "interface { any | int }".
//
// To avoid needing to represent type unions in types1 (since we
// don't have any uses for that today anyway), we simply fold them
// to "any". As a consistency check, we still read the union terms
// to make sure this substitution is safe.
pure := false
for i, n := 0, r.Len(); i < n; i++ {
_ = r.Bool() // tilde
term := r.typ()
if term.IsEmptyInterface() {
pure = true
}
}
return types.NewUnion(terms, tildes)
if !pure {
base.Fatalf("impure type set used in value type")
}
return types.Types[types.TINTER]
}
func (r *reader) interfaceType() *types.Type {
@@ -2097,12 +2127,12 @@ func (r *reader) expr() (res ir.Node) {
return typecheck.Callee(r.obj())
case exprFuncInst:
pos := r.pos()
origPos, pos := r.origPos()
wrapperFn, baseFn, dictPtr := r.funcInst(pos)
if wrapperFn != nil {
return wrapperFn
}
return r.curry(pos, false, baseFn, dictPtr, nil)
return r.curry(origPos, false, baseFn, dictPtr, nil)
case exprConst:
pos := r.pos()
@@ -2132,7 +2162,7 @@ func (r *reader) expr() (res ir.Node) {
case exprMethodVal:
recv := r.expr()
pos := r.pos()
origPos, pos := r.origPos()
wrapperFn, baseFn, dictPtr := r.methodExpr()
// For simple wrapperFn values, the existing machinery for creating
@@ -2164,7 +2194,18 @@ func (r *reader) expr() (res ir.Node) {
}
n := typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, recv, wrapperFn.Sel)).(*ir.SelectorExpr)
assert(n.Selection == wrapperFn.Selection)
// As a consistency check here, we make sure "n" selected the
// same method (represented by a types.Field) that wrapperFn
// selected. However, for anonymous receiver types, there can be
// multiple such types.Field instances (#58563). So we may need
// to fallback to making sure Sym and Type (including the
// receiver parameter's type) match.
if n.Selection != wrapperFn.Selection {
assert(n.Selection.Sym == wrapperFn.Selection.Sym)
assert(types.Identical(n.Selection.Type, wrapperFn.Selection.Type))
assert(types.Identical(n.Selection.Type.Recv().Type, wrapperFn.Selection.Type.Recv().Type))
}
wrapper := methodValueWrapper{
rcvr: n.X.Type(),
@@ -2181,7 +2222,7 @@ func (r *reader) expr() (res ir.Node) {
// For more complicated method expressions, we construct a
// function literal wrapper.
return r.curry(pos, true, baseFn, recv, dictPtr)
return r.curry(origPos, true, baseFn, recv, dictPtr)
case exprMethodExpr:
recv := r.typ()
@@ -2197,7 +2238,7 @@ func (r *reader) expr() (res ir.Node) {
addr = true
}
pos := r.pos()
origPos, pos := r.origPos()
wrapperFn, baseFn, dictPtr := r.methodExpr()
// If we already have a wrapper and don't need to do anything with
@@ -2220,7 +2261,7 @@ func (r *reader) expr() (res ir.Node) {
return typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, ir.TypeNode(recv), method.Sel)).(*ir.SelectorExpr)
}
return r.methodExprWrap(pos, recv, implicits, deref, addr, baseFn, dictPtr)
return r.methodExprWrap(origPos, recv, implicits, deref, addr, baseFn, dictPtr)
case exprIndex:
x := r.expr()
@@ -2550,7 +2591,7 @@ func (pr *pkgReader) objDictName(idx pkgbits.Index, implicits, explicits []*type
// If nilCheck is true and arg0 is an interface value, then it's
// checked to be non-nil as an initial step at the point of evaluating
// the function literal itself.
func (r *reader) curry(pos src.XPos, ifaceHack bool, fun ir.Node, arg0, arg1 ir.Node) ir.Node {
func (r *reader) curry(origPos src.XPos, ifaceHack bool, fun ir.Node, arg0, arg1 ir.Node) ir.Node {
var captured ir.Nodes
captured.Append(fun, arg0)
if arg1 != nil {
@@ -2574,13 +2615,13 @@ func (r *reader) curry(pos src.XPos, ifaceHack bool, fun ir.Node, arg0, arg1 ir.
r.syntheticTailCall(pos, fun, args)
}
return r.syntheticClosure(pos, typ, ifaceHack, captured, addBody)
return r.syntheticClosure(origPos, typ, ifaceHack, captured, addBody)
}
// methodExprWrap returns a function literal that changes method's
// first parameter's type to recv, and uses implicits/deref/addr to
// select the appropriate receiver parameter to pass to method.
func (r *reader) methodExprWrap(pos src.XPos, recv *types.Type, implicits []int, deref, addr bool, method, dictPtr ir.Node) ir.Node {
func (r *reader) methodExprWrap(origPos src.XPos, recv *types.Type, implicits []int, deref, addr bool, method, dictPtr ir.Node) ir.Node {
var captured ir.Nodes
captured.Append(method)
@@ -2631,12 +2672,13 @@ func (r *reader) methodExprWrap(pos src.XPos, recv *types.Type, implicits []int,
r.syntheticTailCall(pos, fn, args)
}
return r.syntheticClosure(pos, typ, false, captured, addBody)
return r.syntheticClosure(origPos, typ, false, captured, addBody)
}
// syntheticClosure constructs a synthetic function literal for
// currying dictionary arguments. pos is the position used for the
// closure. typ is the function literal's signature type.
// currying dictionary arguments. origPos is the position used for the
// closure, which must be a non-inlined position. typ is the function
// literal's signature type.
//
// captures is a list of expressions that need to be evaluated at the
// point of function literal evaluation and captured by the function
@@ -2647,7 +2689,7 @@ func (r *reader) methodExprWrap(pos src.XPos, recv *types.Type, implicits []int,
// list of captured values passed back has the captured variables for
// use within the function literal, corresponding to the expressions
// in captures.
func (r *reader) syntheticClosure(pos src.XPos, typ *types.Type, ifaceHack bool, captures ir.Nodes, addBody func(pos src.XPos, r *reader, captured []ir.Node)) ir.Node {
func (r *reader) syntheticClosure(origPos src.XPos, typ *types.Type, ifaceHack bool, captures ir.Nodes, addBody func(pos src.XPos, r *reader, captured []ir.Node)) ir.Node {
// isSafe reports whether n is an expression that we can safely
// defer to evaluating inside the closure instead, to avoid storing
// them into the closure.
@@ -2664,9 +2706,15 @@ func (r *reader) syntheticClosure(pos src.XPos, typ *types.Type, ifaceHack bool,
return false
}
fn := ir.NewClosureFunc(pos, r.curfn != nil)
// The ODCLFUNC and its body need to use the original position, but
// the OCLOSURE node and any Init statements should use the inlined
// position instead. See also the explanation in reader.funcLit.
inlPos := r.inlPos(origPos)
fn := ir.NewClosureFunc(origPos, r.curfn != nil)
fn.SetWrapper(true)
clo := fn.OClosure
clo.SetPos(inlPos)
ir.NameClosure(clo, r.curfn)
setType(fn.Nname, typ)
@@ -2679,13 +2727,13 @@ func (r *reader) syntheticClosure(pos src.XPos, typ *types.Type, ifaceHack bool,
continue // skip capture; can reference directly
}
tmp := r.tempCopy(pos, n, &init)
ir.NewClosureVar(pos, fn, tmp)
tmp := r.tempCopy(inlPos, n, &init)
ir.NewClosureVar(origPos, fn, tmp)
// We need to nil check interface receivers at the point of method
// value evaluation, ugh.
if ifaceHack && i == 1 && n.Type().IsInterface() {
check := ir.NewUnaryExpr(pos, ir.OCHECKNIL, ir.NewUnaryExpr(pos, ir.OITAB, tmp))
check := ir.NewUnaryExpr(inlPos, ir.OCHECKNIL, ir.NewUnaryExpr(inlPos, ir.OITAB, tmp))
init.Append(typecheck.Stmt(check))
}
}
@@ -2703,7 +2751,7 @@ func (r *reader) syntheticClosure(pos src.XPos, typ *types.Type, ifaceHack bool,
}
assert(next == len(r.closureVars))
addBody(pos, r, captured)
addBody(origPos, r, captured)
}}
bodyReader[fn] = pri
pri.funcBody(fn)

View File

@@ -158,7 +158,11 @@ func readBodies(target *ir.Package, duringInlining bool) {
// Instantiated generic function: add to Decls for typechecking
// and compilation.
if fn.OClosure == nil && len(pri.dict.targs) != 0 {
if duringInlining {
// cmd/link does not support a type symbol referencing a method symbol
// across DSO boundary, so force re-compiling methods on a generic type
// even it was seen from imported package in linkshared mode, see #58966.
canSkipNonGenericMethod := !(base.Ctxt.Flag_linkshared && ir.IsMethod(fn))
if duringInlining && canSkipNonGenericMethod {
inlDecls = append(inlDecls, fn)
} else {
target.Decls = append(target.Decls, fn)

View File

@@ -140,9 +140,30 @@ func New(profileFile string) *Profile {
return nil
}
if len(profile.Sample) == 0 {
// We accept empty profiles, but there is nothing to do.
return nil
}
valueIndex := -1
for i, s := range profile.SampleType {
// Samples count is the raw data collected, and CPU nanoseconds is just
// a scaled version of it, so either one we can find is fine.
if (s.Type == "samples" && s.Unit == "count") ||
(s.Type == "cpu" && s.Unit == "nanoseconds") {
valueIndex = i
break
}
}
if valueIndex == -1 {
log.Fatal("failed to find CPU samples count or CPU nanoseconds value-types in profile.")
return nil
}
g := newGraph(profile, &Options{
CallTree: false,
SampleValue: func(v []int64) int64 { return v[1] },
SampleValue: func(v []int64) int64 { return v[valueIndex] },
})
p := &Profile{

View File

@@ -1757,13 +1757,13 @@
x0:(MOVBstore [i-1] {s} p (SHRWconst [8] w) mem))
&& x0.Uses == 1
&& clobber(x0)
=> (MOVWstore [i-1] {s} p (ROLWconst <w.Type> [8] w) mem)
=> (MOVWstore [i-1] {s} p (ROLWconst <typ.UInt16> [8] w) mem)
(MOVBstore [i] {s} p1 w
x0:(MOVBstore [i] {s} p0 (SHRWconst [8] w) mem))
&& x0.Uses == 1
&& sequentialAddresses(p0, p1, 1)
&& clobber(x0)
=> (MOVWstore [i] {s} p0 (ROLWconst <w.Type> [8] w) mem)
=> (MOVWstore [i] {s} p0 (ROLWconst <typ.UInt16> [8] w) mem)
// Combine stores + shifts into bswap and larger (unaligned) stores
(MOVBstore [i] {s} p w
@@ -1774,7 +1774,7 @@
&& x1.Uses == 1
&& x2.Uses == 1
&& clobber(x0, x1, x2)
=> (MOVLstore [i-3] {s} p (BSWAPL <w.Type> w) mem)
=> (MOVLstore [i-3] {s} p (BSWAPL <typ.UInt32> w) mem)
(MOVBstore [i] {s} p3 w
x2:(MOVBstore [i] {s} p2 (SHRLconst [8] w)
x1:(MOVBstore [i] {s} p1 (SHRLconst [16] w)
@@ -1786,7 +1786,7 @@
&& sequentialAddresses(p1, p2, 1)
&& sequentialAddresses(p2, p3, 1)
&& clobber(x0, x1, x2)
=> (MOVLstore [i] {s} p0 (BSWAPL <w.Type> w) mem)
=> (MOVLstore [i] {s} p0 (BSWAPL <typ.UInt32> w) mem)
(MOVBstore [i] {s} p w
x6:(MOVBstore [i-1] {s} p (SHRQconst [8] w)
@@ -1804,7 +1804,7 @@
&& x5.Uses == 1
&& x6.Uses == 1
&& clobber(x0, x1, x2, x3, x4, x5, x6)
=> (MOVQstore [i-7] {s} p (BSWAPQ <w.Type> w) mem)
=> (MOVQstore [i-7] {s} p (BSWAPQ <typ.UInt64> w) mem)
(MOVBstore [i] {s} p7 w
x6:(MOVBstore [i] {s} p6 (SHRQconst [8] w)
x5:(MOVBstore [i] {s} p5 (SHRQconst [16] w)
@@ -1828,7 +1828,7 @@
&& sequentialAddresses(p5, p6, 1)
&& sequentialAddresses(p6, p7, 1)
&& clobber(x0, x1, x2, x3, x4, x5, x6)
=> (MOVQstore [i] {s} p0 (BSWAPQ <w.Type> w) mem)
=> (MOVQstore [i] {s} p0 (BSWAPQ <typ.UInt64> w) mem)
// Combine constant stores into larger (unaligned) stores.
(MOVBstoreconst [c] {s} p1 x:(MOVBstoreconst [a] {s} p0 mem))
@@ -2180,10 +2180,10 @@
(BSWAP(Q|L) (BSWAP(Q|L) p)) => p
// CPUID feature: MOVBE.
(MOV(Q|L)store [i] {s} p x:(BSWAP(Q|L) w) mem) && x.Uses == 1 && buildcfg.GOAMD64 >= 3 => (MOVBE(Q|L)store [i] {s} p w mem)
(BSWAP(Q|L) x:(MOV(Q|L)load [i] {s} p mem)) && x.Uses == 1 && buildcfg.GOAMD64 >= 3 => (MOVBE(Q|L)load [i] {s} p mem)
(BSWAP(Q|L) (MOVBE(Q|L)load [i] {s} p m)) => (MOV(Q|L)load [i] {s} p m)
(MOVBE(Q|L)store [i] {s} p (BSWAP(Q|L) x) m) => (MOV(Q|L)store [i] {s} p x m)
(MOV(Q|L)store [i] {s} p x:(BSWAP(Q|L) w) mem) && x.Uses == 1 && buildcfg.GOAMD64 >= 3 => (MOVBE(Q|L)store [i] {s} p w mem)
(MOVBE(Q|L)store [i] {s} p x:(BSWAP(Q|L) w) mem) && x.Uses == 1 => (MOV(Q|L)store [i] {s} p w mem)
(BSWAP(Q|L) x:(MOV(Q|L)load [i] {s} p mem)) && x.Uses == 1 && buildcfg.GOAMD64 >= 3 => @x.Block (MOVBE(Q|L)load [i] {s} p mem)
(BSWAP(Q|L) x:(MOVBE(Q|L)load [i] {s} p mem)) && x.Uses == 1 => @x.Block (MOV(Q|L)load [i] {s} p mem)
(MOVWstore [i] {s} p x:(ROLWconst [8] w) mem) && x.Uses == 1 && buildcfg.GOAMD64 >= 3 => (MOVBEWstore [i] {s} p w mem)
(MOVBEWstore [i] {s} p x:(ROLWconst [8] w) mem) && x.Uses == 1 => (MOVWstore [i] {s} p w mem)

View File

@@ -2,14 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// split 3 operand LEA.
// Note: Don't split pointer computations in order to avoid invalid pointers.
(LEA(Q|L|W)1 <t> [c] {s} x y) && isPtr(x.Type) && c != 0 && s == nil => (ADD(Q|L|L) x (ADD(Q|L|L)const <y.Type> [c] y))
(LEA(Q|L|W)1 <t> [c] {s} x y) && !isPtr(x.Type) && c != 0 && s == nil => (ADD(Q|L|L) y (ADD(Q|L|L)const <x.Type> [c] x))
(LEA(Q|L|W)2 <t> [c] {s} x y) && !isPtr(t) && c != 0 && s == nil => (ADD(Q|L|L)const [c] (LEA(Q|L|W)2 <x.Type> x y))
(LEA(Q|L|W)4 <t> [c] {s} x y) && !isPtr(t) && c != 0 && s == nil => (ADD(Q|L|L)const [c] (LEA(Q|L|W)4 <x.Type> x y))
(LEA(Q|L|W)8 <t> [c] {s} x y) && !isPtr(t) && c != 0 && s == nil => (ADD(Q|L|L)const [c] (LEA(Q|L|W)8 <x.Type> x y))
// Prefer SARX/SHLX/SHRX instruction because it has less register restriction on the shift input.
(SAR(Q|L) x y) && buildcfg.GOAMD64 >= 3 => (SARX(Q|L) x y)
(SHL(Q|L) x y) && buildcfg.GOAMD64 >= 3 => (SHLX(Q|L) x y)

View File

@@ -837,25 +837,35 @@
(MOVDaddr [int32(off1)+off2] {sym} ptr)
// fold address into load/store
(MOVBload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
(MOVBload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVBload [off1+int32(off2)] {sym} ptr mem)
(MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
(MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVBUload [off1+int32(off2)] {sym} ptr mem)
(MOVHload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
(MOVHload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVHload [off1+int32(off2)] {sym} ptr mem)
(MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
(MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVHUload [off1+int32(off2)] {sym} ptr mem)
(MOVWload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
(MOVWload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVWload [off1+int32(off2)] {sym} ptr mem)
(MOVWUload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
(MOVWUload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVWUload [off1+int32(off2)] {sym} ptr mem)
(MOVDload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
(MOVDload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVDload [off1+int32(off2)] {sym} ptr mem)
(LDP [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
(LDP [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(LDP [off1+int32(off2)] {sym} ptr mem)
(FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
(FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(FMOVSload [off1+int32(off2)] {sym} ptr mem)
(FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
(FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(FMOVDload [off1+int32(off2)] {sym} ptr mem)
// register indexed load
@@ -920,29 +930,41 @@
(FMOVDloadidx8 ptr (MOVDconst [c]) mem) && is32Bit(c<<3) => (FMOVDload ptr [int32(c)<<3] mem)
(FMOVSloadidx4 ptr (MOVDconst [c]) mem) && is32Bit(c<<2) => (FMOVSload ptr [int32(c)<<2] mem)
(MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) =>
(MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVBstore [off1+int32(off2)] {sym} ptr val mem)
(MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) =>
(MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVHstore [off1+int32(off2)] {sym} ptr val mem)
(MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) =>
(MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVWstore [off1+int32(off2)] {sym} ptr val mem)
(MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) =>
(MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVDstore [off1+int32(off2)] {sym} ptr val mem)
(STP [off1] {sym} (ADDconst [off2] ptr) val1 val2 mem) && is32Bit(int64(off1)+off2) =>
(STP [off1] {sym} (ADDconst [off2] ptr) val1 val2 mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(STP [off1+int32(off2)] {sym} ptr val1 val2 mem)
(FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) =>
(FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(FMOVSstore [off1+int32(off2)] {sym} ptr val mem)
(FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) =>
(FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(FMOVDstore [off1+int32(off2)] {sym} ptr val mem)
(MOVBstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
(MOVBstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVBstorezero [off1+int32(off2)] {sym} ptr mem)
(MOVHstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
(MOVHstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVHstorezero [off1+int32(off2)] {sym} ptr mem)
(MOVWstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
(MOVWstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVWstorezero [off1+int32(off2)] {sym} ptr mem)
(MOVDstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
(MOVDstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVDstorezero [off1+int32(off2)] {sym} ptr mem)
(MOVQstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
(MOVQstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVQstorezero [off1+int32(off2)] {sym} ptr mem)
// register indexed store
@@ -991,71 +1013,93 @@
(FMOVSstoreidx4 ptr (MOVDconst [c]) val mem) && is32Bit(c<<2) => (FMOVSstore [int32(c)<<2] ptr val mem)
(MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVBUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVHUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVWUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVWUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(LDP [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(LDP [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
(MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
(MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
(MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
(STP [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val1 val2 mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(STP [off1+off2] {mergeSym(sym1,sym2)} ptr val1 val2 mem)
(FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
(FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
(MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVQstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
(MOVQstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
// store zero
@@ -2777,7 +2821,7 @@
&& x5.Uses == 1
&& x6.Uses == 1
&& clobber(x0, x1, x2, x3, x4, x5, x6)
=> (MOVDstore [i-7] {s} ptr (REV <w.Type> w) mem)
=> (MOVDstore [i-7] {s} ptr (REV <typ.UInt64> w) mem)
(MOVBstore [7] {s} p w
x0:(MOVBstore [6] {s} p (SRLconst [8] w)
x1:(MOVBstore [5] {s} p (SRLconst [16] w)
@@ -2797,7 +2841,7 @@
&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
&& isSamePtr(p1, p)
&& clobber(x0, x1, x2, x3, x4, x5, x6)
=> (MOVDstoreidx ptr0 idx0 (REV <w.Type> w) mem)
=> (MOVDstoreidx ptr0 idx0 (REV <typ.UInt64> w) mem)
(MOVBstore [i] {s} ptr w
x0:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 24)] w)
x1:(MOVBstore [i-2] {s} ptr (UBFX [armBFAuxInt(16, 16)] w)
@@ -2806,7 +2850,7 @@
&& x1.Uses == 1
&& x2.Uses == 1
&& clobber(x0, x1, x2)
=> (MOVWstore [i-3] {s} ptr (REVW <w.Type> w) mem)
=> (MOVWstore [i-3] {s} ptr (REVW <typ.UInt32> w) mem)
(MOVBstore [3] {s} p w
x0:(MOVBstore [2] {s} p (UBFX [armBFAuxInt(8, 24)] w)
x1:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (UBFX [armBFAuxInt(16, 16)] w)
@@ -2818,7 +2862,7 @@
&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
&& isSamePtr(p1, p)
&& clobber(x0, x1, x2)
=> (MOVWstoreidx ptr0 idx0 (REVW <w.Type> w) mem)
=> (MOVWstoreidx ptr0 idx0 (REVW <typ.UInt32> w) mem)
(MOVBstoreidx ptr (ADDconst [3] idx) w
x0:(MOVBstoreidx ptr (ADDconst [2] idx) (UBFX [armBFAuxInt(8, 24)] w)
x1:(MOVBstoreidx ptr (ADDconst [1] idx) (UBFX [armBFAuxInt(16, 16)] w)
@@ -2827,7 +2871,7 @@
&& x1.Uses == 1
&& x2.Uses == 1
&& clobber(x0, x1, x2)
=> (MOVWstoreidx ptr idx (REVW <w.Type> w) mem)
=> (MOVWstoreidx ptr idx (REVW <typ.UInt32> w) mem)
(MOVBstoreidx ptr idx w
x0:(MOVBstoreidx ptr (ADDconst [1] idx) (UBFX [armBFAuxInt(8, 24)] w)
x1:(MOVBstoreidx ptr (ADDconst [2] idx) (UBFX [armBFAuxInt(16, 16)] w)
@@ -2845,7 +2889,7 @@
&& x1.Uses == 1
&& x2.Uses == 1
&& clobber(x0, x1, x2)
=> (MOVWstore [i-3] {s} ptr (REVW <w.Type> w) mem)
=> (MOVWstore [i-3] {s} ptr (REVW <typ.UInt32> w) mem)
(MOVBstore [3] {s} p w
x0:(MOVBstore [2] {s} p (SRLconst [8] (MOVDreg w))
x1:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (SRLconst [16] (MOVDreg w))
@@ -2857,7 +2901,7 @@
&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
&& isSamePtr(p1, p)
&& clobber(x0, x1, x2)
=> (MOVWstoreidx ptr0 idx0 (REVW <w.Type> w) mem)
=> (MOVWstoreidx ptr0 idx0 (REVW <typ.UInt32> w) mem)
(MOVBstore [i] {s} ptr w
x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] w)
x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] w)
@@ -2866,7 +2910,7 @@
&& x1.Uses == 1
&& x2.Uses == 1
&& clobber(x0, x1, x2)
=> (MOVWstore [i-3] {s} ptr (REVW <w.Type> w) mem)
=> (MOVWstore [i-3] {s} ptr (REVW <typ.UInt32> w) mem)
(MOVBstore [3] {s} p w
x0:(MOVBstore [2] {s} p (SRLconst [8] w)
x1:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (SRLconst [16] w)
@@ -2878,31 +2922,31 @@
&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
&& isSamePtr(p1, p)
&& clobber(x0, x1, x2)
=> (MOVWstoreidx ptr0 idx0 (REVW <w.Type> w) mem)
=> (MOVWstoreidx ptr0 idx0 (REVW <typ.UInt32> w) mem)
(MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (SRLconst [8] w) mem))
&& x.Uses == 1
&& clobber(x)
=> (MOVHstore [i-1] {s} ptr (REV16W <w.Type> w) mem)
=> (MOVHstore [i-1] {s} ptr (REV16W <typ.UInt16> w) mem)
(MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (SRLconst [8] w) mem))
&& x.Uses == 1
&& s == nil
&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
&& clobber(x)
=> (MOVHstoreidx ptr0 idx0 (REV16W <w.Type> w) mem)
=> (MOVHstoreidx ptr0 idx0 (REV16W <typ.UInt16> w) mem)
(MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 8)] w) mem))
&& x.Uses == 1
&& clobber(x)
=> (MOVHstore [i-1] {s} ptr (REV16W <w.Type> w) mem)
=> (MOVHstore [i-1] {s} ptr (REV16W <typ.UInt16> w) mem)
(MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(8, 8)] w) mem))
&& x.Uses == 1
&& s == nil
&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
&& clobber(x)
=> (MOVHstoreidx ptr0 idx0 (REV16W <w.Type> w) mem)
=> (MOVHstoreidx ptr0 idx0 (REV16W <typ.UInt16> w) mem)
(MOVBstoreidx ptr (ADDconst [1] idx) w x:(MOVBstoreidx ptr idx (UBFX [armBFAuxInt(8, 8)] w) mem))
&& x.Uses == 1
&& clobber(x)
=> (MOVHstoreidx ptr idx (REV16W <w.Type> w) mem)
=> (MOVHstoreidx ptr idx (REV16W <typ.UInt16> w) mem)
(MOVBstoreidx ptr idx w x:(MOVBstoreidx ptr (ADDconst [1] idx) (UBFX [armBFAuxInt(8, 8)] w) mem))
&& x.Uses == 1
&& clobber(x)
@@ -2910,23 +2954,23 @@
(MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (SRLconst [8] (MOVDreg w)) mem))
&& x.Uses == 1
&& clobber(x)
=> (MOVHstore [i-1] {s} ptr (REV16W <w.Type> w) mem)
=> (MOVHstore [i-1] {s} ptr (REV16W <typ.UInt16> w) mem)
(MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (SRLconst [8] (MOVDreg w)) mem))
&& x.Uses == 1
&& s == nil
&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
&& clobber(x)
=> (MOVHstoreidx ptr0 idx0 (REV16W <w.Type> w) mem)
=> (MOVHstoreidx ptr0 idx0 (REV16W <typ.UInt16> w) mem)
(MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 24)] w) mem))
&& x.Uses == 1
&& clobber(x)
=> (MOVHstore [i-1] {s} ptr (REV16W <w.Type> w) mem)
=> (MOVHstore [i-1] {s} ptr (REV16W <typ.UInt16> w) mem)
(MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(8, 24)] w) mem))
&& x.Uses == 1
&& s == nil
&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
&& clobber(x)
=> (MOVHstoreidx ptr0 idx0 (REV16W <w.Type> w) mem)
=> (MOVHstoreidx ptr0 idx0 (REV16W <typ.UInt16> w) mem)
// FP simplification
(FNEGS (FMULS x y)) => (FNMULS x y)

View File

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

View File

@@ -855,7 +855,7 @@ func storeOneArg(x *expandState, pos src.XPos, b *Block, locs []*LocalSlot, suff
// storeOneLoad creates a decomposed (one step) load that is then stored.
func storeOneLoad(x *expandState, pos src.XPos, b *Block, source, mem *Value, t *types.Type, offArg, offStore int64, loadRegOffset Abi1RO, storeRc registerCursor) *Value {
from := x.offsetFrom(source.Block, source.Args[0], offArg, types.NewPtr(t))
w := source.Block.NewValue2(source.Pos, OpLoad, t, from, mem)
w := b.NewValue2(source.Pos, OpLoad, t, from, mem)
return x.storeArgOrLoad(pos, b, w, mem, t, offStore, loadRegOffset, storeRc)
}
@@ -962,7 +962,7 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
eltRO := x.regWidth(elt)
source.Type = t
for i := int64(0); i < t.NumElem(); i++ {
sel := source.Block.NewValue1I(pos, OpArraySelect, elt, i, source)
sel := b.NewValue1I(pos, OpArraySelect, elt, i, source)
mem = x.storeArgOrLoad(pos, b, sel, mem, elt, storeOffset+i*elt.Size(), loadRegOffset, storeRc.at(t, 0))
loadRegOffset += eltRO
pos = pos.WithNotStmt()
@@ -997,7 +997,7 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
source.Type = t
for i := 0; i < t.NumFields(); i++ {
fld := t.Field(i)
sel := source.Block.NewValue1I(pos, OpStructSelect, fld.Type, int64(i), source)
sel := b.NewValue1I(pos, OpStructSelect, fld.Type, int64(i), source)
mem = x.storeArgOrLoad(pos, b, sel, mem, fld.Type, storeOffset+fld.Offset, loadRegOffset, storeRc.next(fld.Type))
loadRegOffset += x.regWidth(fld.Type)
pos = pos.WithNotStmt()
@@ -1009,48 +1009,48 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
break
}
tHi, tLo := x.intPairTypes(t.Kind())
sel := source.Block.NewValue1(pos, OpInt64Hi, tHi, source)
sel := b.NewValue1(pos, OpInt64Hi, tHi, source)
mem = x.storeArgOrLoad(pos, b, sel, mem, tHi, storeOffset+x.hiOffset, loadRegOffset+x.hiRo, storeRc.plus(x.hiRo))
pos = pos.WithNotStmt()
sel = source.Block.NewValue1(pos, OpInt64Lo, tLo, source)
sel = b.NewValue1(pos, OpInt64Lo, tLo, source)
return x.storeArgOrLoad(pos, b, sel, mem, tLo, storeOffset+x.lowOffset, loadRegOffset+x.loRo, storeRc.plus(x.hiRo))
case types.TINTER:
sel := source.Block.NewValue1(pos, OpITab, x.typs.BytePtr, source)
sel := b.NewValue1(pos, OpITab, x.typs.BytePtr, source)
mem = x.storeArgOrLoad(pos, b, sel, mem, x.typs.BytePtr, storeOffset, loadRegOffset, storeRc.next(x.typs.BytePtr))
pos = pos.WithNotStmt()
sel = source.Block.NewValue1(pos, OpIData, x.typs.BytePtr, source)
sel = b.NewValue1(pos, OpIData, x.typs.BytePtr, source)
return x.storeArgOrLoad(pos, b, sel, mem, x.typs.BytePtr, storeOffset+x.ptrSize, loadRegOffset+RO_iface_data, storeRc)
case types.TSTRING:
sel := source.Block.NewValue1(pos, OpStringPtr, x.typs.BytePtr, source)
sel := b.NewValue1(pos, OpStringPtr, x.typs.BytePtr, source)
mem = x.storeArgOrLoad(pos, b, sel, mem, x.typs.BytePtr, storeOffset, loadRegOffset, storeRc.next(x.typs.BytePtr))
pos = pos.WithNotStmt()
sel = source.Block.NewValue1(pos, OpStringLen, x.typs.Int, source)
sel = b.NewValue1(pos, OpStringLen, x.typs.Int, source)
return x.storeArgOrLoad(pos, b, sel, mem, x.typs.Int, storeOffset+x.ptrSize, loadRegOffset+RO_string_len, storeRc)
case types.TSLICE:
et := types.NewPtr(t.Elem())
sel := source.Block.NewValue1(pos, OpSlicePtr, et, source)
sel := b.NewValue1(pos, OpSlicePtr, et, source)
mem = x.storeArgOrLoad(pos, b, sel, mem, et, storeOffset, loadRegOffset, storeRc.next(et))
pos = pos.WithNotStmt()
sel = source.Block.NewValue1(pos, OpSliceLen, x.typs.Int, source)
sel = b.NewValue1(pos, OpSliceLen, x.typs.Int, source)
mem = x.storeArgOrLoad(pos, b, sel, mem, x.typs.Int, storeOffset+x.ptrSize, loadRegOffset+RO_slice_len, storeRc.next(x.typs.Int))
sel = source.Block.NewValue1(pos, OpSliceCap, x.typs.Int, source)
sel = b.NewValue1(pos, OpSliceCap, x.typs.Int, source)
return x.storeArgOrLoad(pos, b, sel, mem, x.typs.Int, storeOffset+2*x.ptrSize, loadRegOffset+RO_slice_cap, storeRc)
case types.TCOMPLEX64:
sel := source.Block.NewValue1(pos, OpComplexReal, x.typs.Float32, source)
sel := b.NewValue1(pos, OpComplexReal, x.typs.Float32, source)
mem = x.storeArgOrLoad(pos, b, sel, mem, x.typs.Float32, storeOffset, loadRegOffset, storeRc.next(x.typs.Float32))
pos = pos.WithNotStmt()
sel = source.Block.NewValue1(pos, OpComplexImag, x.typs.Float32, source)
sel = b.NewValue1(pos, OpComplexImag, x.typs.Float32, source)
return x.storeArgOrLoad(pos, b, sel, mem, x.typs.Float32, storeOffset+4, loadRegOffset+RO_complex_imag, storeRc)
case types.TCOMPLEX128:
sel := source.Block.NewValue1(pos, OpComplexReal, x.typs.Float64, source)
sel := b.NewValue1(pos, OpComplexReal, x.typs.Float64, source)
mem = x.storeArgOrLoad(pos, b, sel, mem, x.typs.Float64, storeOffset, loadRegOffset, storeRc.next(x.typs.Float64))
pos = pos.WithNotStmt()
sel = source.Block.NewValue1(pos, OpComplexImag, x.typs.Float64, source)
sel = b.NewValue1(pos, OpComplexImag, x.typs.Float64, source)
return x.storeArgOrLoad(pos, b, sel, mem, x.typs.Float64, storeOffset+8, loadRegOffset+RO_complex_imag, storeRc)
}
@@ -1113,6 +1113,9 @@ func (x *expandState) rewriteArgs(v *Value, firstArg int) {
}
}
}
if x.debug > 1 {
x.Printf("...storeArg %s, %v, %d\n", a.LongString(), aType, aOffset)
}
// "Dereference" of addressed (probably not-SSA-eligible) value becomes Move
// TODO(register args) this will be more complicated with registers in the picture.
mem = x.rewriteDereference(v.Block, sp, a, mem, aOffset, aux.SizeOfArg(auxI), aType, a.Pos)

View File

@@ -856,9 +856,6 @@ func prove(f *Func) {
case OpAnd64, OpAnd32, OpAnd16, OpAnd8:
ft.update(b, v, v.Args[1], unsigned, lt|eq)
ft.update(b, v, v.Args[0], unsigned, lt|eq)
case OpOr64, OpOr32, OpOr16, OpOr8:
ft.update(b, v, v.Args[1], unsigned, gt|eq)
ft.update(b, v, v.Args[0], unsigned, gt|eq)
case OpPhi:
// Determine the min and max value of OpPhi composed entirely of integer constants.
//

View File

@@ -3533,6 +3533,8 @@ func rewriteValueAMD64_OpAMD64BSFQ(v *Value) bool {
}
func rewriteValueAMD64_OpAMD64BSWAPL(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
typ := &b.Func.Config.Types
// match: (BSWAPL (BSWAPL p))
// result: p
for {
@@ -3545,7 +3547,7 @@ func rewriteValueAMD64_OpAMD64BSWAPL(v *Value) bool {
}
// match: (BSWAPL x:(MOVLload [i] {s} p mem))
// cond: x.Uses == 1 && buildcfg.GOAMD64 >= 3
// result: (MOVBELload [i] {s} p mem)
// result: @x.Block (MOVBELload [i] {s} p mem)
for {
x := v_0
if x.Op != OpAMD64MOVLload {
@@ -3558,32 +3560,43 @@ func rewriteValueAMD64_OpAMD64BSWAPL(v *Value) bool {
if !(x.Uses == 1 && buildcfg.GOAMD64 >= 3) {
break
}
v.reset(OpAMD64MOVBELload)
v.AuxInt = int32ToAuxInt(i)
v.Aux = symToAux(s)
v.AddArg2(p, mem)
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVBELload, typ.UInt32)
v.copyOf(v0)
v0.AuxInt = int32ToAuxInt(i)
v0.Aux = symToAux(s)
v0.AddArg2(p, mem)
return true
}
// match: (BSWAPL (MOVBELload [i] {s} p m))
// result: (MOVLload [i] {s} p m)
// match: (BSWAPL x:(MOVBELload [i] {s} p mem))
// cond: x.Uses == 1
// result: @x.Block (MOVLload [i] {s} p mem)
for {
if v_0.Op != OpAMD64MOVBELload {
x := v_0
if x.Op != OpAMD64MOVBELload {
break
}
i := auxIntToInt32(v_0.AuxInt)
s := auxToSym(v_0.Aux)
m := v_0.Args[1]
p := v_0.Args[0]
v.reset(OpAMD64MOVLload)
v.AuxInt = int32ToAuxInt(i)
v.Aux = symToAux(s)
v.AddArg2(p, m)
i := auxIntToInt32(x.AuxInt)
s := auxToSym(x.Aux)
mem := x.Args[1]
p := x.Args[0]
if !(x.Uses == 1) {
break
}
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVLload, typ.UInt32)
v.copyOf(v0)
v0.AuxInt = int32ToAuxInt(i)
v0.Aux = symToAux(s)
v0.AddArg2(p, mem)
return true
}
return false
}
func rewriteValueAMD64_OpAMD64BSWAPQ(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
typ := &b.Func.Config.Types
// match: (BSWAPQ (BSWAPQ p))
// result: p
for {
@@ -3596,7 +3609,7 @@ func rewriteValueAMD64_OpAMD64BSWAPQ(v *Value) bool {
}
// match: (BSWAPQ x:(MOVQload [i] {s} p mem))
// cond: x.Uses == 1 && buildcfg.GOAMD64 >= 3
// result: (MOVBEQload [i] {s} p mem)
// result: @x.Block (MOVBEQload [i] {s} p mem)
for {
x := v_0
if x.Op != OpAMD64MOVQload {
@@ -3609,26 +3622,35 @@ func rewriteValueAMD64_OpAMD64BSWAPQ(v *Value) bool {
if !(x.Uses == 1 && buildcfg.GOAMD64 >= 3) {
break
}
v.reset(OpAMD64MOVBEQload)
v.AuxInt = int32ToAuxInt(i)
v.Aux = symToAux(s)
v.AddArg2(p, mem)
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVBEQload, typ.UInt64)
v.copyOf(v0)
v0.AuxInt = int32ToAuxInt(i)
v0.Aux = symToAux(s)
v0.AddArg2(p, mem)
return true
}
// match: (BSWAPQ (MOVBEQload [i] {s} p m))
// result: (MOVQload [i] {s} p m)
// match: (BSWAPQ x:(MOVBEQload [i] {s} p mem))
// cond: x.Uses == 1
// result: @x.Block (MOVQload [i] {s} p mem)
for {
if v_0.Op != OpAMD64MOVBEQload {
x := v_0
if x.Op != OpAMD64MOVBEQload {
break
}
i := auxIntToInt32(v_0.AuxInt)
s := auxToSym(v_0.Aux)
m := v_0.Args[1]
p := v_0.Args[0]
v.reset(OpAMD64MOVQload)
v.AuxInt = int32ToAuxInt(i)
v.Aux = symToAux(s)
v.AddArg2(p, m)
i := auxIntToInt32(x.AuxInt)
s := auxToSym(x.Aux)
mem := x.Args[1]
p := x.Args[0]
if !(x.Uses == 1) {
break
}
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVQload, typ.UInt64)
v.copyOf(v0)
v0.AuxInt = int32ToAuxInt(i)
v0.Aux = symToAux(s)
v0.AddArg2(p, mem)
return true
}
return false
@@ -9398,21 +9420,26 @@ func rewriteValueAMD64_OpAMD64MOVBELstore(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVBELstore [i] {s} p (BSWAPL x) m)
// result: (MOVLstore [i] {s} p x m)
// match: (MOVBELstore [i] {s} p x:(BSWAPL w) mem)
// cond: x.Uses == 1
// result: (MOVLstore [i] {s} p w mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
p := v_0
if v_1.Op != OpAMD64BSWAPL {
x := v_1
if x.Op != OpAMD64BSWAPL {
break
}
w := x.Args[0]
mem := v_2
if !(x.Uses == 1) {
break
}
x := v_1.Args[0]
m := v_2
v.reset(OpAMD64MOVLstore)
v.AuxInt = int32ToAuxInt(i)
v.Aux = symToAux(s)
v.AddArg3(p, x, m)
v.AddArg3(p, w, mem)
return true
}
return false
@@ -9421,21 +9448,26 @@ func rewriteValueAMD64_OpAMD64MOVBEQstore(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVBEQstore [i] {s} p (BSWAPQ x) m)
// result: (MOVQstore [i] {s} p x m)
// match: (MOVBEQstore [i] {s} p x:(BSWAPQ w) mem)
// cond: x.Uses == 1
// result: (MOVQstore [i] {s} p w mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
p := v_0
if v_1.Op != OpAMD64BSWAPQ {
x := v_1
if x.Op != OpAMD64BSWAPQ {
break
}
w := x.Args[0]
mem := v_2
if !(x.Uses == 1) {
break
}
x := v_1.Args[0]
m := v_2
v.reset(OpAMD64MOVQstore)
v.AuxInt = int32ToAuxInt(i)
v.Aux = symToAux(s)
v.AddArg3(p, x, m)
v.AddArg3(p, w, mem)
return true
}
return false
@@ -10244,7 +10276,7 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
}
// match: (MOVBstore [i] {s} p w x0:(MOVBstore [i-1] {s} p (SHRWconst [8] w) mem))
// cond: x0.Uses == 1 && clobber(x0)
// result: (MOVWstore [i-1] {s} p (ROLWconst <w.Type> [8] w) mem)
// result: (MOVWstore [i-1] {s} p (ROLWconst <typ.UInt16> [8] w) mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
@@ -10265,7 +10297,7 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
v.reset(OpAMD64MOVWstore)
v.AuxInt = int32ToAuxInt(i - 1)
v.Aux = symToAux(s)
v0 := b.NewValue0(x0.Pos, OpAMD64ROLWconst, w.Type)
v0 := b.NewValue0(x0.Pos, OpAMD64ROLWconst, typ.UInt16)
v0.AuxInt = int8ToAuxInt(8)
v0.AddArg(w)
v.AddArg3(p, v0, mem)
@@ -10273,7 +10305,7 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
}
// match: (MOVBstore [i] {s} p1 w x0:(MOVBstore [i] {s} p0 (SHRWconst [8] w) mem))
// cond: x0.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x0)
// result: (MOVWstore [i] {s} p0 (ROLWconst <w.Type> [8] w) mem)
// result: (MOVWstore [i] {s} p0 (ROLWconst <typ.UInt16> [8] w) mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
@@ -10292,7 +10324,7 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
v.reset(OpAMD64MOVWstore)
v.AuxInt = int32ToAuxInt(i)
v.Aux = symToAux(s)
v0 := b.NewValue0(x0.Pos, OpAMD64ROLWconst, w.Type)
v0 := b.NewValue0(x0.Pos, OpAMD64ROLWconst, typ.UInt16)
v0.AuxInt = int8ToAuxInt(8)
v0.AddArg(w)
v.AddArg3(p0, v0, mem)
@@ -10300,7 +10332,7 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
}
// match: (MOVBstore [i] {s} p w x2:(MOVBstore [i-1] {s} p (SHRLconst [8] w) x1:(MOVBstore [i-2] {s} p (SHRLconst [16] w) x0:(MOVBstore [i-3] {s} p (SHRLconst [24] w) mem))))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)
// result: (MOVLstore [i-3] {s} p (BSWAPL <w.Type> w) mem)
// result: (MOVLstore [i-3] {s} p (BSWAPL <typ.UInt32> w) mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
@@ -10345,14 +10377,14 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
v.reset(OpAMD64MOVLstore)
v.AuxInt = int32ToAuxInt(i - 3)
v.Aux = symToAux(s)
v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPL, w.Type)
v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPL, typ.UInt32)
v0.AddArg(w)
v.AddArg3(p, v0, mem)
return true
}
// match: (MOVBstore [i] {s} p3 w x2:(MOVBstore [i] {s} p2 (SHRLconst [8] w) x1:(MOVBstore [i] {s} p1 (SHRLconst [16] w) x0:(MOVBstore [i] {s} p0 (SHRLconst [24] w) mem))))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && sequentialAddresses(p0, p1, 1) && sequentialAddresses(p1, p2, 1) && sequentialAddresses(p2, p3, 1) && clobber(x0, x1, x2)
// result: (MOVLstore [i] {s} p0 (BSWAPL <w.Type> w) mem)
// result: (MOVLstore [i] {s} p0 (BSWAPL <typ.UInt32> w) mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
@@ -10391,14 +10423,14 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
v.reset(OpAMD64MOVLstore)
v.AuxInt = int32ToAuxInt(i)
v.Aux = symToAux(s)
v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPL, w.Type)
v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPL, typ.UInt32)
v0.AddArg(w)
v.AddArg3(p0, v0, mem)
return true
}
// match: (MOVBstore [i] {s} p w x6:(MOVBstore [i-1] {s} p (SHRQconst [8] w) x5:(MOVBstore [i-2] {s} p (SHRQconst [16] w) x4:(MOVBstore [i-3] {s} p (SHRQconst [24] w) x3:(MOVBstore [i-4] {s} p (SHRQconst [32] w) x2:(MOVBstore [i-5] {s} p (SHRQconst [40] w) x1:(MOVBstore [i-6] {s} p (SHRQconst [48] w) x0:(MOVBstore [i-7] {s} p (SHRQconst [56] w) mem))))))))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && clobber(x0, x1, x2, x3, x4, x5, x6)
// result: (MOVQstore [i-7] {s} p (BSWAPQ <w.Type> w) mem)
// result: (MOVQstore [i-7] {s} p (BSWAPQ <typ.UInt64> w) mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
@@ -10491,14 +10523,14 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
v.reset(OpAMD64MOVQstore)
v.AuxInt = int32ToAuxInt(i - 7)
v.Aux = symToAux(s)
v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPQ, w.Type)
v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPQ, typ.UInt64)
v0.AddArg(w)
v.AddArg3(p, v0, mem)
return true
}
// match: (MOVBstore [i] {s} p7 w x6:(MOVBstore [i] {s} p6 (SHRQconst [8] w) x5:(MOVBstore [i] {s} p5 (SHRQconst [16] w) x4:(MOVBstore [i] {s} p4 (SHRQconst [24] w) x3:(MOVBstore [i] {s} p3 (SHRQconst [32] w) x2:(MOVBstore [i] {s} p2 (SHRQconst [40] w) x1:(MOVBstore [i] {s} p1 (SHRQconst [48] w) x0:(MOVBstore [i] {s} p0 (SHRQconst [56] w) mem))))))))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && sequentialAddresses(p0, p1, 1) && sequentialAddresses(p1, p2, 1) && sequentialAddresses(p2, p3, 1) && sequentialAddresses(p3, p4, 1) && sequentialAddresses(p4, p5, 1) && sequentialAddresses(p5, p6, 1) && sequentialAddresses(p6, p7, 1) && clobber(x0, x1, x2, x3, x4, x5, x6)
// result: (MOVQstore [i] {s} p0 (BSWAPQ <w.Type> w) mem)
// result: (MOVQstore [i] {s} p0 (BSWAPQ <typ.UInt64> w) mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
@@ -10577,7 +10609,7 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
v.reset(OpAMD64MOVQstore)
v.AuxInt = int32ToAuxInt(i)
v.Aux = symToAux(s)
v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPQ, w.Type)
v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPQ, typ.UInt64)
v0.AddArg(w)
v.AddArg3(p0, v0, mem)
return true

View File

@@ -7,30 +7,6 @@ import "internal/buildcfg"
func rewriteValueAMD64latelower(v *Value) bool {
switch v.Op {
case OpAMD64LEAL1:
return rewriteValueAMD64latelower_OpAMD64LEAL1(v)
case OpAMD64LEAL2:
return rewriteValueAMD64latelower_OpAMD64LEAL2(v)
case OpAMD64LEAL4:
return rewriteValueAMD64latelower_OpAMD64LEAL4(v)
case OpAMD64LEAL8:
return rewriteValueAMD64latelower_OpAMD64LEAL8(v)
case OpAMD64LEAQ1:
return rewriteValueAMD64latelower_OpAMD64LEAQ1(v)
case OpAMD64LEAQ2:
return rewriteValueAMD64latelower_OpAMD64LEAQ2(v)
case OpAMD64LEAQ4:
return rewriteValueAMD64latelower_OpAMD64LEAQ4(v)
case OpAMD64LEAQ8:
return rewriteValueAMD64latelower_OpAMD64LEAQ8(v)
case OpAMD64LEAW1:
return rewriteValueAMD64latelower_OpAMD64LEAW1(v)
case OpAMD64LEAW2:
return rewriteValueAMD64latelower_OpAMD64LEAW2(v)
case OpAMD64LEAW4:
return rewriteValueAMD64latelower_OpAMD64LEAW4(v)
case OpAMD64LEAW8:
return rewriteValueAMD64latelower_OpAMD64LEAW8(v)
case OpAMD64SARL:
return rewriteValueAMD64latelower_OpAMD64SARL(v)
case OpAMD64SARQ:
@@ -46,375 +22,6 @@ func rewriteValueAMD64latelower(v *Value) bool {
}
return false
}
func rewriteValueAMD64latelower_OpAMD64LEAL1(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (LEAL1 <t> [c] {s} x y)
// cond: isPtr(x.Type) && c != 0 && s == nil
// result: (ADDL x (ADDLconst <y.Type> [c] y))
for {
c := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
y := v_1
if !(isPtr(x.Type) && c != 0 && s == nil) {
continue
}
v.reset(OpAMD64ADDL)
v0 := b.NewValue0(v.Pos, OpAMD64ADDLconst, y.Type)
v0.AuxInt = int32ToAuxInt(c)
v0.AddArg(y)
v.AddArg2(x, v0)
return true
}
break
}
// match: (LEAL1 <t> [c] {s} x y)
// cond: !isPtr(x.Type) && c != 0 && s == nil
// result: (ADDL y (ADDLconst <x.Type> [c] x))
for {
c := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
y := v_1
if !(!isPtr(x.Type) && c != 0 && s == nil) {
continue
}
v.reset(OpAMD64ADDL)
v0 := b.NewValue0(v.Pos, OpAMD64ADDLconst, x.Type)
v0.AuxInt = int32ToAuxInt(c)
v0.AddArg(x)
v.AddArg2(y, v0)
return true
}
break
}
return false
}
func rewriteValueAMD64latelower_OpAMD64LEAL2(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (LEAL2 <t> [c] {s} x y)
// cond: !isPtr(t) && c != 0 && s == nil
// result: (ADDLconst [c] (LEAL2 <x.Type> x y))
for {
t := v.Type
c := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
x := v_0
y := v_1
if !(!isPtr(t) && c != 0 && s == nil) {
break
}
v.reset(OpAMD64ADDLconst)
v.AuxInt = int32ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpAMD64LEAL2, x.Type)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
return false
}
func rewriteValueAMD64latelower_OpAMD64LEAL4(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (LEAL4 <t> [c] {s} x y)
// cond: !isPtr(t) && c != 0 && s == nil
// result: (ADDLconst [c] (LEAL4 <x.Type> x y))
for {
t := v.Type
c := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
x := v_0
y := v_1
if !(!isPtr(t) && c != 0 && s == nil) {
break
}
v.reset(OpAMD64ADDLconst)
v.AuxInt = int32ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpAMD64LEAL4, x.Type)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
return false
}
func rewriteValueAMD64latelower_OpAMD64LEAL8(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (LEAL8 <t> [c] {s} x y)
// cond: !isPtr(t) && c != 0 && s == nil
// result: (ADDLconst [c] (LEAL8 <x.Type> x y))
for {
t := v.Type
c := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
x := v_0
y := v_1
if !(!isPtr(t) && c != 0 && s == nil) {
break
}
v.reset(OpAMD64ADDLconst)
v.AuxInt = int32ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpAMD64LEAL8, x.Type)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
return false
}
func rewriteValueAMD64latelower_OpAMD64LEAQ1(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (LEAQ1 <t> [c] {s} x y)
// cond: isPtr(x.Type) && c != 0 && s == nil
// result: (ADDQ x (ADDQconst <y.Type> [c] y))
for {
c := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
y := v_1
if !(isPtr(x.Type) && c != 0 && s == nil) {
continue
}
v.reset(OpAMD64ADDQ)
v0 := b.NewValue0(v.Pos, OpAMD64ADDQconst, y.Type)
v0.AuxInt = int32ToAuxInt(c)
v0.AddArg(y)
v.AddArg2(x, v0)
return true
}
break
}
// match: (LEAQ1 <t> [c] {s} x y)
// cond: !isPtr(x.Type) && c != 0 && s == nil
// result: (ADDQ y (ADDQconst <x.Type> [c] x))
for {
c := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
y := v_1
if !(!isPtr(x.Type) && c != 0 && s == nil) {
continue
}
v.reset(OpAMD64ADDQ)
v0 := b.NewValue0(v.Pos, OpAMD64ADDQconst, x.Type)
v0.AuxInt = int32ToAuxInt(c)
v0.AddArg(x)
v.AddArg2(y, v0)
return true
}
break
}
return false
}
func rewriteValueAMD64latelower_OpAMD64LEAQ2(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (LEAQ2 <t> [c] {s} x y)
// cond: !isPtr(t) && c != 0 && s == nil
// result: (ADDQconst [c] (LEAQ2 <x.Type> x y))
for {
t := v.Type
c := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
x := v_0
y := v_1
if !(!isPtr(t) && c != 0 && s == nil) {
break
}
v.reset(OpAMD64ADDQconst)
v.AuxInt = int32ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpAMD64LEAQ2, x.Type)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
return false
}
func rewriteValueAMD64latelower_OpAMD64LEAQ4(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (LEAQ4 <t> [c] {s} x y)
// cond: !isPtr(t) && c != 0 && s == nil
// result: (ADDQconst [c] (LEAQ4 <x.Type> x y))
for {
t := v.Type
c := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
x := v_0
y := v_1
if !(!isPtr(t) && c != 0 && s == nil) {
break
}
v.reset(OpAMD64ADDQconst)
v.AuxInt = int32ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpAMD64LEAQ4, x.Type)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
return false
}
func rewriteValueAMD64latelower_OpAMD64LEAQ8(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (LEAQ8 <t> [c] {s} x y)
// cond: !isPtr(t) && c != 0 && s == nil
// result: (ADDQconst [c] (LEAQ8 <x.Type> x y))
for {
t := v.Type
c := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
x := v_0
y := v_1
if !(!isPtr(t) && c != 0 && s == nil) {
break
}
v.reset(OpAMD64ADDQconst)
v.AuxInt = int32ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpAMD64LEAQ8, x.Type)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
return false
}
func rewriteValueAMD64latelower_OpAMD64LEAW1(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (LEAW1 <t> [c] {s} x y)
// cond: isPtr(x.Type) && c != 0 && s == nil
// result: (ADDL x (ADDLconst <y.Type> [c] y))
for {
c := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
y := v_1
if !(isPtr(x.Type) && c != 0 && s == nil) {
continue
}
v.reset(OpAMD64ADDL)
v0 := b.NewValue0(v.Pos, OpAMD64ADDLconst, y.Type)
v0.AuxInt = int32ToAuxInt(c)
v0.AddArg(y)
v.AddArg2(x, v0)
return true
}
break
}
// match: (LEAW1 <t> [c] {s} x y)
// cond: !isPtr(x.Type) && c != 0 && s == nil
// result: (ADDL y (ADDLconst <x.Type> [c] x))
for {
c := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
y := v_1
if !(!isPtr(x.Type) && c != 0 && s == nil) {
continue
}
v.reset(OpAMD64ADDL)
v0 := b.NewValue0(v.Pos, OpAMD64ADDLconst, x.Type)
v0.AuxInt = int32ToAuxInt(c)
v0.AddArg(x)
v.AddArg2(y, v0)
return true
}
break
}
return false
}
func rewriteValueAMD64latelower_OpAMD64LEAW2(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (LEAW2 <t> [c] {s} x y)
// cond: !isPtr(t) && c != 0 && s == nil
// result: (ADDLconst [c] (LEAW2 <x.Type> x y))
for {
t := v.Type
c := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
x := v_0
y := v_1
if !(!isPtr(t) && c != 0 && s == nil) {
break
}
v.reset(OpAMD64ADDLconst)
v.AuxInt = int32ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpAMD64LEAW2, x.Type)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
return false
}
func rewriteValueAMD64latelower_OpAMD64LEAW4(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (LEAW4 <t> [c] {s} x y)
// cond: !isPtr(t) && c != 0 && s == nil
// result: (ADDLconst [c] (LEAW4 <x.Type> x y))
for {
t := v.Type
c := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
x := v_0
y := v_1
if !(!isPtr(t) && c != 0 && s == nil) {
break
}
v.reset(OpAMD64ADDLconst)
v.AuxInt = int32ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpAMD64LEAW4, x.Type)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
return false
}
func rewriteValueAMD64latelower_OpAMD64LEAW8(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (LEAW8 <t> [c] {s} x y)
// cond: !isPtr(t) && c != 0 && s == nil
// result: (ADDLconst [c] (LEAW8 <x.Type> x y))
for {
t := v.Type
c := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
x := v_0
y := v_1
if !(!isPtr(t) && c != 0 && s == nil) {
break
}
v.reset(OpAMD64ADDLconst)
v.AuxInt = int32ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpAMD64LEAW8, x.Type)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
return false
}
func rewriteValueAMD64latelower_OpAMD64SARL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -3203,7 +3203,10 @@ func (s *state) exprCheckPtr(n ir.Node, checkPtrOK bool) *ssa.Value {
n := n.(*ir.UnaryExpr)
a := s.expr(n.X)
if n.X.Type().IsSlice() {
return s.newValue1(ssa.OpSlicePtr, n.Type(), a)
if n.Bounded() {
return s.newValue1(ssa.OpSlicePtr, n.Type(), a)
}
return s.newValue1(ssa.OpSlicePtrUnchecked, n.Type(), a)
} else {
return s.newValue1(ssa.OpStringPtr, n.Type(), a)
}

View File

@@ -615,6 +615,9 @@ func (s *Schedule) staticAssignInlinedCall(l *ir.Name, loff int64, call *ir.Inli
// Build tree with args substituted for params and try it.
args := make(map[*ir.Name]ir.Node)
for i, v := range as2init.Lhs {
if ir.IsBlank(v) {
continue
}
args[v.(*ir.Name)] = as2init.Rhs[i]
}
r, ok := subst(as2body.Rhs[0], args)
@@ -838,7 +841,7 @@ func subst(n ir.Node, m map[*ir.Name]ir.Node) (ir.Node, bool) {
return x
}
x = ir.Copy(x)
ir.EditChildren(x, edit)
ir.EditChildrenWithHidden(x, edit)
if x, ok := x.(*ir.ConvExpr); ok && x.X.Op() == ir.OLITERAL {
// A conversion of variable or expression involving variables
// may become a conversion of constant after inlining the parameters

View File

@@ -7,6 +7,7 @@ package test
import (
"bufio"
"fmt"
"internal/profile"
"internal/testenv"
"io"
"os"
@@ -213,6 +214,73 @@ func TestPGOIntendedInliningShiftedLines(t *testing.T) {
testPGOIntendedInlining(t, dir)
}
// TestPGOSingleIndex tests that the sample index can not be 1 and compilation
// will not fail. All it should care about is that the sample type is either
// CPU nanoseconds or samples count, whichever it finds first.
func TestPGOSingleIndex(t *testing.T) {
for _, tc := range []struct {
originalIndex int
}{{
// The `testdata/pgo/inline/inline_hot.pprof` file is a standard CPU
// profile as the runtime would generate. The 0 index contains the
// value-type samples and value-unit count. The 1 index contains the
// value-type cpu and value-unit nanoseconds. These tests ensure that
// the compiler can work with profiles that only have a single index,
// but are either samples count or CPU nanoseconds.
originalIndex: 0,
}, {
originalIndex: 1,
}} {
t.Run(fmt.Sprintf("originalIndex=%d", tc.originalIndex), func(t *testing.T) {
wd, err := os.Getwd()
if err != nil {
t.Fatalf("error getting wd: %v", err)
}
srcDir := filepath.Join(wd, "testdata/pgo/inline")
// Copy the module to a scratch location so we can add a go.mod.
dir := t.TempDir()
originalPprofFile, err := os.Open(filepath.Join(srcDir, "inline_hot.pprof"))
if err != nil {
t.Fatalf("error opening inline_hot.pprof: %v", err)
}
defer originalPprofFile.Close()
p, err := profile.Parse(originalPprofFile)
if err != nil {
t.Fatalf("error parsing inline_hot.pprof: %v", err)
}
// Move the samples count value-type to the 0 index.
p.SampleType = []*profile.ValueType{p.SampleType[tc.originalIndex]}
// Ensure we only have a single set of sample values.
for _, s := range p.Sample {
s.Value = []int64{s.Value[tc.originalIndex]}
}
modifiedPprofFile, err := os.Create(filepath.Join(dir, "inline_hot.pprof"))
if err != nil {
t.Fatalf("error creating inline_hot.pprof: %v", err)
}
defer modifiedPprofFile.Close()
if err := p.Write(modifiedPprofFile); err != nil {
t.Fatalf("error writing inline_hot.pprof: %v", err)
}
for _, file := range []string{"inline_hot.go", "inline_hot_test.go"} {
if err := copyFile(filepath.Join(dir, file), filepath.Join(srcDir, file)); err != nil {
t.Fatalf("error copying %s: %v", file, err)
}
}
testPGOIntendedInlining(t, dir)
})
}
}
func copyFile(dst, src string) error {
s, err := os.Open(src)
if err != nil {

View File

@@ -34,10 +34,7 @@ func roundFloat(v constant.Value, sz int64) constant.Value {
// truncate float literal fv to 32-bit or 64-bit precision
// according to type; return truncated value.
func truncfltlit(v constant.Value, t *types.Type) constant.Value {
if t.IsUntyped() || overflow(v, t) {
// If there was overflow, simply continuing would set the
// value to Inf which in turn would lead to spurious follow-on
// errors. Avoid this by returning the existing value.
if t.IsUntyped() {
return v
}
@@ -48,10 +45,7 @@ func truncfltlit(v constant.Value, t *types.Type) constant.Value {
// precision, according to type; return truncated value. In case of
// overflow, calls Errorf but does not truncate the input value.
func trunccmplxlit(v constant.Value, t *types.Type) constant.Value {
if t.IsUntyped() || overflow(v, t) {
// If there was overflow, simply continuing would set the
// value to Inf which in turn would lead to spurious follow-on
// errors. Avoid this by returning the existing value.
if t.IsUntyped() {
return v
}
@@ -251,7 +245,6 @@ func convertVal(v constant.Value, t *types.Type, explicit bool) constant.Value {
switch {
case t.IsInteger():
v = toint(v)
overflow(v, t)
return v
case t.IsFloat():
v = toflt(v)
@@ -273,9 +266,6 @@ func tocplx(v constant.Value) constant.Value {
func toflt(v constant.Value) constant.Value {
if v.Kind() == constant.Complex {
if constant.Sign(constant.Imag(v)) != 0 {
base.Errorf("constant %v truncated to real", v)
}
v = constant.Real(v)
}
@@ -284,9 +274,6 @@ func toflt(v constant.Value) constant.Value {
func toint(v constant.Value) constant.Value {
if v.Kind() == constant.Complex {
if constant.Sign(constant.Imag(v)) != 0 {
base.Errorf("constant %v truncated to integer", v)
}
v = constant.Real(v)
}
@@ -321,25 +308,6 @@ func toint(v constant.Value) constant.Value {
return constant.MakeInt64(1)
}
// overflow reports whether constant value v is too large
// to represent with type t, and emits an error message if so.
func overflow(v constant.Value, t *types.Type) bool {
// v has already been converted
// to appropriate form for t.
if t.IsUntyped() {
return false
}
if v.Kind() == constant.Int && constant.BitLen(v) > ir.ConstPrec {
base.Errorf("integer too large")
return true
}
if ir.ConstOverflow(v, t) {
base.Errorf("constant %v overflows %v", types.FmtConst(v, false), t)
return true
}
return false
}
func tostr(v constant.Value) constant.Value {
if v.Kind() == constant.Int {
r := unicode.ReplacementChar
@@ -399,29 +367,7 @@ func EvalConst(n ir.Node) ir.Node {
}
case ir.OADD, ir.OSUB, ir.OMUL, ir.ODIV, ir.OMOD, ir.OOR, ir.OXOR, ir.OAND, ir.OANDNOT:
n := n.(*ir.BinaryExpr)
nl, nr := n.X, n.Y
if nl.Op() == ir.OLITERAL && nr.Op() == ir.OLITERAL {
rval := nr.Val()
// check for divisor underflow in complex division (see issue 20227)
if n.Op() == ir.ODIV && n.Type().IsComplex() && constant.Sign(square(constant.Real(rval))) == 0 && constant.Sign(square(constant.Imag(rval))) == 0 {
base.Errorf("complex division by zero")
n.SetType(nil)
return n
}
if (n.Op() == ir.ODIV || n.Op() == ir.OMOD) && constant.Sign(rval) == 0 {
base.Errorf("division by zero")
n.SetType(nil)
return n
}
tok := tokenForOp[n.Op()]
if n.Op() == ir.ODIV && n.Type().IsInteger() {
tok = token.QUO_ASSIGN // integer division
}
return OrigConst(n, constant.BinaryOp(nl.Val(), tok, rval))
}
return n
case ir.OOROR, ir.OANDAND:
n := n.(*ir.LogicalExpr)
@@ -438,19 +384,7 @@ func EvalConst(n ir.Node) ir.Node {
}
case ir.OLSH, ir.ORSH:
n := n.(*ir.BinaryExpr)
nl, nr := n.X, n.Y
if nl.Op() == ir.OLITERAL && nr.Op() == ir.OLITERAL {
// shiftBound from go/types; "so we can express smallestFloat64" (see issue #44057)
const shiftBound = 1023 - 1 + 52
s, ok := constant.Uint64Val(nr.Val())
if !ok || s > shiftBound {
base.Errorf("invalid shift count %v", nr)
n.SetType(nil)
break
}
return OrigConst(n, constant.Shift(toint(nl.Val()), tokenForOp[n.Op()], uint(s)))
}
return n
case ir.OCONV, ir.ORUNESTR:
n := n.(*ir.ConvExpr)

View File

@@ -184,13 +184,6 @@ func tcArith(n ir.Node, op ir.Op, l, r ir.Node) (ir.Node, ir.Node, *types.Type)
}
}
if (op == ir.ODIV || op == ir.OMOD) && ir.IsConst(r, constant.Int) {
if constant.Sign(r.Val()) == 0 {
base.Errorf("division by zero")
return l, r, nil
}
}
return l, r, t
}

View File

@@ -71,7 +71,7 @@ func typecheckrangeExpr(n *ir.RangeStmt) {
do := func(nn ir.Node, t *types.Type) {
if nn != nil {
if ir.DeclaredBy(nn, n) {
if ir.DeclaredBy(nn, n) && nn.Type() == nil {
nn.SetType(t)
} else if nn.Type() != nil {
if op, why := Assignop(t, nn.Type()); op == ir.OXXX {

View File

@@ -1982,6 +1982,29 @@ func TestIdenticalUnions(t *testing.T) {
}
}
func TestIssue61737(t *testing.T) {
// This test verifies that it is possible to construct invalid interfaces
// containing duplicate methods using the go/types API.
//
// It must be possible for importers to construct such invalid interfaces.
// Previously, this panicked.
sig1 := NewSignatureType(nil, nil, nil, NewTuple(NewParam(nopos, nil, "", Typ[Int])), nil, false)
sig2 := NewSignatureType(nil, nil, nil, NewTuple(NewParam(nopos, nil, "", Typ[String])), nil, false)
methods := []*Func{
NewFunc(nopos, nil, "M", sig1),
NewFunc(nopos, nil, "M", sig2),
}
embeddedMethods := []*Func{
NewFunc(nopos, nil, "M", sig2),
}
embedded := NewInterfaceType(embeddedMethods, nil)
iface := NewInterfaceType(methods, []Type{embedded})
iface.NumMethods() // unlike go/types, there is no Complete() method, so we complete implicitly
}
func TestIssue15305(t *testing.T) {
const src = "package p; func f() int16; var _ = f(undef)"
f := mustParse("issue15305.go", src)

View File

@@ -6,7 +6,6 @@ package types2
import (
"cmd/compile/internal/syntax"
"fmt"
. "internal/types/errors"
"sort"
"strings"
@@ -212,7 +211,6 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *_
// we can get rid of the mpos map below and simply use the cloned method's
// position.
var todo []*Func
var seen objset
var allMethods []*Func
mpos := make(map[*Func]syntax.Pos) // method specification or method embedding position, for good error messages
@@ -222,36 +220,30 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *_
allMethods = append(allMethods, m)
mpos[m] = pos
case explicit:
if check == nil {
panic(fmt.Sprintf("%s: duplicate method %s", m.pos, m.name))
if check != nil {
var err error_
err.code = DuplicateDecl
err.errorf(pos, "duplicate method %s", m.name)
err.errorf(mpos[other.(*Func)], "other declaration of %s", m.name)
check.report(&err)
}
// check != nil
var err error_
err.code = DuplicateDecl
err.errorf(pos, "duplicate method %s", m.name)
err.errorf(mpos[other.(*Func)], "other declaration of %s", m.name)
check.report(&err)
default:
// We have a duplicate method name in an embedded (not explicitly declared) method.
// Check method signatures after all types are computed (issue #33656).
// If we're pre-go1.14 (overlapping embeddings are not permitted), report that
// error here as well (even though we could do it eagerly) because it's the same
// error message.
if check == nil {
// check method signatures after all locally embedded interfaces are computed
todo = append(todo, m, other.(*Func))
break
if check != nil {
check.later(func() {
if !check.allowVersion(m.pkg, 1, 14) || !Identical(m.typ, other.Type()) {
var err error_
err.code = DuplicateDecl
err.errorf(pos, "duplicate method %s", m.name)
err.errorf(mpos[other.(*Func)], "other declaration of %s", m.name)
check.report(&err)
}
}).describef(pos, "duplicate method check for %s", m.name)
}
// check != nil
check.later(func() {
if !check.allowVersion(m.pkg, 1, 14) || !Identical(m.typ, other.Type()) {
var err error_
err.code = DuplicateDecl
err.errorf(pos, "duplicate method %s", m.name)
err.errorf(mpos[other.(*Func)], "other declaration of %s", m.name)
check.report(&err)
}
}).describef(pos, "duplicate method check for %s", m.name)
}
}
@@ -317,15 +309,6 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *_
}
ityp.embedPos = nil // not needed anymore (errors have been reported)
// process todo's (this only happens if check == nil)
for i := 0; i < len(todo); i += 2 {
m := todo[i]
other := todo[i+1]
if !Identical(m.typ, other.typ) {
panic(fmt.Sprintf("%s: duplicate method %s", m.pos, m.name))
}
}
ityp.tset.comparable = allComparable
if len(allMethods) != 0 {
sortMethods(allMethods)

View File

@@ -281,7 +281,9 @@ func walkStringToBytes(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
// Copy from the static string data to the [n]byte.
if len(sc) > 0 {
as := ir.NewAssignStmt(base.Pos, ir.NewStarExpr(base.Pos, p), ir.NewStarExpr(base.Pos, typecheck.ConvNop(ir.NewUnaryExpr(base.Pos, ir.OSPTR, s), t.PtrTo())))
sptr := ir.NewUnaryExpr(base.Pos, ir.OSPTR, s)
sptr.SetBounded(true)
as := ir.NewAssignStmt(base.Pos, ir.NewStarExpr(base.Pos, p), ir.NewStarExpr(base.Pos, typecheck.ConvNop(sptr, t.PtrTo())))
appendWalkStmt(init, as)
}

View File

@@ -191,6 +191,7 @@ func walkRange(nrange *ir.RangeStmt) ir.Node {
// Pointer to current iteration position. Start on entry to the loop
// with the pointer in hu.
ptr := ir.NewUnaryExpr(base.Pos, ir.OSPTR, hs)
ptr.SetBounded(true)
huVal := ir.NewConvExpr(base.Pos, ir.OCONVNOP, types.Types[types.TUNSAFEPTR], ptr)
huVal = ir.NewConvExpr(base.Pos, ir.OCONVNOP, types.Types[types.TUINTPTR], huVal)
hu := typecheck.Temp(types.Types[types.TUINTPTR])

View File

@@ -288,6 +288,7 @@ func (d *dstate) VisitFunc(pkgIdx uint32, fnIdx uint32, fd *coverage.FuncDesc) {
}
fmt.Printf("\nFunc: %s\n", fd.Funcname)
fmt.Printf("Srcfile: %s\n", fd.Srcfile)
fmt.Printf("Literal: %v\n", fd.Lit)
}
for i := 0; i < len(fd.Units); i++ {
u := fd.Units[i]

View File

@@ -568,6 +568,11 @@ func annotate(names []string) {
}
// TODO: process files in parallel here if it matters.
for k, name := range names {
if strings.ContainsAny(name, "\r\n") {
// annotateFile uses '//line' directives, which don't permit newlines.
log.Fatalf("cover: input path contains newline character: %q", name)
}
last := false
if k == len(names)-1 {
last = true
@@ -645,6 +650,11 @@ func (p *Package) annotateFile(name string, fd io.Writer, last bool) {
}
newContent := file.edit.Bytes()
if strings.ContainsAny(name, "\r\n") {
// This should have been checked by the caller already, but we double check
// here just to be sure we haven't missed a caller somewhere.
panic(fmt.Sprintf("annotateFile: name contains unexpected newline character: %q", name))
}
fmt.Fprintf(fd, "//line %s:1:1\n", name)
fd.Write(newContent)

View File

@@ -574,3 +574,34 @@ func runExpectingError(c *exec.Cmd, t *testing.T) string {
}
return string(out)
}
func TestSrcPathWithNewline(t *testing.T) {
testenv.MustHaveExec(t)
t.Parallel()
// srcPath is intentionally not clean so that the path passed to testcover
// will not normalize the trailing / to a \ on Windows.
srcPath := t.TempDir() + string(filepath.Separator) + "\npackage main\nfunc main() { panic(string([]rune{'u', 'h', '-', 'o', 'h'}))\n/*/main.go"
mainSrc := ` package main
func main() {
/* nothing here */
println("ok")
}
`
if err := os.MkdirAll(filepath.Dir(srcPath), 0777); err != nil {
t.Skipf("creating directory with bogus path: %v", err)
}
if err := os.WriteFile(srcPath, []byte(mainSrc), 0666); err != nil {
t.Skipf("writing file with bogus directory: %v", err)
}
cmd := testenv.Command(t, testcover(t), "-mode=atomic", srcPath)
cmd.Stderr = new(bytes.Buffer)
out, err := cmd.Output()
t.Logf("%v:\n%s", cmd, out)
t.Logf("stderr:\n%s", cmd.Stderr)
if err == nil {
t.Errorf("unexpected success; want failure due to newline in file path")
}
}

View File

@@ -9,7 +9,7 @@ require (
golang.org/x/sync v0.1.0
golang.org/x/sys v0.3.0
golang.org/x/term v0.2.0
golang.org/x/tools v0.3.1-0.20221121233702-060c049c4674
golang.org/x/tools v0.3.1-0.20230118190848-070db2996ebe
)
require github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2 // indirect

View File

@@ -12,5 +12,5 @@ golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/tools v0.3.1-0.20221121233702-060c049c4674 h1:Lv0Y+JVwLQF2YThz8ImE7rP2FSv/IzV9lS2k7bvua6U=
golang.org/x/tools v0.3.1-0.20221121233702-060c049c4674/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
golang.org/x/tools v0.3.1-0.20230118190848-070db2996ebe h1:1B2tjdkEp2f885xTfSsY+7mi5fNZHRxWciDl8Hz3EXg=
golang.org/x/tools v0.3.1-0.20230118190848-070db2996ebe/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=

View File

@@ -565,6 +565,11 @@
// generator, containing the Go toolchain and standard library.
// $DOLLAR
// A dollar sign.
// $PATH
// The $PATH of the parent process, with $GOROOT/bin
// placed at the beginning. This causes generators
// that execute 'go' commands to use the same 'go'
// as the parent 'go generate' command.
//
// Other than variable substitution and quoted-string evaluation, no
// special processing such as "globbing" is performed on the command
@@ -1697,6 +1702,10 @@
// error. (The go command's standard error is reserved for printing
// errors building the tests.)
//
// The go command places $GOROOT/bin at the beginning of $PATH
// in the test's environment, so that tests that execute
// 'go' commands use the same 'go' as the parent 'go test' command.
//
// Go test runs in two different modes:
//
// The first, called local directory mode, occurs when go test is

View File

@@ -69,14 +69,10 @@ var exeSuffix string = func() string {
return ""
}()
func tooSlow(t *testing.T) {
func tooSlow(t *testing.T, reason string) {
if testing.Short() {
// In -short mode; skip test, except run it on the {darwin,linux,windows}/amd64 builders.
if testenv.Builder() != "" && runtime.GOARCH == "amd64" && (runtime.GOOS == "linux" || runtime.GOOS == "darwin" || runtime.GOOS == "windows") {
return
}
t.Helper()
t.Skip("skipping test in -short mode")
t.Skipf("skipping test in -short mode: %s", reason)
}
}
@@ -1085,7 +1081,7 @@ func TestPackageMainTestCompilerFlags(t *testing.T) {
// Issue 4104.
func TestGoTestWithPackageListedMultipleTimes(t *testing.T) {
tooSlow(t)
tooSlow(t, "links and runs a test")
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
@@ -1096,7 +1092,7 @@ func TestGoTestWithPackageListedMultipleTimes(t *testing.T) {
}
func TestGoListHasAConsistentOrder(t *testing.T) {
tooSlow(t)
tooSlow(t, "walks all of GOROOT/src twice")
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
@@ -1109,7 +1105,7 @@ func TestGoListHasAConsistentOrder(t *testing.T) {
}
func TestGoListStdDoesNotIncludeCommands(t *testing.T) {
tooSlow(t)
tooSlow(t, "walks all of GOROOT/src")
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
@@ -1119,7 +1115,7 @@ func TestGoListStdDoesNotIncludeCommands(t *testing.T) {
func TestGoListCmdOnlyShowsCommands(t *testing.T) {
skipIfGccgo(t, "gccgo does not have GOROOT")
tooSlow(t)
tooSlow(t, "walks all of GOROOT/src/cmd")
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
@@ -1202,7 +1198,8 @@ func TestGoListTest(t *testing.T) {
}
func TestGoListCompiledCgo(t *testing.T) {
tooSlow(t)
tooSlow(t, "compiles cgo files")
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
@@ -1423,7 +1420,7 @@ func TestDefaultGOPATHPrintedSearchList(t *testing.T) {
func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) {
skipIfGccgo(t, "gccgo does not support -ldflags -X")
tooSlow(t)
tooSlow(t, "compiles and links a binary")
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
@@ -1440,7 +1437,7 @@ func TestLdFlagsLongArgumentsIssue42295(t *testing.T) {
// Test the extremely long command line arguments that contain '\n' characters
// get encoded and passed correctly.
skipIfGccgo(t, "gccgo does not support -ldflags -X")
tooSlow(t)
tooSlow(t, "compiles and links a binary")
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
@@ -1462,7 +1459,7 @@ func TestLdFlagsLongArgumentsIssue42295(t *testing.T) {
func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) {
skipIfGccgo(t, "gccgo has no standard packages")
tooSlow(t)
tooSlow(t, "compiles and links a test binary")
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
@@ -1473,7 +1470,7 @@ func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) {
func TestGoTestDashOWritesBinary(t *testing.T) {
skipIfGccgo(t, "gccgo has no standard packages")
tooSlow(t)
tooSlow(t, "compiles and runs a test binary")
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
@@ -1484,7 +1481,7 @@ func TestGoTestDashOWritesBinary(t *testing.T) {
// Issue 4515.
func TestInstallWithTags(t *testing.T) {
tooSlow(t)
tooSlow(t, "compiles and links binaries")
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
@@ -1553,7 +1550,7 @@ func TestCgoShowsFullPathNames(t *testing.T) {
}
func TestCgoHandlesWlORIGIN(t *testing.T) {
tooSlow(t)
tooSlow(t, "compiles cgo files")
if !canCgo {
t.Skip("skipping because cgo not enabled")
}
@@ -1571,7 +1568,7 @@ func TestCgoHandlesWlORIGIN(t *testing.T) {
}
func TestCgoPkgConfig(t *testing.T) {
tooSlow(t)
tooSlow(t, "compiles cgo files")
if !canCgo {
t.Skip("skipping because cgo not enabled")
}
@@ -1656,7 +1653,7 @@ func TestListTemplateContextFunction(t *testing.T) {
// accessed by a non-local import (found in a GOPATH/GOROOT).
// See golang.org/issue/17475.
func TestImportLocal(t *testing.T) {
tooSlow(t)
tooSlow(t, "builds a lot of sequential packages")
tg := testgo(t)
tg.parallel()
@@ -1814,7 +1811,7 @@ func TestGoInstallPkgdir(t *testing.T) {
// for the install.
t.Skip("skipping because cgo not enabled")
}
tooSlow(t)
tooSlow(t, "builds a package with cgo dependencies")
tg := testgo(t)
tg.parallel()
@@ -1829,7 +1826,7 @@ func TestGoInstallPkgdir(t *testing.T) {
// For issue 14337.
func TestParallelTest(t *testing.T) {
tooSlow(t)
tooSlow(t, "links and runs test binaries")
tg := testgo(t)
tg.parallel()
defer tg.cleanup()
@@ -1849,7 +1846,7 @@ func TestParallelTest(t *testing.T) {
}
func TestBinaryOnlyPackages(t *testing.T) {
tooSlow(t)
tooSlow(t, "compiles several packages sequentially")
tg := testgo(t)
defer tg.cleanup()
@@ -2051,7 +2048,7 @@ func TestFFLAGS(t *testing.T) {
// This is really a cmd/link issue but this is a convenient place to test it.
func TestDuplicateGlobalAsmSymbols(t *testing.T) {
skipIfGccgo(t, "gccgo does not use cmd/asm")
tooSlow(t)
tooSlow(t, "links a binary with cgo dependencies")
if runtime.GOARCH != "386" && runtime.GOARCH != "amd64" {
t.Skipf("skipping test on %s", runtime.GOARCH)
}
@@ -2350,10 +2347,11 @@ func TestUpxCompression(t *testing.T) {
var gocacheverify = godebug.New("gocacheverify")
func TestCacheListStale(t *testing.T) {
tooSlow(t)
tooSlow(t, "links a binary")
if gocacheverify.Value() == "1" {
t.Skip("GODEBUG gocacheverify")
}
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
@@ -2372,8 +2370,7 @@ func TestCacheListStale(t *testing.T) {
}
func TestCacheCoverage(t *testing.T) {
tooSlow(t)
tooSlow(t, "links and runs a test binary with coverage enabled")
if gocacheverify.Value() == "1" {
t.Skip("GODEBUG gocacheverify")
}
@@ -2407,10 +2404,11 @@ func TestIssue22588(t *testing.T) {
}
func TestIssue22531(t *testing.T) {
tooSlow(t)
tooSlow(t, "links binaries")
if gocacheverify.Value() == "1" {
t.Skip("GODEBUG gocacheverify")
}
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
@@ -2436,10 +2434,11 @@ func TestIssue22531(t *testing.T) {
}
func TestIssue22596(t *testing.T) {
tooSlow(t)
tooSlow(t, "links binaries")
if gocacheverify.Value() == "1" {
t.Skip("GODEBUG gocacheverify")
}
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
@@ -2465,7 +2464,7 @@ func TestIssue22596(t *testing.T) {
}
func TestTestCache(t *testing.T) {
tooSlow(t)
tooSlow(t, "links and runs test binaries")
if gocacheverify.Value() == "1" {
t.Skip("GODEBUG gocacheverify")
@@ -2572,7 +2571,8 @@ func TestTestSkipVetAfterFailedBuild(t *testing.T) {
}
func TestTestVetRebuild(t *testing.T) {
tooSlow(t)
tooSlow(t, "links and runs test binaries")
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
@@ -2612,7 +2612,8 @@ func TestTestVetRebuild(t *testing.T) {
}
func TestInstallDeps(t *testing.T) {
tooSlow(t)
tooSlow(t, "links a binary")
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
@@ -2643,7 +2644,8 @@ func TestInstallDeps(t *testing.T) {
// Issue 22986.
func TestImportPath(t *testing.T) {
tooSlow(t)
tooSlow(t, "links and runs a test binary")
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
@@ -2744,7 +2746,8 @@ func TestTwoPkgConfigs(t *testing.T) {
if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
t.Skipf("no shell scripts on %s", runtime.GOOS)
}
tooSlow(t)
tooSlow(t, "builds a package with cgo dependencies")
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
@@ -2775,7 +2778,7 @@ func TestCgoCache(t *testing.T) {
if !canCgo {
t.Skip("no cgo")
}
tooSlow(t)
tooSlow(t, "builds a package with cgo dependencies")
tg := testgo(t)
defer tg.cleanup()
@@ -2828,7 +2831,7 @@ func TestLinkerTmpDirIsDeleted(t *testing.T) {
if !canCgo {
t.Skip("skipping because cgo not enabled")
}
tooSlow(t)
tooSlow(t, "builds a package with cgo dependencies")
tg := testgo(t)
defer tg.cleanup()
@@ -2875,7 +2878,8 @@ func TestLinkerTmpDirIsDeleted(t *testing.T) {
// Issue 25093.
func TestCoverpkgTestOnly(t *testing.T) {
skipIfGccgo(t, "gccgo has no cover tool")
tooSlow(t)
tooSlow(t, "links and runs a test binary with coverage enabled")
tg := testgo(t)
defer tg.cleanup()
tg.parallel()

View File

@@ -2,12 +2,18 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
//go:build unix
package main_test
import (
"bufio"
"context"
"internal/testenv"
"io"
"os"
"os/exec"
"strings"
"syscall"
"testing"
)
@@ -33,3 +39,80 @@ func TestGoBuildUmask(t *testing.T) {
t.Fatalf("wrote x with mode=%v, wanted no 0077 bits", mode)
}
}
// TestTestInterrupt verifies the fix for issue #60203.
//
// If the whole process group for a 'go test' invocation receives
// SIGINT (as would be sent by pressing ^C on a console),
// it should return quickly, not deadlock.
func TestTestInterrupt(t *testing.T) {
if testing.Short() {
t.Skipf("skipping in short mode: test executes many subprocesses")
}
// Don't run this test in parallel, for the same reason.
tg := testgo(t)
defer tg.cleanup()
tg.setenv("GOROOT", testGOROOT)
ctx, cancel := context.WithCancel(context.Background())
cmd := testenv.CommandContext(t, ctx, tg.goTool(), "test", "std", "-short", "-count=1")
cmd.Dir = tg.execDir
// Override $TMPDIR when running the tests: since we're terminating the tests
// with a signal they might fail to clean up some temp files, and we don't
// want that to cause an "unexpected files" failure at the end of the run.
cmd.Env = append(tg.env[:len(tg.env):len(tg.env)], tempEnvName()+"="+t.TempDir())
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
}
cmd.Cancel = func() error {
pgid := cmd.Process.Pid
return syscall.Kill(-pgid, syscall.SIGINT)
}
pipe, err := cmd.StdoutPipe()
if err != nil {
t.Fatal(err)
}
t.Logf("running %v", cmd)
if err := cmd.Start(); err != nil {
t.Fatal(err)
}
stdout := new(strings.Builder)
r := bufio.NewReader(pipe)
line, err := r.ReadString('\n')
if err != nil {
t.Fatal(err)
}
stdout.WriteString(line)
// The output line for some test was written, so we know things are in progress.
//
// Cancel the rest of the run by sending SIGINT to the process group:
// it should finish up and exit with a nonzero status,
// not have to be killed with SIGKILL.
cancel()
io.Copy(stdout, r)
if stdout.Len() > 0 {
t.Logf("stdout:\n%s", stdout)
}
err = cmd.Wait()
ee, _ := err.(*exec.ExitError)
if ee == nil {
t.Fatalf("unexpectedly finished with nonzero status")
}
if len(ee.Stderr) > 0 {
t.Logf("stderr:\n%s", ee.Stderr)
}
if !ee.Exited() {
t.Fatalf("'go test' did not exit after interrupt: %v", err)
}
t.Logf("interrupted tests without deadlocking")
}

View File

@@ -89,6 +89,11 @@ Go generate sets several variables when it runs the generator:
generator, containing the Go toolchain and standard library.
$DOLLAR
A dollar sign.
$PATH
The $PATH of the parent process, with $GOROOT/bin
placed at the beginning. This causes generators
that execute 'go' commands to use the same 'go'
as the parent 'go generate' command.
Other than variable substitution and quoted-string evaluation, no
special processing such as "globbing" is performed on the command

View File

@@ -646,7 +646,7 @@ func runList(ctx context.Context, cmd *base.Command, args []string) {
} else {
pmain, ptest, pxtest, err = load.TestPackagesFor(ctx, pkgOpts, p, nil)
if err != nil {
base.Errorf("can't load test package: %s", err)
base.Errorf("go: can't load test package: %s", err)
}
}
if pmain != nil {

View File

@@ -1960,6 +1960,10 @@ func (p *Package) load(ctx context.Context, opts PackageOpts, path string, stk *
setError(fmt.Errorf("invalid input directory name %q", name))
return
}
if strings.ContainsAny(p.Dir, "\r\n") {
setError(fmt.Errorf("invalid package directory %q", p.Dir))
return
}
// Build list of imported packages and full dependency list.
imports := make([]*Package, 0, len(p.Imports))

View File

@@ -404,18 +404,6 @@ var codeRepoTests = []codeRepoTest{
zipSum: "h1:YJYZRsM9BHFTlVr8YADjT0cJH8uFIDtoc5NLiVqZEx8=",
zipFileHash: "c15e49d58b7a4c37966cbe5bc01a0330cd5f2927e990e1839bda1d407766d9c5",
},
{
vcs: "git",
path: "gopkg.in/natefinch/lumberjack.v2",
rev: "latest",
version: "v2.0.0-20170531160350-a96e63847dc3",
name: "a96e63847dc3c67d17befa69c303767e2f84e54f",
short: "a96e63847dc3",
time: time.Date(2017, 5, 31, 16, 3, 50, 0, time.UTC),
gomod: "module gopkg.in/natefinch/lumberjack.v2\n",
zipSum: "h1:AFxeG48hTWHhDTQDk/m2gorfVHUEa9vo3tp3D7TzwjI=",
zipFileHash: "b5de0da7bbbec76709eef1ac71b6c9ff423b9fbf3bb97b56743450d4937b06d5",
},
{
vcs: "git",
path: "gopkg.in/natefinch/lumberjack.v2",
@@ -818,11 +806,6 @@ var codeRepoVersionsTests = []struct {
path: "swtch.com/testmod",
versions: []string{"v1.0.0", "v1.1.1"},
},
{
vcs: "git",
path: "gopkg.in/natefinch/lumberjack.v2",
versions: []string{"v2.0.0"},
},
{
vcs: "git",
path: "vcs-test.golang.org/git/odd-tags.git",

View File

@@ -162,7 +162,7 @@ func GetModule(modroot string) (*Module, error) {
return nil, errNotFromModuleCache
}
modroot = filepath.Clean(modroot)
if !str.HasFilePathPrefix(modroot, cfg.GOMODCACHE) {
if str.HasFilePathPrefix(modroot, cfg.GOROOTsrc) || !str.HasFilePathPrefix(modroot, cfg.GOMODCACHE) {
return nil, errNotFromModuleCache
}
return openIndexModule(modroot, true)

View File

@@ -10,6 +10,7 @@ import (
"cmd/go/internal/mvs"
"cmd/go/internal/par"
"context"
"errors"
"fmt"
"os"
"reflect"
@@ -689,8 +690,8 @@ func updateWorkspaceRoots(ctx context.Context, rs *Requirements, add []module.Ve
// roots) until the set of roots has converged.
func tidyPrunedRoots(ctx context.Context, mainModule module.Version, direct map[string]bool, pkgs []*loadPkg) (*Requirements, error) {
var (
roots []module.Version
pathIncluded = map[string]bool{mainModule.Path: true}
roots []module.Version
pathIsRoot = map[string]bool{mainModule.Path: true}
)
// We start by adding roots for every package in "all".
//
@@ -710,9 +711,9 @@ func tidyPrunedRoots(ctx context.Context, mainModule module.Version, direct map[
if !pkg.flags.has(pkgInAll) {
continue
}
if pkg.fromExternalModule() && !pathIncluded[pkg.mod.Path] {
if pkg.fromExternalModule() && !pathIsRoot[pkg.mod.Path] {
roots = append(roots, pkg.mod)
pathIncluded[pkg.mod.Path] = true
pathIsRoot[pkg.mod.Path] = true
}
queue = append(queue, pkg)
queued[pkg] = true
@@ -744,11 +745,12 @@ func tidyPrunedRoots(ctx context.Context, mainModule module.Version, direct map[
queue = append(queue, pkg.test)
queued[pkg.test] = true
}
if !pathIncluded[m.Path] {
if !pathIsRoot[m.Path] {
if s := mg.Selected(m.Path); cmpVersion(s, m.Version) < 0 {
roots = append(roots, m)
pathIsRoot[m.Path] = true
}
pathIncluded[m.Path] = true
}
}
@@ -758,10 +760,62 @@ func tidyPrunedRoots(ctx context.Context, mainModule module.Version, direct map[
}
}
roots = tidy.rootModules
_, err := tidy.Graph(ctx)
if err != nil {
return nil, err
}
// We try to avoid adding explicit requirements for test-only dependencies of
// packages in external modules. However, if we drop the explicit
// requirements, that may change an import from unambiguous (due to lazy
// module loading) to ambiguous (because lazy module loading no longer
// disambiguates it). For any package that has become ambiguous, we try
// to fix it by promoting its module to an explicit root.
// (See https://go.dev/issue/60313.)
q := par.NewQueue(runtime.GOMAXPROCS(0))
for {
var disambiguateRoot sync.Map
for _, pkg := range pkgs {
if pkg.mod.Path == "" || pathIsRoot[pkg.mod.Path] {
// Lazy module loading will cause pkg.mod to be checked before any other modules
// that are only indirectly required. It is as unambiguous as possible.
continue
}
pkg := pkg
q.Add(func() {
skipModFile := true
_, _, _, _, err := importFromModules(ctx, pkg.path, tidy, nil, skipModFile)
if aie := (*AmbiguousImportError)(nil); errors.As(err, &aie) {
disambiguateRoot.Store(pkg.mod, true)
}
})
}
<-q.Idle()
disambiguateRoot.Range(func(k, _ any) bool {
m := k.(module.Version)
roots = append(roots, m)
pathIsRoot[m.Path] = true
return true
})
if len(roots) > len(tidy.rootModules) {
module.Sort(roots)
tidy = newRequirements(pruned, roots, tidy.direct)
_, err = tidy.Graph(ctx)
if err != nil {
return nil, err
}
// Adding these roots may have pulled additional modules into the module
// graph, causing additional packages to become ambiguous. Keep iterating
// until we reach a fixed point.
continue
}
break
}
return tidy, nil
}

View File

@@ -256,7 +256,13 @@ func (e *invalidImportError) Unwrap() error {
// If the package is present in exactly one module, importFromModules will
// return the module, its root directory, and a list of other modules that
// lexically could have provided the package but did not.
func importFromModules(ctx context.Context, path string, rs *Requirements, mg *ModuleGraph) (m module.Version, modroot, dir string, altMods []module.Version, err error) {
//
// If skipModFile is true, the go.mod file for the package is not loaded. This
// allows 'go mod tidy' to preserve a minor checksum-preservation bug
// (https://go.dev/issue/56222) for modules with 'go' versions between 1.17 and
// 1.20, preventing unnecessary go.sum churn and network access in those
// modules.
func importFromModules(ctx context.Context, path string, rs *Requirements, mg *ModuleGraph, skipModFile bool) (m module.Version, modroot, dir string, altMods []module.Version, err error) {
invalidf := func(format string, args ...interface{}) (module.Version, string, string, []module.Version, error) {
return module.Version{}, "", "", nil, &invalidImportError{
importPath: path,
@@ -435,6 +441,18 @@ func importFromModules(ctx context.Context, path string, rs *Requirements, mg *M
}
if len(mods) == 1 {
// We've found the unique module containing the package.
// However, in order to actually compile it we need to know what
// Go language version to use, which requires its go.mod file.
//
// If the module graph is pruned and this is a test-only dependency
// of a package in "all", we didn't necessarily load that file
// when we read the module graph, so do it now to be sure.
if !skipModFile && cfg.BuildMod != "vendor" && mods[0].Path != "" && !MainModules.Contains(mods[0].Path) {
if _, err := goModSummary(mods[0]); err != nil {
return module.Version{}, "", "", nil, err
}
}
return mods[0], roots[0], dirs[0], altMods, nil
}

View File

@@ -1583,7 +1583,8 @@ func commitRequirements(ctx context.Context) (err error) {
// keepSums returns the set of modules (and go.mod file entries) for which
// checksums would be needed in order to reload the same set of packages
// loaded by the most recent call to LoadPackages or ImportFromFiles,
// including any go.mod files needed to reconstruct the MVS result,
// including any go.mod files needed to reconstruct the MVS result
// or identify go versions,
// in addition to the checksums for every module in keepMods.
func keepSums(ctx context.Context, ld *loader, rs *Requirements, which whichSums) map[module.Version]bool {
// Every module in the full module graph contributes its requirements,
@@ -1596,7 +1597,17 @@ func keepSums(ctx context.Context, ld *loader, rs *Requirements, which whichSums
// paths of loaded packages. We need to retain sums for all of these modules —
// not just the modules containing the actual packages — in order to rule out
// ambiguous import errors the next time we load the package.
if ld != nil {
keepModSumsForZipSums := true
if ld == nil {
if cfg.BuildMod != "mod" && semver.Compare("v"+MainModules.GoVersion(), tidyGoModSumVersionV) < 0 {
keepModSumsForZipSums = false
}
} else {
keepPkgGoModSums := true
if (ld.Tidy || cfg.BuildMod != "mod") && semver.Compare("v"+ld.GoVersion, tidyGoModSumVersionV) < 0 {
keepPkgGoModSums = false
keepModSumsForZipSums = false
}
for _, pkg := range ld.pkgs {
// We check pkg.mod.Path here instead of pkg.inStd because the
// pseudo-package "C" is not in std, but not provided by any module (and
@@ -1605,6 +1616,16 @@ func keepSums(ctx context.Context, ld *loader, rs *Requirements, which whichSums
continue
}
// We need the checksum for the go.mod file for pkg.mod
// so that we know what Go version to use to compile pkg.
// However, we didn't do so before Go 1.21, and the bug is relatively
// minor, so we maintain the previous (buggy) behavior in 'go mod tidy' to
// avoid introducing unnecessary churn.
if keepPkgGoModSums {
r := resolveReplacement(pkg.mod)
keep[modkey(r)] = true
}
if rs.pruning == pruned && pkg.mod.Path != "" {
if v, ok := rs.rootSelected(pkg.mod.Path); ok && v == pkg.mod.Version {
// pkg was loaded from a root module, and because the main module has
@@ -1660,6 +1681,9 @@ func keepSums(ctx context.Context, ld *loader, rs *Requirements, which whichSums
if which == addBuildListZipSums {
for _, m := range mg.BuildList() {
r := resolveReplacement(m)
if keepModSumsForZipSums {
keep[modkey(r)] = true // we need the go version from the go.mod file to do anything useful with the zipfile
}
keep[r] = true
}
}

View File

@@ -823,6 +823,10 @@ type loader struct {
// transitively *imported by* the packages and tests in the main module.)
allClosesOverTests bool
// skipImportModFiles indicates whether we may skip loading go.mod files
// for imported packages (as in 'go mod tidy' in Go 1.171.20).
skipImportModFiles bool
work *par.Queue
// reset on each iteration
@@ -1003,6 +1007,10 @@ func loadFromRoots(ctx context.Context, params loaderParams) *loader {
// version higher than the go.mod version adds nothing.
ld.TidyCompatibleVersion = ld.GoVersion
}
if semver.Compare("v"+ld.GoVersion, tidyGoModSumVersionV) < 0 {
ld.skipImportModFiles = true
}
}
if semver.Compare("v"+ld.GoVersion, narrowAllVersionV) < 0 && !ld.UseVendorAll {
@@ -1398,7 +1406,7 @@ func (ld *loader) updateRequirements(ctx context.Context) (changed bool, err err
//
// In some sense, we can think of this as upgraded the module providing
// pkg.path from "none" to a version higher than "none".
if _, _, _, _, err = importFromModules(ctx, pkg.path, rs, nil); err == nil {
if _, _, _, _, err = importFromModules(ctx, pkg.path, rs, nil, ld.skipImportModFiles); err == nil {
changed = true
break
}
@@ -1609,7 +1617,7 @@ func (ld *loader) preloadRootModules(ctx context.Context, rootPkgs []string) (ch
// If the main module is tidy and the package is in "all" — or if we're
// lucky — we can identify all of its imports without actually loading the
// full module graph.
m, _, _, _, err := importFromModules(ctx, path, ld.requirements, nil)
m, _, _, _, err := importFromModules(ctx, path, ld.requirements, nil, ld.skipImportModFiles)
if err != nil {
var missing *ImportMissingError
if errors.As(err, &missing) && ld.ResolveMissingImports {
@@ -1697,7 +1705,7 @@ func (ld *loader) load(ctx context.Context, pkg *loadPkg) {
}
var modroot string
pkg.mod, modroot, pkg.dir, pkg.altMods, pkg.err = importFromModules(ctx, pkg.path, ld.requirements, mg)
pkg.mod, modroot, pkg.dir, pkg.altMods, pkg.err = importFromModules(ctx, pkg.path, ld.requirements, mg, ld.skipImportModFiles)
if pkg.dir == "" {
return
}
@@ -1956,7 +1964,7 @@ func (ld *loader) checkTidyCompatibility(ctx context.Context, rs *Requirements)
pkg := pkg
ld.work.Add(func() {
mod, _, _, _, err := importFromModules(ctx, pkg.path, rs, mg)
mod, _, _, _, err := importFromModules(ctx, pkg.path, rs, mg, ld.skipImportModFiles)
if mod != pkg.mod {
mismatches := <-mismatchMu
mismatches[pkg] = mismatch{mod: mod, err: err}

View File

@@ -45,6 +45,13 @@ const (
// "// indirect" dependencies are added in a block separate from the direct
// ones. See https://golang.org/issue/45965.
separateIndirectVersionV = "v1.17"
// tidyGoModSumVersionV is the Go version (plus leading "v") at which
// 'go mod tidy' preserves go.mod checksums needed to build test dependencies
// of packages in "all", so that 'go test all' can be run without checksum
// errors.
// See https://go.dev/issue/56222.
tidyGoModSumVersionV = "v1.21"
)
// ReadModFile reads and parses the mod file at gomod. ReadModFile properly applies the
@@ -566,6 +573,8 @@ func goModSummary(m module.Version) (*modFileSummary, error) {
summary := &modFileSummary{
module: module.Version{Path: m.Path},
}
readVendorList(MainModules.mustGetSingleMainModule())
if vendorVersion[m.Path] != m.Version {
// This module is not vendored, so packages cannot be loaded from it and
// it cannot be relevant to the build.
@@ -574,8 +583,6 @@ func goModSummary(m module.Version) (*modFileSummary, error) {
// For every module other than the target,
// return the full list of modules from modules.txt.
readVendorList(MainModules.mustGetSingleMainModule())
// We don't know what versions the vendored module actually relies on,
// so assume that it requires everything.
summary.require = vendorList
@@ -583,10 +590,10 @@ func goModSummary(m module.Version) (*modFileSummary, error) {
}
actual := resolveReplacement(m)
if HasModRoot() && cfg.BuildMod == "readonly" && !inWorkspaceMode() && actual.Version != "" {
if mustHaveSums() && actual.Version != "" {
key := module.Version{Path: actual.Path, Version: actual.Version + "/go.mod"}
if !modfetch.HaveSum(key) {
suggestion := fmt.Sprintf("; to add it:\n\tgo mod download %s", m.Path)
suggestion := fmt.Sprintf(" for go.mod file; to add it:\n\tgo mod download %s", m.Path)
return nil, module.VersionError(actual, &sumMissingError{suggestion: suggestion})
}
}

View File

@@ -55,6 +55,7 @@ func testMain(m *testing.M) (err error) {
os.Setenv("GOPATH", dir)
cfg.BuildContext.GOPATH = dir
cfg.GOMODCACHE = filepath.Join(dir, "pkg/mod")
cfg.SumdbDir = filepath.Join(dir, "pkg/sumdb")
m.Run()
return nil
}

View File

@@ -432,21 +432,37 @@ func Exec(cancel func(*exec.Cmd) error, waitDelay time.Duration) Cmd {
}
func startCommand(s *State, name, path string, args []string, cancel func(*exec.Cmd) error, waitDelay time.Duration) (WaitFunc, error) {
var stdoutBuf, stderrBuf strings.Builder
cmd := exec.CommandContext(s.Context(), path, args...)
if cancel == nil {
cmd.Cancel = nil
} else {
cmd.Cancel = func() error { return cancel(cmd) }
}
cmd.WaitDelay = waitDelay
cmd.Args[0] = name
cmd.Dir = s.Getwd()
cmd.Env = s.env
cmd.Stdout = &stdoutBuf
cmd.Stderr = &stderrBuf
if err := cmd.Start(); err != nil {
return nil, err
var (
cmd *exec.Cmd
stdoutBuf, stderrBuf strings.Builder
)
for {
cmd = exec.CommandContext(s.Context(), path, args...)
if cancel == nil {
cmd.Cancel = nil
} else {
cmd.Cancel = func() error { return cancel(cmd) }
}
cmd.WaitDelay = waitDelay
cmd.Args[0] = name
cmd.Dir = s.Getwd()
cmd.Env = s.env
cmd.Stdout = &stdoutBuf
cmd.Stderr = &stderrBuf
err := cmd.Start()
if err == nil {
break
}
if isETXTBSY(err) {
// If the script (or its host process) just wrote the executable we're
// trying to run, a fork+exec in another thread may be holding open the FD
// that we used to write the executable (see https://go.dev/issue/22315).
// Since the descriptor should have CLOEXEC set, the problem should
// resolve as soon as the forked child reaches its exec call.
// Keep retrying until that happens.
} else {
return nil, err
}
}
wait := func(s *State) (stdout, stderr string, err error) {

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.
//go:build !(unix || windows)
package script
func isETXTBSY(err error) bool {
return false
}

View File

@@ -0,0 +1,16 @@
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build unix || windows
package script
import (
"errors"
"syscall"
)
func isETXTBSY(err error) bool {
return errors.Is(err, syscall.ETXTBSY)
}

View File

@@ -66,6 +66,7 @@ var passAnalyzersToVet = map[string]bool{
"structtag": true,
"testinggoroutine": true,
"tests": true,
"timeformat": true,
"unmarshal": true,
"unreachable": true,
"unsafeptr": true,

View File

@@ -9,6 +9,7 @@ import (
"cmd/go/internal/test/internal/genflags"
"flag"
"internal/testenv"
"os"
"reflect"
"strings"
"testing"
@@ -16,6 +17,7 @@ import (
func TestMain(m *testing.M) {
cfg.SetGOROOT(testenv.GOROOT(nil), false)
os.Exit(m.Run())
}
func TestPassFlagToTestIncludesAllTestFlags(t *testing.T) {
@@ -48,6 +50,8 @@ func TestPassFlagToTestIncludesAllTestFlags(t *testing.T) {
}
func TestVetAnalyzersSetIsCorrect(t *testing.T) {
testenv.MustHaveGoBuild(t) // runs 'go tool vet -flags'
vetAns, err := genflags.VetAnalyzers()
if err != nil {
t.Fatal(err)

View File

@@ -75,7 +75,7 @@ func testFlags() []string {
}
switch name {
case "testlogfile", "paniconexit0", "fuzzcachedir", "fuzzworker":
case "testlogfile", "paniconexit0", "fuzzcachedir", "fuzzworker", "gocoverdir":
// These flags are only for use by cmd/go.
default:
names = append(names, name)

View File

@@ -86,6 +86,10 @@ standard output, even if the test printed them to its own standard
error. (The go command's standard error is reserved for printing
errors building the tests.)
The go command places $GOROOT/bin at the beginning of $PATH
in the test's environment, so that tests that execute
'go' commands use the same 'go' as the parent 'go test' command.
Go test runs in two different modes:
The first, called local directory mode, occurs when go test is
@@ -1144,7 +1148,15 @@ func (lockedStdout) Write(b []byte) (int, error) {
func (r *runTestActor) Act(b *work.Builder, ctx context.Context, a *work.Action) error {
// Wait for previous test to get started and print its first json line.
<-r.prev
select {
case <-r.prev:
case <-base.Interrupted:
// We can't wait for the previous test action to complete: we don't start
// new actions after an interrupt, so if that action wasn't already running
// it might never happen. Instead, just don't log anything for this action.
base.SetExitStatus(1)
return nil
}
if a.Failed {
// We were unable to build the binary.

View File

@@ -516,6 +516,12 @@ func (b *Builder) build(ctx context.Context, a *Action) (err error) {
b.Print(p.ImportPath + "\n")
}
if p.Error != nil {
// Don't try to build anything for packages with errors. There may be a
// problem with the inputs that makes the package unsafe to build.
return p.Error
}
if p.BinaryOnly {
p.Stale = true
p.StaleReason = "binary-only packages are no longer supported"
@@ -525,6 +531,19 @@ func (b *Builder) build(ctx context.Context, a *Action) (err error) {
return errors.New("binary-only packages are no longer supported")
}
// Go 1.22 is likely to change for loop semantics.
// If we try to build code written for Go 1.22,
// it may have aliasing bugs that it shouldn't have.
// See go.dev/issue/60078.
// When Go 1.22 is released, Go 1.20 will no longer
// be supported, so no one should ever run into this condition,
// but we are adding this check anyway,
// just to help catch some mistakes and usage of old
// Go toolchains beyond their end-of-support.
if p.Module != nil && !(allowedVersion(p.Module.GoVersion) || p.Module.GoVersion == "1.21") {
return errors.New("cannot compile Go " + p.Module.GoVersion + " code")
}
if err := b.Mkdir(a.Objdir); err != nil {
return err
}
@@ -3027,6 +3046,36 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo
}
}
// Scrutinize CFLAGS and related for flags that might cause
// problems if we are using internal linking (for example, use of
// plugins, LTO, etc) by calling a helper routine that builds on
// the existing CGO flags allow-lists. If we see anything
// suspicious, emit a special token file "preferlinkext" (known to
// the linker) in the object file to signal the that it should not
// try to link internally and should revert to external linking.
// The token we pass is a suggestion, not a mandate; if a user is
// explicitly asking for a specific linkmode via the "-linkmode"
// flag, the token will be ignored. NB: in theory we could ditch
// the token approach and just pass a flag to the linker when we
// eventually invoke it, and the linker flag could then be
// documented (although coming up with a simple explanation of the
// flag might be challenging). For more context see issues #58619,
// #58620, and #58848.
flagSources := []string{"CGO_CFLAGS", "CGO_CXXFLAGS", "CGO_FFLAGS"}
flagLists := [][]string{cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS}
if flagsNotCompatibleWithInternalLinking(flagSources, flagLists) {
tokenFile := objdir + "preferlinkext"
if cfg.BuildN || cfg.BuildX {
b.Showcmd("", "echo > %s", tokenFile)
}
if !cfg.BuildN {
if err := os.WriteFile(tokenFile, nil, 0666); err != nil {
return nil, nil, err
}
}
outObj = append(outObj, tokenFile)
}
if cfg.BuildMSan {
cgoCFLAGS = append([]string{"-fsanitize=memory"}, cgoCFLAGS...)
cgoLDFLAGS = append([]string{"-fsanitize=memory"}, cgoLDFLAGS...)
@@ -3276,6 +3325,24 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo
return outGo, outObj, nil
}
// flagsNotCompatibleWithInternalLinking scans the list of cgo
// compiler flags (C/C++/Fortran) looking for flags that might cause
// problems if the build in question uses internal linking. The
// primary culprits are use of plugins or use of LTO, but we err on
// the side of caution, supporting only those flags that are on the
// allow-list for safe flags from security perspective. Return is TRUE
// if a sensitive flag is found, FALSE otherwise.
func flagsNotCompatibleWithInternalLinking(sourceList []string, flagListList [][]string) bool {
for i := range sourceList {
sn := sourceList[i]
fll := flagListList[i]
if err := checkCompilerFlagsForInternalLink(sn, sn, fll); err != nil {
return true
}
}
return false
}
// dynimport creates a Go source file named importGo containing
// //go:cgo_import_dynamic directives for each symbol or library
// dynamically imported by the object files outObj.

View File

@@ -280,14 +280,12 @@ func (tools gccgoToolchain) link(b *Builder, root *Action, out, importcfg string
const ldflagsPrefix = "_CGO_LDFLAGS="
for _, line := range strings.Split(string(flags), "\n") {
if strings.HasPrefix(line, ldflagsPrefix) {
newFlags := strings.Fields(line[len(ldflagsPrefix):])
for _, flag := range newFlags {
// Every _cgo_flags file has -g and -O2 in _CGO_LDFLAGS
// but they don't mean anything to the linker so filter
// them out.
if flag != "-g" && !strings.HasPrefix(flag, "-O") {
cgoldflags = append(cgoldflags, flag)
}
flag := line[len(ldflagsPrefix):]
// Every _cgo_flags file has -g and -O2 in _CGO_LDFLAGS
// but they don't mean anything to the linker so filter
// them out.
if flag != "-g" && !strings.HasPrefix(flag, "-O") {
cgoldflags = append(cgoldflags, flag)
}
}
}

View File

@@ -180,10 +180,10 @@ var validLinkerFlags = []*lazyregexp.Regexp{
re(`-Wl,-berok`),
re(`-Wl,-Bstatic`),
re(`-Wl,-Bsymbolic-functions`),
re(`-Wl,-O([^@,\-][^,]*)?`),
re(`-Wl,-O[0-9]+`),
re(`-Wl,-d[ny]`),
re(`-Wl,--disable-new-dtags`),
re(`-Wl,-e[=,][a-zA-Z0-9]*`),
re(`-Wl,-e[=,][a-zA-Z0-9]+`),
re(`-Wl,--enable-new-dtags`),
re(`-Wl,--end-group`),
re(`-Wl,--(no-)?export-dynamic`),
@@ -192,7 +192,7 @@ var validLinkerFlags = []*lazyregexp.Regexp{
re(`-Wl,--hash-style=(sysv|gnu|both)`),
re(`-Wl,-headerpad_max_install_names`),
re(`-Wl,--no-undefined`),
re(`-Wl,-R([^@\-][^,@]*$)`),
re(`-Wl,-R,?([^@\-,][^,@]*$)`),
re(`-Wl,--just-symbols[=,]([^,@\-][^,@]+)`),
re(`-Wl,-rpath(-link)?[=,]([^,@\-][^,]+)`),
re(`-Wl,-s`),
@@ -230,32 +230,55 @@ var validLinkerFlagsWithNextArg = []string{
}
func checkCompilerFlags(name, source string, list []string) error {
return checkFlags(name, source, list, validCompilerFlags, validCompilerFlagsWithNextArg)
checkOverrides := true
return checkFlags(name, source, list, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides)
}
func checkLinkerFlags(name, source string, list []string) error {
return checkFlags(name, source, list, validLinkerFlags, validLinkerFlagsWithNextArg)
checkOverrides := true
return checkFlags(name, source, list, validLinkerFlags, validLinkerFlagsWithNextArg, checkOverrides)
}
func checkFlags(name, source string, list []string, valid []*lazyregexp.Regexp, validNext []string) error {
// checkCompilerFlagsForInternalLink returns an error if 'list'
// contains a flag or flags that may not be fully supported by
// internal linking (meaning that we should punt the link to the
// external linker).
func checkCompilerFlagsForInternalLink(name, source string, list []string) error {
checkOverrides := false
if err := checkFlags(name, source, list, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides); err != nil {
return err
}
// Currently the only flag on the allow list that causes problems
// for the linker is "-flto"; check for it manually here.
for _, fl := range list {
if strings.HasPrefix(fl, "-flto") {
return fmt.Errorf("flag %q triggers external linking", fl)
}
}
return nil
}
func checkFlags(name, source string, list []string, valid []*lazyregexp.Regexp, validNext []string, checkOverrides bool) error {
// Let users override rules with $CGO_CFLAGS_ALLOW, $CGO_CFLAGS_DISALLOW, etc.
var (
allow *regexp.Regexp
disallow *regexp.Regexp
)
if env := cfg.Getenv("CGO_" + name + "_ALLOW"); env != "" {
r, err := regexp.Compile(env)
if err != nil {
return fmt.Errorf("parsing $CGO_%s_ALLOW: %v", name, err)
if checkOverrides {
if env := cfg.Getenv("CGO_" + name + "_ALLOW"); env != "" {
r, err := regexp.Compile(env)
if err != nil {
return fmt.Errorf("parsing $CGO_%s_ALLOW: %v", name, err)
}
allow = r
}
allow = r
}
if env := cfg.Getenv("CGO_" + name + "_DISALLOW"); env != "" {
r, err := regexp.Compile(env)
if err != nil {
return fmt.Errorf("parsing $CGO_%s_DISALLOW: %v", name, err)
if env := cfg.Getenv("CGO_" + name + "_DISALLOW"); env != "" {
r, err := regexp.Compile(env)
if err != nil {
return fmt.Errorf("parsing $CGO_%s_DISALLOW: %v", name, err)
}
disallow = r
}
disallow = r
}
Args:

View File

@@ -6,6 +6,7 @@ package work
import (
"os"
"strings"
"testing"
)
@@ -28,6 +29,7 @@ var goodCompilerFlags = [][]string{
{"-Wp,-Ufoo"},
{"-Wp,-Dfoo1"},
{"-Wp,-Ufoo1"},
{"-flto"},
{"-fobjc-arc"},
{"-fno-objc-arc"},
{"-fomit-frame-pointer"},
@@ -228,6 +230,11 @@ var badLinkerFlags = [][]string{
{"-Wl,-R,@foo"},
{"-Wl,--just-symbols,@foo"},
{"../x.o"},
{"-Wl,-R,"},
{"-Wl,-O"},
{"-Wl,-e="},
{"-Wl,-e,"},
{"-Wl,-R,-flag"},
}
func TestCheckLinkerFlags(t *testing.T) {
@@ -278,3 +285,34 @@ func TestCheckFlagAllowDisallow(t *testing.T) {
t.Fatalf("missing error for -fplugin=lint.so: %v", err)
}
}
func TestCheckCompilerFlagsForInternalLink(t *testing.T) {
// Any "bad" compiler flag should trigger external linking.
for _, f := range badCompilerFlags {
if err := checkCompilerFlagsForInternalLink("test", "test", f); err == nil {
t.Errorf("missing error for %q", f)
}
}
// All "good" compiler flags should not trigger external linking,
// except for anything that begins with "-flto".
for _, f := range goodCompilerFlags {
foundLTO := false
for _, s := range f {
if strings.Contains(s, "-flto") {
foundLTO = true
}
}
if err := checkCompilerFlagsForInternalLink("test", "test", f); err != nil {
// expect error for -flto
if !foundLTO {
t.Errorf("unexpected error for %q: %v", f, err)
}
} else {
// expect no error for everything else
if foundLTO {
t.Errorf("missing error for %q: %v", f, err)
}
}
}
}

View File

@@ -222,6 +222,7 @@ func scriptEnv(srv *vcstest.Server, srvCertFile string) ([]string, error) {
"devnull=" + os.DevNull,
"goversion=" + version,
"CMDGO_TEST_RUN_MAIN=true",
"newline=\n",
}
if testenv.Builder() != "" || os.Getenv("GIT_TRACE_CURL") == "1" {

View File

@@ -49,6 +49,7 @@ func scriptConditions() map[string]script.Cond {
add("link", lazyBool("testenv.HasLink()", testenv.HasLink))
add("mismatched-goroot", script.Condition("test's GOROOT_FINAL does not match the real GOROOT", isMismatchedGoroot))
add("msan", sysCondition("-msan", platform.MSanSupported, true))
add("cgolinkext", script.BoolCondition("platform requires external linking for cgo", platform.MustLinkExternalGo121(cfg.Goos, cfg.Goarch, true)))
add("net", lazyBool("testenv.HasExternalNetwork()", testenv.HasExternalNetwork))
add("race", sysCondition("-race", platform.RaceDetectorSupported, true))
add("symlink", lazyBool("testenv.HasSymlink()", testenv.HasSymlink))

View File

@@ -382,6 +382,8 @@ The available conditions are:
$WORK filesystem is case-sensitive
[cgo]
host CGO_ENABLED
[cgolinkext]
platform requires external linking for cgo
[compiler:*]
runtime.Compiler == <suffix>
[cross]

View File

@@ -0,0 +1,138 @@
[GOOS:windows] skip 'filesystem normalizes / to \'
[GOOS:plan9] skip 'filesystem disallows \n in paths'
# If the directory path containing a package to be built includes a newline,
# the go command should refuse to even try to build the package.
env DIR=$WORK${/}${newline}'package main'${newline}'func main() { panic("uh-oh")'${newline}'/*'
mkdir $DIR
cd $DIR
exec pwd
cp $WORK/go.mod ./go.mod
cp $WORK/main.go ./main.go
cp $WORK/main_nocgo.go ./main_nocgo.go
cp $WORK/main_test.go ./main_test.go
! go build -o $devnull .
stderr 'package example: invalid package directory .*uh-oh'
[cgo] ! go build -o $devnull main.go
[!cgo] ! go build -o $devnull main_nocgo.go
stderr 'package command-line-arguments: invalid package directory .*uh-oh'
! go run .
stderr 'package example: invalid package directory .*uh-oh'
[cgo] ! go run main.go
[!cgo] ! go run main_nocgo.go
stderr 'package command-line-arguments: invalid package directory .*uh-oh'
! go test .
stderr 'package example: invalid package directory .*uh-oh'
[cgo] ! go test -v main.go main_test.go
[!cgo] ! go test -v main_nocgo.go main_test.go
stderr 'package command-line-arguments: invalid package directory .*uh-oh'
go list -compiled -e -f '{{with .CompiledGoFiles}}{{.}}{{end}}' .
! stdout .
! stderr .
! exists obj_
# The cgo tool should only accept the source file if the working directory
# is not written in line directives in the resulting files.
[cgo] ! go tool cgo main.go
[cgo] stderr 'cgo: input path contains newline character: .*uh-oh'
[cgo] ! exists _obj
[cgo] go tool cgo -trimpath=$PWD main.go
[cgo] grep '//line main\.go:1:1' _obj/main.cgo1.go
[cgo] ! grep 'uh-oh' _obj/main.cgo1.go
[cgo] rm _obj
# Since we do preserve $PWD (or set it appropriately) for commands, and we do
# not resolve symlinks unnecessarily, referring to the contents of the unsafe
# directory via a safe symlink should be ok, and should not inject the data from
# the symlink target path.
[!symlink] stop 'remainder of test checks symlink behavior'
[short] stop 'links and runs binaries'
symlink $WORK${/}link -> $DIR
[cgo] go run $WORK${/}link${/}main.go
[!cgo] go run $WORK${/}link${/}main_nocgo.go
! stdout panic
! stderr panic
stderr '^ok$'
[cgo] go test -v $WORK${/}link${/}main.go $WORK${/}link${/}main_test.go
[!cgo] go test -v $WORK${/}link${/}main_nocgo.go $WORK${/}link${/}main_test.go
! stdout panic
! stderr panic
stdout '^ok$' # 'go test' combines the test's stdout into stderr
cd $WORK/link
[cgo] ! go run $DIR${/}main.go
[!cgo] ! go run $DIR${/}main_nocgo.go
stderr 'package command-line-arguments: invalid package directory .*uh-oh'
go run .
! stdout panic
! stderr panic
stderr '^ok$'
[cgo] go run main.go
[!cgo] go run main_nocgo.go
! stdout panic
! stderr panic
stderr '^ok$'
go test -v
! stdout panic
! stderr panic
stdout '^ok$' # 'go test' combines the test's stdout into stderr
go test -v .
! stdout panic
! stderr panic
stdout '^ok$' # 'go test' combines the test's stdout into stderr
[cgo] go tool cgo main.go
[cgo] grep '//line .*'${/}'link'${/}'main\.go:1:1' _obj/main.cgo1.go
[cgo] ! grep 'uh-oh' _obj/main.cgo1.go
-- $WORK/go.mod --
module example
go 1.19
-- $WORK/main.go --
package main
import "C"
func main() {
/* nothing here */
println("ok")
}
-- $WORK/main_nocgo.go --
//go:build !cgo
package main
func main() {
/* nothing here */
println("ok")
}
-- $WORK/main_test.go --
package main
import "testing"
func TestMain(*testing.M) {
main()
}

View File

@@ -0,0 +1,24 @@
! go build
stderr '^m: cannot compile Go 1.22 code$'
cd dep
! go build
stderr '^m: cannot compile Go 1.22 code$'
-- go.mod --
module m
go 1.22
-- p.go --
package p
-- dep/go.mod --
module dep
go 1.19
require m v1.0.0
replace m v1.0.0 => ../
-- dep/p.go --
package p
import "m"

View File

@@ -0,0 +1,40 @@
# Regression test for https://go.dev/issue/59571
# Build should be reproducible, even with aliased generic types.
go build -a -o 1.a
go build -a -o 2.a
cmp -q 1.a 2.a
-- go.mod --
module m
go 1.20
-- m.go --
package m
type (
SliceFlag[T any] struct{}
Alias1 = SliceFlag[[1]int]
Alias2 = SliceFlag[[2]int]
Alias3 = SliceFlag[[3]int]
Alias4 = SliceFlag[[4]int]
Alias5 = SliceFlag[[5]int]
Alias6 = SliceFlag[[6]int]
Alias7 = SliceFlag[[7]int]
Alias8 = SliceFlag[[8]int]
Alias9 = SliceFlag[[9]int]
Alias10 = SliceFlag[[10]int]
Alias11 = SliceFlag[[11]int]
Alias12 = SliceFlag[[12]int]
Alias13 = SliceFlag[[13]int]
Alias14 = SliceFlag[[14]int]
Alias15 = SliceFlag[[15]int]
Alias16 = SliceFlag[[16]int]
Alias17 = SliceFlag[[17]int]
Alias18 = SliceFlag[[18]int]
Alias19 = SliceFlag[[19]int]
Alias20 = SliceFlag[[20]int]
)
func (x *SliceFlag[T]) String() string { return "zzz" }

View File

@@ -0,0 +1,155 @@
# Test case to verify that when we have a package that uses CGO in
# combination with selected "unusual" flags (involving plugins, LTO)
# that we force external linking. See related
# issues 58619, 58620, and 58848.
[compiler:gccgo] skip # only external linking for gccgo
# This test requires external linking, so use cgo as a proxy
[!cgo] skip
# Here we build three program: one with explicit CGO use, one with no
# CGO use, and one that uses a stdlib package ("runtime/cgo") that has
# CGO in it. It used to be that only the explicit use of CGO would
# trigger external linking, and that the program that only used
# "runtime/cgo" would always be handled with internal linking. This caused
# issues when users included odd/unusual flags (ex: -fplugin, -flto)
# in CGO_CFLAGS, causing the Go linker to have to read and interpret
# non-standard host objects.
#
# As of 1.21 we continue to use internal linking for programs whose
# CGO use comes ony from stdlib packages in the absence of any flag
# funny business, however if the Go command sees flags that may be suspicious,
# it signals the Go linker to invoke the external linker.
# The next few tests run builds passing "-n" to the Go command, then
# checking the output to see if the Go command is trying to pass a
# "preferlinkext" token to the linker to request external linking.
#-----------------------
# Use a fresh GOCACHE for these next steps, so as to have the real
# actions for the runtime/cgo package appear in the "-n -x" output.
env GOCACHE=$WORK/gocache
mkdir $GOCACHE
# First build: there is no CGO in use, so no token should be present regardless
# of weird CGO flags.
go build -x -n -o dummy.exe ./noUseOfCgo
! stderr preferlinkext
env CGO_CFLAGS=-flto
go build -x -n -o dummy.exe ./noUseOfCgo
! stderr preferlinkext
env CGO_CFLAGS=
# Second build uses CGO, so we expect to see the token present in the
# -n output only when strange flags are used.
go build -x -n -o dummy.exe ./usesInternalCgo
! stderr preferlinkext
env CGO_CFLAGS=-flto
go build -x -n -o dummy.exe ./usesInternalCgo
stderr preferlinkext
env CGO_CFLAGS=-fplugin
go build -x -n -o dummy.exe ./usesInternalCgo
stderr preferlinkext
env CGO_CFLAGS=-fprofile-instr-generate
go build -x -n -o dummy.exe ./usesInternalCgo
stderr preferlinkext
env CGO_CFLAGS=
[short] skip
# In the remaining tests below we do actual builds (without -n) to
# verify that the Go linker is going the right thing in addition to the
# Go command. Here the idea is to pass "-tmpdir" to the linker, then
# check after the link is done for the presence of the file
# <tmpdir>/go.o, which the Go linker creates prior to kicking off the
# external linker.
mkdir tmp1
mkdir tmp2
mkdir tmp3
mkdir tmp4
mkdir tmp5
# First build: no external linking expected
go build -ldflags=-tmpdir=tmp1 -o $devnull ./noUseOfCgo &
# Second build: using only "runtime/cgo", expect internal linking.
go build -ldflags=-tmpdir=tmp2 -o $devnull ./usesInternalCgo &
# Third build: program uses only "runtime/cgo", so we would normally
# expect internal linking, except that cflags contain suspicious entries
# (in this case, a flag that does not appear on the allow list).
env CGO_CFLAGS=-fmerge-all-constants
env CGO_LDFLAGS=-fmerge-all-constants
go build -ldflags=-tmpdir=tmp3 -o $devnull ./usesInternalCgo &
env CGO_CFLAGS=
env CGO_LDFLAGS=
# Fourth build: explicit CGO, expect external linking.
go build -ldflags=-tmpdir=tmp4 -o $devnull ./usesExplicitCgo &
# Fifth build: explicit CGO, but we specifically asked for internal linking
# via a flag, so using internal linking it is.
[cgolinkext] go list ./usesInternalCgo
[!cgolinkext] go build '-ldflags=-tmpdir=tmp5 -linkmode=internal' -o $devnull ./usesInternalCgo &
wait
# Check first build: no external linking expected
! exists tmp1/go.o
# Check second build: using only "runtime/cgo", expect internal linking.
[!cgolinkext] ! exists tmp2/go.o
[cgolinkext] exists tmp2/go.o
# Check third build: has suspicious flag.
exists tmp3/go.o
# Fourth build: explicit CGO, expect external linking.
exists tmp4/go.o
# Fifth build: explicit CGO, -linkmode=internal.
! exists tmp5/go.o
-- go.mod --
module cgo.example
go 1.20
-- noUseOfCgo/main.go --
package main
func main() {
println("clean as a whistle")
}
-- usesInternalCgo/main.go --
package main
import (
"runtime/cgo"
)
func main() {
q := "hello"
h := cgo.NewHandle(q)
h.Delete()
}
-- usesExplicitCgo/main.go --
package main
/*
int meaningOfLife() { return 42; }
*/
import "C"
func main() {
println(C.meaningOfLife())
}

View File

@@ -0,0 +1,23 @@
# Test that #cgo LDFLAGS are properly quoted.
# The #cgo LDFLAGS below should pass a string with spaces to -L,
# as though searching a directory with a space in its name.
# It should not pass --nosuchoption to the external linker.
[!cgo] skip
go build
[!exec:gccgo] skip
# TODO: remove once gccgo on builder is updated
[GOOS:aix] [GOARCH:ppc64] skip
go build -compiler gccgo
-- go.mod --
module m
-- cgo.go --
package main
// #cgo LDFLAGS: -L "./ -Wl,--nosuchoption"
import "C"
func main() {}

View File

@@ -0,0 +1,9 @@
! go list a.go
! stdout .
stderr 'invalid import path'
! stderr panic
-- a.go --
package a
import ""

View File

@@ -4,9 +4,9 @@ stderr '^p[/\\]b.go:2:2: expected ''package'', found ''EOF''$'
! go list -f '{{range .Imports}}{{.}} {{end}}' ./p
stderr '^p[/\\]b.go:2:2: expected ''package'', found ''EOF''$'
! go list -test ./t
stderr '^can''t load test package: t[/\\]t_test.go:8:1: expected declaration, found ʕ'
stderr '^go: can''t load test package: t[/\\]t_test.go:8:1: expected declaration, found ʕ'
! go list -test -f '{{range .Imports}}{{.}} {{end}}' ./t
stderr '^can''t load test package: t[/\\]t_test.go:8:1: expected declaration, found ʕ'
stderr '^go: can''t load test package: t[/\\]t_test.go:8:1: expected declaration, found ʕ'
# 'go list -e' should report imports, even if some files have parse errors
# before the import block.

View File

@@ -8,23 +8,23 @@ go build sub.1
go build subver.1
! stderr 'module requires'
! go build badsub.1
stderr '^note: module requires Go 1.11111$'
stderr '^note: module requires Go 1.21$'
go build versioned.1
go mod edit -require versioned.1@v1.1.0
! go build versioned.1
stderr '^note: module requires Go 1.99999$'
stderr '^note: module requires Go 1.21$'
[short] stop
# The message should be printed even if the compiler emits no output.
go build -o $WORK/nooutput.exe nooutput.go
! go build -toolexec=$WORK/nooutput.exe versioned.1
stderr '^# versioned.1\nnote: module requires Go 1.99999$'
stderr '^# versioned.1\nnote: module requires Go 1.21$'
-- go.mod --
module m
go 1.999
go 1.21
require (
sub.1 v1.0.0
subver.1 v1.0.0
@@ -51,14 +51,14 @@ package x
-- subver/go.mod --
module m
go 1.11111
go 1.21
-- subver/x.go --
package x
-- badsub/go.mod --
module m
go 1.11111
go 1.21
-- badsub/x.go --
package x
@@ -73,7 +73,7 @@ package x
-- versioned2/go.mod --
module versioned
go 1.99999
go 1.21
-- versioned2/x.go --
package x

View File

@@ -16,7 +16,8 @@ env GO111MODULE=auto
cd m
cp go.mod go.mod.orig
! go list -m all
stderr '^go: example.com/cmd@v1.1.0-doesnotexist: missing go.sum entry; to add it:\n\tgo mod download example.com/cmd$'
stderr '^go: example.com/cmd@v1.1.0-doesnotexist: reading http.*/mod/example.com/cmd/@v/v1.1.0-doesnotexist.info: 404 Not Found\n\tserver response: 404 page not found$'
stderr '^go: example.com/cmd@v1.1.0-doesnotexist: missing go.sum entry for go.mod file; to add it:\n\tgo mod download example.com/cmd$'
go install example.com/cmd/a@latest
cmp go.mod go.mod.orig
exists $GOPATH/bin/a$GOEXE

View File

@@ -29,4 +29,4 @@ stderr '^go: updates to go.sum needed, disabled by -mod=readonly$'
#
# TODO(#41297): This should not be an error either.
! go list -m -mod=readonly -versions rsc.io/sampler
stderr '^go: rsc\.io/quote@v1\.5\.1: missing go\.sum entry; to add it:\n\tgo mod download rsc\.io/quote$'
stderr '^go: rsc\.io/quote@v1\.5\.1: missing go\.sum entry for go.mod file; to add it:\n\tgo mod download rsc\.io/quote$'

View File

@@ -21,7 +21,8 @@ env GO111MODULE=on
cd m
cp go.mod go.mod.orig
! go list -m all
stderr '^go: example.com/cmd@v1.1.0-doesnotexist: missing go.sum entry; to add it:\n\tgo mod download example.com/cmd$'
stderr '^go: example.com/cmd@v1.1.0-doesnotexist: reading http.*/mod/example\.com/cmd/@v/v1.1.0-doesnotexist.info: 404 Not Found\n\tserver response: 404 page not found$'
stderr '^go: example.com/cmd@v1.1.0-doesnotexist: missing go.sum entry for go.mod file; to add it:\n\tgo mod download example.com/cmd$'
go run example.com/cmd/a@v1.0.0
stdout '^a@v1.0.0$'
cmp go.mod go.mod.orig

View File

@@ -0,0 +1,72 @@
# Regression test for #56222: 'go get -t' and 'go mod tidy'
# should save enough checksums to run 'go test' on the named
# packages or any package in "all" respectively.
# At go 1.20 or earlier, 'go mod tidy' should preserve the historical go.sum
# contents, but 'go test' should flag the missing checksums (instead of trying
# to build the test dependency with the wrong language version).
cd m1
go mod tidy
! go test -o $devnull -c example.com/m2/q
stderr '^# example.com/m2/q\n'..${/}m2${/}q${/}'q_test.go:3:8: example.com/generics@v1.0.0: missing go.sum entry for go.mod file; to add it:\n\tgo mod download example.com/generics$'
go mod download -json example.com/generics
go list -f '{{if eq .ImportPath "example.com/generics"}}{{.Module.GoVersion}}{{end}}' -deps -test example.com/m2/q
stdout 1.18
# Even at go 1.20 or earlier, 'go mod tidy' shouldn't need go.mod files or
# checksums that it won't record.
go mod tidy -go=1.20
go clean -modcache # Remove checksums from the module cache, so that only go.sum is used.
# Issue 60667: 'go list' without -mod=mod shouldn't report the checksums as
# dirty either.
go list -m -u all
env OLDSUMDB=$GOSUMDB
env GOSUMDB=bad
go mod tidy
env GOSUMDB=$OLDSUMDB
# Regardless of the go version in go.mod, 'go get -t' should fetch
# enough checksums to run 'go test' on the named package.
rm p
go mod tidy -go=1.20
go list -m all
! stdout example.com/generics
go get -t example.com/m2/q@v1.0.0
go list -f '{{if eq .ImportPath "example.com/generics"}}{{.Module.GoVersion}}{{end}}' -deps -test example.com/m2/q
stdout 1.18
[!short] go test -o $devnull -c example.com/m2/q
-- m1/go.mod --
module example.com/m1
go 1.20
require example.com/m2 v1.0.0
replace example.com/m2 => ../m2
-- m1/p/p.go --
package p
import _ "example.com/m2/q"
-- m2/go.mod --
module example.com/m2
go 1.20
require example.com/generics v1.0.0
-- m2/q/q.go --
package q
-- m2/q/q_test.go --
package q
import _ "example.com/generics"

View File

@@ -4,7 +4,7 @@ env GO111MODULE=on
# When a sum is needed to load the build list, we get an error for the
# specific module. The .mod file is not downloaded, and go.sum is not written.
! go list -m all
stderr '^go: rsc.io/quote@v1.5.2: missing go.sum entry; to add it:\n\tgo mod download rsc.io/quote$'
stderr '^go: rsc.io/quote@v1.5.2: missing go.sum entry for go.mod file; to add it:\n\tgo mod download rsc.io/quote$'
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod
! exists go.sum
@@ -12,7 +12,7 @@ stderr '^go: rsc.io/quote@v1.5.2: missing go.sum entry; to add it:\n\tgo mod dow
# we should see the same error.
cp go.sum.h2only go.sum
! go list -m all
stderr '^go: rsc.io/quote@v1.5.2: missing go.sum entry; to add it:\n\tgo mod download rsc.io/quote$'
stderr '^go: rsc.io/quote@v1.5.2: missing go.sum entry for go.mod file; to add it:\n\tgo mod download rsc.io/quote$'
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod
cmp go.sum go.sum.h2only
rm go.sum
@@ -21,7 +21,7 @@ rm go.sum
cp go.mod go.mod.orig
go mod edit -replace rsc.io/quote@v1.5.2=rsc.io/quote@v1.5.1
! go list -m all
stderr '^go: rsc.io/quote@v1.5.2 \(replaced by rsc.io/quote@v1.5.1\): missing go.sum entry; to add it:\n\tgo mod download rsc.io/quote$'
stderr '^go: rsc.io/quote@v1.5.2 \(replaced by rsc.io/quote@v1.5.1\): missing go.sum entry for go.mod file; to add it:\n\tgo mod download rsc.io/quote$'
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.1.mod
! exists go.sum
cp go.mod.orig go.mod

View File

@@ -50,7 +50,7 @@ cmp stdout m_all.txt
go mod edit -go=1.16
! go list -m all
stderr '^go: example.net/lazy@v0.1.0 requires\n\texample.com/version@v1.0.1: missing go.sum entry; to add it:\n\tgo mod download example.com/version$'
stderr '^go: example.net/lazy@v0.1.0 requires\n\texample.com/version@v1.0.1: missing go.sum entry for go.mod file; to add it:\n\tgo mod download example.com/version$'
-- go.mod --

View File

@@ -62,7 +62,7 @@ cmp stdout all-m.txt
go mod edit -go=1.16
! go list -m all
stderr '^go: example\.net/indirect@v0\.1\.0 requires\n\texample\.net/ambiguous@v0\.1\.0: missing go\.sum entry; to add it:\n\tgo mod download example\.net/ambiguous\n'
stderr '^go: example\.net/indirect@v0\.1\.0 requires\n\texample\.net/ambiguous@v0\.1\.0: missing go\.sum entry for go\.mod file; to add it:\n\tgo mod download example\.net/ambiguous\n'
-- go.mod --

View File

@@ -45,14 +45,14 @@ go mod tidy -compat=1.17
! stderr .
cmp go.mod go.mod.orig
go list -deps -test -f $MODFMT all
stdout '^example\.com/retract/incompatible v1\.0\.0$'
go list -deps -test -f $MODFMT ./...
stdout '^example.net/lazy v0.1.0$'
go mod edit -go=1.16
! go list -deps -test -f $MODFMT all
! go list -deps -test -f $MODFMT ./...
# TODO(#46160): -count=1 instead of -count=2.
stderr -count=2 '^go: example\.net/lazy@v0\.1\.0 requires\n\texample\.com/retract/incompatible@v1\.0\.0: missing go\.sum entry; to add it:\n\tgo mod download example\.com/retract/incompatible$'
stderr -count=2 '^go: example\.net/lazy@v0\.1\.0 requires\n\texample\.com/retract/incompatible@v1\.0\.0: missing go\.sum entry for go\.mod file; to add it:\n\tgo mod download example\.com/retract/incompatible$'
# If we combine a Go 1.16 go.sum file...
@@ -63,7 +63,7 @@ cp go.mod.orig go.mod
# ...then Go 1.17 no longer works. 😞
! go list -deps -test -f $MODFMT all
stderr -count=1 '^can''t load test package: lazy[/\\]lazy_test.go:3:8: missing go\.sum entry for module providing package example\.com/retract/incompatible \(imported by example\.net/lazy\); to add:\n\tgo get -t example.net/lazy@v0\.1\.0$'
stderr -count=1 '^go: can''t load test package: lazy[/\\]lazy_test.go:3:8: missing go\.sum entry for module providing package example\.com/retract/incompatible \(imported by example\.net/lazy\); to add:\n\tgo get -t example.net/lazy@v0\.1\.0$'
# However, if we take the union of the go.sum files...

View File

@@ -49,7 +49,7 @@ cmp go.mod go.mod.orig
go mod edit -go=1.16
! go list -f $MODFMT -deps ./...
# TODO(#46160): -count=1 instead of -count=2.
stderr -count=2 '^go: example\.net/lazy@v0\.1\.0 requires\n\texample\.net/requireincompatible@v0\.1\.0 requires\n\texample\.com/retract/incompatible@v2\.0\.0\+incompatible: missing go.sum entry; to add it:\n\tgo mod download example.com/retract/incompatible$'
stderr -count=2 '^go: example\.net/lazy@v0\.1\.0 requires\n\texample\.net/requireincompatible@v0\.1\.0 requires\n\texample\.com/retract/incompatible@v2\.0\.0\+incompatible: missing go.sum entry for go.mod file; to add it:\n\tgo mod download example.com/retract/incompatible$'
# There are two ways for the module author to bring the two into alignment.

View File

@@ -48,7 +48,7 @@ cmp stdout out-117.txt
go mod edit -go=1.16
! go list -deps -test -f $MODFMT all
# TODO(#46160): -count=1 instead of -count=2.
stderr -count=2 '^go: example.net/lazy@v0.1.0 requires\n\texample.com/retract/incompatible@v1.0.0: missing go.sum entry; to add it:\n\tgo mod download example.com/retract/incompatible$'
stderr -count=2 '^go: example.net/lazy@v0.1.0 requires\n\texample.com/retract/incompatible@v1.0.0: missing go.sum entry for go.mod file; to add it:\n\tgo mod download example.com/retract/incompatible$'
-- go.mod --

View File

@@ -0,0 +1,69 @@
# Regression test for https://go.dev/issue/60313: 'go mod tidy' did not preserve
# dependencies needed to prevent 'ambiguous import' errors in external test
# dependencies.
cp go.mod go.mod.orig
go mod tidy
cmp go.mod go.mod.orig
-- go.mod --
module example
go 1.20
require (
example.net/a v0.1.0
example.net/b v0.1.0
)
require example.net/outer/inner v0.1.0 // indirect
replace (
example.net/a v0.1.0 => ./a
example.net/b v0.1.0 => ./b
example.net/outer v0.1.0 => ./outer
example.net/outer/inner v0.1.0 => ./inner
)
-- example.go --
package example
import (
_ "example.net/a"
_ "example.net/b"
)
-- a/go.mod --
module example.net/a
go 1.20
require example.net/outer/inner v0.1.0
-- a/a.go --
package a
-- a/a_test.go --
package a_test
import _ "example.net/outer/inner"
-- b/go.mod --
module example.net/b
go 1.20
require example.net/outer v0.1.0
-- b/b.go --
package b
-- b/b_test.go --
package b_test
import _ "example.net/outer/inner"
-- inner/go.mod --
module example.net/outer/inner
go 1.20
-- inner/inner.go --
package inner
-- outer/go.mod --
module example.net/outer
go 1.20
-- outer/inner/inner.go --
package inner

View File

@@ -15,8 +15,7 @@ stdout '\Aok\s+example.com/x\s+[0-9.s]+\n\z'
# Even though ./x looks like a package path, the real package should be
# the implicit '.'.
! go test --answer=42 ./x
stderr '^no Go files in .+$'
! stderr '/x'
stderr '^no Go files in '$PWD'$'
# However, *flags* that appear after unrecognized flags should still be
# interpreted as flags, under the (possibly-erroneous) assumption that

View File

@@ -0,0 +1,24 @@
# This test checks that external linking with --gc-sections does not strip version information.
[short] skip
[!cgo] skip
[GOOS:aix] skip # no --gc-sections
[GOOS:darwin] skip # no --gc-sections
go build -ldflags='-linkmode=external -extldflags=-Wl,--gc-sections'
go version hello$GOEXE
! stdout 'not a Go executable'
! stderr 'not a Go executable'
-- go.mod --
module hello
-- hello.go --
package main
/*
*/
import "C"
func main() {
println("hello")
}

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