[dev.link] all: merge branch 'master' into dev.link
Change-Id: I446db56b20ef2189e23e225a91a17736c1d11e4c
diff --git a/.gitattributes b/.gitattributes
index bcea029..cabbb17 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,16 +1,16 @@
# Treat all files in the Go repo as binary, with no git magic updating
-# line endings. Windows users contributing to Go will need to use a
-# modern version of git and editors capable of LF line endings.
+# line endings. This produces predictable results in different environments.
+#
+# Windows users contributing to Go will need to use a modern version
+# of git and editors capable of LF line endings.
+#
+# Windows .bat files are known to have multiple bugs when run with LF
+# endings, and so they are checked in with CRLF endings, with a test
+# in test/winbatch.go to catch problems. (See golang.org/issue/37791.)
#
# We'll prevent accidental CRLF line endings from entering the repo
-# via the git-review gofmt checks.
+# via the git-codereview gofmt checks and tests.
#
-# See golang.org/issue/9281
+# See golang.org/issue/9281.
* -text
-
-# The only exception is Windows files that must absolutely be CRLF or
-# might not work. Batch files are known to have multiple bugs when run
-# with LF endings. See golang.org/issue/37791 for more information.
-
-*.bat text eol=crlf
diff --git a/AUTHORS b/AUTHORS
index 69e35a1..80c79fe 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1397,6 +1397,7 @@
Uriel Mangado <uriel@berlinblue.org>
Vadim Grek <vadimprog@gmail.com>
Vadim Vygonets <unixdj@gmail.com>
+Vee Zhang <veezhang@126.com> <vveezhang@gmail.com>
Vendasta
Veselkov Konstantin <kostozyb@gmail.com>
Victor Vrantchan <vrancean+github@gmail.com>
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 934834f..6b6ee09 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -2195,6 +2195,7 @@
Vadim Vygonets <unixdj@gmail.com>
Val Polouchkine <vpolouch@justin.tv>
Valentin Vidic <vvidic@valentin-vidic.from.hr>
+Vee Zhang <veezhang@126.com> <vveezhang@gmail.com>
Vega Garcia Luis Alfonso <vegacom@gmail.com>
Venil Noronha <veniln@vmware.com>
Veselkov Konstantin <kostozyb@gmail.com>
diff --git a/api/go1.15.txt b/api/go1.15.txt
new file mode 100644
index 0000000..b51837c
--- /dev/null
+++ b/api/go1.15.txt
@@ -0,0 +1,132 @@
+pkg bufio, var ErrBadReadCount error
+pkg crypto, method (Hash) String() string
+pkg crypto/ecdsa, func SignASN1(io.Reader, *PrivateKey, []uint8) ([]uint8, error)
+pkg crypto/ecdsa, func VerifyASN1(*PublicKey, []uint8, []uint8) bool
+pkg crypto/ecdsa, method (*PrivateKey) Equal(crypto.PrivateKey) bool
+pkg crypto/ecdsa, method (*PublicKey) Equal(crypto.PublicKey) bool
+pkg crypto/ed25519, method (PrivateKey) Equal(crypto.PrivateKey) bool
+pkg crypto/ed25519, method (PublicKey) Equal(crypto.PublicKey) bool
+pkg crypto/elliptic, func MarshalCompressed(Curve, *big.Int, *big.Int) []uint8
+pkg crypto/elliptic, func UnmarshalCompressed(Curve, []uint8) (*big.Int, *big.Int)
+pkg crypto/rsa, method (*PrivateKey) Equal(crypto.PrivateKey) bool
+pkg crypto/rsa, method (*PublicKey) Equal(crypto.PublicKey) bool
+pkg crypto/tls, method (*Dialer) Dial(string, string) (net.Conn, error)
+pkg crypto/tls, method (*Dialer) DialContext(context.Context, string, string) (net.Conn, error)
+pkg crypto/tls, method (ClientAuthType) String() string
+pkg crypto/tls, method (CurveID) String() string
+pkg crypto/tls, method (SignatureScheme) String() string
+pkg crypto/tls, type Config struct, VerifyConnection func(ConnectionState) error
+pkg crypto/tls, type Dialer struct
+pkg crypto/tls, type Dialer struct, Config *Config
+pkg crypto/tls, type Dialer struct, NetDialer *net.Dialer
+pkg crypto/x509, func CreateRevocationList(io.Reader, *RevocationList, *Certificate, crypto.Signer) ([]uint8, error)
+pkg crypto/x509, type RevocationList struct
+pkg crypto/x509, type RevocationList struct, ExtraExtensions []pkix.Extension
+pkg crypto/x509, type RevocationList struct, NextUpdate time.Time
+pkg crypto/x509, type RevocationList struct, Number *big.Int
+pkg crypto/x509, type RevocationList struct, RevokedCertificates []pkix.RevokedCertificate
+pkg crypto/x509, type RevocationList struct, SignatureAlgorithm SignatureAlgorithm
+pkg crypto/x509, type RevocationList struct, ThisUpdate time.Time
+pkg database/sql, method (*DB) SetConnMaxIdleTime(time.Duration)
+pkg database/sql, method (*Row) Err() error
+pkg database/sql, type DBStats struct, MaxIdleTimeClosed int64
+pkg database/sql/driver, type Validator interface { IsValid }
+pkg database/sql/driver, type Validator interface, IsValid() bool
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_APPCONTAINER = 4096
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_APPCONTAINER ideal-int
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 64
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE ideal-int
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = 128
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY ideal-int
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_GUARD_CF = 16384
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_GUARD_CF ideal-int
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA = 32
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA ideal-int
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_NO_BIND = 2048
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_NO_BIND ideal-int
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 512
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_NO_ISOLATION ideal-int
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_NO_SEH = 1024
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_NO_SEH ideal-int
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 256
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_NX_COMPAT ideal-int
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 32768
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE ideal-int
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 8192
+pkg debug/pe, const IMAGE_DLLCHARACTERISTICS_WDM_DRIVER ideal-int
+pkg debug/pe, const IMAGE_FILE_32BIT_MACHINE = 256
+pkg debug/pe, const IMAGE_FILE_32BIT_MACHINE ideal-int
+pkg debug/pe, const IMAGE_FILE_AGGRESIVE_WS_TRIM = 16
+pkg debug/pe, const IMAGE_FILE_AGGRESIVE_WS_TRIM ideal-int
+pkg debug/pe, const IMAGE_FILE_BYTES_REVERSED_HI = 32768
+pkg debug/pe, const IMAGE_FILE_BYTES_REVERSED_HI ideal-int
+pkg debug/pe, const IMAGE_FILE_BYTES_REVERSED_LO = 128
+pkg debug/pe, const IMAGE_FILE_BYTES_REVERSED_LO ideal-int
+pkg debug/pe, const IMAGE_FILE_DEBUG_STRIPPED = 512
+pkg debug/pe, const IMAGE_FILE_DEBUG_STRIPPED ideal-int
+pkg debug/pe, const IMAGE_FILE_DLL = 8192
+pkg debug/pe, const IMAGE_FILE_DLL ideal-int
+pkg debug/pe, const IMAGE_FILE_EXECUTABLE_IMAGE = 2
+pkg debug/pe, const IMAGE_FILE_EXECUTABLE_IMAGE ideal-int
+pkg debug/pe, const IMAGE_FILE_LARGE_ADDRESS_AWARE = 32
+pkg debug/pe, const IMAGE_FILE_LARGE_ADDRESS_AWARE ideal-int
+pkg debug/pe, const IMAGE_FILE_LINE_NUMS_STRIPPED = 4
+pkg debug/pe, const IMAGE_FILE_LINE_NUMS_STRIPPED ideal-int
+pkg debug/pe, const IMAGE_FILE_LOCAL_SYMS_STRIPPED = 8
+pkg debug/pe, const IMAGE_FILE_LOCAL_SYMS_STRIPPED ideal-int
+pkg debug/pe, const IMAGE_FILE_NET_RUN_FROM_SWAP = 2048
+pkg debug/pe, const IMAGE_FILE_NET_RUN_FROM_SWAP ideal-int
+pkg debug/pe, const IMAGE_FILE_RELOCS_STRIPPED = 1
+pkg debug/pe, const IMAGE_FILE_RELOCS_STRIPPED ideal-int
+pkg debug/pe, const IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 1024
+pkg debug/pe, const IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP ideal-int
+pkg debug/pe, const IMAGE_FILE_SYSTEM = 4096
+pkg debug/pe, const IMAGE_FILE_SYSTEM ideal-int
+pkg debug/pe, const IMAGE_FILE_UP_SYSTEM_ONLY = 16384
+pkg debug/pe, const IMAGE_FILE_UP_SYSTEM_ONLY ideal-int
+pkg debug/pe, const IMAGE_SUBSYSTEM_EFI_APPLICATION = 10
+pkg debug/pe, const IMAGE_SUBSYSTEM_EFI_APPLICATION ideal-int
+pkg debug/pe, const IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11
+pkg debug/pe, const IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER ideal-int
+pkg debug/pe, const IMAGE_SUBSYSTEM_EFI_ROM = 13
+pkg debug/pe, const IMAGE_SUBSYSTEM_EFI_ROM ideal-int
+pkg debug/pe, const IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12
+pkg debug/pe, const IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER ideal-int
+pkg debug/pe, const IMAGE_SUBSYSTEM_NATIVE = 1
+pkg debug/pe, const IMAGE_SUBSYSTEM_NATIVE ideal-int
+pkg debug/pe, const IMAGE_SUBSYSTEM_NATIVE_WINDOWS = 8
+pkg debug/pe, const IMAGE_SUBSYSTEM_NATIVE_WINDOWS ideal-int
+pkg debug/pe, const IMAGE_SUBSYSTEM_OS2_CUI = 5
+pkg debug/pe, const IMAGE_SUBSYSTEM_OS2_CUI ideal-int
+pkg debug/pe, const IMAGE_SUBSYSTEM_POSIX_CUI = 7
+pkg debug/pe, const IMAGE_SUBSYSTEM_POSIX_CUI ideal-int
+pkg debug/pe, const IMAGE_SUBSYSTEM_UNKNOWN = 0
+pkg debug/pe, const IMAGE_SUBSYSTEM_UNKNOWN ideal-int
+pkg debug/pe, const IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16
+pkg debug/pe, const IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION ideal-int
+pkg debug/pe, const IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9
+pkg debug/pe, const IMAGE_SUBSYSTEM_WINDOWS_CE_GUI ideal-int
+pkg debug/pe, const IMAGE_SUBSYSTEM_WINDOWS_CUI = 3
+pkg debug/pe, const IMAGE_SUBSYSTEM_WINDOWS_CUI ideal-int
+pkg debug/pe, const IMAGE_SUBSYSTEM_WINDOWS_GUI = 2
+pkg debug/pe, const IMAGE_SUBSYSTEM_WINDOWS_GUI ideal-int
+pkg debug/pe, const IMAGE_SUBSYSTEM_XBOX = 14
+pkg debug/pe, const IMAGE_SUBSYSTEM_XBOX ideal-int
+pkg go/printer, const StdFormat = 16
+pkg go/printer, const StdFormat Mode
+pkg math/big, method (*Int) FillBytes([]uint8) []uint8
+pkg net, method (*Resolver) LookupIP(context.Context, string, string) ([]IP, error)
+pkg net/url, method (*URL) EscapedFragment() string
+pkg net/url, method (*URL) Redacted() string
+pkg net/url, type URL struct, RawFragment string
+pkg os, method (*File) ReadFrom(io.Reader) (int64, error)
+pkg os, var ErrDeadlineExceeded error
+pkg regexp, method (*Regexp) SubexpIndex(string) int
+pkg strconv, func FormatComplex(complex128, uint8, int, int) string
+pkg strconv, func ParseComplex(string, int) (complex128, error)
+pkg sync, method (*Map) LoadAndDelete(interface{}) (interface{}, bool)
+pkg testing, method (*B) TempDir() string
+pkg testing, method (*T) Deadline() (time.Time, bool)
+pkg testing, method (*T) TempDir() string
+pkg testing, type TB interface, TempDir() string
+pkg time, method (*Ticker) Reset(Duration)
diff --git a/api/next.txt b/api/next.txt
index 442c29a..e69de29 100644
--- a/api/next.txt
+++ b/api/next.txt
@@ -1,3 +0,0 @@
-pkg testing, method (*T) Deadline() (time.Time, bool)
-pkg time, method (*Ticker) Reset(Duration)
-pkg sync, method (*Map) LoadAndDelete(interface{}) (interface{}, bool)
diff --git a/doc/go1.10.html b/doc/go1.10.html
index 41db36a..853f874 100644
--- a/doc/go1.10.html
+++ b/doc/go1.10.html
@@ -30,7 +30,7 @@
runs <a href="#test-vet">vet automatically during tests</a>,
and
permits <a href="#cgo">passing string values directly between Go and C using cgo</a>.
-A new <a href="#cgo">compiler option whitelist</a> may cause
+A new <a href="#cgo">hard-coded set of safe compiler options</a> may cause
unexpected <a href="https://golang.org/s/invalidflag"><code>invalid
flag</code></a> errors in code that built successfully with older
releases.
@@ -267,7 +267,7 @@
<p>
Options specified by cgo using <code>#cgo CFLAGS</code> and the like
-are now checked against a whitelist of permitted options.
+are now checked against a list of permitted options.
This closes a security hole in which a downloaded package uses
compiler options like
<span style="white-space: nowrap"><code>-fplugin</code></span>
diff --git a/doc/go1.15.html b/doc/go1.15.html
index 492cac0..dd25b27 100644
--- a/doc/go1.15.html
+++ b/doc/go1.15.html
@@ -55,6 +55,13 @@
on Windows.
</p>
+<p><!-- CL 227003 -->
+ The <code>-race</code> and <code>-msan</code> flags now always
+ enable <code>-d=checkptr</code>, which checks uses
+ of <code>unsafe.Pointer</code>. This was previously the case on all
+ OSes except Windows.
+</p>
+
<p><!-- CL 211139 -->
Go-built DLLs no longer cause the process to exit when it receives a
signal (such as Ctrl-C at a terminal).
@@ -211,10 +218,24 @@
<h2 id="runtime">Runtime</h2>
-<p><!-- CL 232862 -->
- Go now retries system calls that return <code>EINTR</code>. This
- became more common in Go 1.14 with the addition of asynchronous
- preemption, but is now handled transparently.
+<p><!-- CL 221779 -->
+ If <code>panic</code> is invoked with a value whose type is derived from any
+ of: <code>bool</code>, <code>complex64</code>, <code>complex128</code>, <code>float32</code>, <code>float64</code>,
+ <code>int</code>, <code>int8</code>, <code>int16</code>, <code>int32</code>, <code>int64</code>, <code>string</code>,
+ <code>uint</code>, <code>uint8</code>, <code>uint16</code>, <code>uint32</code>, <code>uint64</code>, <code>uintptr</code>,
+ then the value will be printed, instead of just its address.
+ Previously, this was only true for values of exactly these types.
+</p>
+
+<p><!-- CL 228900 -->
+ On a Unix system, if the <code>kill</code> command
+ or <code>kill</code> system call is used to send
+ a <code>SIGSEGV</code>, <code>SIGBUS</code>,
+ or <code>SIGFPE</code> signal to a Go program, and if the signal
+ is not being handled via
+ <a href="/pkg/os/signal/#Notify"><code>os/signal.Notify</code></a>,
+ the Go program will now reliably crash with a stack trace.
+ In earlier releases the behavior was unpredictable.
</p>
<p><!-- CL 221182, CL 229998 -->
@@ -222,8 +243,14 @@
counts, and has lower worst-case latency.
</p>
-<p>
-TODO
+<p><!-- CL 216401 -->
+ Converting a small integer value into an interface value no longer
+ causes allocation.
+</p>
+
+<p><!-- CL 216818 -->
+ Non-blocking receives on closed channels now perform as well as
+ non-blocking receives on open channels.
</p>
<h2 id="compiler">Compiler</h2>
@@ -245,6 +272,15 @@
aggressively eliminating unused type metadata.
</p>
+<p><!-- CL 219357, CL 231600 -->
+ The toolchain now mitigates
+ <a href="https://www.intel.com/content/www/us/en/support/articles/000055650/processors.html">Intel
+ CPU erratum SKX102</a> on <code>GOARCH=amd64</code> by aligning
+ functions to 32 byte boundaries and padding jump instructions. While
+ this padding increases binary sizes, this is more than made up for
+ by the binary size improvements mentioned above.
+</p>
+
<p><!-- CL 222661 -->
Go 1.15 adds a <code>-spectre</code> flag to both the
compiler and the assembler, to allow enabling Spectre mitigations.
@@ -253,6 +289,19 @@
See the <a href="https://github.com/golang/go/wiki/Spectre">Spectre wiki page</a> for details.
</p>
+<p><!-- CL 228578 -->
+ The compiler now rejects <code>//go:</code> compiler directives that
+ have no meaning for the declaration they are applied to with a
+ "misplaced compiler directive" error. Such misapplied directives
+ were broken before, but were silently ignored by the compiler.
+</p>
+
+<p><!-- CL 206658, CL 205066 -->
+ The compiler's <code>-json</code> optimization logging now reports
+ large (>= 128 byte) copies and includes explanations of escape
+ analysis decisions.
+</p>
+
<h2 id="linker">Linker</h2>
<p>
@@ -283,6 +332,14 @@
improvements expected in future releases.
</p>
+<h2 id="objdump">Objdump</h2>
+
+<p><!-- CL 225459 -->
+ The <a href="/cmd/objdump/">objdump</a> tool now supports
+ disassembling in GNU assembler syntax with the <code>-gnu</code>
+ flag.
+</p>
+
<h2 id="library">Core library</h2>
<h3 id="time/tzdata">New embedded tzdata package</h3>
@@ -299,10 +356,6 @@
Either approach increases the size of the program by about 800 KB.
</p>
-<p>
-TODO
-</p>
-
<h3 id="cgo">Cgo</h3>
<p><!-- CL 235817 -->
@@ -321,10 +374,6 @@
in mind.
</p>
-<p>
-TODO
-</p>
-
<dl id="debug/pe"><dt><a href="/pkg/debug/pe/">debug/pe</a></dt>
<dd>
<p><!-- CL 222637 -->
@@ -336,10 +385,53 @@
</dd>
</dl><!-- debug/pe -->
+<dl id="crypto"><dt><a href="/pkg/crypto/">crypto</a></dt>
+ <dd>
+ <p><!-- CL 231417, CL 225460 -->
+ The <code>PrivateKey</code> and <code>PublicKey</code> types in the
+ <a href="/pkg/crypto/rsa"><code>crypto/rsa</code></a>,
+ <a href="/pkg/crypto/ecdsa"><code>crypto/ecdsa</code></a>, and
+ <a href="/pkg/crypto/ed25519"><code>crypto/ed25519</code></a> packages
+ now have an <code>Equal</code> method to compare keys for equivalence
+ or to make type-safe interfaces for public keys. The method signature
+ is compatible with
+ <a href="https://pkg.go.dev/github.com/google/go-cmp/cmp#Equal"><code>go-cmp</code>'s
+ definition of equality</a>.
+ </p>
+
+ <p><!-- CL 224937 -->
+ <a href="/pkg/crypto/#Hash"><code>Hash</code></a> now implements
+ <a href="/pkg/fmt/#Stringer"><code>fmt.Stringer</code></a>.
+ </p>
+ </dd>
+</dl><!-- crypto -->
+
+<dl id="crypto/ecdsa"><dt><a href="/pkg/crypto/ecdsa/">crypto/ecdsa</a></dt>
+ <dd>
+ <p><!-- CL 217940 -->
+ The new <a href="/pkg/crypto/ecdsa/#SignASN1"><code>SignASN1</code></a>
+ and <a href="/pkg/crypto/ecdsa/#VerifyASN1"><code>VerifyASN1</code></a>
+ functions allow generating and verifying ECDSA signatures in the standard
+ ASN.1 DER encoding.
+ </p>
+ </dd>
+</dl><!-- crypto/ecdsa -->
+
+<dl id="crypto/elliptic"><dt><a href="/pkg/crypto/elliptic/">crypto/elliptic</a></dt>
+ <dd>
+ <p><!-- CL 202819 -->
+ The new <a href="/pkg/crypto/elliptic/#MarshalCompressed"><code>MarshalCompressed</code></a>
+ and <a href="/pkg/crypto/elliptic/#UnmarshalCompressed"><code>UnmarshalCompressed</code></a>
+ functions allow encoding and decoding NIST elliptic curve points in compressed format.
+ </p>
+ </dd>
+</dl><!-- crypto/elliptic -->
+
<dl id="crypto/rsa"><dt><a href="/pkg/crypto/rsa/">crypto/rsa</a></dt>
<dd>
<p><!-- CL 226203 -->
- VerifyPKCS1v15 now rejects invalid short signatures with missing leading zeroes.
+ <a href="/pkg/crypto/rsa/#VerifyPKCS1v15"><code>VerifyPKCS1v15</code></a>
+ now rejects invalid short signatures with missing leading zeroes, according to RFC 8017.
</p>
</dd>
</dl><!-- crypto/rsa -->
@@ -353,21 +445,137 @@
<a href="/pkg/crypto/tls/#Dialer.DialContext"><code>DialContext</code></a>
method permits using a context to both connect and handshake with a TLS server.
</p>
+
+ <p><!-- CL 229122 -->
+ The new
+ <a href="/pkg/crypto/tls/#Config.VerifyConnection"><code>VerifyConnection</code></a>
+ callback on the <a href="/pkg/crypto/tls/#Config"><code>Config</code></a> type
+ allows custom verification logic for every connection. It has access to the
+ <a href="/pkg/crypto/tls/#ConnectionState"><code>ConnectionState</code></a>
+ which includes peer certificates, SCTs, and stapled OCSP responses.
+ </p>
+
+ <p><!-- CL 230679 -->
+ Auto-generated session ticket keys are now automatically rotated every 24 hours,
+ with a lifetime of 7 days, to limit their impact on forward secrecy.
+ </p>
+
+ <p><!-- CL 231317 -->
+ Session ticket lifetimes in TLS 1.2 and earlier, where the session keys
+ are reused for resumed connections, are now limited to 7 days, also to
+ limit their impact on forward secrecy.
+ </p>
+
+ <p><!-- CL 231038 -->
+ The client-side downgrade protection checks specified in RFC 8446 are now
+ enforced. This has the potential to cause connection errors for clients
+ encountering middleboxes that behave like unauthorized downgrade attacks.
+ </p>
+
+ <p><!-- CL 208226 -->
+ <a href="/pkg/crypto/tls/#SignatureScheme"><code>SignatureScheme</code></a>,
+ <a href="/pkg/crypto/tls/#CurveID"><code>CurveID</code></a>, and
+ <a href="/pkg/crypto/tls/#ClientAuthType"><code>ClientAuthType</code></a>
+ now implement <a href="/pkg/fmt/#Stringer"><code>fmt.Stringer</code></a>.
+ </p>
+
+ <p><!-- CL 236737 -->
+ The <a href="/pkg/crypto/tls/#ConnectionState"><code>ConnectionState</code></a>
+ fields <code>OCSPResponse</code> and <code>SignedCertificateTimestamps</code>
+ are now repopulated on client-side resumed connections.
+ </p>
</dd>
-</dl>
+</dl><!-- crypto/tls -->
<dl id="crypto/x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt>
<dd>
+ <p><!-- CL 231378, CL 231380, CL 231381 -->
+ If either the name on the certificate or the name being verified (with
+ <a href="/pkg/crypto/x509/#VerifyOptions.DNSName"><code>VerifyOptions.DNSName</code></a>
+ or <a href="/pkg/crypto/x509/#Certificate.VerifyHostname"><code>VerifyHostname</code></a>)
+ are invalid, they will now be compared case-insensitively without further
+ processing (without honoring wildcards or stripping trailing dots).
+ Invalid names include those with any characters other than letters,
+ digits, hyphens and underscores, those with empty labels, and names on
+ certificates with trailing dots.
+ </p>
+
+ <p><!-- CL 231379 -->
+ The deprecated, legacy behavior of treating the <code>CommonName</code>
+ field as a hostname when no Subject Alternative Names are present is now
+ disabled by default. It can be temporarily re-enabled by adding the value
+ <code>x509ignoreCN=0</code> to the <code>GODEBUG</code> environment
+ variable. If the <code>CommonName</code> is an invalid hostname, it's
+ always ignored.
+ </p>
+
+ <p><!-- CL 217298 -->
+ The new <a href="/pkg/crypto/x509/#CreateRevocationList"><code>CreateRevocationList</code></a>
+ function and <a href="/pkg/crypto/x509/#RevocationList"><code>RevocationList</code></a> type
+ allow creating RFC 5280-compliant X.509 v2 Certificate Revocation Lists.
+ </p>
+
+ <p><!-- CL 227098 -->
+ <a href="/pkg/crypto/x509/#CreateCertificate"><code>CreateCertificate</code></a>
+ now automatically generates the <code>SubjectKeyId</code> if the template
+ is a CA and doesn't explicitly specify one.
+ </p>
+
+ <p><!-- CL 228777 -->
+ <a href="/pkg/crypto/x509/#CreateCertificate"><code>CreateCertificate</code></a>
+ now returns an error if the template specifies <code>MaxPathLen</code> but is not a CA.
+ </p>
+
<p><!-- CL 205237 -->
- TODO: <a href="https://golang.org/cl/205237">https://golang.org/cl/205237</a>: load roots from colon separated SSL_CERT_DIR in loadSystemRoots
+ On Unix systems other than macOS, the <code>SSL_CERT_DIR</code>
+ environment variable can now be a colon-separated list.
+ </p>
+
+ <p><!-- CL 227037 -->
+ On macOS, binaries are now always linked against
+ <code>Security.framework</code> to extract the system trust roots,
+ regardless of whether cgo is available. The resulting behavior should be
+ more consistent with the OS verifier.
</p>
</dd>
</dl><!-- crypto/x509 -->
+<dl id="crypto/x509/pkix"><dt><a href="/pkg/crypto/x509/pkix/">crypto/x509/pkix</a></dt>
+ <dd>
+ <p><!-- CL 229864 -->
+ <a href="/pkg/crypto/x509/pkix/#Name.String"><code>Name.String</code></a>
+ now prints non-standard attributes from
+ <a href="/pkg/crypto/x509/pkix/#Name.Names"><code>Names</code></a> if
+ <a href="/pkg/crypto/x509/pkix/#Name.ExtraNames"><code>ExtraNames</code></a> is empty.
+ </p>
+ </dd>
+</dl><!-- crypto/x509/pkix -->
+
+<dl id="encoding/json"><dt><a href="/pkg/encoding/json/">encoding/json</a></dt>
+ <dd>
+ <p><!-- CL 191783 -->
+ Decoding a JSON array into a slice no longer reuses any existing slice elements,
+ following the rules that the package documentation already stated.
+ </p>
+
+ <p><!-- CL 199837 -->
+ Introduce an internal limit to the maximum depth of nesting when decoding.
+ This reduces the possibility that a deeply nested input could use large quantities
+ of stack memory, or even cause a "goroutine stack exceeds limit" panic.
+ </p>
+ </dd>
+</dl><!-- encoding/json -->
+
<dl id="encoding/xml"><dt><a href="/pkg/encoding/xml/">encoding/xml</a></dt>
<dd>
<p><!-- CL 203417 -->
- TODO: <a href="https://golang.org/cl/203417">https://golang.org/cl/203417</a>: fix reserved namespace check to be case-insensitive
+ The encoder has always taken care to avoid using namespace prefixes beginning with
+ <code>xml</code>,
+ which are reserved by the XML specification.
+ Now, following the specification more closely,
+ that check is case-insensitive, so that prefixes beginning with
+ <code>XML</code>, <code>XmL</code>,
+ and so on are also avoided.
</p>
</dd>
</dl><!-- encoding/xml -->
@@ -390,7 +598,8 @@
<dl id="fmt"><dt><a href="/pkg/fmt/">fmt</a></dt>
<dd>
<p><!-- CL 215001 -->
- TODO: <a href="https://golang.org/cl/215001">https://golang.org/cl/215001</a>: do not remove trailing zeros for %g and %G with #(sharp) flag
+ The printing verbs <code>%#g</code> and <code>%#G</code> now preserve
+ trailing zeros for floating-point values.
</p>
</dd>
</dl><!-- fmt -->
@@ -410,7 +619,8 @@
<dl id="math/big"><dt><a href="/pkg/math/big/">math/big</a></dt>
<dd>
<p><!-- CL 230397 -->
- TODO: <a href="https://golang.org/cl/230397">https://golang.org/cl/230397</a>: add (*Int).FillBytes
+ The new <a href="/pkg/math/big/#Int.FillBytes"><code>Int.FillBytes</code></a>
+ method allows serializing to fixed-size pre-allocated byte slices.
</p>
</dd>
</dl><!-- math/big -->
@@ -441,8 +651,10 @@
<dl id="net/http"><dt><a href="/pkg/net/http/">net/http</a></dt>
<dd>
- <p><!-- CL 231418 -->
- TODO: <a href="https://golang.org/cl/231418">https://golang.org/cl/231418</a>: only support "chunked" in inbound Transfer-Encoding headers
+ <p><!-- CL 231418, CL 231419 -->
+ Parsing is now stricter as a hardening measure against request smuggling attacks:
+ non-ASCII white space is no longer trimmed like SP and HTAB, and support for the
+ "<code>identity</code>" <code>Transfer-Encoding</code> was dropped.
</p>
</dd>
</dl><!-- net/http -->
@@ -457,7 +669,9 @@
</p>
<p><!-- CL 224897 -->
- TODO: <a href="https://golang.org/cl/224897">https://golang.org/cl/224897</a>: make Switching Protocol requests (e.g. Websockets) cancelable
+ When a Switching Protocol (like WebSocket) request handled by
+ <a href="/pkg/net/http/httputil/#ReverseProxy"><code>ReverseProxy</code></a>
+ is canceled, the backend connection is now correctly closed.
</p>
</dd>
</dl>
@@ -506,6 +720,14 @@
which <code>Timeout</code> returns <code>true</code> although a
deadline has not been exceeded.
</p>
+
+ <p><!-- CL 232862 -->
+ Packages <code>os</code> and <code>net</code> now automatically
+ retry system calls that fail with <code>EINTR</code>. Previously
+ this led to spurious failures, which became more common in Go
+ 1.14 with the addition of asynchronous preemption. Now this is
+ handled transparently.
+ </p>
</dd>
</dl>
@@ -525,7 +747,7 @@
<dl id="reflect"><dt><a href="/pkg/reflect/">reflect</a></dt>
<dd>
<p><!-- CL 228902 -->
- Package reflect now disallows accessing methods of all
+ Package <code>reflect</code> now disallows accessing methods of all
non-exported fields, whereas previously it allowed accessing
those of non-exported, embedded fields. Code that relies on the
previous behavior should be updated to instead access the
@@ -546,26 +768,6 @@
<dl id="pkg-runtime"><dt><a href="/pkg/runtime/">runtime</a></dt>
<dd>
- <p><!-- CL 221779 -->
- If <code>panic</code> is invoked with a value whose type is derived from any
- of: <code>bool</code>, <code>complex64</code>, <code>complex128</code>, <code>float32</code>, <code>float64</code>,
- <code>int</code>, <code>int8</code>, <code>int16</code>, <code>int32</code>, <code>int64</code>, <code>string</code>,
- <code>uint</code>, <code>uint8</code>, <code>uint16</code>, <code>uint32</code>, <code>uint64</code>, <code>uintptr</code>,
- then the value will be printed, instead of just its address.
- Previously, this was only true for values of exactly these types.
- </p>
-
- <p><!-- CL -->
- On a Unix system, if the <code>kill</code> command
- or <code>kill</code> system call is used to send
- a <code>SIGSEGV</code>, <code>SIGBUS</code>,
- or <code>SIGFPE</code> signal to a Go program, and if the signal
- is not being handled via
- <a href="/pkg/os/signal/#Notify"><code>os/signal.Notify</code></a>,
- the Go program will now reliably crash with a stack trace.
- In earlier releases the behavior was unpredictable.
- </p>
-
<p><!-- CL 216557 -->
Several functions, including
<a href="/pkg/runtime/#ReadMemStats"><code>ReadMemStats</code></a>
@@ -573,16 +775,6 @@
<a href="/pkg/runtime/#GoroutineProfile"><code>GoroutineProfile</code></a>,
no longer block if a garbage collection is in progress.
</p>
-
- <p><!-- CL 216401 -->
- Converting small integer values into an interface value no
- longer causes allocation.
- </p>
-
- <p><!-- CL 216818 -->
- Non-blocking receives on closed channels now perform as well as
- non-blocking receives on open channels.
- </p>
</dd>
</dl>
diff --git a/src/all.bat b/src/all.bat
index 8bbd6b1..ae835d9 100644
--- a/src/all.bat
+++ b/src/all.bat
@@ -1,27 +1,27 @@
-:: Copyright 2012 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.
-
-@echo off
-
-setlocal
-
-if exist make.bat goto ok
-echo all.bat must be run from go\src
-:: cannot exit: would kill parent command interpreter
-goto end
-:ok
-
-set OLDPATH=%PATH%
-call make.bat --no-banner --no-local
-if %GOBUILDFAIL%==1 goto end
-call run.bat --no-rebuild --no-local
-if %GOBUILDFAIL%==1 goto end
-:: we must restore %PATH% before running "dist banner" so that the latter
-:: can get the original %PATH% and give suggestion to add %GOROOT%/bin
-:: to %PATH% if necessary.
-set PATH=%OLDPATH%
-"%GOTOOLDIR%/dist" banner
-
-:end
-if x%GOBUILDEXIT%==x1 exit %GOBUILDFAIL%
+:: Copyright 2012 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.
+
+@echo off
+
+setlocal
+
+if exist make.bat goto ok
+echo all.bat must be run from go\src
+:: cannot exit: would kill parent command interpreter
+goto end
+:ok
+
+set OLDPATH=%PATH%
+call make.bat --no-banner --no-local
+if %GOBUILDFAIL%==1 goto end
+call run.bat --no-rebuild --no-local
+if %GOBUILDFAIL%==1 goto end
+:: we must restore %PATH% before running "dist banner" so that the latter
+:: can get the original %PATH% and give suggestion to add %GOROOT%/bin
+:: to %PATH% if necessary.
+set PATH=%OLDPATH%
+"%GOTOOLDIR%/dist" banner
+
+:end
+if x%GOBUILDEXIT%==x1 exit %GOBUILDFAIL%
diff --git a/src/clean.bat b/src/clean.bat
index 0954dcd..c957353 100644
--- a/src/clean.bat
+++ b/src/clean.bat
@@ -1,32 +1,32 @@
-:: Copyright 2012 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.
-
-@echo off
-
-setlocal
-
-set GOBUILDFAIL=0
-
-go tool dist env -w -p >env.bat
-if errorlevel 1 goto fail
-call env.bat
-del env.bat
-echo.
-
-if exist %GOTOOLDIR%\dist.exe goto distok
-echo cannot find %GOTOOLDIR%\dist; nothing to clean
-goto fail
-:distok
-
-"%GOBIN%\go" clean -i std
-"%GOBIN%\go" tool dist clean
-"%GOBIN%\go" clean -i cmd
-
-goto end
-
-:fail
-set GOBUILDFAIL=1
-
-:end
-if x%GOBUILDEXIT%==x1 exit %GOBUILDFAIL%
+:: Copyright 2012 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.
+
+@echo off
+
+setlocal
+
+set GOBUILDFAIL=0
+
+go tool dist env -w -p >env.bat
+if errorlevel 1 goto fail
+call env.bat
+del env.bat
+echo.
+
+if exist %GOTOOLDIR%\dist.exe goto distok
+echo cannot find %GOTOOLDIR%\dist; nothing to clean
+goto fail
+:distok
+
+"%GOBIN%\go" clean -i std
+"%GOBIN%\go" tool dist clean
+"%GOBIN%\go" clean -i cmd
+
+goto end
+
+:fail
+set GOBUILDFAIL=1
+
+:end
+if x%GOBUILDEXIT%==x1 exit %GOBUILDFAIL%
diff --git a/src/cmd/addr2line/addr2line_test.go b/src/cmd/addr2line/addr2line_test.go
index 22bf137..578d88e 100644
--- a/src/cmd/addr2line/addr2line_test.go
+++ b/src/cmd/addr2line/addr2line_test.go
@@ -73,19 +73,29 @@
if err != nil {
t.Fatalf("Stat failed: %v", err)
}
+ // Debug paths are stored slash-separated, so convert to system-native.
+ srcPath = filepath.FromSlash(srcPath)
fi2, err := os.Stat(srcPath)
+ if gorootFinal := os.Getenv("GOROOT_FINAL"); gorootFinal != "" && strings.HasPrefix(srcPath, gorootFinal) {
+ if os.IsNotExist(err) || (err == nil && !os.SameFile(fi1, fi2)) {
+ // srcPath has had GOROOT_FINAL substituted for GOROOT, and it doesn't
+ // match the actual file. GOROOT probably hasn't been moved to its final
+ // location yet, so try the original location instead.
+ fi2, err = os.Stat(runtime.GOROOT() + strings.TrimPrefix(srcPath, gorootFinal))
+ }
+ }
if err != nil {
t.Fatalf("Stat failed: %v", err)
}
if !os.SameFile(fi1, fi2) {
t.Fatalf("addr2line_test.go and %s are not same file", srcPath)
}
- if srcLineNo != "89" {
- t.Fatalf("line number = %v; want 89", srcLineNo)
+ if srcLineNo != "99" {
+ t.Fatalf("line number = %v; want 99", srcLineNo)
}
}
-// This is line 88. The test depends on that.
+// This is line 98. The test depends on that.
func TestAddr2Line(t *testing.T) {
testenv.MustHaveGoBuild(t)
diff --git a/src/cmd/asm/internal/asm/testdata/arm64enc.s b/src/cmd/asm/internal/asm/testdata/arm64enc.s
index a483c73..56cf51c 100644
--- a/src/cmd/asm/internal/asm/testdata/arm64enc.s
+++ b/src/cmd/asm/internal/asm/testdata/arm64enc.s
@@ -420,6 +420,7 @@
UXTBW R2, R6 // 461c0053
UXTHW R7, R20 // f43c0053
VCNT V0.B8, V0.B8 // 0058200e
+ VCNT V0.B16, V0.B16 // 0058204e
WFE // 5f2003d5
WFI // 7f2003d5
YIELD // 3f2003d5
diff --git a/src/cmd/cgo/doc.go b/src/cmd/cgo/doc.go
index 4366df4..ca18c45 100644
--- a/src/cmd/cgo/doc.go
+++ b/src/cmd/cgo/doc.go
@@ -990,7 +990,7 @@
linker in external linking mode.
By default, cmd/link will decide the linking mode as follows: if the only
-packages using cgo are those on a whitelist of standard library
+packages using cgo are those on a list of known standard library
packages (net, os/user, runtime/cgo), cmd/link will use internal linking
mode. Otherwise, there are non-standard cgo packages involved, and cmd/link
will use external linking mode. The first rule means that a build of
diff --git a/src/cmd/compile/fmt_test.go b/src/cmd/compile/fmt_test.go
index f1af647..e372259 100644
--- a/src/cmd/compile/fmt_test.go
+++ b/src/cmd/compile/fmt_test.go
@@ -96,7 +96,7 @@
}
importPath := filepath.Join("cmd/compile", path)
- if blacklistedPackages[filepath.ToSlash(importPath)] {
+ if ignoredPackages[filepath.ToSlash(importPath)] {
return filepath.SkipDir
}
@@ -344,8 +344,7 @@
for index, file := range files {
ast.Inspect(file, func(n ast.Node) bool {
if call, ok := n.(*ast.CallExpr); ok {
- // ignore blacklisted functions
- if blacklistedFunctions[nodeString(call.Fun)] {
+ if ignoredFunctions[nodeString(call.Fun)] {
return true
}
// look for an arguments that might be a format string
@@ -354,7 +353,7 @@
// make sure we have enough arguments
n := numFormatArgs(s)
if i+1+n > len(call.Args) {
- t.Errorf("%s: not enough format args (blacklist %s?)", posString(call), nodeString(call.Fun))
+ t.Errorf("%s: not enough format args (ignore %s?)", posString(call), nodeString(call.Fun))
break // ignore this call
}
// assume last n arguments are to be formatted;
@@ -549,14 +548,14 @@
return string(append(buf, in[i0:]...))
}
-// blacklistedPackages is the set of packages which can
+// ignoredPackages is the set of packages which can
// be ignored.
-var blacklistedPackages = map[string]bool{}
+var ignoredPackages = map[string]bool{}
-// blacklistedFunctions is the set of functions which may have
+// ignoredFunctions is the set of functions which may have
// format-like arguments but which don't do any formatting and
// thus may be ignored.
-var blacklistedFunctions = map[string]bool{}
+var ignoredFunctions = map[string]bool{}
func init() {
// verify that knownFormats entries are correctly formatted
diff --git a/src/cmd/compile/fmtmap_test.go b/src/cmd/compile/fmtmap_test.go
index 6f69abf..cb7a7d9 100644
--- a/src/cmd/compile/fmtmap_test.go
+++ b/src/cmd/compile/fmtmap_test.go
@@ -140,6 +140,7 @@
"float64 %.3f": "",
"float64 %.6g": "",
"float64 %g": "",
+ "int %#x": "",
"int %-12d": "",
"int %-6d": "",
"int %-8o": "",
@@ -203,6 +204,7 @@
"uint64 %b": "",
"uint64 %d": "",
"uint64 %x": "",
+ "uint8 %#x": "",
"uint8 %d": "",
"uint8 %v": "",
"uint8 %x": "",
diff --git a/src/cmd/compile/internal/arm/ssa.go b/src/cmd/compile/internal/arm/ssa.go
index 9935616..1da72aa 100644
--- a/src/cmd/compile/internal/arm/ssa.go
+++ b/src/cmd/compile/internal/arm/ssa.go
@@ -888,16 +888,30 @@
var blockJump = map[ssa.BlockKind]struct {
asm, invasm obj.As
}{
- ssa.BlockARMEQ: {arm.ABEQ, arm.ABNE},
- ssa.BlockARMNE: {arm.ABNE, arm.ABEQ},
- ssa.BlockARMLT: {arm.ABLT, arm.ABGE},
- ssa.BlockARMGE: {arm.ABGE, arm.ABLT},
- ssa.BlockARMLE: {arm.ABLE, arm.ABGT},
- ssa.BlockARMGT: {arm.ABGT, arm.ABLE},
- ssa.BlockARMULT: {arm.ABLO, arm.ABHS},
- ssa.BlockARMUGE: {arm.ABHS, arm.ABLO},
- ssa.BlockARMUGT: {arm.ABHI, arm.ABLS},
- ssa.BlockARMULE: {arm.ABLS, arm.ABHI},
+ ssa.BlockARMEQ: {arm.ABEQ, arm.ABNE},
+ ssa.BlockARMNE: {arm.ABNE, arm.ABEQ},
+ ssa.BlockARMLT: {arm.ABLT, arm.ABGE},
+ ssa.BlockARMGE: {arm.ABGE, arm.ABLT},
+ ssa.BlockARMLE: {arm.ABLE, arm.ABGT},
+ ssa.BlockARMGT: {arm.ABGT, arm.ABLE},
+ ssa.BlockARMULT: {arm.ABLO, arm.ABHS},
+ ssa.BlockARMUGE: {arm.ABHS, arm.ABLO},
+ ssa.BlockARMUGT: {arm.ABHI, arm.ABLS},
+ ssa.BlockARMULE: {arm.ABLS, arm.ABHI},
+ ssa.BlockARMLTnoov: {arm.ABMI, arm.ABPL},
+ ssa.BlockARMGEnoov: {arm.ABPL, arm.ABMI},
+}
+
+// To model a 'LEnoov' ('<=' without overflow checking) branching
+var leJumps = [2][2]gc.IndexJump{
+ {{Jump: arm.ABEQ, Index: 0}, {Jump: arm.ABPL, Index: 1}}, // next == b.Succs[0]
+ {{Jump: arm.ABMI, Index: 0}, {Jump: arm.ABEQ, Index: 0}}, // next == b.Succs[1]
+}
+
+// To model a 'GTnoov' ('>' without overflow checking) branching
+var gtJumps = [2][2]gc.IndexJump{
+ {{Jump: arm.ABMI, Index: 1}, {Jump: arm.ABEQ, Index: 1}}, // next == b.Succs[0]
+ {{Jump: arm.ABEQ, Index: 1}, {Jump: arm.ABPL, Index: 0}}, // next == b.Succs[1]
}
func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
@@ -941,7 +955,8 @@
ssa.BlockARMLT, ssa.BlockARMGE,
ssa.BlockARMLE, ssa.BlockARMGT,
ssa.BlockARMULT, ssa.BlockARMUGT,
- ssa.BlockARMULE, ssa.BlockARMUGE:
+ ssa.BlockARMULE, ssa.BlockARMUGE,
+ ssa.BlockARMLTnoov, ssa.BlockARMGEnoov:
jmp := blockJump[b.Kind]
switch next {
case b.Succs[0].Block():
@@ -958,6 +973,12 @@
}
}
+ case ssa.BlockARMLEnoov:
+ s.CombJump(b, next, &leJumps)
+
+ case ssa.BlockARMGTnoov:
+ s.CombJump(b, next, >Jumps)
+
default:
b.Fatalf("branch not implemented: %s", b.LongString())
}
diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go
index 8e781a7..f3e9ab7 100644
--- a/src/cmd/compile/internal/gc/esc.go
+++ b/src/cmd/compile/internal/gc/esc.go
@@ -141,13 +141,13 @@
return samesafeexpr(dst.Left, src.Left)
}
-// mayAffectMemory reports whether n evaluation may affect program memory state.
-// If expression can't affect it, then it can be safely ignored by the escape analysis.
+// mayAffectMemory reports whether evaluation of n may affect the program's
+// memory state. If the expression can't affect memory state, then it can be
+// safely ignored by the escape analysis.
func mayAffectMemory(n *Node) bool {
- // We may want to use "memory safe" black list instead of general
- // "side-effect free", which can include all calls and other ops
- // that can affect allocate or change global state.
- // It's safer to start from a whitelist for now.
+ // We may want to use a list of "memory safe" ops instead of generally
+ // "side-effect free", which would include all calls and other ops that can
+ // allocate or change global state. For now, it's safer to start with the latter.
//
// We're ignoring things like division by zero, index out of range,
// and nil pointer dereference here.
diff --git a/src/cmd/compile/internal/ssa/compile.go b/src/cmd/compile/internal/ssa/compile.go
index 2dbe9cf..dbdd027 100644
--- a/src/cmd/compile/internal/ssa/compile.go
+++ b/src/cmd/compile/internal/ssa/compile.go
@@ -451,6 +451,7 @@
{name: "lowered deadcode for cse", fn: deadcode}, // deadcode immediately before CSE avoids CSE making dead values live again
{name: "lowered cse", fn: cse},
{name: "elim unread autos", fn: elimUnreadAutos},
+ {name: "tighten tuple selectors", fn: tightenTupleSelectors, required: true},
{name: "lowered deadcode", fn: deadcode, required: true},
{name: "checkLower", fn: checkLower, required: true},
{name: "late phielim", fn: phielim},
@@ -509,6 +510,8 @@
{"decompose builtin", "late opt"},
// decompose builtin is the last pass that may introduce new float ops, so run softfloat after it
{"decompose builtin", "softfloat"},
+ // tuple selectors must be tightened to generators and de-duplicated before scheduling
+ {"tighten tuple selectors", "schedule"},
// remove critical edges before phi tighten, so that phi args get better placement
{"critical", "phi tighten"},
// don't layout blocks until critical edges have been removed
diff --git a/src/cmd/compile/internal/ssa/cse.go b/src/cmd/compile/internal/ssa/cse.go
index 6bfd296..3b4f2be 100644
--- a/src/cmd/compile/internal/ssa/cse.go
+++ b/src/cmd/compile/internal/ssa/cse.go
@@ -223,60 +223,6 @@
}
}
- // Fixup tuple selectors.
- //
- // If we have rewritten a tuple generator to a new one in a different
- // block, copy its selectors to the new generator's block, so tuple
- // generator and selectors stay together.
- //
- // Note: that there must be only one selector of each type per tuple
- // generator. CSE may have left us with more than one so we de-duplicate
- // them using a map. See issue 16741.
- selectors := make(map[struct {
- id ID
- op Op
- }]*Value)
- for _, b := range f.Blocks {
- for _, selector := range b.Values {
- if selector.Op != OpSelect0 && selector.Op != OpSelect1 {
- continue
- }
-
- // Get the tuple generator to use as a key for de-duplication.
- tuple := selector.Args[0]
- if !tuple.Type.IsTuple() {
- f.Fatalf("arg of tuple selector %s is not a tuple: %s", selector.String(), tuple.LongString())
- }
-
- // If there is a pre-existing selector in the target block then
- // use that. Do this even if the selector is already in the
- // target block to avoid duplicate tuple selectors.
- key := struct {
- id ID
- op Op
- }{tuple.ID, selector.Op}
- if t := selectors[key]; t != nil {
- if selector != t {
- selector.copyOf(t)
- }
- continue
- }
-
- // If the selector is in the wrong block copy it into the target
- // block.
- if selector.Block != tuple.Block {
- t := selector.copyInto(tuple.Block)
- selector.copyOf(t)
- selectors[key] = t
- continue
- }
-
- // The selector is in the target block. Add it to the map so it
- // cannot be duplicated.
- selectors[key] = selector
- }
- }
-
if f.pass.stats > 0 {
f.LogStat("CSE REWRITES", rewrites)
}
diff --git a/src/cmd/compile/internal/ssa/gen/ARM.rules b/src/cmd/compile/internal/ssa/gen/ARM.rules
index a8cea68..5b3179a 100644
--- a/src/cmd/compile/internal/ssa/gen/ARM.rules
+++ b/src/cmd/compile/internal/ssa/gen/ARM.rules
@@ -704,6 +704,10 @@
(UGE (InvertFlags cmp) yes no) -> (ULE cmp yes no)
(EQ (InvertFlags cmp) yes no) -> (EQ cmp yes no)
(NE (InvertFlags cmp) yes no) -> (NE cmp yes no)
+(LTnoov (InvertFlags cmp) yes no) => (GTnoov cmp yes no)
+(GEnoov (InvertFlags cmp) yes no) => (LEnoov cmp yes no)
+(LEnoov (InvertFlags cmp) yes no) => (GEnoov cmp yes no)
+(GTnoov (InvertFlags cmp) yes no) => (LTnoov cmp yes no)
// absorb flag constants into boolean values
(Equal (FlagEQ)) -> (MOVWconst [1])
@@ -1417,42 +1421,42 @@
(NE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (NE (TEQshiftLLreg x y z) yes no)
(NE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (NE (TEQshiftRLreg x y z) yes no)
(NE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (NE (TEQshiftRAreg x y z) yes no)
-(LT (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 -> (LT (CMP x y) yes no)
-(LT (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 -> (LT (CMP a (MUL <x.Type> x y)) yes no)
-(LT (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 -> (LT (CMPconst [c] x) yes no)
-(LT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 -> (LT (CMPshiftLL x y [c]) yes no)
-(LT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 -> (LT (CMPshiftRL x y [c]) yes no)
-(LT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 -> (LT (CMPshiftRA x y [c]) yes no)
-(LT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 -> (LT (CMPshiftLLreg x y z) yes no)
-(LT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 -> (LT (CMPshiftRLreg x y z) yes no)
-(LT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 -> (LT (CMPshiftRAreg x y z) yes no)
-(LE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 -> (LE (CMP x y) yes no)
-(LE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 -> (LE (CMP a (MUL <x.Type> x y)) yes no)
-(LE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 -> (LE (CMPconst [c] x) yes no)
-(LE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 -> (LE (CMPshiftLL x y [c]) yes no)
-(LE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 -> (LE (CMPshiftRL x y [c]) yes no)
-(LE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 -> (LE (CMPshiftRA x y [c]) yes no)
-(LE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 -> (LE (CMPshiftLLreg x y z) yes no)
-(LE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 -> (LE (CMPshiftRLreg x y z) yes no)
-(LE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 -> (LE (CMPshiftRAreg x y z) yes no)
-(LT (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 -> (LT (CMN x y) yes no)
-(LT (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 -> (LT (CMN a (MUL <x.Type> x y)) yes no)
-(LT (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 -> (LT (CMNconst [c] x) yes no)
-(LT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 -> (LT (CMNshiftLL x y [c]) yes no)
-(LT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 -> (LT (CMNshiftRL x y [c]) yes no)
-(LT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 -> (LT (CMNshiftRA x y [c]) yes no)
-(LT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LT (CMNshiftLLreg x y z) yes no)
-(LT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LT (CMNshiftRLreg x y z) yes no)
-(LT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LT (CMNshiftRAreg x y z) yes no)
-(LE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 -> (LE (CMN x y) yes no)
-(LE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 -> (LE (CMN a (MUL <x.Type> x y)) yes no)
-(LE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 -> (LE (CMNconst [c] x) yes no)
-(LE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 -> (LE (CMNshiftLL x y [c]) yes no)
-(LE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 -> (LE (CMNshiftRL x y [c]) yes no)
-(LE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 -> (LE (CMNshiftRA x y [c]) yes no)
-(LE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LE (CMNshiftLLreg x y z) yes no)
-(LE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LE (CMNshiftRLreg x y z) yes no)
-(LE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LE (CMNshiftRAreg x y z) yes no)
+(LT (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 -> (LTnoov (CMP x y) yes no)
+(LT (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 -> (LTnoov (CMP a (MUL <x.Type> x y)) yes no)
+(LT (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 -> (LTnoov (CMPconst [c] x) yes no)
+(LT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 -> (LTnoov (CMPshiftLL x y [c]) yes no)
+(LT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 -> (LTnoov (CMPshiftRL x y [c]) yes no)
+(LT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 -> (LTnoov (CMPshiftRA x y [c]) yes no)
+(LT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 -> (LTnoov (CMPshiftLLreg x y z) yes no)
+(LT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 -> (LTnoov (CMPshiftRLreg x y z) yes no)
+(LT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 -> (LTnoov (CMPshiftRAreg x y z) yes no)
+(LE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 -> (LEnoov (CMP x y) yes no)
+(LE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 -> (LEnoov (CMP a (MUL <x.Type> x y)) yes no)
+(LE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 -> (LEnoov (CMPconst [c] x) yes no)
+(LE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 -> (LEnoov (CMPshiftLL x y [c]) yes no)
+(LE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 -> (LEnoov (CMPshiftRL x y [c]) yes no)
+(LE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 -> (LEnoov (CMPshiftRA x y [c]) yes no)
+(LE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (CMPshiftLLreg x y z) yes no)
+(LE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (CMPshiftRLreg x y z) yes no)
+(LE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 -> (LEnoov (CMPshiftRAreg x y z) yes no)
+(LT (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 -> (LTnoov (CMN x y) yes no)
+(LT (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 -> (LTnoov (CMN a (MUL <x.Type> x y)) yes no)
+(LT (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 -> (LTnoov (CMNconst [c] x) yes no)
+(LT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 -> (LTnoov (CMNshiftLL x y [c]) yes no)
+(LT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 -> (LTnoov (CMNshiftRL x y [c]) yes no)
+(LT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 -> (LTnoov (CMNshiftRA x y [c]) yes no)
+(LT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LTnoov (CMNshiftLLreg x y z) yes no)
+(LT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LTnoov (CMNshiftRLreg x y z) yes no)
+(LT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LTnoov (CMNshiftRAreg x y z) yes no)
+(LE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 -> (LEnoov (CMN x y) yes no)
+(LE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 -> (LEnoov (CMN a (MUL <x.Type> x y)) yes no)
+(LE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 -> (LEnoov (CMNconst [c] x) yes no)
+(LE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 -> (LEnoov (CMNshiftLL x y [c]) yes no)
+(LE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 -> (LEnoov (CMNshiftRL x y [c]) yes no)
+(LE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 -> (LEnoov (CMNshiftRA x y [c]) yes no)
+(LE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (CMNshiftLLreg x y z) yes no)
+(LE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (CMNshiftRLreg x y z) yes no)
+(LE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LEnoov (CMNshiftRAreg x y z) yes no)
(LT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (LT (TST x y) yes no)
(LT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (LT (TSTconst [c] x) yes no)
(LT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (LT (TSTshiftLL x y [c]) yes no)
@@ -1485,43 +1489,43 @@
(LE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (LE (TEQshiftLLreg x y z) yes no)
(LE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (LE (TEQshiftRLreg x y z) yes no)
(LE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (LE (TEQshiftRAreg x y z) yes no)
-(GT (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 -> (GT (CMP x y) yes no)
-(GT (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 -> (GT (CMP a (MUL <x.Type> x y)) yes no)
-(GT (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 -> (GT (CMPconst [c] x) yes no)
-(GT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 -> (GT (CMPshiftLL x y [c]) yes no)
-(GT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 -> (GT (CMPshiftRL x y [c]) yes no)
-(GT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 -> (GT (CMPshiftRA x y [c]) yes no)
-(GT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 -> (GT (CMPshiftLLreg x y z) yes no)
-(GT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 -> (GT (CMPshiftRLreg x y z) yes no)
-(GT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 -> (GT (CMPshiftRAreg x y z) yes no)
-(GE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 -> (GE (CMP x y) yes no)
-(GE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 -> (GE (CMP a (MUL <x.Type> x y)) yes no)
-(GE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 -> (GE (CMPconst [c] x) yes no)
-(GE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 -> (GE (CMPshiftLL x y [c]) yes no)
-(GE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 -> (GE (CMPshiftRL x y [c]) yes no)
-(GE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 -> (GE (CMPshiftRA x y [c]) yes no)
-(GE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 -> (GE (CMPshiftLLreg x y z) yes no)
-(GE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 -> (GE (CMPshiftRLreg x y z) yes no)
-(GE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 -> (GE (CMPshiftRAreg x y z) yes no)
-(GT (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 -> (GT (CMN x y) yes no)
-(GT (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 -> (GT (CMNconst [c] x) yes no)
-(GT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 -> (GT (CMNshiftLL x y [c]) yes no)
-(GT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 -> (GT (CMNshiftRL x y [c]) yes no)
-(GT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 -> (GT (CMNshiftRA x y [c]) yes no)
-(GT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GT (CMNshiftLLreg x y z) yes no)
-(GT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GT (CMNshiftRLreg x y z) yes no)
-(GT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GT (CMNshiftRAreg x y z) yes no)
-(GE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 -> (GE (CMN x y) yes no)
-(GE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 -> (GE (CMN a (MUL <x.Type> x y)) yes no)
-(GE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 -> (GE (CMNconst [c] x) yes no)
-(GE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 -> (GE (CMNshiftLL x y [c]) yes no)
-(GE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 -> (GE (CMNshiftRL x y [c]) yes no)
-(GE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 -> (GE (CMNshiftRA x y [c]) yes no)
-(GE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GE (CMNshiftLLreg x y z) yes no)
-(GE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GE (CMNshiftRLreg x y z) yes no)
-(GE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GE (CMNshiftRAreg x y z) yes no)
+(GT (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 -> (GTnoov (CMP x y) yes no)
+(GT (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 -> (GTnoov (CMP a (MUL <x.Type> x y)) yes no)
+(GT (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 -> (GTnoov (CMPconst [c] x) yes no)
+(GT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 -> (GTnoov (CMPshiftLL x y [c]) yes no)
+(GT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 -> (GTnoov (CMPshiftRL x y [c]) yes no)
+(GT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 -> (GTnoov (CMPshiftRA x y [c]) yes no)
+(GT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 -> (GTnoov (CMPshiftLLreg x y z) yes no)
+(GT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 -> (GTnoov (CMPshiftRLreg x y z) yes no)
+(GT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 -> (GTnoov (CMPshiftRAreg x y z) yes no)
+(GE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 -> (GEnoov (CMP x y) yes no)
+(GE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 -> (GEnoov (CMP a (MUL <x.Type> x y)) yes no)
+(GE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 -> (GEnoov (CMPconst [c] x) yes no)
+(GE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 -> (GEnoov (CMPshiftLL x y [c]) yes no)
+(GE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 -> (GEnoov (CMPshiftRL x y [c]) yes no)
+(GE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 -> (GEnoov (CMPshiftRA x y [c]) yes no)
+(GE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (CMPshiftLLreg x y z) yes no)
+(GE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (CMPshiftRLreg x y z) yes no)
+(GE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 -> (GEnoov (CMPshiftRAreg x y z) yes no)
+(GT (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 -> (GTnoov (CMN x y) yes no)
+(GT (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 -> (GTnoov (CMNconst [c] x) yes no)
+(GT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 -> (GTnoov (CMNshiftLL x y [c]) yes no)
+(GT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 -> (GTnoov (CMNshiftRL x y [c]) yes no)
+(GT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 -> (GTnoov (CMNshiftRA x y [c]) yes no)
+(GT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GTnoov (CMNshiftLLreg x y z) yes no)
+(GT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GTnoov (CMNshiftRLreg x y z) yes no)
+(GT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GTnoov (CMNshiftRAreg x y z) yes no)
+(GE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 -> (GEnoov (CMN x y) yes no)
+(GE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 -> (GEnoov (CMN a (MUL <x.Type> x y)) yes no)
+(GE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 -> (GEnoov (CMNconst [c] x) yes no)
+(GE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 -> (GEnoov (CMNshiftLL x y [c]) yes no)
+(GE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 -> (GEnoov (CMNshiftRL x y [c]) yes no)
+(GE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 -> (GEnoov (CMNshiftRA x y [c]) yes no)
+(GE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (CMNshiftLLreg x y z) yes no)
+(GE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (CMNshiftRLreg x y z) yes no)
+(GE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GEnoov (CMNshiftRAreg x y z) yes no)
(GT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (GT (TST x y) yes no)
-(GT (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 -> (GT (CMN a (MUL <x.Type> x y)) yes no)
+(GT (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 -> (GTnoov (CMN a (MUL <x.Type> x y)) yes no)
(GT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (GT (TSTconst [c] x) yes no)
(GT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (GT (TSTshiftLL x y [c]) yes no)
(GT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (GT (TSTshiftRL x y [c]) yes no)
diff --git a/src/cmd/compile/internal/ssa/gen/ARMOps.go b/src/cmd/compile/internal/ssa/gen/ARMOps.go
index 4abe5c9..14407fe 100644
--- a/src/cmd/compile/internal/ssa/gen/ARMOps.go
+++ b/src/cmd/compile/internal/ssa/gen/ARMOps.go
@@ -584,6 +584,10 @@
{name: "ULE", controls: 1},
{name: "UGT", controls: 1},
{name: "UGE", controls: 1},
+ {name: "LTnoov", controls: 1}, // 'LT' but without honoring overflow
+ {name: "LEnoov", controls: 1}, // 'LE' but without honoring overflow
+ {name: "GTnoov", controls: 1}, // 'GT' but without honoring overflow
+ {name: "GEnoov", controls: 1}, // 'GE' but without honoring overflow
}
archs = append(archs, arch{
diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go
index 4a83a46..7f6bf3e 100644
--- a/src/cmd/compile/internal/ssa/opGen.go
+++ b/src/cmd/compile/internal/ssa/opGen.go
@@ -61,6 +61,10 @@
BlockARMULE
BlockARMUGT
BlockARMUGE
+ BlockARMLTnoov
+ BlockARMLEnoov
+ BlockARMGTnoov
+ BlockARMGEnoov
BlockARM64EQ
BlockARM64NE
@@ -185,16 +189,20 @@
BlockAMD64ORD: "ORD",
BlockAMD64NAN: "NAN",
- BlockARMEQ: "EQ",
- BlockARMNE: "NE",
- BlockARMLT: "LT",
- BlockARMLE: "LE",
- BlockARMGT: "GT",
- BlockARMGE: "GE",
- BlockARMULT: "ULT",
- BlockARMULE: "ULE",
- BlockARMUGT: "UGT",
- BlockARMUGE: "UGE",
+ BlockARMEQ: "EQ",
+ BlockARMNE: "NE",
+ BlockARMLT: "LT",
+ BlockARMLE: "LE",
+ BlockARMGT: "GT",
+ BlockARMGE: "GE",
+ BlockARMULT: "ULT",
+ BlockARMULE: "ULE",
+ BlockARMUGT: "UGT",
+ BlockARMUGE: "UGE",
+ BlockARMLTnoov: "LTnoov",
+ BlockARMLEnoov: "LEnoov",
+ BlockARMGTnoov: "GTnoov",
+ BlockARMGEnoov: "GEnoov",
BlockARM64EQ: "EQ",
BlockARM64NE: "NE",
diff --git a/src/cmd/compile/internal/ssa/rewriteARM.go b/src/cmd/compile/internal/ssa/rewriteARM.go
index 5c8dd0f..be5f56a 100644
--- a/src/cmd/compile/internal/ssa/rewriteARM.go
+++ b/src/cmd/compile/internal/ssa/rewriteARM.go
@@ -17514,7 +17514,7 @@
}
// match: (GE (CMPconst [0] l:(SUB x y)) yes no)
// cond: l.Uses==1
- // result: (GE (CMP x y) yes no)
+ // result: (GEnoov (CMP x y) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -17531,12 +17531,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMP, types.TypeFlags)
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMGE, v0)
+ b.resetWithControl(BlockARMGEnoov, v0)
return true
}
// match: (GE (CMPconst [0] l:(MULS x y a)) yes no)
// cond: l.Uses==1
- // result: (GE (CMP a (MUL <x.Type> x y)) yes no)
+ // result: (GEnoov (CMP a (MUL <x.Type> x y)) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -17556,12 +17556,12 @@
v1 := b.NewValue0(v_0.Pos, OpARMMUL, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
- b.resetWithControl(BlockARMGE, v0)
+ b.resetWithControl(BlockARMGEnoov, v0)
return true
}
// match: (GE (CMPconst [0] l:(SUBconst [c] x)) yes no)
// cond: l.Uses==1
- // result: (GE (CMPconst [c] x) yes no)
+ // result: (GEnoov (CMPconst [c] x) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -17579,12 +17579,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMPconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
- b.resetWithControl(BlockARMGE, v0)
+ b.resetWithControl(BlockARMGEnoov, v0)
return true
}
// match: (GE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no)
// cond: l.Uses==1
- // result: (GE (CMPshiftLL x y [c]) yes no)
+ // result: (GEnoov (CMPshiftLL x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -17603,12 +17603,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftLL, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMGE, v0)
+ b.resetWithControl(BlockARMGEnoov, v0)
return true
}
// match: (GE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no)
// cond: l.Uses==1
- // result: (GE (CMPshiftRL x y [c]) yes no)
+ // result: (GEnoov (CMPshiftRL x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -17627,12 +17627,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRL, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMGE, v0)
+ b.resetWithControl(BlockARMGEnoov, v0)
return true
}
// match: (GE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no)
// cond: l.Uses==1
- // result: (GE (CMPshiftRA x y [c]) yes no)
+ // result: (GEnoov (CMPshiftRA x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -17651,12 +17651,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRA, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMGE, v0)
+ b.resetWithControl(BlockARMGEnoov, v0)
return true
}
// match: (GE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no)
// cond: l.Uses==1
- // result: (GE (CMPshiftLLreg x y z) yes no)
+ // result: (GEnoov (CMPshiftLLreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -17674,12 +17674,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftLLreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMGE, v0)
+ b.resetWithControl(BlockARMGEnoov, v0)
return true
}
// match: (GE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no)
// cond: l.Uses==1
- // result: (GE (CMPshiftRLreg x y z) yes no)
+ // result: (GEnoov (CMPshiftRLreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -17697,12 +17697,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRLreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMGE, v0)
+ b.resetWithControl(BlockARMGEnoov, v0)
return true
}
// match: (GE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no)
// cond: l.Uses==1
- // result: (GE (CMPshiftRAreg x y z) yes no)
+ // result: (GEnoov (CMPshiftRAreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -17720,12 +17720,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRAreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMGE, v0)
+ b.resetWithControl(BlockARMGEnoov, v0)
return true
}
// match: (GE (CMPconst [0] l:(ADD x y)) yes no)
// cond: l.Uses==1
- // result: (GE (CMN x y) yes no)
+ // result: (GEnoov (CMN x y) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -17746,14 +17746,14 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMN, types.TypeFlags)
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMGE, v0)
+ b.resetWithControl(BlockARMGEnoov, v0)
return true
}
break
}
// match: (GE (CMPconst [0] l:(MULA x y a)) yes no)
// cond: l.Uses==1
- // result: (GE (CMN a (MUL <x.Type> x y)) yes no)
+ // result: (GEnoov (CMN a (MUL <x.Type> x y)) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -17773,12 +17773,12 @@
v1 := b.NewValue0(v_0.Pos, OpARMMUL, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
- b.resetWithControl(BlockARMGE, v0)
+ b.resetWithControl(BlockARMGEnoov, v0)
return true
}
// match: (GE (CMPconst [0] l:(ADDconst [c] x)) yes no)
// cond: l.Uses==1
- // result: (GE (CMNconst [c] x) yes no)
+ // result: (GEnoov (CMNconst [c] x) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -17796,12 +17796,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMNconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
- b.resetWithControl(BlockARMGE, v0)
+ b.resetWithControl(BlockARMGEnoov, v0)
return true
}
// match: (GE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no)
// cond: l.Uses==1
- // result: (GE (CMNshiftLL x y [c]) yes no)
+ // result: (GEnoov (CMNshiftLL x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -17820,12 +17820,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftLL, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMGE, v0)
+ b.resetWithControl(BlockARMGEnoov, v0)
return true
}
// match: (GE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no)
// cond: l.Uses==1
- // result: (GE (CMNshiftRL x y [c]) yes no)
+ // result: (GEnoov (CMNshiftRL x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -17844,12 +17844,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRL, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMGE, v0)
+ b.resetWithControl(BlockARMGEnoov, v0)
return true
}
// match: (GE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no)
// cond: l.Uses==1
- // result: (GE (CMNshiftRA x y [c]) yes no)
+ // result: (GEnoov (CMNshiftRA x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -17868,12 +17868,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRA, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMGE, v0)
+ b.resetWithControl(BlockARMGEnoov, v0)
return true
}
// match: (GE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no)
// cond: l.Uses==1
- // result: (GE (CMNshiftLLreg x y z) yes no)
+ // result: (GEnoov (CMNshiftLLreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -17891,12 +17891,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftLLreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMGE, v0)
+ b.resetWithControl(BlockARMGEnoov, v0)
return true
}
// match: (GE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no)
// cond: l.Uses==1
- // result: (GE (CMNshiftRLreg x y z) yes no)
+ // result: (GEnoov (CMNshiftRLreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -17914,12 +17914,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRLreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMGE, v0)
+ b.resetWithControl(BlockARMGEnoov, v0)
return true
}
// match: (GE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no)
// cond: l.Uses==1
- // result: (GE (CMNshiftRAreg x y z) yes no)
+ // result: (GEnoov (CMNshiftRAreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -17937,7 +17937,7 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRAreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMGE, v0)
+ b.resetWithControl(BlockARMGEnoov, v0)
return true
}
// match: (GE (CMPconst [0] l:(AND x y)) yes no)
@@ -18324,6 +18324,15 @@
b.resetWithControl(BlockARMGE, v0)
return true
}
+ case BlockARMGEnoov:
+ // match: (GEnoov (InvertFlags cmp) yes no)
+ // result: (LEnoov cmp yes no)
+ for b.Controls[0].Op == OpARMInvertFlags {
+ v_0 := b.Controls[0]
+ cmp := v_0.Args[0]
+ b.resetWithControl(BlockARMLEnoov, cmp)
+ return true
+ }
case BlockARMGT:
// match: (GT (FlagEQ) yes no)
// result: (First no yes)
@@ -18368,7 +18377,7 @@
}
// match: (GT (CMPconst [0] l:(SUB x y)) yes no)
// cond: l.Uses==1
- // result: (GT (CMP x y) yes no)
+ // result: (GTnoov (CMP x y) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -18385,12 +18394,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMP, types.TypeFlags)
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMGT, v0)
+ b.resetWithControl(BlockARMGTnoov, v0)
return true
}
// match: (GT (CMPconst [0] l:(MULS x y a)) yes no)
// cond: l.Uses==1
- // result: (GT (CMP a (MUL <x.Type> x y)) yes no)
+ // result: (GTnoov (CMP a (MUL <x.Type> x y)) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -18410,12 +18419,12 @@
v1 := b.NewValue0(v_0.Pos, OpARMMUL, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
- b.resetWithControl(BlockARMGT, v0)
+ b.resetWithControl(BlockARMGTnoov, v0)
return true
}
// match: (GT (CMPconst [0] l:(SUBconst [c] x)) yes no)
// cond: l.Uses==1
- // result: (GT (CMPconst [c] x) yes no)
+ // result: (GTnoov (CMPconst [c] x) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -18433,12 +18442,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMPconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
- b.resetWithControl(BlockARMGT, v0)
+ b.resetWithControl(BlockARMGTnoov, v0)
return true
}
// match: (GT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no)
// cond: l.Uses==1
- // result: (GT (CMPshiftLL x y [c]) yes no)
+ // result: (GTnoov (CMPshiftLL x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -18457,12 +18466,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftLL, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMGT, v0)
+ b.resetWithControl(BlockARMGTnoov, v0)
return true
}
// match: (GT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no)
// cond: l.Uses==1
- // result: (GT (CMPshiftRL x y [c]) yes no)
+ // result: (GTnoov (CMPshiftRL x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -18481,12 +18490,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRL, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMGT, v0)
+ b.resetWithControl(BlockARMGTnoov, v0)
return true
}
// match: (GT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no)
// cond: l.Uses==1
- // result: (GT (CMPshiftRA x y [c]) yes no)
+ // result: (GTnoov (CMPshiftRA x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -18505,12 +18514,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRA, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMGT, v0)
+ b.resetWithControl(BlockARMGTnoov, v0)
return true
}
// match: (GT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no)
// cond: l.Uses==1
- // result: (GT (CMPshiftLLreg x y z) yes no)
+ // result: (GTnoov (CMPshiftLLreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -18528,12 +18537,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftLLreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMGT, v0)
+ b.resetWithControl(BlockARMGTnoov, v0)
return true
}
// match: (GT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no)
// cond: l.Uses==1
- // result: (GT (CMPshiftRLreg x y z) yes no)
+ // result: (GTnoov (CMPshiftRLreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -18551,12 +18560,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRLreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMGT, v0)
+ b.resetWithControl(BlockARMGTnoov, v0)
return true
}
// match: (GT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no)
// cond: l.Uses==1
- // result: (GT (CMPshiftRAreg x y z) yes no)
+ // result: (GTnoov (CMPshiftRAreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -18574,12 +18583,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRAreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMGT, v0)
+ b.resetWithControl(BlockARMGTnoov, v0)
return true
}
// match: (GT (CMPconst [0] l:(ADD x y)) yes no)
// cond: l.Uses==1
- // result: (GT (CMN x y) yes no)
+ // result: (GTnoov (CMN x y) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -18600,14 +18609,14 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMN, types.TypeFlags)
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMGT, v0)
+ b.resetWithControl(BlockARMGTnoov, v0)
return true
}
break
}
// match: (GT (CMPconst [0] l:(ADDconst [c] x)) yes no)
// cond: l.Uses==1
- // result: (GT (CMNconst [c] x) yes no)
+ // result: (GTnoov (CMNconst [c] x) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -18625,12 +18634,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMNconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
- b.resetWithControl(BlockARMGT, v0)
+ b.resetWithControl(BlockARMGTnoov, v0)
return true
}
// match: (GT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no)
// cond: l.Uses==1
- // result: (GT (CMNshiftLL x y [c]) yes no)
+ // result: (GTnoov (CMNshiftLL x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -18649,12 +18658,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftLL, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMGT, v0)
+ b.resetWithControl(BlockARMGTnoov, v0)
return true
}
// match: (GT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no)
// cond: l.Uses==1
- // result: (GT (CMNshiftRL x y [c]) yes no)
+ // result: (GTnoov (CMNshiftRL x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -18673,12 +18682,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRL, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMGT, v0)
+ b.resetWithControl(BlockARMGTnoov, v0)
return true
}
// match: (GT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no)
// cond: l.Uses==1
- // result: (GT (CMNshiftRA x y [c]) yes no)
+ // result: (GTnoov (CMNshiftRA x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -18697,12 +18706,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRA, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMGT, v0)
+ b.resetWithControl(BlockARMGTnoov, v0)
return true
}
// match: (GT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no)
// cond: l.Uses==1
- // result: (GT (CMNshiftLLreg x y z) yes no)
+ // result: (GTnoov (CMNshiftLLreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -18720,12 +18729,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftLLreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMGT, v0)
+ b.resetWithControl(BlockARMGTnoov, v0)
return true
}
// match: (GT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no)
// cond: l.Uses==1
- // result: (GT (CMNshiftRLreg x y z) yes no)
+ // result: (GTnoov (CMNshiftRLreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -18743,12 +18752,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRLreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMGT, v0)
+ b.resetWithControl(BlockARMGTnoov, v0)
return true
}
// match: (GT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no)
// cond: l.Uses==1
- // result: (GT (CMNshiftRAreg x y z) yes no)
+ // result: (GTnoov (CMNshiftRAreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -18766,7 +18775,7 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRAreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMGT, v0)
+ b.resetWithControl(BlockARMGTnoov, v0)
return true
}
// match: (GT (CMPconst [0] l:(AND x y)) yes no)
@@ -18799,7 +18808,7 @@
}
// match: (GT (CMPconst [0] l:(MULA x y a)) yes no)
// cond: l.Uses==1
- // result: (GT (CMN a (MUL <x.Type> x y)) yes no)
+ // result: (GTnoov (CMN a (MUL <x.Type> x y)) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -18819,7 +18828,7 @@
v1 := b.NewValue0(v_0.Pos, OpARMMUL, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
- b.resetWithControl(BlockARMGT, v0)
+ b.resetWithControl(BlockARMGTnoov, v0)
return true
}
// match: (GT (CMPconst [0] l:(ANDconst [c] x)) yes no)
@@ -19178,6 +19187,15 @@
b.resetWithControl(BlockARMGT, v0)
return true
}
+ case BlockARMGTnoov:
+ // match: (GTnoov (InvertFlags cmp) yes no)
+ // result: (LTnoov cmp yes no)
+ for b.Controls[0].Op == OpARMInvertFlags {
+ v_0 := b.Controls[0]
+ cmp := v_0.Args[0]
+ b.resetWithControl(BlockARMLTnoov, cmp)
+ return true
+ }
case BlockIf:
// match: (If (Equal cc) yes no)
// result: (EQ cc yes no)
@@ -19312,7 +19330,7 @@
}
// match: (LE (CMPconst [0] l:(SUB x y)) yes no)
// cond: l.Uses==1
- // result: (LE (CMP x y) yes no)
+ // result: (LEnoov (CMP x y) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -19329,12 +19347,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMP, types.TypeFlags)
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMLE, v0)
+ b.resetWithControl(BlockARMLEnoov, v0)
return true
}
// match: (LE (CMPconst [0] l:(MULS x y a)) yes no)
// cond: l.Uses==1
- // result: (LE (CMP a (MUL <x.Type> x y)) yes no)
+ // result: (LEnoov (CMP a (MUL <x.Type> x y)) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -19354,12 +19372,12 @@
v1 := b.NewValue0(v_0.Pos, OpARMMUL, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
- b.resetWithControl(BlockARMLE, v0)
+ b.resetWithControl(BlockARMLEnoov, v0)
return true
}
// match: (LE (CMPconst [0] l:(SUBconst [c] x)) yes no)
// cond: l.Uses==1
- // result: (LE (CMPconst [c] x) yes no)
+ // result: (LEnoov (CMPconst [c] x) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -19377,12 +19395,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMPconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
- b.resetWithControl(BlockARMLE, v0)
+ b.resetWithControl(BlockARMLEnoov, v0)
return true
}
// match: (LE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no)
// cond: l.Uses==1
- // result: (LE (CMPshiftLL x y [c]) yes no)
+ // result: (LEnoov (CMPshiftLL x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -19401,12 +19419,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftLL, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMLE, v0)
+ b.resetWithControl(BlockARMLEnoov, v0)
return true
}
// match: (LE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no)
// cond: l.Uses==1
- // result: (LE (CMPshiftRL x y [c]) yes no)
+ // result: (LEnoov (CMPshiftRL x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -19425,12 +19443,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRL, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMLE, v0)
+ b.resetWithControl(BlockARMLEnoov, v0)
return true
}
// match: (LE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no)
// cond: l.Uses==1
- // result: (LE (CMPshiftRA x y [c]) yes no)
+ // result: (LEnoov (CMPshiftRA x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -19449,12 +19467,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRA, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMLE, v0)
+ b.resetWithControl(BlockARMLEnoov, v0)
return true
}
// match: (LE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no)
// cond: l.Uses==1
- // result: (LE (CMPshiftLLreg x y z) yes no)
+ // result: (LEnoov (CMPshiftLLreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -19472,12 +19490,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftLLreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMLE, v0)
+ b.resetWithControl(BlockARMLEnoov, v0)
return true
}
// match: (LE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no)
// cond: l.Uses==1
- // result: (LE (CMPshiftRLreg x y z) yes no)
+ // result: (LEnoov (CMPshiftRLreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -19495,12 +19513,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRLreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMLE, v0)
+ b.resetWithControl(BlockARMLEnoov, v0)
return true
}
// match: (LE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no)
// cond: l.Uses==1
- // result: (LE (CMPshiftRAreg x y z) yes no)
+ // result: (LEnoov (CMPshiftRAreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -19518,12 +19536,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRAreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMLE, v0)
+ b.resetWithControl(BlockARMLEnoov, v0)
return true
}
// match: (LE (CMPconst [0] l:(ADD x y)) yes no)
// cond: l.Uses==1
- // result: (LE (CMN x y) yes no)
+ // result: (LEnoov (CMN x y) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -19544,14 +19562,14 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMN, types.TypeFlags)
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMLE, v0)
+ b.resetWithControl(BlockARMLEnoov, v0)
return true
}
break
}
// match: (LE (CMPconst [0] l:(MULA x y a)) yes no)
// cond: l.Uses==1
- // result: (LE (CMN a (MUL <x.Type> x y)) yes no)
+ // result: (LEnoov (CMN a (MUL <x.Type> x y)) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -19571,12 +19589,12 @@
v1 := b.NewValue0(v_0.Pos, OpARMMUL, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
- b.resetWithControl(BlockARMLE, v0)
+ b.resetWithControl(BlockARMLEnoov, v0)
return true
}
// match: (LE (CMPconst [0] l:(ADDconst [c] x)) yes no)
// cond: l.Uses==1
- // result: (LE (CMNconst [c] x) yes no)
+ // result: (LEnoov (CMNconst [c] x) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -19594,12 +19612,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMNconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
- b.resetWithControl(BlockARMLE, v0)
+ b.resetWithControl(BlockARMLEnoov, v0)
return true
}
// match: (LE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no)
// cond: l.Uses==1
- // result: (LE (CMNshiftLL x y [c]) yes no)
+ // result: (LEnoov (CMNshiftLL x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -19618,12 +19636,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftLL, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMLE, v0)
+ b.resetWithControl(BlockARMLEnoov, v0)
return true
}
// match: (LE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no)
// cond: l.Uses==1
- // result: (LE (CMNshiftRL x y [c]) yes no)
+ // result: (LEnoov (CMNshiftRL x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -19642,12 +19660,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRL, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMLE, v0)
+ b.resetWithControl(BlockARMLEnoov, v0)
return true
}
// match: (LE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no)
// cond: l.Uses==1
- // result: (LE (CMNshiftRA x y [c]) yes no)
+ // result: (LEnoov (CMNshiftRA x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -19666,12 +19684,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRA, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMLE, v0)
+ b.resetWithControl(BlockARMLEnoov, v0)
return true
}
// match: (LE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no)
// cond: l.Uses==1
- // result: (LE (CMNshiftLLreg x y z) yes no)
+ // result: (LEnoov (CMNshiftLLreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -19689,12 +19707,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftLLreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMLE, v0)
+ b.resetWithControl(BlockARMLEnoov, v0)
return true
}
// match: (LE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no)
// cond: l.Uses==1
- // result: (LE (CMNshiftRLreg x y z) yes no)
+ // result: (LEnoov (CMNshiftRLreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -19712,12 +19730,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRLreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMLE, v0)
+ b.resetWithControl(BlockARMLEnoov, v0)
return true
}
// match: (LE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no)
// cond: l.Uses==1
- // result: (LE (CMNshiftRAreg x y z) yes no)
+ // result: (LEnoov (CMNshiftRAreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -19735,7 +19753,7 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRAreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMLE, v0)
+ b.resetWithControl(BlockARMLEnoov, v0)
return true
}
// match: (LE (CMPconst [0] l:(AND x y)) yes no)
@@ -20122,6 +20140,15 @@
b.resetWithControl(BlockARMLE, v0)
return true
}
+ case BlockARMLEnoov:
+ // match: (LEnoov (InvertFlags cmp) yes no)
+ // result: (GEnoov cmp yes no)
+ for b.Controls[0].Op == OpARMInvertFlags {
+ v_0 := b.Controls[0]
+ cmp := v_0.Args[0]
+ b.resetWithControl(BlockARMGEnoov, cmp)
+ return true
+ }
case BlockARMLT:
// match: (LT (FlagEQ) yes no)
// result: (First no yes)
@@ -20166,7 +20193,7 @@
}
// match: (LT (CMPconst [0] l:(SUB x y)) yes no)
// cond: l.Uses==1
- // result: (LT (CMP x y) yes no)
+ // result: (LTnoov (CMP x y) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -20183,12 +20210,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMP, types.TypeFlags)
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMLT, v0)
+ b.resetWithControl(BlockARMLTnoov, v0)
return true
}
// match: (LT (CMPconst [0] l:(MULS x y a)) yes no)
// cond: l.Uses==1
- // result: (LT (CMP a (MUL <x.Type> x y)) yes no)
+ // result: (LTnoov (CMP a (MUL <x.Type> x y)) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -20208,12 +20235,12 @@
v1 := b.NewValue0(v_0.Pos, OpARMMUL, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
- b.resetWithControl(BlockARMLT, v0)
+ b.resetWithControl(BlockARMLTnoov, v0)
return true
}
// match: (LT (CMPconst [0] l:(SUBconst [c] x)) yes no)
// cond: l.Uses==1
- // result: (LT (CMPconst [c] x) yes no)
+ // result: (LTnoov (CMPconst [c] x) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -20231,12 +20258,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMPconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
- b.resetWithControl(BlockARMLT, v0)
+ b.resetWithControl(BlockARMLTnoov, v0)
return true
}
// match: (LT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no)
// cond: l.Uses==1
- // result: (LT (CMPshiftLL x y [c]) yes no)
+ // result: (LTnoov (CMPshiftLL x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -20255,12 +20282,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftLL, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMLT, v0)
+ b.resetWithControl(BlockARMLTnoov, v0)
return true
}
// match: (LT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no)
// cond: l.Uses==1
- // result: (LT (CMPshiftRL x y [c]) yes no)
+ // result: (LTnoov (CMPshiftRL x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -20279,12 +20306,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRL, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMLT, v0)
+ b.resetWithControl(BlockARMLTnoov, v0)
return true
}
// match: (LT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no)
// cond: l.Uses==1
- // result: (LT (CMPshiftRA x y [c]) yes no)
+ // result: (LTnoov (CMPshiftRA x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -20303,12 +20330,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRA, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMLT, v0)
+ b.resetWithControl(BlockARMLTnoov, v0)
return true
}
// match: (LT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no)
// cond: l.Uses==1
- // result: (LT (CMPshiftLLreg x y z) yes no)
+ // result: (LTnoov (CMPshiftLLreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -20326,12 +20353,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftLLreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMLT, v0)
+ b.resetWithControl(BlockARMLTnoov, v0)
return true
}
// match: (LT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no)
// cond: l.Uses==1
- // result: (LT (CMPshiftRLreg x y z) yes no)
+ // result: (LTnoov (CMPshiftRLreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -20349,12 +20376,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRLreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMLT, v0)
+ b.resetWithControl(BlockARMLTnoov, v0)
return true
}
// match: (LT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no)
// cond: l.Uses==1
- // result: (LT (CMPshiftRAreg x y z) yes no)
+ // result: (LTnoov (CMPshiftRAreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -20372,12 +20399,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRAreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMLT, v0)
+ b.resetWithControl(BlockARMLTnoov, v0)
return true
}
// match: (LT (CMPconst [0] l:(ADD x y)) yes no)
// cond: l.Uses==1
- // result: (LT (CMN x y) yes no)
+ // result: (LTnoov (CMN x y) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -20398,14 +20425,14 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMN, types.TypeFlags)
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMLT, v0)
+ b.resetWithControl(BlockARMLTnoov, v0)
return true
}
break
}
// match: (LT (CMPconst [0] l:(MULA x y a)) yes no)
// cond: l.Uses==1
- // result: (LT (CMN a (MUL <x.Type> x y)) yes no)
+ // result: (LTnoov (CMN a (MUL <x.Type> x y)) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -20425,12 +20452,12 @@
v1 := b.NewValue0(v_0.Pos, OpARMMUL, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
- b.resetWithControl(BlockARMLT, v0)
+ b.resetWithControl(BlockARMLTnoov, v0)
return true
}
// match: (LT (CMPconst [0] l:(ADDconst [c] x)) yes no)
// cond: l.Uses==1
- // result: (LT (CMNconst [c] x) yes no)
+ // result: (LTnoov (CMNconst [c] x) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -20448,12 +20475,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMNconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
- b.resetWithControl(BlockARMLT, v0)
+ b.resetWithControl(BlockARMLTnoov, v0)
return true
}
// match: (LT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no)
// cond: l.Uses==1
- // result: (LT (CMNshiftLL x y [c]) yes no)
+ // result: (LTnoov (CMNshiftLL x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -20472,12 +20499,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftLL, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMLT, v0)
+ b.resetWithControl(BlockARMLTnoov, v0)
return true
}
// match: (LT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no)
// cond: l.Uses==1
- // result: (LT (CMNshiftRL x y [c]) yes no)
+ // result: (LTnoov (CMNshiftRL x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -20496,12 +20523,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRL, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMLT, v0)
+ b.resetWithControl(BlockARMLTnoov, v0)
return true
}
// match: (LT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no)
// cond: l.Uses==1
- // result: (LT (CMNshiftRA x y [c]) yes no)
+ // result: (LTnoov (CMNshiftRA x y [c]) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -20520,12 +20547,12 @@
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRA, types.TypeFlags)
v0.AuxInt = c
v0.AddArg2(x, y)
- b.resetWithControl(BlockARMLT, v0)
+ b.resetWithControl(BlockARMLTnoov, v0)
return true
}
// match: (LT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no)
// cond: l.Uses==1
- // result: (LT (CMNshiftLLreg x y z) yes no)
+ // result: (LTnoov (CMNshiftLLreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -20543,12 +20570,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftLLreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMLT, v0)
+ b.resetWithControl(BlockARMLTnoov, v0)
return true
}
// match: (LT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no)
// cond: l.Uses==1
- // result: (LT (CMNshiftRLreg x y z) yes no)
+ // result: (LTnoov (CMNshiftRLreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -20566,12 +20593,12 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRLreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMLT, v0)
+ b.resetWithControl(BlockARMLTnoov, v0)
return true
}
// match: (LT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no)
// cond: l.Uses==1
- // result: (LT (CMNshiftRAreg x y z) yes no)
+ // result: (LTnoov (CMNshiftRAreg x y z) yes no)
for b.Controls[0].Op == OpARMCMPconst {
v_0 := b.Controls[0]
if v_0.AuxInt != 0 {
@@ -20589,7 +20616,7 @@
}
v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRAreg, types.TypeFlags)
v0.AddArg3(x, y, z)
- b.resetWithControl(BlockARMLT, v0)
+ b.resetWithControl(BlockARMLTnoov, v0)
return true
}
// match: (LT (CMPconst [0] l:(AND x y)) yes no)
@@ -20976,6 +21003,15 @@
b.resetWithControl(BlockARMLT, v0)
return true
}
+ case BlockARMLTnoov:
+ // match: (LTnoov (InvertFlags cmp) yes no)
+ // result: (GTnoov cmp yes no)
+ for b.Controls[0].Op == OpARMInvertFlags {
+ v_0 := b.Controls[0]
+ cmp := v_0.Args[0]
+ b.resetWithControl(BlockARMGTnoov, cmp)
+ return true
+ }
case BlockARMNE:
// match: (NE (CMPconst [0] (Equal cc)) yes no)
// result: (EQ cc yes no)
diff --git a/src/cmd/compile/internal/ssa/rewriteCond_test.go b/src/cmd/compile/internal/ssa/rewriteCond_test.go
index 6536d3a..2c26fdf 100644
--- a/src/cmd/compile/internal/ssa/rewriteCond_test.go
+++ b/src/cmd/compile/internal/ssa/rewriteCond_test.go
@@ -7,24 +7,26 @@
import (
"math"
"math/rand"
- "runtime"
"testing"
)
var (
- x64 int64 = math.MaxInt64 - 2
- x64b int64 = math.MaxInt64 - 2
- x64c int64 = math.MaxInt64 - 2
- y64 int64 = math.MinInt64 + 1
- x32 int32 = math.MaxInt32 - 2
- x32b int32 = math.MaxInt32 - 2
- y32 int32 = math.MinInt32 + 1
- one64 int64 = 1
- one32 int32 = 1
- v64 int64 = 11 // ensure it's not 2**n +/- 1
- v64_n int64 = -11
- v32 int32 = 11
- v32_n int32 = -11
+ x64 int64 = math.MaxInt64 - 2
+ x64b int64 = math.MaxInt64 - 2
+ x64c int64 = math.MaxInt64 - 2
+ y64 int64 = math.MinInt64 + 1
+ x32 int32 = math.MaxInt32 - 2
+ x32b int32 = math.MaxInt32 - 2
+ x32c int32 = math.MaxInt32 - 2
+ y32 int32 = math.MinInt32 + 1
+ one64 int64 = 1
+ one32 int32 = 1
+ v64 int64 = 11 // ensure it's not 2**n +/- 1
+ v64_n int64 = -11
+ v32 int32 = 11
+ v32_n int32 = -11
+ uv32 uint32 = 19
+ uz uint8 = 1 // for lowering to SLL/SRL/SRA
)
var crTests = []struct {
@@ -39,6 +41,8 @@
{"MAddVar32", testMAddVar32},
{"MSubVar64", testMSubVar64},
{"MSubVar32", testMSubVar32},
+ {"AddShift32", testAddShift32},
+ {"SubShift32", testSubShift32},
}
var crBenches = []struct {
@@ -58,9 +62,6 @@
// and machine code sequences are covered.
// It's for arm64 initially, please see https://github.com/golang/go/issues/38740
func TestCondRewrite(t *testing.T) {
- if runtime.GOARCH == "arm" {
- t.Skip("fix on arm expected!")
- }
for _, test := range crTests {
t.Run(test.name, test.tf)
}
@@ -408,6 +409,66 @@
}
}
+// 32-bit ADDshift, pick up 1~2 scenarios randomly for each condition
+func testAddShift32(t *testing.T) {
+ if x32+v32<<1 < 0 {
+ } else {
+ t.Errorf("'%#x + %#x<<%#x < 0' failed", x32, v32, 1)
+ }
+
+ if x32+v32>>1 <= 0 {
+ } else {
+ t.Errorf("'%#x + %#x>>%#x <= 0' failed", x32, v32, 1)
+ }
+
+ if x32+int32(uv32>>1) > 0 {
+ t.Errorf("'%#x + int32(%#x>>%#x) > 0' failed", x32, uv32, 1)
+ }
+
+ if x32+v32<<uz >= 0 {
+ t.Errorf("'%#x + %#x<<%#x >= 0' failed", x32, v32, uz)
+ }
+
+ if x32+v32>>uz > 0 {
+ t.Errorf("'%#x + %#x>>%#x > 0' failed", x32, v32, uz)
+ }
+
+ if x32+int32(uv32>>uz) < 0 {
+ } else {
+ t.Errorf("'%#x + int32(%#x>>%#x) < 0' failed", x32, uv32, uz)
+ }
+}
+
+// 32-bit SUBshift, pick up 1~2 scenarios randomly for each condition
+func testSubShift32(t *testing.T) {
+ if y32-v32<<1 > 0 {
+ } else {
+ t.Errorf("'%#x - %#x<<%#x > 0' failed", y32, v32, 1)
+ }
+
+ if y32-v32>>1 < 0 {
+ t.Errorf("'%#x - %#x>>%#x < 0' failed", y32, v32, 1)
+ }
+
+ if y32-int32(uv32>>1) >= 0 {
+ } else {
+ t.Errorf("'%#x - int32(%#x>>%#x) >= 0' failed", y32, uv32, 1)
+ }
+
+ if y32-v32<<uz < 0 {
+ t.Errorf("'%#x - %#x<<%#x < 0' failed", y32, v32, uz)
+ }
+
+ if y32-v32>>uz >= 0 {
+ } else {
+ t.Errorf("'%#x - %#x>>%#x >= 0' failed", y32, v32, uz)
+ }
+
+ if y32-int32(uv32>>uz) <= 0 {
+ t.Errorf("'%#x - int32(%#x>>%#x) <= 0' failed", y32, uv32, uz)
+ }
+}
+
var rnd = rand.New(rand.NewSource(0))
var sink int64
diff --git a/src/cmd/compile/internal/ssa/tuple.go b/src/cmd/compile/internal/ssa/tuple.go
new file mode 100644
index 0000000..38deabf
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/tuple.go
@@ -0,0 +1,59 @@
+// 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 ssa
+
+// tightenTupleSelectors ensures that tuple selectors (Select0 and
+// Select1 ops) are in the same block as their tuple generator. The
+// function also ensures that there are no duplicate tuple selectors.
+// These properties are expected by the scheduler but may not have
+// been maintained by the optimization pipeline up to this point.
+//
+// See issues 16741 and 39472.
+func tightenTupleSelectors(f *Func) {
+ selectors := make(map[struct {
+ id ID
+ op Op
+ }]*Value)
+ for _, b := range f.Blocks {
+ for _, selector := range b.Values {
+ if selector.Op != OpSelect0 && selector.Op != OpSelect1 {
+ continue
+ }
+
+ // Get the tuple generator to use as a key for de-duplication.
+ tuple := selector.Args[0]
+ if !tuple.Type.IsTuple() {
+ f.Fatalf("arg of tuple selector %s is not a tuple: %s", selector.String(), tuple.LongString())
+ }
+
+ // If there is a pre-existing selector in the target block then
+ // use that. Do this even if the selector is already in the
+ // target block to avoid duplicate tuple selectors.
+ key := struct {
+ id ID
+ op Op
+ }{tuple.ID, selector.Op}
+ if t := selectors[key]; t != nil {
+ if selector != t {
+ selector.copyOf(t)
+ }
+ continue
+ }
+
+ // If the selector is in the wrong block copy it into the target
+ // block.
+ if selector.Block != tuple.Block {
+ t := selector.copyInto(tuple.Block)
+ selector.copyOf(t)
+ selectors[key] = t
+ continue
+ }
+
+ // The selector is in the target block. Add it to the map so it
+ // cannot be duplicated.
+ selectors[key] = selector
+ }
+ }
+}
diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go
index 08ef056..e1cd496 100644
--- a/src/cmd/dist/test.go
+++ b/src/cmd/dist/test.go
@@ -178,15 +178,6 @@
return
}
- // We must unset GOROOT_FINAL before tests, because runtime/debug requires
- // correct access to source code, so if we have GOROOT_FINAL in effect,
- // at least runtime/debug test will fail.
- // If GOROOT_FINAL was set before, then now all the commands will appear stale.
- // Nothing we can do about that other than not checking them below.
- // (We call checkNotStale but only with "std" not "cmd".)
- os.Setenv("GOROOT_FINAL_OLD", os.Getenv("GOROOT_FINAL")) // for cmd/link test
- os.Unsetenv("GOROOT_FINAL")
-
for _, name := range t.runNames {
if !t.isRegisteredTestName(name) {
fatalf("unknown test %q", name)
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index 4c30de4..021930a 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -124,7 +124,6 @@
fmt.Printf("SKIP\n")
return
}
- os.Unsetenv("GOROOT_FINAL")
flag.Parse()
@@ -180,6 +179,11 @@
}
testGOROOT = goEnv("GOROOT")
os.Setenv("TESTGO_GOROOT", testGOROOT)
+ // Ensure that GOROOT is set explicitly.
+ // Otherwise, if the toolchain was built with GOROOT_FINAL set but has not
+ // yet been moved to its final location, programs that invoke runtime.GOROOT
+ // may accidentally use the wrong path.
+ os.Setenv("GOROOT", testGOROOT)
// The whole GOROOT/pkg tree was installed using the GOHOSTOS/GOHOSTARCH
// toolchain (installed in GOROOT/pkg/tool/GOHOSTOS_GOHOSTARCH).
@@ -216,8 +220,10 @@
}
testCC = strings.TrimSpace(string(out))
- if out, err := exec.Command(testGo, "env", "CGO_ENABLED").Output(); err != nil {
- fmt.Fprintf(os.Stderr, "running testgo failed: %v\n", err)
+ cmd := exec.Command(testGo, "env", "CGO_ENABLED")
+ cmd.Stderr = new(strings.Builder)
+ if out, err := cmd.Output(); err != nil {
+ fmt.Fprintf(os.Stderr, "running testgo failed: %v\n%s", err, cmd.Stderr)
canRun = false
} else {
canCgo, err = strconv.ParseBool(strings.TrimSpace(string(out)))
diff --git a/src/cmd/go/internal/web/http.go b/src/cmd/go/internal/web/http.go
index beb80c5..e050980 100644
--- a/src/cmd/go/internal/web/http.go
+++ b/src/cmd/go/internal/web/http.go
@@ -13,6 +13,7 @@
import (
"crypto/tls"
+ "errors"
"fmt"
"mime"
"net/http"
@@ -47,6 +48,13 @@
lastHop := via[len(via)-1].URL
return fmt.Errorf("redirected from secure URL %s to insecure URL %s", lastHop, req.URL)
}
+
+ // Go's http.DefaultClient allows 10 redirects before returning an error.
+ // The securityPreservingHTTPClient also uses this default policy to avoid
+ // Go command hangs.
+ if len(via) >= 10 {
+ return errors.New("stopped after 10 redirects")
+ }
return nil
},
}
diff --git a/src/cmd/go/internal/work/gc.go b/src/cmd/go/internal/work/gc.go
index 318d688..f1d08e0 100644
--- a/src/cmd/go/internal/work/gc.go
+++ b/src/cmd/go/internal/work/gc.go
@@ -168,7 +168,7 @@
CheckFlags:
for _, flag := range gcflags {
// Concurrent compilation is presumed incompatible with any gcflags,
- // except for a small whitelist of commonly used flags.
+ // except for known commonly used flags.
// If the user knows better, they can manually add their own -c to the gcflags.
switch flag {
case "-N", "-l", "-S", "-B", "-C", "-I":
diff --git a/src/cmd/go/proxy_test.go b/src/cmd/go/proxy_test.go
index 8214488..2a4d293 100644
--- a/src/cmd/go/proxy_test.go
+++ b/src/cmd/go/proxy_test.go
@@ -174,6 +174,25 @@
return
}
+ // Request for $GOPROXY/redirect/<count>/... goes to redirects.
+ if strings.HasPrefix(path, "redirect/") {
+ path = path[len("redirect/"):]
+ if j := strings.Index(path, "/"); j >= 0 {
+ count, err := strconv.Atoi(path[:j])
+ if err != nil {
+ return
+ }
+
+ // The last redirect.
+ if count <= 1 {
+ http.Redirect(w, r, fmt.Sprintf("/mod/%s", path[j+1:]), 302)
+ return
+ }
+ http.Redirect(w, r, fmt.Sprintf("/mod/redirect/%d/%s", count-1, path[j+1:]), 302)
+ return
+ }
+ }
+
// Request for $GOPROXY/sumdb/<name>/supported
// is checking whether it's OK to access sumdb via the proxy.
if path == "sumdb/"+testSumDBName+"/supported" {
diff --git a/src/cmd/go/script_test.go b/src/cmd/go/script_test.go
index a49a705..2e8f18a 100644
--- a/src/cmd/go/script_test.go
+++ b/src/cmd/go/script_test.go
@@ -130,6 +130,7 @@
"GOPROXY=" + proxyURL,
"GOPRIVATE=",
"GOROOT=" + testGOROOT,
+ "GOROOT_FINAL=" + os.Getenv("GOROOT_FINAL"), // causes spurious rebuilds and breaks the "stale" built-in if not propagated
"TESTGO_GOROOT=" + testGOROOT,
"GOSUMDB=" + testSumDBVerifierKey,
"GONOPROXY=",
diff --git a/src/cmd/go/testdata/script/README b/src/cmd/go/testdata/script/README
index c7fa7cf..76d6651 100644
--- a/src/cmd/go/testdata/script/README
+++ b/src/cmd/go/testdata/script/README
@@ -34,6 +34,7 @@
GOPATH=$WORK/gopath
GOPROXY=<local module proxy serving from cmd/go/testdata/mod>
GOROOT=<actual GOROOT>
+ GOROOT_FINAL=<actual GOROOT_FINAL>
TESTGO_GOROOT=<GOROOT used to build cmd/go, for use in tests that may change GOROOT>
HOME=/no-home
PATH=<actual PATH>
diff --git a/src/cmd/go/testdata/script/build_trimpath.txt b/src/cmd/go/testdata/script/build_trimpath.txt
index cfab807..ad78bcf 100644
--- a/src/cmd/go/testdata/script/build_trimpath.txt
+++ b/src/cmd/go/testdata/script/build_trimpath.txt
@@ -1,5 +1,9 @@
[short] skip
+# If GOROOT_FINAL is set, 'go build -trimpath' bakes that into the resulting
+# binary instead of GOROOT. Explicitly unset it here.
+env GOROOT_FINAL=
+
# Set up two identical directories that can be used as GOPATH.
env GO111MODULE=on
mkdir $WORK/a/src/paths $WORK/b/src/paths
diff --git a/src/cmd/go/testdata/script/goroot_executable.txt b/src/cmd/go/testdata/script/goroot_executable.txt
index 4e04bad..fdbcde0 100644
--- a/src/cmd/go/testdata/script/goroot_executable.txt
+++ b/src/cmd/go/testdata/script/goroot_executable.txt
@@ -2,6 +2,13 @@
mkdir $WORK/new/bin
+# In this test, we are specifically checking the logic for deriving
+# the value of GOROOT from runtime.GOROOT.
+# GOROOT_FINAL changes the default behavior of runtime.GOROOT,
+# and will thus cause the test to fail if it is set when our
+# new cmd/go is built.
+env GOROOT_FINAL=
+
go build -o $WORK/new/bin/go$GOEXE cmd/go &
go build -o $WORK/bin/check$GOEXE check.go &
wait
diff --git a/src/cmd/go/testdata/script/mod_convert_dep.txt b/src/cmd/go/testdata/script/mod_convert_dep.txt
index 267c90e..ad22aca 100644
--- a/src/cmd/go/testdata/script/mod_convert_dep.txt
+++ b/src/cmd/go/testdata/script/mod_convert_dep.txt
@@ -20,7 +20,6 @@
! go list .
stderr 'cannot find main module'
! stderr 'Gopkg.lock'
-! stderr 'go mod init'
-- $WORK/test/Gopkg.lock --
-- $WORK/test/x/x.go --
diff --git a/src/cmd/go/testdata/script/mod_get_too_many_redirects.txt b/src/cmd/go/testdata/script/mod_get_too_many_redirects.txt
new file mode 100644
index 0000000..9cbe0d2
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_get_too_many_redirects.txt
@@ -0,0 +1,10 @@
+env GO111MODULE=on
+env GOPROXYBASE=$GOPROXY
+env GOPROXY=$GOPROXYBASE/redirect/11
+env GOSUMDB=off
+
+! go get -d rsc.io/quote@v1.2.0
+stderr 'stopped after 10 redirects'
+
+env GOPROXY=$GOPROXYBASE/redirect/9
+go get -d rsc.io/quote@v1.2.0
diff --git a/src/cmd/internal/moddeps/moddeps_test.go b/src/cmd/internal/moddeps/moddeps_test.go
index 5d73edd..2e61673 100644
--- a/src/cmd/internal/moddeps/moddeps_test.go
+++ b/src/cmd/internal/moddeps/moddeps_test.go
@@ -36,7 +36,7 @@
if err != nil {
return err
}
- if info.Name() == "vendor" || info.Name() == "testdata" {
+ if info.IsDir() && (info.Name() == "vendor" || info.Name() == "testdata") {
return filepath.SkipDir
}
if path == filepath.Join(runtime.GOROOT(), "pkg") {
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go
index 7f5cba6..df17729 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -460,7 +460,6 @@
{AFCVTZSD, C_FREG, C_NONE, C_NONE, C_REG, 29, 4, 0, 0, 0},
{ASCVTFD, C_REG, C_NONE, C_NONE, C_FREG, 29, 4, 0, 0, 0},
{AFCVTSD, C_FREG, C_NONE, C_NONE, C_FREG, 29, 4, 0, 0, 0},
- {AVCNT, C_ARNG, C_NONE, C_NONE, C_ARNG, 29, 4, 0, 0, 0},
{AVMOV, C_ELEM, C_NONE, C_NONE, C_REG, 73, 4, 0, 0, 0},
{AVMOV, C_ELEM, C_NONE, C_NONE, C_ELEM, 92, 4, 0, 0, 0},
{AVMOV, C_ELEM, C_NONE, C_NONE, C_VREG, 80, 4, 0, 0, 0},
@@ -2773,6 +2772,7 @@
oprangeset(AVSRI, t)
case AVREV32:
+ oprangeset(AVCNT, t)
oprangeset(AVRBIT, t)
oprangeset(AVREV64, t)
oprangeset(AVREV16, t)
@@ -4523,7 +4523,7 @@
c.ctxt.Diag("invalid arrangement: %v\n", p)
}
- if (p.As == AVMOV || p.As == AVRBIT) && (af != ARNG_16B && af != ARNG_8B) {
+ if (p.As == AVMOV || p.As == AVRBIT || p.As == AVCNT) && (af != ARNG_16B && af != ARNG_8B) {
c.ctxt.Diag("invalid arrangement: %v", p)
}
diff --git a/src/cmd/internal/objabi/util.go b/src/cmd/internal/objabi/util.go
index 2f94ec6..f7873a4 100644
--- a/src/cmd/internal/objabi/util.go
+++ b/src/cmd/internal/objabi/util.go
@@ -134,7 +134,7 @@
}
func Framepointer_enabled(goos, goarch string) bool {
- return framepointer_enabled != 0 && (goarch == "amd64" || goarch == "arm64" && goos == "linux")
+ return framepointer_enabled != 0 && (goarch == "amd64" || goarch == "arm64" && (goos == "linux" || goos == "darwin"))
}
func addexp(s string) {
diff --git a/src/cmd/link/dwarf_test.go b/src/cmd/link/dwarf_test.go
index 326f493..ac6937c 100644
--- a/src/cmd/link/dwarf_test.go
+++ b/src/cmd/link/dwarf_test.go
@@ -33,8 +33,8 @@
t.Fatalf("go list: %v\n%s", err, out)
}
if string(out) != "false\n" {
- if os.Getenv("GOROOT_FINAL_OLD") != "" {
- t.Skip("cmd/link is stale, but $GOROOT_FINAL_OLD is set")
+ if strings.HasPrefix(testenv.Builder(), "darwin-") {
+ t.Skipf("cmd/link is spuriously stale on Darwin builders - see #33598")
}
t.Fatalf("cmd/link is stale - run go install cmd/link")
}
diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go
index 9b4214b..f87776e 100644
--- a/src/cmd/link/internal/loader/loader.go
+++ b/src/cmd/link/internal/loader/loader.go
@@ -616,15 +616,15 @@
}
fmt.Fprintf(os.Stderr, "cmd/link: while reading object for '%v': duplicate symbol '%s', previous def at '%v', with mismatched payload: %s\n", r.unit.Lib, name, rdup.unit.Lib, reason)
- // For the moment, whitelist DWARF subprogram DIEs for
+ // For the moment, allow DWARF subprogram DIEs for
// auto-generated wrapper functions. What seems to happen
// here is that we get different line numbers on formal
// params; I am guessing that the pos is being inherited
// from the spot where the wrapper is needed.
- whitelist := strings.HasPrefix(name, "go.info.go.interface") ||
+ allowed := strings.HasPrefix(name, "go.info.go.interface") ||
strings.HasPrefix(name, "go.info.go.builtin") ||
strings.HasPrefix(name, "go.debuglines")
- if !whitelist {
+ if !allowed {
l.strictDupMsgs++
}
}
diff --git a/src/cmd/objdump/objdump_test.go b/src/cmd/objdump/objdump_test.go
index c974d67..a9dc7d1 100644
--- a/src/cmd/objdump/objdump_test.go
+++ b/src/cmd/objdump/objdump_test.go
@@ -138,7 +138,11 @@
args = append(args, flags...)
args = append(args, "fmthello.go")
cmd := exec.Command(testenv.GoToolPath(t), args...)
- cmd.Dir = "testdata" // "Bad line" bug #36683 is sensitive to being run in the source directory
+ // "Bad line" bug #36683 is sensitive to being run in the source directory.
+ cmd.Dir = "testdata"
+ // Ensure that the source file location embedded in the binary matches our
+ // actual current GOROOT, instead of GOROOT_FINAL if set.
+ cmd.Env = append(os.Environ(), "GOROOT_FINAL=")
t.Logf("Running %v", cmd.Args)
out, err := cmd.CombinedOutput()
if err != nil {
diff --git a/src/crypto/tls/common.go b/src/crypto/tls/common.go
index fd21ae8..3a5ca22 100644
--- a/src/crypto/tls/common.go
+++ b/src/crypto/tls/common.go
@@ -278,6 +278,8 @@
serverCertificates []*x509.Certificate // Certificate chain presented by the server
verifiedChains [][]*x509.Certificate // Certificate chains we built for verification
receivedAt time.Time // When the session ticket was received from the server
+ ocspResponse []byte // Stapled OCSP response presented by the server
+ scts [][]byte // SCTs presented by the server
// TLS 1.3 fields.
nonce []byte // Ticket nonce sent by the server, to derive PSK
diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go
index 40c8e02..46b0a77 100644
--- a/src/crypto/tls/handshake_client.go
+++ b/src/crypto/tls/handshake_client.go
@@ -728,10 +728,17 @@
return false, errors.New("tls: server resumed a session with a different cipher suite")
}
- // Restore masterSecret and peerCerts from previous state
+ // Restore masterSecret, peerCerts, and ocspResponse from previous state
hs.masterSecret = hs.session.masterSecret
c.peerCertificates = hs.session.serverCertificates
c.verifiedChains = hs.session.verifiedChains
+ c.ocspResponse = hs.session.ocspResponse
+ // Let the ServerHello SCTs override the session SCTs from the original
+ // connection, if any are provided
+ if len(c.scts) == 0 && len(hs.session.scts) != 0 {
+ c.scts = hs.session.scts
+ }
+
return true, nil
}
@@ -788,6 +795,8 @@
serverCertificates: c.peerCertificates,
verifiedChains: c.verifiedChains,
receivedAt: c.config.time(),
+ ocspResponse: c.ocspResponse,
+ scts: c.scts,
}
return nil
diff --git a/src/crypto/tls/handshake_client_test.go b/src/crypto/tls/handshake_client_test.go
index 1cda901..12b0254 100644
--- a/src/crypto/tls/handshake_client_test.go
+++ b/src/crypto/tls/handshake_client_test.go
@@ -19,6 +19,7 @@
"os"
"os/exec"
"path/filepath"
+ "reflect"
"strconv"
"strings"
"testing"
@@ -2430,3 +2431,83 @@
t.Errorf("client unexpectedly reacted to a canary in TLS 1.0")
}
}
+
+func TestResumptionKeepsOCSPAndSCT(t *testing.T) {
+ t.Run("TLSv12", func(t *testing.T) { testResumptionKeepsOCSPAndSCT(t, VersionTLS12) })
+ t.Run("TLSv13", func(t *testing.T) { testResumptionKeepsOCSPAndSCT(t, VersionTLS13) })
+}
+
+func testResumptionKeepsOCSPAndSCT(t *testing.T, ver uint16) {
+ issuer, err := x509.ParseCertificate(testRSACertificateIssuer)
+ if err != nil {
+ t.Fatalf("failed to parse test issuer")
+ }
+ roots := x509.NewCertPool()
+ roots.AddCert(issuer)
+ clientConfig := &Config{
+ MaxVersion: ver,
+ ClientSessionCache: NewLRUClientSessionCache(32),
+ ServerName: "example.golang",
+ RootCAs: roots,
+ }
+ serverConfig := testConfig.Clone()
+ serverConfig.MaxVersion = ver
+ serverConfig.Certificates[0].OCSPStaple = []byte{1, 2, 3}
+ serverConfig.Certificates[0].SignedCertificateTimestamps = [][]byte{{4, 5, 6}}
+
+ _, ccs, err := testHandshake(t, clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+ // after a new session we expect to see OCSPResponse and
+ // SignedCertificateTimestamps populated as usual
+ if !bytes.Equal(ccs.OCSPResponse, serverConfig.Certificates[0].OCSPStaple) {
+ t.Errorf("client ConnectionState contained unexpected OCSPResponse: wanted %v, got %v",
+ serverConfig.Certificates[0].OCSPStaple, ccs.OCSPResponse)
+ }
+ if !reflect.DeepEqual(ccs.SignedCertificateTimestamps, serverConfig.Certificates[0].SignedCertificateTimestamps) {
+ t.Errorf("client ConnectionState contained unexpected SignedCertificateTimestamps: wanted %v, got %v",
+ serverConfig.Certificates[0].SignedCertificateTimestamps, ccs.SignedCertificateTimestamps)
+ }
+
+ // if the server doesn't send any SCTs, repopulate the old SCTs
+ oldSCTs := serverConfig.Certificates[0].SignedCertificateTimestamps
+ serverConfig.Certificates[0].SignedCertificateTimestamps = nil
+ _, ccs, err = testHandshake(t, clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+ if !ccs.DidResume {
+ t.Fatalf("expected session to be resumed")
+ }
+ // after a resumed session we also expect to see OCSPResponse
+ // and SignedCertificateTimestamps populated
+ if !bytes.Equal(ccs.OCSPResponse, serverConfig.Certificates[0].OCSPStaple) {
+ t.Errorf("client ConnectionState contained unexpected OCSPResponse after resumption: wanted %v, got %v",
+ serverConfig.Certificates[0].OCSPStaple, ccs.OCSPResponse)
+ }
+ if !reflect.DeepEqual(ccs.SignedCertificateTimestamps, oldSCTs) {
+ t.Errorf("client ConnectionState contained unexpected SignedCertificateTimestamps after resumption: wanted %v, got %v",
+ oldSCTs, ccs.SignedCertificateTimestamps)
+ }
+
+ // Only test overriding the SCTs for TLS 1.2, since in 1.3
+ // the server won't send the message containing them
+ if ver == VersionTLS13 {
+ return
+ }
+
+ // if the server changes the SCTs it sends, they should override the saved SCTs
+ serverConfig.Certificates[0].SignedCertificateTimestamps = [][]byte{{7, 8, 9}}
+ _, ccs, err = testHandshake(t, clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+ if !ccs.DidResume {
+ t.Fatalf("expected session to be resumed")
+ }
+ if !reflect.DeepEqual(ccs.SignedCertificateTimestamps, serverConfig.Certificates[0].SignedCertificateTimestamps) {
+ t.Errorf("client ConnectionState contained unexpected SignedCertificateTimestamps after resumption: wanted %v, got %v",
+ serverConfig.Certificates[0].SignedCertificateTimestamps, ccs.SignedCertificateTimestamps)
+ }
+}
diff --git a/src/crypto/tls/handshake_client_tls13.go b/src/crypto/tls/handshake_client_tls13.go
index 35a00f2..9c61105 100644
--- a/src/crypto/tls/handshake_client_tls13.go
+++ b/src/crypto/tls/handshake_client_tls13.go
@@ -334,6 +334,8 @@
c.didResume = true
c.peerCertificates = hs.session.serverCertificates
c.verifiedChains = hs.session.verifiedChains
+ c.ocspResponse = hs.session.ocspResponse
+ c.scts = hs.session.scts
return nil
}
@@ -666,6 +668,8 @@
nonce: msg.nonce,
useBy: c.config.time().Add(lifetime),
ageAdd: msg.ageAdd,
+ ocspResponse: c.ocspResponse,
+ scts: c.scts,
}
cacheKey := clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
diff --git a/src/crypto/x509/x509.go b/src/crypto/x509/x509.go
index 288c9c6..338b488 100644
--- a/src/crypto/x509/x509.go
+++ b/src/crypto/x509/x509.go
@@ -2129,16 +2129,13 @@
authorityKeyId = parent.SubjectKeyId
}
- encodedPublicKey := asn1.BitString{BitLength: len(publicKeyBytes) * 8, Bytes: publicKeyBytes}
- pki := publicKeyInfo{nil, publicKeyAlgorithm, encodedPublicKey}
subjectKeyId := template.SubjectKeyId
if len(subjectKeyId) == 0 && template.IsCA {
- // SubjectKeyId generated using method 1 in RFC 5280, Section 4.2.1.2
- b, err := asn1.Marshal(pki)
- if err != nil {
- return nil, err
- }
- h := sha1.Sum(b)
+ // SubjectKeyId generated using method 1 in RFC 5280, Section 4.2.1.2:
+ // (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the
+ // value of the BIT STRING subjectPublicKey (excluding the tag,
+ // length, and number of unused bits).
+ h := sha1.Sum(publicKeyBytes)
subjectKeyId = h[:]
}
@@ -2147,6 +2144,7 @@
return
}
+ encodedPublicKey := asn1.BitString{BitLength: len(publicKeyBytes) * 8, Bytes: publicKeyBytes}
c := tbsCertificate{
Version: 2,
SerialNumber: template.SerialNumber,
@@ -2154,7 +2152,7 @@
Issuer: asn1.RawValue{FullBytes: asn1Issuer},
Validity: validity{template.NotBefore.UTC(), template.NotAfter.UTC()},
Subject: asn1.RawValue{FullBytes: asn1Subject},
- PublicKey: pki,
+ PublicKey: publicKeyInfo{nil, publicKeyAlgorithm, encodedPublicKey},
Extensions: extensions,
}
diff --git a/src/go/internal/srcimporter/srcimporter.go b/src/go/internal/srcimporter/srcimporter.go
index daef27c..90bb3a9 100644
--- a/src/go/internal/srcimporter/srcimporter.go
+++ b/src/go/internal/srcimporter/srcimporter.go
@@ -20,6 +20,7 @@
"path/filepath"
"strings"
"sync"
+ _ "unsafe" // for go:linkname
)
// An Importer provides the context for importing packages from source code.
@@ -133,7 +134,7 @@
// build.Context's VFS.
conf.FakeImportC = true
} else {
- conf.UsesCgo = true
+ setUsesCgo(&conf)
file, err := p.cgo(bp)
if err != nil {
return nil, err
@@ -260,3 +261,6 @@
}
return filepath.Join(elem...)
}
+
+//go:linkname setUsesCgo go/types.srcimporter_setUsesCgo
+func setUsesCgo(conf *types.Config)
diff --git a/src/go/types/api.go b/src/go/types/api.go
index 7787b88..1abcd9d 100644
--- a/src/go/types/api.go
+++ b/src/go/types/api.go
@@ -105,14 +105,14 @@
// Do not use casually!
FakeImportC bool
- // If UsesCgo is set, the type checker expects the
+ // If go115UsesCgo is set, the type checker expects the
// _cgo_gotypes.go file generated by running cmd/cgo to be
// provided as a package source file. Qualified identifiers
// referring to package C will be resolved to cgo-provided
// declarations within _cgo_gotypes.go.
//
- // It is an error to set both FakeImportC and UsesCgo.
- UsesCgo bool
+ // It is an error to set both FakeImportC and go115UsesCgo.
+ go115UsesCgo bool
// If Error != nil, it is called with each error found
// during type checking; err has dynamic type Error.
@@ -140,6 +140,10 @@
DisableUnusedImportCheck bool
}
+func srcimporter_setUsesCgo(conf *Config) {
+ conf.go115UsesCgo = true
+}
+
// Info holds result type information for a type-checked package.
// Only the information for which a map is provided is collected.
// If the package has type errors, the collected information may
diff --git a/src/go/types/check.go b/src/go/types/check.go
index a94770f..007babd 100644
--- a/src/go/types/check.go
+++ b/src/go/types/check.go
@@ -248,10 +248,10 @@
// Files checks the provided files as part of the checker's package.
func (check *Checker) Files(files []*ast.File) error { return check.checkFiles(files) }
-var errBadCgo = errors.New("cannot use FakeImportC and UsesCgo together")
+var errBadCgo = errors.New("cannot use FakeImportC and go115UsesCgo together")
func (check *Checker) checkFiles(files []*ast.File) (err error) {
- if check.conf.FakeImportC && check.conf.UsesCgo {
+ if check.conf.FakeImportC && check.conf.go115UsesCgo {
return errBadCgo
}
diff --git a/src/go/types/resolver.go b/src/go/types/resolver.go
index f80b4ec..078adc5 100644
--- a/src/go/types/resolver.go
+++ b/src/go/types/resolver.go
@@ -141,10 +141,10 @@
}
// no package yet => import it
- if path == "C" && (check.conf.FakeImportC || check.conf.UsesCgo) {
+ if path == "C" && (check.conf.FakeImportC || check.conf.go115UsesCgo) {
imp = NewPackage("C", "C")
imp.fake = true // package scope is not populated
- imp.cgo = check.conf.UsesCgo
+ imp.cgo = check.conf.go115UsesCgo
} else {
// ordinary import
var err error
diff --git a/src/html/template/html.go b/src/html/template/html.go
index 13a0cd0..356b829 100644
--- a/src/html/template/html.go
+++ b/src/html/template/html.go
@@ -240,8 +240,7 @@
}
s = strings.ToLower(s)
if t := attrType(s); t != contentTypePlain {
- // TODO: Split attr and element name part filters so we can whitelist
- // attributes.
+ // TODO: Split attr and element name part filters so we can recognize known attributes.
return filterFailsafe
}
for _, r := range s {
diff --git a/src/internal/poll/fd_unix.go b/src/internal/poll/fd_unix.go
index 85c79bb..4872fa9 100644
--- a/src/internal/poll/fd_unix.go
+++ b/src/internal/poll/fd_unix.go
@@ -479,7 +479,7 @@
return dupCloseOnExecOld(fd)
}
-// dupCloseOnExecUnixOld is the traditional way to dup an fd and
+// dupCloseOnExecOld is the traditional way to dup an fd and
// set its O_CLOEXEC bit, using two system calls.
func dupCloseOnExecOld(fd int) (int, string, error) {
syscall.ForkLock.RLock()
diff --git a/src/make.bat b/src/make.bat
index f7955ec..277a34d 100644
--- a/src/make.bat
+++ b/src/make.bat
@@ -1,153 +1,152 @@
-:: Copyright 2012 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.
-
-:: Environment variables that control make.bat:
-::
-:: GOROOT_FINAL: The expected final Go root, baked into binaries.
-:: The default is the location of the Go tree during the build.
-::
-:: GOHOSTARCH: The architecture for host tools (compilers and
-:: binaries). Binaries of this type must be executable on the current
-:: system, so the only common reason to set this is to set
-:: GOHOSTARCH=386 on an amd64 machine.
-::
-:: GOARCH: The target architecture for installed packages and tools.
-::
-:: GOOS: The target operating system for installed packages and tools.
-::
-:: GO_GCFLAGS: Additional go tool compile arguments to use when
-:: building the packages and commands.
-::
-:: GO_LDFLAGS: Additional go tool link arguments to use when
-:: building the commands.
-::
-:: CGO_ENABLED: Controls cgo usage during the build. Set it to 1
-:: to include all cgo related files, .c and .go file with "cgo"
-:: build directive, in the build. Set it to 0 to ignore them.
-::
-:: CC: Command line to run to compile C code for GOHOSTARCH.
-:: Default is "gcc".
-::
-:: CC_FOR_TARGET: Command line to run compile C code for GOARCH.
-:: This is used by cgo. Default is CC.
-::
-:: FC: Command line to run to compile Fortran code.
-:: This is used by cgo. Default is "gfortran".
-
-@echo off
-
-:: Keep environment variables within this script
-:: unless invoked with --no-local.
-if x%1==x--no-local goto nolocal
-if x%2==x--no-local goto nolocal
-if x%3==x--no-local goto nolocal
-if x%4==x--no-local goto nolocal
-setlocal
-:nolocal
-
-set GOENV=off
-set GOBUILDFAIL=0
-set GOFLAGS=
-set GO111MODULE=
-
-if exist make.bat goto ok
-echo Must run make.bat from Go src directory.
-goto fail
-:ok
-
-:: Clean old generated file that will cause problems in the build.
-del /F ".\pkg\runtime\runtime_defs.go" 2>NUL
-
-:: Set GOROOT for build.
-cd ..
-set GOROOT_TEMP=%CD%
-set GOROOT=
-cd src
-set vflag=
-if x%1==x-v set vflag=-v
-if x%2==x-v set vflag=-v
-if x%3==x-v set vflag=-v
-if x%4==x-v set vflag=-v
-
-if not exist ..\bin\tool mkdir ..\bin\tool
-
-:: Calculating GOROOT_BOOTSTRAP
-if not "x%GOROOT_BOOTSTRAP%"=="x" goto bootstrapset
-for /f "tokens=*" %%g in ('where go 2^>nul') do (
- if "x%GOROOT_BOOTSTRAP%"=="x" (
- for /f "tokens=*" %%i in ('%%g env GOROOT 2^>nul') do (
- if /I not %%i==%GOROOT_TEMP% (
- set GOROOT_BOOTSTRAP=%%i
- )
- )
- )
-)
-if "x%GOROOT_BOOTSTRAP%"=="x" set GOROOT_BOOTSTRAP=%HOMEDRIVE%%HOMEPATH%\Go1.4
-
-:bootstrapset
-if not exist "%GOROOT_BOOTSTRAP%\bin\go.exe" goto bootstrapfail
-set GOROOT=%GOROOT_TEMP%
-set GOROOT_TEMP=
-
-echo Building Go cmd/dist using %GOROOT_BOOTSTRAP%
-if x%vflag==x-v echo cmd/dist
-setlocal
-set GOROOT=%GOROOT_BOOTSTRAP%
-set GOOS=
-set GOARCH=
-set GOBIN=
-set GO111MODULE=off
-"%GOROOT_BOOTSTRAP%\bin\go.exe" build -o cmd\dist\dist.exe .\cmd\dist
-endlocal
-if errorlevel 1 goto fail
-.\cmd\dist\dist.exe env -w -p >env.bat
-if errorlevel 1 goto fail
-call env.bat
-del env.bat
-if x%vflag==x-v echo.
-
-if x%1==x--dist-tool goto copydist
-if x%2==x--dist-tool goto copydist
-if x%3==x--dist-tool goto copydist
-if x%4==x--dist-tool goto copydist
-
-set buildall=-a
-if x%1==x--no-clean set buildall=
-if x%2==x--no-clean set buildall=
-if x%3==x--no-clean set buildall=
-if x%4==x--no-clean set buildall=
-if x%1==x--no-banner set buildall=%buildall% --no-banner
-if x%2==x--no-banner set buildall=%buildall% --no-banner
-if x%3==x--no-banner set buildall=%buildall% --no-banner
-if x%4==x--no-banner set buildall=%buildall% --no-banner
-
-:: Run dist bootstrap to complete make.bash.
-:: Bootstrap installs a proper cmd/dist, built with the new toolchain.
-:: Throw ours, built with Go 1.4, away after bootstrap.
-.\cmd\dist\dist.exe bootstrap %vflag% %buildall%
-if errorlevel 1 goto fail
-del .\cmd\dist\dist.exe
-goto end
-
-:: DO NOT ADD ANY NEW CODE HERE.
-:: The bootstrap+del above are the final step of make.bat.
-:: If something must be added, add it to cmd/dist's cmdbootstrap,
-:: to avoid needing three copies in three different shell languages
-:: (make.bash, make.bat, make.rc).
-
-:copydist
-mkdir "%GOTOOLDIR%" 2>NUL
-copy cmd\dist\dist.exe "%GOTOOLDIR%\"
-goto end
-
-:bootstrapfail
-echo ERROR: Cannot find %GOROOT_BOOTSTRAP%\bin\go.exe
-echo Set GOROOT_BOOTSTRAP to a working Go tree ^>= Go 1.4.
-
-:fail
-set GOBUILDFAIL=1
-if x%GOBUILDEXIT%==x1 exit %GOBUILDFAIL%
-
-:end
-
+:: Copyright 2012 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.
+
+:: Environment variables that control make.bat:
+::
+:: GOROOT_FINAL: The expected final Go root, baked into binaries.
+:: The default is the location of the Go tree during the build.
+::
+:: GOHOSTARCH: The architecture for host tools (compilers and
+:: binaries). Binaries of this type must be executable on the current
+:: system, so the only common reason to set this is to set
+:: GOHOSTARCH=386 on an amd64 machine.
+::
+:: GOARCH: The target architecture for installed packages and tools.
+::
+:: GOOS: The target operating system for installed packages and tools.
+::
+:: GO_GCFLAGS: Additional go tool compile arguments to use when
+:: building the packages and commands.
+::
+:: GO_LDFLAGS: Additional go tool link arguments to use when
+:: building the commands.
+::
+:: CGO_ENABLED: Controls cgo usage during the build. Set it to 1
+:: to include all cgo related files, .c and .go file with "cgo"
+:: build directive, in the build. Set it to 0 to ignore them.
+::
+:: CC: Command line to run to compile C code for GOHOSTARCH.
+:: Default is "gcc".
+::
+:: CC_FOR_TARGET: Command line to run compile C code for GOARCH.
+:: This is used by cgo. Default is CC.
+::
+:: FC: Command line to run to compile Fortran code.
+:: This is used by cgo. Default is "gfortran".
+
+@echo off
+
+:: Keep environment variables within this script
+:: unless invoked with --no-local.
+if x%1==x--no-local goto nolocal
+if x%2==x--no-local goto nolocal
+if x%3==x--no-local goto nolocal
+if x%4==x--no-local goto nolocal
+setlocal
+:nolocal
+
+set GOENV=off
+set GOBUILDFAIL=0
+set GOFLAGS=
+set GO111MODULE=
+
+if exist make.bat goto ok
+echo Must run make.bat from Go src directory.
+goto fail
+:ok
+
+:: Clean old generated file that will cause problems in the build.
+del /F ".\pkg\runtime\runtime_defs.go" 2>NUL
+
+:: Set GOROOT for build.
+cd ..
+set GOROOT_TEMP=%CD%
+set GOROOT=
+cd src
+set vflag=
+if x%1==x-v set vflag=-v
+if x%2==x-v set vflag=-v
+if x%3==x-v set vflag=-v
+if x%4==x-v set vflag=-v
+
+if not exist ..\bin\tool mkdir ..\bin\tool
+
+:: Calculating GOROOT_BOOTSTRAP
+if not "x%GOROOT_BOOTSTRAP%"=="x" goto bootstrapset
+for /f "tokens=*" %%g in ('where go 2^>nul') do (
+ if "x%GOROOT_BOOTSTRAP%"=="x" (
+ for /f "tokens=*" %%i in ('%%g env GOROOT 2^>nul') do (
+ if /I not %%i==%GOROOT_TEMP% (
+ set GOROOT_BOOTSTRAP=%%i
+ )
+ )
+ )
+)
+if "x%GOROOT_BOOTSTRAP%"=="x" set GOROOT_BOOTSTRAP=%HOMEDRIVE%%HOMEPATH%\Go1.4
+
+:bootstrapset
+if not exist "%GOROOT_BOOTSTRAP%\bin\go.exe" goto bootstrapfail
+set GOROOT=%GOROOT_TEMP%
+set GOROOT_TEMP=
+
+echo Building Go cmd/dist using %GOROOT_BOOTSTRAP%
+if x%vflag==x-v echo cmd/dist
+setlocal
+set GOROOT=%GOROOT_BOOTSTRAP%
+set GOOS=
+set GOARCH=
+set GOBIN=
+set GO111MODULE=off
+"%GOROOT_BOOTSTRAP%\bin\go.exe" build -o cmd\dist\dist.exe .\cmd\dist
+endlocal
+if errorlevel 1 goto fail
+.\cmd\dist\dist.exe env -w -p >env.bat
+if errorlevel 1 goto fail
+call env.bat
+del env.bat
+if x%vflag==x-v echo.
+
+if x%1==x--dist-tool goto copydist
+if x%2==x--dist-tool goto copydist
+if x%3==x--dist-tool goto copydist
+if x%4==x--dist-tool goto copydist
+
+set buildall=-a
+if x%1==x--no-clean set buildall=
+if x%2==x--no-clean set buildall=
+if x%3==x--no-clean set buildall=
+if x%4==x--no-clean set buildall=
+if x%1==x--no-banner set buildall=%buildall% --no-banner
+if x%2==x--no-banner set buildall=%buildall% --no-banner
+if x%3==x--no-banner set buildall=%buildall% --no-banner
+if x%4==x--no-banner set buildall=%buildall% --no-banner
+
+:: Run dist bootstrap to complete make.bash.
+:: Bootstrap installs a proper cmd/dist, built with the new toolchain.
+:: Throw ours, built with Go 1.4, away after bootstrap.
+.\cmd\dist\dist.exe bootstrap %vflag% %buildall%
+if errorlevel 1 goto fail
+del .\cmd\dist\dist.exe
+goto end
+
+:: DO NOT ADD ANY NEW CODE HERE.
+:: The bootstrap+del above are the final step of make.bat.
+:: If something must be added, add it to cmd/dist's cmdbootstrap,
+:: to avoid needing three copies in three different shell languages
+:: (make.bash, make.bat, make.rc).
+
+:copydist
+mkdir "%GOTOOLDIR%" 2>NUL
+copy cmd\dist\dist.exe "%GOTOOLDIR%\"
+goto end
+
+:bootstrapfail
+echo ERROR: Cannot find %GOROOT_BOOTSTRAP%\bin\go.exe
+echo Set GOROOT_BOOTSTRAP to a working Go tree ^>= Go 1.4.
+
+:fail
+set GOBUILDFAIL=1
+if x%GOBUILDEXIT%==x1 exit %GOBUILDFAIL%
+
+:end
diff --git a/src/net/http/request.go b/src/net/http/request.go
index e924e2a..fe6b609 100644
--- a/src/net/http/request.go
+++ b/src/net/http/request.go
@@ -503,7 +503,7 @@
// NOTE: This is not intended to reflect the actual Go version being used.
// It was changed at the time of Go 1.1 release because the former User-Agent
-// had ended up on a blacklist for some intrusion detection systems.
+// had ended up blocked by some intrusion detection systems.
// See https://codereview.appspot.com/7532043.
const defaultUserAgent = "Go-http-client/1.1"
diff --git a/src/net/http/server.go b/src/net/http/server.go
index b613c21..a995a50 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -1698,9 +1698,9 @@
time.Sleep(rstAvoidanceDelay)
}
-// validNextProto reports whether the proto is not a blacklisted ALPN
-// protocol name. Empty and built-in protocol types are blacklisted
-// and can't be overridden with alternate implementations.
+// validNextProto reports whether the proto is a valid ALPN protocol name.
+// Everything is valid except the empty string and built-in protocol types,
+// so that those can't be overridden with alternate implementations.
func validNextProto(proto string) bool {
switch proto {
case "", "http/1.1", "http/1.0":
diff --git a/src/os/file_unix.go b/src/os/file_unix.go
index b93e2bd..f2c00ae 100644
--- a/src/os/file_unix.go
+++ b/src/os/file_unix.go
@@ -202,10 +202,8 @@
break
}
- // On OS X, sigaction(2) doesn't guarantee that SA_RESTART will cause
- // open(2) to be restarted for regular files. This is easy to reproduce on
- // fuse file systems (see https://golang.org/issue/11180).
- if runtime.GOOS == "darwin" && e == syscall.EINTR {
+ // We have to check EINTR here, per issues 11180 and 39237.
+ if e == syscall.EINTR {
continue
}
diff --git a/src/os/removeall_at.go b/src/os/removeall_at.go
index e619851..37bf1b8 100644
--- a/src/os/removeall_at.go
+++ b/src/os/removeall_at.go
@@ -9,7 +9,6 @@
import (
"internal/syscall/unix"
"io"
- "runtime"
"syscall"
)
@@ -178,7 +177,7 @@
}
// See comment in openFileNolog.
- if runtime.GOOS == "darwin" && e == syscall.EINTR {
+ if e == syscall.EINTR {
continue
}
diff --git a/src/os/signal/internal/pty/pty.go b/src/os/signal/internal/pty/pty.go
index fb3ee1e..f8813ce 100644
--- a/src/os/signal/internal/pty/pty.go
+++ b/src/os/signal/internal/pty/pty.go
@@ -40,8 +40,8 @@
func (e *PtyError) Unwrap() error { return e.Errno }
-// Open returns a master pty and the name of the linked slave tty.
-func Open() (master *os.File, slave string, err error) {
+// Open returns a control pty and the name of the linked process tty.
+func Open() (pty *os.File, processTTY string, err error) {
m, err := C.posix_openpt(C.O_RDWR)
if err != nil {
return nil, "", ptyError("posix_openpt", err)
@@ -54,6 +54,6 @@
C.close(m)
return nil, "", ptyError("unlockpt", err)
}
- slave = C.GoString(C.ptsname(m))
- return os.NewFile(uintptr(m), "pty-master"), slave, nil
+ processTTY = C.GoString(C.ptsname(m))
+ return os.NewFile(uintptr(m), "pty"), processTTY, nil
}
diff --git a/src/os/signal/signal_cgo_test.go b/src/os/signal/signal_cgo_test.go
index 849a96e..a117221 100644
--- a/src/os/signal/signal_cgo_test.go
+++ b/src/os/signal/signal_cgo_test.go
@@ -19,7 +19,7 @@
"io"
"os"
"os/exec"
- "os/signal/internal/pty"
+ ptypkg "os/signal/internal/pty"
"strconv"
"strings"
"sync"
@@ -71,20 +71,20 @@
// The test only fails when using a "slow device," in this
// case a pseudo-terminal.
- master, sname, err := pty.Open()
+ pty, procTTYName, err := ptypkg.Open()
if err != nil {
- ptyErr := err.(*pty.PtyError)
+ ptyErr := err.(*ptypkg.PtyError)
if ptyErr.FuncName == "posix_openpt" && ptyErr.Errno == syscall.EACCES {
t.Skip("posix_openpt failed with EACCES, assuming chroot and skipping")
}
t.Fatal(err)
}
- defer master.Close()
- slave, err := os.OpenFile(sname, os.O_RDWR, 0)
+ defer pty.Close()
+ procTTY, err := os.OpenFile(procTTYName, os.O_RDWR, 0)
if err != nil {
t.Fatal(err)
}
- defer slave.Close()
+ defer procTTY.Close()
// Start an interactive shell.
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
@@ -92,9 +92,9 @@
cmd := exec.CommandContext(ctx, bash, "--norc", "--noprofile", "-i")
// Clear HISTFILE so that we don't read or clobber the user's bash history.
cmd.Env = append(os.Environ(), "HISTFILE=")
- cmd.Stdin = slave
- cmd.Stdout = slave
- cmd.Stderr = slave
+ cmd.Stdin = procTTY
+ cmd.Stdout = procTTY
+ cmd.Stderr = procTTY
cmd.SysProcAttr = &syscall.SysProcAttr{
Setsid: true,
Setctty: true,
@@ -105,21 +105,21 @@
t.Fatal(err)
}
- if err := slave.Close(); err != nil {
- t.Errorf("closing slave: %v", err)
+ if err := procTTY.Close(); err != nil {
+ t.Errorf("closing procTTY: %v", err)
}
progReady := make(chan bool)
sawPrompt := make(chan bool, 10)
const prompt = "prompt> "
- // Read data from master in the background.
+ // Read data from pty in the background.
var wg sync.WaitGroup
wg.Add(1)
defer wg.Wait()
go func() {
defer wg.Done()
- input := bufio.NewReader(master)
+ input := bufio.NewReader(pty)
var line, handled []byte
for {
b, err := input.ReadByte()
@@ -130,11 +130,11 @@
if perr, ok := err.(*os.PathError); ok {
err = perr.Err
}
- // EOF means master is closed.
+ // EOF means pty is closed.
// EIO means child process is done.
- // "file already closed" means deferred close of master has happened.
+ // "file already closed" means deferred close of pty has happened.
if err != io.EOF && err != syscall.EIO && !strings.Contains(err.Error(), "file already closed") {
- t.Logf("error reading from master: %v", err)
+ t.Logf("error reading from pty: %v", err)
}
return
}
@@ -161,7 +161,7 @@
}()
// Set the bash prompt so that we can see it.
- if _, err := master.Write([]byte("PS1='" + prompt + "'\n")); err != nil {
+ if _, err := pty.Write([]byte("PS1='" + prompt + "'\n")); err != nil {
t.Fatalf("setting prompt: %v", err)
}
select {
@@ -172,7 +172,7 @@
// Start a small program that reads from stdin
// (namely the code at the top of this function).
- if _, err := master.Write([]byte("GO_TEST_TERMINAL_SIGNALS=1 " + os.Args[0] + " -test.run=TestTerminalSignal\n")); err != nil {
+ if _, err := pty.Write([]byte("GO_TEST_TERMINAL_SIGNALS=1 " + os.Args[0] + " -test.run=TestTerminalSignal\n")); err != nil {
t.Fatal(err)
}
@@ -190,7 +190,7 @@
time.Sleep(pause)
// Send a ^Z to stop the program.
- if _, err := master.Write([]byte{26}); err != nil {
+ if _, err := pty.Write([]byte{26}); err != nil {
t.Fatalf("writing ^Z to pty: %v", err)
}
@@ -202,7 +202,7 @@
}
// Restart the stopped program.
- if _, err := master.Write([]byte("fg\n")); err != nil {
+ if _, err := pty.Write([]byte("fg\n")); err != nil {
t.Fatalf("writing %q to pty: %v", "fg", err)
}
@@ -217,7 +217,7 @@
// Write some data for the program to read,
// which should cause it to exit.
- if _, err := master.Write([]byte{'\n'}); err != nil {
+ if _, err := pty.Write([]byte{'\n'}); err != nil {
t.Fatalf("writing %q to pty: %v", "\n", err)
}
@@ -229,7 +229,7 @@
}
// Exit the shell with the program's exit status.
- if _, err := master.Write([]byte("exit $?\n")); err != nil {
+ if _, err := pty.Write([]byte("exit $?\n")); err != nil {
t.Fatalf("writing %q to pty: %v", "exit", err)
}
diff --git a/src/race.bat b/src/race.bat
index d26f318..8f03556 100644
--- a/src/race.bat
+++ b/src/race.bat
@@ -1,51 +1,51 @@
-:: Copyright 2013 The Go Authors. All rights reserved.
-:: Use of this source code is governed by a BSD-style
-:: license that can be found in the LICENSE file.
-
-:: race.bash tests the standard library under the race detector.
-:: https://golang.org/doc/articles/race_detector.html
-
-@echo off
-
-setlocal
-
-if exist make.bat goto ok
-echo race.bat must be run from go\src
-:: cannot exit: would kill parent command interpreter
-goto end
-:ok
-
-set GOROOT=%CD%\..
-call make.bat --dist-tool >NUL
-if errorlevel 1 goto fail
-.\cmd\dist\dist.exe env -w -p >env.bat
-if errorlevel 1 goto fail
-call env.bat
-del env.bat
-
-if %GOHOSTARCH% == amd64 goto continue
-echo Race detector is only supported on windows/amd64.
-goto fail
-
-:continue
-call make.bat --no-banner --no-local
-if %GOBUILDFAIL%==1 goto end
-echo # go install -race std
-go install -race std
-if errorlevel 1 goto fail
-
-go tool dist test -race
-
-if errorlevel 1 goto fail
-goto succ
-
-:fail
-set GOBUILDFAIL=1
-echo Fail.
-goto end
-
-:succ
-echo All tests passed.
-
-:end
-if x%GOBUILDEXIT%==x1 exit %GOBUILDFAIL%
+:: Copyright 2013 The Go Authors. All rights reserved.
+:: Use of this source code is governed by a BSD-style
+:: license that can be found in the LICENSE file.
+
+:: race.bash tests the standard library under the race detector.
+:: https://golang.org/doc/articles/race_detector.html
+
+@echo off
+
+setlocal
+
+if exist make.bat goto ok
+echo race.bat must be run from go\src
+:: cannot exit: would kill parent command interpreter
+goto end
+:ok
+
+set GOROOT=%CD%\..
+call make.bat --dist-tool >NUL
+if errorlevel 1 goto fail
+.\cmd\dist\dist.exe env -w -p >env.bat
+if errorlevel 1 goto fail
+call env.bat
+del env.bat
+
+if %GOHOSTARCH% == amd64 goto continue
+echo Race detector is only supported on windows/amd64.
+goto fail
+
+:continue
+call make.bat --no-banner --no-local
+if %GOBUILDFAIL%==1 goto end
+echo # go install -race std
+go install -race std
+if errorlevel 1 goto fail
+
+go tool dist test -race
+
+if errorlevel 1 goto fail
+goto succ
+
+:fail
+set GOBUILDFAIL=1
+echo Fail.
+goto end
+
+:succ
+echo All tests passed.
+
+:end
+if x%GOBUILDEXIT%==x1 exit %GOBUILDFAIL%
diff --git a/src/run.bat b/src/run.bat
index 69c1818..c299671 100644
--- a/src/run.bat
+++ b/src/run.bat
@@ -1,59 +1,54 @@
-:: Copyright 2012 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.
-
-@echo off
-
-if exist ..\bin\go.exe goto ok
-echo Must run run.bat from Go src directory after installing cmd/go.
-goto fail
-:ok
-
-:: Keep environment variables within this script
-:: unless invoked with --no-local.
-if x%1==x--no-local goto nolocal
-if x%2==x--no-local goto nolocal
-setlocal
-:nolocal
-
-set GOBUILDFAIL=0
-
-:: we disallow local import for non-local packages, if %GOROOT% happens
-:: to be under %GOPATH%, then some tests below will fail
-set GOPATH=
-:: Issue 14340: ignore GOBIN during all.bat.
-set GOBIN=
-set GOFLAGS=
-set GO111MODULE=
-
-rem TODO avoid rebuild if possible
-
-if x%1==x--no-rebuild goto norebuild
-echo ##### Building packages and commands.
-..\bin\go install -a -v std cmd
-if errorlevel 1 goto fail
-echo.
-:norebuild
-
-:: we must unset GOROOT_FINAL before tests, because runtime/debug requires
-:: correct access to source code, so if we have GOROOT_FINAL in effect,
-:: at least runtime/debug test will fail.
-set GOROOT_FINAL=
-
-:: get CGO_ENABLED
-..\bin\go env > env.bat
-if errorlevel 1 goto fail
-call env.bat
-del env.bat
-echo.
-
-..\bin\go tool dist test
-if errorlevel 1 goto fail
-echo.
-
-goto end
-
-:fail
-set GOBUILDFAIL=1
-
-:end
+:: Copyright 2012 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.
+
+@echo off
+
+if exist ..\bin\go.exe goto ok
+echo Must run run.bat from Go src directory after installing cmd/go.
+goto fail
+:ok
+
+:: Keep environment variables within this script
+:: unless invoked with --no-local.
+if x%1==x--no-local goto nolocal
+if x%2==x--no-local goto nolocal
+setlocal
+:nolocal
+
+set GOBUILDFAIL=0
+
+:: we disallow local import for non-local packages, if %GOROOT% happens
+:: to be under %GOPATH%, then some tests below will fail
+set GOPATH=
+:: Issue 14340: ignore GOBIN during all.bat.
+set GOBIN=
+set GOFLAGS=
+set GO111MODULE=
+
+rem TODO avoid rebuild if possible
+
+if x%1==x--no-rebuild goto norebuild
+echo ##### Building packages and commands.
+..\bin\go install -a -v std cmd
+if errorlevel 1 goto fail
+echo.
+:norebuild
+
+:: get CGO_ENABLED
+..\bin\go env > env.bat
+if errorlevel 1 goto fail
+call env.bat
+del env.bat
+echo.
+
+..\bin\go tool dist test
+if errorlevel 1 goto fail
+echo.
+
+goto end
+
+:fail
+set GOBUILDFAIL=1
+
+:end
diff --git a/src/runtime/cgo_sigaction.go b/src/runtime/cgo_sigaction.go
index bc5e078..de634dc 100644
--- a/src/runtime/cgo_sigaction.go
+++ b/src/runtime/cgo_sigaction.go
@@ -18,12 +18,12 @@
//go:nosplit
//go:nowritebarrierrec
func sigaction(sig uint32, new, old *sigactiont) {
- // The runtime package is explicitly blacklisted from sanitizer
- // instrumentation in racewalk.go, but we might be calling into instrumented C
- // functions here — so we need the pointer parameters to be properly marked.
+ // racewalk.go avoids adding sanitizing instrumentation to package runtime,
+ // but we might be calling into instrumented C functions here,
+ // so we need the pointer parameters to be properly marked.
//
- // Mark the input as having been written before the call and the output as
- // read after.
+ // Mark the input as having been written before the call
+ // and the output as read after.
if msanenabled && new != nil {
msanwrite(unsafe.Pointer(new), unsafe.Sizeof(*new))
}
diff --git a/src/runtime/debugcall.go b/src/runtime/debugcall.go
index 5cbe382..6c285ec 100644
--- a/src/runtime/debugcall.go
+++ b/src/runtime/debugcall.go
@@ -61,7 +61,7 @@
"debugCall16384",
"debugCall32768",
"debugCall65536":
- // These functions are whitelisted so that the debugger can initiate multiple function calls.
+ // These functions are allowed so that the debugger can initiate multiple function calls.
// See: https://golang.org/cl/161137/
return
}
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
index 77a5a38..eaf8db7 100644
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -976,6 +976,7 @@
throw("malloc called with no P")
}
}
+ var span *mspan
var x unsafe.Pointer
noscan := typ == nil || typ.ptrdata == 0
if size <= maxSmallSize {
@@ -1028,10 +1029,10 @@
return x
}
// Allocate a new maxTinySize block.
- span := c.alloc[tinySpanClass]
+ span = c.alloc[tinySpanClass]
v := nextFreeFast(span)
if v == 0 {
- v, _, shouldhelpgc = c.nextFree(tinySpanClass)
+ v, span, shouldhelpgc = c.nextFree(tinySpanClass)
}
x = unsafe.Pointer(v)
(*[2]uint64)(x)[0] = 0
@@ -1052,7 +1053,7 @@
}
size = uintptr(class_to_size[sizeclass])
spc := makeSpanClass(sizeclass, noscan)
- span := c.alloc[spc]
+ span = c.alloc[spc]
v := nextFreeFast(span)
if v == 0 {
v, span, shouldhelpgc = c.nextFree(spc)
@@ -1063,15 +1064,14 @@
}
}
} else {
- var s *mspan
shouldhelpgc = true
systemstack(func() {
- s = largeAlloc(size, needzero, noscan)
+ span = largeAlloc(size, needzero, noscan)
})
- s.freeindex = 1
- s.allocCount = 1
- x = unsafe.Pointer(s.base())
- size = s.elemsize
+ span.freeindex = 1
+ span.allocCount = 1
+ x = unsafe.Pointer(span.base())
+ size = span.elemsize
}
var scanSize uintptr
@@ -1112,7 +1112,7 @@
// This may be racing with GC so do it atomically if there can be
// a race marking the bit.
if gcphase != _GCoff {
- gcmarknewobject(uintptr(x), size, scanSize)
+ gcmarknewobject(span, uintptr(x), size, scanSize)
}
if raceenabled {
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go
index dafb463..fe988c4 100644
--- a/src/runtime/mgcmark.go
+++ b/src/runtime/mgcmark.go
@@ -1627,11 +1627,21 @@
//
//go:nowritebarrier
//go:nosplit
-func gcmarknewobject(obj, size, scanSize uintptr) {
+func gcmarknewobject(span *mspan, obj, size, scanSize uintptr) {
if useCheckmark { // The world should be stopped so this should not happen.
throw("gcmarknewobject called while doing checkmark")
}
- markBitsForAddr(obj).setMarked()
+
+ // Mark object.
+ objIndex := span.objIndex(obj)
+ span.markBitsForIndex(objIndex).setMarked()
+
+ // Mark span.
+ arena, pageIdx, pageMask := pageIndexOf(span.base())
+ if arena.pageMarks[pageIdx]&pageMask == 0 {
+ atomic.Or8(&arena.pageMarks[pageIdx], pageMask)
+ }
+
gcw := &getg().m.p.ptr().gcw
gcw.bytesMarked += uint64(size)
gcw.scanWork += int64(scanSize)
diff --git a/src/runtime/mstats.go b/src/runtime/mstats.go
index ba50872..6a8a34d 100644
--- a/src/runtime/mstats.go
+++ b/src/runtime/mstats.go
@@ -529,7 +529,7 @@
// Calculate memory allocator stats.
// During program execution we only count number of frees and amount of freed memory.
- // Current number of alive object in the heap and amount of alive heap memory
+ // Current number of alive objects in the heap and amount of alive heap memory
// are calculated by scanning all spans.
// Total number of mallocs is calculated as number of frees plus number of alive objects.
// Similarly, total amount of allocated memory is calculated as amount of freed memory
diff --git a/src/runtime/mwbbuf.go b/src/runtime/mwbbuf.go
index f444452..632769c 100644
--- a/src/runtime/mwbbuf.go
+++ b/src/runtime/mwbbuf.go
@@ -296,6 +296,13 @@
continue
}
mbits.setMarked()
+
+ // Mark span.
+ arena, pageIdx, pageMask := pageIndexOf(span.base())
+ if arena.pageMarks[pageIdx]&pageMask == 0 {
+ atomic.Or8(&arena.pageMarks[pageIdx], pageMask)
+ }
+
if span.spanclass.noscan() {
gcw.bytesMarked += uint64(span.elemsize)
continue
diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go
index ce2ec6d..1e86662 100644
--- a/src/runtime/symtab.go
+++ b/src/runtime/symtab.go
@@ -563,8 +563,8 @@
// given program counter address, or else nil.
//
// If pc represents multiple functions because of inlining, it returns
-// the a *Func describing the innermost function, but with an entry
-// of the outermost function.
+// the *Func describing the innermost function, but with an entry of
+// the outermost function.
func FuncForPC(pc uintptr) *Func {
f := findfunc(pc)
if !f.valid() {
diff --git a/test/codegen/comparisons.go b/test/codegen/comparisons.go
index eb2f331..9080857 100644
--- a/test/codegen/comparisons.go
+++ b/test/codegen/comparisons.go
@@ -253,6 +253,8 @@
// 'comparing to zero' expressions
// var + const
+// 'x-const' might be canonicalized to 'x+(-const)', so we check both
+// CMN and CMP for subtraction expressions to make the pattern robust.
func CmpToZero_ex1(a int64, e int32) int {
// arm64:`CMN`,-`ADD`,`(BMI|BPL)`
if a+3 < 0 {
@@ -269,37 +271,41 @@
return 2
}
- // arm64:`CMP`,-`SUB`,`(BMI|BPL)`
+ // arm64:`CMP|CMN`,-`(ADD|SUB)`,`(BMI|BPL)`
if a-7 < 0 {
return 3
}
- // arm64:`CMP`,-`SUB`,`(BMI|BPL)`
+ // arm64:`CMP|CMN`,-`(ADD|SUB)`,`(BMI|BPL)`
if a-11 >= 0 {
return 4
}
- // arm64:`CMP`,-`SUB`,`BEQ`,`(BMI|BPL)`
+ // arm64:`CMP|CMN`,-`(ADD|SUB)`,`BEQ`,`(BMI|BPL)`
if a-19 > 0 {
return 4
}
// arm64:`CMNW`,-`ADDW`,`(BMI|BPL)`
+ // arm:`CMN`,-`ADD`,`(BMI|BPL)`
if e+3 < 0 {
return 5
}
// arm64:`CMNW`,-`ADDW`,`(BMI|BPL)`
+ // arm:`CMN`,-`ADD`,`(BMI|BPL)`
if e+13 >= 0 {
return 6
}
- // arm64:`CMPW`,-`SUBW`,`(BMI|BPL)`
+ // arm64:`CMPW|CMNW`,`(BMI|BPL)`
+ // arm:`CMP|CMN`, -`(ADD|SUB)`, `(BMI|BPL)`
if e-7 < 0 {
return 7
}
- // arm64:`CMPW`,-`SUBW`,`(BMI|BPL)`
+ // arm64:`CMPW|CMNW`,`(BMI|BPL)`
+ // arm:`CMP|CMN`, -`(ADD|SUB)`, `(BMI|BPL)`
if e-11 >= 0 {
return 8
}
@@ -326,11 +332,13 @@
}
// arm64:`CMNW`,-`ADDW`,`(BMI|BPL)`
+ // arm:`CMN`,-`ADD`,`(BMI|BPL)`
if e+f < 0 {
return 5
}
// arm64:`CMNW`,-`ADDW`,`(BMI|BPL)`
+ // arm:`CMN`,-`ADD`,`(BMI|BPL)`
if f+g >= 0 {
return 6
}
@@ -350,11 +358,13 @@
}
// arm64:`CMNW`,-`MADDW`,`MULW`,`BEQ`,`(BMI|BPL)`
+ // arm:`CMN`,-`MULA`,`MUL`,`BEQ`,`(BMI|BPL)`
if e+f*g > 0 {
return 5
}
// arm64:`CMNW`,-`MADDW`,`MULW`,`BEQ`,`(BMI|BPL)`
+ // arm:`CMN`,-`MULA`,`MUL`,`BEQ`,`(BMI|BPL)`
if f+g*h <= 0 {
return 6
}
@@ -384,3 +394,16 @@
}
return 0
}
+
+func CmpToZero_ex5(e, f int32, u uint32) int {
+ // arm:`CMN`,-`ADD`,`BEQ`,`(BMI|BPL)`
+ if e+f<<1 > 0 {
+ return 1
+ }
+
+ // arm:`CMP`,-`SUB`,`(BMI|BPL)`
+ if f-int32(u>>2) >= 0 {
+ return 2
+ }
+ return 0
+}
diff --git a/test/fixedbugs/issue39472.go b/test/fixedbugs/issue39472.go
new file mode 100644
index 0000000..61444a2
--- /dev/null
+++ b/test/fixedbugs/issue39472.go
@@ -0,0 +1,12 @@
+// compile -N
+
+// 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 p
+
+func f(x float64) bool {
+ x += 1
+ return (x != 0) == (x != 0)
+}
diff --git a/test/winbatch.go b/test/winbatch.go
index 30e0e3c..c3b48d3 100644
--- a/test/winbatch.go
+++ b/test/winbatch.go
@@ -4,8 +4,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Check that batch files are maintained as CRLF files (consistent behaviour
-// on all operating systems). See https://github.com/golang/go/issues/37791
+// Check that batch files are maintained as CRLF files (consistent
+// behavior on all operating systems). See golang.org/issue/37791.
package main
@@ -13,18 +13,56 @@
"bytes"
"fmt"
"io/ioutil"
+ "log"
"os"
"path/filepath"
"runtime"
+ "strings"
)
func main() {
- batches, _ := filepath.Glob(runtime.GOROOT() + "/src/*.bat")
- for _, bat := range batches {
- body, _ := ioutil.ReadFile(bat)
- if !bytes.Contains(body, []byte("\r\n")) {
- fmt.Printf("Windows batch file %s does not contain CRLF line termination.\nTry running git checkout src/*.bat to fix this.\n", bat)
- os.Exit(1)
+ // Ensure that the GOROOT/src/all.bat file exists and has strict CRLF line endings.
+ enforceBatchStrictCRLF(filepath.Join(runtime.GOROOT(), "src", "all.bat"))
+
+ // Walk the entire Go repository source tree (without GOROOT/pkg),
+ // skipping directories that start with "." and named "testdata",
+ // and ensure all .bat files found have exact CRLF line endings.
+ err := filepath.Walk(runtime.GOROOT(), func(path string, fi os.FileInfo, err error) error {
+ if err != nil {
+ return err
}
+ if fi.IsDir() && (strings.HasPrefix(fi.Name(), ".") || fi.Name() == "testdata") {
+ return filepath.SkipDir
+ }
+ if path == filepath.Join(runtime.GOROOT(), "pkg") {
+ // GOROOT/pkg is known to contain generated artifacts, not source code.
+ // Skip it to avoid false positives. (Also see golang.org/issue/37929.)
+ return filepath.SkipDir
+ }
+ if filepath.Ext(fi.Name()) == ".bat" {
+ enforceBatchStrictCRLF(path)
+ }
+ return nil
+ })
+ if err != nil {
+ log.Fatalln(err)
+ }
+}
+
+func enforceBatchStrictCRLF(path string) {
+ b, err := ioutil.ReadFile(path)
+ if err != nil {
+ log.Fatalln(err)
+ }
+ cr, lf := bytes.Count(b, []byte{13}), bytes.Count(b, []byte{10})
+ crlf := bytes.Count(b, []byte{13, 10})
+ if cr != crlf || lf != crlf {
+ if rel, err := filepath.Rel(runtime.GOROOT(), path); err == nil {
+ // Make the test failure more readable by showing a path relative to GOROOT.
+ path = rel
+ }
+ fmt.Printf("Windows batch file %s does not use strict CRLF line termination.\n", path)
+ fmt.Printf("Please convert it to CRLF before checking it in due to golang.org/issue/37791.\n")
+ os.Exit(1)
}
}