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> <h2 id="language">Changes to the language</h2>
<p> <p>
TODO There are no changes to the language.
</p> </p>
<h2 id="ports">Ports</h2> <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 --> <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 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>
<p><!-- CL 254740 --> <p><!-- CL 254740 -->
The iOS port, which was previously <code>darwin/arm64</code>, is now The iOS port, which was previously <code>darwin/arm64</code>, has
moved to <code>ios/arm64</code>. <code>GOOS=ios</code> implies the been renamed to <code>ios/arm64</code>. <code>GOOS=ios</code>
implies the
<code>darwin</code> build tag, just as <code>GOOS=android</code> <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>
<p><!-- golang.org/issue/42100, CL 263798 --> <p><!-- golang.org/issue/42100, CL 263798 -->
The <code>ios/amd64</code> port is added, targetting the iOS simulator Go 1.16 adds an <code>ios/amd64</code> port, which targets the iOS
running on AMD64-based macOS. 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> </p>
<h3 id="netbsd">NetBSD</h3> <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). <code>netbsd/arm64</code> port).
</p> </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> <h3 id="386">386</h3>
<p><!-- golang.org/issue/40255, golang.org/issue/41848, CL 258957, and CL 260017 --> <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>. with <code>GO386=softfloat</code>.
</p> </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> <h2 id="tools">Tools</h2>
<p> <p>
@ -85,7 +110,7 @@ Do not send CLs removing the interior tags from such phrases.
<p><!-- golang.org/issue/41330 --> <p><!-- golang.org/issue/41330 -->
Module-aware mode is enabled by default, regardless of whether a 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 <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, variable now defaults to <code>on</code>. To switch to the previous behavior,
set <code>GO111MODULE</code> to <code>auto</code>. set <code>GO111MODULE</code> to <code>auto</code>.
</p> </p>
@ -141,6 +166,17 @@ Do not send CLs removing the interior tags from such phrases.
non-reproducible builds. non-reproducible builds.
</p> </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> <h4 id="go-test"><code>go</code> <code>test</code></h4>
<p><!-- golang.org/issue/29062 --> <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 The <code>go</code> <code>get</code> <code>-insecure</code> flag is
deprecated and will be removed in a future version. This flag permits deprecated and will be removed in a future version. This flag permits
fetching from repositories and resolving custom domains using insecure 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 checksum database. To permit the use of insecure schemes, use the
<code>GOINSECURE</code> environment variable instead. To bypass module <code>GOINSECURE</code> environment variable instead. To bypass module
sum validation, use <code>GOPRIVATE</code> or <code>GONOSUMDB</code>. 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 --> <!-- CL 235677: https://golang.org/cl/235677: cmd/vet: bring in pass to catch invalid uses of testing.T in goroutines -->
</p> </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> <h2 id="runtime">Runtime</h2>
<p> <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>
<p><!-- CL 267100 --> <p><!-- CL 267100 -->
@ -275,10 +342,21 @@ Do not send CLs removing the interior tags from such phrases.
variable. variable.
</p> </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> <h2 id="compiler">Compiler</h2>
<p> <p><!-- CL 256459, CL 264837, CL 266203, CL 256460 -->
TODO 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> </p>
<h2 id="linker">Linker</h2> <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 supported architecture/OS combinations (the 1.15 performance improvements
were primarily focused on <code>ELF</code>-based OSes and were primarily focused on <code>ELF</code>-based OSes and
<code>amd64</code> architectures). For a representative set of <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 5-15% less memory on average for <code>linux/amd64</code>, with larger
improvements for other architectures and OSes. improvements for other architectures and OSes. Most binaries are
</p> also smaller as a result of more aggressive symbol pruning.
<p>
TODO: update with final numbers later in the release.
</p> </p>
<p><!-- CL 255259 --> <p><!-- CL 255259 -->
@ -313,9 +388,54 @@ Do not send CLs removing the interior tags from such phrases.
<h2 id="library">Core library</h2> <h2 id="library">Core library</h2>
<h3 id="library-embed">Embedded Files</h3>
<p> <p>
TODO: mention significant additions like new packages (<code>io/fs</code>), The new <a href="/pkg/embed/"><code>embed</code></a> package
new proposal-scoped features (<code>//go:embed</code>), and so on 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>
<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> <dl id="crypto/hmac"><dt><a href="/pkg/crypto/hmac/">crypto/hmac</a></dt>
<dd> <dd>
<p><!-- CL 261960 --> <p><!-- CL 261960 -->
<a href="/pkg/crypto/hmac/#New">New</a> will now panic if separate calls to <a href="/pkg/crypto/hmac/#New"><code>New</code></a> will now panic if
the hash generation function fail to return new values. Previously, the separate calls to the hash generation function fail to return new values.
behavior was undefined and invalid outputs were sometimes generated. Previously, the behavior was undefined and invalid outputs were sometimes
generated.
</p> </p>
</dd> </dd>
</dl><!-- crypto/hmac --> </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> <dl id="crypto/tls"><dt><a href="/pkg/crypto/tls/">crypto/tls</a></dt>
<dd> <dd>
<p><!-- CL 256897 --> <p><!-- CL 256897 -->
I/O operations on closing or closed TLS connections can now be detected using I/O operations on closing or closed TLS connections can now be detected
the new <a href="/pkg/net/#ErrClosed">ErrClosed</a> error. A typical use using the new <a href="/pkg/net/#ErrClosed"><code>net.ErrClosed</code></a>
would be <code>errors.Is(err, net.ErrClosed)</code>. In earlier releases error. A typical use would be <code>errors.Is(err, net.ErrClosed)</code>.
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>.
</p> </p>
<p><!-- CL 266037 --> <p><!-- CL 266037 -->
A default deadline is set in <a href="/pkg/crypto/tls/#Conn.Close">Close</a> A default write deadline is now set in
before sending the close notify alert, in order to prevent blocking <a href="/pkg/crypto/tls/#Conn.Close"><code>Conn.Close</code></a>
before sending the "close notify" alert, in order to prevent blocking
indefinitely. indefinitely.
</p> </p>
<p><!-- CL 246338 --> <p><!-- CL 246338 -->
<a href="/pkg/crypto/tls#Conn.HandshakeContext">(*Conn).HandshakeContext</a> was added to The new <a href="/pkg/crypto/tls#Conn.HandshakeContext"><code>Conn.HandshakeContext</code></a>
allow the user to control cancellation of an in-progress TLS Handshake. method allows cancellation of an in-progress handshake. The provided
The context provided is propagated into the context is accessible through the new
<a href="/pkg/crypto/tls#ClientHelloInfo">ClientHelloInfo</a> <a href="/pkg/crypto/tls#ClientHelloInfo.Context"><code>ClientHelloInfo.Context</code></a>
and <a href="/pkg/crypto/tls#CertificateRequestInfo">CertificateRequestInfo</a> and <a href="/pkg/crypto/tls#CertificateRequestInfo.Context">
structs and accessible through the new <code>CertificateRequestInfo.Context</code></a> methods. Canceling the
<a href="/pkg/crypto/tls#ClientHelloInfo.Context">(*ClientHelloInfo).Context</a> context after the handshake has finished has no effect.
and
<a href="/pkg/crypto/tls#CertificateRequestInfo.Context">
(*CertificateRequestInfo).Context
</a> methods respectively. Canceling the context after the handshake has finished
has no effect.
</p> </p>
<p><!-- CL 239748 --> <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"> <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"> <a href="/pkg/crypto/tls/#Config.NextProtos">
the list advertised by the client</a>. the list advertised by the client</a>.
</p> </p>
<p><!-- CL 262857 --> <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 over AES-GCM cipher suites if either the client or server doesn't have AES hardware
support, unless the application set both support, unless both <a href="/pkg/crypto/tls/#Config.PreferServerCipherSuites">
<a href="/pkg/crypto/tls/#Config.PreferServerCipherSuites"><code>Config.PreferServerCipherSuites</code></a> <code>Config.PreferServerCipherSuites</code></a>
and <a href="/pkg/crypto/tls/#Config.CipherSuites"><code>Config.CipherSuites</code></a> and <a href="/pkg/crypto/tls/#Config.CipherSuites"><code>Config.CipherSuites</code></a>
or there are no other AEAD cipher suites supported. are set. The client is assumed not to have AES hardware support if it does
The client is assumed not to have AES hardware support if it does not signal a not signal a preference for AES-GCM cipher suites.
preference for AES-GCM cipher suites.
</p> </p>
<p><!-- CL 246637 --> <p><!-- CL 246637 -->
<a href="/pkg/crypto/tls/#Config.Clone"><code>Config.Clone</code></a> now returns <a href="/pkg/crypto/tls/#Config.Clone"><code>Config.Clone</code></a> now
a nil <code>*Config</code> if the source is nil, rather than panicking. returns nil if the receiver is nil, rather than panicking.
</p> </p>
</dd> </dd>
</dl><!-- crypto/tls --> </dl><!-- crypto/tls -->
<dl id="crypto/x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt> <dl id="crypto/x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt>
<dd> <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 --> <p><!-- CL 235078 -->
<a href="/pkg/crypto/x509/#ParseCertificate">ParseCertificate</a> and <a href="/pkg/crypto/x509/#ParseCertificate"><code>ParseCertificate</code></a> and
<a href="/pkg/crypto/x509/#CreateCertificate">CreateCertificate</a> both <a href="/pkg/crypto/x509/#CreateCertificate"><code>CreateCertificate</code></a>
now enforce string encoding restrictions for the fields <code>DNSNames</code>, now enforce string encoding restrictions for the <code>DNSNames</code>,
<code>EmailAddresses</code>, and <code>URIs</code>. These fields can only <code>EmailAddresses</code>, and <code>URIs</code> fields. These fields
contain strings with characters within the ASCII range. can only contain strings with characters within the ASCII range.
</p> </p>
<p><!-- CL 259697 --> <p><!-- CL 259697 -->
<a href="/pkg/crypto/x509/#CreateCertificate">CreateCertificate</a> now <a href="/pkg/crypto/x509/#CreateCertificate"><code>CreateCertificate</code></a>
verifies the generated certificate's signature using the signer's now verifies the generated certificate's signature using the signer's
public key. If the signature is invalid, an error is returned, instead public key. If the signature is invalid, an error is returned, instead of
of a malformed certificate. a malformed certificate.
</p> </p>
<p><!-- CL 233163 --> <p><!-- CL 233163 -->
A number of additional fields have been added to the A number of additional fields have been added to the
<a href="/pkg/crypto/x509/#CertificateRequest">CertificateRequest</a> type. <a href="/pkg/crypto/x509/#CertificateRequest"><code>CertificateRequest</code></a> type.
These fields are now parsed in <a href="/pkg/crypto/x509/#ParseCertificateRequest">ParseCertificateRequest</a> These fields are now parsed in <a href="/pkg/crypto/x509/#ParseCertificateRequest">
and marshalled in <a href="/pkg/crypto/x509/#CreateCertificateRequest">CreateCertificateRequest</a>. <code>ParseCertificateRequest</code></a> and marshalled in
<a href="/pkg/crypto/x509/#CreateCertificateRequest"><code>CreateCertificateRequest</code></a>.
</p> </p>
<p><!-- CL 257939 --> <p><!-- CL 257939 -->
@ -448,7 +570,9 @@ Do not send CLs removing the interior tags from such phrases.
</p> </p>
<p><!-- CL 262343 --> <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> </p>
</dd> </dd>
</dl><!-- crypto/x509 --> </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> <dl id="encoding/asn1"><dt><a href="/pkg/encoding/asn1">encoding/asn1</a></dt>
<dd> <dd>
<p><!-- CL 255881 --> <p><!-- CL 255881 -->
<a href="/pkg/encoding/asn1/#Unmarshal">Unmarshal</a> and <a href="/pkg/encoding/asn1/#Unmarshal"><code>Unmarshal</code></a> and
<a href="/pkg/encoding/asn1/#UnmarshalWithParams">UnmarshalWithParams</a> <a href="/pkg/encoding/asn1/#UnmarshalWithParams"><code>UnmarshalWithParams</code></a>
now return an error instead of panic when the argument is not now return an error instead of panicking when the argument is not
a pointer or is nil. This change matches the behavior of other 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> </p>
</dd> </dd>
</dl> </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> <dl id="flag"><dt><a href="/pkg/flag/">flag</a></dt>
<dd> <dd>
<p><!-- CL 240014 --> <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> </p>
</dd> </dd>
</dl><!-- flag --> </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> <dl id="io"><dt><a href="/pkg/io/">io</a></dt>
<dd> <dd>
<p><!-- CL 261577 --> <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> </p>
</dd> </dd>
</dl><!-- io --> </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> <dl id="log"><dt><a href="/pkg/log/">log</a></dt>
<dd> <dd>
<p><!-- CL 264460 --> <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> </p>
</dd> </dd>
</dl><!-- log --> </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> <dl id="log/syslog"><dt><a href="/pkg/log/syslog/">log/syslog</a></dt>
<dd> <dd>
<p><!-- CL 264297 --> <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> </p>
</dd> </dd>
</dl><!-- log/syslog --> </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> <dl id="mime/multipart"><dt><a href="/pkg/mime/multipart/">mime/multipart</a></dt>
<dd> <dd>
<p><!-- CL 247477 --> <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> </p>
</dd> </dd>
</dl><!-- mime/multipart --> </dl><!-- mime/multipart -->
@ -550,7 +686,10 @@ Do not send CLs removing the interior tags from such phrases.
</p> </p>
<p><!-- CL 238629 --> <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> </p>
</dd> </dd>
</dl><!-- net --> </dl><!-- net -->
@ -578,23 +717,29 @@ Do not send CLs removing the interior tags from such phrases.
</p> </p>
<p><!-- CL 256498, golang.org/issue/36990 --> <p><!-- CL 256498, golang.org/issue/36990 -->
Cookies set with <code>SameSiteDefaultMode</code> now behave according to the current Cookies set with <a href="/pkg/net/http/#SameSiteDefaultMode"><code>SameSiteDefaultMode</code></a>
spec (no attribute is set) instead of generating a SameSite key without a value. now behave according to the current spec (no attribute is set) instead of
generating a SameSite key without a value.
</p> </p>
<p><!-- CL 246338 --> <p><!-- CL 246338 -->
The <a href="/pkg/net/http/"><code>net/http</code></a> package now uses the new The <a href="/pkg/net/http/"><code>net/http</code></a> package now passes the
<a href="/pkg/crypto/tls#Conn.HandshakeContext"><code>(*tls.Conn).HandshakeContext</code></a> <a href="/pkg/net/http/#Request.Context"><code>Request</code> context</a> to
with the <a href="/pkg/net/http/#Request"><code>Request</code></a> context <a href="/pkg/crypto/tls#Conn.HandshakeContext"><code>tls.Conn.HandshakeContext</code></a>
when performing TLS handshakes in the client or server. when performing TLS handshakes.
</p> </p>
<p><!-- CL 250039 --> <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>
<p><!-- CL 249440 --> <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> </p>
</dd> </dd>
</dl><!-- net/http --> </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> <dl id="net/http/httputil"><dt><a href="/pkg/net/http/httputil/">net/http/httputil</a></dt>
<dd> <dd>
<p><!-- CL 260637 --> <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> </p>
</dd> </dd>
</dl><!-- net/http/httputil --> </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> <dl id="net/smtp"><dt><a href="/pkg/net/smtp/">net/smtp</a></dt>
<dd> <dd>
<p><!-- CL 247257 --> <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> </p>
</dd> </dd>
</dl><!-- net/smtp --> </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> <dl id="os/signal"><dt><a href="/pkg/os/signal/">os/signal</a></dt>
<dd> <dd>
<p><!-- CL 219640 --> <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> </p>
</dd> </dd>
</dl><!-- os/signal --> </dl><!-- os/signal -->
<dl id="path"><dt><a href="/pkg/path/">path</a></dt> <dl id="path"><dt><a href="/pkg/path/">path</a></dt>
<dd> <dd>
<p><!-- CL 264397 --> <p><!-- CL 264397, golang.org/issues/28614 -->
TODO: <a href="https://golang.org/cl/264397">https://golang.org/cl/264397</a>: validate patterns in Match, Glob 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> </p>
</dd> </dd>
</dl><!-- path --> </dl><!-- path -->
<dl id="path/filepath"><dt><a href="/pkg/path/filepath/">path/filepath</a></dt> <dl id="path/filepath"><dt><a href="/pkg/path/filepath/">path/filepath</a></dt>
<dd> <dd>
<p><!-- CL 264397 --> <p><!-- CL 264397, golang.org/issues/28614 -->
TODO: <a href="https://golang.org/cl/264397">https://golang.org/cl/264397</a>: validate patterns in Match, Glob 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> </p>
</dd> </dd>
</dl><!-- path/filepath --> </dl><!-- path/filepath -->
<dl id="reflect"><dt><a href="/pkg/reflect/">reflect</a></dt> <dl id="reflect"><dt><a href="/pkg/reflect/">reflect</a></dt>
<dd> <dd>
<p><!-- CL 248341 --> <p><!-- CL 248341, golang.org/issues/40281 -->
TODO: <a href="https://golang.org/cl/248341">https://golang.org/cl/248341</a>: support multiple keys in struct tags <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> </p>
</dd> </dd>
</dl><!-- reflect --> </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> <dl id="runtime/debug"><dt><a href="/pkg/runtime/debug/">runtime/debug</a></dt>
<dd> <dd>
<p><!-- CL 249677 --> <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 used when <code>SetPanicOnFault</code> is enabled may now have an
<code>Addr</code> method. If that method exists, it returns the memory <code>Addr</code> method. If that method exists, it returns the memory
address that triggered the fault. 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> <dl id="syscall"><dt><a href="/pkg/syscall/">syscall</a></dt>
<dd> <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 --> <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>
<p><!-- CL 269761, golang.org/issue/42584 --> <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>
<p><!-- CL 210639 --> <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> </p>
</dd> </dd>
</dl><!-- syscall --> </dl><!-- syscall -->

View file

@ -28,6 +28,7 @@ func TestMSAN(t *testing.T) {
{src: "msan4.go"}, {src: "msan4.go"},
{src: "msan5.go"}, {src: "msan5.go"},
{src: "msan6.go"}, {src: "msan6.go"},
{src: "msan7.go"},
{src: "msan_fail.go", wantErr: true}, {src: "msan_fail.go", wantErr: true},
} }
for _, tc := range cases { 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" "errors"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"math" "math"
"os" "os"
"path" "path"
@ -773,7 +772,7 @@ func TestReadTruncation(t *testing.T) {
"testdata/pax-path-hdr.tar", "testdata/pax-path-hdr.tar",
"testdata/sparse-formats.tar", "testdata/sparse-formats.tar",
} { } {
buf, err := ioutil.ReadFile(p) buf, err := os.ReadFile(p)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -82,6 +82,7 @@ func initssaconfig() {
growslice = sysfunc("growslice") growslice = sysfunc("growslice")
msanread = sysfunc("msanread") msanread = sysfunc("msanread")
msanwrite = sysfunc("msanwrite") msanwrite = sysfunc("msanwrite")
msanmove = sysfunc("msanmove")
newobject = sysfunc("newobject") newobject = sysfunc("newobject")
newproc = sysfunc("newproc") newproc = sysfunc("newproc")
panicdivide = sysfunc("panicdivide") 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) return s.newValue2(op, t, arg0, arg1)
} }
func (s *state) instrument(t *types.Type, addr *ssa.Value, wr bool) { type instrumentKind uint8
if !s.curfn.InstrumentBody() {
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 return
} }
@ -982,33 +1021,54 @@ func (s *state) instrument(t *types.Type, addr *ssa.Value, wr bool) {
var fn *obj.LSym var fn *obj.LSym
needWidth := false needWidth := false
if addr2 != nil && kind != instrumentMove {
panic("instrument2: non-nil addr2 for non-move instrumentation")
}
if base.Flag.MSan { if base.Flag.MSan {
fn = msanread switch kind {
if wr { case instrumentRead:
fn = msanread
case instrumentWrite:
fn = msanwrite fn = msanwrite
case instrumentMove:
fn = msanmove
default:
panic("unreachable")
} }
needWidth = true needWidth = true
} else if base.Flag.Race && t.NumComponents(types.CountBlankFields) > 1 { } else if base.Flag.Race && t.NumComponents(types.CountBlankFields) > 1 {
// for composite objects we have to write every address // for composite objects we have to write every address
// because a write might happen to any subobject. // because a write might happen to any subobject.
// composites with only one element don't have subobjects, though. // composites with only one element don't have subobjects, though.
fn = racereadrange switch kind {
if wr { case instrumentRead:
fn = racereadrange
case instrumentWrite:
fn = racewriterange fn = racewriterange
default:
panic("unreachable")
} }
needWidth = true needWidth = true
} else if base.Flag.Race { } else if base.Flag.Race {
// for non-composite objects we can write just the start // for non-composite objects we can write just the start
// address, as any write must write the first byte. // address, as any write must write the first byte.
fn = raceread switch kind {
if wr { case instrumentRead:
fn = raceread
case instrumentWrite:
fn = racewrite fn = racewrite
default:
panic("unreachable")
} }
} else { } else {
panic("unreachable") panic("unreachable")
} }
args := []*ssa.Value{addr} args := []*ssa.Value{addr}
if addr2 != nil {
args = append(args, addr2)
}
if needWidth { if needWidth {
args = append(args, s.constInt(types.Types[types.TUINTPTR], w)) 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 { 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) 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) { 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 := s.newValue2I(ssa.OpZero, types.TypeMem, t.Size(), dst, s.mem())
store.Aux = t store.Aux = t
s.vars[memVar] = store s.vars[memVar] = store
} }
func (s *state) move(t *types.Type, dst, src *ssa.Value) { func (s *state) move(t *types.Type, dst, src *ssa.Value) {
s.instrument(t, src, false) s.instrumentMove(t, dst, src)
s.instrument(t, dst, true)
store := s.newValue3I(ssa.OpMove, types.TypeMem, t.Size(), dst, src, s.mem()) store := s.newValue3I(ssa.OpMove, types.TypeMem, t.Size(), dst, src, s.mem())
store.Aux = t store.Aux = t
s.vars[memVar] = store 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. // do *left = right for type t.
func (s *state) storeType(t *types.Type, left, right *ssa.Value, skip skipMask, leftIsStmt bool) { 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)) { if skip == 0 && (!t.HasPointers() || ssa.IsStackAddr(left)) {
// Known to not have write barrier. Store the whole type. // 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) { func wantN(t *testing.T, out string, desired string, n int) {
if strings.Count(out, desired) != n { 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 // fold ADDL into LEAL
(ADDLconst [c] (LEAL [d] {s} x)) && is32Bit(int64(c)+int64(d)) => (LEAL [c+d] {s} x) (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) (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) (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) (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]) (MUL (MOVWconst [c]) (MOVWconst [d])) => (MOVWconst [c*d])
(MULA (MOVWconst [c]) (MOVWconst [d]) a) => (ADDconst [c*d] a) (MULA (MOVWconst [c]) (MOVWconst [d]) a) => (ADDconst [c*d] a)
(MULS (MOVWconst [c]) (MOVWconst [d]) a) => (SUBconst [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))]) (Select0 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [int32(uint32(c)/uint32(d))])
(Select1 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) => (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] (MOVWconst [d])) => (MOVWconst [c&d])
(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x) (ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x)
(ORconst [c] (MOVWconst [d])) => (MOVWconst [c|d]) (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) (MADDW a (MOVDconst [c]) (MOVDconst [d])) => (ADDconst [int64(int32(c)*int32(d))] a)
(MSUB a (MOVDconst [c]) (MOVDconst [d])) => (SUBconst [c*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) (MSUBW a (MOVDconst [c]) (MOVDconst [d])) => (SUBconst [int64(int32(c)*int32(d))] a)
(DIV (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c/d]) (DIV (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [c/d])
(UDIV (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [int64(uint64(c)/uint64(d))]) (UDIV (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint64(c)/uint64(d))])
(DIVW (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [int64(int32(c)/int32(d))]) (DIVW (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(int32(c)/int32(d))])
(UDIVW (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [int64(uint32(c)/uint32(d))]) (UDIVW (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint32(c)/uint32(d))])
(MOD (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c%d]) (MOD (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [c%d])
(UMOD (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [int64(uint64(c)%uint64(d))]) (UMOD (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint64(c)%uint64(d))])
(MODW (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [int64(int32(c)%int32(d))]) (MODW (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(int32(c)%int32(d))])
(UMODW (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [int64(uint32(c)%uint32(d))]) (UMODW (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint32(c)%uint32(d))])
(ANDconst [c] (MOVDconst [d])) => (MOVDconst [c&d]) (ANDconst [c] (MOVDconst [d])) => (MOVDconst [c&d])
(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x) (ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x)
(ANDconst [c] (MOVWUreg x)) => (ANDconst [c&(1<<32-1)] 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]) (MUL (MOVWconst [c]) (MOVWconst [d])) => (MOVWconst [c*d])
(Select1 (MULTU (MOVWconst [c]) (MOVWconst [d]))) => (MOVWconst [int32(uint32(c)*uint32(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)]) (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 (DIV (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [c/d])
(Select1 (DIVU (MOVWconst [c]) (MOVWconst [d]))) => (MOVWconst [int32(uint32(c)/uint32(d))]) (Select1 (DIVU (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [int32(uint32(c)/uint32(d))])
(Select0 (DIV (MOVWconst [c]) (MOVWconst [d]))) => (MOVWconst [c%d]) (Select0 (DIV (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [c%d])
(Select0 (DIVU (MOVWconst [c]) (MOVWconst [d]))) => (MOVWconst [int32(uint32(c)%uint32(d))]) (Select0 (DIVU (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [int32(uint32(c)%uint32(d))])
(ANDconst [c] (MOVWconst [d])) => (MOVWconst [c&d]) (ANDconst [c] (MOVWconst [d])) => (MOVWconst [c&d])
(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x) (ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x)
(ORconst [c] (MOVWconst [d])) => (MOVWconst [c|d]) (ORconst [c] (MOVWconst [d])) => (MOVWconst [c|d])

View file

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

View file

@ -845,6 +845,7 @@
(SUB x (MOVDconst [c])) && is32Bit(-c) => (ADDconst [-c] x) (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] (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) (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 // folding offset into address
(I64AddConst [off] (LoweredAddr {sym} [off2] base)) && isU32Bit(off+int64(off2)) => (I64AddConst [off] (LoweredAddr {sym} [off2] base)) && isU32Bit(off+int64(off2)) =>
(LoweredAddr {sym} [int32(off)+off2] base) (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 // 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))]) (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) v.AddArg(x)
return true 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)) // match: (ADDLconst [c] (LEAL1 [d] {s} x y))
// cond: is32Bit(int64(c)+int64(d)) // cond: is32Bit(int64(c)+int64(d))
// result: (LEAL1 [c+d] {s} x y) // result: (LEAL1 [c+d] {s} x y)

View file

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

View file

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

View file

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

View file

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

View file

@ -4195,6 +4195,20 @@ func rewriteValuePPC64_OpPPC64ADDconst(v *Value) bool {
v.AddArg(x) v.AddArg(x)
return true 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)) // match: (ADDconst [c] (SUBFCconst [d] x))
// cond: is32Bit(c+d) // cond: is32Bit(c+d)
// result: (SUBFCconst [c+d] x) // result: (SUBFCconst [c+d] x)

View file

@ -3693,6 +3693,20 @@ func rewriteValueWasm_OpWasmI64AddConst(v *Value) bool {
v.AddArg(base) v.AddArg(base)
return true 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 return false
} }
func rewriteValueWasm_OpWasmI64And(v *Value) bool { 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: 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 := s.Prog(wasm.AGet)
p.From.Type = obj.TYPE_ADDR p.From.Type = obj.TYPE_ADDR
switch v.Aux.(type) { switch v.Aux.(type) {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -3,11 +3,10 @@ module cmd
go 1.16 go 1.16
require ( require (
github.com/google/pprof v0.0.0-20201007051231-1066cbb265c7 github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2
github.com/ianlancetaylor/demangle v0.0.0-20200414190113-039b1ae3a340 // indirect
golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
golang.org/x/mod v0.4.0 golang.org/x/mod v0.4.0
golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65 // indirect golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect
golang.org/x/tools v0.0.0-20201110201400-7099162a900a 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/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/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/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-20201203190320-1bf35d6f28c2 h1:HyOHhUtuB/Ruw/L5s5pG2D0kckkN2/IzBs9OClGHnHI=
github.com/google/pprof v0.0.0-20201007051231-1066cbb265c7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 h1:mV02weKRL81bEnm8A0HT1/CAelMQDBuQIfLw8n+d6xI=
github.com/ianlancetaylor/demangle v0.0.0-20200414190113-039b1ae3a340 h1:S1+yTUaFPXuDZnPDbO+TrDFIjPzQraYH8/CwSlu9Fac= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200414190113-039b1ae3a340/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 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 h1:XmKBi9R6duxOB3lfc72wyrwiOY7X2Jl1wuI+RFOyMDE=
golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4= 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-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-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-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-20201204225414-ed752295db88 h1:KmZPnMocC93w341XZp26yTJg8Za7lhb2KhkYmixoeso=
golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 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-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-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-20201208211828-de58e7c01d49 h1:K1QAOVIWIvmQ66F1Z3AEa9Wzp0bj+xU3YzLkvROk2Ds=
golang.org/x/tools v0.0.0-20201110201400-7099162a900a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 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-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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -13,7 +13,6 @@ import (
"fmt" "fmt"
"io" "io"
"io/fs" "io/fs"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strconv" "strconv"
@ -239,7 +238,7 @@ func (c *Cache) GetBytes(id ActionID) ([]byte, Entry, error) {
if err != nil { if err != nil {
return nil, entry, err return nil, entry, err
} }
data, _ := ioutil.ReadFile(c.OutputFile(entry.OutputID)) data, _ := os.ReadFile(c.OutputFile(entry.OutputID))
if sha256.Sum256(data) != entry.OutputID { if sha256.Sum256(data) != entry.OutputID {
return nil, entry, &entryNotFoundError{Err: errors.New("bad checksum")} 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. // Truncate the file only *after* writing it.
// (This should be a no-op, but truncate just in case of previous corruption.) // (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 // 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 // of the same content to the same file is idempotent, and does not — even
// temporarily! — undo the effect of the first write. // temporarily! — undo the effect of the first write.

View file

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

View file

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

View file

@ -6,7 +6,6 @@ package cache
import ( import (
"fmt" "fmt"
"io/ioutil"
"os" "os"
"testing" "testing"
) )
@ -28,7 +27,7 @@ func TestHash(t *testing.T) {
} }
func TestHashFile(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 { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -13,7 +13,6 @@ import (
"go/parser" "go/parser"
"go/token" "go/token"
"io" "io"
"io/ioutil"
"log" "log"
"os" "os"
"os/exec" "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. // generate runs the generation directives for a single file.
func generate(absFile string) bool { func generate(absFile string) bool {
src, err := ioutil.ReadFile(absFile) src, err := os.ReadFile(absFile)
if err != nil { if err != nil {
log.Fatalf("generate: %s", err) log.Fatalf("generate: %s", err)
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -10,7 +10,6 @@ import (
"fmt" "fmt"
"io" "io"
"io/fs" "io/fs"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"sort" "sort"
@ -155,7 +154,7 @@ func runVendor(ctx context.Context, cmd *base.Command, args []string) {
base.Fatalf("go mod vendor: %v", err) 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) base.Fatalf("go mod vendor: %v", err)
} }
} }
@ -244,7 +243,7 @@ var metaPrefixes = []string{
} }
// matchMetadata reports whether info is a metadata file. // 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() name := info.Name()
for _, p := range metaPrefixes { for _, p := range metaPrefixes {
if strings.HasPrefix(name, p) { 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. // 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") { if strings.HasSuffix(info.Name(), "_test.go") {
return false 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. // 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) { func copyDir(dst, src string, match func(dir string, info fs.DirEntry) bool) {
files, err := ioutil.ReadDir(src) files, err := os.ReadDir(src)
if err != nil { if err != nil {
base.Fatalf("go mod vendor: %v", err) 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) base.Fatalf("go mod vendor: %v", err)
} }
for _, file := range files { for _, file := range files {
if file.IsDir() || !file.Mode().IsRegular() || !match(src, file) { if file.IsDir() || !file.Type().IsRegular() || !match(src, file) {
continue continue
} }
r, err := os.Open(filepath.Join(src, file.Name())) r, err := os.Open(filepath.Join(src, file.Name()))

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -15,7 +15,6 @@ import (
"flag" "flag"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"log" "log"
"os" "os"
"strings" "strings"
@ -124,7 +123,7 @@ func main() {
} }
if f[3] != "-" { 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) fmt.Fprintf(os.Stderr, "?%s\n", err)
continue continue
} }

View file

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

View file

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

View file

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

View file

@ -12,7 +12,6 @@ import (
"fmt" "fmt"
"io" "io"
"io/fs" "io/fs"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"sort" "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 { if err := os.MkdirAll(parentDir, 0777); err != nil {
return "", err return "", err
} }
if err := ioutil.WriteFile(partialPath, nil, 0666); err != nil { if err := os.WriteFile(partialPath, nil, 0666); err != nil {
return "", err return "", err
} }
if err := modzip.Unzip(dir, mod, zipfile); err != nil { 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 // 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 // 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. // 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 { if err != nil {
return err return err
} }

View file

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

View file

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

View file

@ -61,8 +61,8 @@ package modload
// Similarly, if the LoadTests flag is set but the "all" pattern does not close // 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 // 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 // "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 // 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+. // 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 // 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 // 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 // UseVendorAll causes the "all" package pattern to be interpreted as if
// running "go mod vendor" (or building with "-mod=vendor"). // running "go mod vendor" (or building with "-mod=vendor").
// //
// Once lazy loading is implemented, this will be a no-op for modules that // This is a no-op for modules that declare 'go 1.16' or higher, for which this
// declare 'go 1.16' or higher. // is the default (and only) interpretation of the "all" pattern in module mode.
UseVendorAll bool UseVendorAll bool
// AllowErrors indicates that LoadPackages should not terminate the process if // AllowErrors indicates that LoadPackages should not terminate the process if

View file

@ -25,10 +25,11 @@ import (
"golang.org/x/mod/semver" "golang.org/x/mod/semver"
) )
// lazyLoadingVersion is the Go version (plus leading "v") at which lazy module // narrowAllVersionV is the Go version (plus leading "v") at which the
// loading takes effect. // module-module "all" pattern no longer closes over the dependencies of
const lazyLoadingVersionV = "v1.16" // tests outside of the main module.
const go116EnableLazyLoading = true const narrowAllVersionV = "v1.16"
const go116EnableNarrowAll = true
var modFile *modfile.File 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 // (Otherwise — as in Go 1.16+ — the "all" pattern includes only the packages
// transitively *imported by* the packages and tests in the main module.) // transitively *imported by* the packages and tests in the main module.)
func (i *modFileIndex) allPatternClosesOverTests() bool { func (i *modFileIndex) allPatternClosesOverTests() bool {
if !go116EnableLazyLoading { if !go116EnableNarrowAll {
return true 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 // 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 // continue to use the older interpretation. (If i == nil, we not in any
// module at all and should use the latest semantics.) // module at all and should use the latest semantics.)

View file

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

View file

@ -8,7 +8,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io/fs" "io/fs"
"io/ioutil" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"sync" "sync"
@ -40,7 +40,7 @@ func readVendorList() {
vendorPkgModule = make(map[string]module.Version) vendorPkgModule = make(map[string]module.Version)
vendorVersion = make(map[string]string) vendorVersion = make(map[string]string)
vendorMeta = make(map[module.Version]vendorMetadata) 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 err != nil {
if !errors.Is(err, fs.ErrNotExist) { if !errors.Is(err, fs.ErrNotExist) {
base.Fatalf("go: %s", err) 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) 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 // file in the same directory as filename, then renames it atomically to the
// final name. // final name.
// //
@ -67,7 +67,7 @@ func WriteToFile(filename string, data io.Reader, perm fs.FileMode) (err error)
return robustio.Rename(f.Name(), filename) 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. // may occur if the file is concurrently replaced.
// //
// Errors are classified heuristically and retries are bounded, so even this // Errors are classified heuristically and retries are bounded, so even this

View file

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

View file

@ -8,7 +8,6 @@ package renameio
import ( import (
"io/fs" "io/fs"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"syscall" "syscall"
@ -16,7 +15,7 @@ import (
) )
func TestWriteFileModeAppliesUmask(t *testing.T) { func TestWriteFileModeAppliesUmask(t *testing.T) {
dir, err := ioutil.TempDir("", "renameio") dir, err := os.MkdirTemp("", "renameio")
if err != nil { if err != nil {
t.Fatalf("Failed to create temporary directory: %v", err) 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) 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. // occur if the file is concurrently replaced.
// //
// (See golang.org/issue/31247 and golang.org/issue/32188.) // (See golang.org/issue/31247 and golang.org/issue/32188.)

View file

@ -8,7 +8,6 @@ package robustio
import ( import (
"errors" "errors"
"io/ioutil"
"math/rand" "math/rand"
"os" "os"
"syscall" "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) { func readFile(filename string) ([]byte, error) {
var b []byte var b []byte
err := retry(func() (err error, mayRetry bool) { 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 // 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 // as a spurious error, but the file may also genuinely not exist, so the

View file

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

View file

@ -13,7 +13,6 @@ import (
"go/build" "go/build"
"io" "io"
"io/fs" "io/fs"
"io/ioutil"
"os" "os"
"os/exec" "os/exec"
"path" "path"
@ -884,7 +883,7 @@ func builderTest(b *work.Builder, ctx context.Context, p *load.Package) (buildAc
if !cfg.BuildN { if !cfg.BuildN {
// writeTestmain writes _testmain.go, // writeTestmain writes _testmain.go,
// using the test description gathered in t. // 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 return nil, nil, nil, err
} }
} }
@ -1561,13 +1560,18 @@ func hashOpen(name string) (cache.ActionID, error) {
} }
hashWriteStat(h, info) hashWriteStat(h, info)
if info.IsDir() { if info.IsDir() {
names, err := ioutil.ReadDir(name) files, err := os.ReadDir(name)
if err != nil { if err != nil {
fmt.Fprintf(h, "err %v\n", err) fmt.Fprintf(h, "err %v\n", err)
} }
for _, f := range names { for _, f := range files {
fmt.Fprintf(h, "file %s ", f.Name()) 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() { } else if info.Mode().IsRegular() {
// Because files might be very large, do not attempt // 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. // 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 err != nil || !bytes.HasPrefix(testlog, testlogMagic) || testlog[len(testlog)-1] != '\n' {
if cache.DebugTest { if cache.DebugTest {
if err != nil { if err != nil {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -7,7 +7,6 @@ package work
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io/ioutil"
"os" "os"
"os/exec" "os/exec"
"strings" "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 return "", err
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -45,7 +45,6 @@ package main
import ( import (
"bytes" "bytes"
"io/ioutil"
"log" "log"
"os" "os"
) )
@ -57,11 +56,11 @@ func main() {
base := []byte(os.Args[1]) base := []byte(os.Args[1])
path := os.Args[2] path := os.Args[2]
data, err := ioutil.ReadFile(path) data, err := os.ReadFile(path)
if err != nil { if err != nil {
log.Fatal(err) 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 { if err != nil {
log.Fatal(err) log.Fatal(err)
} }

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