Merge branch 'master' into dev.regabi

Change-Id: I098acdbc5e2676aeb8700d935e796a9c29d04b88
This commit is contained in:
Alexander Rakoczy 2020-12-14 11:42:42 -05:00
commit 267975dc47
399 changed files with 3512 additions and 2229 deletions

View File

@ -26,12 +26,12 @@ Do not send CLs removing the interior tags from such phrases.
<h2 id="language">Changes to the language</h2>
<p>
TODO
There are no changes to the language.
</p>
<h2 id="ports">Ports</h2>
<h3 id="darwin">Darwin</h3>
<h3 id="darwin">Darwin and iOS</h3>
<p><!-- golang.org/issue/38485, golang.org/issue/41385, CL 266373, more CLs -->
Go 1.16 adds support of 64-bit ARM architecture on macOS (also known as
@ -43,15 +43,24 @@ Do not send CLs removing the interior tags from such phrases.
</p>
<p><!-- CL 254740 -->
The iOS port, which was previously <code>darwin/arm64</code>, is now
moved to <code>ios/arm64</code>. <code>GOOS=ios</code> implies the
The iOS port, which was previously <code>darwin/arm64</code>, has
been renamed to <code>ios/arm64</code>. <code>GOOS=ios</code>
implies the
<code>darwin</code> build tag, just as <code>GOOS=android</code>
implies the <code>linux</code> build tag.
implies the <code>linux</code> build tag. This change should be
transparent to anyone using gomobile to build iOS apps.
</p>
<p><!-- golang.org/issue/42100, CL 263798 -->
The <code>ios/amd64</code> port is added, targetting the iOS simulator
running on AMD64-based macOS.
Go 1.16 adds an <code>ios/amd64</code> port, which targets the iOS
simulator running on AMD64-based macOS. Previously this was
unofficially supported through <code>darwin/amd64</code> with
the <code>ios</code> build tag set.
</p>
<p><!-- golang.org/issue/23011 -->
Go 1.16 is the last release that will run on macOS 10.12 Sierra.
Go 1.17 will require macOS 10.13 High Sierra or later.
</p>
<h3 id="netbsd">NetBSD</h3>
@ -61,6 +70,14 @@ Do not send CLs removing the interior tags from such phrases.
<code>netbsd/arm64</code> port).
</p>
<h3 id="openbsd">OpenBSD</h3>
<p><!-- golang.org/issue/40995 -->
Go now supports the MIPS64 architecture on OpenBSD
(the <code>openbsd/mips64</code> port). This port does not yet
support cgo.
</p>
<h3 id="386">386</h3>
<p><!-- golang.org/issue/40255, golang.org/issue/41848, CL 258957, and CL 260017 -->
@ -72,6 +89,14 @@ Do not send CLs removing the interior tags from such phrases.
with <code>GO386=softfloat</code>.
</p>
<h3 id="riscv">RISC-V</h3>
<p><!-- golang.org/issue/36641, CL 267317 -->
The <code>linux/riscv64</code> port now supports cgo and
<code>-buildmode=pie</code>. This release also includes performance
optimizations and code generation improvements for RISC-V.
</p>
<h2 id="tools">Tools</h2>
<p>
@ -85,7 +110,7 @@ Do not send CLs removing the interior tags from such phrases.
<p><!-- golang.org/issue/41330 -->
Module-aware mode is enabled by default, regardless of whether a
<code>go.mod</code> file is present in the current working directory or a
parent directory. Specifically, the <code>GO111MODULE</code> environment
parent directory. More precisely, the <code>GO111MODULE</code> environment
variable now defaults to <code>on</code>. To switch to the previous behavior,
set <code>GO111MODULE</code> to <code>auto</code>.
</p>
@ -141,6 +166,17 @@ Do not send CLs removing the interior tags from such phrases.
non-reproducible builds.
</p>
<h4 id="embed">Embedding Files</h4>
<p>
The <code>go</code> command now supports including
static files and file trees as part of the final executable,
using the new <code>//go:embed</code> directive.
See the documentation for the new
<a href="/pkg/embed/"><code>embed</code></a>
package for details.
</p>
<h4 id="go-test"><code>go</code> <code>test</code></h4>
<p><!-- golang.org/issue/29062 -->
@ -166,7 +202,7 @@ Do not send CLs removing the interior tags from such phrases.
The <code>go</code> <code>get</code> <code>-insecure</code> flag is
deprecated and will be removed in a future version. This flag permits
fetching from repositories and resolving custom domains using insecure
schemes such as HTTP, and also bypassess module sum validation using the
schemes such as HTTP, and also bypasses module sum validation using the
checksum database. To permit the use of insecure schemes, use the
<code>GOINSECURE</code> environment variable instead. To bypass module
sum validation, use <code>GOPRIVATE</code> or <code>GONOSUMDB</code>.
@ -257,10 +293,41 @@ Do not send CLs removing the interior tags from such phrases.
<!-- CL 235677: https://golang.org/cl/235677: cmd/vet: bring in pass to catch invalid uses of testing.T in goroutines -->
</p>
<p><!-- CL 248686, CL 276372 -->
The vet tool now warns about amd64 assembly that clobbers the BP
register (the frame pointer) without saving and restoring it,
contrary to the calling convention. Code that doesn't preserve the
BP register must be modified to either not use BP at all or preserve
BP by saving and restoring it. An easy way to preserve BP is to set
the frame size to a nonzero value, which causes the generated
prologue and epilogue to preserve the BP register for you.
See <a href="https://golang.org/cl/248260">CL 248260</a> for example
fixes.
</p>
<h2 id="runtime">Runtime</h2>
<p>
TODO
The new <a href="/pkg/runtime/metrics/"><code>runtime/metrics</code></a> package
introduces a stable interface for reading
implementation-defined metrics from the Go runtime.
It supersedes existing functions like
<a href="/pkg/runtime/#ReadMemStats"><code>runtime.ReadMemStats</code></a>
and
<a href="/pkg/runtime/debug/#GCStats"><code>debug.GCStats</code></a>
and is significantly more general and efficient.
See the package documentation for more details.
</p>
<p><!-- CL 254659 -->
Setting the <code>GODEBUG</code> environment variable
to <code>inittrace=1</code> now causes the runtime to emit a single
line to standard error for each package <code>init</code>,
summarizing its execution time and memory allocation. This trace can
be used to find bottlenecks or regressions in Go startup
performance.
The <a href="/pkg/runtime/#hdr-Environment_Variables"><code>GODEBUG</code><
documentation</a> describes the format.
</p>
<p><!-- CL 267100 -->
@ -275,10 +342,21 @@ Do not send CLs removing the interior tags from such phrases.
variable.
</p>
<p><!-- CL 220419, CL 271987 -->
Go 1.16 fixes a discrepancy between the race detector and
the <a href="/ref/mem">Go memory model</a>. The race detector now
more precisely follows the channel synchronization rules of the
memory model. As a result, the detector may now report races it
previously missed.
</p>
<h2 id="compiler">Compiler</h2>
<p>
TODO
<p><!-- CL 256459, CL 264837, CL 266203, CL 256460 -->
The compiler can now inline functions with
non-labeled <code>for</code> loops, method values, and type
switches. The inliner can also detect more indirect calls where
inlining is possible.
</p>
<h2 id="linker">Linker</h2>
@ -297,13 +375,10 @@ Do not send CLs removing the interior tags from such phrases.
supported architecture/OS combinations (the 1.15 performance improvements
were primarily focused on <code>ELF</code>-based OSes and
<code>amd64</code> architectures). For a representative set of
large Go programs, linking is 20-35% faster than 1.15 and requires
large Go programs, linking is 20-25% faster than 1.15 and requires
5-15% less memory on average for <code>linux/amd64</code>, with larger
improvements for other architectures and OSes.
</p>
<p>
TODO: update with final numbers later in the release.
improvements for other architectures and OSes. Most binaries are
also smaller as a result of more aggressive symbol pruning.
</p>
<p><!-- CL 255259 -->
@ -313,9 +388,54 @@ Do not send CLs removing the interior tags from such phrases.
<h2 id="library">Core library</h2>
<h3 id="library-embed">Embedded Files</h3>
<p>
TODO: mention significant additions like new packages (<code>io/fs</code>),
new proposal-scoped features (<code>//go:embed</code>), and so on
The new <a href="/pkg/embed/"><code>embed</code></a> package
provides access to files embedded in the program during compilation
using the new <a href="#embed"><code>//go:embed</code> directive</a>.
</p>
<h3 id="fs">File Systems</h3>
<p>
The new <a href="/pkg/io/fs/"><code>io/fs</code></a> package
defines an abstraction for read-only trees of files,
the <a href="/pkg/io/fs/#FS"><code>fs.FS</code></a> interface,
and the standard library packages have
been adapted to make use of the interface as appropriate.
</p>
<p>
On the producer side of the interface,
the new <a href="/pkg/embed/#FS">embed.FS</code></a> type
implements <code>fs.FS</code>, as does
<a href="/pkg/archive/zip/#Reader"><code>zip.Reader</code></a>.
The new <a href="/pkg/os/#DirFS"><code>os.DirFS</code></a> function
provides an implementation of <code>fs.FS</code> backed by a tree
of operating system files.
</p>
<p>
On the consumer side,
the new <a href="/pkg/net/http/#FS"><code>http.FS</code></a>
function converts an <code>fs.FS</code> to an
<a href="/pkg/net/http/#Handler"><code>http.Handler</code></a>.
Also, the <a href="/pkg/html/template/"><code>html/template</code></a>
and <a href="/pkg/text/template/"><code>text/template</code></a>
packages <a href="/pkg/html/template/#ParseFS"><code>ParseFS</code></a>
functions and methods read templates from an <code>fs.FS</code>.
</p>
<p>
For testing code that implements <code>fs.FS</code>,
the new <a href="/pkg/testing/fstest/"><code>testing/fstest</code></a>
package provides a <a href="/pkg/testing/fstest/#TestFS"><code>TestFS</code></a>
function that checks for and reports common mistakes.
It also provides a simple in-memory file system implementation,
<a href="/pkg/testing/fstest/#MapFS"><code>MapFS</code></a>,
which can be useful for testing code that accepts <code>fs.FS</code>
implementations.
</p>
<p>
@ -347,9 +467,10 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="crypto/hmac"><dt><a href="/pkg/crypto/hmac/">crypto/hmac</a></dt>
<dd>
<p><!-- CL 261960 -->
<a href="/pkg/crypto/hmac/#New">New</a> will now panic if separate calls to
the hash generation function fail to return new values. Previously, the
behavior was undefined and invalid outputs were sometimes generated.
<a href="/pkg/crypto/hmac/#New"><code>New</code></a> will now panic if
separate calls to the hash generation function fail to return new values.
Previously, the behavior was undefined and invalid outputs were sometimes
generated.
</p>
</dd>
</dl><!-- crypto/hmac -->
@ -357,82 +478,83 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="crypto/tls"><dt><a href="/pkg/crypto/tls/">crypto/tls</a></dt>
<dd>
<p><!-- CL 256897 -->
I/O operations on closing or closed TLS connections can now be detected using
the new <a href="/pkg/net/#ErrClosed">ErrClosed</a> error. A typical use
would be <code>errors.Is(err, net.ErrClosed)</code>. In earlier releases
the only way to reliably detect this case was to match the string returned
by the <code>Error</code> method with <code>"tls: use of closed connection"</code>.
I/O operations on closing or closed TLS connections can now be detected
using the new <a href="/pkg/net/#ErrClosed"><code>net.ErrClosed</code></a>
error. A typical use would be <code>errors.Is(err, net.ErrClosed)</code>.
</p>
<p><!-- CL 266037 -->
A default deadline is set in <a href="/pkg/crypto/tls/#Conn.Close">Close</a>
before sending the close notify alert, in order to prevent blocking
A default write deadline is now set in
<a href="/pkg/crypto/tls/#Conn.Close"><code>Conn.Close</code></a>
before sending the "close notify" alert, in order to prevent blocking
indefinitely.
</p>
<p><!-- CL 246338 -->
<a href="/pkg/crypto/tls#Conn.HandshakeContext">(*Conn).HandshakeContext</a> was added to
allow the user to control cancellation of an in-progress TLS Handshake.
The context provided is propagated into the
<a href="/pkg/crypto/tls#ClientHelloInfo">ClientHelloInfo</a>
and <a href="/pkg/crypto/tls#CertificateRequestInfo">CertificateRequestInfo</a>
structs and accessible through the new
<a href="/pkg/crypto/tls#ClientHelloInfo.Context">(*ClientHelloInfo).Context</a>
and
<a href="/pkg/crypto/tls#CertificateRequestInfo.Context">
(*CertificateRequestInfo).Context
</a> methods respectively. Canceling the context after the handshake has finished
has no effect.
The new <a href="/pkg/crypto/tls#Conn.HandshakeContext"><code>Conn.HandshakeContext</code></a>
method allows cancellation of an in-progress handshake. The provided
context is accessible through the new
<a href="/pkg/crypto/tls#ClientHelloInfo.Context"><code>ClientHelloInfo.Context</code></a>
and <a href="/pkg/crypto/tls#CertificateRequestInfo.Context">
<code>CertificateRequestInfo.Context</code></a> methods. Canceling the
context after the handshake has finished has no effect.
</p>
<p><!-- CL 239748 -->
Clients now ensure that the server selects
Clients now return a handshake error if the server selects
<a href="/pkg/crypto/tls/#ConnectionState.NegotiatedProtocol">
an ALPN protocol</a> from
an ALPN protocol</a> that was not in
<a href="/pkg/crypto/tls/#Config.NextProtos">
the list advertised by the client</a>.
</p>
<p><!-- CL 262857 -->
TLS servers will now prefer other AEAD cipher suites (such as ChaCha20Poly1305)
Servers will now prefer other available AEAD cipher suites (such as ChaCha20Poly1305)
over AES-GCM cipher suites if either the client or server doesn't have AES hardware
support, unless the application set both
<a href="/pkg/crypto/tls/#Config.PreferServerCipherSuites"><code>Config.PreferServerCipherSuites</code></a>
support, unless both <a href="/pkg/crypto/tls/#Config.PreferServerCipherSuites">
<code>Config.PreferServerCipherSuites</code></a>
and <a href="/pkg/crypto/tls/#Config.CipherSuites"><code>Config.CipherSuites</code></a>
or there are no other AEAD cipher suites supported.
The client is assumed not to have AES hardware support if it does not signal a
preference for AES-GCM cipher suites.
are set. The client is assumed not to have AES hardware support if it does
not signal a preference for AES-GCM cipher suites.
</p>
<p><!-- CL 246637 -->
<a href="/pkg/crypto/tls/#Config.Clone"><code>Config.Clone</code></a> now returns
a nil <code>*Config</code> if the source is nil, rather than panicking.
<a href="/pkg/crypto/tls/#Config.Clone"><code>Config.Clone</code></a> now
returns nil if the receiver is nil, rather than panicking.
</p>
</dd>
</dl><!-- crypto/tls -->
<dl id="crypto/x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt>
<dd>
<p>
The <code>GODEBUG=x509ignoreCN=0</code> flag will be removed in Go 1.17.
It enables the legacy behavior of treating the <code>CommonName</code>
field on X.509 certificates as a host name when no Subject Alternative
Names are present.
</p>
<p><!-- CL 235078 -->
<a href="/pkg/crypto/x509/#ParseCertificate">ParseCertificate</a> and
<a href="/pkg/crypto/x509/#CreateCertificate">CreateCertificate</a> both
now enforce string encoding restrictions for the fields <code>DNSNames</code>,
<code>EmailAddresses</code>, and <code>URIs</code>. These fields can only
contain strings with characters within the ASCII range.
<a href="/pkg/crypto/x509/#ParseCertificate"><code>ParseCertificate</code></a> and
<a href="/pkg/crypto/x509/#CreateCertificate"><code>CreateCertificate</code></a>
now enforce string encoding restrictions for the <code>DNSNames</code>,
<code>EmailAddresses</code>, and <code>URIs</code> fields. These fields
can only contain strings with characters within the ASCII range.
</p>
<p><!-- CL 259697 -->
<a href="/pkg/crypto/x509/#CreateCertificate">CreateCertificate</a> now
verifies the generated certificate's signature using the signer's
public key. If the signature is invalid, an error is returned, instead
of a malformed certificate.
<a href="/pkg/crypto/x509/#CreateCertificate"><code>CreateCertificate</code></a>
now verifies the generated certificate's signature using the signer's
public key. If the signature is invalid, an error is returned, instead of
a malformed certificate.
</p>
<p><!-- CL 233163 -->
A number of additional fields have been added to the
<a href="/pkg/crypto/x509/#CertificateRequest">CertificateRequest</a> type.
These fields are now parsed in <a href="/pkg/crypto/x509/#ParseCertificateRequest">ParseCertificateRequest</a>
and marshalled in <a href="/pkg/crypto/x509/#CreateCertificateRequest">CreateCertificateRequest</a>.
<a href="/pkg/crypto/x509/#CertificateRequest"><code>CertificateRequest</code></a> type.
These fields are now parsed in <a href="/pkg/crypto/x509/#ParseCertificateRequest">
<code>ParseCertificateRequest</code></a> and marshalled in
<a href="/pkg/crypto/x509/#CreateCertificateRequest"><code>CreateCertificateRequest</code></a>.
</p>
<p><!-- CL 257939 -->
@ -448,7 +570,9 @@ Do not send CLs removing the interior tags from such phrases.
</p>
<p><!-- CL 262343 -->
TODO: <a href="https://golang.org/cl/262343">https://golang.org/cl/262343</a>: add Unwrap to SystemRootsError
The new <a href="/pkg/crypto/x509/#SystemRootsError.Unwrap"><code>SystemRootsError.Unwrap</code></a>
method allows accessing the <a href="/pkg/crypto/x509/#SystemRootsError.Err"><code>Err</code></a>
field through the <a href="/pkg/errors"><code>errors</code></a> package functions.
</p>
</dd>
</dl><!-- crypto/x509 -->
@ -456,11 +580,11 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="encoding/asn1"><dt><a href="/pkg/encoding/asn1">encoding/asn1</a></dt>
<dd>
<p><!-- CL 255881 -->
<a href="/pkg/encoding/asn1/#Unmarshal">Unmarshal</a> and
<a href="/pkg/encoding/asn1/#UnmarshalWithParams">UnmarshalWithParams</a>
now return an error instead of panic when the argument is not
<a href="/pkg/encoding/asn1/#Unmarshal"><code>Unmarshal</code></a> and
<a href="/pkg/encoding/asn1/#UnmarshalWithParams"><code>UnmarshalWithParams</code></a>
now return an error instead of panicking when the argument is not
a pointer or is nil. This change matches the behavior of other
encoding packages such as <a href="/pkg/encoding/json">encoding/json</a>.
encoding packages such as <a href="/pkg/encoding/json"><code>encoding/json</code></a>.
</p>
</dd>
</dl>
@ -494,7 +618,10 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="flag"><dt><a href="/pkg/flag/">flag</a></dt>
<dd>
<p><!-- CL 240014 -->
TODO: <a href="https://golang.org/cl/240014">https://golang.org/cl/240014</a>: add Func
The new <a href="/pkg/flag/#Func"><code>Func</code></a> function
allows registering a flag implemented by calling a function,
as a lighter-weight alternative to implementing the
<a href="/pkg/flag/#Value"><code>Value</code></a> interface.
</p>
</dd>
</dl><!-- flag -->
@ -502,7 +629,8 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="io"><dt><a href="/pkg/io/">io</a></dt>
<dd>
<p><!-- CL 261577 -->
TODO: <a href="https://golang.org/cl/261577">https://golang.org/cl/261577</a>: add a new ReadSeekCloser interface
The package now defines a
<a href="/pkg/io/#ReadSeekCloser"><code>ReadSeekCloser</code></a> interface.
</p>
</dd>
</dl><!-- io -->
@ -510,7 +638,8 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="log"><dt><a href="/pkg/log/">log</a></dt>
<dd>
<p><!-- CL 264460 -->
TODO: <a href="https://golang.org/cl/264460">https://golang.org/cl/264460</a>: expose std via new Default function
The new <a href="/pkg/log/#Default"><code>Default</code></a> function
provides access to the default <a href="/pkg/log/#Logger"><code>Logger</code></a>.
</p>
</dd>
</dl><!-- log -->
@ -518,7 +647,11 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="log/syslog"><dt><a href="/pkg/log/syslog/">log/syslog</a></dt>
<dd>
<p><!-- CL 264297 -->
TODO: <a href="https://golang.org/cl/264297">https://golang.org/cl/264297</a>: set local to true if network is any of &#34;unix&#34;, or &#34;unixgram&#34;
The <a href="/pkg/log/syslog/#Writer"><code>Writer</code></a>
now uses the local message format
(omitting the host name and using a shorter time stamp)
when logging to custom Unix domain sockets,
matching the format already used for the default log socket.
</p>
</dd>
</dl><!-- log/syslog -->
@ -526,7 +659,10 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="mime/multipart"><dt><a href="/pkg/mime/multipart/">mime/multipart</a></dt>
<dd>
<p><!-- CL 247477 -->
TODO: <a href="https://golang.org/cl/247477">https://golang.org/cl/247477</a>: return overflow errors in Reader.ReadForm
The <a href="/pkg/mime/multipart/#Reader"><code>Reader</code></a>'s
<a href="/pkg/mime/multipart/#Reader.ReadForm"><code>ReadForm</code></a>
method no longer rejects form data
when passed the maximum int64 value as a limit.
</p>
</dd>
</dl><!-- mime/multipart -->
@ -550,7 +686,10 @@ Do not send CLs removing the interior tags from such phrases.
</p>
<p><!-- CL 238629 -->
TODO: <a href="https://golang.org/cl/238629">https://golang.org/cl/238629</a>: prefer /etc/hosts over DNS when no /etc/nsswitch.conf is present
On Linux, host name lookups no longer use DNS before checking
<code>/etc/hosts</code> when <code>/etc/nsswitch.conf</code>
is missing; this is common on musl-based systems and makes
Go programs match the behavior of C programs on those systems.
</p>
</dd>
</dl><!-- net -->
@ -578,23 +717,29 @@ Do not send CLs removing the interior tags from such phrases.
</p>
<p><!-- CL 256498, golang.org/issue/36990 -->
Cookies set with <code>SameSiteDefaultMode</code> now behave according to the current
spec (no attribute is set) instead of generating a SameSite key without a value.
Cookies set with <a href="/pkg/net/http/#SameSiteDefaultMode"><code>SameSiteDefaultMode</code></a>
now behave according to the current spec (no attribute is set) instead of
generating a SameSite key without a value.
</p>
<p><!-- CL 246338 -->
The <a href="/pkg/net/http/"><code>net/http</code></a> package now uses the new
<a href="/pkg/crypto/tls#Conn.HandshakeContext"><code>(*tls.Conn).HandshakeContext</code></a>
with the <a href="/pkg/net/http/#Request"><code>Request</code></a> context
when performing TLS handshakes in the client or server.
The <a href="/pkg/net/http/"><code>net/http</code></a> package now passes the
<a href="/pkg/net/http/#Request.Context"><code>Request</code> context</a> to
<a href="/pkg/crypto/tls#Conn.HandshakeContext"><code>tls.Conn.HandshakeContext</code></a>
when performing TLS handshakes.
</p>
<p><!-- CL 250039 -->
TODO: <a href="https://golang.org/cl/250039">https://golang.org/cl/250039</a>: set Content-Length:0 for empty PATCH requests as with POST, PATCH
The <a href="/pkg/net/http/#Client">Client</a> now sends
an explicit <code>Content-Length:</code> <code>0</code>
header in <code>PATCH</code> requests with empty bodies,
matching the existing behavior of <code>POST</code> and <code>PUT</code>.
</p>
<p><!-- CL 249440 -->
TODO: <a href="https://golang.org/cl/249440">https://golang.org/cl/249440</a>: match http scheme when selecting http_proxy
The <a href="/pkg/net/http/#ProxyFromEnvironment">ProxyFromEnvironment</a> function
no longer returns the setting of the <code>HTTP_PROXY</code> environment
variable for <code>https://</code> URLs when <code>HTTPS_PROXY</code> is unset.
</p>
</dd>
</dl><!-- net/http -->
@ -602,7 +747,9 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="net/http/httputil"><dt><a href="/pkg/net/http/httputil/">net/http/httputil</a></dt>
<dd>
<p><!-- CL 260637 -->
TODO: <a href="https://golang.org/cl/260637">https://golang.org/cl/260637</a>: flush ReverseProxy immediately if Content-Length is -1
The <a href="/pkg/net/http/httputil/#ReverseProxy">ReverseProxy</a>
now flushes buffered data more aggressively when proxying
streamed responses with unknown body lengths.
</p>
</dd>
</dl><!-- net/http/httputil -->
@ -610,7 +757,10 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="net/smtp"><dt><a href="/pkg/net/smtp/">net/smtp</a></dt>
<dd>
<p><!-- CL 247257 -->
TODO: <a href="https://golang.org/cl/247257">https://golang.org/cl/247257</a>: adds support for the SMTPUTF8 extension
The <a href="/pkg/net/smtp/#Client">Client</a>'s
<a href="/pkg/net/smtp/#Client.Mail"><code>Mail</code></a>
method now sends the <code>SMTPUTF8</code> directive to
servers that support it, signaling that addresses are encoded in UTF-8.
</p>
</dd>
</dl><!-- net/smtp -->
@ -629,55 +779,52 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="os/signal"><dt><a href="/pkg/os/signal/">os/signal</a></dt>
<dd>
<p><!-- CL 219640 -->
TODO: <a href="https://golang.org/cl/219640">https://golang.org/cl/219640</a>: add NotifyContext to cancel context using system signals
The new
<a href="/pkg/os/signal/#NotifyContext"><code>NotifyContext</code></a>
function allows creating contexts that are canceled upon arrival of
specific signals.
</p>
</dd>
</dl><!-- os/signal -->
<dl id="path"><dt><a href="/pkg/path/">path</a></dt>
<dd>
<p><!-- CL 264397 -->
TODO: <a href="https://golang.org/cl/264397">https://golang.org/cl/264397</a>: validate patterns in Match, Glob
<p><!-- CL 264397, golang.org/issues/28614 -->
The <code>Match</code> and <code>Glob</code> functions now
return an error if the unmatched part of the pattern has a
syntax error. Previously, the functions returned early on a failed
match, and thus did not report any later syntax error in the
pattern.
</p>
</dd>
</dl><!-- path -->
<dl id="path/filepath"><dt><a href="/pkg/path/filepath/">path/filepath</a></dt>
<dd>
<p><!-- CL 264397 -->
TODO: <a href="https://golang.org/cl/264397">https://golang.org/cl/264397</a>: validate patterns in Match, Glob
<p><!-- CL 264397, golang.org/issues/28614 -->
The <code>Match</code> and <code>Glob</code> functions now
return an error if the unmatched part of the pattern has a
syntax error. Previously, the functions returned early on a failed
match, and thus did not report any later syntax error in the
pattern.
</p>
</dd>
</dl><!-- path/filepath -->
<dl id="reflect"><dt><a href="/pkg/reflect/">reflect</a></dt>
<dd>
<p><!-- CL 248341 -->
TODO: <a href="https://golang.org/cl/248341">https://golang.org/cl/248341</a>: support multiple keys in struct tags
<p><!-- CL 248341, golang.org/issues/40281 -->
<code>StructTag</code> now allows multiple space-separated keys
in key:value pairs, as in <code>`json xml:"field1"`</code>
(equivalent to <code>`json:"field1" xml:"field1"`</code>).
</p>
</dd>
</dl><!-- reflect -->
<dl id="runtime"><dt><a href="/pkg/runtime/">runtime</a></dt>
<dd>
<p><!-- CL 37222 -->
TODO: <a href="https://golang.org/cl/37222">https://golang.org/cl/37222</a>: make stack traces of endless recursion print only top and bottom 50
</p>
<p><!-- CL 242258 -->
TODO: <a href="https://golang.org/cl/242258">https://golang.org/cl/242258</a>: add 24 byte allocation size class
</p>
<p><!-- CL 254659 -->
TODO: <a href="https://golang.org/cl/254659">https://golang.org/cl/254659</a>: implement GODEBUG=inittrace=1 support
</p>
</dd>
</dl><!-- runtime -->
<dl id="runtime/debug"><dt><a href="/pkg/runtime/debug/">runtime/debug</a></dt>
<dd>
<p><!-- CL 249677 -->
The <a href="/pkg/runtime#Error"><code>runtime.Error</code> values
The <a href="/pkg/runtime#Error"><code>runtime.Error</code></a> values
used when <code>SetPanicOnFault</code> is enabled may now have an
<code>Addr</code> method. If that method exists, it returns the memory
address that triggered the fault.
@ -700,16 +847,30 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="syscall"><dt><a href="/pkg/syscall/">syscall</a></dt>
<dd>
<p><!-- CL 263271 -->
<a href="/pkg/syscall/?GOOS=windows#NewCallback"><code>NewCallback</code></a>
and
<a href="/pkg/syscall/?GOOS=windows#NewCallbackCDecl"><code>NewCallbackCDecl</code></a>
now correctly support callback functions with multiple
sub-<code>uintptr</code>-sized arguments in a row. This may
require changing uses of these functions to eliminate manual
padding between small arguments.
</p>
<p><!-- CL 261917 -->
<a href="/pkg/syscall/#SysProcAttr"><code>SysProcAttr</code></a> on Windows has a new NoInheritHandles field that disables inheriting handles when creating a new process.
<a href="/pkg/syscall/?GOOS=windows#SysProcAttr"><code>SysProcAttr</code></a> on Windows has a new NoInheritHandles field that disables inheriting handles when creating a new process.
</p>
<p><!-- CL 269761, golang.org/issue/42584 -->
<a href="/pkg/syscall/#DLLError"><code>DLLError</code></a> on Windows now has an Unwrap function for unwrapping its underlying error.
<a href="/pkg/syscall/?GOOS=windows#DLLError"><code>DLLError</code></a> on Windows now has an Unwrap function for unwrapping its underlying error.
</p>
<p><!-- CL 210639 -->
TODO: <a href="https://golang.org/cl/210639">https://golang.org/cl/210639</a>: support POSIX semantics for Linux syscalls
On Linux,
<a href="/pkg/syscall/#Setgid"><code>Setgid</code></a>,
<a href="/pkg/syscall/#Setuid"><code>Setuid</code></a>,
and related calls are now implemented.
Previously, they returned an <code>syscall.EOPNOTSUPP</code> error.
</p>
</dd>
</dl><!-- syscall -->

View File

@ -28,6 +28,7 @@ func TestMSAN(t *testing.T) {
{src: "msan4.go"},
{src: "msan5.go"},
{src: "msan6.go"},
{src: "msan7.go"},
{src: "msan_fail.go", wantErr: true},
}
for _, tc := range cases {

View File

@ -0,0 +1,38 @@
// Copyright 2020 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
// Test passing C struct to exported Go function.
/*
#include <stdint.h>
#include <stdlib.h>
// T is a C struct with alignment padding after b.
// The padding bytes are not considered initialized by MSAN.
// It is big enough to be passed on stack in C ABI (and least
// on AMD64).
typedef struct { char b; uintptr_t x, y; } T;
extern void F(T);
// Use weak as a hack to permit defining a function even though we use export.
void CF(int x) __attribute__ ((weak));
void CF(int x) {
T *t = malloc(sizeof(T));
t->b = (char)x;
t->x = x;
t->y = x;
F(*t);
}
*/
import "C"
//export F
func F(t C.T) { println(t.b, t.x, t.y) }
func main() {
C.CF(C.int(0))
}

View File

@ -10,7 +10,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"math"
"os"
"path"
@ -773,7 +772,7 @@ func TestReadTruncation(t *testing.T) {
"testdata/pax-path-hdr.tar",
"testdata/sparse-formats.tar",
} {
buf, err := ioutil.ReadFile(p)
buf, err := os.ReadFile(p)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}

View File

@ -11,7 +11,6 @@ import (
"internal/testenv"
"io"
"io/fs"
"io/ioutil"
"math"
"os"
"path"
@ -263,7 +262,7 @@ func TestFileInfoHeaderDir(t *testing.T) {
func TestFileInfoHeaderSymlink(t *testing.T) {
testenv.MustHaveSymlink(t)
tmpdir, err := ioutil.TempDir("", "TestFileInfoHeaderSymlink")
tmpdir, err := os.MkdirTemp("", "TestFileInfoHeaderSymlink")
if err != nil {
t.Fatal(err)
}

View File

@ -9,7 +9,6 @@ import (
"encoding/hex"
"errors"
"io"
"io/ioutil"
"os"
"path"
"reflect"
@ -520,7 +519,7 @@ func TestWriter(t *testing.T) {
}
if v.file != "" {
want, err := ioutil.ReadFile(v.file)
want, err := os.ReadFile(v.file)
if err != nil {
t.Fatalf("ReadFile() = %v, want nil", err)
}

View File

@ -11,7 +11,6 @@ import (
"internal/obscuretestdata"
"io"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"regexp"
@ -629,7 +628,7 @@ func readTestFile(t *testing.T, zt ZipTest, ft ZipTestFile, f *File) {
var c []byte
if ft.Content != nil {
c = ft.Content
} else if c, err = ioutil.ReadFile("testdata/" + ft.File); err != nil {
} else if c, err = os.ReadFile("testdata/" + ft.File); err != nil {
t.Error(err)
return
}
@ -685,7 +684,7 @@ func TestInvalidFiles(t *testing.T) {
}
func messWith(fileName string, corrupter func(b []byte)) (r io.ReaderAt, size int64) {
data, err := ioutil.ReadFile(filepath.Join("testdata", fileName))
data, err := os.ReadFile(filepath.Join("testdata", fileName))
if err != nil {
panic("Error reading " + fileName + ": " + err.Error())
}
@ -792,17 +791,17 @@ func returnRecursiveZip() (r io.ReaderAt, size int64) {
//
// func main() {
// bigZip := makeZip("big.file", io.LimitReader(zeros{}, 1<<32-1))
// if err := ioutil.WriteFile("/tmp/big.zip", bigZip, 0666); err != nil {
// if err := os.WriteFile("/tmp/big.zip", bigZip, 0666); err != nil {
// log.Fatal(err)
// }
//
// biggerZip := makeZip("big.zip", bytes.NewReader(bigZip))
// if err := ioutil.WriteFile("/tmp/bigger.zip", biggerZip, 0666); err != nil {
// if err := os.WriteFile("/tmp/bigger.zip", biggerZip, 0666); err != nil {
// log.Fatal(err)
// }
//
// biggestZip := makeZip("bigger.zip", bytes.NewReader(biggerZip))
// if err := ioutil.WriteFile("/tmp/biggest.zip", biggestZip, 0666); err != nil {
// if err := os.WriteFile("/tmp/biggest.zip", biggestZip, 0666); err != nil {
// log.Fatal(err)
// }
// }

View File

@ -10,8 +10,8 @@ import (
"fmt"
"io"
"io/fs"
"io/ioutil"
"math/rand"
"os"
"strings"
"testing"
"time"
@ -237,7 +237,7 @@ func TestWriterTime(t *testing.T) {
t.Fatalf("unexpected Close error: %v", err)
}
want, err := ioutil.ReadFile("testdata/time-go.zip")
want, err := os.ReadFile("testdata/time-go.zip")
if err != nil {
t.Fatalf("unexpected ReadFile error: %v", err)
}

View File

@ -8,7 +8,6 @@ import (
"bufio"
"bytes"
"internal/testenv"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@ -98,8 +97,8 @@ func testAddr2Line(t *testing.T, exepath, addr string) {
if !os.SameFile(fi1, fi2) {
t.Fatalf("addr2line_test.go and %s are not same file", srcPath)
}
if srcLineNo != "107" {
t.Fatalf("line number = %v; want 107", srcLineNo)
if srcLineNo != "106" {
t.Fatalf("line number = %v; want 106", srcLineNo)
}
}
@ -107,7 +106,7 @@ func testAddr2Line(t *testing.T, exepath, addr string) {
func TestAddr2Line(t *testing.T) {
testenv.MustHaveGoBuild(t)
tmpDir, err := ioutil.TempDir("", "TestAddr2Line")
tmpDir, err := os.MkdirTemp("", "TestAddr2Line")
if err != nil {
t.Fatal("TempDir failed: ", err)
}

View File

@ -17,7 +17,6 @@ import (
"go/token"
"go/types"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
@ -342,7 +341,7 @@ func fileFeatures(filename string) []string {
if filename == "" {
return nil
}
bs, err := ioutil.ReadFile(filename)
bs, err := os.ReadFile(filename)
if err != nil {
log.Fatalf("Error reading file %s: %v", filename, err)
}

View File

@ -9,7 +9,6 @@ import (
"flag"
"fmt"
"go/build"
"io/ioutil"
"os"
"path/filepath"
"sort"
@ -75,7 +74,7 @@ func TestGolden(t *testing.T) {
f.Close()
}
bs, err := ioutil.ReadFile(goldenFile)
bs, err := os.ReadFile(goldenFile)
if err != nil {
t.Fatalf("opening golden.txt for package %q: %v", fi.Name(), err)
}

View File

@ -187,16 +187,17 @@ var runtimeDecls = [...]struct {
{"racewriterange", funcTag, 121},
{"msanread", funcTag, 121},
{"msanwrite", funcTag, 121},
{"checkptrAlignment", funcTag, 122},
{"checkptrArithmetic", funcTag, 124},
{"libfuzzerTraceCmp1", funcTag, 126},
{"libfuzzerTraceCmp2", funcTag, 128},
{"libfuzzerTraceCmp4", funcTag, 129},
{"libfuzzerTraceCmp8", funcTag, 130},
{"libfuzzerTraceConstCmp1", funcTag, 126},
{"libfuzzerTraceConstCmp2", funcTag, 128},
{"libfuzzerTraceConstCmp4", funcTag, 129},
{"libfuzzerTraceConstCmp8", funcTag, 130},
{"msanmove", funcTag, 122},
{"checkptrAlignment", funcTag, 123},
{"checkptrArithmetic", funcTag, 125},
{"libfuzzerTraceCmp1", funcTag, 127},
{"libfuzzerTraceCmp2", funcTag, 129},
{"libfuzzerTraceCmp4", funcTag, 130},
{"libfuzzerTraceCmp8", funcTag, 131},
{"libfuzzerTraceConstCmp1", funcTag, 127},
{"libfuzzerTraceConstCmp2", funcTag, 129},
{"libfuzzerTraceConstCmp4", funcTag, 130},
{"libfuzzerTraceConstCmp8", funcTag, 131},
{"x86HasPOPCNT", varTag, 6},
{"x86HasSSE41", varTag, 6},
{"x86HasFMA", varTag, 6},
@ -205,7 +206,7 @@ var runtimeDecls = [...]struct {
}
func runtimeTypes() []*types.Type {
var typs [131]*types.Type
var typs [132]*types.Type
typs[0] = types.ByteType
typs[1] = types.NewPtr(typs[0])
typs[2] = types.Types[types.TANY]
@ -328,14 +329,15 @@ func runtimeTypes() []*types.Type {
typs[119] = functype(nil, []*ir.Field{anonfield(typs[65])}, []*ir.Field{anonfield(typs[20])})
typs[120] = functype(nil, []*ir.Field{anonfield(typs[26]), anonfield(typs[26])}, []*ir.Field{anonfield(typs[26])})
typs[121] = functype(nil, []*ir.Field{anonfield(typs[5]), anonfield(typs[5])}, nil)
typs[122] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil)
typs[123] = types.NewSlice(typs[7])
typs[124] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[123])}, nil)
typs[125] = types.Types[types.TUINT8]
typs[126] = functype(nil, []*ir.Field{anonfield(typs[125]), anonfield(typs[125])}, nil)
typs[127] = types.Types[types.TUINT16]
typs[128] = functype(nil, []*ir.Field{anonfield(typs[127]), anonfield(typs[127])}, nil)
typs[129] = functype(nil, []*ir.Field{anonfield(typs[65]), anonfield(typs[65])}, nil)
typs[130] = functype(nil, []*ir.Field{anonfield(typs[24]), anonfield(typs[24])}, nil)
typs[122] = functype(nil, []*ir.Field{anonfield(typs[5]), anonfield(typs[5]), anonfield(typs[5])}, nil)
typs[123] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil)
typs[124] = types.NewSlice(typs[7])
typs[125] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[124])}, nil)
typs[126] = types.Types[types.TUINT8]
typs[127] = functype(nil, []*ir.Field{anonfield(typs[126]), anonfield(typs[126])}, nil)
typs[128] = types.Types[types.TUINT16]
typs[129] = functype(nil, []*ir.Field{anonfield(typs[128]), anonfield(typs[128])}, nil)
typs[130] = functype(nil, []*ir.Field{anonfield(typs[65]), anonfield(typs[65])}, nil)
typs[131] = functype(nil, []*ir.Field{anonfield(typs[24]), anonfield(typs[24])}, nil)
return typs[:]
}

View File

@ -237,6 +237,7 @@ func racewriterange(addr, size uintptr)
// memory sanitizer
func msanread(addr, size uintptr)
func msanwrite(addr, size uintptr)
func msanmove(dst, src, size uintptr)
func checkptrAlignment(unsafe.Pointer, *byte, uintptr)
func checkptrArithmetic(unsafe.Pointer, []unsafe.Pointer)

View File

@ -209,6 +209,7 @@ var (
growslice,
msanread,
msanwrite,
msanmove,
newobject,
newproc,
panicdivide,

View File

@ -82,6 +82,7 @@ func initssaconfig() {
growslice = sysfunc("growslice")
msanread = sysfunc("msanread")
msanwrite = sysfunc("msanwrite")
msanmove = sysfunc("msanmove")
newobject = sysfunc("newobject")
newproc = sysfunc("newproc")
panicdivide = sysfunc("panicdivide")
@ -965,8 +966,46 @@ func (s *state) newValueOrSfCall2(op ssa.Op, t *types.Type, arg0, arg1 *ssa.Valu
return s.newValue2(op, t, arg0, arg1)
}
func (s *state) instrument(t *types.Type, addr *ssa.Value, wr bool) {
if !s.curfn.InstrumentBody() {
type instrumentKind uint8
const (
instrumentRead = iota
instrumentWrite
instrumentMove
)
func (s *state) instrument(t *types.Type, addr *ssa.Value, kind instrumentKind) {
s.instrument2(t, addr, nil, kind)
}
// instrumentFields instruments a read/write operation on addr.
// If it is instrumenting for MSAN and t is a struct type, it instruments
// operation for each field, instead of for the whole struct.
func (s *state) instrumentFields(t *types.Type, addr *ssa.Value, kind instrumentKind) {
if !base.Flag.MSan || !t.IsStruct() {
s.instrument(t, addr, kind)
return
}
for _, f := range t.Fields().Slice() {
if f.Sym.IsBlank() {
continue
}
offptr := s.newValue1I(ssa.OpOffPtr, types.NewPtr(f.Type), f.Offset, addr)
s.instrumentFields(f.Type, offptr, kind)
}
}
func (s *state) instrumentMove(t *types.Type, dst, src *ssa.Value) {
if base.Flag.MSan {
s.instrument2(t, dst, src, instrumentMove)
} else {
s.instrument(t, src, instrumentRead)
s.instrument(t, dst, instrumentWrite)
}
}
func (s *state) instrument2(t *types.Type, addr, addr2 *ssa.Value, kind instrumentKind) {
if !s.curfn.Func().InstrumentBody() {
return
}
@ -982,33 +1021,54 @@ func (s *state) instrument(t *types.Type, addr *ssa.Value, wr bool) {
var fn *obj.LSym
needWidth := false
if addr2 != nil && kind != instrumentMove {
panic("instrument2: non-nil addr2 for non-move instrumentation")
}
if base.Flag.MSan {
fn = msanread
if wr {
switch kind {
case instrumentRead:
fn = msanread
case instrumentWrite:
fn = msanwrite
case instrumentMove:
fn = msanmove
default:
panic("unreachable")
}
needWidth = true
} else if base.Flag.Race && t.NumComponents(types.CountBlankFields) > 1 {
// for composite objects we have to write every address
// because a write might happen to any subobject.
// composites with only one element don't have subobjects, though.
fn = racereadrange
if wr {
switch kind {
case instrumentRead:
fn = racereadrange
case instrumentWrite:
fn = racewriterange
default:
panic("unreachable")
}
needWidth = true
} else if base.Flag.Race {
// for non-composite objects we can write just the start
// address, as any write must write the first byte.
fn = raceread
if wr {
switch kind {
case instrumentRead:
fn = raceread
case instrumentWrite:
fn = racewrite
default:
panic("unreachable")
}
} else {
panic("unreachable")
}
args := []*ssa.Value{addr}
if addr2 != nil {
args = append(args, addr2)
}
if needWidth {
args = append(args, s.constInt(types.Types[types.TUINTPTR], w))
}
@ -1016,7 +1076,7 @@ func (s *state) instrument(t *types.Type, addr *ssa.Value, wr bool) {
}
func (s *state) load(t *types.Type, src *ssa.Value) *ssa.Value {
s.instrument(t, src, false)
s.instrumentFields(t, src, instrumentRead)
return s.rawLoad(t, src)
}
@ -1029,15 +1089,14 @@ func (s *state) store(t *types.Type, dst, val *ssa.Value) {
}
func (s *state) zero(t *types.Type, dst *ssa.Value) {
s.instrument(t, dst, true)
s.instrument(t, dst, instrumentWrite)
store := s.newValue2I(ssa.OpZero, types.TypeMem, t.Size(), dst, s.mem())
store.Aux = t
s.vars[memVar] = store
}
func (s *state) move(t *types.Type, dst, src *ssa.Value) {
s.instrument(t, src, false)
s.instrument(t, dst, true)
s.instrumentMove(t, dst, src)
store := s.newValue3I(ssa.OpMove, types.TypeMem, t.Size(), dst, src, s.mem())
store.Aux = t
s.vars[memVar] = store
@ -5263,7 +5322,7 @@ func (s *state) rtcall(fn *obj.LSym, returns bool, results []*types.Type, args .
// do *left = right for type t.
func (s *state) storeType(t *types.Type, left, right *ssa.Value, skip skipMask, leftIsStmt bool) {
s.instrument(t, left, true)
s.instrument(t, left, instrumentWrite)
if skip == 0 && (!t.HasPointers() || ssa.IsStackAddr(left)) {
// Known to not have write barrier. Store the whole type.

View File

@ -51,7 +51,7 @@ func want(t *testing.T, out string, desired string) {
func wantN(t *testing.T, out string, desired string, n int) {
if strings.Count(out, desired) != n {
t.Errorf("expected exactly %d occurences of %s in \n%s", n, desired, out)
t.Errorf("expected exactly %d occurrences of %s in \n%s", n, desired, out)
}
}

View File

@ -531,6 +531,7 @@
// fold ADDL into LEAL
(ADDLconst [c] (LEAL [d] {s} x)) && is32Bit(int64(c)+int64(d)) => (LEAL [c+d] {s} x)
(LEAL [c] {s} (ADDLconst [d] x)) && is32Bit(int64(c)+int64(d)) => (LEAL [c+d] {s} x)
(ADDLconst [c] x:(SP)) => (LEAL [c] x) // so it is rematerializeable
(LEAL [c] {s} (ADDL x y)) && x.Op != OpSB && y.Op != OpSB => (LEAL1 [c] {s} x y)
(ADDL x (LEAL [c] {s} y)) && x.Op != OpSB && y.Op != OpSB => (LEAL1 [c] {s} x y)

View File

@ -760,8 +760,8 @@
(MUL (MOVWconst [c]) (MOVWconst [d])) => (MOVWconst [c*d])
(MULA (MOVWconst [c]) (MOVWconst [d]) a) => (ADDconst [c*d] a)
(MULS (MOVWconst [c]) (MOVWconst [d]) a) => (SUBconst [c*d] a)
(Select0 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) => (MOVWconst [int32(uint32(c)/uint32(d))])
(Select1 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) => (MOVWconst [int32(uint32(c)%uint32(d))])
(Select0 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [int32(uint32(c)/uint32(d))])
(Select1 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [int32(uint32(c)%uint32(d))])
(ANDconst [c] (MOVWconst [d])) => (MOVWconst [c&d])
(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x)
(ORconst [c] (MOVWconst [d])) => (MOVWconst [c|d])

View File

@ -1372,14 +1372,14 @@
(MADDW a (MOVDconst [c]) (MOVDconst [d])) => (ADDconst [int64(int32(c)*int32(d))] a)
(MSUB a (MOVDconst [c]) (MOVDconst [d])) => (SUBconst [c*d] a)
(MSUBW a (MOVDconst [c]) (MOVDconst [d])) => (SUBconst [int64(int32(c)*int32(d))] a)
(DIV (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c/d])
(UDIV (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [int64(uint64(c)/uint64(d))])
(DIVW (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [int64(int32(c)/int32(d))])
(UDIVW (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [int64(uint32(c)/uint32(d))])
(MOD (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c%d])
(UMOD (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [int64(uint64(c)%uint64(d))])
(MODW (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [int64(int32(c)%int32(d))])
(UMODW (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [int64(uint32(c)%uint32(d))])
(DIV (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [c/d])
(UDIV (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint64(c)/uint64(d))])
(DIVW (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(int32(c)/int32(d))])
(UDIVW (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint32(c)/uint32(d))])
(MOD (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [c%d])
(UMOD (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint64(c)%uint64(d))])
(MODW (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(int32(c)%int32(d))])
(UMODW (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint32(c)%uint32(d))])
(ANDconst [c] (MOVDconst [d])) => (MOVDconst [c&d])
(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x)
(ANDconst [c] (MOVWUreg x)) => (ANDconst [c&(1<<32-1)] x)

View File

@ -626,10 +626,10 @@
(MUL (MOVWconst [c]) (MOVWconst [d])) => (MOVWconst [c*d])
(Select1 (MULTU (MOVWconst [c]) (MOVWconst [d]))) => (MOVWconst [int32(uint32(c)*uint32(d))])
(Select0 (MULTU (MOVWconst [c]) (MOVWconst [d]))) => (MOVWconst [int32((int64(uint32(c))*int64(uint32(d)))>>32)])
(Select1 (DIV (MOVWconst [c]) (MOVWconst [d]))) => (MOVWconst [c/d])
(Select1 (DIVU (MOVWconst [c]) (MOVWconst [d]))) => (MOVWconst [int32(uint32(c)/uint32(d))])
(Select0 (DIV (MOVWconst [c]) (MOVWconst [d]))) => (MOVWconst [c%d])
(Select0 (DIVU (MOVWconst [c]) (MOVWconst [d]))) => (MOVWconst [int32(uint32(c)%uint32(d))])
(Select1 (DIV (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [c/d])
(Select1 (DIVU (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [int32(uint32(c)/uint32(d))])
(Select0 (DIV (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [c%d])
(Select0 (DIVU (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [int32(uint32(c)%uint32(d))])
(ANDconst [c] (MOVWconst [d])) => (MOVWconst [c&d])
(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x)
(ORconst [c] (MOVWconst [d])) => (MOVWconst [c|d])

View File

@ -617,10 +617,10 @@
(SRLVconst [c] (MOVVconst [d])) => (MOVVconst [int64(uint64(d)>>uint64(c))])
(SRAVconst [c] (MOVVconst [d])) => (MOVVconst [d>>uint64(c)])
(Select1 (MULVU (MOVVconst [c]) (MOVVconst [d]))) => (MOVVconst [c*d])
(Select1 (DIVV (MOVVconst [c]) (MOVVconst [d]))) => (MOVVconst [c/d])
(Select1 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) => (MOVVconst [int64(uint64(c)/uint64(d))])
(Select0 (DIVV (MOVVconst [c]) (MOVVconst [d]))) => (MOVVconst [c%d]) // mod
(Select0 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) => (MOVVconst [int64(uint64(c)%uint64(d))]) // mod
(Select1 (DIVV (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [c/d])
(Select1 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [int64(uint64(c)/uint64(d))])
(Select0 (DIVV (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [c%d]) // mod
(Select0 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [int64(uint64(c)%uint64(d))]) // mod
(ANDconst [c] (MOVVconst [d])) => (MOVVconst [c&d])
(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x)
(ORconst [c] (MOVVconst [d])) => (MOVVconst [c|d])

View File

@ -845,6 +845,7 @@
(SUB x (MOVDconst [c])) && is32Bit(-c) => (ADDconst [-c] x)
(ADDconst [c] (MOVDaddr [d] {sym} x)) && is32Bit(c+int64(d)) => (MOVDaddr [int32(c+int64(d))] {sym} x)
(ADDconst [c] x:(SP)) && is32Bit(c) => (MOVDaddr [int32(c)] x) // so it is rematerializeable
(MULL(W|D) x (MOVDconst [c])) && is16Bit(c) => (MULL(W|D)const [int32(c)] x)

View File

@ -399,6 +399,7 @@
// folding offset into address
(I64AddConst [off] (LoweredAddr {sym} [off2] base)) && isU32Bit(off+int64(off2)) =>
(LoweredAddr {sym} [int32(off)+off2] base)
(I64AddConst [off] x:(SP)) && isU32Bit(off) => (LoweredAddr [int32(off)] x) // so it is rematerializeable
// transforming readonly globals into constants
(I64Load [off] (LoweredAddr {sym} [off2] (SB)) _) && symIsRO(sym) && isU32Bit(off+int64(off2)) => (I64Const [int64(read64(sym, off+int64(off2), config.ctxt.Arch.ByteOrder))])

View File

@ -1027,6 +1027,19 @@ func rewriteValue386_Op386ADDLconst(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ADDLconst [c] x:(SP))
// result: (LEAL [c] x)
for {
c := auxIntToInt32(v.AuxInt)
x := v_0
if x.Op != OpSP {
break
}
v.reset(Op386LEAL)
v.AuxInt = int32ToAuxInt(c)
v.AddArg(x)
return true
}
// match: (ADDLconst [c] (LEAL1 [d] {s} x y))
// cond: is32Bit(int64(c)+int64(d))
// result: (LEAL1 [c+d] {s} x y)

View File

@ -15599,6 +15599,7 @@ func rewriteValueARM_OpSelect0(v *Value) bool {
return true
}
// match: (Select0 (CALLudiv (MOVWconst [c]) (MOVWconst [d])))
// cond: d != 0
// result: (MOVWconst [int32(uint32(c)/uint32(d))])
for {
if v_0.Op != OpARMCALLudiv {
@ -15615,6 +15616,9 @@ func rewriteValueARM_OpSelect0(v *Value) bool {
break
}
d := auxIntToInt32(v_0_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpARMMOVWconst)
v.AuxInt = int32ToAuxInt(int32(uint32(c) / uint32(d)))
return true
@ -15661,6 +15665,7 @@ func rewriteValueARM_OpSelect1(v *Value) bool {
return true
}
// match: (Select1 (CALLudiv (MOVWconst [c]) (MOVWconst [d])))
// cond: d != 0
// result: (MOVWconst [int32(uint32(c)%uint32(d))])
for {
if v_0.Op != OpARMCALLudiv {
@ -15677,6 +15682,9 @@ func rewriteValueARM_OpSelect1(v *Value) bool {
break
}
d := auxIntToInt32(v_0_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpARMMOVWconst)
v.AuxInt = int32ToAuxInt(int32(uint32(c) % uint32(d)))
return true

View File

@ -3396,6 +3396,7 @@ func rewriteValueARM64_OpARM64DIV(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (DIV (MOVDconst [c]) (MOVDconst [d]))
// cond: d != 0
// result: (MOVDconst [c/d])
for {
if v_0.Op != OpARM64MOVDconst {
@ -3406,6 +3407,9 @@ func rewriteValueARM64_OpARM64DIV(v *Value) bool {
break
}
d := auxIntToInt64(v_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(c / d)
return true
@ -3416,6 +3420,7 @@ func rewriteValueARM64_OpARM64DIVW(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (DIVW (MOVDconst [c]) (MOVDconst [d]))
// cond: d != 0
// result: (MOVDconst [int64(int32(c)/int32(d))])
for {
if v_0.Op != OpARM64MOVDconst {
@ -3426,6 +3431,9 @@ func rewriteValueARM64_OpARM64DIVW(v *Value) bool {
break
}
d := auxIntToInt64(v_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(int32(c) / int32(d)))
return true
@ -6165,6 +6173,7 @@ func rewriteValueARM64_OpARM64MOD(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOD (MOVDconst [c]) (MOVDconst [d]))
// cond: d != 0
// result: (MOVDconst [c%d])
for {
if v_0.Op != OpARM64MOVDconst {
@ -6175,6 +6184,9 @@ func rewriteValueARM64_OpARM64MOD(v *Value) bool {
break
}
d := auxIntToInt64(v_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(c % d)
return true
@ -6185,6 +6197,7 @@ func rewriteValueARM64_OpARM64MODW(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MODW (MOVDconst [c]) (MOVDconst [d]))
// cond: d != 0
// result: (MOVDconst [int64(int32(c)%int32(d))])
for {
if v_0.Op != OpARM64MOVDconst {
@ -6195,6 +6208,9 @@ func rewriteValueARM64_OpARM64MODW(v *Value) bool {
break
}
d := auxIntToInt64(v_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(int32(c) % int32(d)))
return true
@ -20423,6 +20439,7 @@ func rewriteValueARM64_OpARM64UDIV(v *Value) bool {
return true
}
// match: (UDIV (MOVDconst [c]) (MOVDconst [d]))
// cond: d != 0
// result: (MOVDconst [int64(uint64(c)/uint64(d))])
for {
if v_0.Op != OpARM64MOVDconst {
@ -20433,6 +20450,9 @@ func rewriteValueARM64_OpARM64UDIV(v *Value) bool {
break
}
d := auxIntToInt64(v_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(uint64(c) / uint64(d)))
return true
@ -20475,6 +20495,7 @@ func rewriteValueARM64_OpARM64UDIVW(v *Value) bool {
return true
}
// match: (UDIVW (MOVDconst [c]) (MOVDconst [d]))
// cond: d != 0
// result: (MOVDconst [int64(uint32(c)/uint32(d))])
for {
if v_0.Op != OpARM64MOVDconst {
@ -20485,6 +20506,9 @@ func rewriteValueARM64_OpARM64UDIVW(v *Value) bool {
break
}
d := auxIntToInt64(v_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(uint32(c) / uint32(d)))
return true
@ -20539,6 +20563,7 @@ func rewriteValueARM64_OpARM64UMOD(v *Value) bool {
return true
}
// match: (UMOD (MOVDconst [c]) (MOVDconst [d]))
// cond: d != 0
// result: (MOVDconst [int64(uint64(c)%uint64(d))])
for {
if v_0.Op != OpARM64MOVDconst {
@ -20549,6 +20574,9 @@ func rewriteValueARM64_OpARM64UMOD(v *Value) bool {
break
}
d := auxIntToInt64(v_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(uint64(c) % uint64(d)))
return true
@ -20608,6 +20636,7 @@ func rewriteValueARM64_OpARM64UMODW(v *Value) bool {
return true
}
// match: (UMODW (MOVDconst [c]) (MOVDconst [d]))
// cond: d != 0
// result: (MOVDconst [int64(uint32(c)%uint32(d))])
for {
if v_0.Op != OpARM64MOVDconst {
@ -20618,6 +20647,9 @@ func rewriteValueARM64_OpARM64UMODW(v *Value) bool {
break
}
d := auxIntToInt64(v_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(uint32(c) % uint32(d)))
return true

View File

@ -6421,6 +6421,7 @@ func rewriteValueMIPS_OpSelect0(v *Value) bool {
break
}
// match: (Select0 (DIV (MOVWconst [c]) (MOVWconst [d])))
// cond: d != 0
// result: (MOVWconst [c%d])
for {
if v_0.Op != OpMIPSDIV {
@ -6437,11 +6438,15 @@ func rewriteValueMIPS_OpSelect0(v *Value) bool {
break
}
d := auxIntToInt32(v_0_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpMIPSMOVWconst)
v.AuxInt = int32ToAuxInt(c % d)
return true
}
// match: (Select0 (DIVU (MOVWconst [c]) (MOVWconst [d])))
// cond: d != 0
// result: (MOVWconst [int32(uint32(c)%uint32(d))])
for {
if v_0.Op != OpMIPSDIVU {
@ -6458,6 +6463,9 @@ func rewriteValueMIPS_OpSelect0(v *Value) bool {
break
}
d := auxIntToInt32(v_0_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpMIPSMOVWconst)
v.AuxInt = int32ToAuxInt(int32(uint32(c) % uint32(d)))
return true
@ -6609,6 +6617,7 @@ func rewriteValueMIPS_OpSelect1(v *Value) bool {
break
}
// match: (Select1 (DIV (MOVWconst [c]) (MOVWconst [d])))
// cond: d != 0
// result: (MOVWconst [c/d])
for {
if v_0.Op != OpMIPSDIV {
@ -6625,11 +6634,15 @@ func rewriteValueMIPS_OpSelect1(v *Value) bool {
break
}
d := auxIntToInt32(v_0_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpMIPSMOVWconst)
v.AuxInt = int32ToAuxInt(c / d)
return true
}
// match: (Select1 (DIVU (MOVWconst [c]) (MOVWconst [d])))
// cond: d != 0
// result: (MOVWconst [int32(uint32(c)/uint32(d))])
for {
if v_0.Op != OpMIPSDIVU {
@ -6646,6 +6659,9 @@ func rewriteValueMIPS_OpSelect1(v *Value) bool {
break
}
d := auxIntToInt32(v_0_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpMIPSMOVWconst)
v.AuxInt = int32ToAuxInt(int32(uint32(c) / uint32(d)))
return true

View File

@ -6887,6 +6887,7 @@ func rewriteValueMIPS64_OpSelect0(v *Value) bool {
return true
}
// match: (Select0 (DIVV (MOVVconst [c]) (MOVVconst [d])))
// cond: d != 0
// result: (MOVVconst [c%d])
for {
if v_0.Op != OpMIPS64DIVV {
@ -6903,11 +6904,15 @@ func rewriteValueMIPS64_OpSelect0(v *Value) bool {
break
}
d := auxIntToInt64(v_0_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpMIPS64MOVVconst)
v.AuxInt = int64ToAuxInt(c % d)
return true
}
// match: (Select0 (DIVVU (MOVVconst [c]) (MOVVconst [d])))
// cond: d != 0
// result: (MOVVconst [int64(uint64(c)%uint64(d))])
for {
if v_0.Op != OpMIPS64DIVVU {
@ -6924,6 +6929,9 @@ func rewriteValueMIPS64_OpSelect0(v *Value) bool {
break
}
d := auxIntToInt64(v_0_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpMIPS64MOVVconst)
v.AuxInt = int64ToAuxInt(int64(uint64(c) % uint64(d)))
return true
@ -7099,6 +7107,7 @@ func rewriteValueMIPS64_OpSelect1(v *Value) bool {
break
}
// match: (Select1 (DIVV (MOVVconst [c]) (MOVVconst [d])))
// cond: d != 0
// result: (MOVVconst [c/d])
for {
if v_0.Op != OpMIPS64DIVV {
@ -7115,11 +7124,15 @@ func rewriteValueMIPS64_OpSelect1(v *Value) bool {
break
}
d := auxIntToInt64(v_0_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpMIPS64MOVVconst)
v.AuxInt = int64ToAuxInt(c / d)
return true
}
// match: (Select1 (DIVVU (MOVVconst [c]) (MOVVconst [d])))
// cond: d != 0
// result: (MOVVconst [int64(uint64(c)/uint64(d))])
for {
if v_0.Op != OpMIPS64DIVVU {
@ -7136,6 +7149,9 @@ func rewriteValueMIPS64_OpSelect1(v *Value) bool {
break
}
d := auxIntToInt64(v_0_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpMIPS64MOVVconst)
v.AuxInt = int64ToAuxInt(int64(uint64(c) / uint64(d)))
return true

View File

@ -4195,6 +4195,20 @@ func rewriteValuePPC64_OpPPC64ADDconst(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ADDconst [c] x:(SP))
// cond: is32Bit(c)
// result: (MOVDaddr [int32(c)] x)
for {
c := auxIntToInt64(v.AuxInt)
x := v_0
if x.Op != OpSP || !(is32Bit(c)) {
break
}
v.reset(OpPPC64MOVDaddr)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
// match: (ADDconst [c] (SUBFCconst [d] x))
// cond: is32Bit(c+d)
// result: (SUBFCconst [c+d] x)

View File

@ -3693,6 +3693,20 @@ func rewriteValueWasm_OpWasmI64AddConst(v *Value) bool {
v.AddArg(base)
return true
}
// match: (I64AddConst [off] x:(SP))
// cond: isU32Bit(off)
// result: (LoweredAddr [int32(off)] x)
for {
off := auxIntToInt64(v.AuxInt)
x := v_0
if x.Op != OpSP || !(isU32Bit(off)) {
break
}
v.reset(OpWasmLoweredAddr)
v.AuxInt = int32ToAuxInt(int32(off))
v.AddArg(x)
return true
}
return false
}
func rewriteValueWasm_OpWasmI64And(v *Value) bool {

View File

@ -232,6 +232,12 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value, extend bool) {
}
case ssa.OpWasmLoweredAddr:
if v.Aux == nil { // address of off(SP), no symbol
getValue64(s, v.Args[0])
i64Const(s, v.AuxInt)
s.Prog(wasm.AI64Add)
break
}
p := s.Prog(wasm.AGet)
p.From.Type = obj.TYPE_ADDR
switch v.Aux.(type) {

View File

@ -12,7 +12,6 @@ import (
"go/parser"
"go/token"
"io"
"io/ioutil"
"log"
"os"
"sort"
@ -304,7 +303,7 @@ func (f *File) Visit(node ast.Node) ast.Visitor {
func annotate(name string) {
fset := token.NewFileSet()
content, err := ioutil.ReadFile(name)
content, err := os.ReadFile(name)
if err != nil {
log.Fatalf("cover: %s: %s", name, err)
}

View File

@ -13,7 +13,6 @@ import (
"go/parser"
"go/token"
"internal/testenv"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@ -81,7 +80,7 @@ var debug = flag.Bool("debug", false, "keep rewritten files for debugging")
// We use TestMain to set up a temporary directory and remove it when
// the tests are done.
func TestMain(m *testing.M) {
dir, err := ioutil.TempDir("", "go-testcover")
dir, err := os.MkdirTemp("", "go-testcover")
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
@ -173,7 +172,7 @@ func TestCover(t *testing.T) {
buildCover(t)
// Read in the test file (testTest) and write it, with LINEs specified, to coverInput.
file, err := ioutil.ReadFile(testTest)
file, err := os.ReadFile(testTest)
if err != nil {
t.Fatal(err)
}
@ -192,7 +191,7 @@ func TestCover(t *testing.T) {
[]byte("}"))
lines = append(lines, []byte("func unFormatted2(b bool) {if b{}else{}}"))
if err := ioutil.WriteFile(coverInput, bytes.Join(lines, []byte("\n")), 0666); err != nil {
if err := os.WriteFile(coverInput, bytes.Join(lines, []byte("\n")), 0666); err != nil {
t.Fatal(err)
}
@ -208,11 +207,11 @@ func TestCover(t *testing.T) {
// Copy testmain to testTempDir, so that it is in the same directory
// as coverOutput.
b, err := ioutil.ReadFile(testMain)
b, err := os.ReadFile(testMain)
if err != nil {
t.Fatal(err)
}
if err := ioutil.WriteFile(tmpTestMain, b, 0444); err != nil {
if err := os.WriteFile(tmpTestMain, b, 0444); err != nil {
t.Fatal(err)
}
@ -220,7 +219,7 @@ func TestCover(t *testing.T) {
cmd = exec.Command(testenv.GoToolPath(t), "run", tmpTestMain, coverOutput)
run(cmd, t)
file, err = ioutil.ReadFile(coverOutput)
file, err = os.ReadFile(coverOutput)
if err != nil {
t.Fatal(err)
}
@ -251,7 +250,7 @@ func TestDirectives(t *testing.T) {
// Read the source file and find all the directives. We'll keep
// track of whether each one has been seen in the output.
testDirectives := filepath.Join(testdata, "directives.go")
source, err := ioutil.ReadFile(testDirectives)
source, err := os.ReadFile(testDirectives)
if err != nil {
t.Fatal(err)
}
@ -398,7 +397,7 @@ func TestCoverHTML(t *testing.T) {
// Extract the parts of the HTML with comment markers,
// and compare against a golden file.
entireHTML, err := ioutil.ReadFile(htmlHTML)
entireHTML, err := os.ReadFile(htmlHTML)
if err != nil {
t.Fatal(err)
}
@ -420,7 +419,7 @@ func TestCoverHTML(t *testing.T) {
if scan.Err() != nil {
t.Error(scan.Err())
}
golden, err := ioutil.ReadFile(htmlGolden)
golden, err := os.ReadFile(htmlGolden)
if err != nil {
t.Fatalf("reading golden file: %v", err)
}
@ -457,7 +456,7 @@ func TestHtmlUnformatted(t *testing.T) {
t.Fatal(err)
}
if err := ioutil.WriteFile(filepath.Join(htmlUDir, "go.mod"), []byte("module htmlunformatted\n"), 0666); err != nil {
if err := os.WriteFile(filepath.Join(htmlUDir, "go.mod"), []byte("module htmlunformatted\n"), 0666); err != nil {
t.Fatal(err)
}
@ -474,10 +473,10 @@ lab:
const htmlUTestContents = `package htmlunformatted`
if err := ioutil.WriteFile(htmlU, []byte(htmlUContents), 0444); err != nil {
if err := os.WriteFile(htmlU, []byte(htmlUContents), 0444); err != nil {
t.Fatal(err)
}
if err := ioutil.WriteFile(htmlUTest, []byte(htmlUTestContents), 0444); err != nil {
if err := os.WriteFile(htmlUTest, []byte(htmlUTestContents), 0444); err != nil {
t.Fatal(err)
}
@ -540,13 +539,13 @@ func TestFuncWithDuplicateLines(t *testing.T) {
t.Fatal(err)
}
if err := ioutil.WriteFile(filepath.Join(lineDupDir, "go.mod"), []byte("module linedup\n"), 0666); err != nil {
if err := os.WriteFile(filepath.Join(lineDupDir, "go.mod"), []byte("module linedup\n"), 0666); err != nil {
t.Fatal(err)
}
if err := ioutil.WriteFile(lineDupGo, []byte(lineDupContents), 0444); err != nil {
if err := os.WriteFile(lineDupGo, []byte(lineDupContents), 0444); err != nil {
t.Fatal(err)
}
if err := ioutil.WriteFile(lineDupTestGo, []byte(lineDupTestContents), 0444); err != nil {
if err := os.WriteFile(lineDupTestGo, []byte(lineDupTestContents), 0444); err != nil {
t.Fatal(err)
}

View File

@ -11,7 +11,6 @@ import (
"fmt"
"html/template"
"io"
"io/ioutil"
"math"
"os"
"path/filepath"
@ -43,7 +42,7 @@ func htmlOutput(profile, outfile string) error {
if err != nil {
return err
}
src, err := ioutil.ReadFile(file)
src, err := os.ReadFile(file)
if err != nil {
return fmt.Errorf("can't read %q: %v", fn, err)
}
@ -62,7 +61,7 @@ func htmlOutput(profile, outfile string) error {
var out *os.File
if outfile == "" {
var dir string
dir, err = ioutil.TempDir("", "cover")
dir, err = os.MkdirTemp("", "cover")
if err != nil {
return err
}

View File

@ -15,7 +15,6 @@ import (
"go/token"
"io"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"sort"
@ -217,7 +216,7 @@ func processFile(filename string, useStdin bool) error {
return nil
}
return ioutil.WriteFile(f.Name(), newSrc, 0)
return os.WriteFile(f.Name(), newSrc, 0)
}
func gofmt(n interface{}) string {

View File

@ -9,7 +9,6 @@ import (
"go/ast"
"go/parser"
"go/token"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@ -162,12 +161,12 @@ func typecheck(cfg *TypeConfig, f *ast.File) (typeof map[interface{}]string, ass
if err != nil {
return err
}
dir, err := ioutil.TempDir(os.TempDir(), "fix_cgo_typecheck")
dir, err := os.MkdirTemp(os.TempDir(), "fix_cgo_typecheck")
if err != nil {
return err
}
defer os.RemoveAll(dir)
err = ioutil.WriteFile(filepath.Join(dir, "in.go"), txt, 0600)
err = os.WriteFile(filepath.Join(dir, "in.go"), txt, 0600)
if err != nil {
return err
}
@ -176,7 +175,7 @@ func typecheck(cfg *TypeConfig, f *ast.File) (typeof map[interface{}]string, ass
if err != nil {
return err
}
out, err := ioutil.ReadFile(filepath.Join(dir, "_cgo_gotypes.go"))
out, err := os.ReadFile(filepath.Join(dir, "_cgo_gotypes.go"))
if err != nil {
return err
}

View File

@ -3,11 +3,10 @@ module cmd
go 1.16
require (
github.com/google/pprof v0.0.0-20201007051231-1066cbb265c7
github.com/ianlancetaylor/demangle v0.0.0-20200414190113-039b1ae3a340 // indirect
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2
golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
golang.org/x/mod v0.4.0
golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65 // indirect
golang.org/x/tools v0.0.0-20201110201400-7099162a900a
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect
golang.org/x/tools v0.0.0-20201208211828-de58e7c01d49
)

View File

@ -1,11 +1,10 @@
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/google/pprof v0.0.0-20201007051231-1066cbb265c7 h1:qYWTuM6SUNWgtvkhV8oH6GFHCpU+rKQOxPcepM3xKi0=
github.com/google/pprof v0.0.0-20201007051231-1066cbb265c7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200414190113-039b1ae3a340 h1:S1+yTUaFPXuDZnPDbO+TrDFIjPzQraYH8/CwSlu9Fac=
github.com/ianlancetaylor/demangle v0.0.0-20200414190113-039b1ae3a340/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2 h1:HyOHhUtuB/Ruw/L5s5pG2D0kckkN2/IzBs9OClGHnHI=
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 h1:mV02weKRL81bEnm8A0HT1/CAelMQDBuQIfLw8n+d6xI=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff h1:XmKBi9R6duxOB3lfc72wyrwiOY7X2Jl1wuI+RFOyMDE=
golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
@ -26,14 +25,14 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65 h1:Qo9oJ566/Sq7N4hrGftVXs8GI2CXBCuOd4S2wHE/e0M=
golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 h1:KmZPnMocC93w341XZp26yTJg8Za7lhb2KhkYmixoeso=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20201110201400-7099162a900a h1:5E6TPwSBG74zT8xSrVc8W59K4ch4NFobVTnh2BYzHyU=
golang.org/x/tools v0.0.0-20201110201400-7099162a900a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208211828-de58e7c01d49 h1:K1QAOVIWIvmQ66F1Z3AEa9Wzp0bj+xU3YzLkvROk2Ds=
golang.org/x/tools v0.0.0-20201208211828-de58e7c01d49/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=

View File

@ -17,7 +17,6 @@ import (
"internal/testenv"
"io"
"io/fs"
"io/ioutil"
"log"
"os"
"os/exec"
@ -100,7 +99,7 @@ func TestMain(m *testing.M) {
// Run with a temporary TMPDIR to check that the tests don't
// leave anything behind.
topTmpdir, err := ioutil.TempDir("", "cmd-go-test-")
topTmpdir, err := os.MkdirTemp("", "cmd-go-test-")
if err != nil {
log.Fatal(err)
}
@ -109,7 +108,7 @@ func TestMain(m *testing.M) {
}
os.Setenv(tempEnvName(), topTmpdir)
dir, err := ioutil.TempDir(topTmpdir, "tmpdir")
dir, err := os.MkdirTemp(topTmpdir, "tmpdir")
if err != nil {
log.Fatal(err)
}
@ -616,7 +615,7 @@ func (tg *testgoData) makeTempdir() {
tg.t.Helper()
if tg.tempdir == "" {
var err error
tg.tempdir, err = ioutil.TempDir("", "gotest")
tg.tempdir, err = os.MkdirTemp("", "gotest")
tg.must(err)
}
}
@ -633,7 +632,7 @@ func (tg *testgoData) tempFile(path, contents string) {
bytes = formatted
}
}
tg.must(ioutil.WriteFile(filepath.Join(tg.tempdir, path), bytes, 0644))
tg.must(os.WriteFile(filepath.Join(tg.tempdir, path), bytes, 0644))
}
// tempDir adds a temporary directory for a run of testgo.
@ -833,7 +832,7 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) {
return err
}
dest := filepath.Join("goroot", copydir, srcrel)
data, err := ioutil.ReadFile(path)
data, err := os.ReadFile(path)
if err != nil {
return err
}
@ -850,18 +849,18 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) {
tg.setenv("GOROOT", tg.path("goroot"))
addVar := func(name string, idx int) (restore func()) {
data, err := ioutil.ReadFile(name)
data, err := os.ReadFile(name)
if err != nil {
t.Fatal(err)
}
old := data
data = append(data, fmt.Sprintf("var DummyUnusedVar%d bool\n", idx)...)
if err := ioutil.WriteFile(name, append(data, '\n'), 0666); err != nil {
if err := os.WriteFile(name, append(data, '\n'), 0666); err != nil {
t.Fatal(err)
}
tg.sleep()
return func() {
if err := ioutil.WriteFile(name, old, 0666); err != nil {
if err := os.WriteFile(name, old, 0666); err != nil {
t.Fatal(err)
}
}
@ -2674,7 +2673,7 @@ echo $* >>`+tg.path("pkg-config.out"))
tg.setenv("GOPATH", tg.path("."))
tg.setenv("PKG_CONFIG", tg.path("pkg-config.sh"))
tg.run("build", "x")
out, err := ioutil.ReadFile(tg.path("pkg-config.out"))
out, err := os.ReadFile(tg.path("pkg-config.out"))
tg.must(err)
out = bytes.TrimSpace(out)
want := "--cflags --static --static -- a a\n--libs --static --static -- a a"

View File

@ -5,7 +5,6 @@
package main_test
import (
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@ -20,14 +19,14 @@ func TestAbsolutePath(t *testing.T) {
defer tg.cleanup()
tg.parallel()
tmp, err := ioutil.TempDir("", "TestAbsolutePath")
tmp, err := os.MkdirTemp("", "TestAbsolutePath")
if err != nil {
t.Fatal(err)
}
defer robustio.RemoveAll(tmp)
file := filepath.Join(tmp, "a.go")
err = ioutil.WriteFile(file, []byte{}, 0644)
err = os.WriteFile(file, []byte{}, 0644)
if err != nil {
t.Fatal(err)
}

View File

@ -6,7 +6,7 @@ package main_test
import (
"bytes"
"io/ioutil"
"os"
"testing"
"cmd/go/internal/help"
@ -23,7 +23,7 @@ func TestDocsUpToDate(t *testing.T) {
buf := new(bytes.Buffer)
// Match the command in mkalldocs.sh that generates alldocs.go.
help.Help(buf, []string{"documentation"})
data, err := ioutil.ReadFile("alldocs.go")
data, err := os.ReadFile("alldocs.go")
if err != nil {
t.Fatalf("error reading alldocs.go: %v", err)
}

View File

@ -5,7 +5,6 @@
package auth
import (
"io/ioutil"
"os"
"path/filepath"
"runtime"
@ -99,7 +98,7 @@ func readNetrc() {
return
}
data, err := ioutil.ReadFile(path)
data, err := os.ReadFile(path)
if err != nil {
if !os.IsNotExist(err) {
netrcErr = err

View File

@ -10,7 +10,6 @@ import (
"context"
"fmt"
"io"
"io/ioutil"
urlpkg "net/url"
"os"
"os/exec"
@ -117,7 +116,7 @@ func printOSDetails(w io.Writer) {
case "illumos", "solaris":
// Be sure to use the OS-supplied uname, in "/usr/bin":
printCmdOut(w, "uname -srv: ", "/usr/bin/uname", "-srv")
out, err := ioutil.ReadFile("/etc/release")
out, err := os.ReadFile("/etc/release")
if err == nil {
fmt.Fprintf(w, "/etc/release: %s\n", out)
} else {
@ -177,7 +176,7 @@ func printGlibcVersion(w io.Writer) {
src := []byte(`int main() {}`)
srcfile := filepath.Join(tempdir, "go-bug.c")
outfile := filepath.Join(tempdir, "go-bug")
err := ioutil.WriteFile(srcfile, src, 0644)
err := os.WriteFile(srcfile, src, 0644)
if err != nil {
return
}

View File

@ -13,7 +13,6 @@ import (
"fmt"
"io"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"strconv"
@ -239,7 +238,7 @@ func (c *Cache) GetBytes(id ActionID) ([]byte, Entry, error) {
if err != nil {
return nil, entry, err
}
data, _ := ioutil.ReadFile(c.OutputFile(entry.OutputID))
data, _ := os.ReadFile(c.OutputFile(entry.OutputID))
if sha256.Sum256(data) != entry.OutputID {
return nil, entry, &entryNotFoundError{Err: errors.New("bad checksum")}
}
@ -378,7 +377,7 @@ func (c *Cache) putIndexEntry(id ActionID, out OutputID, size int64, allowVerify
// Truncate the file only *after* writing it.
// (This should be a no-op, but truncate just in case of previous corruption.)
//
// This differs from ioutil.WriteFile, which truncates to 0 *before* writing
// This differs from os.WriteFile, which truncates to 0 *before* writing
// via os.O_TRUNC. Truncating only after writing ensures that a second write
// of the same content to the same file is idempotent, and does not — even
// temporarily! — undo the effect of the first write.

View File

@ -8,7 +8,6 @@ import (
"bytes"
"encoding/binary"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
@ -20,7 +19,7 @@ func init() {
}
func TestBasic(t *testing.T) {
dir, err := ioutil.TempDir("", "cachetest-")
dir, err := os.MkdirTemp("", "cachetest-")
if err != nil {
t.Fatal(err)
}
@ -65,7 +64,7 @@ func TestBasic(t *testing.T) {
}
func TestGrowth(t *testing.T) {
dir, err := ioutil.TempDir("", "cachetest-")
dir, err := os.MkdirTemp("", "cachetest-")
if err != nil {
t.Fatal(err)
}
@ -118,7 +117,7 @@ func TestVerifyPanic(t *testing.T) {
t.Fatal("initEnv did not set verify")
}
dir, err := ioutil.TempDir("", "cachetest-")
dir, err := os.MkdirTemp("", "cachetest-")
if err != nil {
t.Fatal(err)
}
@ -151,7 +150,7 @@ func dummyID(x int) [HashSize]byte {
}
func TestCacheTrim(t *testing.T) {
dir, err := ioutil.TempDir("", "cachetest-")
dir, err := os.MkdirTemp("", "cachetest-")
if err != nil {
t.Fatal(err)
}
@ -207,7 +206,7 @@ func TestCacheTrim(t *testing.T) {
t.Fatal(err)
}
c.OutputFile(entry.OutputID)
data, err := ioutil.ReadFile(filepath.Join(dir, "trim.txt"))
data, err := os.ReadFile(filepath.Join(dir, "trim.txt"))
if err != nil {
t.Fatal(err)
}
@ -220,7 +219,7 @@ func TestCacheTrim(t *testing.T) {
t.Fatal(err)
}
c.OutputFile(entry.OutputID)
data2, err := ioutil.ReadFile(filepath.Join(dir, "trim.txt"))
data2, err := os.ReadFile(filepath.Join(dir, "trim.txt"))
if err != nil {
t.Fatal(err)
}

View File

@ -6,7 +6,6 @@ package cache
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sync"
@ -49,7 +48,7 @@ func initDefaultCache() {
}
if _, err := os.Stat(filepath.Join(dir, "README")); err != nil {
// Best effort.
ioutil.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666)
os.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666)
}
c, err := Open(dir)

View File

@ -6,7 +6,6 @@ package cache
import (
"fmt"
"io/ioutil"
"os"
"testing"
)
@ -28,7 +27,7 @@ func TestHash(t *testing.T) {
}
func TestHashFile(t *testing.T) {
f, err := ioutil.TempFile("", "cmd-go-test-")
f, err := os.CreateTemp("", "cmd-go-test-")
if err != nil {
t.Fatal(err)
}

View File

@ -12,7 +12,6 @@ import (
"go/build"
"internal/cfg"
"io"
"io/ioutil"
"os"
"path/filepath"
"runtime"
@ -187,7 +186,7 @@ func initEnvCache() {
if file == "" {
return
}
data, err := ioutil.ReadFile(file)
data, err := os.ReadFile(file)
if err != nil {
return
}

View File

@ -9,7 +9,6 @@ import (
"context"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"strconv"
@ -244,7 +243,7 @@ func clean(p *load.Package) {
base.Errorf("%v", p.Error)
return
}
dirs, err := ioutil.ReadDir(p.Dir)
dirs, err := os.ReadDir(p.Dir)
if err != nil {
base.Errorf("go clean %s: %v", p.Dir, err)
return

View File

@ -10,7 +10,6 @@ import (
"encoding/json"
"fmt"
"go/build"
"io/ioutil"
"os"
"path/filepath"
"runtime"
@ -452,7 +451,7 @@ func updateEnvFile(add map[string]string, del map[string]bool) {
if file == "" {
base.Fatalf("go env: cannot find go env config: %v", err)
}
data, err := ioutil.ReadFile(file)
data, err := os.ReadFile(file)
if err != nil && (!os.IsNotExist(err) || len(add) == 0) {
base.Fatalf("go env: reading go env config: %v", err)
}
@ -506,11 +505,11 @@ func updateEnvFile(add map[string]string, del map[string]bool) {
}
data = []byte(strings.Join(lines, ""))
err = ioutil.WriteFile(file, data, 0666)
err = os.WriteFile(file, data, 0666)
if err != nil {
// Try creating directory.
os.MkdirAll(filepath.Dir(file), 0777)
err = ioutil.WriteFile(file, data, 0666)
err = os.WriteFile(file, data, 0666)
if err != nil {
base.Fatalf("go env: writing go env config: %v", err)
}

View File

@ -86,7 +86,7 @@ func Init(wd string) error {
return nil
}
b, err := ioutil.ReadFile(OverlayFile)
b, err := os.ReadFile(OverlayFile)
if err != nil {
return fmt.Errorf("reading overlay file: %v", err)
}

View File

@ -8,7 +8,6 @@ import (
"internal/testenv"
"io"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"reflect"
@ -47,7 +46,7 @@ func initOverlay(t *testing.T, config string) {
if err := os.MkdirAll(filepath.Dir(name), 0777); err != nil {
t.Fatal(err)
}
if err := ioutil.WriteFile(name, f.Data, 0666); err != nil {
if err := os.WriteFile(name, f.Data, 0666); err != nil {
t.Fatal(err)
}
}

View File

@ -13,7 +13,6 @@ import (
"go/parser"
"go/token"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
@ -201,7 +200,7 @@ func runGenerate(ctx context.Context, cmd *base.Command, args []string) {
// generate runs the generation directives for a single file.
func generate(absFile string) bool {
src, err := ioutil.ReadFile(absFile)
src, err := os.ReadFile(absFile)
if err != nil {
log.Fatalf("generate: %s", err)
}

View File

@ -7,7 +7,7 @@ package imports
import (
"bytes"
"internal/testenv"
"io/ioutil"
"os"
"path"
"path/filepath"
"runtime"
@ -57,7 +57,7 @@ func TestScan(t *testing.T) {
func TestScanDir(t *testing.T) {
testenv.MustHaveGoBuild(t)
dirs, err := ioutil.ReadDir("testdata")
dirs, err := os.ReadDir("testdata")
if err != nil {
t.Fatal(err)
}
@ -66,7 +66,7 @@ func TestScanDir(t *testing.T) {
continue
}
t.Run(dir.Name(), func(t *testing.T) {
tagsData, err := ioutil.ReadFile(filepath.Join("testdata", dir.Name(), "tags.txt"))
tagsData, err := os.ReadFile(filepath.Join("testdata", dir.Name(), "tags.txt"))
if err != nil {
t.Fatalf("error reading tags: %v", err)
}
@ -75,7 +75,7 @@ func TestScanDir(t *testing.T) {
tags[t] = true
}
wantData, err := ioutil.ReadFile(filepath.Join("testdata", dir.Name(), "want.txt"))
wantData, err := os.ReadFile(filepath.Join("testdata", dir.Name(), "want.txt"))
if err != nil {
t.Fatalf("error reading want: %v", err)
}

View File

@ -15,7 +15,6 @@ import (
"go/scanner"
"go/token"
"io/fs"
"io/ioutil"
"os"
"path"
pathpkg "path"
@ -1147,7 +1146,7 @@ var (
// goModPath returns the module path in the go.mod in dir, if any.
func goModPath(dir string) (path string) {
return goModPathCache.Do(dir, func() interface{} {
data, err := ioutil.ReadFile(filepath.Join(dir, "go.mod"))
data, err := os.ReadFile(filepath.Join(dir, "go.mod"))
if err != nil {
return ""
}
@ -1296,9 +1295,9 @@ HaveGoMod:
// Otherwise it is not possible to vendor just a/b/c and still import the
// non-vendored a/b. See golang.org/issue/13832.
func hasGoFiles(dir string) bool {
fis, _ := ioutil.ReadDir(dir)
for _, fi := range fis {
if !fi.IsDir() && strings.HasSuffix(fi.Name(), ".go") {
files, _ := os.ReadDir(dir)
for _, f := range files {
if !f.IsDir() && strings.HasSuffix(f.Name(), ".go") {
return true
}
}
@ -1728,7 +1727,7 @@ func (p *Package) load(ctx context.Context, path string, stk *ImportStack, impor
// not work for any package that lacks a Target — such as a non-main
// package in module mode. We should probably fix that.
shlibnamefile := p.Target[:len(p.Target)-2] + ".shlibname"
shlib, err := ioutil.ReadFile(shlibnamefile)
shlib, err := os.ReadFile(shlibnamefile)
if err != nil && !os.IsNotExist(err) {
base.Fatalf("reading shlibname: %v", err)
}
@ -1998,6 +1997,16 @@ func (p *Package) resolveEmbed(patterns []string) (files []string, pmap map[stri
return err
}
rel := filepath.ToSlash(path[len(p.Dir)+1:])
name := info.Name()
if path != file && (isBadEmbedName(name) || name[0] == '.' || name[0] == '_') {
// Ignore bad names, assuming they won't go into modules.
// Also avoid hidden files that user may not know about.
// See golang.org/issue/42328.
if info.IsDir() {
return fs.SkipDir
}
return nil
}
if info.IsDir() {
if _, err := fsys.Stat(filepath.Join(path, "go.mod")); err == nil {
return filepath.SkipDir
@ -2007,10 +2016,6 @@ func (p *Package) resolveEmbed(patterns []string) (files []string, pmap map[stri
if !info.Mode().IsRegular() {
return nil
}
if isBadEmbedName(info.Name()) {
// Ignore bad names, assuming they won't go into modules.
return nil
}
count++
if have[rel] != pid {
have[rel] = pid
@ -2050,6 +2055,9 @@ func validEmbedPattern(pattern string) bool {
// as existing for embedding.
func isBadEmbedName(name string) bool {
switch name {
// Empty string should be impossible but make it bad.
case "":
return true
// Version control directories won't be present in module.
case ".bzr", ".hg", ".git", ".svn":
return true

View File

@ -9,7 +9,6 @@ package filelock_test
import (
"fmt"
"internal/testenv"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@ -51,9 +50,9 @@ func mustTempFile(t *testing.T) (f *os.File, remove func()) {
t.Helper()
base := filepath.Base(t.Name())
f, err := ioutil.TempFile("", base)
f, err := os.CreateTemp("", base)
if err != nil {
t.Fatalf(`ioutil.TempFile("", %q) = %v`, base, err)
t.Fatalf(`os.CreateTemp("", %q) = %v`, base, err)
}
t.Logf("fd %d = %s", f.Fd(), f.Name())

View File

@ -10,7 +10,6 @@ package lockedfile_test
import (
"fmt"
"internal/testenv"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@ -23,7 +22,7 @@ import (
func mustTempDir(t *testing.T) (dir string, remove func()) {
t.Helper()
dir, err := ioutil.TempDir("", filepath.Base(t.Name()))
dir, err := os.MkdirTemp("", filepath.Base(t.Name()))
if err != nil {
t.Fatal(err)
}
@ -155,8 +154,8 @@ func TestCanLockExistingFile(t *testing.T) {
defer remove()
path := filepath.Join(dir, "existing.txt")
if err := ioutil.WriteFile(path, []byte("ok"), 0777); err != nil {
t.Fatalf("ioutil.WriteFile: %v", err)
if err := os.WriteFile(path, []byte("ok"), 0777); err != nil {
t.Fatalf("os.WriteFile: %v", err)
}
f, err := lockedfile.Edit(path)
@ -201,7 +200,7 @@ func TestSpuriousEDEADLK(t *testing.T) {
}
defer b.Close()
if err := ioutil.WriteFile(filepath.Join(dir, "locked"), []byte("ok"), 0666); err != nil {
if err := os.WriteFile(filepath.Join(dir, "locked"), []byte("ok"), 0666); err != nil {
t.Fatal(err)
}

View File

@ -10,7 +10,6 @@ import (
"fmt"
"io"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"sort"
@ -155,7 +154,7 @@ func runVendor(ctx context.Context, cmd *base.Command, args []string) {
base.Fatalf("go mod vendor: %v", err)
}
if err := ioutil.WriteFile(filepath.Join(vdir, "modules.txt"), buf.Bytes(), 0666); err != nil {
if err := os.WriteFile(filepath.Join(vdir, "modules.txt"), buf.Bytes(), 0666); err != nil {
base.Fatalf("go mod vendor: %v", err)
}
}
@ -244,7 +243,7 @@ var metaPrefixes = []string{
}
// matchMetadata reports whether info is a metadata file.
func matchMetadata(dir string, info fs.FileInfo) bool {
func matchMetadata(dir string, info fs.DirEntry) bool {
name := info.Name()
for _, p := range metaPrefixes {
if strings.HasPrefix(name, p) {
@ -255,7 +254,7 @@ func matchMetadata(dir string, info fs.FileInfo) bool {
}
// matchPotentialSourceFile reports whether info may be relevant to a build operation.
func matchPotentialSourceFile(dir string, info fs.FileInfo) bool {
func matchPotentialSourceFile(dir string, info fs.DirEntry) bool {
if strings.HasSuffix(info.Name(), "_test.go") {
return false
}
@ -281,8 +280,8 @@ func matchPotentialSourceFile(dir string, info fs.FileInfo) bool {
}
// copyDir copies all regular files satisfying match(info) from src to dst.
func copyDir(dst, src string, match func(dir string, info fs.FileInfo) bool) {
files, err := ioutil.ReadDir(src)
func copyDir(dst, src string, match func(dir string, info fs.DirEntry) bool) {
files, err := os.ReadDir(src)
if err != nil {
base.Fatalf("go mod vendor: %v", err)
}
@ -290,7 +289,7 @@ func copyDir(dst, src string, match func(dir string, info fs.FileInfo) bool) {
base.Fatalf("go mod vendor: %v", err)
}
for _, file := range files {
if file.IsDir() || !file.Mode().IsRegular() || !match(src, file) {
if file.IsDir() || !file.Type().IsRegular() || !match(src, file) {
continue
}
r, err := os.Open(filepath.Join(src, file.Name()))

View File

@ -10,7 +10,6 @@ import (
"errors"
"fmt"
"io/fs"
"io/ioutil"
"os"
"runtime"
@ -87,7 +86,7 @@ func verifyMod(mod module.Version) []error {
_, zipErr = os.Stat(zip)
}
dir, dirErr := modfetch.DownloadDir(mod)
data, err := ioutil.ReadFile(zip + "hash")
data, err := os.ReadFile(zip + "hash")
if err != nil {
if zipErr != nil && errors.Is(zipErr, fs.ErrNotExist) &&
dirErr != nil && errors.Is(dirErr, fs.ErrNotExist) {

View File

@ -9,7 +9,6 @@ import (
"context"
"fmt"
"internal/testenv"
"io/ioutil"
"log"
"os"
"os/exec"
@ -37,7 +36,7 @@ func testMain(m *testing.M) int {
return 0
}
dir, err := ioutil.TempDir("", "modconv-test-")
dir, err := os.MkdirTemp("", "modconv-test-")
if err != nil {
log.Fatal(err)
}
@ -167,7 +166,7 @@ func TestConvertLegacyConfig(t *testing.T) {
for name := range Converters {
file := filepath.Join(dir, name)
data, err := ioutil.ReadFile(file)
data, err := os.ReadFile(file)
if err == nil {
f := new(modfile.File)
f.AddModuleStmt(tt.path)

View File

@ -7,7 +7,7 @@ package modconv
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
)
@ -42,7 +42,7 @@ func Test(t *testing.T) {
if Converters[extMap[ext]] == nil {
t.Fatalf("Converters[%q] == nil", extMap[ext])
}
data, err := ioutil.ReadFile(test)
data, err := os.ReadFile(test)
if err != nil {
t.Fatal(err)
}
@ -50,7 +50,7 @@ func Test(t *testing.T) {
if err != nil {
t.Fatal(err)
}
want, err := ioutil.ReadFile(test[:len(test)-len(ext)] + ".out")
want, err := os.ReadFile(test[:len(test)-len(ext)] + ".out")
if err != nil {
t.Error(err)
}

View File

@ -11,7 +11,6 @@ import (
"fmt"
"io"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"strings"
@ -598,7 +597,7 @@ func rewriteVersionList(dir string) {
}
defer unlock()
infos, err := ioutil.ReadDir(dir)
infos, err := os.ReadDir(dir)
if err != nil {
return
}

View File

@ -5,14 +5,13 @@
package modfetch
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
)
func TestWriteDiskCache(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "go-writeCache-test-")
tmpdir, err := os.MkdirTemp("", "go-writeCache-test-")
if err != nil {
t.Fatal(err)
}

View File

@ -12,7 +12,6 @@ import (
"fmt"
"io"
"io/fs"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@ -189,7 +188,7 @@ func WorkDir(typ, name string) (dir, lockfile string, err error) {
}
defer unlock()
data, err := ioutil.ReadFile(dir + ".info")
data, err := os.ReadFile(dir + ".info")
info, err2 := os.Stat(dir)
if err == nil && err2 == nil && info.IsDir() {
// Info file and directory both already exist: reuse.
@ -211,7 +210,7 @@ func WorkDir(typ, name string) (dir, lockfile string, err error) {
if err := os.MkdirAll(dir, 0777); err != nil {
return "", "", err
}
if err := ioutil.WriteFile(dir+".info", []byte(key), 0666); err != nil {
if err := os.WriteFile(dir+".info", []byte(key), 0666); err != nil {
os.RemoveAll(dir)
return "", "", err
}

View File

@ -12,7 +12,6 @@ import (
"internal/testenv"
"io"
"io/fs"
"io/ioutil"
"log"
"os"
"os/exec"
@ -54,7 +53,7 @@ func testMain(m *testing.M) int {
return 0
}
dir, err := ioutil.TempDir("", "gitrepo-test-")
dir, err := os.MkdirTemp("", "gitrepo-test-")
if err != nil {
log.Fatal(err)
}

View File

@ -15,7 +15,6 @@ import (
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"strings"
@ -124,7 +123,7 @@ func main() {
}
if f[3] != "-" {
if err := ioutil.WriteFile(f[3], data, 0666); err != nil {
if err := os.WriteFile(f[3], data, 0666); err != nil {
fmt.Fprintf(os.Stderr, "?%s\n", err)
continue
}

View File

@ -10,7 +10,6 @@ import (
"internal/lazyregexp"
"io"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"sort"
@ -433,7 +432,7 @@ func (r *vcsRepo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser,
if rev == "latest" {
rev = r.cmd.latest
}
f, err := ioutil.TempFile("", "go-readzip-*.zip")
f, err := os.CreateTemp("", "go-readzip-*.zip")
if err != nil {
return nil, err
}

View File

@ -11,7 +11,6 @@ import (
"fmt"
"io"
"io/fs"
"io/ioutil"
"os"
"path"
"sort"
@ -966,7 +965,7 @@ func (r *codeRepo) Zip(dst io.Writer, version string) error {
subdir = strings.Trim(subdir, "/")
// Spool to local file.
f, err := ioutil.TempFile("", "go-codehost-")
f, err := os.CreateTemp("", "go-codehost-")
if err != nil {
dl.Close()
return err

View File

@ -11,7 +11,6 @@ import (
"hash"
"internal/testenv"
"io"
"io/ioutil"
"log"
"os"
"reflect"
@ -38,7 +37,7 @@ func testMain(m *testing.M) int {
// code, bypass the sum database.
cfg.GOSUMDB = "off"
dir, err := ioutil.TempDir("", "gitrepo-test-")
dir, err := os.MkdirTemp("", "gitrepo-test-")
if err != nil {
log.Fatal(err)
}
@ -424,7 +423,7 @@ var codeRepoTests = []codeRepoTest{
func TestCodeRepo(t *testing.T) {
testenv.MustHaveExternalNetwork(t)
tmpdir, err := ioutil.TempDir("", "modfetch-test-")
tmpdir, err := os.MkdirTemp("", "modfetch-test-")
if err != nil {
t.Fatal(err)
}
@ -491,9 +490,9 @@ func TestCodeRepo(t *testing.T) {
needHash := !testing.Short() && (tt.zipFileHash != "" || tt.zipSum != "")
if tt.zip != nil || tt.zipErr != "" || needHash {
f, err := ioutil.TempFile(tmpdir, tt.version+".zip.")
f, err := os.CreateTemp(tmpdir, tt.version+".zip.")
if err != nil {
t.Fatalf("ioutil.TempFile: %v", err)
t.Fatalf("os.CreateTemp: %v", err)
}
zipfile := f.Name()
defer func() {
@ -655,7 +654,7 @@ var codeRepoVersionsTests = []struct {
func TestCodeRepoVersions(t *testing.T) {
testenv.MustHaveExternalNetwork(t)
tmpdir, err := ioutil.TempDir("", "vgo-modfetch-test-")
tmpdir, err := os.MkdirTemp("", "vgo-modfetch-test-")
if err != nil {
t.Fatal(err)
}
@ -729,7 +728,7 @@ var latestTests = []struct {
func TestLatest(t *testing.T) {
testenv.MustHaveExternalNetwork(t)
tmpdir, err := ioutil.TempDir("", "vgo-modfetch-test-")
tmpdir, err := os.MkdirTemp("", "vgo-modfetch-test-")
if err != nil {
t.Fatal(err)
}

View File

@ -12,7 +12,6 @@ import (
"fmt"
"io"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"sort"
@ -136,7 +135,7 @@ func download(ctx context.Context, mod module.Version) (dir string, err error) {
if err := os.MkdirAll(parentDir, 0777); err != nil {
return "", err
}
if err := ioutil.WriteFile(partialPath, nil, 0666); err != nil {
if err := os.WriteFile(partialPath, nil, 0666); err != nil {
return "", err
}
if err := modzip.Unzip(dir, mod, zipfile); err != nil {
@ -223,7 +222,7 @@ func downloadZip(ctx context.Context, mod module.Version, zipfile string) (err e
// contents of the file (by hashing it) before we commit it. Because the file
// is zip-compressed, we need an actual file — or at least an io.ReaderAt — to
// validate it: we can't just tee the stream as we write it.
f, err := ioutil.TempFile(filepath.Dir(zipfile), filepath.Base(renameio.Pattern(zipfile)))
f, err := os.CreateTemp(filepath.Dir(zipfile), filepath.Base(renameio.Pattern(zipfile)))
if err != nil {
return err
}

View File

@ -24,7 +24,6 @@ import (
"fmt"
"internal/testenv"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
@ -81,7 +80,7 @@ func TestZipSums(t *testing.T) {
if *modCacheDir != "" {
cfg.BuildContext.GOPATH = *modCacheDir
} else {
tmpDir, err := ioutil.TempDir("", "TestZipSums")
tmpDir, err := os.MkdirTemp("", "TestZipSums")
if err != nil {
t.Fatal(err)
}

View File

@ -12,7 +12,6 @@ import (
"fmt"
"go/build"
"internal/lazyregexp"
"io/ioutil"
"os"
"path"
"path/filepath"
@ -445,13 +444,13 @@ func CreateModFile(ctx context.Context, modPath string) {
// this is an existing project. Walking the tree for packages would be more
// accurate, but could take much longer.
empty := true
fis, _ := ioutil.ReadDir(modRoot)
for _, fi := range fis {
name := fi.Name()
files, _ := os.ReadDir(modRoot)
for _, f := range files {
name := f.Name()
if strings.HasPrefix(name, ".") || strings.HasPrefix(name, "_") {
continue
}
if strings.HasSuffix(name, ".go") || fi.IsDir() {
if strings.HasSuffix(name, ".go") || f.IsDir() {
empty = false
break
}
@ -632,7 +631,7 @@ func setDefaultBuildMod() {
func convertLegacyConfig(modPath string) (from string, err error) {
for _, name := range altConfigs {
cfg := filepath.Join(modRoot, name)
data, err := ioutil.ReadFile(cfg)
data, err := os.ReadFile(cfg)
if err == nil {
convert := modconv.Converters[name]
if convert == nil {
@ -731,9 +730,9 @@ func findModulePath(dir string) (string, error) {
// Cast about for import comments,
// first in top-level directory, then in subdirectories.
list, _ := ioutil.ReadDir(dir)
list, _ := os.ReadDir(dir)
for _, info := range list {
if info.Mode().IsRegular() && strings.HasSuffix(info.Name(), ".go") {
if info.Type().IsRegular() && strings.HasSuffix(info.Name(), ".go") {
if com := findImportComment(filepath.Join(dir, info.Name())); com != "" {
return com, nil
}
@ -741,9 +740,9 @@ func findModulePath(dir string) (string, error) {
}
for _, info1 := range list {
if info1.IsDir() {
files, _ := ioutil.ReadDir(filepath.Join(dir, info1.Name()))
files, _ := os.ReadDir(filepath.Join(dir, info1.Name()))
for _, info2 := range files {
if info2.Mode().IsRegular() && strings.HasSuffix(info2.Name(), ".go") {
if info2.Type().IsRegular() && strings.HasSuffix(info2.Name(), ".go") {
if com := findImportComment(filepath.Join(dir, info1.Name(), info2.Name())); com != "" {
return path.Dir(com), nil
}
@ -753,7 +752,7 @@ func findModulePath(dir string) (string, error) {
}
// Look for Godeps.json declaring import path.
data, _ := ioutil.ReadFile(filepath.Join(dir, "Godeps/Godeps.json"))
data, _ := os.ReadFile(filepath.Join(dir, "Godeps/Godeps.json"))
var cfg1 struct{ ImportPath string }
json.Unmarshal(data, &cfg1)
if cfg1.ImportPath != "" {
@ -761,7 +760,7 @@ func findModulePath(dir string) (string, error) {
}
// Look for vendor.json declaring import path.
data, _ = ioutil.ReadFile(filepath.Join(dir, "vendor/vendor.json"))
data, _ = os.ReadFile(filepath.Join(dir, "vendor/vendor.json"))
var cfg2 struct{ RootPath string }
json.Unmarshal(data, &cfg2)
if cfg2.RootPath != "" {
@ -813,7 +812,7 @@ var (
)
func findImportComment(file string) string {
data, err := ioutil.ReadFile(file)
data, err := os.ReadFile(file)
if err != nil {
return ""
}

View File

@ -61,8 +61,8 @@ package modload
// Similarly, if the LoadTests flag is set but the "all" pattern does not close
// over test dependencies, then when we load the test of a package that is in
// "all" but outside the main module, the dependencies of that test will not
// necessarily themselves be in "all". That configuration does not arise in Go
// 1.111.15, but it will be possible with lazy loading in Go 1.16+.
// necessarily themselves be in "all". (That configuration does not arise in Go
// 1.111.15, but it will be possible in Go 1.16+.)
//
// Loading proceeds from the roots, using a parallel work-queue with a limit on
// the amount of active work (to avoid saturating disks, CPU cores, and/or
@ -158,8 +158,8 @@ type PackageOpts struct {
// UseVendorAll causes the "all" package pattern to be interpreted as if
// running "go mod vendor" (or building with "-mod=vendor").
//
// Once lazy loading is implemented, this will be a no-op for modules that
// declare 'go 1.16' or higher.
// This is a no-op for modules that declare 'go 1.16' or higher, for which this
// is the default (and only) interpretation of the "all" pattern in module mode.
UseVendorAll bool
// AllowErrors indicates that LoadPackages should not terminate the process if

View File

@ -25,10 +25,11 @@ import (
"golang.org/x/mod/semver"
)
// lazyLoadingVersion is the Go version (plus leading "v") at which lazy module
// loading takes effect.
const lazyLoadingVersionV = "v1.16"
const go116EnableLazyLoading = true
// narrowAllVersionV is the Go version (plus leading "v") at which the
// module-module "all" pattern no longer closes over the dependencies of
// tests outside of the main module.
const narrowAllVersionV = "v1.16"
const go116EnableNarrowAll = true
var modFile *modfile.File
@ -296,10 +297,10 @@ func indexModFile(data []byte, modFile *modfile.File, needsFix bool) *modFileInd
// (Otherwise — as in Go 1.16+ — the "all" pattern includes only the packages
// transitively *imported by* the packages and tests in the main module.)
func (i *modFileIndex) allPatternClosesOverTests() bool {
if !go116EnableLazyLoading {
if !go116EnableNarrowAll {
return true
}
if i != nil && semver.Compare(i.goVersionV, lazyLoadingVersionV) < 0 {
if i != nil && semver.Compare(i.goVersionV, narrowAllVersionV) < 0 {
// The module explicitly predates the change in "all" for lazy loading, so
// continue to use the older interpretation. (If i == nil, we not in any
// module at all and should use the latest semantics.)

View File

@ -7,7 +7,6 @@ package modload
import (
"context"
"internal/testenv"
"io/ioutil"
"log"
"os"
"path"
@ -27,7 +26,7 @@ func TestMain(m *testing.M) {
func testMain(m *testing.M) int {
cfg.GOPROXY = "direct"
dir, err := ioutil.TempDir("", "modload-test-")
dir, err := os.MkdirTemp("", "modload-test-")
if err != nil {
log.Fatal(err)
}

View File

@ -8,7 +8,7 @@ import (
"errors"
"fmt"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"strings"
"sync"
@ -40,7 +40,7 @@ func readVendorList() {
vendorPkgModule = make(map[string]module.Version)
vendorVersion = make(map[string]string)
vendorMeta = make(map[module.Version]vendorMetadata)
data, err := ioutil.ReadFile(filepath.Join(ModRoot(), "vendor/modules.txt"))
data, err := os.ReadFile(filepath.Join(ModRoot(), "vendor/modules.txt"))
if err != nil {
if !errors.Is(err, fs.ErrNotExist) {
base.Fatalf("go: %s", err)

View File

@ -25,7 +25,7 @@ func Pattern(filename string) string {
return filepath.Join(filepath.Dir(filename), filepath.Base(filename)+patternSuffix)
}
// WriteFile is like ioutil.WriteFile, but first writes data to an arbitrary
// WriteFile is like os.WriteFile, but first writes data to an arbitrary
// file in the same directory as filename, then renames it atomically to the
// final name.
//
@ -67,7 +67,7 @@ func WriteToFile(filename string, data io.Reader, perm fs.FileMode) (err error)
return robustio.Rename(f.Name(), filename)
}
// ReadFile is like ioutil.ReadFile, but on Windows retries spurious errors that
// ReadFile is like os.ReadFile, but on Windows retries spurious errors that
// may occur if the file is concurrently replaced.
//
// Errors are classified heuristically and retries are bounded, so even this

View File

@ -10,7 +10,6 @@ import (
"encoding/binary"
"errors"
"internal/testenv"
"io/ioutil"
"math/rand"
"os"
"path/filepath"
@ -30,7 +29,7 @@ func TestConcurrentReadsAndWrites(t *testing.T) {
testenv.SkipFlaky(t, 33041)
}
dir, err := ioutil.TempDir("", "renameio")
dir, err := os.MkdirTemp("", "renameio")
if err != nil {
t.Fatal(err)
}

View File

@ -8,7 +8,6 @@ package renameio
import (
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"syscall"
@ -16,7 +15,7 @@ import (
)
func TestWriteFileModeAppliesUmask(t *testing.T) {
dir, err := ioutil.TempDir("", "renameio")
dir, err := os.MkdirTemp("", "renameio")
if err != nil {
t.Fatalf("Failed to create temporary directory: %v", err)
}

View File

@ -22,7 +22,7 @@ func Rename(oldpath, newpath string) error {
return rename(oldpath, newpath)
}
// ReadFile is like ioutil.ReadFile, but on Windows retries errors that may
// ReadFile is like os.ReadFile, but on Windows retries errors that may
// occur if the file is concurrently replaced.
//
// (See golang.org/issue/31247 and golang.org/issue/32188.)

View File

@ -8,7 +8,6 @@ package robustio
import (
"errors"
"io/ioutil"
"math/rand"
"os"
"syscall"
@ -70,11 +69,11 @@ func rename(oldpath, newpath string) (err error) {
})
}
// readFile is like ioutil.ReadFile, but retries ephemeral errors.
// readFile is like os.ReadFile, but retries ephemeral errors.
func readFile(filename string) ([]byte, error) {
var b []byte
err := retry(func() (err error, mayRetry bool) {
b, err = ioutil.ReadFile(filename)
b, err = os.ReadFile(filename)
// Unlike in rename, we do not retry errFileNotFound here: it can occur
// as a spurious error, but the file may also genuinely not exist, so the

View File

@ -7,7 +7,6 @@
package robustio
import (
"io/ioutil"
"os"
)
@ -16,7 +15,7 @@ func rename(oldpath, newpath string) error {
}
func readFile(filename string) ([]byte, error) {
return ioutil.ReadFile(filename)
return os.ReadFile(filename)
}
func removeAll(path string) error {

View File

@ -13,7 +13,6 @@ import (
"go/build"
"io"
"io/fs"
"io/ioutil"
"os"
"os/exec"
"path"
@ -884,7 +883,7 @@ func builderTest(b *work.Builder, ctx context.Context, p *load.Package) (buildAc
if !cfg.BuildN {
// writeTestmain writes _testmain.go,
// using the test description gathered in t.
if err := ioutil.WriteFile(testDir+"_testmain.go", *pmain.Internal.TestmainGo, 0666); err != nil {
if err := os.WriteFile(testDir+"_testmain.go", *pmain.Internal.TestmainGo, 0666); err != nil {
return nil, nil, nil, err
}
}
@ -1561,13 +1560,18 @@ func hashOpen(name string) (cache.ActionID, error) {
}
hashWriteStat(h, info)
if info.IsDir() {
names, err := ioutil.ReadDir(name)
files, err := os.ReadDir(name)
if err != nil {
fmt.Fprintf(h, "err %v\n", err)
}
for _, f := range names {
for _, f := range files {
fmt.Fprintf(h, "file %s ", f.Name())
hashWriteStat(h, f)
finfo, err := f.Info()
if err != nil {
fmt.Fprintf(h, "err %v\n", err)
} else {
hashWriteStat(h, finfo)
}
}
} else if info.Mode().IsRegular() {
// Because files might be very large, do not attempt
@ -1616,7 +1620,7 @@ func (c *runCache) saveOutput(a *work.Action) {
}
// See comment about two-level lookup in tryCacheWithID above.
testlog, err := ioutil.ReadFile(a.Objdir + "testlog.txt")
testlog, err := os.ReadFile(a.Objdir + "testlog.txt")
if err != nil || !bytes.HasPrefix(testlog, testlogMagic) || testlog[len(testlog)-1] != '\n' {
if cache.DebugTest {
if err != nil {

View File

@ -34,7 +34,7 @@ package txtar
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"strings"
)
@ -66,7 +66,7 @@ func Format(a *Archive) []byte {
// ParseFile parses the named file as an archive.
func ParseFile(file string) (*Archive, error) {
data, err := ioutil.ReadFile(file)
data, err := os.ReadFile(file)
if err != nil {
return nil, err
}

View File

@ -7,7 +7,6 @@ package vcs
import (
"errors"
"internal/testenv"
"io/ioutil"
"os"
"path"
"path/filepath"
@ -208,7 +207,7 @@ func TestRepoRootForImportPath(t *testing.T) {
// Test that vcsFromDir correctly inspects a given directory and returns the right VCS and root.
func TestFromDir(t *testing.T) {
tempDir, err := ioutil.TempDir("", "vcstest")
tempDir, err := os.MkdirTemp("", "vcstest")
if err != nil {
t.Fatal(err)
}

View File

@ -7,7 +7,6 @@ package web
import (
"errors"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"testing"
@ -16,7 +15,7 @@ import (
func TestGetFileURL(t *testing.T) {
const content = "Hello, file!\n"
f, err := ioutil.TempFile("", "web-TestGetFileURL")
f, err := os.CreateTemp("", "web-TestGetFileURL")
if err != nil {
t.Fatal(err)
}

View File

@ -14,7 +14,6 @@ import (
"debug/elf"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"runtime"
@ -253,7 +252,7 @@ func (b *Builder) Init() {
if cfg.BuildN {
b.WorkDir = "$WORK"
} else {
tmp, err := ioutil.TempDir(cfg.Getenv("GOTMPDIR"), "go-build")
tmp, err := os.MkdirTemp(cfg.Getenv("GOTMPDIR"), "go-build")
if err != nil {
base.Fatalf("go: creating work dir: %v", err)
}

View File

@ -8,7 +8,6 @@ import (
"bytes"
"fmt"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"reflect"
@ -170,7 +169,7 @@ func TestSharedLibName(t *testing.T) {
for _, data := range testData {
func() {
if data.rootedAt != "" {
tmpGopath, err := ioutil.TempDir("", "gopath")
tmpGopath, err := os.MkdirTemp("", "gopath")
if err != nil {
t.Fatal(err)
}
@ -238,7 +237,7 @@ func TestRespectSetgidDir(t *testing.T) {
return cmdBuf.WriteString(fmt.Sprint(a...))
}
setgiddir, err := ioutil.TempDir("", "SetGroupID")
setgiddir, err := os.MkdirTemp("", "SetGroupID")
if err != nil {
t.Fatal(err)
}
@ -258,9 +257,9 @@ func TestRespectSetgidDir(t *testing.T) {
t.Fatal(err)
}
pkgfile, err := ioutil.TempFile("", "pkgfile")
pkgfile, err := os.CreateTemp("", "pkgfile")
if err != nil {
t.Fatalf("ioutil.TempFile(\"\", \"pkgfile\"): %v", err)
t.Fatalf("os.CreateTemp(\"\", \"pkgfile\"): %v", err)
}
defer os.Remove(pkgfile.Name())
defer pkgfile.Close()

View File

@ -7,7 +7,6 @@ package work
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"os/exec"
"strings"
@ -344,7 +343,7 @@ func (b *Builder) gccgoBuildIDFile(a *Action) (string, error) {
}
}
if err := ioutil.WriteFile(sfile, buf.Bytes(), 0666); err != nil {
if err := os.WriteFile(sfile, buf.Bytes(), 0666); err != nil {
return "", err
}

View File

@ -16,7 +16,6 @@ import (
"internal/lazyregexp"
"io"
"io/fs"
"io/ioutil"
"log"
"math/rand"
"os"
@ -94,7 +93,7 @@ func (b *Builder) Do(ctx context.Context, root *Action) {
base.Fatalf("go: refusing to write action graph to %v\n", file)
}
js := actionGraphJSON(root)
if err := ioutil.WriteFile(file, []byte(js), 0666); err != nil {
if err := os.WriteFile(file, []byte(js), 0666); err != nil {
fmt.Fprintf(os.Stderr, "go: writing action graph: %v\n", err)
base.SetExitStatus(1)
}
@ -636,7 +635,7 @@ OverlayLoop:
sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles)
} else {
for _, sfile := range sfiles {
data, err := ioutil.ReadFile(filepath.Join(a.Package.Dir, sfile))
data, err := os.ReadFile(filepath.Join(a.Package.Dir, sfile))
if err == nil {
if bytes.HasPrefix(data, []byte("TEXT")) || bytes.Contains(data, []byte("\nTEXT")) ||
bytes.HasPrefix(data, []byte("DATA")) || bytes.Contains(data, []byte("\nDATA")) ||
@ -1471,7 +1470,7 @@ func (b *Builder) installShlibname(ctx context.Context, a *Action) error {
// TODO: BuildN
a1 := a.Deps[0]
err := ioutil.WriteFile(a.Target, []byte(filepath.Base(a1.Target)+"\n"), 0666)
err := os.WriteFile(a.Target, []byte(filepath.Base(a1.Target)+"\n"), 0666)
if err != nil {
return err
}
@ -1788,7 +1787,7 @@ func (b *Builder) writeFile(file string, text []byte) error {
if cfg.BuildN {
return nil
}
return ioutil.WriteFile(file, text, 0666)
return os.WriteFile(file, text, 0666)
}
// Install the cgo export header file, if there is one.
@ -2537,7 +2536,7 @@ func (b *Builder) gccSupportsFlag(compiler []string, flag string) bool {
tmp := os.DevNull
if runtime.GOOS == "windows" {
f, err := ioutil.TempFile(b.WorkDir, "")
f, err := os.CreateTemp(b.WorkDir, "")
if err != nil {
return false
}
@ -2840,7 +2839,7 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo
continue
}
src, err := ioutil.ReadFile(f)
src, err := os.ReadFile(f)
if err != nil {
return nil, nil, err
}
@ -3070,7 +3069,7 @@ func (b *Builder) swigDoIntSize(objdir string) (intsize string, err error) {
return "$INTBITS", nil
}
src := filepath.Join(b.WorkDir, "swig_intsize.go")
if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0666); err != nil {
if err = os.WriteFile(src, []byte(swigIntSizeCode), 0666); err != nil {
return
}
srcs := []string{src}
@ -3230,7 +3229,7 @@ func passLongArgsInResponseFiles(cmd *exec.Cmd) (cleanup func()) {
return
}
tf, err := ioutil.TempFile("", "args")
tf, err := os.CreateTemp("", "args")
if err != nil {
log.Fatalf("error writing long arguments to response file: %v", err)
}

View File

@ -9,7 +9,6 @@ import (
"bytes"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
@ -426,11 +425,11 @@ func toolVerify(a *Action, b *Builder, p *load.Package, newTool string, ofile st
if err := b.run(a, p.Dir, p.ImportPath, nil, newArgs...); err != nil {
return err
}
data1, err := ioutil.ReadFile(ofile)
data1, err := os.ReadFile(ofile)
if err != nil {
return err
}
data2, err := ioutil.ReadFile(ofile + ".new")
data2, err := os.ReadFile(ofile + ".new")
if err != nil {
return err
}
@ -580,7 +579,7 @@ func pluginPath(a *Action) string {
}
fmt.Fprintf(h, "build ID: %s\n", buildID)
for _, file := range str.StringList(p.GoFiles, p.CgoFiles, p.SFiles) {
data, err := ioutil.ReadFile(filepath.Join(p.Dir, file))
data, err := os.ReadFile(filepath.Join(p.Dir, file))
if err != nil {
base.Fatalf("go: %s", err)
}

View File

@ -6,7 +6,6 @@ package work
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@ -271,7 +270,7 @@ func (tools gccgoToolchain) link(b *Builder, root *Action, out, importcfg string
}
readCgoFlags := func(flagsFile string) error {
flags, err := ioutil.ReadFile(flagsFile)
flags, err := os.ReadFile(flagsFile)
if err != nil {
return err
}

View File

@ -13,7 +13,6 @@ import (
"fmt"
"io"
"io/fs"
"io/ioutil"
"log"
"net"
"net/http"
@ -75,12 +74,12 @@ func StartProxy() {
var modList []module.Version
func readModList() {
infos, err := ioutil.ReadDir("testdata/mod")
files, err := os.ReadDir("testdata/mod")
if err != nil {
log.Fatal(err)
}
for _, info := range infos {
name := info.Name()
for _, f := range files {
name := f.Name()
if !strings.HasSuffix(name, ".txt") {
continue
}

View File

@ -15,7 +15,6 @@ import (
"go/build"
"internal/testenv"
"io/fs"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@ -220,7 +219,7 @@ func (ts *testScript) run() {
for _, f := range a.Files {
name := ts.mkabs(ts.expand(f.Name, false))
ts.check(os.MkdirAll(filepath.Dir(name), 0777))
ts.check(ioutil.WriteFile(name, f.Data, 0666))
ts.check(os.WriteFile(name, f.Data, 0666))
}
// With -v or -testwork, start log with full environment.
@ -377,19 +376,19 @@ var (
func isCaseSensitive(t *testing.T) bool {
onceCaseSensitive.Do(func() {
tmpdir, err := ioutil.TempDir("", "case-sensitive")
tmpdir, err := os.MkdirTemp("", "case-sensitive")
if err != nil {
t.Fatal("failed to create directory to determine case-sensitivity:", err)
}
defer os.RemoveAll(tmpdir)
fcap := filepath.Join(tmpdir, "FILE")
if err := ioutil.WriteFile(fcap, []byte{}, 0644); err != nil {
if err := os.WriteFile(fcap, []byte{}, 0644); err != nil {
t.Fatal("error writing file to determine case-sensitivity:", err)
}
flow := filepath.Join(tmpdir, "file")
_, err = ioutil.ReadFile(flow)
_, err = os.ReadFile(flow)
switch {
case err == nil:
caseSensitive = false
@ -450,9 +449,9 @@ func (ts *testScript) cmdAddcrlf(want simpleStatus, args []string) {
for _, file := range args {
file = ts.mkabs(file)
data, err := ioutil.ReadFile(file)
data, err := os.ReadFile(file)
ts.check(err)
ts.check(ioutil.WriteFile(file, bytes.ReplaceAll(data, []byte("\n"), []byte("\r\n")), 0666))
ts.check(os.WriteFile(file, bytes.ReplaceAll(data, []byte("\n"), []byte("\r\n")), 0666))
}
}
@ -557,12 +556,12 @@ func (ts *testScript) doCmdCmp(args []string, env, quiet bool) {
} else if name1 == "stderr" {
text1 = ts.stderr
} else {
data, err := ioutil.ReadFile(ts.mkabs(name1))
data, err := os.ReadFile(ts.mkabs(name1))
ts.check(err)
text1 = string(data)
}
data, err := ioutil.ReadFile(ts.mkabs(name2))
data, err := os.ReadFile(ts.mkabs(name2))
ts.check(err)
text2 = string(data)
@ -614,14 +613,14 @@ func (ts *testScript) cmdCp(want simpleStatus, args []string) {
info, err := os.Stat(src)
ts.check(err)
mode = info.Mode() & 0777
data, err = ioutil.ReadFile(src)
data, err = os.ReadFile(src)
ts.check(err)
}
targ := dst
if dstDir {
targ = filepath.Join(dst, filepath.Base(src))
}
err := ioutil.WriteFile(targ, data, mode)
err := os.WriteFile(targ, data, mode)
switch want {
case failure:
if err == nil {
@ -897,7 +896,7 @@ func scriptMatch(ts *testScript, want simpleStatus, args []string, text, name st
isGrep := name == "grep"
if isGrep {
name = args[1] // for error messages
data, err := ioutil.ReadFile(ts.mkabs(args[1]))
data, err := os.ReadFile(ts.mkabs(args[1]))
ts.check(err)
text = string(data)
}

View File

@ -23,7 +23,6 @@ import (
"flag"
"fmt"
"io/fs"
"io/ioutil"
"log"
"os"
"os/exec"
@ -58,7 +57,7 @@ func main() {
log.SetFlags(0)
var err error
tmpdir, err = ioutil.TempDir("", "addmod-")
tmpdir, err = os.MkdirTemp("", "addmod-")
if err != nil {
log.Fatal(err)
}
@ -82,7 +81,7 @@ func main() {
exitCode := 0
for _, arg := range flag.Args() {
if err := ioutil.WriteFile(filepath.Join(tmpdir, "go.mod"), []byte("module m\n"), 0666); err != nil {
if err := os.WriteFile(filepath.Join(tmpdir, "go.mod"), []byte("module m\n"), 0666); err != nil {
fatalf("%v", err)
}
run(goCmd, "get", "-d", arg)
@ -98,13 +97,13 @@ func main() {
continue
}
path, vers, dir := f[0], f[1], f[2]
mod, err := ioutil.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".mod"))
mod, err := os.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".mod"))
if err != nil {
log.Printf("%s: %v", arg, err)
exitCode = 1
continue
}
info, err := ioutil.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".info"))
info, err := os.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".info"))
if err != nil {
log.Printf("%s: %v", arg, err)
exitCode = 1
@ -128,7 +127,7 @@ func main() {
}
name := info.Name()
if name == "go.mod" || strings.HasSuffix(name, ".go") {
data, err := ioutil.ReadFile(path)
data, err := os.ReadFile(path)
if err != nil {
return err
}
@ -144,7 +143,7 @@ func main() {
data := txtar.Format(a)
target := filepath.Join("mod", strings.ReplaceAll(path, "/", "_")+"_"+vers+".txt")
if err := ioutil.WriteFile(target, data, 0666); err != nil {
if err := os.WriteFile(target, data, 0666); err != nil {
log.Printf("%s: %v", arg, err)
exitCode = 1
continue

View File

@ -18,7 +18,6 @@ import (
"flag"
"fmt"
"io/fs"
"io/ioutil"
"log"
"os"
"path/filepath"
@ -63,7 +62,7 @@ func main() {
if !info.Type().IsRegular() {
return nil
}
data, err := ioutil.ReadFile(path)
data, err := os.ReadFile(path)
if err != nil {
log.Fatal(err)
}

View File

@ -81,7 +81,6 @@ package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"time"
)
@ -100,7 +99,7 @@ func truncateLike(t, p time.Time) time.Time {
func main() {
var t1 time.Time
b1, err := ioutil.ReadFile(os.Args[1])
b1, err := os.ReadFile(os.Args[1])
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
@ -111,7 +110,7 @@ func main() {
}
var t2 time.Time
b2, err := ioutil.ReadFile(os.Args[2])
b2, err := os.ReadFile(os.Args[2])
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)

View File

@ -121,7 +121,6 @@ package main
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
@ -131,7 +130,7 @@ import (
func main() {
exe := os.Args[1]
data, err := ioutil.ReadFile(exe)
data, err := os.ReadFile(exe)
if err != nil {
log.Fatal(err)
}

View File

@ -54,7 +54,6 @@ func Test(t *testing.T) {}
package main
import (
"io/ioutil"
"log"
"os"
"strings"
@ -62,13 +61,13 @@ import (
func main() {
log.SetFlags(0)
b, err := ioutil.ReadFile(os.Args[1])
b, err := os.ReadFile(os.Args[1])
if err != nil {
log.Fatal(err)
}
s := strings.ReplaceAll(string(b), "p.go:4:2:", "p.go:4:")
s = strings.ReplaceAll(s, "p1.go:6:2:", "p1.go:6:")
ioutil.WriteFile(os.Args[1], []byte(s), 0644)
os.WriteFile(os.Args[1], []byte(s), 0644)
if err != nil {
log.Fatal(err)
}

View File

@ -45,7 +45,6 @@ package main
import (
"bytes"
"io/ioutil"
"log"
"os"
)
@ -57,11 +56,11 @@ func main() {
base := []byte(os.Args[1])
path := os.Args[2]
data, err := ioutil.ReadFile(path)
data, err := os.ReadFile(path)
if err != nil {
log.Fatal(err)
}
err = ioutil.WriteFile(path, bytes.ReplaceAll(data, base, append(base, "XXX"...)), 0644)
err = os.WriteFile(path, bytes.ReplaceAll(data, base, append(base, "XXX"...)), 0644)
if err != nil {
log.Fatal(err)
}

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