Merge tag 'go1.17rc1' into HEAD

Change-Id: Ie1b4fb93860dedd6184dfe880685d601ea49308c
diff --git a/VERSION b/VERSION
index 98df369..cc14961 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-go1.17beta1
\ No newline at end of file
+go1.17rc1
\ No newline at end of file
diff --git a/api/go1.17.txt b/api/go1.17.txt
index f054458..3d0a464 100644
--- a/api/go1.17.txt
+++ b/api/go1.17.txt
@@ -28,6 +28,40 @@
 pkg go/build, type Context struct, ToolTags []string
 pkg go/parser, const SkipObjectResolution = 64
 pkg go/parser, const SkipObjectResolution Mode
+pkg image, method (*Alpha) RGBA64At(int, int) color.RGBA64
+pkg image, method (*Alpha) SetRGBA64(int, int, color.RGBA64)
+pkg image, method (*Alpha16) RGBA64At(int, int) color.RGBA64
+pkg image, method (*Alpha16) SetRGBA64(int, int, color.RGBA64)
+pkg image, method (*CMYK) RGBA64At(int, int) color.RGBA64
+pkg image, method (*CMYK) SetRGBA64(int, int, color.RGBA64)
+pkg image, method (*Gray) RGBA64At(int, int) color.RGBA64
+pkg image, method (*Gray) SetRGBA64(int, int, color.RGBA64)
+pkg image, method (*Gray16) RGBA64At(int, int) color.RGBA64
+pkg image, method (*Gray16) SetRGBA64(int, int, color.RGBA64)
+pkg image, method (*NRGBA) RGBA64At(int, int) color.RGBA64
+pkg image, method (*NRGBA) SetRGBA64(int, int, color.RGBA64)
+pkg image, method (*NRGBA64) RGBA64At(int, int) color.RGBA64
+pkg image, method (*NRGBA64) SetRGBA64(int, int, color.RGBA64)
+pkg image, method (*NYCbCrA) RGBA64At(int, int) color.RGBA64
+pkg image, method (*Paletted) RGBA64At(int, int) color.RGBA64
+pkg image, method (*Paletted) SetRGBA64(int, int, color.RGBA64)
+pkg image, method (*RGBA) RGBA64At(int, int) color.RGBA64
+pkg image, method (*RGBA) SetRGBA64(int, int, color.RGBA64)
+pkg image, method (*Uniform) RGBA64At(int, int) color.RGBA64
+pkg image, method (*YCbCr) RGBA64At(int, int) color.RGBA64
+pkg image, method (Rectangle) RGBA64At(int, int) color.RGBA64
+pkg image, type RGBA64Image interface { At, Bounds, ColorModel, RGBA64At }
+pkg image, type RGBA64Image interface, At(int, int) color.Color
+pkg image, type RGBA64Image interface, Bounds() Rectangle
+pkg image, type RGBA64Image interface, ColorModel() color.Model
+pkg image, type RGBA64Image interface, RGBA64At(int, int) color.RGBA64
+pkg image/draw, type RGBA64Image interface { At, Bounds, ColorModel, RGBA64At, Set, SetRGBA64 }
+pkg image/draw, type RGBA64Image interface, At(int, int) color.Color
+pkg image/draw, type RGBA64Image interface, Bounds() image.Rectangle
+pkg image/draw, type RGBA64Image interface, ColorModel() color.Model
+pkg image/draw, type RGBA64Image interface, RGBA64At(int, int) color.RGBA64
+pkg image/draw, type RGBA64Image interface, Set(int, int, color.Color)
+pkg image/draw, type RGBA64Image interface, SetRGBA64(int, int, color.RGBA64)
 pkg io/fs, func FileInfoToDirEntry(FileInfo) DirEntry
 pkg math, const MaxFloat64 = 1.79769e+308  // 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368
 pkg math, const MaxInt = 9223372036854775807
@@ -147,13 +181,14 @@
 pkg syscall (windows-amd64), type SysProcAttr struct, ParentProcess Handle
 pkg testing, method (*B) Setenv(string, string)
 pkg testing, method (*T) Setenv(string, string)
+pkg testing, type TB interface, Setenv(string, string)
 pkg text/template/parse, const SkipFuncCheck = 2
 pkg text/template/parse, const SkipFuncCheck Mode
 pkg time, const Layout = "01/02 03:04:05PM '06 -0700"
 pkg time, const Layout ideal-string
 pkg time, func UnixMicro(int64) Time
 pkg time, func UnixMilli(int64) Time
-pkg time, method (*Time) IsDST() bool
 pkg time, method (Time) GoString() string
+pkg time, method (Time) IsDST() bool
 pkg time, method (Time) UnixMicro() int64
 pkg time, method (Time) UnixMilli() int64
diff --git a/doc/asm.html b/doc/asm.html
index 7173d9b..d578800 100644
--- a/doc/asm.html
+++ b/doc/asm.html
@@ -828,10 +828,6 @@
 <h3 id="arm64">ARM64</h3>
 
 <p>
-The ARM64 port is in an experimental state.
-</p>
-
-<p>
 <code>R18</code> is the "platform register", reserved on the Apple platform.
 To prevent accidental misuse, the register is named <code>R18_PLATFORM</code>.
 <code>R27</code> and <code>R28</code> are reserved by the compiler and linker.
diff --git a/doc/go1.17.html b/doc/go1.17.html
index 49fbabd..fa8f14d 100644
--- a/doc/go1.17.html
+++ b/doc/go1.17.html
@@ -59,7 +59,7 @@
 </ul>
 
 <p>
-  These enhancements were added to simplify writing code that conforms
+  The package unsafe enhancements were added to simplify writing code that conforms
   to <code>unsafe.Pointer</code>'s <a href="/pkg/unsafe/#Pointer">safety
   rules</a>, but the rules remain unchanged. In particular, existing
   programs that correctly use <code>unsafe.Pointer</code> remain
@@ -106,8 +106,7 @@
   of directly using machine instructions. In Go 1.17, this is also
   done on the 32-bit x86 and 32-bit ARM architectures on OpenBSD
   (the <code>openbsd/386</code> and <code>openbsd/arm</code> ports).
-  This ensures forward-compatibility with future versions of
-  OpenBSD, in particular, with OpenBSD 6.9 onwards, which requires
+  This ensures compatibility with OpenBSD 6.9 onwards, which require
   system calls to be made through <code>libc</code> for non-static
   Go binaries.
 </p>
@@ -163,7 +162,7 @@
   By default, <code>go</code> <code>mod</code> <code>tidy</code> verifies that
   the selected versions of dependencies relevant to the main module are the same
   versions that would be used by the prior Go release (Go 1.16 for a module that
-  spsecifies <code>go</code> <code>1.17</code>), and preserves
+  specifies <code>go</code> <code>1.17</code>), and preserves
   the <code>go.sum</code> entries needed by that release even for dependencies
   that are not normally needed by other commands.
 </p>
@@ -188,6 +187,13 @@
   features.
 </p>
 
+<p><!-- golang.org/issue/46366 -->
+  The <code>go</code> <code>mod</code> <code>graph</code> subcommand also
+  supports the <code>-go</code> flag, which causes it to report the graph as
+  seen by the indicated Go version, showing dependencies that may otherwise be
+  pruned out by lazy loading.
+</p>
+
 <h4 id="module-deprecation-comments">Module deprecation comments</h4>
 
 <p><!-- golang.org/issue/40357 -->
@@ -215,6 +221,16 @@
   <code>environment</code> for details.
 </p>
 
+<p><!-- golang.org/issue/43684 -->
+  <code>go</code> <code>get</code> prints a deprecation warning when installing
+  commands outside the main module (without the <code>-d</code> flag).
+  <code>go</code> <code>install</code> <code>cmd@version</code> should be used
+  instead to install a command at a specific version, using a suffix like
+  <code>@latest</code> or <code>@v1.2.3</code>. In Go 1.18, the <code>-d</code>
+  flag will always be enabled, and <code>go</code> <code>get</code> will only
+  be used to change dependencies in <code>go.mod</code>.
+</p>
+
 <h4 id="missing-go-directive"><code>go.mod</code> files missing <code>go</code> directives</h4>
 
 <p><!-- golang.org/issue/44976 -->
@@ -293,7 +309,21 @@
   <a href="https://golang.org/design/draft-gobuild">https://golang.org/design/draft-gobuild</a>.
 </p>
 
-<h3 id="gofmt"><code>gofmt</code></h3>
+<h4 id="go run"><code>go</code> <code>run</code></h4>
+
+<p><!-- golang.org/issue/42088 -->
+  <code>go</code> <code>run</code> now accepts arguments with version suffixes
+  (for example, <code>go</code> <code>run</code>
+  <code>example.com/cmd@v1.0.0</code>).  This causes <code>go</code>
+  <code>run</code> to build and run packages in module-aware mode, ignoring the
+  <code>go.mod</code> file in the current directory or any parent directory, if
+  there is one. This is useful for running executables without installing them or
+  without changing dependencies of the current module.
+</p>
+
+<h3 id="gofmt">Gofmt</h3>
+
+<p>
   <code>gofmt</code> (and <code>go</code> <code>fmt</code>) now synchronizes
   <code>//go:build</code> lines with <code>// +build</code> lines. If a file
   only has <code>// +build</code> lines, they will be moved to the appropriate
@@ -301,7 +331,7 @@
   added. Otherwise, <code>// +build</code> lines will be overwritten based on
   any existing <code>//go:build</code> lines. For more information, see
   <a href="https://golang.org/design/draft-gobuild">https://golang.org/design/draft-gobuild</a>.
-</h3>
+</p>
 
 <h3 id="vet">Vet</h3>
 
@@ -371,30 +401,37 @@
 
 <p><!-- golang.org/issue/40724 -->
   Go 1.17 implements a new way of passing function arguments and results using
-  registers instead of the stack. This work is enabled for Linux, MacOS, and
-  Windows on the 64-bit x86 architecture (the <code>linux/amd64</code>,
-  <code>darwin/amd64</code>, <code>windows/amd64</code> ports). For a
-  representative set of Go  packages and programs, benchmarking has shown
-  performance improvements of about 5%, and a typical reduction in binary size
-  of about 2%.
+  registers instead of the stack.
+  Benchmarks for a representative set of Go packages and programs show
+  performance improvements of about 5%, and a typical reduction in
+  binary size of about 2%.
+  This is currently enabled for Linux, macOS, and Windows on the
+  64-bit x86 architecture (the <code>linux/amd64</code>,
+  <code>darwin/amd64</code>, and <code>windows/amd64</code> ports).
 </p>
 
 <p>
-  This change does not affect the functionality of any safe Go code. It can affect
-  code outside the <a href="/doc/go1compat">compatibility guidelines</a> with
-  minimal impact. To maintain compatibility with existing assembly functions,
-  adapter functions converting between the new register-based calling convention
-  and the previous stack-based calling convention (also known as ABI wrappers)
-  are sometimes used. This is mostly invisible to users, except for assembly
-  functions that have their addresses taken in Go. Using <code>reflect.ValueOf(fn).Pointer()</code>
-  (or similar approaches such as via <code>unsafe.Pointer</code>) to get the address
-  of an assembly function will now return the address of the ABI wrapper. This is
-  mostly harmless, except for special-purpose assembly code (such as accessing
-  thread-local storage or requiring a special stack alignment). Assembly functions
-  called indirectly from Go via <code>func</code> values will now be made through
-  ABI wrappers, which may cause a very small performance overhead. Also, calling
-  Go functions from assembly may now go through ABI wrappers, with a very small
-  performance overhead.
+  This change does not affect the functionality of any safe Go code
+  and is designed to have no impact on most assembly code.
+  It may affect code that violates
+  the <a href="/pkg/unsafe#Pointer"><code>unsafe.Pointer</code></a>
+  rules when accessing function arguments, or that depends on
+  undocumented behavior involving comparing function code pointers.
+  To maintain compatibility with existing assembly functions, the
+  compiler generates adapter functions that convert between the new
+  register-based calling convention and the previous stack-based
+  calling convention.
+  These adapters are typically invisible to users, except that taking
+  the address of a Go function in assembly code or taking the address
+  of an assembly function in Go code
+  using <code>reflect.ValueOf(fn).Pointer()</code>
+  or <code>unsafe.Pointer</code> will now return the address of the
+  adapter.
+  Code that depends on the value of these code pointers may no longer
+  behave as expected.
+  Adapters also may cause a very small performance overhead in two
+  cases: calling an assembly function indirectly from Go via
+  a <code>func</code> value, and calling Go functions from assembly.
 </p>
 
 <p><!-- CL 304470 -->
@@ -405,15 +442,19 @@
   by commas. Aggregate-typed (struct, array, string, slice, interface, and complex)
   arguments are delimited by curly braces. A caveat is that the value of an
   argument that only lives in a register and is not stored to memory may be
-  inaccurate. Results (which were usually inaccurate) are no longer printed.
+  inaccurate. Function return values (which were usually inaccurate) are no longer
+  printed.
 </p>
 
 <p><!-- CL 283112, golang.org/issue/28727 -->
-  Functions containing closures can now be inlined. One effect of this change is
-  that a function with a closure may actually produce a distinct closure function
-  for each place that the function is inlined. Hence, this change could reveal
-  bugs where Go functions are compared (incorrectly) by pointer value. Go
-  functions are by definition not comparable.
+  Functions containing closures can now be inlined.
+  One effect of this change is that a function with a closure may
+  produce a distinct closure code pointer for each place that the
+  function is inlined.
+  Go function values are not directly comparable, but this change
+  could reveal bugs in code that uses <code>reflect</code>
+  or <code>unsafe.Pointer</code> to bypass this language restriction
+  and compare functions by code pointer.
 </p>
 
 <h2 id="library">Core library</h2>
@@ -427,6 +468,67 @@
   <a href="/pkg/runtime/cgo#Handle">runtime/cgo.Handle</a> for more information.
 </p>
 
+<h3 id="semicolons">URL query parsing</h3>
+<!-- CL 325697, CL 326309 -->
+
+<p>
+  The <code>net/url</code> and <code>net/http</code> packages used to accept
+  <code>";"</code> (semicolon) as a setting separator in URL queries, in
+  addition to <code>"&"</code> (ampersand). Now, settings with non-percent-encoded
+  semicolons are rejected and <code>net/http</code> servers will log a warning to
+  <a href="/pkg/net/http#Server.ErrorLog"><code>Server.ErrorLog</code></a>
+  when encountering one in a request URL.
+</p>
+
+<p>
+  For example, before Go 1.17 the <a href="/pkg/net/url#URL.Query"><code>Query</code></a>
+  method of the URL <code>example?a=1;b=2&c=3</code> would have returned
+  <code>map[a:[1] b:[2] c:[3]]</code>, while now it returns <code>map[c:[3]]</code>.
+</p>
+
+<p>
+  When encountering such a query string,
+  <a href="/pkg/net/url#URL.Query"><code>URL.Query</code></a>
+  and
+  <a href="/pkg/net/http#Request.FormValue"><code>Request.FormValue</code></a>
+  ignore any settings that contain a semicolon,
+  <a href="/pkg/net/url#ParseQuery"><code>ParseQuery</code></a>
+  returns the remaining settings and an error, and
+  <a href="/pkg/net/http#Request.ParseForm"><code>Request.ParseForm</code></a>
+  and
+  <a href="/pkg/net/http#Request.ParseMultipartForm"><code>Request.ParseMultipartForm</code></a>
+  return an error but still set <code>Request</code> fields based on the
+  remaining settings.
+</p>
+
+<p>
+  <code>net/http</code> users can restore the original behavior by using the new
+  <a href="/pkg/net/http#AllowQuerySemicolons"><code>AllowQuerySemicolons</code></a>
+  handler wrapper. This will also suppress the <code>ErrorLog</code> warning.
+  Note that accepting semicolons as query separators can lead to security issues
+  if different systems interpret cache keys differently.
+  See <a href="https://golang.org/issue/25192">issue 25192</a> for more information.
+</p>
+
+<h3 id="ALPN">TLS strict ALPN</h3>
+<!-- CL 289209, CL 325432 -->
+
+<p>
+  When <a href="/pkg/crypto/tls#Config.NextProtos"><code>Config.NextProtos</code></a>
+  is set, servers now enforce that there is an overlap between the configured
+  protocols and the ALPN protocols advertised by the client, if any. If there is
+  no mutually supported protocol, the connection is closed with the
+  <code>no_application_protocol</code> alert, as required by RFC 7301. This
+  helps mitigate <a href="https://alpaca-attack.com/">the ALPACA cross-protocol attack</a>.
+</p>
+
+<p>
+  As an exception, when the value <code>"h2"</code> is included in the server's
+  <code>Config.NextProtos</code>, HTTP/1.1 clients will be allowed to connect as
+  if they didn't support ALPN.
+  See <a href="https://golang.org/issue/46310">issue 46310</a> for more information.
+</p>
+
 <h3 id="minor_library_changes">Minor changes to the library</h3>
 
 <p>
@@ -535,14 +637,6 @@
       methods. Canceling the context after the handshake has finished has no effect.
     </p>
 
-    <p><!-- CL 289209 -->
-      When <a href="/pkg/crypto/tls#Config.NextProtos"><code>Config.NextProtos</code></a>
-      is set, servers now enforce that there is an overlap between the
-      configured protocols and the protocols advertised by the client, if any.
-      If there is no overlap the connection is closed with the
-      <code>no_application_protocol</code> alert, as required by RFC 7301.
-    </p>
-
     <p><!-- CL 314609 -->
       Cipher suite ordering is now handled entirely by the
       <code>crypto/tls</code> package. Currently, cipher suites are sorted based
@@ -562,6 +656,15 @@
       weakness</a>. They are still enabled by default but only as a last resort,
       thanks to the cipher suite ordering change above.
     </p>
+
+    <p><!-- golang.org/issue/45428 -->
+      Beginning in the next release, Go 1.18, the
+      <a href="/pkg/crypto/tls/#Config.MinVersion"><code>Config.MinVersion</code></a>
+      for <code>crypto/tls</code> clients will default to TLS 1.2, disabling TLS 1.0
+      and TLS 1.1 by default. Applications will be able to override the change by
+      explicitly setting <code>Config.MinVersion</code>.
+      This will not affect <code>crypto/tls</code> servers.
+    </p>
   </dd>
 </dl><!-- crypto/tls -->
 
@@ -589,6 +692,14 @@
       roots. This adds support for the new system trusted certificate store in
       FreeBSD 12.2+.
     </p>
+
+    <p><!-- golang.org/issue/41682 -->
+      Beginning in the next release, Go 1.18, <code>crypto/x509</code> will
+      reject certificates signed with the SHA-1 hash function. This doesn't
+      apply to self-signed root certificates. Practical attacks against SHA-1
+      <a href="https://shattered.io/">have been demonstrated in 2017</a> and publicly
+      trusted Certificate Authorities have not issued SHA-1 certificates since 2015.
+    </p>
   </dd>
 </dl><!-- crypto/x509 -->
 
@@ -644,6 +755,22 @@
   </dd>
 </dl><!-- encoding/csv -->
 
+<dl id="encoding/xml"><dt><a href="/pkg/encoding/xml/">encoding/xml</a></dt>
+  <dd>
+    <p><!-- CL 277893 -->
+      When a comment appears within a
+      <a href="/pkg/encoding/xml/#Directive"><code>Directive</code></a>, it is now replaced
+      with a single space instead of being completely elided.
+    </p>
+
+    <p>
+      Invalid element or attribute names with leading, trailing, or multiple
+      colons are now stored unmodified into the
+      <a href="/pkg/encoding/xml/#Name"><code>Name.Local</code></a> field.
+    </p>
+  </dd>
+</dl><!-- encoding/xml -->
+
 <dl id="flag"><dt><a href="/pkg/flag/">flag</a></dt>
   <dd>
     <p><!-- CL 271788 -->
@@ -679,6 +806,29 @@
   </dd>
 </dl><!-- go/format -->
 
+<dl id="go/parser"><dt><a href="/pkg/go/parser/">go/parser</a></dt>
+  <dd>
+    <p><!-- CL 306149 -->
+      The new <a href="/pkg/go/parser/#SkipObjectResolution"><code>SkipObjectResolution</code></a>
+      <code>Mode</code> value instructs the parser not to resolve identifiers to
+      their declaration. This may improve parsing speed.
+    </p>
+  </dd>
+</dl><!-- go/parser -->
+
+<dl id="image"><dt><a href="/pkg/image/">image</a></dt>
+  <dd>
+    <p><!-- CL 311129 -->
+      The concrete image types (<code>RGBA</code>, <code>Gray16</code> and so on)
+      now implement a new <a href="/pkg/image/#RGBA64Image"><code>RGBA64Image</code></a>
+      interface. The concrete types that previously implemented
+      <a href="/pkg/image/draw/#Image"><code>draw.Image</code></a> now also implement
+      <a href="/pkg/image/draw/#RGBA64Image"><code>draw.RGBA64Image</code></a>, a
+      new interface in the <code>image/draw</code> package.
+    </p>
+  </dd>
+</dl><!-- image -->
+
 <dl id="io/fs"><dt><a href="/pkg/io/fs/">io/fs</a></dt>
   <dd>
     <p><!-- CL 293649 -->
@@ -707,6 +857,20 @@
   </dd>
 </dl><!-- mime -->
 
+<dl id="mime/multipart"><dt><a href="/pkg/mime/multipart/">mime/multipart</a></dt>
+  <dd>
+    <p><!-- CL 313809 -->
+      <a href="/pkg/mime/multipart/#Part.FileName"><code>Part.FileName</code></a>
+      now applies
+      <a href="/pkg/path/filepath/#Base"><code>filepath.Base</code></a> to the
+      return value. This mitigates potential path traversal vulnerabilities in
+      applications that accept multipart messages, such as <code>net/http</code>
+      servers that call
+      <a href="/pkg/net/http/#Request.FormFile"><code>Request.FormFile</code></a>.
+    </p>
+  </dd>
+</dl><!-- mime/multipart -->
+
 <dl id="net"><dt><a href="/pkg/net/">net</a></dt>
   <dd>
     <p><!-- CL 272668 -->
@@ -726,14 +890,14 @@
       the <a href="/pkg/net/#Error"><code>net.Error</code></a> interface.
     </p>
 
-    <p><!-- CL325829 -->
+    <p><!-- CL 325829 -->
       The <a href="/pkg/net/#ParseIP"><code>ParseIP</code></a> and <a href="/pkg/net/#ParseCIDR"><code>ParseCIDR</code></a>
       functions now reject IPv4 addresses which contain decimal components with leading zeros.
 
       These components were always interpreted as decimal, but some operating systems treat them as octal.
       This mismatch could hypothetically lead to security issues if a Go application was used to validate IP addresses
       which were then used in their original form with non-Go applications which interpreted components as octal. Generally,
-      it is advisable to always re-encoded values after validation, which avoids this class of parser misalignment issues.
+      it is advisable to always re-encode values after validation, which avoids this class of parser misalignment issues.
     </p>
   </dd>
 </dl><!-- net -->
@@ -757,15 +921,38 @@
       The <a href="/pkg/net/http/#ReadRequest"><code>ReadRequest</code></a> function
       now returns an error when the request has multiple Host headers.
     </p>
+
+    <p><!-- CL 313950 -->
+      When producing a redirect to the cleaned version of a URL,
+      <a href="/pkg/net/http/#ServeMux"><code>ServeMux</code></a> now always
+      uses relative URLs in the <code>Location</code> header. Previously it
+      would echo the full URL of the request, which could lead to unintended
+      redirects if the client could be made to send an absolute request URL.
+    </p>
+
+    <p><!-- CL 308009, CL 313489 -->
+      When interpreting certain HTTP headers handled by <code>net/http</code>,
+      non-ASCII characters are now ignored or rejected.
+    </p>
+
+    <p><!-- CL 325697 -->
+      If
+      <a href="/pkg/net/http/#Request.ParseForm"><code>Request.ParseForm</code></a>
+      returns an error when called by
+      <a href="/pkg/net/http/#Request.ParseMultipartForm"><code>Request.ParseMultipartForm</code></a>,
+      the latter now continues populating
+      <a href="/pkg/net/http/#Request.MultipartForm"><code>Request.MultipartForm</code></a>
+      before returning it.
+    </p>
   </dd>
 </dl><!-- net/http -->
 
 <dl id="net/http/httptest"><dt><a href="/pkg/net/http/httptest/">net/http/httptest</a></dt>
   <dd>
     <p><!-- CL 308950 -->
-      <a href="/pkg/net/http/httptest/#ResponseRecorder.WriteHeader"><code>ResponseRecorder.WriteHeader></code></a>
+      <a href="/pkg/net/http/httptest/#ResponseRecorder.WriteHeader"><code>ResponseRecorder.WriteHeader</code></a>
       now panics when the provided code is not a valid three-digit HTTP status code.
-      This matches the behavior of <a href="/pkg/net/http/#ResponseWriter"><code>ResponseWriter></code></a>
+      This matches the behavior of <a href="/pkg/net/http/#ResponseWriter"><code>ResponseWriter</code></a>
       implementations in the <a href="/pkg/net/http/"><code>net/http</code></a> package.
     </p>
   </dd>
@@ -784,7 +971,7 @@
   <dd>
     <p><!-- CL 268020 -->
       The <a href="/pkg/os/#File.WriteString"><code>File.WriteString</code></a> method
-      has been optimized to no longer make a copy of the input string.
+      has been optimized to not make a copy of the input string.
     </p>
   </dd>
 </dl><!-- os -->
@@ -810,6 +997,14 @@
       The <a href="/pkg/reflect/#ArrayOf"><code>ArrayOf</code></a> function now panics when
       called with a negative length.
     </p>
+
+    <p><!-- CL 301652 -->
+      Checking the <a href="/pkg/reflect/#Type"><code>Type.ConvertibleTo</code></a> method
+      is no longer sufficient to guarantee that a call to
+      <a href="/pkg/reflect/#Value.Convert"><code>Value.Convert</code></a> will not panic.
+      It may panic when converting `[]T` to `*[N]T` if the slice's length is less than N.
+      See the <a href="#language">language changes</a> section above.
+    </p>
   </dd>
 </dl><!-- reflect -->
 
@@ -836,7 +1031,7 @@
   <dd>
     <p><!-- CL 170079, CL 170080 -->
       The <code>strconv</code> package now uses Ulf Adams's Ryƫ algorithm for formatting floating-point numbers.
-      This algorithm improves performance on most inputs, and is more than 99% faster on worst-case inputs.
+      This algorithm improves performance on most inputs and is more than 99% faster on worst-case inputs.
     </p>
 
     <p><!-- CL 314775 -->
@@ -947,10 +1142,13 @@
 
     <p><!-- CL 293349 -->
       The new <a href="/pkg/time/#Time.UnixMilli"><code>Time.UnixMilli</code></a> and
-      <a href="/pkg/time/#Time.UnixMicro"><code>Time.UnixMicro</code></a> methods return the number of milliseconds and
-      microseconds elapsed since January 1, 1970 UTC respectively.<br>
-      The new <code>UnixMilli</code> and <code>UnixMicro</code> functions return local Time corresponding to given
-      Unix time.
+      <a href="/pkg/time/#Time.UnixMicro"><code>Time.UnixMicro</code></a>
+      methods return the number of milliseconds and microseconds elapsed since
+      January 1, 1970 UTC respectively.
+      <br />
+      The new <a href="/pkg/time/#UnixMilli"><code>UnixMilli</code></a> and
+      <a href="/pkg/time/#UnixMicro"><code>UnixMicro</code></a> functions
+      return the local <code>Time</code> corresponding to the given Unix time.
     </p>
 
     <p><!-- CL 300996 -->
diff --git a/doc/go_spec.html b/doc/go_spec.html
index 561d442..ad21ffb 100644
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,6 +1,6 @@
 <!--{
 	"Title": "The Go Programming Language Specification",
-	"Subtitle": "Version of Jun 2, 2021",
+	"Subtitle": "Version of Jul 1, 2021",
 	"Path": "/ref/spec"
 }-->
 
@@ -4670,7 +4670,7 @@
 
 <pre>
 append cap complex imag len make new real
-unsafe.Alignof unsafe.Offsetof unsafe.Sizeof
+unsafe.Add unsafe.Alignof unsafe.Offsetof unsafe.Sizeof unsafe.Slice
 </pre>
 
 <pre>
@@ -6782,7 +6782,8 @@
 
 <p>
 The function <code>Slice</code> returns a slice whose underlying array starts at <code>ptr</code>
-and whose length and capacity are <code>len</code>:
+and whose length and capacity are <code>len</code>.
+<code>Slice(ptr, len)</code> is equivalent to
 </p>
 
 <pre>
@@ -6790,10 +6791,17 @@
 </pre>
 
 <p>
+except that, as a special case, if <code>ptr</code>
+is <code>nil</code> and <code>len</code> is zero,
+<code>Slice</code> returns <code>nil</code>.
+</p>
+
+<p>
 The <code>len</code> argument must be of integer type or an untyped <a href="#Constants">constant</a>.
 A constant <code>len</code> argument must be non-negative and <a href="#Representability">representable</a> by a value of type <code>int</code>;
 if it is an untyped constant it is given type <code>int</code>.
-If <code>ptr</code> is <code>nil</code> or <code>len</code> is negative at run time,
+At run time, if <code>len</code> is negative,
+or if <code>ptr</code> is <code>nil</code> and <code>len</code> is not zero,
 a <a href="#Run_time_panics">run-time panic</a> occurs.
 </p>
 
diff --git a/misc/cgo/testcshared/cshared_test.go b/misc/cgo/testcshared/cshared_test.go
index 90d8c36..19ad8c7 100644
--- a/misc/cgo/testcshared/cshared_test.go
+++ b/misc/cgo/testcshared/cshared_test.go
@@ -292,11 +292,60 @@
 		"-installsuffix", "testcshared",
 		"-o", libgoname,
 		filepath.Join(".", "libgo", "libgo.go")}
+	if GOOS == "windows" && strings.HasSuffix(args[6], ".a") {
+		args[6] = strings.TrimSuffix(args[6], ".a") + ".dll"
+	}
 	cmd = exec.Command(args[0], args[1:]...)
 	out, err = cmd.CombinedOutput()
 	if err != nil {
 		return fmt.Errorf("command failed: %v\n%v\n%s\n", args, err, out)
 	}
+	if GOOS == "windows" {
+		// We can't simply pass -Wl,--out-implib, because this relies on having imports from multiple packages,
+		// which results in the linkers output implib getting overwritten at each step. So instead build the
+		// import library the traditional way, using a def file.
+		err = os.WriteFile("libgo.def",
+			[]byte("LIBRARY libgo.dll\nEXPORTS\n\tDidInitRun\n\tDidMainRun\n\tDivu\n\tFromPkg\n\t_cgo_dummy_export\n"),
+			0644)
+		if err != nil {
+			return fmt.Errorf("unable to write def file: %v", err)
+		}
+		out, err = exec.Command(cc[0], append(cc[1:], "-print-prog-name=dlltool")...).CombinedOutput()
+		if err != nil {
+			return fmt.Errorf("unable to find dlltool path: %v\n%s\n", err, out)
+		}
+		args := []string{strings.TrimSpace(string(out)), "-D", args[6], "-l", libgoname, "-d", "libgo.def"}
+
+		// This is an unfortunate workaround for https://github.com/mstorsjo/llvm-mingw/issues/205 in which
+		// we basically reimplement the contents of the dlltool.sh wrapper: https://git.io/JZFlU
+		dlltoolContents, err := os.ReadFile(args[0])
+		if err != nil {
+			return fmt.Errorf("unable to read dlltool: %v\n", err)
+		}
+		if bytes.HasPrefix(dlltoolContents, []byte("#!/bin/sh")) && bytes.Contains(dlltoolContents, []byte("llvm-dlltool")) {
+			base, name := filepath.Split(args[0])
+			args[0] = filepath.Join(base, "llvm-dlltool")
+			var machine string
+			switch strings.SplitN(name, "-", 2)[0] {
+			case "i686":
+				machine = "i386"
+			case "x86_64":
+				machine = "i386:x86-64"
+			case "armv7":
+				machine = "arm"
+			case "aarch64":
+				machine = "arm64"
+			}
+			if len(machine) > 0 {
+				args = append(args, "-m", machine)
+			}
+		}
+
+		out, err = exec.Command(args[0], args[1:]...).CombinedOutput()
+		if err != nil {
+			return fmt.Errorf("unable to run dlltool to create import library: %v\n%s\n", err, out)
+		}
+	}
 
 	if runtime.GOOS != GOOS && GOOS == "android" {
 		args = append(adbCmd(), "push", libgoname, fmt.Sprintf("%s/%s", androiddir, libgoname))
@@ -400,7 +449,7 @@
 	defer f.Close()
 	section := f.Section(".edata")
 	if section == nil {
-		t.Fatalf(".edata section is not present")
+		t.Skip(".edata section is not present")
 	}
 
 	// TODO: deduplicate this struct from cmd/link/internal/ld/pe.go
@@ -749,7 +798,12 @@
 	defer os.RemoveAll(tmpdir)
 
 	lib := filepath.Join(tmpdir, "libtestgo2c2go."+libSuffix)
-	run(t, nil, "go", "build", "-buildmode=c-shared", "-o", lib, "./go2c2go/go")
+	var env []string
+	if GOOS == "windows" && strings.HasSuffix(lib, ".a") {
+		env = append(env, "CGO_LDFLAGS=-Wl,--out-implib,"+lib, "CGO_LDFLAGS_ALLOW=.*")
+		lib = strings.TrimSuffix(lib, ".a") + ".dll"
+	}
+	run(t, env, "go", "build", "-buildmode=c-shared", "-o", lib, "./go2c2go/go")
 
 	cgoCflags := os.Getenv("CGO_CFLAGS")
 	if cgoCflags != "" {
diff --git a/src/cmd/asm/internal/asm/parse.go b/src/cmd/asm/internal/asm/parse.go
index ab48632..4cddcf4 100644
--- a/src/cmd/asm/internal/asm/parse.go
+++ b/src/cmd/asm/internal/asm/parse.go
@@ -1003,7 +1003,8 @@
 				p.errorf("unimplemented two-register form")
 			}
 			a.Index = r1
-			if scale != 0 && p.arch.Family == sys.ARM64 {
+			if scale != 0 && scale != 1 && p.arch.Family == sys.ARM64 {
+				// Support (R1)(R2) (no scaling) and (R1)(R2*1).
 				p.errorf("arm64 doesn't support scaled register format")
 			} else {
 				a.Scale = int16(scale)
diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s
index 1146c1a..d8a20ed 100644
--- a/src/cmd/asm/internal/asm/testdata/arm64.s
+++ b/src/cmd/asm/internal/asm/testdata/arm64.s
@@ -89,7 +89,7 @@
 	CMP	R1<<33, R2
 	CMP	R22.SXTX, RSP                    // ffe336eb
 	CMP	$0x22220000, RSP                 // CMP $572653568, RSP   // 5b44a4d2ff633beb
-	CMPW	$0x22220000, RSP                 // CMPW $572653568, RSP  // 5b44a452ff633b6b
+	CMPW	$0x22220000, RSP                 // CMPW $572653568, RSP  // 5b44a452ff433b6b
 	CCMN	MI, ZR, R1, $4	                 // e44341ba
 	// MADD Rn,Rm,Ra,Rd
 	MADD	R1, R2, R3, R4                   // 6408019b
@@ -377,6 +377,7 @@
 	MOVD	$0x1000100010001000, RSP      // MOVD	$1152939097061330944, RSP   // ff8304b2
 	MOVW	$0x10001000, RSP              // MOVW	$268439552, RSP             // ff830432
 	ADDW	$0x10001000, R1               // ADDW	$268439552, R1              // fb83043221001b0b
+	ADDW	$0x22220000, RSP, R3          // ADDW	$572653568, RSP, R3         // 5b44a452e3433b0b
 
 // move a large constant to a Vd.
 	VMOVS	$0x80402010, V11                                      // VMOVS	$2151686160, V11
@@ -547,6 +548,7 @@
 // shifted or extended register offset.
 	MOVD	(R2)(R6.SXTW), R4               // 44c866f8
 	MOVD	(R3)(R6), R5                    // 656866f8
+	MOVD	(R3)(R6*1), R5                  // 656866f8
 	MOVD	(R2)(R6), R4                    // 446866f8
 	MOVWU	(R19)(R20<<2), R20              // 747a74b8
 	MOVD	(R2)(R6<<3), R4                 // 447866f8
@@ -579,6 +581,7 @@
 	MOVB	R4, (R2)(R6.SXTX)               // 44e82638
 	MOVB	R8, (R3)(R9.UXTW)               // 68482938
 	MOVB	R10, (R5)(R8)                   // aa682838
+	MOVB	R10, (R5)(R8*1)                 // aa682838
 	MOVH	R11, (R2)(R7.SXTW<<1)           // 4bd82778
 	MOVH	R5, (R1)(R2<<1)                 // 25782278
 	MOVH	R7, (R2)(R5.SXTX<<1)            // 47f82578
diff --git a/src/cmd/cgo/main.go b/src/cmd/cgo/main.go
index 03a662e..c6a0c52 100644
--- a/src/cmd/cgo/main.go
+++ b/src/cmd/cgo/main.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Cgo; see gmp.go for an overview.
+// Cgo; see doc.go for an overview.
 
 // TODO(rsc):
 //	Emit correct line number annotations.
diff --git a/src/cmd/compile/abi-internal.md b/src/cmd/compile/abi-internal.md
index 1ae3c25..2bb4055 100644
--- a/src/cmd/compile/abi-internal.md
+++ b/src/cmd/compile/abi-internal.md
@@ -233,7 +233,7 @@
     r1.x    uintptr
     r1.y    [2]uintptr
     a1Spill uint8
-    a2Spill uint8
+    a3Spill uint8
     _       [6]uint8  // alignment padding
 
 In the stack frame, only the `a2` field is initialized on entry; the
diff --git a/src/cmd/compile/internal/escape/escape.go b/src/cmd/compile/internal/escape/escape.go
index 3ac7ff1..cd56f07 100644
--- a/src/cmd/compile/internal/escape/escape.go
+++ b/src/cmd/compile/internal/escape/escape.go
@@ -2013,14 +2013,14 @@
 		return "too large for stack"
 	}
 
-	if (n.Op() == ir.ONEW || n.Op() == ir.OPTRLIT) && n.Type().Elem().Width >= ir.MaxImplicitStackVarSize {
+	if (n.Op() == ir.ONEW || n.Op() == ir.OPTRLIT) && n.Type().Elem().Width > ir.MaxImplicitStackVarSize {
 		return "too large for stack"
 	}
 
-	if n.Op() == ir.OCLOSURE && typecheck.ClosureType(n.(*ir.ClosureExpr)).Size() >= ir.MaxImplicitStackVarSize {
+	if n.Op() == ir.OCLOSURE && typecheck.ClosureType(n.(*ir.ClosureExpr)).Size() > ir.MaxImplicitStackVarSize {
 		return "too large for stack"
 	}
-	if n.Op() == ir.OCALLPART && typecheck.PartialCallType(n.(*ir.SelectorExpr)).Size() >= ir.MaxImplicitStackVarSize {
+	if n.Op() == ir.OCALLPART && typecheck.PartialCallType(n.(*ir.SelectorExpr)).Size() > ir.MaxImplicitStackVarSize {
 		return "too large for stack"
 	}
 
@@ -2033,7 +2033,7 @@
 		if !ir.IsSmallIntConst(r) {
 			return "non-constant size"
 		}
-		if t := n.Type(); t.Elem().Width != 0 && ir.Int64Val(r) >= ir.MaxImplicitStackVarSize/t.Elem().Width {
+		if t := n.Type(); t.Elem().Width != 0 && ir.Int64Val(r) > ir.MaxImplicitStackVarSize/t.Elem().Width {
 			return "too large for stack"
 		}
 	}
diff --git a/src/cmd/compile/internal/reflectdata/reflect.go b/src/cmd/compile/internal/reflectdata/reflect.go
index e07294b..eb9a8a6 100644
--- a/src/cmd/compile/internal/reflectdata/reflect.go
+++ b/src/cmd/compile/internal/reflectdata/reflect.go
@@ -669,7 +669,7 @@
 // tflag is documented in reflect/type.go.
 //
 // tflag values must be kept in sync with copies in:
-//	cmd/compile/internal/gc/reflect.go
+//	cmd/compile/internal/reflectdata/reflect.go
 //	cmd/link/internal/ld/decodesym.go
 //	reflect/type.go
 //	runtime/type.go
diff --git a/src/cmd/compile/internal/ssa/debug.go b/src/cmd/compile/internal/ssa/debug.go
index eaa9497..8e28723 100644
--- a/src/cmd/compile/internal/ssa/debug.go
+++ b/src/cmd/compile/internal/ssa/debug.go
@@ -1115,8 +1115,14 @@
 			continue
 		}
 
+		mustBeFirst := func(v *Value) bool {
+			return v.Op == OpPhi || v.Op.isLoweredGetClosurePtr() ||
+				v.Op == OpArgIntReg || v.Op == OpArgFloatReg
+		}
+
 		zeroWidthPending := false
-		apcChangedSize := 0 // size of changedVars for leading Args, Phi, ClosurePtr
+		blockPrologComplete := false // set to true at first non-zero-width op
+		apcChangedSize := 0          // size of changedVars for leading Args, Phi, ClosurePtr
 		// expect to see values in pattern (apc)* (zerowidth|real)*
 		for _, v := range b.Values {
 			slots := state.valueNames[v.ID]
@@ -1125,16 +1131,16 @@
 
 			if opcodeTable[v.Op].zeroWidth {
 				if changed {
-					if hasAnyArgOp(v) || v.Op == OpPhi || v.Op.isLoweredGetClosurePtr() {
+					if mustBeFirst(v) || v.Op == OpArg {
 						// These ranges begin at true beginning of block, not after first instruction
-						if zeroWidthPending {
-							panic(fmt.Errorf("Unexpected op '%s' mixed with OpArg/OpPhi/OpLoweredGetClosurePtr at beginning of block %s in %s\n%s", v.LongString(), b, b.Func.Name, b.Func))
+						if blockPrologComplete && mustBeFirst(v) {
+							panic(fmt.Errorf("Unexpected placement of op '%s' appearing after non-pseudo-op at beginning of block %s in %s\n%s", v.LongString(), b, b.Func.Name, b.Func))
 						}
 						apcChangedSize = len(state.changedVars.contents())
+						// Other zero-width ops must wait on a "real" op.
+						zeroWidthPending = true
 						continue
 					}
-					// Other zero-width ops must wait on a "real" op.
-					zeroWidthPending = true
 				}
 				continue
 			}
@@ -1145,6 +1151,7 @@
 			// Not zero-width; i.e., a "real" instruction.
 
 			zeroWidthPending = false
+			blockPrologComplete = true
 			for i, varID := range state.changedVars.contents() {
 				if i < apcChangedSize { // buffered true start-of-block changes
 					state.updateVar(VarID(varID), v.Block, BlockStart)
diff --git a/src/cmd/compile/internal/ssagen/ssa.go b/src/cmd/compile/internal/ssagen/ssa.go
index 004e084..f1dc56e 100644
--- a/src/cmd/compile/internal/ssagen/ssa.go
+++ b/src/cmd/compile/internal/ssagen/ssa.go
@@ -3174,7 +3174,7 @@
 		arrlen := s.constInt(types.Types[types.TINT], n.Type().Elem().NumElem())
 		cap := s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], v)
 		s.boundsCheck(arrlen, cap, ssa.BoundsConvert, false)
-		return s.newValue1(ssa.OpSlicePtrUnchecked, types.Types[types.TINT], v)
+		return s.newValue1(ssa.OpSlicePtrUnchecked, n.Type(), v)
 
 	case ir.OCALLFUNC:
 		n := n.(*ir.CallExpr)
diff --git a/src/cmd/compile/internal/typecheck/builtin.go b/src/cmd/compile/internal/typecheck/builtin.go
index 67a894c..833b17b 100644
--- a/src/cmd/compile/internal/typecheck/builtin.go
+++ b/src/cmd/compile/internal/typecheck/builtin.go
@@ -138,6 +138,7 @@
 	{"growslice", funcTag, 116},
 	{"unsafeslice", funcTag, 117},
 	{"unsafeslice64", funcTag, 118},
+	{"unsafeslicecheckptr", funcTag, 118},
 	{"memmove", funcTag, 119},
 	{"memclrNoHeapPointers", funcTag, 120},
 	{"memclrHasPointers", funcTag, 120},
@@ -341,8 +342,8 @@
 	typs[114] = newSig(params(typs[1], typs[15], typs[15], typs[7]), params(typs[7]))
 	typs[115] = types.NewSlice(typs[2])
 	typs[116] = newSig(params(typs[1], typs[115], typs[15]), params(typs[115]))
-	typs[117] = newSig(params(typs[1], typs[15]), nil)
-	typs[118] = newSig(params(typs[1], typs[22]), nil)
+	typs[117] = newSig(params(typs[1], typs[7], typs[15]), nil)
+	typs[118] = newSig(params(typs[1], typs[7], typs[22]), nil)
 	typs[119] = newSig(params(typs[3], typs[3], typs[5]), nil)
 	typs[120] = newSig(params(typs[7], typs[5]), nil)
 	typs[121] = newSig(params(typs[3], typs[3], typs[5]), params(typs[6]))
diff --git a/src/cmd/compile/internal/typecheck/builtin/runtime.go b/src/cmd/compile/internal/typecheck/builtin/runtime.go
index ebeaeae..2b29ea3 100644
--- a/src/cmd/compile/internal/typecheck/builtin/runtime.go
+++ b/src/cmd/compile/internal/typecheck/builtin/runtime.go
@@ -183,8 +183,9 @@
 func makeslice64(typ *byte, len int64, cap int64) unsafe.Pointer
 func makeslicecopy(typ *byte, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer
 func growslice(typ *byte, old []any, cap int) (ary []any)
-func unsafeslice(typ *byte, len int)
-func unsafeslice64(typ *byte, len int64)
+func unsafeslice(typ *byte, ptr unsafe.Pointer, len int)
+func unsafeslice64(typ *byte, ptr unsafe.Pointer, len int64)
+func unsafeslicecheckptr(typ *byte, ptr unsafe.Pointer, len int64)
 
 func memmove(to *any, frm *any, length uintptr)
 func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
diff --git a/src/cmd/compile/internal/typecheck/const.go b/src/cmd/compile/internal/typecheck/const.go
index 5a35eea..761b043 100644
--- a/src/cmd/compile/internal/typecheck/const.go
+++ b/src/cmd/compile/internal/typecheck/const.go
@@ -633,6 +633,17 @@
 	if l.Type() == nil || r.Type() == nil {
 		return l, r
 	}
+
+	if !l.Type().IsInterface() && !r.Type().IsInterface() {
+		// Can't mix bool with non-bool, string with non-string.
+		if l.Type().IsBoolean() != r.Type().IsBoolean() {
+			return l, r
+		}
+		if l.Type().IsString() != r.Type().IsString() {
+			return l, r
+		}
+	}
+
 	if !l.Type().IsUntyped() {
 		r = convlit(r, l.Type())
 		return l, r
@@ -647,17 +658,10 @@
 		return l, r
 	}
 
-	// Can't mix bool with non-bool, string with non-string, or nil with anything (untyped).
-	if l.Type().IsBoolean() != r.Type().IsBoolean() {
-		return l, r
-	}
-	if l.Type().IsString() != r.Type().IsString() {
-		return l, r
-	}
+	// Can't mix nil with anything untyped.
 	if ir.IsNil(l) || ir.IsNil(r) {
 		return l, r
 	}
-
 	t := defaultType(mixUntyped(l.Type(), r.Type()))
 	l = convlit(l, t)
 	r = convlit(r, t)
diff --git a/src/cmd/compile/internal/typecheck/func.go b/src/cmd/compile/internal/typecheck/func.go
index a6dfbbf..fbcc784 100644
--- a/src/cmd/compile/internal/typecheck/func.go
+++ b/src/cmd/compile/internal/typecheck/func.go
@@ -1018,7 +1018,14 @@
 	t := n.X.Type()
 	if !t.IsPtr() {
 		base.Errorf("first argument to unsafe.Slice must be pointer; have %L", t)
+	} else if t.Elem().NotInHeap() {
+		// TODO(mdempsky): This can be relaxed, but should only affect the
+		// Go runtime itself. End users should only see //go:notinheap
+		// types due to incomplete C structs in cgo, and those types don't
+		// have a meaningful size anyway.
+		base.Errorf("unsafe.Slice of incomplete (or unallocatable) type not allowed")
 	}
+
 	if !checkunsafeslice(&n.Y) {
 		n.SetType(nil)
 		return n
diff --git a/src/cmd/compile/internal/typecheck/stmt.go b/src/cmd/compile/internal/typecheck/stmt.go
index 175216f..922a01b 100644
--- a/src/cmd/compile/internal/typecheck/stmt.go
+++ b/src/cmd/compile/internal/typecheck/stmt.go
@@ -204,8 +204,20 @@
 		r.Use = ir.CallUseList
 		rtyp := r.Type()
 
+		mismatched := false
+		failed := false
 		for i := range lhs {
-			assignType(i, rtyp.Field(i).Type)
+			result := rtyp.Field(i).Type
+			assignType(i, result)
+
+			if lhs[i].Type() == nil || result == nil {
+				failed = true
+			} else if lhs[i] != ir.BlankNode && !types.Identical(lhs[i].Type(), result) {
+				mismatched = true
+			}
+		}
+		if mismatched && !failed {
+			rewriteMultiValueCall(stmt, r)
 		}
 		return
 	}
diff --git a/src/cmd/compile/internal/typecheck/typecheck.go b/src/cmd/compile/internal/typecheck/typecheck.go
index 95f7b50..359f662 100644
--- a/src/cmd/compile/internal/typecheck/typecheck.go
+++ b/src/cmd/compile/internal/typecheck/typecheck.go
@@ -945,16 +945,18 @@
 		return
 	}
 
-	// Rewrite f(g()) into t1, t2, ... = g(); f(t1, t2, ...).
-
 	// Save n as n.Orig for fmt.go.
 	if ir.Orig(n) == n {
 		n.(ir.OrigNode).SetOrig(ir.SepCopy(n))
 	}
 
-	as := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, nil)
-	as.Rhs.Append(list...)
+	// Rewrite f(g()) into t1, t2, ... = g(); f(t1, t2, ...).
+	rewriteMultiValueCall(n, list[0])
+}
 
+// rewriteMultiValueCall rewrites multi-valued f() to use temporaries,
+// so the backend wouldn't need to worry about tuple-valued expressions.
+func rewriteMultiValueCall(n ir.InitNode, call ir.Node) {
 	// If we're outside of function context, then this call will
 	// be executed during the generated init function. However,
 	// init.go hasn't yet created it. Instead, associate the
@@ -964,25 +966,40 @@
 	if static {
 		ir.CurFunc = InitTodoFunc
 	}
-	list = nil
-	for _, f := range t.FieldSlice() {
-		t := Temp(f.Type)
-		as.PtrInit().Append(ir.NewDecl(base.Pos, ir.ODCL, t))
-		as.Lhs.Append(t)
-		list = append(list, t)
+
+	as := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, []ir.Node{call})
+	results := call.Type().FieldSlice()
+	list := make([]ir.Node, len(results))
+	for i, result := range results {
+		tmp := Temp(result.Type)
+		as.PtrInit().Append(ir.NewDecl(base.Pos, ir.ODCL, tmp))
+		as.Lhs.Append(tmp)
+		list[i] = tmp
 	}
 	if static {
 		ir.CurFunc = nil
 	}
 
+	n.PtrInit().Append(Stmt(as))
+
 	switch n := n.(type) {
+	default:
+		base.Fatalf("rewriteMultiValueCall %+v", n.Op())
 	case *ir.CallExpr:
 		n.Args = list
 	case *ir.ReturnStmt:
 		n.Results = list
+	case *ir.AssignListStmt:
+		if n.Op() != ir.OAS2FUNC {
+			base.Fatalf("rewriteMultiValueCall: invalid op %v", n.Op())
+		}
+		as.SetOp(ir.OAS2FUNC)
+		n.SetOp(ir.OAS2)
+		n.Rhs = make([]ir.Node, len(list))
+		for i, tmp := range list {
+			n.Rhs[i] = AssignConv(tmp, n.Lhs[i].Type(), "assignment")
+		}
 	}
-
-	n.PtrInit().Append(Stmt(as))
 }
 
 func checksliceindex(l ir.Node, r ir.Node, tp *types.Type) bool {
@@ -1443,15 +1460,22 @@
 }
 
 func errorDetails(nl ir.Nodes, tstruct *types.Type, isddd bool) string {
-	// If we don't know any type at a call site, let's suppress any return
-	// message signatures. See Issue https://golang.org/issues/19012.
+	// Suppress any return message signatures if:
+	//
+	// (1) We don't know any type at a call site (see #19012).
+	// (2) Any node has an unknown type.
+	// (3) Invalid type for variadic parameter (see #46957).
 	if tstruct == nil {
-		return ""
+		return "" // case 1
 	}
-	// If any node has an unknown type, suppress it as well
+
+	if isddd && !nl[len(nl)-1].Type().IsSlice() {
+		return "" // case 3
+	}
+
 	for _, n := range nl {
 		if n.Type() == nil {
-			return ""
+			return "" // case 2
 		}
 	}
 	return fmt.Sprintf("\n\thave %s\n\twant %v", fmtSignature(nl, isddd), tstruct)
diff --git a/src/cmd/compile/internal/types/fmt.go b/src/cmd/compile/internal/types/fmt.go
index b538ea8..8b98895 100644
--- a/src/cmd/compile/internal/types/fmt.go
+++ b/src/cmd/compile/internal/types/fmt.go
@@ -109,14 +109,18 @@
 		return "<S>"
 	}
 
-	if s.Name == "_" {
-		return "_"
+	q := pkgqual(s.Pkg, verb, mode)
+	if q == "" {
+		return s.Name
 	}
+
 	buf := fmtBufferPool.Get().(*bytes.Buffer)
 	buf.Reset()
 	defer fmtBufferPool.Put(buf)
 
-	symfmt(buf, s, verb, mode)
+	buf.WriteString(q)
+	buf.WriteByte('.')
+	buf.WriteString(s.Name)
 	return InternString(buf.Bytes())
 }
 
@@ -128,56 +132,49 @@
 		b.WriteString("<S>")
 		return
 	}
-	if s.Name == "_" {
-		b.WriteString("_")
-		return
-	}
 
 	symfmt(b, s, verb, mode)
 }
 
 func symfmt(b *bytes.Buffer, s *Sym, verb rune, mode fmtMode) {
+	if q := pkgqual(s.Pkg, verb, mode); q != "" {
+		b.WriteString(q)
+		b.WriteByte('.')
+	}
+	b.WriteString(s.Name)
+}
+
+// pkgqual returns the qualifier that should be used for printing
+// symbols from the given package in the given mode.
+// If it returns the empty string, no qualification is needed.
+func pkgqual(pkg *Pkg, verb rune, mode fmtMode) string {
 	if verb != 'S' {
 		switch mode {
 		case fmtGo: // This is for the user
-			if s.Pkg == BuiltinPkg || s.Pkg == LocalPkg {
-				b.WriteString(s.Name)
-				return
+			if pkg == BuiltinPkg || pkg == LocalPkg {
+				return ""
 			}
 
 			// If the name was used by multiple packages, display the full path,
-			if s.Pkg.Name != "" && NumImport[s.Pkg.Name] > 1 {
-				fmt.Fprintf(b, "%q.%s", s.Pkg.Path, s.Name)
-				return
+			if pkg.Name != "" && NumImport[pkg.Name] > 1 {
+				return strconv.Quote(pkg.Path)
 			}
-			b.WriteString(s.Pkg.Name)
-			b.WriteByte('.')
-			b.WriteString(s.Name)
-			return
+			return pkg.Name
 
 		case fmtDebug:
-			b.WriteString(s.Pkg.Name)
-			b.WriteByte('.')
-			b.WriteString(s.Name)
-			return
+			return pkg.Name
 
 		case fmtTypeIDName:
 			// dcommontype, typehash
-			b.WriteString(s.Pkg.Name)
-			b.WriteByte('.')
-			b.WriteString(s.Name)
-			return
+			return pkg.Name
 
 		case fmtTypeID:
 			// (methodsym), typesym, weaksym
-			b.WriteString(s.Pkg.Prefix)
-			b.WriteByte('.')
-			b.WriteString(s.Name)
-			return
+			return pkg.Prefix
 		}
 	}
 
-	b.WriteString(s.Name)
+	return ""
 }
 
 // Type
diff --git a/src/cmd/compile/internal/walk/builtin.go b/src/cmd/compile/internal/walk/builtin.go
index 62eb429..14efc05 100644
--- a/src/cmd/compile/internal/walk/builtin.go
+++ b/src/cmd/compile/internal/walk/builtin.go
@@ -489,7 +489,7 @@
 		base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", n.Type().Elem())
 	}
 	if n.Esc() == ir.EscNone {
-		if t.Size() >= ir.MaxImplicitStackVarSize {
+		if t.Size() > ir.MaxImplicitStackVarSize {
 			base.Fatalf("large ONEW with EscNone: %v", n)
 		}
 		return stackTempAddr(init, t)
@@ -654,36 +654,28 @@
 }
 
 func walkUnsafeSlice(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
+	ptr := safeExpr(n.X, init)
 	len := safeExpr(n.Y, init)
 
 	fnname := "unsafeslice64"
-	argtype := types.Types[types.TINT64]
+	lenType := types.Types[types.TINT64]
 
 	// Type checking guarantees that TIDEAL len/cap are positive and fit in an int.
 	// The case of len or cap overflow when converting TUINT or TUINTPTR to TINT
 	// will be handled by the negative range checks in unsafeslice during runtime.
-	if len.Type().IsKind(types.TIDEAL) || len.Type().Size() <= types.Types[types.TUINT].Size() {
+	if ir.ShouldCheckPtr(ir.CurFunc, 1) {
+		fnname = "unsafeslicecheckptr"
+		// for simplicity, unsafeslicecheckptr always uses int64
+	} else if len.Type().IsKind(types.TIDEAL) || len.Type().Size() <= types.Types[types.TUINT].Size() {
 		fnname = "unsafeslice"
-		argtype = types.Types[types.TINT]
+		lenType = types.Types[types.TINT]
 	}
 
 	t := n.Type()
 
-	// Call runtime.unsafeslice[64] to check that the length argument is
-	// non-negative and smaller than the max length allowed for the
-	// element type.
+	// Call runtime.unsafeslice{,64,checkptr} to check ptr and len.
 	fn := typecheck.LookupRuntime(fnname)
-	init.Append(mkcall1(fn, nil, init, reflectdata.TypePtr(t.Elem()), typecheck.Conv(len, argtype)))
-
-	ptr := walkExpr(n.X, init)
-
-	c := ir.NewUnaryExpr(n.Pos(), ir.OCHECKNIL, ptr)
-	c.SetTypecheck(1)
-	init.Append(c)
-
-	// TODO(mdempsky): checkptr instrumentation. Maybe merge into length
-	// check above, along with nil check? Need to be careful about
-	// notinheap pointers though: can't pass them as unsafe.Pointer.
+	init.Append(mkcall1(fn, nil, init, reflectdata.TypePtr(t.Elem()), typecheck.Conv(ptr, types.Types[types.TUNSAFEPTR]), typecheck.Conv(len, lenType)))
 
 	h := ir.NewSliceHeaderExpr(n.Pos(), t,
 		typecheck.Conv(ptr, types.Types[types.TUNSAFEPTR]),
diff --git a/src/cmd/compile/internal/walk/walk.go b/src/cmd/compile/internal/walk/walk.go
index fe2c62c..26da6e3 100644
--- a/src/cmd/compile/internal/walk/walk.go
+++ b/src/cmd/compile/internal/walk/walk.go
@@ -313,7 +313,7 @@
 			return true
 
 		case ir.OINDEX, ir.OSLICE, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR, ir.OSLICESTR,
-			ir.ODEREF, ir.ODOTPTR, ir.ODOTTYPE, ir.ODIV, ir.OMOD:
+			ir.ODEREF, ir.ODOTPTR, ir.ODOTTYPE, ir.ODIV, ir.OMOD, ir.OSLICE2ARRPTR:
 			// These ops might panic, make sure they are done
 			// before we start marshaling args for a call. See issue 16760.
 			return true
diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go
index 1ed2c0f..f40fa92 100644
--- a/src/cmd/dist/test.go
+++ b/src/cmd/dist/test.go
@@ -737,9 +737,9 @@
 						fn: func(dt *distTest) error {
 							cmd := t.addCmd(dt, "misc/swig/callback", t.goTest())
 							cmd.Env = append(os.Environ(),
-								"CGO_CFLAGS=-flto -Wno-lto-type-mismatch",
-								"CGO_CXXFLAGS=-flto -Wno-lto-type-mismatch",
-								"CGO_LDFLAGS=-flto -Wno-lto-type-mismatch",
+								"CGO_CFLAGS=-flto -Wno-lto-type-mismatch -Wno-unknown-warning-option",
+								"CGO_CXXFLAGS=-flto -Wno-lto-type-mismatch -Wno-unknown-warning-option",
+								"CGO_LDFLAGS=-flto -Wno-lto-type-mismatch -Wno-unknown-warning-option",
 							)
 							return nil
 						},
@@ -781,7 +781,7 @@
 			t.registerTest("testasan", "../misc/cgo/testasan", "go", "run", ".")
 		}
 		if goos == "linux" && goarch != "ppc64le" {
-			// because syscall.SysProcAttri struct used in misc/cgo/testsanitizers is only built on linux.
+			// because syscall.SysProcAttr struct used in misc/cgo/testsanitizers is only built on linux.
 			// Some inconsistent failures happen on ppc64le so disable for now.
 			t.registerHostTest("testsanitizers", "../misc/cgo/testsanitizers", "misc/cgo/testsanitizers", ".")
 		}
@@ -1057,7 +1057,7 @@
 			"darwin-amd64", "darwin-arm64",
 			"freebsd-amd64",
 			"android-arm", "android-arm64", "android-386",
-			"windows-amd64", "windows-386":
+			"windows-amd64", "windows-386", "windows-arm64":
 			return true
 		}
 		return false
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index ab61017..90eb3e2 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -1186,13 +1186,17 @@
 //
 // Usage:
 //
-// 	go mod graph
+// 	go mod graph [-go=version]
 //
 // Graph prints the module requirement graph (with replacements applied)
 // in text form. Each line in the output has two space-separated fields: a module
 // and one of its requirements. Each module is identified as a string of the form
 // path@version, except for the main module, which has no @version suffix.
 //
+// The -go flag causes graph to report the module graph as loaded by by the
+// given Go version, instead of the version indicated by the 'go' directive
+// in the go.mod file.
+//
 // See https://golang.org/ref/mod#go-mod-graph for more about 'go mod graph'.
 //
 //
@@ -1568,7 +1572,7 @@
 //
 // A build constraint, also known as a build tag, is a line comment that begins
 //
-// 	// +build
+// 	//go:build
 //
 // that lists the conditions under which a file should be included in the package.
 // Constraints may appear in any kind of source file (not just Go), but
@@ -1576,30 +1580,20 @@
 // only by blank lines and other line comments. These rules mean that in Go
 // files a build constraint must appear before the package clause.
 //
-// To distinguish build constraints from package documentation, a series of
-// build constraints must be followed by a blank line.
+// To distinguish build constraints from package documentation,
+// a build constraint should be followed by a blank line.
 //
-// A build constraint is evaluated as the OR of space-separated options.
-// Each option evaluates as the AND of its comma-separated terms.
-// Each term consists of letters, digits, underscores, and dots.
-// A term may be negated with a preceding !.
-// For example, the build constraint:
+// A build constraint is evaluated as an expression containing options
+// combined by ||, &&, and ! operators and parentheses. Operators have
+// the same meaning as in Go.
 //
-// 	// +build linux,386 darwin,!cgo
+// For example, the following build constraint constrains a file to
+// build when the "linux" and "386" constraints are satisfied, or when
+// "darwin" is satisfied and "cgo" is not:
 //
-// corresponds to the boolean formula:
+// 	//go:build (linux && 386) || (darwin && !cgo)
 //
-// 	(linux AND 386) OR (darwin AND (NOT cgo))
-//
-// A file may have multiple build constraints. The overall constraint is the AND
-// of the individual constraints. That is, the build constraints:
-//
-// 	// +build linux darwin
-// 	// +build amd64
-//
-// corresponds to the boolean formula:
-//
-// 	(linux OR darwin) AND amd64
+// It is an error for a file to have more than one //go:build line.
 //
 // During a particular build, the following words are satisfied:
 //
@@ -1637,24 +1631,28 @@
 //
 // To keep a file from being considered for the build:
 //
-// 	// +build ignore
+// 	//go:build ignore
 //
 // (any other unsatisfied word will work as well, but "ignore" is conventional.)
 //
 // To build a file only when using cgo, and only on Linux and OS X:
 //
-// 	// +build linux,cgo darwin,cgo
+// 	//go:build cgo && (linux || darwin)
 //
 // Such a file is usually paired with another file implementing the
 // default functionality for other systems, which in this case would
 // carry the constraint:
 //
-// 	// +build !linux,!darwin !cgo
+// 	//go:build !(cgo && (linux || darwin))
 //
 // Naming a file dns_windows.go will cause it to be included only when
 // building the package for Windows; similarly, math_386.s will be included
 // only when building the package for 32-bit x86.
 //
+// Go versions 1.16 and earlier used a different syntax for build constraints,
+// with a "// +build" prefix. The gofmt command will add an equivalent //go:build
+// constraint when encountering the older syntax.
+//
 //
 // Build modes
 //
@@ -1893,6 +1891,9 @@
 // 	GOMIPS64
 // 		For GOARCH=mips64{,le}, whether to use floating point instructions.
 // 		Valid values are hardfloat (default), softfloat.
+// 	GOPPC64
+// 		For GOARCH=ppc64{,le}, the target ISA (Instruction Set Architecture).
+// 		Valid values are power8 (default), power9.
 // 	GOWASM
 // 		For GOARCH=wasm, comma-separated list of experimental WebAssembly features to use.
 // 		Valid values are satconv, signext.
@@ -1902,6 +1903,12 @@
 // 	GCCGOTOOLDIR
 // 		If set, where to find gccgo tools, such as cgo.
 // 		The default is based on how gccgo was configured.
+// 	GOEXPERIMENT
+// 		Comma-separated list of toolchain experiments to enable or disable.
+// 		The list of available experiments may change arbitrarily over time.
+// 		See src/internal/goexperiment/flags.go for currently valid values.
+// 		Warning: This variable is provided for the development and testing
+// 		of the Go toolchain itself. Use beyond that purpose is unsupported.
 // 	GOROOT_FINAL
 // 		The root of the installed Go tree, when it is
 // 		installed in a location other than where it is built.
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index a059a6d..c0c86ab 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -72,7 +72,6 @@
 // (temp) directory.
 var testGOROOT string
 
-var testCC string
 var testGOCACHE string
 
 var testGo string
@@ -179,13 +178,6 @@
 			os.Exit(2)
 		}
 
-		out, err = exec.Command(gotool, "env", "CC").CombinedOutput()
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "could not find testing CC: %v\n%s", err, out)
-			os.Exit(2)
-		}
-		testCC = strings.TrimSpace(string(out))
-
 		cmd := exec.Command(testGo, "env", "CGO_ENABLED")
 		cmd.Stderr = new(strings.Builder)
 		if out, err := cmd.Output(); err != nil {
@@ -2185,7 +2177,7 @@
 			// See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
 			section := f.Section(".edata")
 			if section == nil {
-				t.Fatalf(".edata section is not present")
+				t.Skip(".edata section is not present")
 			}
 			// TODO: deduplicate this struct from cmd/link/internal/ld/pe.go
 			type IMAGE_EXPORT_DIRECTORY struct {
diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go
index b47eb81..57a3c1f 100644
--- a/src/cmd/go/internal/cfg/cfg.go
+++ b/src/cmd/go/internal/cfg/cfg.go
@@ -77,6 +77,14 @@
 	ctxt.GOOS = envOr("GOOS", ctxt.GOOS)
 	ctxt.GOARCH = envOr("GOARCH", ctxt.GOARCH)
 
+	// The experiments flags are based on GOARCH, so they may
+	// need to change.  TODO: This should be cleaned up.
+	buildcfg.UpdateExperiments(ctxt.GOOS, ctxt.GOARCH, envOr("GOEXPERIMENT", buildcfg.DefaultGOEXPERIMENT))
+	ctxt.ToolTags = nil
+	for _, exp := range buildcfg.EnabledExperiments() {
+		ctxt.ToolTags = append(ctxt.ToolTags, "goexperiment."+exp)
+	}
+
 	// The go/build rule for whether cgo is enabled is:
 	//	1. If $CGO_ENABLED is set, respect it.
 	//	2. Otherwise, if this is a cross-compile, disable cgo.
diff --git a/src/cmd/go/internal/envcmd/env.go b/src/cmd/go/internal/envcmd/env.go
index b30c37ab..1553d26 100644
--- a/src/cmd/go/internal/envcmd/env.go
+++ b/src/cmd/go/internal/envcmd/env.go
@@ -10,6 +10,7 @@
 	"encoding/json"
 	"fmt"
 	"go/build"
+	"internal/buildcfg"
 	"io"
 	"os"
 	"path/filepath"
@@ -72,6 +73,7 @@
 		{Name: "GOCACHE", Value: cache.DefaultDir()},
 		{Name: "GOENV", Value: envFile},
 		{Name: "GOEXE", Value: cfg.ExeSuffix},
+		{Name: "GOEXPERIMENT", Value: buildcfg.GOEXPERIMENT()},
 		{Name: "GOFLAGS", Value: cfg.Getenv("GOFLAGS")},
 		{Name: "GOHOSTARCH", Value: runtime.GOARCH},
 		{Name: "GOHOSTOS", Value: runtime.GOOS},
@@ -197,6 +199,21 @@
 	if *envU && *envW {
 		base.Fatalf("go env: cannot use -u with -w")
 	}
+
+	// Handle 'go env -w' and 'go env -u' before calling buildcfg.Check,
+	// so they can be used to recover from an invalid configuration.
+	if *envW {
+		runEnvW(args)
+		return
+	}
+
+	if *envU {
+		runEnvU(args)
+		return
+	}
+
+	buildcfg.Check()
+
 	env := cfg.CmdEnv
 	env = append(env, ExtraEnvVars()...)
 
@@ -206,14 +223,7 @@
 
 	// Do we need to call ExtraEnvVarsCostly, which is a bit expensive?
 	needCostly := false
-	if *envU || *envW {
-		// We're overwriting or removing default settings,
-		// so it doesn't really matter what the existing settings are.
-		//
-		// Moreover, we haven't validated the new settings yet, so it is
-		// important that we NOT perform any actions based on them,
-		// such as initializing the builder to compute other variables.
-	} else if len(args) == 0 {
+	if len(args) == 0 {
 		// We're listing all environment variables ("go env"),
 		// including the expensive ones.
 		needCostly = true
@@ -238,95 +248,6 @@
 		env = append(env, ExtraEnvVarsCostly()...)
 	}
 
-	if *envW {
-		// Process and sanity-check command line.
-		if len(args) == 0 {
-			base.Fatalf("go env -w: no KEY=VALUE arguments given")
-		}
-		osEnv := make(map[string]string)
-		for _, e := range cfg.OrigEnv {
-			if i := strings.Index(e, "="); i >= 0 {
-				osEnv[e[:i]] = e[i+1:]
-			}
-		}
-		add := make(map[string]string)
-		for _, arg := range args {
-			i := strings.Index(arg, "=")
-			if i < 0 {
-				base.Fatalf("go env -w: arguments must be KEY=VALUE: invalid argument: %s", arg)
-			}
-			key, val := arg[:i], arg[i+1:]
-			if err := checkEnvWrite(key, val); err != nil {
-				base.Fatalf("go env -w: %v", err)
-			}
-			if _, ok := add[key]; ok {
-				base.Fatalf("go env -w: multiple values for key: %s", key)
-			}
-			add[key] = val
-			if osVal := osEnv[key]; osVal != "" && osVal != val {
-				fmt.Fprintf(os.Stderr, "warning: go env -w %s=... does not override conflicting OS environment variable\n", key)
-			}
-		}
-
-		goos, okGOOS := add["GOOS"]
-		goarch, okGOARCH := add["GOARCH"]
-		if okGOOS || okGOARCH {
-			if !okGOOS {
-				goos = cfg.Goos
-			}
-			if !okGOARCH {
-				goarch = cfg.Goarch
-			}
-			if err := work.CheckGOOSARCHPair(goos, goarch); err != nil {
-				base.Fatalf("go env -w: %v", err)
-			}
-		}
-
-		gotmp, okGOTMP := add["GOTMPDIR"]
-		if okGOTMP {
-			if !filepath.IsAbs(gotmp) && gotmp != "" {
-				base.Fatalf("go env -w: GOTMPDIR must be an absolute path")
-			}
-		}
-
-		updateEnvFile(add, nil)
-		return
-	}
-
-	if *envU {
-		// Process and sanity-check command line.
-		if len(args) == 0 {
-			base.Fatalf("go env -u: no arguments given")
-		}
-		del := make(map[string]bool)
-		for _, arg := range args {
-			if err := checkEnvWrite(arg, ""); err != nil {
-				base.Fatalf("go env -u: %v", err)
-			}
-			del[arg] = true
-		}
-		if del["GOOS"] || del["GOARCH"] {
-			goos, goarch := cfg.Goos, cfg.Goarch
-			if del["GOOS"] {
-				goos = getOrigEnv("GOOS")
-				if goos == "" {
-					goos = build.Default.GOOS
-				}
-			}
-			if del["GOARCH"] {
-				goarch = getOrigEnv("GOARCH")
-				if goarch == "" {
-					goarch = build.Default.GOARCH
-				}
-			}
-			if err := work.CheckGOOSARCHPair(goos, goarch); err != nil {
-				base.Fatalf("go env -u: %v", err)
-			}
-		}
-		updateEnvFile(nil, del)
-		return
-	}
-
 	if len(args) > 0 {
 		if *envJson {
 			var es []cfg.EnvVar
@@ -351,6 +272,109 @@
 	PrintEnv(os.Stdout, env)
 }
 
+func runEnvW(args []string) {
+	// Process and sanity-check command line.
+	if len(args) == 0 {
+		base.Fatalf("go env -w: no KEY=VALUE arguments given")
+	}
+	osEnv := make(map[string]string)
+	for _, e := range cfg.OrigEnv {
+		if i := strings.Index(e, "="); i >= 0 {
+			osEnv[e[:i]] = e[i+1:]
+		}
+	}
+	add := make(map[string]string)
+	for _, arg := range args {
+		i := strings.Index(arg, "=")
+		if i < 0 {
+			base.Fatalf("go env -w: arguments must be KEY=VALUE: invalid argument: %s", arg)
+		}
+		key, val := arg[:i], arg[i+1:]
+		if err := checkEnvWrite(key, val); err != nil {
+			base.Fatalf("go env -w: %v", err)
+		}
+		if _, ok := add[key]; ok {
+			base.Fatalf("go env -w: multiple values for key: %s", key)
+		}
+		add[key] = val
+		if osVal := osEnv[key]; osVal != "" && osVal != val {
+			fmt.Fprintf(os.Stderr, "warning: go env -w %s=... does not override conflicting OS environment variable\n", key)
+		}
+	}
+
+	if err := checkBuildConfig(add, nil); err != nil {
+		base.Fatalf("go env -w: %v", err)
+	}
+
+	gotmp, okGOTMP := add["GOTMPDIR"]
+	if okGOTMP {
+		if !filepath.IsAbs(gotmp) && gotmp != "" {
+			base.Fatalf("go env -w: GOTMPDIR must be an absolute path")
+		}
+	}
+
+	updateEnvFile(add, nil)
+}
+
+func runEnvU(args []string) {
+	// Process and sanity-check command line.
+	if len(args) == 0 {
+		base.Fatalf("go env -u: no arguments given")
+	}
+	del := make(map[string]bool)
+	for _, arg := range args {
+		if err := checkEnvWrite(arg, ""); err != nil {
+			base.Fatalf("go env -u: %v", err)
+		}
+		del[arg] = true
+	}
+
+	if err := checkBuildConfig(nil, del); err != nil {
+		base.Fatalf("go env -u: %v", err)
+	}
+
+	updateEnvFile(nil, del)
+}
+
+// checkBuildConfig checks whether the build configuration is valid
+// after the specified configuration environment changes are applied.
+func checkBuildConfig(add map[string]string, del map[string]bool) error {
+	// get returns the value for key after applying add and del and
+	// reports whether it changed. cur should be the current value
+	// (i.e., before applying changes) and def should be the default
+	// value (i.e., when no environment variables are provided at all).
+	get := func(key, cur, def string) (string, bool) {
+		if val, ok := add[key]; ok {
+			return val, true
+		}
+		if del[key] {
+			val := getOrigEnv(key)
+			if val == "" {
+				val = def
+			}
+			return val, true
+		}
+		return cur, false
+	}
+
+	goos, okGOOS := get("GOOS", cfg.Goos, build.Default.GOOS)
+	goarch, okGOARCH := get("GOARCH", cfg.Goarch, build.Default.GOARCH)
+	if okGOOS || okGOARCH {
+		if err := work.CheckGOOSARCHPair(goos, goarch); err != nil {
+			return err
+		}
+	}
+
+	goexperiment, okGOEXPERIMENT := get("GOEXPERIMENT", buildcfg.GOEXPERIMENT(), "")
+	if okGOEXPERIMENT {
+		if _, _, err := buildcfg.ParseGOEXPERIMENT(goos, goarch, goexperiment); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
 // PrintEnv prints the environment variables to w.
 func PrintEnv(w io.Writer, env []cfg.EnvVar) {
 	for _, e := range env {
diff --git a/src/cmd/go/internal/help/helpdoc.go b/src/cmd/go/internal/help/helpdoc.go
index 2f86e41..490ff1f 100644
--- a/src/cmd/go/internal/help/helpdoc.go
+++ b/src/cmd/go/internal/help/helpdoc.go
@@ -598,6 +598,9 @@
 	GOMIPS64
 		For GOARCH=mips64{,le}, whether to use floating point instructions.
 		Valid values are hardfloat (default), softfloat.
+	GOPPC64
+		For GOARCH=ppc64{,le}, the target ISA (Instruction Set Architecture).
+		Valid values are power8 (default), power9.
 	GOWASM
 		For GOARCH=wasm, comma-separated list of experimental WebAssembly features to use.
 		Valid values are satconv, signext.
@@ -607,6 +610,12 @@
 	GCCGOTOOLDIR
 		If set, where to find gccgo tools, such as cgo.
 		The default is based on how gccgo was configured.
+	GOEXPERIMENT
+		Comma-separated list of toolchain experiments to enable or disable.
+		The list of available experiments may change arbitrarily over time.
+		See src/internal/goexperiment/flags.go for currently valid values.
+		Warning: This variable is provided for the development and testing
+		of the Go toolchain itself. Use beyond that purpose is unsupported.
 	GOROOT_FINAL
 		The root of the installed Go tree, when it is
 		installed in a location other than where it is built.
@@ -784,7 +793,7 @@
 	Long: `
 A build constraint, also known as a build tag, is a line comment that begins
 
-	// +build
+	//go:build
 
 that lists the conditions under which a file should be included in the package.
 Constraints may appear in any kind of source file (not just Go), but
@@ -792,30 +801,20 @@
 only by blank lines and other line comments. These rules mean that in Go
 files a build constraint must appear before the package clause.
 
-To distinguish build constraints from package documentation, a series of
-build constraints must be followed by a blank line.
+To distinguish build constraints from package documentation,
+a build constraint should be followed by a blank line.
 
-A build constraint is evaluated as the OR of space-separated options.
-Each option evaluates as the AND of its comma-separated terms.
-Each term consists of letters, digits, underscores, and dots.
-A term may be negated with a preceding !.
-For example, the build constraint:
+A build constraint is evaluated as an expression containing options
+combined by ||, &&, and ! operators and parentheses. Operators have
+the same meaning as in Go.
 
-	// +build linux,386 darwin,!cgo
+For example, the following build constraint constrains a file to
+build when the "linux" and "386" constraints are satisfied, or when
+"darwin" is satisfied and "cgo" is not:
 
-corresponds to the boolean formula:
+	//go:build (linux && 386) || (darwin && !cgo)
 
-	(linux AND 386) OR (darwin AND (NOT cgo))
-
-A file may have multiple build constraints. The overall constraint is the AND
-of the individual constraints. That is, the build constraints:
-
-	// +build linux darwin
-	// +build amd64
-
-corresponds to the boolean formula:
-
-	(linux OR darwin) AND amd64
+It is an error for a file to have more than one //go:build line.
 
 During a particular build, the following words are satisfied:
 
@@ -853,22 +852,26 @@
 
 To keep a file from being considered for the build:
 
-	// +build ignore
+	//go:build ignore
 
 (any other unsatisfied word will work as well, but "ignore" is conventional.)
 
 To build a file only when using cgo, and only on Linux and OS X:
 
-	// +build linux,cgo darwin,cgo
+	//go:build cgo && (linux || darwin)
 
 Such a file is usually paired with another file implementing the
 default functionality for other systems, which in this case would
 carry the constraint:
 
-	// +build !linux,!darwin !cgo
+	//go:build !(cgo && (linux || darwin))
 
 Naming a file dns_windows.go will cause it to be included only when
 building the package for Windows; similarly, math_386.s will be included
 only when building the package for 32-bit x86.
+
+Go versions 1.16 and earlier used a different syntax for build constraints,
+with a "// +build" prefix. The gofmt command will add an equivalent //go:build
+constraint when encountering the older syntax.
 `,
 }
diff --git a/src/cmd/go/internal/imports/read.go b/src/cmd/go/internal/imports/read.go
index 5e27078..70d5190 100644
--- a/src/cmd/go/internal/imports/read.go
+++ b/src/cmd/go/internal/imports/read.go
@@ -8,6 +8,7 @@
 
 import (
 	"bufio"
+	"bytes"
 	"errors"
 	"io"
 	"unicode/utf8"
@@ -22,6 +23,19 @@
 	nerr int
 }
 
+var bom = []byte{0xef, 0xbb, 0xbf}
+
+func newImportReader(b *bufio.Reader) *importReader {
+	// Remove leading UTF-8 BOM.
+	// Per https://golang.org/ref/spec#Source_code_representation:
+	// a compiler may ignore a UTF-8-encoded byte order mark (U+FEFF)
+	// if it is the first Unicode code point in the source text.
+	if leadingBytes, err := b.Peek(3); err == nil && bytes.Equal(leadingBytes, bom) {
+		b.Discard(3)
+	}
+	return &importReader{b: b}
+}
+
 func isIdent(c byte) bool {
 	return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '_' || c >= utf8.RuneSelf
 }
@@ -201,7 +215,7 @@
 // ReadComments is like io.ReadAll, except that it only reads the leading
 // block of comments in the file.
 func ReadComments(f io.Reader) ([]byte, error) {
-	r := &importReader{b: bufio.NewReader(f)}
+	r := newImportReader(bufio.NewReader(f))
 	r.peekByte(true)
 	if r.err == nil && !r.eof {
 		// Didn't reach EOF, so must have found a non-space byte. Remove it.
@@ -213,7 +227,7 @@
 // ReadImports is like io.ReadAll, except that it expects a Go file as input
 // and stops reading the input once the imports have completed.
 func ReadImports(f io.Reader, reportSyntaxError bool, imports *[]string) ([]byte, error) {
-	r := &importReader{b: bufio.NewReader(f)}
+	r := newImportReader(bufio.NewReader(f))
 
 	r.readKeyword("package")
 	r.readIdent()
diff --git a/src/cmd/go/internal/imports/read_test.go b/src/cmd/go/internal/imports/read_test.go
index 6ea356f..6a1a652 100644
--- a/src/cmd/go/internal/imports/read_test.go
+++ b/src/cmd/go/internal/imports/read_test.go
@@ -66,6 +66,10 @@
 		`,
 		"",
 	},
+	{
+		"\ufeffđ”»" + `package p; import "x";ℙvar x = 1`,
+		"",
+	},
 }
 
 var readCommentsTests = []readTest{
@@ -82,6 +86,10 @@
 		"",
 	},
 	{
+		"\ufeffđ”»" + `ℙpackage p; import . "x"`,
+		"",
+	},
+	{
 		`// foo
 
 		/* bar */
@@ -94,6 +102,19 @@
 		ℙHello, world`,
 		"",
 	},
+	{
+		"\ufeffđ”»" + `// foo
+
+		/* bar */
+
+		/* quux */ // baz
+
+		/*/ zot */
+
+		// asdf
+		ℙHello, world`,
+		"",
+	},
 }
 
 func testRead(t *testing.T, tests []readTest, read func(io.Reader) ([]byte, error)) {
@@ -107,6 +128,11 @@
 			in = tt.in[:j] + tt.in[j+len("ℙ"):]
 			testOut = tt.in[:j]
 		}
+		d := strings.Index(tt.in, "đ”»")
+		if d >= 0 {
+			in = in[:d] + in[d+len("đ”»"):]
+			testOut = testOut[d+len("đ”»"):]
+		}
 		r := strings.NewReader(in)
 		buf, err := read(r)
 		if err != nil {
diff --git a/src/cmd/go/internal/list/list.go b/src/cmd/go/internal/list/list.go
index 53aaf31..7cb9ec6 100644
--- a/src/cmd/go/internal/list/list.go
+++ b/src/cmd/go/internal/list/list.go
@@ -724,8 +724,18 @@
 
 	// Record non-identity import mappings in p.ImportMap.
 	for _, p := range pkgs {
-		for i, srcPath := range p.Internal.RawImports {
-			path := p.Imports[i]
+		nRaw := len(p.Internal.RawImports)
+		for i, path := range p.Imports {
+			var srcPath string
+			if i < nRaw {
+				srcPath = p.Internal.RawImports[i]
+			} else {
+				// This path is not within the raw imports, so it must be an import
+				// found only within CompiledGoFiles. Those paths are found in
+				// CompiledImports.
+				srcPath = p.Internal.CompiledImports[i-nRaw]
+			}
+
 			if path != srcPath {
 				if p.ImportMap == nil {
 					p.ImportMap = make(map[string]string)
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
index 158bce4..ef5b383 100644
--- a/src/cmd/go/internal/load/pkg.go
+++ b/src/cmd/go/internal/load/pkg.go
@@ -194,8 +194,8 @@
 	// Unexported fields are not part of the public API.
 	Build             *build.Package
 	Imports           []*Package           // this package's direct imports
-	CompiledImports   []string             // additional Imports necessary when using CompiledGoFiles (all from standard library)
-	RawImports        []string             // this package's original imports as they appear in the text of the program
+	CompiledImports   []string             // additional Imports necessary when using CompiledGoFiles (all from standard library); 1:1 with the end of PackagePublic.Imports
+	RawImports        []string             // this package's original imports as they appear in the text of the program; 1:1 with the end of PackagePublic.Imports
 	ForceLibrary      bool                 // this package is a library (even if named "main")
 	CmdlineFiles      bool                 // package built from files listed on command line
 	CmdlinePkg        bool                 // package listed on command line
diff --git a/src/cmd/go/internal/load/test.go b/src/cmd/go/internal/load/test.go
index 6baa1db..c828296 100644
--- a/src/cmd/go/internal/load/test.go
+++ b/src/cmd/go/internal/load/test.go
@@ -116,7 +116,7 @@
 			// Can't change that code, because that code is only for loading the
 			// non-test copy of a package.
 			ptestErr = &PackageError{
-				ImportStack:   testImportStack(stk[0], p1, p.ImportPath),
+				ImportStack:   importCycleStack(p1, p.ImportPath),
 				Err:           errors.New("import cycle not allowed in test"),
 				IsImportCycle: true,
 			}
@@ -375,22 +375,44 @@
 	return pmain, ptest, pxtest
 }
 
-func testImportStack(top string, p *Package, target string) []string {
-	stk := []string{top, p.ImportPath}
-Search:
-	for p.ImportPath != target {
-		for _, p1 := range p.Internal.Imports {
-			if p1.ImportPath == target || str.Contains(p1.Deps, target) {
-				stk = append(stk, p1.ImportPath)
-				p = p1
-				continue Search
+// importCycleStack returns an import stack from p to the package whose import
+// path is target.
+func importCycleStack(p *Package, target string) []string {
+	// importerOf maps each import path to its importer nearest to p.
+	importerOf := map[string]string{p.ImportPath: ""}
+
+	// q is a breadth-first queue of packages to search for target.
+	// Every package added to q has a corresponding entry in pathTo.
+	//
+	// We search breadth-first for two reasons:
+	//
+	// 	1. We want to report the shortest cycle.
+	//
+	// 	2. If p contains multiple cycles, the first cycle we encounter might not
+	// 	   contain target. To ensure termination, we have to break all cycles
+	// 	   other than the first.
+	q := []*Package{p}
+
+	for len(q) > 0 {
+		p := q[0]
+		q = q[1:]
+		if path := p.ImportPath; path == target {
+			var stk []string
+			for path != "" {
+				stk = append(stk, path)
+				path = importerOf[path]
+			}
+			return stk
+		}
+		for _, dep := range p.Internal.Imports {
+			if _, ok := importerOf[dep.ImportPath]; !ok {
+				importerOf[dep.ImportPath] = p.ImportPath
+				q = append(q, dep)
 			}
 		}
-		// Can't happen, but in case it does...
-		stk = append(stk, "<lost path to cycle>")
-		break
 	}
-	return stk
+
+	panic("lost path to cycle")
 }
 
 // recompileForTest copies and replaces certain packages in pmain's dependency
diff --git a/src/cmd/go/internal/lockedfile/lockedfile_filelock.go b/src/cmd/go/internal/lockedfile/lockedfile_filelock.go
index 729df5c..e4923f6 100644
--- a/src/cmd/go/internal/lockedfile/lockedfile_filelock.go
+++ b/src/cmd/go/internal/lockedfile/lockedfile_filelock.go
@@ -11,7 +11,6 @@
 	"io/fs"
 	"os"
 
-	"cmd/go/internal/fsys"
 	"cmd/go/internal/lockedfile/internal/filelock"
 )
 
@@ -21,7 +20,7 @@
 	// calls for Linux and Windows anyway, so it's simpler to use that approach
 	// consistently.
 
-	f, err := fsys.OpenFile(name, flag&^os.O_TRUNC, perm)
+	f, err := os.OpenFile(name, flag&^os.O_TRUNC, perm)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/cmd/go/internal/lockedfile/lockedfile_plan9.go b/src/cmd/go/internal/lockedfile/lockedfile_plan9.go
index 3d4b97d..979118b 100644
--- a/src/cmd/go/internal/lockedfile/lockedfile_plan9.go
+++ b/src/cmd/go/internal/lockedfile/lockedfile_plan9.go
@@ -13,8 +13,6 @@
 	"os"
 	"strings"
 	"time"
-
-	"cmd/go/internal/fsys"
 )
 
 // Opening an exclusive-use file returns an error.
@@ -59,7 +57,7 @@
 	// If the file was unpacked or created by some other program, it might not
 	// have the ModeExclusive bit set. Set it before we call OpenFile, so that we
 	// can be confident that a successful OpenFile implies exclusive use.
-	if fi, err := fsys.Stat(name); err == nil {
+	if fi, err := os.Stat(name); err == nil {
 		if fi.Mode()&fs.ModeExclusive == 0 {
 			if err := os.Chmod(name, fi.Mode()|fs.ModeExclusive); err != nil {
 				return nil, err
@@ -72,7 +70,7 @@
 	nextSleep := 1 * time.Millisecond
 	const maxSleep = 500 * time.Millisecond
 	for {
-		f, err := fsys.OpenFile(name, flag, perm|fs.ModeExclusive)
+		f, err := os.OpenFile(name, flag, perm|fs.ModeExclusive)
 		if err == nil {
 			return f, nil
 		}
diff --git a/src/cmd/go/internal/modcmd/graph.go b/src/cmd/go/internal/modcmd/graph.go
index 7785330..903bd99 100644
--- a/src/cmd/go/internal/modcmd/graph.go
+++ b/src/cmd/go/internal/modcmd/graph.go
@@ -18,7 +18,7 @@
 )
 
 var cmdGraph = &base.Command{
-	UsageLine: "go mod graph",
+	UsageLine: "go mod graph [-go=version]",
 	Short:     "print module requirement graph",
 	Long: `
 Graph prints the module requirement graph (with replacements applied)
@@ -26,12 +26,21 @@
 and one of its requirements. Each module is identified as a string of the form
 path@version, except for the main module, which has no @version suffix.
 
+The -go flag causes graph to report the module graph as loaded by by the
+given Go version, instead of the version indicated by the 'go' directive
+in the go.mod file.
+
 See https://golang.org/ref/mod#go-mod-graph for more about 'go mod graph'.
 	`,
 	Run: runGraph,
 }
 
+var (
+	graphGo goVersionFlag
+)
+
 func init() {
+	cmdGraph.Flag.Var(&graphGo, "go", "")
 	base.AddModCommonFlags(&cmdGraph.Flag)
 }
 
@@ -41,7 +50,7 @@
 	}
 	modload.ForceUseModules = true
 	modload.RootMode = modload.NeedRoot
-	mg := modload.LoadModGraph(ctx)
+	mg := modload.LoadModGraph(ctx, graphGo.String())
 
 	w := bufio.NewWriter(os.Stdout)
 	defer w.Flush()
diff --git a/src/cmd/go/internal/modcmd/vendor.go b/src/cmd/go/internal/modcmd/vendor.go
index 8e1c043..713d5f9 100644
--- a/src/cmd/go/internal/modcmd/vendor.go
+++ b/src/cmd/go/internal/modcmd/vendor.go
@@ -13,6 +13,7 @@
 	"io"
 	"io/fs"
 	"os"
+	"path"
 	"path/filepath"
 	"sort"
 	"strings"
@@ -299,7 +300,7 @@
 		if modPath == pkg {
 			break
 		}
-		pkg = filepath.Dir(pkg)
+		pkg = path.Dir(pkg)
 		dst = filepath.Dir(dst)
 		src = filepath.Dir(src)
 	}
diff --git a/src/cmd/go/internal/modcmd/verify.go b/src/cmd/go/internal/modcmd/verify.go
index 5c321c7..5a6eca3 100644
--- a/src/cmd/go/internal/modcmd/verify.go
+++ b/src/cmd/go/internal/modcmd/verify.go
@@ -54,7 +54,8 @@
 	sem := make(chan token, runtime.GOMAXPROCS(0))
 
 	// Use a slice of result channels, so that the output is deterministic.
-	mods := modload.LoadModGraph(ctx).BuildList()[1:]
+	const defaultGoVersion = ""
+	mods := modload.LoadModGraph(ctx, defaultGoVersion).BuildList()[1:]
 	errsChans := make([]<-chan []error, len(mods))
 
 	for i, mod := range mods {
diff --git a/src/cmd/go/internal/modfetch/cache.go b/src/cmd/go/internal/modfetch/cache.go
index f3b58a1..b01b467 100644
--- a/src/cmd/go/internal/modfetch/cache.go
+++ b/src/cmd/go/internal/modfetch/cache.go
@@ -152,7 +152,7 @@
 // If err is nil, the caller MUST eventually call the unlock function.
 func SideLock() (unlock func(), err error) {
 	if err := checkCacheDir(); err != nil {
-		base.Fatalf("go: %v", err)
+		return nil, err
 	}
 
 	path := filepath.Join(cfg.GOMODCACHE, "cache", "lock")
diff --git a/src/cmd/go/internal/modfetch/codehost/git_test.go b/src/cmd/go/internal/modfetch/codehost/git_test.go
index 89a73ba..a684fa1 100644
--- a/src/cmd/go/internal/modfetch/codehost/git_test.go
+++ b/src/cmd/go/internal/modfetch/codehost/git_test.go
@@ -8,7 +8,6 @@
 	"archive/zip"
 	"bytes"
 	"flag"
-	"fmt"
 	"internal/testenv"
 	"io"
 	"io/fs"
@@ -47,12 +46,6 @@
 var localGitRepo string
 
 func testMain(m *testing.M) int {
-	if _, err := exec.LookPath("git"); err != nil {
-		fmt.Fprintln(os.Stderr, "skipping because git binary not found")
-		fmt.Println("PASS")
-		return 0
-	}
-
 	dir, err := os.MkdirTemp("", "gitrepo-test-")
 	if err != nil {
 		log.Fatal(err)
@@ -60,23 +53,25 @@
 	defer os.RemoveAll(dir)
 
 	if testenv.HasExternalNetwork() && testenv.HasExec() {
-		// Clone gitrepo1 into a local directory.
-		// If we use a file:// URL to access the local directory,
-		// then git starts up all the usual protocol machinery,
-		// which will let us test remote git archive invocations.
-		localGitRepo = filepath.Join(dir, "gitrepo2")
-		if _, err := Run("", "git", "clone", "--mirror", gitrepo1, localGitRepo); err != nil {
-			log.Fatal(err)
-		}
-		if _, err := Run(localGitRepo, "git", "config", "daemon.uploadarch", "true"); err != nil {
-			log.Fatal(err)
+		if _, err := exec.LookPath("git"); err == nil {
+			// Clone gitrepo1 into a local directory.
+			// If we use a file:// URL to access the local directory,
+			// then git starts up all the usual protocol machinery,
+			// which will let us test remote git archive invocations.
+			localGitRepo = filepath.Join(dir, "gitrepo2")
+			if _, err := Run("", "git", "clone", "--mirror", gitrepo1, localGitRepo); err != nil {
+				log.Fatal(err)
+			}
+			if _, err := Run(localGitRepo, "git", "config", "daemon.uploadarch", "true"); err != nil {
+				log.Fatal(err)
+			}
 		}
 	}
 
 	return m.Run()
 }
 
-func testRepo(remote string) (Repo, error) {
+func testRepo(t *testing.T, remote string) (Repo, error) {
 	if remote == "localGitRepo" {
 		// Convert absolute path to file URL. LocalGitRepo will not accept
 		// Windows absolute paths because they look like a host:path remote.
@@ -87,15 +82,17 @@
 		} else {
 			url = "file:///" + filepath.ToSlash(localGitRepo)
 		}
+		testenv.MustHaveExecPath(t, "git")
 		return LocalGitRepo(url)
 	}
-	kind := "git"
+	vcs := "git"
 	for _, k := range []string{"hg"} {
 		if strings.Contains(remote, "/"+k+"/") {
-			kind = k
+			vcs = k
 		}
 	}
-	return NewRepo(kind, remote)
+	testenv.MustHaveExecPath(t, vcs)
+	return NewRepo(vcs, remote)
 }
 
 var tagsTests = []struct {
@@ -116,7 +113,7 @@
 
 	for _, tt := range tagsTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -168,7 +165,7 @@
 
 	for _, tt := range latestTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -221,7 +218,7 @@
 
 	for _, tt := range readFileTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -412,7 +409,7 @@
 
 	for _, tt := range readZipTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -581,7 +578,7 @@
 
 	for _, tt := range statTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
diff --git a/src/cmd/go/internal/modfetch/fetch.go b/src/cmd/go/internal/modfetch/fetch.go
index e40593a..d3d30d9 100644
--- a/src/cmd/go/internal/modfetch/fetch.go
+++ b/src/cmd/go/internal/modfetch/fetch.go
@@ -22,6 +22,7 @@
 
 	"cmd/go/internal/base"
 	"cmd/go/internal/cfg"
+	"cmd/go/internal/fsys"
 	"cmd/go/internal/lockedfile"
 	"cmd/go/internal/par"
 	"cmd/go/internal/robustio"
@@ -416,7 +417,18 @@
 
 	goSum.m = make(map[module.Version][]string)
 	goSum.status = make(map[modSum]modSumStatus)
-	data, err := lockedfile.Read(GoSumFile)
+	var (
+		data []byte
+		err  error
+	)
+	if actualSumFile, ok := fsys.OverlayPath(GoSumFile); ok {
+		// Don't lock go.sum if it's part of the overlay.
+		// On Plan 9, locking requires chmod, and we don't want to modify any file
+		// in the overlay. See #44700.
+		data, err = os.ReadFile(actualSumFile)
+	} else {
+		data, err = lockedfile.Read(GoSumFile)
+	}
 	if err != nil && !os.IsNotExist(err) {
 		return false, err
 	}
@@ -716,6 +728,9 @@
 	if cfg.BuildMod == "readonly" {
 		base.Fatalf("go: updates to go.sum needed, disabled by -mod=readonly")
 	}
+	if _, ok := fsys.OverlayPath(GoSumFile); ok {
+		base.Fatalf("go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay")
+	}
 
 	// Make a best-effort attempt to acquire the side lock, only to exclude
 	// previous versions of the 'go' command from making simultaneous edits.
diff --git a/src/cmd/go/internal/modget/get.go b/src/cmd/go/internal/modget/get.go
index 8eee723..9672e55 100644
--- a/src/cmd/go/internal/modget/get.go
+++ b/src/cmd/go/internal/modget/get.go
@@ -506,7 +506,8 @@
 func newResolver(ctx context.Context, queries []*query) *resolver {
 	// LoadModGraph also sets modload.Target, which is needed by various resolver
 	// methods.
-	mg := modload.LoadModGraph(ctx)
+	const defaultGoVersion = ""
+	mg := modload.LoadModGraph(ctx, defaultGoVersion)
 
 	buildList := mg.BuildList()
 	initialVersion := make(map[string]string, len(buildList))
@@ -1153,6 +1154,7 @@
 		Tags:                     imports.AnyTags(),
 		VendorModulesInGOROOTSrc: true,
 		LoadTests:                *getT,
+		AssumeRootsImported:      true, // After 'go get foo', imports of foo should build.
 		SilencePackageErrors:     true, // May be fixed by subsequent upgrades or downgrades.
 	}
 
@@ -1802,7 +1804,8 @@
 		return false
 	}
 
-	r.buildList = modload.LoadModGraph(ctx).BuildList()
+	const defaultGoVersion = ""
+	r.buildList = modload.LoadModGraph(ctx, defaultGoVersion).BuildList()
 	r.buildListVersion = make(map[string]string, len(r.buildList))
 	for _, m := range r.buildList {
 		r.buildListVersion[m.Path] = m.Version
diff --git a/src/cmd/go/internal/modload/buildlist.go b/src/cmd/go/internal/modload/buildlist.go
index e5db41c..604a57b 100644
--- a/src/cmd/go/internal/modload/buildlist.go
+++ b/src/cmd/go/internal/modload/buildlist.go
@@ -403,11 +403,33 @@
 // LoadModGraph loads and returns the graph of module dependencies of the main module,
 // without loading any packages.
 //
+// If the goVersion string is non-empty, the returned graph is the graph
+// as interpreted by the given Go version (instead of the version indicated
+// in the go.mod file).
+//
 // Modules are loaded automatically (and lazily) in LoadPackages:
 // LoadModGraph need only be called if LoadPackages is not,
 // typically in commands that care about modules but no particular package.
-func LoadModGraph(ctx context.Context) *ModuleGraph {
-	rs, mg, err := expandGraph(ctx, LoadModFile(ctx))
+func LoadModGraph(ctx context.Context, goVersion string) *ModuleGraph {
+	rs := LoadModFile(ctx)
+
+	if goVersion != "" {
+		depth := modDepthFromGoVersion(goVersion)
+		if depth == eager && rs.depth != eager {
+			// Use newRequirements instead of convertDepth because convertDepth
+			// also updates roots; here, we want to report the unmodified roots
+			// even though they may seem inconsistent.
+			rs = newRequirements(eager, rs.rootModules, rs.direct)
+		}
+
+		mg, err := rs.Graph(ctx)
+		if err != nil {
+			base.Fatalf("go: %v", err)
+		}
+		return mg
+	}
+
+	rs, mg, err := expandGraph(ctx, rs)
 	if err != nil {
 		base.Fatalf("go: %v", err)
 	}
@@ -443,7 +465,7 @@
 		// roots — but in a lazy module it may pull in previously-irrelevant
 		// transitive dependencies.
 
-		newRS, rsErr := updateRoots(ctx, rs.direct, rs, nil, nil)
+		newRS, rsErr := updateRoots(ctx, rs.direct, rs, nil, nil, false)
 		if rsErr != nil {
 			// Failed to update roots, perhaps because of an error in a transitive
 			// dependency needed for the update. Return the original Requirements
@@ -517,11 +539,11 @@
 	return tidyLazyRoots(ctx, rs.direct, pkgs)
 }
 
-func updateRoots(ctx context.Context, direct map[string]bool, rs *Requirements, pkgs []*loadPkg, add []module.Version) (*Requirements, error) {
+func updateRoots(ctx context.Context, direct map[string]bool, rs *Requirements, pkgs []*loadPkg, add []module.Version, rootsImported bool) (*Requirements, error) {
 	if rs.depth == eager {
 		return updateEagerRoots(ctx, direct, rs, add)
 	}
-	return updateLazyRoots(ctx, direct, rs, pkgs, add)
+	return updateLazyRoots(ctx, direct, rs, pkgs, add, rootsImported)
 }
 
 // tidyLazyRoots returns a minimal set of root requirements that maintains the
@@ -661,7 +683,7 @@
 //
 // (See https://golang.org/design/36460-lazy-module-loading#invariants for more
 // detail.)
-func updateLazyRoots(ctx context.Context, direct map[string]bool, rs *Requirements, pkgs []*loadPkg, add []module.Version) (*Requirements, error) {
+func updateLazyRoots(ctx context.Context, direct map[string]bool, rs *Requirements, pkgs []*loadPkg, add []module.Version, rootsImported bool) (*Requirements, error) {
 	roots := rs.rootModules
 	rootsUpgraded := false
 
@@ -688,6 +710,10 @@
 			//
 			// (This is the “import invariant” that makes lazy loading possible.)
 
+		case rootsImported && pkg.flags.has(pkgFromRoot):
+			// pkg is a transitive dependency of some root, and we are treating the
+			// roots as if they are imported by the main module (as in 'go get').
+
 		case pkg.flags.has(pkgIsRoot):
 			// pkg is a root of the package-import graph. (Generally this means that
 			// it matches a command-line argument.) We want future invocations of the
diff --git a/src/cmd/go/internal/modload/import.go b/src/cmd/go/internal/modload/import.go
index f76befc..d2bbe5c 100644
--- a/src/cmd/go/internal/modload/import.go
+++ b/src/cmd/go/internal/modload/import.go
@@ -178,11 +178,13 @@
 		// Importing package is unknown, or the missing package was named on the
 		// command line. Recommend 'go mod download' for the modules that could
 		// provide the package, since that shouldn't change go.mod.
-		args := make([]string, len(e.mods))
-		for i, mod := range e.mods {
-			args[i] = mod.Path
+		if len(e.mods) > 0 {
+			args := make([]string, len(e.mods))
+			for i, mod := range e.mods {
+				args[i] = mod.Path
+			}
+			hint = fmt.Sprintf("; to add:\n\tgo mod download %s", strings.Join(args, " "))
 		}
-		hint = fmt.Sprintf("; to add:\n\tgo mod download %s", strings.Join(args, " "))
 	} else {
 		// Importing package is known (common case). Recommend 'go get' on the
 		// current version of the importing package.
@@ -426,6 +428,15 @@
 					mv = module.ZeroPseudoVersion("v0")
 				}
 			}
+			mg, err := rs.Graph(ctx)
+			if err != nil {
+				return module.Version{}, err
+			}
+			if cmpVersion(mg.Selected(mp), mv) >= 0 {
+				// We can't resolve the import by adding mp@mv to the module graph,
+				// because the selected version of mp is already at least mv.
+				continue
+			}
 			mods = append(mods, module.Version{Path: mp, Version: mv})
 		}
 
diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go
index eb9cfe6..a8cbd9f 100644
--- a/src/cmd/go/internal/modload/init.go
+++ b/src/cmd/go/internal/modload/init.go
@@ -71,7 +71,7 @@
 const (
 	// AutoRoot is the default for most commands. modload.Init will look for
 	// a go.mod file in the current directory or any parent. If none is found,
-	// modules may be disabled (GO111MODULE=on) or commands may run in a
+	// modules may be disabled (GO111MODULE=auto) or commands may run in a
 	// limited module mode.
 	AutoRoot Root = iota
 
@@ -412,7 +412,16 @@
 	}
 
 	gomod := ModFilePath()
-	data, err := lockedfile.Read(gomod)
+	var data []byte
+	var err error
+	if gomodActual, ok := fsys.OverlayPath(gomod); ok {
+		// Don't lock go.mod if it's part of the overlay.
+		// On Plan 9, locking requires chmod, and we don't want to modify any file
+		// in the overlay. See #44700.
+		data, err = os.ReadFile(gomodActual)
+	} else {
+		data, err = lockedfile.Read(gomodActual)
+	}
 	if err != nil {
 		base.Fatalf("go: %v", err)
 	}
@@ -661,7 +670,7 @@
 	for _, n := range mPathCount {
 		if n > 1 {
 			var err error
-			rs, err = updateRoots(ctx, rs.direct, rs, nil, nil)
+			rs, err = updateRoots(ctx, rs.direct, rs, nil, nil, false)
 			if err != nil {
 				base.Fatalf("go: %v", err)
 			}
@@ -1026,6 +1035,13 @@
 		}
 		return
 	}
+	gomod := ModFilePath()
+	if _, ok := fsys.OverlayPath(gomod); ok {
+		if dirty {
+			base.Fatalf("go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay")
+		}
+		return
+	}
 
 	new, err := modFile.Format()
 	if err != nil {
diff --git a/src/cmd/go/internal/modload/load.go b/src/cmd/go/internal/modload/load.go
index a9d1777..771b142 100644
--- a/src/cmd/go/internal/modload/load.go
+++ b/src/cmd/go/internal/modload/load.go
@@ -171,6 +171,11 @@
 	// if the flag is set to "readonly" (the default) or "vendor".
 	ResolveMissingImports bool
 
+	// AssumeRootsImported indicates that the transitive dependencies of the root
+	// packages should be treated as if those roots will be imported by the main
+	// module.
+	AssumeRootsImported bool
+
 	// AllowPackage, if non-nil, is called after identifying the module providing
 	// each package. If AllowPackage returns a non-nil error, that error is set
 	// for the package, and the imports and test of that package will not be
@@ -670,20 +675,6 @@
 	return "."
 }
 
-// TargetPackages returns the list of packages in the target (top-level) module
-// matching pattern, which may be relative to the working directory, under all
-// build tag settings.
-func TargetPackages(ctx context.Context, pattern string) *search.Match {
-	// TargetPackages is relative to the main module, so ensure that the main
-	// module is a thing that can contain packages.
-	LoadModFile(ctx) // Sets Target.
-	ModRoot()        // Emits an error if Target cannot contain packages.
-
-	m := search.NewMatch(pattern)
-	matchPackages(ctx, m, imports.AnyTags(), omitStd, []module.Version{Target})
-	return m
-}
-
 // ImportMap returns the actual package import path
 // for an import path found in source code.
 // If the given import path does not appear in the source code
@@ -715,29 +706,6 @@
 	return pkg.mod
 }
 
-// PackageImports returns the imports for the package named by the import path.
-// Test imports will be returned as well if tests were loaded for the package
-// (i.e., if "all" was loaded or if LoadTests was set and the path was matched
-// by a command line argument). PackageImports will return nil for
-// unknown package paths.
-func PackageImports(path string) (imports, testImports []string) {
-	pkg, ok := loaded.pkgCache.Get(path).(*loadPkg)
-	if !ok {
-		return nil, nil
-	}
-	imports = make([]string, len(pkg.imports))
-	for i, p := range pkg.imports {
-		imports[i] = p.path
-	}
-	if pkg.test != nil {
-		testImports = make([]string, len(pkg.test.imports))
-		for i, p := range pkg.test.imports {
-			testImports[i] = p.path
-		}
-	}
-	return imports, testImports
-}
-
 // Lookup returns the source directory, import path, and any loading error for
 // the package at path as imported from the package in parentDir.
 // Lookup requires that one of the Load functions in this package has already
@@ -875,6 +843,11 @@
 	// are also roots (and must be marked pkgIsRoot).
 	pkgIsRoot
 
+	// pkgFromRoot indicates that the package is in the transitive closure of
+	// imports starting at the roots. (Note that every package marked as pkgIsRoot
+	// is also trivially marked pkgFromRoot.)
+	pkgFromRoot
+
 	// pkgImportsLoaded indicates that the imports and testImports fields of a
 	// loadPkg have been populated.
 	pkgImportsLoaded
@@ -1068,7 +1041,7 @@
 		// iteration so we don't need to also update it here. (That would waste time
 		// computing a "direct" map that we'll have to recompute later anyway.)
 		direct := ld.requirements.direct
-		rs, err := updateRoots(ctx, direct, ld.requirements, noPkgs, toAdd)
+		rs, err := updateRoots(ctx, direct, ld.requirements, noPkgs, toAdd, ld.AssumeRootsImported)
 		if err != nil {
 			// If an error was found in a newly added module, report the package
 			// import stack instead of the module requirement stack. Packages
@@ -1274,7 +1247,7 @@
 		addRoots = tidy.rootModules
 	}
 
-	rs, err = updateRoots(ctx, direct, rs, ld.pkgs, addRoots)
+	rs, err = updateRoots(ctx, direct, rs, ld.pkgs, addRoots, ld.AssumeRootsImported)
 	if err != nil {
 		// We don't actually know what even the root requirements are supposed to be,
 		// so we can't proceed with loading. Return the error to the caller
@@ -1433,6 +1406,9 @@
 		// This package matches a root pattern by virtue of being in "all".
 		flags |= pkgIsRoot
 	}
+	if flags.has(pkgIsRoot) {
+		flags |= pkgFromRoot
+	}
 
 	old := pkg.flags.update(flags)
 	new := old | flags
@@ -1487,6 +1463,12 @@
 			ld.applyPkgFlags(ctx, dep, pkgInAll)
 		}
 	}
+
+	if new.has(pkgFromRoot) && !old.has(pkgFromRoot|pkgImportsLoaded) {
+		for _, dep := range pkg.imports {
+			ld.applyPkgFlags(ctx, dep, pkgFromRoot)
+		}
+	}
 }
 
 // preloadRootModules loads the module requirements needed to identify the
@@ -1549,7 +1531,7 @@
 	}
 	module.Sort(toAdd)
 
-	rs, err := updateRoots(ctx, ld.requirements.direct, ld.requirements, nil, toAdd)
+	rs, err := updateRoots(ctx, ld.requirements.direct, ld.requirements, nil, toAdd, ld.AssumeRootsImported)
 	if err != nil {
 		// We are missing some root dependency, and for some reason we can't load
 		// enough of the module dependency graph to add the missing root. Package
diff --git a/src/cmd/go/internal/modload/modfile.go b/src/cmd/go/internal/modload/modfile.go
index 1145ac4..d280945 100644
--- a/src/cmd/go/internal/modload/modfile.go
+++ b/src/cmd/go/internal/modload/modfile.go
@@ -8,6 +8,7 @@
 	"context"
 	"errors"
 	"fmt"
+	"os"
 	"path/filepath"
 	"strings"
 	"sync"
@@ -15,6 +16,7 @@
 
 	"cmd/go/internal/base"
 	"cmd/go/internal/cfg"
+	"cmd/go/internal/fsys"
 	"cmd/go/internal/lockedfile"
 	"cmd/go/internal/modfetch"
 	"cmd/go/internal/par"
@@ -601,8 +603,16 @@
 				dir = filepath.Join(ModRoot(), dir)
 			}
 			gomod := filepath.Join(dir, "go.mod")
-
-			data, err := lockedfile.Read(gomod)
+			var data []byte
+			var err error
+			if gomodActual, ok := fsys.OverlayPath(gomod); ok {
+				// Don't lock go.mod if it's part of the overlay.
+				// On Plan 9, locking requires chmod, and we don't want to modify any file
+				// in the overlay. See #44700.
+				data, err = os.ReadFile(gomodActual)
+			} else {
+				data, err = lockedfile.Read(gomodActual)
+			}
 			if err != nil {
 				return cached{nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(gomod), err))}
 			}
diff --git a/src/cmd/go/internal/modload/query.go b/src/cmd/go/internal/modload/query.go
index 6f6c6e8..dda9004 100644
--- a/src/cmd/go/internal/modload/query.go
+++ b/src/cmd/go/internal/modload/query.go
@@ -920,8 +920,8 @@
 	return ""
 }
 
-// ModuleHasRootPackage returns whether module m contains a package m.Path.
-func ModuleHasRootPackage(ctx context.Context, m module.Version) (bool, error) {
+// moduleHasRootPackage returns whether module m contains a package m.Path.
+func moduleHasRootPackage(ctx context.Context, m module.Version) (bool, error) {
 	needSum := false
 	root, isLocal, err := fetch(ctx, m, needSum)
 	if err != nil {
diff --git a/src/cmd/go/main.go b/src/cmd/go/main.go
index 02174a5..16361e0 100644
--- a/src/cmd/go/main.go
+++ b/src/cmd/go/main.go
@@ -145,24 +145,6 @@
 		os.Exit(2)
 	}
 
-	if err := buildcfg.Error; err != nil {
-		fmt.Fprintf(os.Stderr, "go: %v\n", buildcfg.Error)
-		os.Exit(2)
-	}
-
-	// Set environment (GOOS, GOARCH, etc) explicitly.
-	// In theory all the commands we invoke should have
-	// the same default computation of these as we do,
-	// but in practice there might be skew
-	// This makes sure we all agree.
-	cfg.OrigEnv = os.Environ()
-	cfg.CmdEnv = envcmd.MkEnv()
-	for _, env := range cfg.CmdEnv {
-		if os.Getenv(env.Name) != env.Value {
-			os.Setenv(env.Name, env.Value)
-		}
-	}
-
 BigCmdLoop:
 	for bigCmd := base.Go; ; {
 		for _, cmd := range bigCmd.Commands {
@@ -188,18 +170,7 @@
 			if !cmd.Runnable() {
 				continue
 			}
-			cmd.Flag.Usage = func() { cmd.Usage() }
-			if cmd.CustomFlags {
-				args = args[1:]
-			} else {
-				base.SetFromGOFLAGS(&cmd.Flag)
-				cmd.Flag.Parse(args[1:])
-				args = cmd.Flag.Args()
-			}
-			ctx := maybeStartTrace(context.Background())
-			ctx, span := trace.StartSpan(ctx, fmt.Sprint("Running ", cmd.Name(), " command"))
-			cmd.Run(ctx, cmd, args)
-			span.Done()
+			invoke(cmd, args)
 			base.Exit()
 			return
 		}
@@ -213,6 +184,39 @@
 	}
 }
 
+func invoke(cmd *base.Command, args []string) {
+	// 'go env' handles checking the build config
+	if cmd != envcmd.CmdEnv {
+		buildcfg.Check()
+	}
+
+	// Set environment (GOOS, GOARCH, etc) explicitly.
+	// In theory all the commands we invoke should have
+	// the same default computation of these as we do,
+	// but in practice there might be skew
+	// This makes sure we all agree.
+	cfg.OrigEnv = os.Environ()
+	cfg.CmdEnv = envcmd.MkEnv()
+	for _, env := range cfg.CmdEnv {
+		if os.Getenv(env.Name) != env.Value {
+			os.Setenv(env.Name, env.Value)
+		}
+	}
+
+	cmd.Flag.Usage = func() { cmd.Usage() }
+	if cmd.CustomFlags {
+		args = args[1:]
+	} else {
+		base.SetFromGOFLAGS(&cmd.Flag)
+		cmd.Flag.Parse(args[1:])
+		args = cmd.Flag.Args()
+	}
+	ctx := maybeStartTrace(context.Background())
+	ctx, span := trace.StartSpan(ctx, fmt.Sprint("Running ", cmd.Name(), " command"))
+	cmd.Run(ctx, cmd, args)
+	span.Done()
+}
+
 func init() {
 	base.Usage = mainUsage
 }
diff --git a/src/cmd/go/testdata/script/build_ignore_leading_bom.txt b/src/cmd/go/testdata/script/build_ignore_leading_bom.txt
new file mode 100644
index 0000000..37141f3
--- /dev/null
+++ b/src/cmd/go/testdata/script/build_ignore_leading_bom.txt
@@ -0,0 +1,27 @@
+# Per https://golang.org/ref/spec#Source_code_representation:
+# a compiler may ignore a UTF-8-encoded byte order mark (U+FEFF)
+# if it is the first Unicode code point in the source text.
+
+go list -f 'Imports: {{.Imports}} EmbedFiles: {{.EmbedFiles}}' .
+stdout '^Imports: \[embed m/hello\] EmbedFiles: \[.*file\]$'
+
+-- go.mod --
+module m
+
+go 1.16
+-- m.go --
+ï»żpackage main
+
+import (
+	_ "embed"
+
+	"m/hello"
+)
+
+//go:embed file
+var s string
+
+-- hello/hello.go --
+package hello
+
+-- file --
diff --git a/src/cmd/go/testdata/script/env_cross_build.txt b/src/cmd/go/testdata/script/env_cross_build.txt
new file mode 100644
index 0000000..3feeba6
--- /dev/null
+++ b/src/cmd/go/testdata/script/env_cross_build.txt
@@ -0,0 +1,29 @@
+# Test that the corect default GOEXPERIMENT is used when cross
+# building with GOENV (#46815).
+
+# Unset variables set by the TestScript harness. Users typically won't
+# explicitly configure these, and #46815 doesn't repro if they are.
+env GOOS=
+env GOARCH=
+env GOEXPERIMENT=
+
+env GOENV=windows-amd64
+go build internal/abi
+
+env GOENV=ios-arm64
+go build internal/abi
+
+env GOENV=linux-mips
+go build internal/abi
+
+-- windows-amd64 --
+GOOS=windows
+GOARCH=amd64
+
+-- ios-arm64 --
+GOOS=ios
+GOARCH=arm64
+
+-- linux-mips --
+GOOS=linux
+GOARCH=mips
diff --git a/src/cmd/go/testdata/script/env_exp.txt b/src/cmd/go/testdata/script/env_exp.txt
new file mode 100644
index 0000000..681512d
--- /dev/null
+++ b/src/cmd/go/testdata/script/env_exp.txt
@@ -0,0 +1,17 @@
+# Test GOEXPERIMENT variable
+
+# go env shows default empty GOEXPERIMENT
+go env
+stdout GOEXPERIMENT=
+
+# go env shows valid experiments
+env GOEXPERIMENT=fieldtrack,staticlockranking
+go env GOEXPERIMENT
+stdout '.*fieldtrack.*staticlockranking.*'
+go env
+stdout 'GOEXPERIMENT=.*fieldtrack.*staticlockranking.*'
+
+# go env rejects unknown experiments
+env GOEXPERIMENT=bad
+! go env GOEXPERIMENT
+stderr 'unknown GOEXPERIMENT bad'
diff --git a/src/cmd/go/testdata/script/env_unset.txt b/src/cmd/go/testdata/script/env_unset.txt
new file mode 100644
index 0000000..4e0f249
--- /dev/null
+++ b/src/cmd/go/testdata/script/env_unset.txt
@@ -0,0 +1,30 @@
+# Test that we can unset variables, even if initially invalid,
+# as long as resulting config is valid.
+
+env GOENV=badenv
+env GOOS=
+env GOARCH=
+env GOEXPERIMENT=
+
+! go env
+stderr '^go(\.exe)?: unknown GOEXPERIMENT badexp$'
+
+go env -u GOEXPERIMENT
+
+! go env
+stderr '^cmd/go: unsupported GOOS/GOARCH pair bados/badarch$'
+
+! go env -u GOOS
+stderr '^go env -u: unsupported GOOS/GOARCH pair \w+/badarch$'
+
+! go env -u GOARCH
+stderr '^go env -u: unsupported GOOS/GOARCH pair bados/\w+$'
+
+go env -u GOOS GOARCH
+
+go env
+
+-- badenv --
+GOOS=bados
+GOARCH=badarch
+GOEXPERIMENT=badexp
diff --git a/src/cmd/go/testdata/script/env_write.txt b/src/cmd/go/testdata/script/env_write.txt
index 4fa39df..b5e9739 100644
--- a/src/cmd/go/testdata/script/env_write.txt
+++ b/src/cmd/go/testdata/script/env_write.txt
@@ -179,3 +179,9 @@
 stderr 'go env -w: GOMODCACHE entry is relative; must be absolute path: "~/test"'
 ! go env -w GOMODCACHE=./test
 stderr 'go env -w: GOMODCACHE entry is relative; must be absolute path: "./test"'
+
+# go env -w checks validity of GOEXPERIMENT
+env GOEXPERIMENT=
+! go env -w GOEXPERIMENT=badexp
+stderr 'unknown GOEXPERIMENT badexp'
+go env -w GOEXPERIMENT=fieldtrack
diff --git a/src/cmd/go/testdata/script/list_cgo_compiled_importmap.txt b/src/cmd/go/testdata/script/list_cgo_compiled_importmap.txt
new file mode 100644
index 0000000..3d68ef3
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_cgo_compiled_importmap.txt
@@ -0,0 +1,38 @@
+# Regression test for https://golang.org/issue/46462.
+#
+# The "runtime/cgo" import found in synthesized .go files (reported in
+# the CompiledGoFiles field) should have a corresponding entry in the
+# ImportMap field when a runtime/cgo variant (such as a test variant)
+# will be used.
+
+[short] skip  # -compiled can be slow (because it compiles things)
+[!cgo] skip
+
+env CGO_ENABLED=1
+env GOFLAGS=-tags=netcgo  # Force net to use cgo even on Windows.
+
+
+# "runtime/cgo [runtime.test]" appears in the the test dependencies of "runtime",
+# because "runtime/cgo" itself depends on "runtime"
+
+go list -deps -test -compiled -f '{{if eq .ImportPath "net [runtime.test]"}}{{printf "%q" .Imports}}{{end}}' runtime
+
+	# Control case: the explicitly-imported package "sync" is a test variant,
+	# because "sync" depends on "runtime".
+stdout '"sync \[runtime\.test\]"'
+! stdout '"sync"'
+
+	# Experiment: the implicitly-imported package "runtime/cgo" is also a test variant,
+	# because "runtime/cgo" also depends on "runtime".
+stdout '"runtime/cgo \[runtime\.test\]"'
+! stdout '"runtime/cgo"'
+
+
+# Because the import of "runtime/cgo" in the cgo-generated file actually refers
+# to "runtime/cgo [runtime.test]", the latter should be listed in the ImportMap.
+# BUG(#46462): Today, it is not.
+
+go list -deps -test -compiled -f '{{if eq .ImportPath "net [runtime.test]"}}{{printf "%q" .ImportMap}}{{end}}' runtime
+
+stdout '"sync":"sync \[runtime\.test\]"'                # control
+stdout '"runtime/cgo":"runtime/cgo \[runtime\.test\]"'  # experiment
diff --git a/src/cmd/go/testdata/script/mod_edit_no_modcache.txt b/src/cmd/go/testdata/script/mod_edit_no_modcache.txt
new file mode 100644
index 0000000..ced15bb
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_edit_no_modcache.txt
@@ -0,0 +1,15 @@
+# 'go mod edit' opportunistically locks the side-lock file in the module cache,
+# for compatibility with older versions of the 'go' command.
+# It does not otherwise depend on the module cache, so it should not
+# fail if the module cache directory cannot be created.
+
+[root] skip
+
+mkdir $WORK/readonly
+chmod 0555 $WORK/readonly
+env GOPATH=$WORK/readonly/nonexist
+
+go mod edit -go=1.17
+
+-- go.mod --
+module example.com/m
diff --git a/src/cmd/go/testdata/script/mod_get_lazy_indirect.txt b/src/cmd/go/testdata/script/mod_get_lazy_indirect.txt
new file mode 100644
index 0000000..1cef9d1
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_get_lazy_indirect.txt
@@ -0,0 +1,44 @@
+# https://golang.org/issue/45979: after 'go get' on a package,
+# that package should be importable without error.
+
+
+# We start out with an unresolved dependency.
+# 'go list' suggests that we run 'go get' on that dependency.
+
+! go list -deps .
+stderr '^m.go:3:8: no required module provides package rsc\.io/quote; to add it:\n\tgo get rsc.io/quote$'
+
+
+# When we run the suggested 'go get' command, the new dependency can be used
+# immediately.
+#
+# 'go get' marks the new dependency as 'indirect', because it doesn't scan
+# enough source code to know whether it is direct, and it is easier and less
+# invasive to remove an incorrect indirect mark (e.g. using 'go get') than to
+# add one that is missing ('go mod tidy' or 'go mod vendor').
+
+go get rsc.io/quote
+grep 'rsc.io/quote v\d+\.\d+\.\d+ // indirect$' go.mod
+! grep 'rsc.io/quote v\d+\.\d+\.\d+$' go.mod
+
+go list -deps .
+! stderr .
+[!short] go build .
+[!short] ! stderr .
+
+
+# 'go get .' (or 'go mod tidy') removes the indirect mark.
+
+go get .
+grep 'rsc.io/quote v\d+\.\d+\.\d+$' go.mod
+! grep 'rsc.io/quote v\d+\.\d+\.\d+ // indirect$' go.mod
+
+
+-- go.mod --
+module example.com/m
+
+go 1.17
+-- m.go --
+package m
+
+import _ "rsc.io/quote"
diff --git a/src/cmd/go/testdata/script/mod_graph_version.txt b/src/cmd/go/testdata/script/mod_graph_version.txt
new file mode 100644
index 0000000..f9a73f4
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_graph_version.txt
@@ -0,0 +1,101 @@
+# For this module, Go 1.17 prunes out a (transitive and otherwise-irrelevant)
+# requirement on a retracted higher version of a dependency.
+# However, when Go 1.16 reads the same requirements from the go.mod file,
+# it does not prune out that requirement, and selects the retracted version.
+#
+# The Go 1.16 module graph looks like:
+#
+# m ---- lazy v0.1.0 ---- requireincompatible v0.1.0 ---- incompatible v2.0.0+incompatible
+# |        |
+# + -------+------------- incompatible v1.0.0
+#
+# The Go 1.17 module graph is the same except that the dependencies of
+# requireincompatible are pruned out (because the module that requires
+# it — lazy v0.1.0 — specifies 'go 1.17', and it is not otherwise relevant to
+# the main module).
+
+cp go.mod go.mod.orig
+
+go mod graph
+cp stdout graph-1.17.txt
+stdout '^example\.com/m example\.com/retract/incompatible@v1\.0\.0$'
+stdout '^example\.net/lazy@v0\.1\.0 example\.com/retract/incompatible@v1\.0\.0$'
+! stdout 'example\.com/retract/incompatible@v2\.0\.0\+incompatible'
+
+go mod graph -go=1.17
+cmp stdout graph-1.17.txt
+
+cmp go.mod go.mod.orig
+
+
+# Setting -go=1.16 should report the graph as viewed by Go 1.16,
+# but should not edit the go.mod file.
+
+go mod graph -go=1.16
+cp stdout graph-1.16.txt
+stdout '^example\.com/m example\.com/retract/incompatible@v1\.0\.0$'
+stdout '^example\.net/lazy@v0\.1\.0 example.com/retract/incompatible@v1\.0\.0$'
+stdout '^example.net/requireincompatible@v0.1.0 example.com/retract/incompatible@v2\.0\.0\+incompatible$'
+
+cmp go.mod go.mod.orig
+
+
+# If we actually update the go.mod file to the requested go version,
+# we should get the same selected versions, but the roots of the graph
+# may be updated.
+#
+# TODO(#45551): The roots should not be updated.
+
+go mod edit -go=1.16
+go mod graph
+! stdout '^example\.com/m example\.com/retract/incompatible@v1\.0\.0$'
+stdout '^example\.net/lazy@v0.1.0 example.com/retract/incompatible@v1\.0\.0$'
+stdout '^example.net/requireincompatible@v0.1.0 example.com/retract/incompatible@v2\.0\.0\+incompatible$'
+	# TODO(#45551): cmp stdout graph-1.16.txt
+
+
+# Unsupported go versions should be rejected, since we don't know
+# what versions they would report.
+! go mod graph -go=1.99999999999
+stderr '^invalid value "1\.99999999999" for flag -go: maximum supported Go version is '$goversion'\nusage: go mod graph \[-go=version\]\nRun ''go help mod graph'' for details.$'
+
+
+-- go.mod --
+// Module m indirectly imports a package from
+// example.com/retract/incompatible. Its selected version of
+// that module is lower under Go 1.17 semantics than under Go 1.16.
+module example.com/m
+
+go 1.17
+
+replace (
+	example.net/lazy v0.1.0 => ./lazy
+	example.net/requireincompatible v0.1.0 => ./requireincompatible
+)
+
+require (
+	example.com/retract/incompatible v1.0.0 // indirect
+	example.net/lazy v0.1.0
+)
+-- lazy/go.mod --
+// Module lazy requires example.com/retract/incompatible v1.0.0.
+//
+// When viewed from the outside it also has a transitive dependency
+// on v2.0.0+incompatible, but in lazy mode that transitive dependency
+// is pruned out.
+module example.net/lazy
+
+go 1.17
+
+exclude example.com/retract/incompatible v2.0.0+incompatible
+
+require (
+	example.com/retract/incompatible v1.0.0
+	example.net/requireincompatible v0.1.0
+)
+-- requireincompatible/go.mod --
+module example.net/requireincompatible
+
+go 1.15
+
+require example.com/retract/incompatible v2.0.0+incompatible
diff --git a/src/cmd/go/testdata/script/mod_install_hint.txt b/src/cmd/go/testdata/script/mod_install_hint.txt
new file mode 100644
index 0000000..ab02840
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_install_hint.txt
@@ -0,0 +1,5 @@
+# Module is replaced but not required. No hint appears as no module is suggested.

+go mod init m

+go mod edit -replace=github.com/notrequired@v0.5.0=github.com/doesnotexist@v0.5.0

+! go install github.com/notrequired

+! stderr 'to add it:'
\ No newline at end of file
diff --git a/src/cmd/go/testdata/script/mod_invalid_version.txt b/src/cmd/go/testdata/script/mod_invalid_version.txt
index 34d9c47..6846a79 100644
--- a/src/cmd/go/testdata/script/mod_invalid_version.txt
+++ b/src/cmd/go/testdata/script/mod_invalid_version.txt
@@ -19,7 +19,7 @@
 go mod edit -require golang.org/x/text@14c0d48ead0c
 cd outside
 ! go list -m golang.org/x/text
-stderr 'go list -m: example.com@v0.0.0 \(replaced by \./\..\): parsing ../go.mod: '$WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "14c0d48ead0c" invalid: must be of the form v1.2.3'
+stderr 'go list -m: example.com@v0.0.0 \(replaced by \./\.\.\): parsing ..[/\\]go.mod: '$WORK'[/\\]gopath[/\\]src[/\\]go.mod:5: require golang.org/x/text: version "14c0d48ead0c" invalid: must be of the form v1.2.3'
 cd ..
 go list -m golang.org/x/text
 stdout 'golang.org/x/text v0.1.1-0.20170915032832-14c0d48ead0c'
@@ -47,10 +47,10 @@
 go mod edit -require golang.org/x/text@v2.1.1-0.20170915032832-14c0d48ead0c
 cd outside
 ! go list -m golang.org/x/text
-stderr 'go list -m: example.com@v0.0.0 \(replaced by \./\.\.\): parsing ../go.mod: '$WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2'
+stderr 'go list -m: example.com@v0.0.0 \(replaced by \./\.\.\): parsing ..[/\\]go.mod: '$WORK'[/\\]gopath[/\\]src[/\\]go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2'
 cd ..
 ! go list -m golang.org/x/text
-stderr $WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2'
+stderr $WORK'[/\\]gopath[/\\]src[/\\]go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2'
 
 # A pseudo-version with fewer than 12 digits of SHA-1 prefix is invalid.
 cp go.mod.orig go.mod
diff --git a/src/cmd/go/testdata/script/mod_list_test_cycle.txt b/src/cmd/go/testdata/script/mod_list_test_cycle.txt
new file mode 100644
index 0000000..755e50b
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_list_test_cycle.txt
@@ -0,0 +1,23 @@
+# https://golang.org/issue/45863: a typo in a test package leading to an
+# import cycle should be diagnosed, instead of causing an infinite loop.
+# The failure mode of this test prior to the fix was a timeout or OOM crash.
+
+go list -e -test -deps ./datastore/sql
+
+-- go.mod --
+module golang.org/issue45863
+
+go 1.17
+-- datastore/datastore_health.go --
+package datastore
+
+import (
+	"golang.org/issue45863/datastore"
+	"golang.org/issue45863/datastore/sql"
+)
+-- datastore/sql/sql.go --
+package sql
+-- datastore/sql/sql_test.go --
+package sql
+
+import _ "golang.org/issue45863/datastore"
diff --git a/src/cmd/go/testdata/script/mod_overlay.txt b/src/cmd/go/testdata/script/mod_overlay.txt
index 92e79c7..86ab04b 100644
--- a/src/cmd/go/testdata/script/mod_overlay.txt
+++ b/src/cmd/go/testdata/script/mod_overlay.txt
@@ -21,7 +21,7 @@
 cd $WORK/gopath/src/get-doesnt-add-dep
 cp $WORK/overlay/get_doesnt_add_dep_go_mod $WORK/want_go_mod
 ! go get -d -overlay overlay.json .
-stderr 'overlaid files can''t be opened for write'
+stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$'
 cmp $WORK/overlay/get_doesnt_add_dep_go_mod $WORK/want_go_mod
 
 # Content of overlaid go.sum is used.
@@ -41,10 +41,10 @@
 # attempting to update the file
 cp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums
 ! go get -d -overlay overlay.json .
-stderr 'overlaid files can''t be opened for write'
+stderr '^go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay$'
 cmp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums
 ! go mod tidy -overlay overlay.json
-stderr 'overlaid files can''t be opened for write'
+stderr '^go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay$'
 cmp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums
 
 # -overlay works with -modfile.
@@ -56,7 +56,7 @@
 stdout 'found.the/module'
 # Even with -modfile, overlaid files can't be opened for write.
 ! go get -modfile=alternate.mod -overlay overlay.json -d rsc.io/quote
-stderr 'overlaid files can''t be opened for write'
+stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$'
 
 # Carving out a module by adding an overlaid go.mod file
 cd $WORK/gopath/src/carve
@@ -78,7 +78,7 @@
 stdout ^carve2/nomod$
 # Editing go.mod file fails because overlay is read only
 ! go get -overlay overlay.json -d rsc.io/quote
-stderr 'overlaid files can''t be opened for write'
+stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$'
 ! grep rsc.io/quote $WORK/overlay/carve2-nomod-go.mod
 # Editing go.mod file succeeds because we use -modfile to redirect to same file
 go get -overlay overlay.json -modfile $WORK/overlay/carve2-nomod-go.mod -d rsc.io/quote
diff --git a/src/cmd/go/testdata/script/mod_sumdb_golang.txt b/src/cmd/go/testdata/script/mod_sumdb_golang.txt
index cc0b0da..becd88b 100644
--- a/src/cmd/go/testdata/script/mod_sumdb_golang.txt
+++ b/src/cmd/go/testdata/script/mod_sumdb_golang.txt
@@ -10,45 +10,73 @@
 stdout '^sum.golang.org$'
 
 # Download direct from github.
+
 [!net] skip
 [!exec:git] skip
 env GOSUMDB=sum.golang.org
 env GOPROXY=direct
+
 go get -d rsc.io/quote@v1.5.2
 cp go.sum saved.sum
 
+
 # Download from proxy.golang.org with go.sum entry already.
 # Use 'go list' instead of 'go get' since the latter may download extra go.mod
 # files not listed in go.sum.
+
 go clean -modcache
 env GOSUMDB=
 env GOPROXY=
-go list -x -deps rsc.io/quote
+
+go list -x -m all  # Download go.mod files.
 ! stderr github
 stderr proxy.golang.org/rsc.io/quote
 ! stderr sum.golang.org/tile
 ! stderr sum.golang.org/lookup/rsc.io/quote
+
+go list -x -deps rsc.io/quote  # Download module source.
+! stderr github
+stderr proxy.golang.org/rsc.io/quote
+! stderr sum.golang.org/tile
+! stderr sum.golang.org/lookup/rsc.io/quote
+
 cmp go.sum saved.sum
 
+
 # Download again.
 # Should use the checksum database to validate new go.sum lines,
 # but not need to fetch any new data from the proxy.
+
 rm go.sum
-go list -mod=mod -x rsc.io/quote
+
+go list -mod=mod -x -m all  # Add checksums for go.mod files.
+stderr sum.golang.org/tile
 ! stderr github
 ! stderr proxy.golang.org/rsc.io/quote
-stderr sum.golang.org/tile
 stderr sum.golang.org/lookup/rsc.io/quote
+
+go list -mod=mod -x rsc.io/quote  # Add checksums for module source.
+! stderr .  # Adds checksums, but for entities already in the module cache.
+
 cmp go.sum saved.sum
 
+
 # test fallback to direct
+
 env TESTGOPROXY404=1
 go clean -modcache
 rm go.sum
-go list -mod=mod -x rsc.io/quote
+
+go list -mod=mod -x -m all  # Download go.mod files
 stderr 'proxy.golang.org.*404 testing'
 stderr github.com/rsc
+
+go list -mod=mod -x rsc.io/quote  # Download module source.
+stderr 'proxy.golang.org.*404 testing'
+stderr github.com/rsc
+
 cmp go.sum saved.sum
 
+
 -- go.mod --
 module m
diff --git a/src/cmd/go/testdata/script/mod_tidy_replace_old.txt b/src/cmd/go/testdata/script/mod_tidy_replace_old.txt
new file mode 100644
index 0000000..cfd3792
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_replace_old.txt
@@ -0,0 +1,34 @@
+# Regression test for https://golang.org/issue/46659.
+#
+# If a 'replace' directive specifies an older-than-selected version of a module,
+# 'go mod tidy' shouldn't try to add that version to the build list to resolve a
+# missing package: it won't be selected, and would cause the module loader to
+# loop indefinitely trying to resolve the package.
+
+cp go.mod go.mod.orig
+
+! go mod tidy
+! stderr panic
+stderr '^golang\.org/issue46659 imports\n\texample\.com/missingpkg/deprecated: package example\.com/missingpkg/deprecated provided by example\.com/missingpkg at latest version v1\.0\.0 but not at required version v1\.0\.1-beta$'
+
+go mod tidy -e
+
+cmp go.mod go.mod.orig
+
+-- go.mod --
+module golang.org/issue46659
+
+go 1.17
+
+replace example.com/missingpkg v1.0.1-alpha => example.com/missingpkg v1.0.0
+
+require example.com/usemissingpre v1.0.0
+
+require example.com/missingpkg v1.0.1-beta // indirect
+-- m.go --
+package m
+
+import (
+	_ "example.com/missingpkg/deprecated"
+	_ "example.com/usemissingpre"
+)
diff --git a/src/cmd/go/testdata/script/mod_vendor_issue46867.txt b/src/cmd/go/testdata/script/mod_vendor_issue46867.txt
new file mode 100644
index 0000000..38ae87b
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_vendor_issue46867.txt
@@ -0,0 +1,31 @@
+# Regression test for golang.org/issue/46867:
+# 'go mod vendor' on Windows attempted to open and copy
+# files from directories outside of the module.
+
+cd subdir
+go mod vendor
+! exists vendor/example.net/NOTICE
+exists vendor/example.net/m/NOTICE
+
+-- subdir/go.mod --
+module golang.org/issue46867
+
+go 1.17
+
+replace example.net/m v0.1.0 => ./m
+
+require example.net/m v0.1.0
+-- subdir/issue.go --
+package issue
+
+import _ "example.net/m/n"
+-- subdir/m/go.mod --
+module example.net/m
+
+go 1.17
+-- subdir/m/n/n.go --
+package n
+-- subdir/m/NOTICE --
+This notice is in module m and SHOULD be vendored.
+-- subdir/NOTICE --
+This notice is outside of module m and SHOULD NOT be vendored.
diff --git a/src/cmd/gofmt/doc.go b/src/cmd/gofmt/doc.go
index 68476e7..e340665 100644
--- a/src/cmd/gofmt/doc.go
+++ b/src/cmd/gofmt/doc.go
@@ -26,9 +26,6 @@
 		Do not print reformatted sources to standard output.
 		If a file's formatting is different from gofmt's, print its name
 		to standard output.
-	-G
-		Allow generic code, using type parameters.
-		See golang.org/issues/43651 for more information.
 	-r rule
 		Apply the rewrite rule to the source before reformatting.
 	-s
diff --git a/src/cmd/internal/moddeps/moddeps_test.go b/src/cmd/internal/moddeps/moddeps_test.go
index 268843d..06cf08f 100644
--- a/src/cmd/internal/moddeps/moddeps_test.go
+++ b/src/cmd/internal/moddeps/moddeps_test.go
@@ -5,6 +5,7 @@
 package moddeps_test
 
 import (
+	"bytes"
 	"encoding/json"
 	"fmt"
 	"internal/testenv"
@@ -68,7 +69,7 @@
 
 			// There is no vendor directory, so the module must have no dependencies.
 			// Check that the list of active modules contains only the main module.
-			cmd := exec.Command(goBin, "list", "-mod=mod", "-m", "all")
+			cmd := exec.Command(goBin, "list", "-mod=readonly", "-m", "all")
 			cmd.Env = append(os.Environ(), "GO111MODULE=on")
 			cmd.Dir = m.Dir
 			cmd.Stderr = new(strings.Builder)
@@ -124,10 +125,38 @@
 		t.Skip("skipping because a diff command with support for --recursive and --unified flags is unavailable")
 	}
 
+	// We're going to check the standard modules for tidiness, so we need a usable
+	// GOMODCACHE. If the default directory doesn't exist, use a temporary
+	// directory instead. (That can occur, for example, when running under
+	// run.bash with GO_TEST_SHORT=0: run.bash sets GOPATH=/nonexist-gopath, and
+	// GO_TEST_SHORT=0 causes it to run this portion of the test.)
+	var modcacheEnv []string
+	{
+		out, err := exec.Command(goBin, "env", "GOMODCACHE").Output()
+		if err != nil {
+			t.Fatalf("%s env GOMODCACHE: %v", goBin, err)
+		}
+		modcacheOk := false
+		if gomodcache := string(bytes.TrimSpace(out)); gomodcache != "" {
+			if _, err := os.Stat(gomodcache); err == nil {
+				modcacheOk = true
+			}
+		}
+		if !modcacheOk {
+			modcacheEnv = []string{
+				"GOMODCACHE=" + t.TempDir(),
+				"GOFLAGS=" + os.Getenv("GOFLAGS") + " -modcacherw", // Allow t.TempDir() to clean up subdirectories.
+			}
+		}
+	}
+
 	// Build the bundle binary at the golang.org/x/tools
 	// module version specified in GOROOT/src/cmd/go.mod.
 	bundleDir := t.TempDir()
-	r := runner{Dir: filepath.Join(runtime.GOROOT(), "src/cmd")}
+	r := runner{
+		Dir: filepath.Join(runtime.GOROOT(), "src/cmd"),
+		Env: append(os.Environ(), modcacheEnv...),
+	}
 	r.run(t, goBin, "build", "-mod=readonly", "-o", bundleDir, "golang.org/x/tools/cmd/bundle")
 
 	var gorootCopyDir string
@@ -161,7 +190,7 @@
 			}
 			r := runner{
 				Dir: filepath.Join(gorootCopyDir, rel),
-				Env: append(os.Environ(),
+				Env: append(append(os.Environ(), modcacheEnv...),
 					// Set GOROOT.
 					"GOROOT="+gorootCopyDir,
 					// Explicitly override PWD and clear GOROOT_FINAL so that GOROOT=gorootCopyDir is definitely used.
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go
index b8c3cd9..d99afa3 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -4333,8 +4333,10 @@
 		if p.To.Reg == REG_RSP && isADDSop(p.As) {
 			c.ctxt.Diag("illegal destination register: %v\n", p)
 		}
+		lsl0 := LSL0_64
 		if isADDWop(p.As) || isANDWop(p.As) {
 			o1 = c.omovconst(AMOVW, p, &p.From, REGTMP)
+			lsl0 = LSL0_32
 		} else {
 			o1 = c.omovconst(AMOVD, p, &p.From, REGTMP)
 		}
@@ -4350,7 +4352,7 @@
 		if p.To.Reg == REGSP || r == REGSP {
 			o2 = c.opxrrr(p, p.As, false)
 			o2 |= REGTMP & 31 << 16
-			o2 |= LSL0_64
+			o2 |= uint32(lsl0)
 		} else {
 			o2 = c.oprrr(p, p.As)
 			o2 |= REGTMP & 31 << 16 /* shift is 0 */
diff --git a/src/cmd/internal/sys/supported.go b/src/cmd/internal/sys/supported.go
index fa477b8..0d2bad9 100644
--- a/src/cmd/internal/sys/supported.go
+++ b/src/cmd/internal/sys/supported.go
@@ -74,7 +74,7 @@
 			"android/amd64", "android/arm", "android/arm64", "android/386",
 			"freebsd/amd64",
 			"darwin/amd64", "darwin/arm64",
-			"windows/amd64", "windows/386":
+			"windows/amd64", "windows/386", "windows/arm64":
 			return true
 		}
 		return false
diff --git a/src/cmd/link/internal/ld/decodesym.go b/src/cmd/link/internal/ld/decodesym.go
index c41d977..629bdcf 100644
--- a/src/cmd/link/internal/ld/decodesym.go
+++ b/src/cmd/link/internal/ld/decodesym.go
@@ -16,12 +16,12 @@
 
 // Decoding the type.* symbols.	 This has to be in sync with
 // ../../runtime/type.go, or more specifically, with what
-// cmd/compile/internal/gc/reflect.go stuffs in these.
+// cmd/compile/internal/reflectdata/reflect.go stuffs in these.
 
 // tflag is documented in reflect/type.go.
 //
 // tflag values must be kept in sync with copies in:
-//	cmd/compile/internal/gc/reflect.go
+//	cmd/compile/internal/reflectdata/reflect.go
 //	cmd/link/internal/ld/decodesym.go
 //	reflect/type.go
 //	runtime/type.go
diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go
index 8baf6af..e8b025b 100644
--- a/src/cmd/link/internal/ld/elf.go
+++ b/src/cmd/link/internal/ld/elf.go
@@ -950,6 +950,11 @@
 	}
 
 	s = ldr.CreateSymForUpdate(".dynamic", 0)
+	if ctxt.BuildMode == BuildModePIE {
+		// https://github.com/bminor/glibc/blob/895ef79e04a953cac1493863bcae29ad85657ee1/elf/elf.h#L986
+		const DTFLAGS_1_PIE = 0x08000000
+		Elfwritedynent(ctxt.Arch, s, elf.DT_FLAGS_1, uint64(DTFLAGS_1_PIE))
+	}
 	elfverneed = nfile
 	if elfverneed != 0 {
 		elfWriteDynEntSym(ctxt, s, elf.DT_VERNEED, gnuVersionR.Sym())
diff --git a/src/cmd/link/internal/ld/ld_test.go b/src/cmd/link/internal/ld/ld_test.go
index ca76463..3702a4d 100644
--- a/src/cmd/link/internal/ld/ld_test.go
+++ b/src/cmd/link/internal/ld/ld_test.go
@@ -174,6 +174,8 @@
 		t.Skip("skipping windows amd64/386 only test")
 	}
 
+	testenv.MustHaveCGO(t)
+
 	t.Run("aslr", func(t *testing.T) {
 		testWindowsBuildmodeCSharedASLR(t, true)
 	})
diff --git a/src/cmd/pprof/pprof.go b/src/cmd/pprof/pprof.go
index 1d10a7b..e72c765 100644
--- a/src/cmd/pprof/pprof.go
+++ b/src/cmd/pprof/pprof.go
@@ -233,8 +233,8 @@
 }
 
 func (f *file) ObjAddr(addr uint64) (uint64, error) {
-	// No support for shared libraries.
-	return 0, nil
+	// No support for shared libraries, so translation is a no-op.
+	return addr, nil
 }
 
 func (f *file) BuildID() string {
diff --git a/src/cmd/pprof/pprof_test.go b/src/cmd/pprof/pprof_test.go
new file mode 100644
index 0000000..11e251b
--- /dev/null
+++ b/src/cmd/pprof/pprof_test.go
@@ -0,0 +1,127 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"internal/testenv"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+var tmp, pprofExe string // populated by buildPprof
+
+func TestMain(m *testing.M) {
+	if !testenv.HasGoBuild() {
+		return
+	}
+
+	var exitcode int
+	if err := buildPprof(); err == nil {
+		exitcode = m.Run()
+	} else {
+		fmt.Println(err)
+		exitcode = 1
+	}
+	os.RemoveAll(tmp)
+	os.Exit(exitcode)
+}
+
+func buildPprof() error {
+	var err error
+	tmp, err = os.MkdirTemp("", "TestPprof")
+	if err != nil {
+		return fmt.Errorf("TempDir failed: %v", err)
+	}
+
+	pprofExe = filepath.Join(tmp, "testpprof.exe")
+	gotool, err := testenv.GoTool()
+	if err != nil {
+		return err
+	}
+	out, err := exec.Command(gotool, "build", "-o", pprofExe, "cmd/pprof").CombinedOutput()
+	if err != nil {
+		os.RemoveAll(tmp)
+		return fmt.Errorf("go build -o %v cmd/pprof: %v\n%s", pprofExe, err, string(out))
+	}
+
+	return nil
+}
+
+// See also runtime/pprof.cpuProfilingBroken.
+func mustHaveCPUProfiling(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("skipping on %s, unimplemented", runtime.GOOS)
+	case "aix":
+		t.Skipf("skipping on %s, issue 45170", runtime.GOOS)
+	case "ios", "dragonfly", "netbsd", "illumos", "solaris":
+		t.Skipf("skipping on %s, issue 13841", runtime.GOOS)
+	case "openbsd":
+		if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
+			t.Skipf("skipping on %s/%s, issue 13841", runtime.GOOS, runtime.GOARCH)
+		}
+	}
+}
+
+func mustHaveDisasm(t *testing.T) {
+	switch runtime.GOARCH {
+	case "mips", "mipsle", "mips64", "mips64le":
+		t.Skipf("skipping on %s, issue 12559", runtime.GOARCH)
+	case "riscv64":
+		t.Skipf("skipping on %s, issue 36738", runtime.GOARCH)
+	case "s390x":
+		t.Skipf("skipping on %s, issue 15255", runtime.GOARCH)
+	}
+
+	// Skip PIE platforms, pprof can't disassemble PIE.
+	if runtime.GOOS == "windows" {
+		t.Skipf("skipping on %s, issue 46639", runtime.GOOS)
+	}
+	if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
+		t.Skipf("skipping on %s/%s, issue 46639", runtime.GOOS, runtime.GOARCH)
+	}
+}
+
+// TestDisasm verifies that cmd/pprof can successfully disassemble functions.
+//
+// This is a regression test for issue 46636.
+func TestDisasm(t *testing.T) {
+	mustHaveCPUProfiling(t)
+	mustHaveDisasm(t)
+	testenv.MustHaveGoBuild(t)
+
+	tmpdir := t.TempDir()
+	cpuExe := filepath.Join(tmpdir, "cpu.exe")
+	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", cpuExe, "cpu.go")
+	cmd.Dir = "testdata/"
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("build failed: %v\n%s", err, out)
+	}
+
+	profile := filepath.Join(tmpdir, "cpu.pprof")
+	cmd = exec.Command(cpuExe, "-output", profile)
+	out, err = cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("cpu failed: %v\n%s", err, out)
+	}
+
+	cmd = exec.Command(pprofExe, "-disasm", "main.main", cpuExe, profile)
+	out, err = cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("pprof failed: %v\n%s", err, out)
+	}
+
+	sout := string(out)
+	want := "ROUTINE ======================== main.main"
+	if !strings.Contains(sout, want) {
+		t.Errorf("pprof disasm got %s want contains %q", sout, want)
+	}
+}
diff --git a/src/cmd/pprof/testdata/cpu.go b/src/cmd/pprof/testdata/cpu.go
new file mode 100644
index 0000000..5b68287
--- /dev/null
+++ b/src/cmd/pprof/testdata/cpu.go
@@ -0,0 +1,41 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"flag"
+	"fmt"
+	"os"
+	"runtime/pprof"
+	"time"
+)
+
+var output = flag.String("output", "", "pprof profile output file")
+
+func main() {
+	flag.Parse()
+	if *output == "" {
+		fmt.Fprintf(os.Stderr, "usage: %s -output file.pprof\n", os.Args[0])
+		os.Exit(2)
+	}
+
+	f, err := os.Create(*output)
+	if err != nil {
+		fmt.Fprintln(os.Stderr, err)
+		os.Exit(2)
+	}
+	defer f.Close()
+
+	if err := pprof.StartCPUProfile(f); err != nil {
+		fmt.Fprintln(os.Stderr, err)
+		os.Exit(2)
+	}
+	defer pprof.StopCPUProfile()
+
+	// Spin for long enough to collect some samples.
+	start := time.Now()
+	for time.Since(start) < time.Second {
+	}
+}
diff --git a/src/crypto/tls/key_agreement.go b/src/crypto/tls/key_agreement.go
index 8cfbd73..c28a64f 100644
--- a/src/crypto/tls/key_agreement.go
+++ b/src/crypto/tls/key_agreement.go
@@ -86,7 +86,11 @@
 		return nil, nil, err
 	}
 
-	encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret)
+	rsaKey, ok := cert.PublicKey.(*rsa.PublicKey)
+	if !ok {
+		return nil, nil, errors.New("tls: server certificate contains incorrect key type for selected ciphersuite")
+	}
+	encrypted, err := rsa.EncryptPKCS1v15(config.rand(), rsaKey, preMasterSecret)
 	if err != nil {
 		return nil, nil, err
 	}
diff --git a/src/crypto/x509/parser.go b/src/crypto/x509/parser.go
index 3d51ddd..f085162 100644
--- a/src/crypto/x509/parser.go
+++ b/src/crypto/x509/parser.go
@@ -734,10 +734,12 @@
 				if !val.ReadASN1(&akid, cryptobyte_asn1.SEQUENCE) {
 					return errors.New("x509: invalid authority key identifier")
 				}
-				if !akid.ReadASN1(&akid, cryptobyte_asn1.Tag(0).ContextSpecific()) {
-					return errors.New("x509: invalid authority key identifier")
+				if akid.PeekASN1Tag(cryptobyte_asn1.Tag(0).ContextSpecific()) {
+					if !akid.ReadASN1(&akid, cryptobyte_asn1.Tag(0).ContextSpecific()) {
+						return errors.New("x509: invalid authority key identifier")
+					}
+					out.AuthorityKeyId = akid
 				}
-				out.AuthorityKeyId = akid
 			case 37:
 				out.ExtKeyUsage, out.UnknownExtKeyUsage, err = parseExtKeyUsageExtension(e.Value)
 				if err != nil {
diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go
index 802bce0..a4053ab 100644
--- a/src/crypto/x509/x509_test.go
+++ b/src/crypto/x509/x509_test.go
@@ -3174,3 +3174,45 @@
 		}
 	}
 }
+
+const optionalAuthKeyIDPEM = `-----BEGIN CERTIFICATE-----
+MIIFEjCCBHugAwIBAgICAQwwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1Zh
+bGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu
+Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24g
+QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAe
+BgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTA0MDYyOTE3MzkxNloX
+DTI0MDYyOTE3MzkxNlowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVs
+ZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAy
+IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0A
+MIIBCAKCAQEAtzLI/ulxpgSFrQwRZN/OTe/IAxiHP6Gr+zymn/DDodrU2G4rU5D7
+JKQ+hPCe6F/s5SdE9SimP3ve4CrwyK9TL57KBQGTHo9mHDmnTfpatnMEJWbrd3/n
+WcZKmSUUVOsmx/N/GdUwcI+vsEYq/63rKe3Xn6oEh6PU+YmlNF/bQ5GCNtlmPLG4
+uYL9nDo+EMg77wZlZnqbGRg9/3FRPDAuX749d3OyXQZswyNWmiuFJpIcpwKz5D8N
+rwh5grg2Peqc0zWzvGnK9cyd6P1kjReAM25eSl2ZyR6HtJ0awNVuEzUjXt+bXz3v
+1vd2wuo+u3gNHEJnawTY+Nbab4vyRKABqwIBA6OCAfMwggHvMB0GA1UdDgQWBBS/
+X7fRzt0fhvRbVazc1xDCDqmI5zCB0gYDVR0jBIHKMIHHoYHBpIG+MIG7MSQwIgYD
+VQQHExtWYWxpQ2VydCBWYWxpZGF0aW9uIE5ldHdvcmsxFzAVBgNVBAoTDlZhbGlD
+ZXJ0LCBJbmMuMTUwMwYDVQQLEyxWYWxpQ2VydCBDbGFzcyAyIFBvbGljeSBWYWxp
+ZGF0aW9uIEF1dGhvcml0eTEhMB8GA1UEAxMYaHR0cDovL3d3dy52YWxpY2VydC5j
+b20vMSAwHgYJKoZIhvcNAQkBFhFpbmZvQHZhbGljZXJ0LmNvbYIBATAPBgNVHRMB
+Af8EBTADAQH/MDkGCCsGAQUFBwEBBC0wKzApBggrBgEFBQcwAYYdaHR0cDovL29j
+c3Auc3RhcmZpZWxkdGVjaC5jb20wSgYDVR0fBEMwQTA/oD2gO4Y5aHR0cDovL2Nl
+cnRpZmljYXRlcy5zdGFyZmllbGR0ZWNoLmNvbS9yZXBvc2l0b3J5L3Jvb3QuY3Js
+MFEGA1UdIARKMEgwRgYEVR0gADA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY2VydGlm
+aWNhdGVzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkwDgYDVR0PAQH/BAQD
+AgEGMA0GCSqGSIb3DQEBBQUAA4GBAKVi8afCXSWlcD284ipxs33kDTcdVWptobCr
+mADkhWBKIMuh8D1195TaQ39oXCUIuNJ9MxB73HZn8bjhU3zhxoNbKXuNSm8uf0So
+GkVrMgfHeMpkksK0hAzc3S1fTbvdiuo43NlmouxBulVtWmQ9twPMHOKRUJ7jCUSV
+FxdzPcwl
+-----END CERTIFICATE-----`
+
+func TestAuthKeyIdOptional(t *testing.T) {
+	b, _ := pem.Decode([]byte(optionalAuthKeyIDPEM))
+	if b == nil {
+		t.Fatalf("couldn't decode test certificate")
+	}
+	_, err := ParseCertificate(b.Bytes)
+	if err != nil {
+		t.Fatalf("ParseCertificate to failed to parse certificate with optional authority key identifier fields: %s", err)
+	}
+}
diff --git a/src/database/sql/sql_test.go b/src/database/sql/sql_test.go
index 80f63e8..f771dee 100644
--- a/src/database/sql/sql_test.go
+++ b/src/database/sql/sql_test.go
@@ -2838,7 +2838,7 @@
 	db := newTestDB(t, "people")
 	defer closeDB(t, db)
 
-	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond)
+	ctx, cancel := context.WithCancel(context.Background())
 	defer cancel()
 	tx, err := db.BeginTx(ctx, nil)
 	if err != nil {
@@ -2849,6 +2849,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
+	cancel()
 	// Run number of stmt queries to reproduce deadlock from context cancel
 	for i := 0; i < 1e3; i++ {
 		// Encounter any close related errors (e.g. ErrTxDone, stmt is closed)
diff --git a/src/debug/elf/file.go b/src/debug/elf/file.go
index cd5bf8f..b25d820 100644
--- a/src/debug/elf/file.go
+++ b/src/debug/elf/file.go
@@ -1164,6 +1164,13 @@
 			b = dbuf
 		}
 
+		if f.Type == ET_EXEC {
+			// Do not apply relocations to DWARF sections for ET_EXEC binaries.
+			// Relocations should already be applied, and .rela sections may
+			// contain incorrect data.
+			return b, nil
+		}
+
 		for _, r := range f.Sections {
 			if r.Type != SHT_RELA && r.Type != SHT_REL {
 				continue
diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go
index 4b15231..df55bab 100644
--- a/src/go/build/deps_test.go
+++ b/src/go/build/deps_test.go
@@ -440,7 +440,8 @@
 	# HTTP, King of Dependencies.
 
 	FMT
-	< golang.org/x/net/http2/hpack, net/http/internal, net/http/internal/ascii;
+	< golang.org/x/net/http2/hpack
+	< net/http/internal, net/http/internal/ascii, net/http/internal/testcert;
 
 	FMT, NET, container/list, encoding/binary, log
 	< golang.org/x/text/transform
@@ -459,6 +460,7 @@
 	golang.org/x/net/http2/hpack,
 	net/http/internal,
 	net/http/internal/ascii,
+	net/http/internal/testcert,
 	net/http/httptrace,
 	mime/multipart,
 	log
diff --git a/src/go/build/doc.go b/src/go/build/doc.go
index 2c6f0a8..778b4f4 100644
--- a/src/go/build/doc.go
+++ b/src/go/build/doc.go
@@ -59,7 +59,7 @@
 //
 // A build constraint, also known as a build tag, is a line comment that begins
 //
-// 	// +build
+// 	//go:build
 //
 // that lists the conditions under which a file should be included in the
 // package. Build constraints may also be part of a file's name
diff --git a/src/go/build/read.go b/src/go/build/read.go
index aa7c6ee..b98c793 100644
--- a/src/go/build/read.go
+++ b/src/go/build/read.go
@@ -6,6 +6,7 @@
 
 import (
 	"bufio"
+	"bytes"
 	"errors"
 	"fmt"
 	"go/ast"
@@ -28,9 +29,19 @@
 	pos  token.Position
 }
 
+var bom = []byte{0xef, 0xbb, 0xbf}
+
 func newImportReader(name string, r io.Reader) *importReader {
+	b := bufio.NewReader(r)
+	// Remove leading UTF-8 BOM.
+	// Per https://golang.org/ref/spec#Source_code_representation:
+	// a compiler may ignore a UTF-8-encoded byte order mark (U+FEFF)
+	// if it is the first Unicode code point in the source text.
+	if leadingBytes, err := b.Peek(3); err == nil && bytes.Equal(leadingBytes, bom) {
+		b.Discard(3)
+	}
 	return &importReader{
-		b: bufio.NewReader(r),
+		b: b,
 		pos: token.Position{
 			Filename: name,
 			Line:     1,
diff --git a/src/go/build/read_test.go b/src/go/build/read_test.go
index 32e6bae..1e5e1c2 100644
--- a/src/go/build/read_test.go
+++ b/src/go/build/read_test.go
@@ -66,6 +66,10 @@
 		`,
 		"",
 	},
+	{
+		"\ufeffđ”»" + `package p; import "x";ℙvar x = 1`,
+		"",
+	},
 }
 
 var readCommentsTests = []readTest{
@@ -82,6 +86,10 @@
 		"",
 	},
 	{
+		"\ufeffđ”»" + `ℙpackage p; import . "x"`,
+		"",
+	},
+	{
 		`// foo
 
 		/* bar */
@@ -94,6 +102,19 @@
 		ℙHello, world`,
 		"",
 	},
+	{
+		"\ufeffđ”»" + `// foo
+
+		/* bar */
+
+		/* quux */ // baz
+
+		/*/ zot */
+
+		// asdf
+		ℙHello, world`,
+		"",
+	},
 }
 
 func testRead(t *testing.T, tests []readTest, read func(io.Reader) ([]byte, error)) {
@@ -107,6 +128,11 @@
 			in = tt.in[:j] + tt.in[j+len("ℙ"):]
 			testOut = tt.in[:j]
 		}
+		d := strings.Index(tt.in, "đ”»")
+		if d >= 0 {
+			in = in[:d] + in[d+len("đ”»"):]
+			testOut = testOut[d+len("đ”»"):]
+		}
 		r := strings.NewReader(in)
 		buf, err := read(r)
 		if err != nil {
@@ -265,6 +291,12 @@
 		 test:3:16:z`,
 	},
 	{
+		"\ufeffpackage p\nimport \"embed\"\n//go:embed x y z\nvar files embed.FS",
+		`test:3:12:x
+		 test:3:14:y
+		 test:3:16:z`,
+	},
+	{
 		"package p\nimport \"embed\"\nvar s = \"/*\"\n//go:embed x\nvar files embed.FS",
 		`test:4:12:x`,
 	},
@@ -292,6 +324,10 @@
 		"package p\n//go:embed x y z\nvar files embed.FS", // no import, no scan
 		"",
 	},
+	{
+		"\ufeffpackage p\n//go:embed x y z\nvar files embed.FS", // no import, no scan
+		"",
+	},
 }
 
 func TestReadEmbed(t *testing.T) {
diff --git a/src/go/parser/parser.go b/src/go/parser/parser.go
index 3965641..f10c865 100644
--- a/src/go/parser/parser.go
+++ b/src/go/parser/parser.go
@@ -1302,7 +1302,12 @@
 		p.errorExpected(p.pos, "operand")
 		rbrack := p.pos
 		p.next()
-		return &ast.BadExpr{From: x.Pos(), To: rbrack}
+		return &ast.IndexExpr{
+			X:      x,
+			Lbrack: lbrack,
+			Index:  &ast.BadExpr{From: rbrack, To: rbrack},
+			Rbrack: rbrack,
+		}
 	}
 	p.exprLev++
 
diff --git a/src/go/scanner/scanner.go b/src/go/scanner/scanner.go
index 29cbf39..f08e28c 100644
--- a/src/go/scanner/scanner.go
+++ b/src/go/scanner/scanner.go
@@ -373,7 +373,7 @@
 			continue
 		}
 		s.rdOffset += rdOffset
-		if b < utf8.RuneSelf {
+		if 0 < b && b < utf8.RuneSelf {
 			// Optimization: we've encountered an ASCII character that's not a letter
 			// or number. Avoid the call into s.next() and corresponding set up.
 			//
diff --git a/src/go/scanner/scanner_test.go b/src/go/scanner/scanner_test.go
index ac8d257..db123c3 100644
--- a/src/go/scanner/scanner_test.go
+++ b/src/go/scanner/scanner_test.go
@@ -812,6 +812,8 @@
 	{"//\ufeff", token.COMMENT, 2, "//\ufeff", "illegal byte order mark"},                                // only first BOM is ignored
 	{"'\ufeff" + `'`, token.CHAR, 1, "'\ufeff" + `'`, "illegal byte order mark"},                         // only first BOM is ignored
 	{`"` + "abc\ufeffdef" + `"`, token.STRING, 4, `"` + "abc\ufeffdef" + `"`, "illegal byte order mark"}, // only first BOM is ignored
+	{"abc\x00def", token.IDENT, 3, "abc", "illegal character NUL"},
+	{"abc\x00", token.IDENT, 3, "abc", "illegal character NUL"},
 }
 
 func TestScanErrors(t *testing.T) {
diff --git a/src/go/types/check_test.go b/src/go/types/check_test.go
index 6c3b630..c85a8e4 100644
--- a/src/go/types/check_test.go
+++ b/src/go/types/check_test.go
@@ -202,17 +202,20 @@
 	return ""
 }
 
-func checkFiles(t *testing.T, sizes Sizes, goVersion string, filenames []string, srcs [][]byte, manual bool) {
+func checkFiles(t *testing.T, sizes Sizes, goVersion string, filenames []string, srcs [][]byte, manual bool, imp Importer) {
 	if len(filenames) == 0 {
 		t.Fatal("no source files")
 	}
 
+	if strings.HasSuffix(filenames[0], ".go2") && !typeparams.Enabled {
+		t.Skip("type params are not enabled")
+	}
+	if strings.HasSuffix(filenames[0], ".go1") && typeparams.Enabled {
+		t.Skip("type params are enabled")
+	}
+
 	mode := parser.AllErrors
-	if strings.HasSuffix(filenames[0], ".go2") {
-		if !typeparams.Enabled {
-			t.Skip("type params are not enabled")
-		}
-	} else {
+	if !strings.HasSuffix(filenames[0], ".go2") {
 		mode |= typeparams.DisallowParsing
 	}
 
@@ -249,7 +252,10 @@
 		}
 	}
 
-	conf.Importer = importer.Default()
+	conf.Importer = imp
+	if imp == nil {
+		conf.Importer = importer.Default()
+	}
 	conf.Error = func(err error) {
 		if *haltOnError {
 			defer panic(err)
@@ -319,7 +325,7 @@
 func TestLongConstants(t *testing.T) {
 	format := "package longconst\n\nconst _ = %s\nconst _ = %s // ERROR excessively long constant"
 	src := fmt.Sprintf(format, strings.Repeat("1", 9999), strings.Repeat("1", 10001))
-	checkFiles(t, nil, "", []string{"longconst.go"}, [][]byte{[]byte(src)}, false)
+	checkFiles(t, nil, "", []string{"longconst.go"}, [][]byte{[]byte(src)}, false, nil)
 }
 
 // TestIndexRepresentability tests that constant index operands must
@@ -327,7 +333,7 @@
 // represent larger values.
 func TestIndexRepresentability(t *testing.T) {
 	const src = "package index\n\nvar s []byte\nvar _ = s[int64 /* ERROR \"int64\\(1\\) << 40 \\(.*\\) overflows int\" */ (1) << 40]"
-	checkFiles(t, &StdSizes{4, 4}, "", []string{"index.go"}, [][]byte{[]byte(src)}, false)
+	checkFiles(t, &StdSizes{4, 4}, "", []string{"index.go"}, [][]byte{[]byte(src)}, false, nil)
 }
 
 func TestIssue46453(t *testing.T) {
@@ -335,7 +341,7 @@
 		t.Skip("type params are enabled")
 	}
 	const src = "package p\ntype _ comparable // ERROR \"undeclared name: comparable\""
-	checkFiles(t, nil, "", []string{"issue46453.go"}, [][]byte{[]byte(src)}, false)
+	checkFiles(t, nil, "", []string{"issue46453.go"}, [][]byte{[]byte(src)}, false, nil)
 }
 
 func TestCheck(t *testing.T)     { DefPredeclaredTestFuncs(); testDir(t, "check") }
@@ -385,5 +391,5 @@
 		}
 		srcs[i] = src
 	}
-	checkFiles(t, nil, goVersion, filenames, srcs, manual)
+	checkFiles(t, nil, goVersion, filenames, srcs, manual, nil)
 }
diff --git a/src/go/types/errors.go b/src/go/types/errors.go
index 19e9ae8..2263106 100644
--- a/src/go/types/errors.go
+++ b/src/go/types/errors.go
@@ -31,7 +31,7 @@
 		if check.pkgPathMap == nil {
 			check.pkgPathMap = make(map[string]map[string]bool)
 			check.seenPkgMap = make(map[*Package]bool)
-			check.markImports(pkg)
+			check.markImports(check.pkg)
 		}
 		// If the same package name was used by multiple packages, display the full path.
 		if len(check.pkgPathMap[pkg.name]) > 1 {
diff --git a/src/go/types/issues_test.go b/src/go/types/issues_test.go
index 4492691..519e199 100644
--- a/src/go/types/issues_test.go
+++ b/src/go/types/issues_test.go
@@ -577,42 +577,64 @@
 }
 
 func TestIssue43124(t *testing.T) {
-	// TODO(rFindley) enhance the testdata tests to be able to express this type
-	//                of setup.
+	// TODO(rFindley) move this to testdata by enhancing support for importing.
 
 	// All involved packages have the same name (template). Error messages should
 	// disambiguate between text/template and html/template by printing the full
 	// path.
 	const (
 		asrc = `package a; import "text/template"; func F(template.Template) {}; func G(int) {}`
-		bsrc = `package b; import ("a"; "html/template"); func _() { a.F(template.Template{}) }`
-		csrc = `package c; import ("a"; "html/template"); func _() { a.G(template.Template{}) }`
+		bsrc = `
+package b
+
+import (
+	"a"
+	"html/template"
+)
+
+func _() {
+	// Packages should be fully qualified when there is ambiguity within the
+	// error string itself.
+	a.F(template /* ERROR cannot use.*html/template.* as .*text/template */ .Template{})
+}
+`
+		csrc = `
+package c
+
+import (
+	"a"
+	"fmt"
+	"html/template"
+)
+
+// Issue #46905: make sure template is not the first package qualified.
+var _ fmt.Stringer = 1 // ERROR cannot use 1.*as fmt\.Stringer
+
+// Packages should be fully qualified when there is ambiguity in reachable
+// packages. In this case both a (and for that matter html/template) import
+// text/template.
+func _() { a.G(template /* ERROR cannot use .*html/template.*Template */ .Template{}) }
+`
+
+		tsrc = `
+package template
+
+import "text/template"
+
+type T int
+
+// Verify that the current package name also causes disambiguation.
+var _ T = template /* ERROR cannot use.*text/template.* as T value */.Template{}
+`
 	)
 
 	a, err := pkgFor("a", asrc, nil)
 	if err != nil {
 		t.Fatalf("package a failed to typecheck: %v", err)
 	}
-	conf := Config{Importer: importHelper{pkg: a, fallback: importer.Default()}}
+	imp := importHelper{pkg: a, fallback: importer.Default()}
 
-	// Packages should be fully qualified when there is ambiguity within the
-	// error string itself.
-	bast := mustParse(t, bsrc)
-	_, err = conf.Check(bast.Name.Name, fset, []*ast.File{bast}, nil)
-	if err == nil {
-		t.Fatal("package b had no errors")
-	}
-	if !strings.Contains(err.Error(), "text/template") || !strings.Contains(err.Error(), "html/template") {
-		t.Errorf("type checking error for b does not disambiguate package template: %q", err)
-	}
-
-	// ...and also when there is any ambiguity in reachable packages.
-	cast := mustParse(t, csrc)
-	_, err = conf.Check(cast.Name.Name, fset, []*ast.File{cast}, nil)
-	if err == nil {
-		t.Fatal("package c had no errors")
-	}
-	if !strings.Contains(err.Error(), "html/template") {
-		t.Errorf("type checking error for c does not disambiguate package template: %q", err)
-	}
+	checkFiles(t, nil, "", []string{"b.go"}, [][]byte{[]byte(bsrc)}, false, imp)
+	checkFiles(t, nil, "", []string{"c.go"}, [][]byte{[]byte(csrc)}, false, imp)
+	checkFiles(t, nil, "", []string{"t.go"}, [][]byte{[]byte(tsrc)}, false, imp)
 }
diff --git a/src/go/types/stdlib_test.go b/src/go/types/stdlib_test.go
index 503d0a6..d86a77a 100644
--- a/src/go/types/stdlib_test.go
+++ b/src/go/types/stdlib_test.go
@@ -26,9 +26,15 @@
 	. "go/types"
 )
 
+// The cmd/*/internal packages may have been deleted as part of a binary
+// release. Import from source instead.
+//
+// (See https://golang.org/issue/43232 and
+// https://github.com/golang/build/blob/df58bbac082bc87c4a3cdfe336d1ffe60bbaa916/cmd/release/release.go#L533-L545.)
+//
 // Use the same importer for all std lib tests to
 // avoid repeated importing of the same packages.
-var stdLibImporter = importer.Default()
+var stdLibImporter = importer.ForCompiler(token.NewFileSet(), "source", nil)
 
 func TestStdlib(t *testing.T) {
 	testenv.MustHaveGoBuild(t)
diff --git a/src/go/types/testdata/check/issues.src b/src/go/types/testdata/check/issues.src
index e2ac067..55fe220 100644
--- a/src/go/types/testdata/check/issues.src
+++ b/src/go/types/testdata/check/issues.src
@@ -6,7 +6,7 @@
 
 import (
 	"fmt"
-	syn "cmd/compile/internal/syntax"
+	syn "regexp/syntax"
 	t1 "text/template"
 	t2 "html/template"
 )
@@ -329,10 +329,10 @@
 func issue28281g() (... /* ERROR can only use ... with final parameter */ TT)
 
 // Issue #26234: Make various field/method lookup errors easier to read by matching cmd/compile's output
-func issue26234a(f *syn.File) {
+func issue26234a(f *syn.Prog) {
 	// The error message below should refer to the actual package name (syntax)
 	// not the local package name (syn).
-	f.foo /* ERROR f.foo undefined \(type \*syntax.File has no field or method foo\) */
+	f.foo /* ERROR f\.foo undefined \(type \*syntax\.Prog has no field or method foo\) */
 }
 
 type T struct {
@@ -357,11 +357,11 @@
 	var _ T = 0 // ERROR cannot use 0 \(untyped int constant\) as T
 
 	// There is only one package with name syntax imported, only use the (global) package name in error messages.
-	var _ *syn.File = 0 // ERROR cannot use 0 \(untyped int constant\) as \*syntax.File
+	var _ *syn.Prog = 0 // ERROR cannot use 0 \(untyped int constant\) as \*syntax.Prog
 
 	// Because both t1 and t2 have the same global package name (template),
 	// qualify packages with full path name in this case.
-	var _ t1.Template = t2 /* ERROR cannot use .* \(value of type "html/template".Template\) as "text/template".Template */ .Template{}
+	var _ t1.Template = t2 /* ERROR cannot use .* \(value of type .html/template.\.Template\) as .text/template.\.Template */ .Template{}
 }
 
 func issue42989(s uint) {
diff --git a/src/go/types/testdata/examples/functions.go2 b/src/go/types/testdata/examples/functions.go2
index fb74ae7..a053471 100644
--- a/src/go/types/testdata/examples/functions.go2
+++ b/src/go/types/testdata/examples/functions.go2
@@ -210,5 +210,5 @@
 func h[] /* ERROR empty type parameter list */ ()
 
 func _() {
-	h[] /* ERROR operand */ ()
+	h /* ERROR cannot index */ [] /* ERROR operand */ ()
 }
diff --git a/src/go/types/testdata/fixedbugs/issue46403.src b/src/go/types/testdata/fixedbugs/issue46403.src
new file mode 100644
index 0000000..9d47522
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue46403.src
@@ -0,0 +1,11 @@
+// Copyright 2021 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 issue46403
+
+func _() {
+	// a should be used, despite the parser error below.
+	var a []int
+	var _ = a[] // ERROR expected operand
+}
diff --git a/src/go/types/testdata/fixedbugs/issue46404.go1 b/src/go/types/testdata/fixedbugs/issue46404.go1
new file mode 100644
index 0000000..db604bc
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue46404.go1
@@ -0,0 +1,8 @@
+// Copyright 2021 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 issue46404
+
+// Check that we don't type check t[_] as an instantiation.
+type t [t /* ERROR not a type */ [_]]_ // ERROR cannot use
diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go
index 5185c33..1738d86 100644
--- a/src/go/types/typexpr.go
+++ b/src/go/types/typexpr.go
@@ -463,8 +463,12 @@
 		}
 
 	case *ast.IndexExpr:
-		exprs := typeparams.UnpackExpr(e.Index)
-		return check.instantiatedType(e.X, exprs, def)
+		if typeparams.Enabled {
+			exprs := typeparams.UnpackExpr(e.Index)
+			return check.instantiatedType(e.X, exprs, def)
+		}
+		check.errorf(e0, _NotAType, "%s is not a type", e0)
+		check.use(e.X)
 
 	case *ast.ParenExpr:
 		// Generic types must be instantiated before they can be used in any form.
diff --git a/src/image/draw/draw.go b/src/image/draw/draw.go
index 8f96aa2..13f6668 100644
--- a/src/image/draw/draw.go
+++ b/src/image/draw/draw.go
@@ -23,6 +23,16 @@
 	Set(x, y int, c color.Color)
 }
 
+// RGBA64Image extends both the Image and image.RGBA64Image interfaces with a
+// SetRGBA64 method to change a single pixel. SetRGBA64 is equivalent to
+// calling Set, but it can avoid allocations from converting concrete color
+// types to the color.Color interface type.
+type RGBA64Image interface {
+	image.RGBA64Image
+	Set(x, y int, c color.Color)
+	SetRGBA64(x, y int, c color.RGBA64)
+}
+
 // Quantizer produces a palette for an image.
 type Quantizer interface {
 	// Quantize appends up to cap(p) - len(p) colors to p and returns the
diff --git a/src/image/geom.go b/src/image/geom.go
index 78e9e49..e71aa61 100644
--- a/src/image/geom.go
+++ b/src/image/geom.go
@@ -246,6 +246,14 @@
 	return color.Transparent
 }
 
+// RGBA64At implements the RGBA64Image interface.
+func (r Rectangle) RGBA64At(x, y int) color.RGBA64 {
+	if (Point{x, y}).In(r) {
+		return color.RGBA64{0xffff, 0xffff, 0xffff, 0xffff}
+	}
+	return color.RGBA64{}
+}
+
 // Bounds implements the Image interface.
 func (r Rectangle) Bounds() Rectangle {
 	return r
diff --git a/src/image/gif/reader.go b/src/image/gif/reader.go
index e580ab0..9e8268c 100644
--- a/src/image/gif/reader.go
+++ b/src/image/gif/reader.go
@@ -116,7 +116,7 @@
 // consumed when checking that the blockReader is exhausted.
 //
 // To avoid the allocation of a bufio.Reader for the lzw Reader, blockReader
-// implements io.ReadByte and buffers blocks into the decoder's "tmp" buffer.
+// implements io.ByteReader and buffers blocks into the decoder's "tmp" buffer.
 type blockReader struct {
 	d    *decoder
 	i, j uint8 // d.tmp[i:j] contains the buffered bytes
diff --git a/src/image/image.go b/src/image/image.go
index 8adba96..930d9ac 100644
--- a/src/image/image.go
+++ b/src/image/image.go
@@ -45,6 +45,17 @@
 	At(x, y int) color.Color
 }
 
+// RGBA64Image is an Image whose pixels can be converted directly to a
+// color.RGBA64.
+type RGBA64Image interface {
+	// RGBA64At returns the RGBA64 color of the pixel at (x, y). It is
+	// equivalent to calling At(x, y).RGBA() and converting the resulting
+	// 32-bit return values to a color.RGBA64, but it can avoid allocations
+	// from converting concrete color types to the color.Color interface type.
+	RGBA64At(x, y int) color.RGBA64
+	Image
+}
+
 // PalettedImage is an image whose colors may come from a limited palette.
 // If m is a PalettedImage and m.ColorModel() returns a color.Palette p,
 // then m.At(x, y) should be equivalent to p[m.ColorIndexAt(x, y)]. If m's
@@ -90,6 +101,24 @@
 	return p.RGBAAt(x, y)
 }
 
+func (p *RGBA) RGBA64At(x, y int) color.RGBA64 {
+	if !(Point{x, y}.In(p.Rect)) {
+		return color.RGBA64{}
+	}
+	i := p.PixOffset(x, y)
+	s := p.Pix[i : i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
+	r := uint16(s[0])
+	g := uint16(s[1])
+	b := uint16(s[2])
+	a := uint16(s[3])
+	return color.RGBA64{
+		(r << 8) | r,
+		(g << 8) | g,
+		(b << 8) | b,
+		(a << 8) | a,
+	}
+}
+
 func (p *RGBA) RGBAAt(x, y int) color.RGBA {
 	if !(Point{x, y}.In(p.Rect)) {
 		return color.RGBA{}
@@ -118,6 +147,18 @@
 	s[3] = c1.A
 }
 
+func (p *RGBA) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	s := p.Pix[i : i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
+	s[0] = uint8(c.R >> 8)
+	s[1] = uint8(c.G >> 8)
+	s[2] = uint8(c.B >> 8)
+	s[3] = uint8(c.A >> 8)
+}
+
 func (p *RGBA) SetRGBA(x, y int, c color.RGBA) {
 	if !(Point{x, y}.In(p.Rect)) {
 		return
@@ -311,6 +352,11 @@
 	return p.NRGBAAt(x, y)
 }
 
+func (p *NRGBA) RGBA64At(x, y int) color.RGBA64 {
+	r, g, b, a := p.NRGBAAt(x, y).RGBA()
+	return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
+}
+
 func (p *NRGBA) NRGBAAt(x, y int) color.NRGBA {
 	if !(Point{x, y}.In(p.Rect)) {
 		return color.NRGBA{}
@@ -339,6 +385,24 @@
 	s[3] = c1.A
 }
 
+func (p *NRGBA) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	r, g, b, a := uint32(c.R), uint32(c.G), uint32(c.B), uint32(c.A)
+	if (a != 0) && (a != 0xffff) {
+		r = (r * 0xffff) / a
+		g = (g * 0xffff) / a
+		b = (b * 0xffff) / a
+	}
+	i := p.PixOffset(x, y)
+	s := p.Pix[i : i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
+	s[0] = uint8(r >> 8)
+	s[1] = uint8(g >> 8)
+	s[2] = uint8(b >> 8)
+	s[3] = uint8(a >> 8)
+}
+
 func (p *NRGBA) SetNRGBA(x, y int, c color.NRGBA) {
 	if !(Point{x, y}.In(p.Rect)) {
 		return
@@ -415,6 +479,11 @@
 	return p.NRGBA64At(x, y)
 }
 
+func (p *NRGBA64) RGBA64At(x, y int) color.RGBA64 {
+	r, g, b, a := p.NRGBA64At(x, y).RGBA()
+	return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
+}
+
 func (p *NRGBA64) NRGBA64At(x, y int) color.NRGBA64 {
 	if !(Point{x, y}.In(p.Rect)) {
 		return color.NRGBA64{}
@@ -452,6 +521,28 @@
 	s[7] = uint8(c1.A)
 }
 
+func (p *NRGBA64) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	r, g, b, a := uint32(c.R), uint32(c.G), uint32(c.B), uint32(c.A)
+	if (a != 0) && (a != 0xffff) {
+		r = (r * 0xffff) / a
+		g = (g * 0xffff) / a
+		b = (b * 0xffff) / a
+	}
+	i := p.PixOffset(x, y)
+	s := p.Pix[i : i+8 : i+8] // Small cap improves performance, see https://golang.org/issue/27857
+	s[0] = uint8(r >> 8)
+	s[1] = uint8(r)
+	s[2] = uint8(g >> 8)
+	s[3] = uint8(g)
+	s[4] = uint8(b >> 8)
+	s[5] = uint8(b)
+	s[6] = uint8(a >> 8)
+	s[7] = uint8(a)
+}
+
 func (p *NRGBA64) SetNRGBA64(x, y int, c color.NRGBA64) {
 	if !(Point{x, y}.In(p.Rect)) {
 		return
@@ -532,6 +623,12 @@
 	return p.AlphaAt(x, y)
 }
 
+func (p *Alpha) RGBA64At(x, y int) color.RGBA64 {
+	a := uint16(p.AlphaAt(x, y).A)
+	a |= a << 8
+	return color.RGBA64{a, a, a, a}
+}
+
 func (p *Alpha) AlphaAt(x, y int) color.Alpha {
 	if !(Point{x, y}.In(p.Rect)) {
 		return color.Alpha{}
@@ -554,6 +651,14 @@
 	p.Pix[i] = color.AlphaModel.Convert(c).(color.Alpha).A
 }
 
+func (p *Alpha) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i] = uint8(c.A >> 8)
+}
+
 func (p *Alpha) SetAlpha(x, y int, c color.Alpha) {
 	if !(Point{x, y}.In(p.Rect)) {
 		return
@@ -626,6 +731,11 @@
 	return p.Alpha16At(x, y)
 }
 
+func (p *Alpha16) RGBA64At(x, y int) color.RGBA64 {
+	a := p.Alpha16At(x, y).A
+	return color.RGBA64{a, a, a, a}
+}
+
 func (p *Alpha16) Alpha16At(x, y int) color.Alpha16 {
 	if !(Point{x, y}.In(p.Rect)) {
 		return color.Alpha16{}
@@ -650,6 +760,15 @@
 	p.Pix[i+1] = uint8(c1.A)
 }
 
+func (p *Alpha16) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i+0] = uint8(c.A >> 8)
+	p.Pix[i+1] = uint8(c.A)
+}
+
 func (p *Alpha16) SetAlpha16(x, y int, c color.Alpha16) {
 	if !(Point{x, y}.In(p.Rect)) {
 		return
@@ -723,6 +842,12 @@
 	return p.GrayAt(x, y)
 }
 
+func (p *Gray) RGBA64At(x, y int) color.RGBA64 {
+	gray := uint16(p.GrayAt(x, y).Y)
+	gray |= gray << 8
+	return color.RGBA64{gray, gray, gray, 0xffff}
+}
+
 func (p *Gray) GrayAt(x, y int) color.Gray {
 	if !(Point{x, y}.In(p.Rect)) {
 		return color.Gray{}
@@ -745,6 +870,16 @@
 	p.Pix[i] = color.GrayModel.Convert(c).(color.Gray).Y
 }
 
+func (p *Gray) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	// This formula is the same as in color.grayModel.
+	gray := (19595*uint32(c.R) + 38470*uint32(c.G) + 7471*uint32(c.B) + 1<<15) >> 24
+	i := p.PixOffset(x, y)
+	p.Pix[i] = uint8(gray)
+}
+
 func (p *Gray) SetGray(x, y int, c color.Gray) {
 	if !(Point{x, y}.In(p.Rect)) {
 		return
@@ -804,6 +939,11 @@
 	return p.Gray16At(x, y)
 }
 
+func (p *Gray16) RGBA64At(x, y int) color.RGBA64 {
+	gray := p.Gray16At(x, y).Y
+	return color.RGBA64{gray, gray, gray, 0xffff}
+}
+
 func (p *Gray16) Gray16At(x, y int) color.Gray16 {
 	if !(Point{x, y}.In(p.Rect)) {
 		return color.Gray16{}
@@ -828,6 +968,17 @@
 	p.Pix[i+1] = uint8(c1.Y)
 }
 
+func (p *Gray16) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	// This formula is the same as in color.gray16Model.
+	gray := (19595*uint32(c.R) + 38470*uint32(c.G) + 7471*uint32(c.B) + 1<<15) >> 16
+	i := p.PixOffset(x, y)
+	p.Pix[i+0] = uint8(gray >> 8)
+	p.Pix[i+1] = uint8(gray)
+}
+
 func (p *Gray16) SetGray16(x, y int, c color.Gray16) {
 	if !(Point{x, y}.In(p.Rect)) {
 		return
@@ -888,6 +1039,11 @@
 	return p.CMYKAt(x, y)
 }
 
+func (p *CMYK) RGBA64At(x, y int) color.RGBA64 {
+	r, g, b, a := p.CMYKAt(x, y).RGBA()
+	return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
+}
+
 func (p *CMYK) CMYKAt(x, y int) color.CMYK {
 	if !(Point{x, y}.In(p.Rect)) {
 		return color.CMYK{}
@@ -916,6 +1072,19 @@
 	s[3] = c1.K
 }
 
+func (p *CMYK) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	cc, mm, yy, kk := color.RGBToCMYK(uint8(c.R>>8), uint8(c.G>>8), uint8(c.B>>8))
+	i := p.PixOffset(x, y)
+	s := p.Pix[i : i+4 : i+4] // Small cap improves performance, see https://golang.org/issue/27857
+	s[0] = cc
+	s[1] = mm
+	s[2] = yy
+	s[3] = kk
+}
+
 func (p *CMYK) SetCMYK(x, y int, c color.CMYK) {
 	if !(Point{x, y}.In(p.Rect)) {
 		return
@@ -988,6 +1157,26 @@
 	return p.Palette[p.Pix[i]]
 }
 
+func (p *Paletted) RGBA64At(x, y int) color.RGBA64 {
+	if len(p.Palette) == 0 {
+		return color.RGBA64{}
+	}
+	c := color.Color(nil)
+	if !(Point{x, y}.In(p.Rect)) {
+		c = p.Palette[0]
+	} else {
+		i := p.PixOffset(x, y)
+		c = p.Palette[p.Pix[i]]
+	}
+	r, g, b, a := c.RGBA()
+	return color.RGBA64{
+		uint16(r),
+		uint16(g),
+		uint16(b),
+		uint16(a),
+	}
+}
+
 // PixOffset returns the index of the first element of Pix that corresponds to
 // the pixel at (x, y).
 func (p *Paletted) PixOffset(x, y int) int {
@@ -1002,6 +1191,14 @@
 	p.Pix[i] = uint8(p.Palette.Index(c))
 }
 
+func (p *Paletted) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i] = uint8(p.Palette.Index(c))
+}
+
 func (p *Paletted) ColorIndexAt(x, y int) uint8 {
 	if !(Point{x, y}.In(p.Rect)) {
 		return 0
diff --git a/src/image/image_test.go b/src/image/image_test.go
index b9b9bfa..7f41bcb 100644
--- a/src/image/image_test.go
+++ b/src/image/image_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"image/color"
+	"image/color/palette"
 	"testing"
 )
 
@@ -191,6 +192,92 @@
 	}
 }
 
+func TestRGBA64Image(t *testing.T) {
+	// memset sets every element of s to v.
+	memset := func(s []byte, v byte) {
+		for i := range s {
+			s[i] = v
+		}
+	}
+
+	r := Rect(0, 0, 3, 2)
+	testCases := []Image{
+		NewAlpha(r),
+		NewAlpha16(r),
+		NewCMYK(r),
+		NewGray(r),
+		NewGray16(r),
+		NewNRGBA(r),
+		NewNRGBA64(r),
+		NewNYCbCrA(r, YCbCrSubsampleRatio444),
+		NewPaletted(r, palette.Plan9),
+		NewRGBA(r),
+		NewRGBA64(r),
+		NewUniform(color.RGBA64{}),
+		NewYCbCr(r, YCbCrSubsampleRatio444),
+		r,
+	}
+	for _, tc := range testCases {
+		switch tc := tc.(type) {
+		// Most of the concrete image types in the testCases implement the
+		// draw.RGBA64Image interface: they have a SetRGBA64 method. We use an
+		// interface literal here, instead of importing "image/draw", to avoid
+		// an import cycle.
+		//
+		// The YCbCr and NYCbCrA types are special-cased. Chroma subsampling
+		// means that setting one pixel can modify neighboring pixels. They
+		// don't have Set or SetRGBA64 methods because that side effect could
+		// be surprising. Here, we just memset the channel buffers instead.
+		//
+		// The Uniform and Rectangle types are also special-cased, as they
+		// don't have a Set or SetRGBA64 method.
+		case interface {
+			SetRGBA64(x, y int, c color.RGBA64)
+		}:
+			tc.SetRGBA64(1, 1, color.RGBA64{0x7FFF, 0x3FFF, 0x0000, 0x7FFF})
+
+		case *NYCbCrA:
+			memset(tc.YCbCr.Y, 0x77)
+			memset(tc.YCbCr.Cb, 0x88)
+			memset(tc.YCbCr.Cr, 0x99)
+			memset(tc.A, 0xAA)
+
+		case *Uniform:
+			tc.C = color.RGBA64{0x7FFF, 0x3FFF, 0x0000, 0x7FFF}
+
+		case *YCbCr:
+			memset(tc.Y, 0x77)
+			memset(tc.Cb, 0x88)
+			memset(tc.Cr, 0x99)
+
+		case Rectangle:
+			// No-op. Rectangle pixels' colors are immutable. They're always
+			// color.Opaque.
+
+		default:
+			t.Errorf("could not initialize pixels for %T", tc)
+			continue
+		}
+
+		// Check that RGBA64At(x, y) is equivalent to At(x, y).RGBA().
+		rgba64Image, ok := tc.(RGBA64Image)
+		if !ok {
+			t.Errorf("%T is not an RGBA64Image", tc)
+			continue
+		}
+		got := rgba64Image.RGBA64At(1, 1)
+		wantR, wantG, wantB, wantA := tc.At(1, 1).RGBA()
+		if (uint32(got.R) != wantR) || (uint32(got.G) != wantG) ||
+			(uint32(got.B) != wantB) || (uint32(got.A) != wantA) {
+			t.Errorf("%T:\ngot  (0x%04X, 0x%04X, 0x%04X, 0x%04X)\n"+
+				"want (0x%04X, 0x%04X, 0x%04X, 0x%04X)", tc,
+				got.R, got.G, got.B, got.A,
+				wantR, wantG, wantB, wantA)
+			continue
+		}
+	}
+}
+
 func BenchmarkAt(b *testing.B) {
 	for _, tc := range testImages {
 		b.Run(tc.name, func(b *testing.B) {
diff --git a/src/image/names.go b/src/image/names.go
index 8595a35..17b0658 100644
--- a/src/image/names.go
+++ b/src/image/names.go
@@ -41,6 +41,11 @@
 
 func (c *Uniform) At(x, y int) color.Color { return c.C }
 
+func (c *Uniform) RGBA64At(x, y int) color.RGBA64 {
+	r, g, b, a := c.C.RGBA()
+	return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
+}
+
 // Opaque scans the entire image and reports whether it is fully opaque.
 func (c *Uniform) Opaque() bool {
 	_, _, _, a := c.C.RGBA()
diff --git a/src/image/ycbcr.go b/src/image/ycbcr.go
index fbdffe1..328b90d 100644
--- a/src/image/ycbcr.go
+++ b/src/image/ycbcr.go
@@ -71,6 +71,11 @@
 	return p.YCbCrAt(x, y)
 }
 
+func (p *YCbCr) RGBA64At(x, y int) color.RGBA64 {
+	r, g, b, a := p.YCbCrAt(x, y).RGBA()
+	return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
+}
+
 func (p *YCbCr) YCbCrAt(x, y int) color.YCbCr {
 	if !(Point{x, y}.In(p.Rect)) {
 		return color.YCbCr{}
@@ -210,6 +215,11 @@
 	return p.NYCbCrAAt(x, y)
 }
 
+func (p *NYCbCrA) RGBA64At(x, y int) color.RGBA64 {
+	r, g, b, a := p.NYCbCrAAt(x, y).RGBA()
+	return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
+}
+
 func (p *NYCbCrA) NYCbCrAAt(x, y int) color.NYCbCrA {
 	if !(Point{X: x, Y: y}.In(p.Rect)) {
 		return color.NYCbCrA{}
diff --git a/src/internal/buildcfg/exp.go b/src/internal/buildcfg/exp.go
index 2435a79..9a60253 100644
--- a/src/internal/buildcfg/exp.go
+++ b/src/internal/buildcfg/exp.go
@@ -6,7 +6,6 @@
 
 import (
 	"fmt"
-	"os"
 	"reflect"
 	"strings"
 
@@ -18,20 +17,19 @@
 //
 // (This is not necessarily the set of experiments the compiler itself
 // was built with.)
-var Experiment goexperiment.Flags = parseExperiments()
-
-var regabiSupported = GOARCH == "amd64" && (GOOS == "android" || GOOS == "linux" || GOOS == "darwin" || GOOS == "windows")
-
+//
 // experimentBaseline specifies the experiment flags that are enabled by
 // default in the current toolchain. This is, in effect, the "control"
 // configuration and any variation from this is an experiment.
-var experimentBaseline = goexperiment.Flags{
-	RegabiWrappers: regabiSupported,
-	RegabiG:        regabiSupported,
-	RegabiReflect:  regabiSupported,
-	RegabiDefer:    regabiSupported,
-	RegabiArgs:     regabiSupported,
-}
+var Experiment, experimentBaseline = func() (goexperiment.Flags, goexperiment.Flags) {
+	flags, baseline, err := ParseGOEXPERIMENT(GOOS, GOARCH, envOr("GOEXPERIMENT", defaultGOEXPERIMENT))
+	if err != nil {
+		Error = err
+	}
+	return flags, baseline
+}()
+
+const DefaultGOEXPERIMENT = defaultGOEXPERIMENT
 
 // FramePointerEnabled enables the use of platform conventions for
 // saving frame pointers.
@@ -42,16 +40,29 @@
 // Note: must agree with runtime.framepointer_enabled.
 var FramePointerEnabled = GOARCH == "amd64" || GOARCH == "arm64"
 
-func parseExperiments() goexperiment.Flags {
+// ParseGOEXPERIMENT parses a (GOOS, GOARCH, GOEXPERIMENT)
+// configuration tuple and returns the enabled and baseline experiment
+// flag sets.
+//
+// TODO(mdempsky): Move to internal/goexperiment.
+func ParseGOEXPERIMENT(goos, goarch, goexp string) (flags, baseline goexperiment.Flags, err error) {
+	regabiSupported := goarch == "amd64" && (goos == "android" || goos == "linux" || goos == "darwin" || goos == "windows")
+
+	baseline = goexperiment.Flags{
+		RegabiWrappers: regabiSupported,
+		RegabiG:        regabiSupported,
+		RegabiReflect:  regabiSupported,
+		RegabiDefer:    regabiSupported,
+		RegabiArgs:     regabiSupported,
+	}
+
 	// Start with the statically enabled set of experiments.
-	flags := experimentBaseline
+	flags = baseline
 
 	// Pick up any changes to the baseline configuration from the
 	// GOEXPERIMENT environment. This can be set at make.bash time
 	// and overridden at build time.
-	env := envOr("GOEXPERIMENT", defaultGOEXPERIMENT)
-
-	if env != "" {
+	if goexp != "" {
 		// Create a map of known experiment names.
 		names := make(map[string]func(bool))
 		rv := reflect.ValueOf(&flags).Elem()
@@ -74,7 +85,7 @@
 		}
 
 		// Parse names.
-		for _, f := range strings.Split(env, ",") {
+		for _, f := range strings.Split(goexp, ",") {
 			if f == "" {
 				continue
 			}
@@ -91,15 +102,15 @@
 			}
 			set, ok := names[f]
 			if !ok {
-				fmt.Printf("unknown experiment %s\n", f)
-				os.Exit(2)
+				err = fmt.Errorf("unknown GOEXPERIMENT %s", f)
+				return
 			}
 			set(val)
 		}
 	}
 
 	// regabi is only supported on amd64.
-	if GOARCH != "amd64" {
+	if goarch != "amd64" {
 		flags.RegabiWrappers = false
 		flags.RegabiG = false
 		flags.RegabiReflect = false
@@ -108,12 +119,12 @@
 	}
 	// Check regabi dependencies.
 	if flags.RegabiG && !flags.RegabiWrappers {
-		Error = fmt.Errorf("GOEXPERIMENT regabig requires regabiwrappers")
+		err = fmt.Errorf("GOEXPERIMENT regabig requires regabiwrappers")
 	}
 	if flags.RegabiArgs && !(flags.RegabiWrappers && flags.RegabiG && flags.RegabiReflect && flags.RegabiDefer) {
-		Error = fmt.Errorf("GOEXPERIMENT regabiargs requires regabiwrappers,regabig,regabireflect,regabidefer")
+		err = fmt.Errorf("GOEXPERIMENT regabiargs requires regabiwrappers,regabig,regabireflect,regabidefer")
 	}
-	return flags
+	return
 }
 
 // expList returns the list of lower-cased experiment names for
@@ -165,3 +176,14 @@
 func AllExperiments() []string {
 	return expList(&Experiment, nil, true)
 }
+
+// UpdateExperiments updates the Experiment global based on a new GOARCH value.
+// This is only required for cmd/go, which can change GOARCH after
+// program startup due to use of "go env -w".
+func UpdateExperiments(goos, goarch, goexperiment string) {
+	var err error
+	Experiment, experimentBaseline, err = ParseGOEXPERIMENT(goos, goarch, goexperiment)
+	if err != nil {
+		Error = err
+	}
+}
diff --git a/src/internal/bytealg/index_generic.go b/src/internal/bytealg/index_generic.go
index 287bdba..0a6eb90 100644
--- a/src/internal/bytealg/index_generic.go
+++ b/src/internal/bytealg/index_generic.go
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// go:build !amd64 && !arm64 && !s390x && !ppc64le && !ppc64
 //go:build !amd64 && !arm64 && !s390x && !ppc64le && !ppc64
 // +build !amd64,!arm64,!s390x,!ppc64le,!ppc64
 
diff --git a/src/internal/bytealg/index_native.go b/src/internal/bytealg/index_native.go
index 75aff4b..9547a5d 100644
--- a/src/internal/bytealg/index_native.go
+++ b/src/internal/bytealg/index_native.go
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// go:build amd64 || arm64 || s390x || ppc64le || ppc64
 //go:build amd64 || arm64 || s390x || ppc64le || ppc64
 // +build amd64 arm64 s390x ppc64le ppc64
 
diff --git a/src/internal/reflectlite/type.go b/src/internal/reflectlite/type.go
index f529f7c..b1899b0 100644
--- a/src/internal/reflectlite/type.go
+++ b/src/internal/reflectlite/type.go
@@ -68,7 +68,7 @@
 }
 
 /*
- * These data structures are known to the compiler (../../cmd/internal/gc/reflect.go).
+ * These data structures are known to the compiler (../../cmd/internal/reflectdata/reflect.go).
  * A few are known to ../runtime/type.go to convey to debuggers.
  * They are also known to ../runtime/type.go.
  */
@@ -111,7 +111,7 @@
 // available in the memory directly following the rtype value.
 //
 // tflag values must be kept in sync with copies in:
-//	cmd/compile/internal/gc/reflect.go
+//	cmd/compile/internal/reflectdata/reflect.go
 //	cmd/link/internal/ld/decodesym.go
 //	runtime/type.go
 type tflag uint8
diff --git a/src/math/big/int.go b/src/math/big/int.go
index 65f3248..7647346 100644
--- a/src/math/big/int.go
+++ b/src/math/big/int.go
@@ -425,7 +425,7 @@
 	return z.setFromScanner(strings.NewReader(s), base)
 }
 
-// setFromScanner implements SetString given an io.BytesScanner.
+// setFromScanner implements SetString given an io.ByteScanner.
 // For documentation see comments of SetString.
 func (z *Int) setFromScanner(r io.ByteScanner, base int) (*Int, bool) {
 	if _, _, err := z.scan(r, base); err != nil {
diff --git a/src/math/rand/rand.go b/src/math/rand/rand.go
index 8179d9f..13f20ca 100644
--- a/src/math/rand/rand.go
+++ b/src/math/rand/rand.go
@@ -12,9 +12,6 @@
 // The default Source is safe for concurrent use by multiple goroutines, but
 // Sources created by NewSource are not.
 //
-// Mathematical interval notation such as [0, n) is used throughout the
-// documentation for this package.
-//
 // This package's outputs might be easily predictable regardless of how it's
 // seeded. For random numbers suitable for security-sensitive work, see the
 // crypto/rand package.
@@ -106,7 +103,7 @@
 	return int(u << 1 >> 1) // clear sign bit if int == int32
 }
 
-// Int63n returns, as an int64, a non-negative pseudo-random number in [0,n).
+// Int63n returns, as an int64, a non-negative pseudo-random number in the half-open interval [0,n).
 // It panics if n <= 0.
 func (r *Rand) Int63n(n int64) int64 {
 	if n <= 0 {
@@ -123,7 +120,7 @@
 	return v % n
 }
 
-// Int31n returns, as an int32, a non-negative pseudo-random number in [0,n).
+// Int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n).
 // It panics if n <= 0.
 func (r *Rand) Int31n(n int32) int32 {
 	if n <= 0 {
@@ -140,7 +137,7 @@
 	return v % n
 }
 
-// int31n returns, as an int32, a non-negative pseudo-random number in [0,n).
+// int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n).
 // n must be > 0, but int31n does not check this; the caller must ensure it.
 // int31n exists because Int31n is inefficient, but Go 1 compatibility
 // requires that the stream of values produced by math/rand remain unchanged.
@@ -164,7 +161,7 @@
 	return int32(prod >> 32)
 }
 
-// Intn returns, as an int, a non-negative pseudo-random number in [0,n).
+// Intn returns, as an int, a non-negative pseudo-random number in the half-open interval [0,n).
 // It panics if n <= 0.
 func (r *Rand) Intn(n int) int {
 	if n <= 0 {
@@ -176,7 +173,7 @@
 	return int(r.Int63n(int64(n)))
 }
 
-// Float64 returns, as a float64, a pseudo-random number in [0.0,1.0).
+// Float64 returns, as a float64, a pseudo-random number in the half-open interval [0.0,1.0).
 func (r *Rand) Float64() float64 {
 	// A clearer, simpler implementation would be:
 	//	return float64(r.Int63n(1<<53)) / (1<<53)
@@ -202,7 +199,7 @@
 	return f
 }
 
-// Float32 returns, as a float32, a pseudo-random number in [0.0,1.0).
+// Float32 returns, as a float32, a pseudo-random number in the half-open interval [0.0,1.0).
 func (r *Rand) Float32() float32 {
 	// Same rationale as in Float64: we want to preserve the Go 1 value
 	// stream except we want to fix it not to return 1.0
@@ -215,7 +212,8 @@
 	return f
 }
 
-// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n).
+// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers
+// in the half-open interval [0,n).
 func (r *Rand) Perm(n int) []int {
 	m := make([]int, n)
 	// In the following loop, the iteration when i=0 always swaps m[0] with m[0].
@@ -323,31 +321,31 @@
 // Int returns a non-negative pseudo-random int from the default Source.
 func Int() int { return globalRand.Int() }
 
-// Int63n returns, as an int64, a non-negative pseudo-random number in [0,n)
+// Int63n returns, as an int64, a non-negative pseudo-random number in the half-open interval [0,n)
 // from the default Source.
 // It panics if n <= 0.
 func Int63n(n int64) int64 { return globalRand.Int63n(n) }
 
-// Int31n returns, as an int32, a non-negative pseudo-random number in [0,n)
+// Int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n)
 // from the default Source.
 // It panics if n <= 0.
 func Int31n(n int32) int32 { return globalRand.Int31n(n) }
 
-// Intn returns, as an int, a non-negative pseudo-random number in [0,n)
+// Intn returns, as an int, a non-negative pseudo-random number in the half-open interval [0,n)
 // from the default Source.
 // It panics if n <= 0.
 func Intn(n int) int { return globalRand.Intn(n) }
 
-// Float64 returns, as a float64, a pseudo-random number in [0.0,1.0)
+// Float64 returns, as a float64, a pseudo-random number in the half-open interval [0.0,1.0)
 // from the default Source.
 func Float64() float64 { return globalRand.Float64() }
 
-// Float32 returns, as a float32, a pseudo-random number in [0.0,1.0)
+// Float32 returns, as a float32, a pseudo-random number in the half-open interval [0.0,1.0)
 // from the default Source.
 func Float32() float32 { return globalRand.Float32() }
 
-// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n)
-// from the default Source.
+// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers
+// in the half-open interval [0,n) from the default Source.
 func Perm(n int) []int { return globalRand.Perm(n) }
 
 // Shuffle pseudo-randomizes the order of elements using the default Source.
diff --git a/src/net/dial_test.go b/src/net/dial_test.go
index fbd1aa3..12f47ec 100644
--- a/src/net/dial_test.go
+++ b/src/net/dial_test.go
@@ -155,40 +155,27 @@
 	return c, err
 }
 
-func dialClosedPort(t *testing.T) (actual, expected time.Duration) {
-	// Estimate the expected time for this platform.
-	// On Windows, dialing a closed port takes roughly 1 second,
-	// but other platforms should be instantaneous.
-	if runtime.GOOS == "windows" {
-		expected = 1500 * time.Millisecond
-	} else if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
-		expected = 150 * time.Millisecond
-	} else {
-		expected = 95 * time.Millisecond
-	}
+func dialClosedPort(t *testing.T) (dialLatency time.Duration) {
+	// On most platforms, dialing a closed port should be nearly instantaneous —
+	// less than a few hundred milliseconds. However, on some platforms it may be
+	// much slower: on Windows and OpenBSD, it has been observed to take up to a
+	// few seconds.
 
 	l, err := Listen("tcp", "127.0.0.1:0")
 	if err != nil {
-		t.Logf("dialClosedPort: Listen failed: %v", err)
-		return 999 * time.Hour, expected
+		t.Fatalf("dialClosedPort: Listen failed: %v", err)
 	}
 	addr := l.Addr().String()
 	l.Close()
-	// On OpenBSD, interference from TestTCPSelfConnect is mysteriously
-	// causing the first attempt to hang for a few seconds, so we throw
-	// away the first result and keep the second.
-	for i := 1; ; i++ {
-		startTime := time.Now()
-		c, err := Dial("tcp", addr)
-		if err == nil {
-			c.Close()
-		}
-		elapsed := time.Now().Sub(startTime)
-		if i == 2 {
-			t.Logf("dialClosedPort: measured delay %v", elapsed)
-			return elapsed, expected
-		}
+
+	startTime := time.Now()
+	c, err := Dial("tcp", addr)
+	if err == nil {
+		c.Close()
 	}
+	elapsed := time.Now().Sub(startTime)
+	t.Logf("dialClosedPort: measured delay %v", elapsed)
+	return elapsed
 }
 
 func TestDialParallel(t *testing.T) {
@@ -198,10 +185,7 @@
 		t.Skip("both IPv4 and IPv6 are required")
 	}
 
-	closedPortDelay, expectClosedPortDelay := dialClosedPort(t)
-	if closedPortDelay > expectClosedPortDelay {
-		t.Errorf("got %v; want <= %v", closedPortDelay, expectClosedPortDelay)
-	}
+	closedPortDelay := dialClosedPort(t)
 
 	const instant time.Duration = 0
 	const fallbackDelay = 200 * time.Millisecond
@@ -682,10 +666,7 @@
 		t.Skip("both IPv4 and IPv6 are required")
 	}
 
-	closedPortDelay, expectClosedPortDelay := dialClosedPort(t)
-	if closedPortDelay > expectClosedPortDelay {
-		t.Errorf("got %v; want <= %v", closedPortDelay, expectClosedPortDelay)
-	}
+	closedPortDelay := dialClosedPort(t)
 
 	origTestHookLookupIP := testHookLookupIP
 	defer func() { testHookLookupIP = origTestHookLookupIP }()
diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go
index a59be7f..350ad5d 100644
--- a/src/net/dnsclient_unix_test.go
+++ b/src/net/dnsclient_unix_test.go
@@ -1846,6 +1846,17 @@
 							Target: dnsmessage.MustNewName("<html>.golang.org."),
 						},
 					},
+					dnsmessage.Resource{
+						Header: dnsmessage.ResourceHeader{
+							Name:   n,
+							Type:   dnsmessage.TypeSRV,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.SRVResource{
+							Target: dnsmessage.MustNewName("good.golang.org."),
+						},
+					},
 				)
 			case dnsmessage.TypeMX:
 				r.Answers = append(r.Answers,
@@ -1860,6 +1871,17 @@
 							MX: dnsmessage.MustNewName("<html>.golang.org."),
 						},
 					},
+					dnsmessage.Resource{
+						Header: dnsmessage.ResourceHeader{
+							Name:   dnsmessage.MustNewName("good.golang.org."),
+							Type:   dnsmessage.TypeMX,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.MXResource{
+							MX: dnsmessage.MustNewName("good.golang.org."),
+						},
+					},
 				)
 			case dnsmessage.TypeNS:
 				r.Answers = append(r.Answers,
@@ -1874,6 +1896,17 @@
 							NS: dnsmessage.MustNewName("<html>.golang.org."),
 						},
 					},
+					dnsmessage.Resource{
+						Header: dnsmessage.ResourceHeader{
+							Name:   dnsmessage.MustNewName("good.golang.org."),
+							Type:   dnsmessage.TypeNS,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.NSResource{
+							NS: dnsmessage.MustNewName("good.golang.org."),
+						},
+					},
 				)
 			case dnsmessage.TypePTR:
 				r.Answers = append(r.Answers,
@@ -1888,6 +1921,17 @@
 							PTR: dnsmessage.MustNewName("<html>.golang.org."),
 						},
 					},
+					dnsmessage.Resource{
+						Header: dnsmessage.ResourceHeader{
+							Name:   dnsmessage.MustNewName("good.golang.org."),
+							Type:   dnsmessage.TypePTR,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.PTRResource{
+							PTR: dnsmessage.MustNewName("good.golang.org."),
+						},
+					},
 				)
 			}
 			return r, nil
@@ -1903,57 +1947,177 @@
 	defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
 	testHookHostsPath = "testdata/hosts"
 
-	_, err := r.LookupCNAME(context.Background(), "golang.org")
-	if expected := "lookup golang.org: CNAME target is invalid"; err == nil || err.Error() != expected {
-		t.Errorf("Resolver.LookupCNAME returned unexpected error, got %q, want %q", err, expected)
-	}
-	_, err = LookupCNAME("golang.org")
-	if expected := "lookup golang.org: CNAME target is invalid"; err == nil || err.Error() != expected {
-		t.Errorf("LookupCNAME returned unexpected error, got %q, want %q", err, expected)
+	tests := []struct {
+		name string
+		f    func(*testing.T)
+	}{
+		{
+			name: "CNAME",
+			f: func(t *testing.T) {
+				expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"}
+				_, err := r.LookupCNAME(context.Background(), "golang.org")
+				if err.Error() != expectedErr.Error() {
+					t.Fatalf("unexpected error: %s", err)
+				}
+				_, err = LookupCNAME("golang.org")
+				if err.Error() != expectedErr.Error() {
+					t.Fatalf("unexpected error: %s", err)
+				}
+			},
+		},
+		{
+			name: "SRV (bad record)",
+			f: func(t *testing.T) {
+				expected := []*SRV{
+					{
+						Target: "good.golang.org.",
+					},
+				}
+				expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"}
+				_, records, err := r.LookupSRV(context.Background(), "target", "tcp", "golang.org")
+				if err.Error() != expectedErr.Error() {
+					t.Fatalf("unexpected error: %s", err)
+				}
+				if !reflect.DeepEqual(records, expected) {
+					t.Error("Unexpected record set")
+				}
+				_, records, err = LookupSRV("target", "tcp", "golang.org")
+				if err.Error() != expectedErr.Error() {
+					t.Errorf("unexpected error: %s", err)
+				}
+				if !reflect.DeepEqual(records, expected) {
+					t.Error("Unexpected record set")
+				}
+			},
+		},
+		{
+			name: "SRV (bad header)",
+			f: func(t *testing.T) {
+				_, _, err := r.LookupSRV(context.Background(), "hdr", "tcp", "golang.org.")
+				if expected := "lookup golang.org.: SRV header name is invalid"; err == nil || err.Error() != expected {
+					t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err, expected)
+				}
+				_, _, err = LookupSRV("hdr", "tcp", "golang.org.")
+				if expected := "lookup golang.org.: SRV header name is invalid"; err == nil || err.Error() != expected {
+					t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err, expected)
+				}
+			},
+		},
+		{
+			name: "MX",
+			f: func(t *testing.T) {
+				expected := []*MX{
+					{
+						Host: "good.golang.org.",
+					},
+				}
+				expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"}
+				records, err := r.LookupMX(context.Background(), "golang.org")
+				if err.Error() != expectedErr.Error() {
+					t.Fatalf("unexpected error: %s", err)
+				}
+				if !reflect.DeepEqual(records, expected) {
+					t.Error("Unexpected record set")
+				}
+				records, err = LookupMX("golang.org")
+				if err.Error() != expectedErr.Error() {
+					t.Fatalf("unexpected error: %s", err)
+				}
+				if !reflect.DeepEqual(records, expected) {
+					t.Error("Unexpected record set")
+				}
+			},
+		},
+		{
+			name: "NS",
+			f: func(t *testing.T) {
+				expected := []*NS{
+					{
+						Host: "good.golang.org.",
+					},
+				}
+				expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "golang.org"}
+				records, err := r.LookupNS(context.Background(), "golang.org")
+				if err.Error() != expectedErr.Error() {
+					t.Fatalf("unexpected error: %s", err)
+				}
+				if !reflect.DeepEqual(records, expected) {
+					t.Error("Unexpected record set")
+				}
+				records, err = LookupNS("golang.org")
+				if err.Error() != expectedErr.Error() {
+					t.Fatalf("unexpected error: %s", err)
+				}
+				if !reflect.DeepEqual(records, expected) {
+					t.Error("Unexpected record set")
+				}
+			},
+		},
+		{
+			name: "Addr",
+			f: func(t *testing.T) {
+				expected := []string{"good.golang.org."}
+				expectedErr := &DNSError{Err: errMalformedDNSRecordsDetail, Name: "192.0.2.42"}
+				records, err := r.LookupAddr(context.Background(), "192.0.2.42")
+				if err.Error() != expectedErr.Error() {
+					t.Fatalf("unexpected error: %s", err)
+				}
+				if !reflect.DeepEqual(records, expected) {
+					t.Error("Unexpected record set")
+				}
+				records, err = LookupAddr("192.0.2.42")
+				if err.Error() != expectedErr.Error() {
+					t.Fatalf("unexpected error: %s", err)
+				}
+				if !reflect.DeepEqual(records, expected) {
+					t.Error("Unexpected record set")
+				}
+			},
+		},
 	}
 
-	_, _, err = r.LookupSRV(context.Background(), "target", "tcp", "golang.org")
-	if expected := "lookup golang.org: SRV target is invalid"; err == nil || err.Error() != expected {
-		t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err, expected)
-	}
-	_, _, err = LookupSRV("target", "tcp", "golang.org")
-	if expected := "lookup golang.org: SRV target is invalid"; err == nil || err.Error() != expected {
-		t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err, expected)
+	for _, tc := range tests {
+		t.Run(tc.name, tc.f)
 	}
 
-	_, _, err = r.LookupSRV(context.Background(), "hdr", "tcp", "golang.org")
-	if expected := "lookup golang.org: SRV header name is invalid"; err == nil || err.Error() != expected {
-		t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err, expected)
-	}
-	_, _, err = LookupSRV("hdr", "tcp", "golang.org")
-	if expected := "lookup golang.org: SRV header name is invalid"; err == nil || err.Error() != expected {
-		t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err, expected)
-	}
+}
 
-	_, err = r.LookupMX(context.Background(), "golang.org")
-	if expected := "lookup golang.org: MX target is invalid"; err == nil || err.Error() != expected {
-		t.Errorf("Resolver.LookupMX returned unexpected error, got %q, want %q", err, expected)
+func TestNullMX(t *testing.T) {
+	fake := fakeDNSServer{
+		rh: func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) {
+			r := dnsmessage.Message{
+				Header: dnsmessage.Header{
+					ID:       q.Header.ID,
+					Response: true,
+					RCode:    dnsmessage.RCodeSuccess,
+				},
+				Questions: q.Questions,
+				Answers: []dnsmessage.Resource{
+					{
+						Header: dnsmessage.ResourceHeader{
+							Name:  q.Questions[0].Name,
+							Type:  dnsmessage.TypeMX,
+							Class: dnsmessage.ClassINET,
+						},
+						Body: &dnsmessage.MXResource{
+							MX: dnsmessage.MustNewName("."),
+						},
+					},
+				},
+			}
+			return r, nil
+		},
 	}
-	_, err = LookupMX("golang.org")
-	if expected := "lookup golang.org: MX target is invalid"; err == nil || err.Error() != expected {
-		t.Errorf("LookupMX returned unexpected error, got %q, want %q", err, expected)
+	r := Resolver{PreferGo: true, Dial: fake.DialContext}
+	rrset, err := r.LookupMX(context.Background(), "golang.org")
+	if err != nil {
+		t.Fatalf("LookupMX: %v", err)
 	}
-
-	_, err = r.LookupNS(context.Background(), "golang.org")
-	if expected := "lookup golang.org: NS target is invalid"; err == nil || err.Error() != expected {
-		t.Errorf("Resolver.LookupNS returned unexpected error, got %q, want %q", err, expected)
-	}
-	_, err = LookupNS("golang.org")
-	if expected := "lookup golang.org: NS target is invalid"; err == nil || err.Error() != expected {
-		t.Errorf("LookupNS returned unexpected error, got %q, want %q", err, expected)
-	}
-
-	_, err = r.LookupAddr(context.Background(), "192.0.2.42")
-	if expected := "lookup 192.0.2.42: PTR target is invalid"; err == nil || err.Error() != expected {
-		t.Errorf("Resolver.LookupAddr returned unexpected error, got %q, want %q", err, expected)
-	}
-	_, err = LookupAddr("192.0.2.42")
-	if expected := "lookup 192.0.2.42: PTR target is invalid"; err == nil || err.Error() != expected {
-		t.Errorf("LookupAddr returned unexpected error, got %q, want %q", err, expected)
+	if want := []*MX{&MX{Host: "."}}; !reflect.DeepEqual(rrset, want) {
+		records := []string{}
+		for _, rr := range rrset {
+			records = append(records, fmt.Sprintf("%v", rr))
+		}
+		t.Errorf("records = [%v]; want [%v]", strings.Join(records, " "), want[0])
 	}
 }
diff --git a/src/net/http/httptest/server.go b/src/net/http/httptest/server.go
index a02a6d6..4f85ff5 100644
--- a/src/net/http/httptest/server.go
+++ b/src/net/http/httptest/server.go
@@ -14,7 +14,7 @@
 	"log"
 	"net"
 	"net/http"
-	"net/http/internal"
+	"net/http/internal/testcert"
 	"os"
 	"strings"
 	"sync"
@@ -144,7 +144,7 @@
 	if s.client == nil {
 		s.client = &http.Client{Transport: &http.Transport{}}
 	}
-	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+	cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
 	if err != nil {
 		panic(fmt.Sprintf("httptest: NewTLSServer: %v", err))
 	}
diff --git a/src/net/http/internal/testcert.go b/src/net/http/internal/testcert/testcert.go
similarity index 94%
rename from src/net/http/internal/testcert.go
rename to src/net/http/internal/testcert/testcert.go
index 2284a83..5f94704 100644
--- a/src/net/http/internal/testcert.go
+++ b/src/net/http/internal/testcert/testcert.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package internal
+// Package testcert contains a test-only localhost certificate.
+package testcert
 
 import "strings"
 
@@ -25,7 +26,7 @@
 fblo6RBxUQ==
 -----END CERTIFICATE-----`)
 
-// LocalhostKey is the private key for localhostCert.
+// LocalhostKey is the private key for LocalhostCert.
 var LocalhostKey = []byte(testingKey(`-----BEGIN RSA TESTING KEY-----
 MIICXgIBAAKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9
 SjY1bIw4iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZB
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
index c2f8811..6394da3 100644
--- a/src/net/http/serve_test.go
+++ b/src/net/http/serve_test.go
@@ -25,6 +25,7 @@
 	"net/http/httptest"
 	"net/http/httputil"
 	"net/http/internal"
+	"net/http/internal/testcert"
 	"net/url"
 	"os"
 	"os/exec"
@@ -1475,7 +1476,7 @@
 	defer afterTest(t)
 	defer SetTestHookServerServe(nil)
 
-	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+	cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -1599,7 +1600,7 @@
 }
 
 func TestAutomaticHTTP2_ListenAndServe(t *testing.T) {
-	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+	cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -1609,7 +1610,7 @@
 }
 
 func TestAutomaticHTTP2_ListenAndServe_GetCertificate(t *testing.T) {
-	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+	cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/src/net/http/server.go b/src/net/http/server.go
index 50fab45..5b113cf 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -333,7 +333,7 @@
 const bufferBeforeChunkingSize = 2048
 
 // chunkWriter writes to a response's conn buffer, and is the writer
-// wrapped by the response.bufw buffered writer.
+// wrapped by the response.w buffered writer.
 //
 // chunkWriter also is responsible for finalizing the Header, including
 // conditionally setting the Content-Type and setting a Content-Length
@@ -1529,12 +1529,12 @@
 // The Writers are wired together like:
 //
 // 1. *response (the ResponseWriter) ->
-// 2. (*response).w, a *bufio.Writer of bufferBeforeChunkingSize bytes
+// 2. (*response).w, a *bufio.Writer of bufferBeforeChunkingSize bytes ->
 // 3. chunkWriter.Writer (whose writeHeader finalizes Content-Length/Type)
-//    and which writes the chunk headers, if needed.
-// 4. conn.buf, a bufio.Writer of default (4kB) bytes, writing to ->
+//    and which writes the chunk headers, if needed ->
+// 4. conn.bufw, a *bufio.Writer of default (4kB) bytes, writing to ->
 // 5. checkConnErrorWriter{c}, which notes any non-nil error on Write
-//    and populates c.werr with it if so. but otherwise writes to:
+//    and populates c.werr with it if so, but otherwise writes to ->
 // 6. the rwc, the net.Conn.
 //
 // TODO(bradfitz): short-circuit some of the buffering when the
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
index 47cb992..309194e 100644
--- a/src/net/http/transport.go
+++ b/src/net/http/transport.go
@@ -427,6 +427,7 @@
 //
 // The environment values may be either a complete URL or a
 // "host[:port]", in which case the "http" scheme is assumed.
+// The schemes "http", "https", and "socks5" are supported.
 // An error is returned if the value is a different form.
 //
 // A nil URL and nil error are returned if no proxy is defined in the
diff --git a/src/net/http/transport_internal_test.go b/src/net/http/transport_internal_test.go
index 1097ffd..1cce272 100644
--- a/src/net/http/transport_internal_test.go
+++ b/src/net/http/transport_internal_test.go
@@ -12,7 +12,7 @@
 	"errors"
 	"io"
 	"net"
-	"net/http/internal"
+	"net/http/internal/testcert"
 	"strings"
 	"testing"
 )
@@ -191,7 +191,7 @@
 
 // Issue 25009
 func TestTransportBodyAltRewind(t *testing.T) {
-	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+	cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index dcaacec..690e0c2 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -30,7 +30,7 @@
 	"net/http/httptest"
 	"net/http/httptrace"
 	"net/http/httputil"
-	"net/http/internal"
+	"net/http/internal/testcert"
 	"net/textproto"
 	"net/url"
 	"os"
@@ -4299,7 +4299,7 @@
 
 // Issue 13839
 func TestNoCrashReturningTransportAltConn(t *testing.T) {
-	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+	cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/src/net/lookup.go b/src/net/lookup.go
index 02a4cdc..d350ef7 100644
--- a/src/net/lookup.go
+++ b/src/net/lookup.go
@@ -424,7 +424,7 @@
 		return "", err
 	}
 	if !isDomainName(cname) {
-		return "", &DNSError{Err: "CNAME target is invalid", Name: host}
+		return "", &DNSError{Err: errMalformedDNSRecordsDetail, Name: host}
 	}
 	return cname, nil
 }
@@ -440,7 +440,9 @@
 // and proto are empty strings, LookupSRV looks up name directly.
 //
 // The returned service names are validated to be properly
-// formatted presentation-format domain names.
+// formatted presentation-format domain names. If the response contains
+// invalid names, those records are filtered out and an error
+// will be returned alongside the the remaining results, if any.
 func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
 	return DefaultResolver.LookupSRV(context.Background(), service, proto, name)
 }
@@ -456,7 +458,9 @@
 // and proto are empty strings, LookupSRV looks up name directly.
 //
 // The returned service names are validated to be properly
-// formatted presentation-format domain names.
+// formatted presentation-format domain names. If the response contains
+// invalid names, those records are filtered out and an error
+// will be returned alongside the the remaining results, if any.
 func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) {
 	cname, addrs, err := r.lookupSRV(ctx, service, proto, name)
 	if err != nil {
@@ -465,21 +469,28 @@
 	if cname != "" && !isDomainName(cname) {
 		return "", nil, &DNSError{Err: "SRV header name is invalid", Name: name}
 	}
+	filteredAddrs := make([]*SRV, 0, len(addrs))
 	for _, addr := range addrs {
 		if addr == nil {
 			continue
 		}
 		if !isDomainName(addr.Target) {
-			return "", nil, &DNSError{Err: "SRV target is invalid", Name: name}
+			continue
 		}
+		filteredAddrs = append(filteredAddrs, addr)
 	}
-	return cname, addrs, nil
+	if len(addrs) != len(filteredAddrs) {
+		return cname, filteredAddrs, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name}
+	}
+	return cname, filteredAddrs, nil
 }
 
 // LookupMX returns the DNS MX records for the given domain name sorted by preference.
 //
 // The returned mail server names are validated to be properly
-// formatted presentation-format domain names.
+// formatted presentation-format domain names. If the response contains
+// invalid names, those records are filtered out and an error
+// will be returned alongside the the remaining results, if any.
 //
 // LookupMX uses context.Background internally; to specify the context, use
 // Resolver.LookupMX.
@@ -490,27 +501,38 @@
 // LookupMX returns the DNS MX records for the given domain name sorted by preference.
 //
 // The returned mail server names are validated to be properly
-// formatted presentation-format domain names.
+// formatted presentation-format domain names. If the response contains
+// invalid names, those records are filtered out and an error
+// will be returned alongside the the remaining results, if any.
 func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*MX, error) {
 	records, err := r.lookupMX(ctx, name)
 	if err != nil {
 		return nil, err
 	}
+	filteredMX := make([]*MX, 0, len(records))
 	for _, mx := range records {
 		if mx == nil {
 			continue
 		}
-		if !isDomainName(mx.Host) {
-			return nil, &DNSError{Err: "MX target is invalid", Name: name}
+		// Bypass the hostname validity check for targets which contain only a dot,
+		// as this is used to represent a 'Null' MX record.
+		if mx.Host != "." && !isDomainName(mx.Host) {
+			continue
 		}
+		filteredMX = append(filteredMX, mx)
 	}
-	return records, nil
+	if len(records) != len(filteredMX) {
+		return filteredMX, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name}
+	}
+	return filteredMX, nil
 }
 
 // LookupNS returns the DNS NS records for the given domain name.
 //
 // The returned name server names are validated to be properly
-// formatted presentation-format domain names.
+// formatted presentation-format domain names. If the response contains
+// invalid names, those records are filtered out and an error
+// will be returned alongside the the remaining results, if any.
 //
 // LookupNS uses context.Background internally; to specify the context, use
 // Resolver.LookupNS.
@@ -521,21 +543,28 @@
 // LookupNS returns the DNS NS records for the given domain name.
 //
 // The returned name server names are validated to be properly
-// formatted presentation-format domain names.
+// formatted presentation-format domain names. If the response contains
+// invalid names, those records are filtered out and an error
+// will be returned alongside the the remaining results, if any.
 func (r *Resolver) LookupNS(ctx context.Context, name string) ([]*NS, error) {
 	records, err := r.lookupNS(ctx, name)
 	if err != nil {
 		return nil, err
 	}
+	filteredNS := make([]*NS, 0, len(records))
 	for _, ns := range records {
 		if ns == nil {
 			continue
 		}
 		if !isDomainName(ns.Host) {
-			return nil, &DNSError{Err: "NS target is invalid", Name: name}
+			continue
 		}
+		filteredNS = append(filteredNS, ns)
 	}
-	return records, nil
+	if len(records) != len(filteredNS) {
+		return filteredNS, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name}
+	}
+	return filteredNS, nil
 }
 
 // LookupTXT returns the DNS TXT records for the given domain name.
@@ -555,7 +584,8 @@
 // of names mapping to that address.
 //
 // The returned names are validated to be properly formatted presentation-format
-// domain names.
+// domain names. If the response contains invalid names, those records are filtered
+// out and an error will be returned alongside the the remaining results, if any.
 //
 // When using the host C library resolver, at most one result will be
 // returned. To bypass the host resolver, use a custom Resolver.
@@ -570,16 +600,26 @@
 // of names mapping to that address.
 //
 // The returned names are validated to be properly formatted presentation-format
-// domain names.
+// domain names. If the response contains invalid names, those records are filtered
+// out and an error will be returned alongside the the remaining results, if any.
 func (r *Resolver) LookupAddr(ctx context.Context, addr string) ([]string, error) {
 	names, err := r.lookupAddr(ctx, addr)
 	if err != nil {
 		return nil, err
 	}
+	filteredNames := make([]string, 0, len(names))
 	for _, name := range names {
-		if !isDomainName(name) {
-			return nil, &DNSError{Err: "PTR target is invalid", Name: addr}
+		if isDomainName(name) {
+			filteredNames = append(filteredNames, name)
 		}
 	}
-	return names, nil
+	if len(names) != len(filteredNames) {
+		return filteredNames, &DNSError{Err: errMalformedDNSRecordsDetail, Name: addr}
+	}
+	return filteredNames, nil
 }
+
+// errMalformedDNSRecordsDetail is the DNSError detail which is returned when a Resolver.Lookup...
+// method recieves DNS records which contain invalid DNS names. This may be returned alongside
+// results which have had the malformed records filtered out.
+var errMalformedDNSRecordsDetail = "DNS response contained records which contain invalid names"
diff --git a/src/net/lookup_windows_test.go b/src/net/lookup_windows_test.go
index 62b61ed..aa95501 100644
--- a/src/net/lookup_windows_test.go
+++ b/src/net/lookup_windows_test.go
@@ -299,7 +299,7 @@
 	ptr = make([]string, 0, 10)
 	rx := regexp.MustCompile(`(?m)^Pinging\s+([a-zA-Z0-9.\-]+)\s+\[.*$`)
 	for _, ans := range rx.FindAllStringSubmatch(r, -1) {
-		ptr = append(ptr, ans[1]+".")
+		ptr = append(ptr, absDomainName([]byte(ans[1])))
 	}
 	return
 }
diff --git a/src/os/example_test.go b/src/os/example_test.go
index 1151e52..b24e63d 100644
--- a/src/os/example_test.go
+++ b/src/os/example_test.go
@@ -5,6 +5,7 @@
 package os_test
 
 import (
+	"errors"
 	"fmt"
 	"io/fs"
 	"log"
@@ -71,9 +72,9 @@
 	}
 }
 
-func ExampleIsNotExist() {
+func ExampleErrNotExist() {
 	filename := "a-nonexistent-file"
-	if _, err := os.Stat(filename); os.IsNotExist(err) {
+	if _, err := os.Stat(filename); errors.Is(err, fs.ErrNotExist) {
 		fmt.Println("file does not exist")
 	}
 	// Output:
diff --git a/src/os/fifo_test.go b/src/os/fifo_test.go
index 9b262f8..007ed29 100644
--- a/src/os/fifo_test.go
+++ b/src/os/fifo_test.go
@@ -26,9 +26,6 @@
 	switch runtime.GOOS {
 	case "android":
 		t.Skip("skipping on Android; mkfifo syscall not available")
-	case "openbsd":
-		// On OpenBSD 6.2 this test just hangs for some reason.
-		t.Skip("skipping on OpenBSD; issue 25877")
 	}
 
 	dir := t.TempDir()
diff --git a/src/os/signal/signal_test.go b/src/os/signal/signal_test.go
index cea6874..649854b 100644
--- a/src/os/signal/signal_test.go
+++ b/src/os/signal/signal_test.go
@@ -32,6 +32,11 @@
 // The current value is set based on flakes observed in the Go builders.
 var settleTime = 100 * time.Millisecond
 
+// fatalWaitingTime is an absurdly long time to wait for signals to be
+// delivered but, using it, we (hopefully) eliminate test flakes on the
+// build servers. See #46736 for discussion.
+var fatalWaitingTime = 30 * time.Second
+
 func init() {
 	if testenv.Builder() == "solaris-amd64-oraclerel" {
 		// The solaris-amd64-oraclerel builder has been observed to time out in
@@ -84,7 +89,7 @@
 	// General user code should filter out all unexpected signals instead of just
 	// SIGURG, but since os/signal is tightly coupled to the runtime it seems
 	// appropriate to be stricter here.
-	for time.Since(start) < settleTime {
+	for time.Since(start) < fatalWaitingTime {
 		select {
 		case s := <-c:
 			if s == sig {
@@ -97,7 +102,7 @@
 			timer.Reset(settleTime / 10)
 		}
 	}
-	t.Fatalf("timeout after %v waiting for %v", settleTime, sig)
+	t.Fatalf("timeout after %v waiting for %v", fatalWaitingTime, sig)
 }
 
 // quiesce waits until we can be reasonably confident that all pending signals
diff --git a/src/path/filepath/path_test.go b/src/path/filepath/path_test.go
index cd107b6..bc5509b 100644
--- a/src/path/filepath/path_test.go
+++ b/src/path/filepath/path_test.go
@@ -1469,11 +1469,16 @@
 	// Try different numbers of "..".
 	for _, i := range []int{c, c + 1, c + 2} {
 		check := strings.Join([]string{evalTmpDir, strings.Join(dd[:i], string(os.PathSeparator)), evalTmpDir[len(vol)+1:], "b", "file"}, string(os.PathSeparator))
-		if resolved, err := filepath.EvalSymlinks(check); err != nil {
+		resolved, err := filepath.EvalSymlinks(check)
+		switch {
+		case runtime.GOOS == "darwin" && errors.Is(err, fs.ErrNotExist):
+			// On darwin, the temp dir is sometimes cleaned up mid-test (issue 37910).
+			testenv.SkipFlaky(t, 37910)
+		case err != nil:
 			t.Errorf("EvalSymlinks(%q) failed: %v", check, err)
-		} else if !strings.HasSuffix(resolved, wantSuffix) {
+		case !strings.HasSuffix(resolved, wantSuffix):
 			t.Errorf("EvalSymlinks(%q) = %q does not end with %q", check, resolved, wantSuffix)
-		} else {
+		default:
 			t.Logf("EvalSymlinks(%q) = %q", check, resolved)
 		}
 	}
diff --git a/src/reflect/abi_test.go b/src/reflect/abi_test.go
index 1a2a48b..5a0130f 100644
--- a/src/reflect/abi_test.go
+++ b/src/reflect/abi_test.go
@@ -79,7 +79,34 @@
 		t.Errorf("bad method value call: got %#v, want %#v", r2, a2)
 	}
 	if s.Value != 3 {
-		t.Errorf("bad method value call: failed to set s.Value: got %d, want %d", s.Value, 1)
+		t.Errorf("bad method value call: failed to set s.Value: got %d, want %d", s.Value, 3)
+	}
+
+	s, i = makeMethodValue("ValueRegMethodSpillInt")
+	f3 := i.(func(StructFillRegs, int, MagicLastTypeNameForTestingRegisterABI) (StructFillRegs, int))
+	r3a, r3b := f3(a2, 42, MagicLastTypeNameForTestingRegisterABI{})
+	if r3a != a2 {
+		t.Errorf("bad method value call: got %#v, want %#v", r3a, a2)
+	}
+	if r3b != 42 {
+		t.Errorf("bad method value call: got %#v, want %#v", r3b, 42)
+	}
+	if s.Value != 4 {
+		t.Errorf("bad method value call: failed to set s.Value: got %d, want %d", s.Value, 4)
+	}
+
+	s, i = makeMethodValue("ValueRegMethodSpillPtr")
+	f4 := i.(func(StructFillRegs, *byte, MagicLastTypeNameForTestingRegisterABI) (StructFillRegs, *byte))
+	vb := byte(10)
+	r4a, r4b := f4(a2, &vb, MagicLastTypeNameForTestingRegisterABI{})
+	if r4a != a2 {
+		t.Errorf("bad method value call: got %#v, want %#v", r4a, a2)
+	}
+	if r4b != &vb {
+		t.Errorf("bad method value call: got %#v, want %#v", r4b, &vb)
+	}
+	if s.Value != 5 {
+		t.Errorf("bad method value call: failed to set s.Value: got %d, want %d", s.Value, 5)
 	}
 }
 
@@ -112,6 +139,20 @@
 	return s
 }
 
+// When called as a method value, i is passed on the stack.
+// When called as a method, i is passed in a register.
+func (m *StructWithMethods) ValueRegMethodSpillInt(s StructFillRegs, i int, _ MagicLastTypeNameForTestingRegisterABI) (StructFillRegs, int) {
+	m.Value = 4
+	return s, i
+}
+
+// When called as a method value, i is passed on the stack.
+// When called as a method, i is passed in a register.
+func (m *StructWithMethods) ValueRegMethodSpillPtr(s StructFillRegs, i *byte, _ MagicLastTypeNameForTestingRegisterABI) (StructFillRegs, *byte) {
+	m.Value = 5
+	return s, i
+}
+
 func TestReflectCallABI(t *testing.T) {
 	// Enable register-based reflect.Call and ensure we don't
 	// use potentially incorrect cached versions by clearing
diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go
index 17104ad..0db5e13 100644
--- a/src/reflect/all_test.go
+++ b/src/reflect/all_test.go
@@ -4371,7 +4371,7 @@
 	if !v.Type().ConvertibleTo(pt) {
 		t.Errorf("[]byte should be convertible to *[8]byte")
 	}
-	shouldPanic("reflect: cannot convert slice with length 4 to array pointer with length 8", func() {
+	shouldPanic("reflect: cannot convert slice with length 4 to pointer to array with length 8", func() {
 		_ = v.Convert(pt)
 	})
 }
diff --git a/src/reflect/type.go b/src/reflect/type.go
index 39414fc..f672a7a 100644
--- a/src/reflect/type.go
+++ b/src/reflect/type.go
@@ -107,10 +107,14 @@
 
 	// ConvertibleTo reports whether a value of the type is convertible to type u.
 	// Even if ConvertibleTo returns true, the conversion may still panic.
+	// For example, a slice of type []T is convertible to *[N]T,
+	// but the conversion will panic if its length is less than N.
 	ConvertibleTo(u Type) bool
 
 	// Comparable reports whether values of this type are comparable.
 	// Even if Comparable returns true, the comparison may still panic.
+	// For example, values of interface type are comparable,
+	// but the comparison will panic if their dynamic type is not comparable.
 	Comparable() bool
 
 	// Methods applicable only to some types, depending on Kind.
@@ -224,7 +228,7 @@
 // See https://golang.org/issue/4876 for more details.
 
 /*
- * These data structures are known to the compiler (../../cmd/internal/gc/reflect.go).
+ * These data structures are known to the compiler (../../cmd/internal/reflectdata/reflect.go).
  * A few are known to ../runtime/type.go to convey to debuggers.
  * They are also known to ../runtime/type.go.
  */
@@ -267,7 +271,7 @@
 // available in the memory directly following the rtype value.
 //
 // tflag values must be kept in sync with copies in:
-//	cmd/compile/internal/gc/reflect.go
+//	cmd/compile/internal/reflectdata/reflect.go
 //	cmd/link/internal/ld/decodesym.go
 //	runtime/type.go
 type tflag uint8
@@ -1906,7 +1910,7 @@
 
 	// Make a map type.
 	// Note: flag values must match those used in the TMAP case
-	// in ../cmd/compile/internal/gc/reflect.go:writeType.
+	// in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
 	var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil)
 	mt := **(**mapType)(unsafe.Pointer(&imap))
 	mt.str = resolveReflectName(newName(s, "", false))
@@ -2837,7 +2841,7 @@
 
 // typeptrdata returns the length in bytes of the prefix of t
 // containing pointer data. Anything after this offset is scalar data.
-// keep in sync with ../cmd/compile/internal/gc/reflect.go
+// keep in sync with ../cmd/compile/internal/reflectdata/reflect.go
 func typeptrdata(t *rtype) uintptr {
 	switch t.Kind() {
 	case Struct:
@@ -2861,7 +2865,7 @@
 	}
 }
 
-// See cmd/compile/internal/gc/reflect.go for derivation of constant.
+// See cmd/compile/internal/reflectdata/reflect.go for derivation of constant.
 const maxPtrmaskBytes = 2048
 
 // ArrayOf returns the array type with the given length and element type.
diff --git a/src/reflect/value.go b/src/reflect/value.go
index 418dff7..9dce251 100644
--- a/src/reflect/value.go
+++ b/src/reflect/value.go
@@ -952,25 +952,47 @@
 			continue
 		}
 
-		// There are three cases to handle in translating each
+		// There are four cases to handle in translating each
 		// argument:
 		// 1. Stack -> stack translation.
-		// 2. Registers -> stack translation.
-		// 3. Registers -> registers translation.
-		// The fourth cases can't happen, because a method value
-		// call uses strictly fewer registers than a method call.
+		// 2. Stack -> registers translation.
+		// 3. Registers -> stack translation.
+		// 4. Registers -> registers translation.
+		// TODO(mknyszek): Cases 2 and 3 below only work on little endian
+		// architectures. This is OK for now, but this needs to be fixed
+		// before supporting the register ABI on big endian architectures.
 
 		// If the value ABI passes the value on the stack,
 		// then the method ABI does too, because it has strictly
 		// fewer arguments. Simply copy between the two.
 		if vStep := valueSteps[0]; vStep.kind == abiStepStack {
 			mStep := methodSteps[0]
-			if mStep.kind != abiStepStack || vStep.size != mStep.size {
-				panic("method ABI and value ABI do not align")
+			// Handle stack -> stack translation.
+			if mStep.kind == abiStepStack {
+				if vStep.size != mStep.size {
+					panic("method ABI and value ABI do not align")
+				}
+				typedmemmove(t,
+					add(methodFrame, mStep.stkOff, "precomputed stack offset"),
+					add(valueFrame, vStep.stkOff, "precomputed stack offset"))
+				continue
 			}
-			typedmemmove(t,
-				add(methodFrame, mStep.stkOff, "precomputed stack offset"),
-				add(valueFrame, vStep.stkOff, "precomputed stack offset"))
+			// Handle stack -> register translation.
+			for _, mStep := range methodSteps {
+				from := add(valueFrame, vStep.stkOff+mStep.offset, "precomputed stack offset")
+				switch mStep.kind {
+				case abiStepPointer:
+					// Do the pointer copy directly so we get a write barrier.
+					methodRegs.Ptrs[mStep.ireg] = *(*unsafe.Pointer)(from)
+					fallthrough // We need to make sure this ends up in Ints, too.
+				case abiStepIntReg:
+					memmove(unsafe.Pointer(&methodRegs.Ints[mStep.ireg]), from, mStep.size)
+				case abiStepFloatReg:
+					memmove(unsafe.Pointer(&methodRegs.Floats[mStep.freg]), from, mStep.size)
+				default:
+					panic("unexpected method step")
+				}
+			}
 			continue
 		}
 		// Handle register -> stack translation.
@@ -1359,10 +1381,16 @@
 	return packEface(v)
 }
 
-// InterfaceData returns the interface v's value as a uintptr pair.
+// InterfaceData returns a pair of unspecified uintptr values.
 // It panics if v's Kind is not Interface.
+//
+// In earlier versions of Go, this function returned the interface's
+// value as a uintptr pair. As of Go 1.4, the implementation of
+// interface values precludes any defined use of InterfaceData.
+//
+// Deprecated: The memory representation of interface values is not
+// compatible with InterfaceData.
 func (v Value) InterfaceData() [2]uintptr {
-	// TODO: deprecate this
 	v.mustBe(Interface)
 	// We treat this as a read operation, so we allow
 	// it even for unexported data, because the caller
@@ -3045,7 +3073,7 @@
 	n := t.Elem().Len()
 	h := (*unsafeheader.Slice)(v.ptr)
 	if n > h.Len {
-		panic("reflect: cannot convert slice with length " + itoa.Itoa(h.Len) + " to array pointer with length " + itoa.Itoa(n))
+		panic("reflect: cannot convert slice with length " + itoa.Itoa(h.Len) + " to pointer to array with length " + itoa.Itoa(n))
 	}
 	return Value{t.common(), h.Data, v.flag&^(flagIndir|flagAddr|flagKindMask) | flag(Ptr)}
 }
diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go
index 0e287d0..8ffb48a 100644
--- a/src/runtime/cgocall.go
+++ b/src/runtime/cgocall.go
@@ -110,6 +110,8 @@
 	return as.retval
 }
 
+var ncgocall uint64 // number of cgo calls in total for dead m
+
 // Call from Go to C.
 //
 // This must be nosplit because it's used for syscalls on some
diff --git a/src/runtime/checkptr.go b/src/runtime/checkptr.go
index 59891a06..d429508 100644
--- a/src/runtime/checkptr.go
+++ b/src/runtime/checkptr.go
@@ -16,11 +16,30 @@
 	}
 
 	// Check that (*[n]elem)(p) doesn't straddle multiple heap objects.
-	if size := n * elem.size; size > 1 && checkptrBase(p) != checkptrBase(add(p, size-1)) {
+	// TODO(mdempsky): Fix #46938 so we don't need to worry about overflow here.
+	if checkptrStraddles(p, n*elem.size) {
 		throw("checkptr: converted pointer straddles multiple allocations")
 	}
 }
 
+// checkptrStraddles reports whether the first size-bytes of memory
+// addressed by ptr is known to straddle more than one Go allocation.
+func checkptrStraddles(ptr unsafe.Pointer, size uintptr) bool {
+	if size <= 1 {
+		return false
+	}
+
+	end := add(ptr, size-1)
+	if uintptr(end) < uintptr(ptr) {
+		return true
+	}
+
+	// TODO(mdempsky): Detect when [ptr, end] contains Go allocations,
+	// but neither ptr nor end point into one themselves.
+
+	return checkptrBase(ptr) != checkptrBase(end)
+}
+
 func checkptrArithmetic(p unsafe.Pointer, originals []unsafe.Pointer) {
 	if 0 < uintptr(p) && uintptr(p) < minLegalPointer {
 		throw("checkptr: pointer arithmetic computed bad pointer value")
diff --git a/src/runtime/checkptr_test.go b/src/runtime/checkptr_test.go
index 194cc12..2a5c364 100644
--- a/src/runtime/checkptr_test.go
+++ b/src/runtime/checkptr_test.go
@@ -30,6 +30,8 @@
 		{"CheckPtrArithmetic2", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"},
 		{"CheckPtrSize", "fatal error: checkptr: converted pointer straddles multiple allocations\n"},
 		{"CheckPtrSmall", "fatal error: checkptr: pointer arithmetic computed bad pointer value\n"},
+		{"CheckPtrSliceOK", ""},
+		{"CheckPtrSliceFail", "fatal error: checkptr: unsafe.Slice result straddles multiple allocations\n"},
 	}
 
 	for _, tc := range testCases {
diff --git a/src/runtime/debug.go b/src/runtime/debug.go
index f411b22..82deefa 100644
--- a/src/runtime/debug.go
+++ b/src/runtime/debug.go
@@ -45,7 +45,7 @@
 
 // NumCgoCall returns the number of cgo calls made by the current process.
 func NumCgoCall() int64 {
-	var n int64
+	var n = int64(atomic.Load64(&ncgocall))
 	for mp := (*m)(atomic.Loadp(unsafe.Pointer(&allm))); mp != nil; mp = mp.alllink {
 		n += int64(mp.ncgocall)
 	}
diff --git a/src/runtime/example_test.go b/src/runtime/example_test.go
index e4912a5..dcb8f77 100644
--- a/src/runtime/example_test.go
+++ b/src/runtime/example_test.go
@@ -12,12 +12,15 @@
 
 func ExampleFrames() {
 	c := func() {
-		// Ask runtime.Callers for up to 10 pcs, including runtime.Callers itself.
+		// Ask runtime.Callers for up to 10 PCs, including runtime.Callers itself.
 		pc := make([]uintptr, 10)
 		n := runtime.Callers(0, pc)
 		if n == 0 {
-			// No pcs available. Stop now.
-			// This can happen if the first argument to runtime.Callers is large.
+			// No PCs available. This can happen if the first argument to
+			// runtime.Callers is large.
+			//
+			// Return now to avoid processing the zero Frame that would
+			// otherwise be returned by frames.Next below.
 			return
 		}
 
@@ -25,9 +28,12 @@
 		frames := runtime.CallersFrames(pc)
 
 		// Loop to get frames.
-		// A fixed number of pcs can expand to an indefinite number of Frames.
+		// A fixed number of PCs can expand to an indefinite number of Frames.
 		for {
 			frame, more := frames.Next()
+
+			// Process this frame.
+			//
 			// To keep this example's output stable
 			// even if there are changes in the testing package,
 			// stop unwinding when we leave package runtime.
@@ -35,6 +41,8 @@
 				break
 			}
 			fmt.Printf("- more:%v | %s\n", more, frame.Function)
+
+			// Check whether there are more frames to process after this one.
 			if !more {
 				break
 			}
diff --git a/src/runtime/internal/atomic/atomic_386.s b/src/runtime/internal/atomic/atomic_386.s
index 37318e0..724d515 100644
--- a/src/runtime/internal/atomic/atomic_386.s
+++ b/src/runtime/internal/atomic/atomic_386.s
@@ -65,7 +65,7 @@
 
 // bool ·Cas64(uint64 *val, uint64 old, uint64 new)
 // Atomically:
-//	if(*val == *old){
+//	if(*val == old){
 //		*val = new;
 //		return 1;
 //	} else {
diff --git a/src/runtime/internal/atomic/atomic_amd64.s b/src/runtime/internal/atomic/atomic_amd64.s
index 57cd59d..d21514b 100644
--- a/src/runtime/internal/atomic/atomic_amd64.s
+++ b/src/runtime/internal/atomic/atomic_amd64.s
@@ -37,7 +37,7 @@
 
 // bool	·Cas64(uint64 *val, uint64 old, uint64 new)
 // Atomically:
-//	if(*val == *old){
+//	if(*val == old){
 //		*val = new;
 //		return 1;
 //	} else {
diff --git a/src/runtime/internal/atomic/atomic_arm64.s b/src/runtime/internal/atomic/atomic_arm64.s
index e9467af..5f77d92 100644
--- a/src/runtime/internal/atomic/atomic_arm64.s
+++ b/src/runtime/internal/atomic/atomic_arm64.s
@@ -192,7 +192,7 @@
 
 // bool ·Cas64(uint64 *ptr, uint64 old, uint64 new)
 // Atomically:
-//      if(*val == *old){
+//      if(*val == old){
 //              *val = new;
 //              return 1;
 //      } else {
diff --git a/src/runtime/internal/atomic/atomic_mips64x.s b/src/runtime/internal/atomic/atomic_mips64x.s
index fba668f..fedfc4a 100644
--- a/src/runtime/internal/atomic/atomic_mips64x.s
+++ b/src/runtime/internal/atomic/atomic_mips64x.s
@@ -37,7 +37,7 @@
 
 // bool	cas64(uint64 *ptr, uint64 old, uint64 new)
 // Atomically:
-//	if(*val == *old){
+//	if(*val == old){
 //		*val = new;
 //		return 1;
 //	} else {
diff --git a/src/runtime/internal/atomic/atomic_ppc64x.s b/src/runtime/internal/atomic/atomic_ppc64x.s
index dca26cb..226b3b6 100644
--- a/src/runtime/internal/atomic/atomic_ppc64x.s
+++ b/src/runtime/internal/atomic/atomic_ppc64x.s
@@ -107,7 +107,7 @@
 
 // bool	·Cas64(uint64 *ptr, uint64 old, uint64 new)
 // Atomically:
-//	if(*val == *old){
+//	if(*val == old){
 //		*val = new;
 //		return 1;
 //	} else {
diff --git a/src/runtime/internal/atomic/atomic_riscv64.s b/src/runtime/internal/atomic/atomic_riscv64.s
index ec05302..21d5adc 100644
--- a/src/runtime/internal/atomic/atomic_riscv64.s
+++ b/src/runtime/internal/atomic/atomic_riscv64.s
@@ -30,8 +30,9 @@
 
 #include "textflag.h"
 
+// func Cas(ptr *uint64, old, new uint64) bool
 // Atomically:
-//      if(*val == *old){
+//      if(*val == old){
 //              *val = new;
 //              return 1;
 //      } else {
diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go
index 0013935..079be10 100644
--- a/src/runtime/os_darwin.go
+++ b/src/runtime/os_darwin.go
@@ -118,10 +118,15 @@
 
 // sigNoteSleep waits for a note created by sigNoteSetup to be woken.
 func sigNoteSleep(*note) {
-	entersyscallblock()
-	var b byte
-	read(sigNoteRead, unsafe.Pointer(&b), 1)
-	exitsyscall()
+	for {
+		var b byte
+		entersyscallblock()
+		n := read(sigNoteRead, unsafe.Pointer(&b), 1)
+		exitsyscall()
+		if n != -_EINTR {
+			return
+		}
+	}
 }
 
 // BSD interface for threading.
diff --git a/src/runtime/pprof/mprof_test.go b/src/runtime/pprof/mprof_test.go
index 3ef40d3..b4680fb 100644
--- a/src/runtime/pprof/mprof_test.go
+++ b/src/runtime/pprof/mprof_test.go
@@ -86,6 +86,17 @@
 
 	runtime.GC() // materialize stats
 
+	// TODO(mknyszek): Fix #45315 and remove this extra call.
+	//
+	// Unfortunately, it's possible for the sweep termination condition
+	// to flap, so with just one runtime.GC call, a freed object could be
+	// missed, leading this test to fail. A second call reduces the chance
+	// of this happening to zero, because sweeping actually has to finish
+	// to move on to the next GC, during which nothing will happen.
+	//
+	// See #46500 for more details.
+	runtime.GC()
+
 	memoryProfilerRun++
 
 	tests := []struct {
diff --git a/src/runtime/pprof/pprof_test.go b/src/runtime/pprof/pprof_test.go
index 0a442f9..cba6faf 100644
--- a/src/runtime/pprof/pprof_test.go
+++ b/src/runtime/pprof/pprof_test.go
@@ -264,6 +264,27 @@
 	return p
 }
 
+func cpuProfilingBroken() bool {
+	switch runtime.GOOS {
+	case "plan9":
+		// Profiling unimplemented.
+		return true
+	case "aix":
+		// See https://golang.org/issue/45170.
+		return true
+	case "ios", "dragonfly", "netbsd", "illumos", "solaris":
+		// See https://golang.org/issue/13841.
+		return true
+	case "openbsd":
+		if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
+			// See https://golang.org/issue/13841.
+			return true
+		}
+	}
+
+	return false
+}
+
 // testCPUProfile runs f under the CPU profiler, checking for some conditions specified by need,
 // as interpreted by matches, and returns the parsed profile.
 func testCPUProfile(t *testing.T, matches matchFunc, need []string, avoid []string, f func(dur time.Duration)) *profile.Profile {
@@ -279,16 +300,7 @@
 		t.Skip("skipping on plan9")
 	}
 
-	broken := false
-	switch runtime.GOOS {
-	// See https://golang.org/issue/45170 for AIX.
-	case "ios", "dragonfly", "netbsd", "illumos", "solaris", "aix":
-		broken = true
-	case "openbsd":
-		if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
-			broken = true
-		}
-	}
+	broken := cpuProfilingBroken()
 
 	maxDuration := 5 * time.Second
 	if testing.Short() && broken {
@@ -623,7 +635,7 @@
 
 //go:noinline
 func growstack(n int) {
-	var buf [8 << 16]byte
+	var buf [8 << 18]byte
 	use(buf)
 	if n > 0 {
 		growstack(n - 1)
@@ -631,7 +643,7 @@
 }
 
 //go:noinline
-func use(x [8 << 16]byte) {}
+func use(x [8 << 18]byte) {}
 
 func TestBlockProfile(t *testing.T) {
 	type TestCase struct {
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index ed556d5..81758ac 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -529,8 +529,8 @@
 	allglock mutex
 	allgs    []*g
 
-	// allglen and allgptr are atomic variables that contain len(allg) and
-	// &allg[0] respectively. Proper ordering depends on totally-ordered
+	// allglen and allgptr are atomic variables that contain len(allgs) and
+	// &allgs[0] respectively. Proper ordering depends on totally-ordered
 	// loads and stores. Writes are protected by allglock.
 	//
 	// allgptr is updated before allglen. Readers should read allglen
@@ -1522,6 +1522,8 @@
 	}
 	unlock(&sched.lock)
 
+	atomic.Xadd64(&ncgocall, int64(m.ncgocall))
+
 	// Release the P.
 	handoffp(releasep())
 	// After this point we must not have write barriers.
diff --git a/src/runtime/race/syso_test.go b/src/runtime/race/syso_test.go
index cbce5a8..f509573 100644
--- a/src/runtime/race/syso_test.go
+++ b/src/runtime/race/syso_test.go
@@ -2,14 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !android && !js && !ppc64le
-// +build !android,!js,!ppc64le
-
-// Note: we don't run on Android or ppc64 because if there is any non-race test
-// file in this package, the OS tries to link the .syso file into the
-// test (even when we're not in race mode), which fails. I'm not sure
-// why, but easiest to just punt - as long as a single builder runs
-// this test, we're good.
+//go:build race
+// +build race
 
 package race
 
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index 0e0eb0b..2a66826 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -895,7 +895,7 @@
 // layout of Itab known to compilers
 // allocated in non-garbage-collected memory
 // Needs to be in sync with
-// ../cmd/compile/internal/gc/reflect.go:/^func.WriteTabs.
+// ../cmd/compile/internal/reflectdata/reflect.go:/^func.WriteTabs.
 type itab struct {
 	inter *interfacetype
 	_type *_type
@@ -940,7 +940,7 @@
 
 // A _defer holds an entry on the list of deferred calls.
 // If you add a field here, add code to clear it in freedefer and deferProcStack
-// This struct must match the code in cmd/compile/internal/gc/reflect.go:deferstruct
+// This struct must match the code in cmd/compile/internal/reflectdata/reflect.go:deferstruct
 // and cmd/compile/internal/gc/ssa.go:(*state).call.
 // Some defers will be allocated on the stack and some on the heap.
 // All defers are logically part of the stack, so write barriers to
diff --git a/src/runtime/select.go b/src/runtime/select.go
index e72761b..06edb69 100644
--- a/src/runtime/select.go
+++ b/src/runtime/select.go
@@ -15,7 +15,7 @@
 
 // Select case descriptor.
 // Known to compiler.
-// Changes here must also be made in src/cmd/internal/gc/select.go's scasetype.
+// Changes here must also be made in src/cmd/compile/internal/walk/select.go's scasetype.
 type scase struct {
 	c    *hchan         // chan
 	elem unsafe.Pointer // data element
diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go
index f2e5269..6096760 100644
--- a/src/runtime/signal_unix.go
+++ b/src/runtime/signal_unix.go
@@ -280,6 +280,8 @@
 		it.it_value = it.it_interval
 		setitimer(_ITIMER_PROF, &it, nil)
 	} else {
+		setitimer(_ITIMER_PROF, &itimerval{}, nil)
+
 		// If the Go signal handler should be disabled by default,
 		// switch back to the signal handler that was installed
 		// when we enabled profiling. We don't try to handle the case
@@ -303,8 +305,6 @@
 				setsig(_SIGPROF, h)
 			}
 		}
-
-		setitimer(_ITIMER_PROF, &itimerval{}, nil)
 	}
 }
 
@@ -382,7 +382,7 @@
 //go:nosplit
 func sigFetchG(c *sigctxt) *g {
 	switch GOARCH {
-	case "arm", "arm64":
+	case "arm", "arm64", "ppc64", "ppc64le":
 		if !iscgo && inVDSOPage(c.sigpc()) {
 			// When using cgo, we save the g on TLS and load it from there
 			// in sigtramp. Just use that.
diff --git a/src/runtime/slice.go b/src/runtime/slice.go
index f9d4154..01cdcae 100644
--- a/src/runtime/slice.go
+++ b/src/runtime/slice.go
@@ -112,19 +112,37 @@
 	return makeslice(et, len, cap)
 }
 
-func unsafeslice(et *_type, len int) {
+func unsafeslice(et *_type, ptr unsafe.Pointer, len int) {
+	if len == 0 {
+		return
+	}
+
+	if ptr == nil {
+		panic(errorString("unsafe.Slice: ptr is nil and len is not zero"))
+	}
+
 	mem, overflow := math.MulUintptr(et.size, uintptr(len))
 	if overflow || mem > maxAlloc || len < 0 {
 		panicunsafeslicelen()
 	}
 }
 
-func unsafeslice64(et *_type, len64 int64) {
+func unsafeslice64(et *_type, ptr unsafe.Pointer, len64 int64) {
 	len := int(len64)
 	if int64(len) != len64 {
 		panicunsafeslicelen()
 	}
-	unsafeslice(et, len)
+	unsafeslice(et, ptr, len)
+}
+
+func unsafeslicecheckptr(et *_type, ptr unsafe.Pointer, len64 int64) {
+	unsafeslice64(et, ptr, len64)
+
+	// Check that underlying array doesn't straddle multiple heap objects.
+	// unsafeslice64 has already checked for overflow.
+	if checkptrStraddles(ptr, uintptr(len64)*et.size) {
+		throw("checkptr: unsafe.Slice result straddles multiple allocations")
+	}
 }
 
 func panicunsafeslicelen() {
diff --git a/src/runtime/stack.go b/src/runtime/stack.go
index b21c9c9..6e0d157 100644
--- a/src/runtime/stack.go
+++ b/src/runtime/stack.go
@@ -1064,7 +1064,9 @@
 	// recheck the bounds on return.)
 	if f := findfunc(gp.sched.pc); f.valid() {
 		max := uintptr(funcMaxSPDelta(f))
-		for newsize-gp.sched.sp < max+_StackGuard {
+		needed := max + _StackGuard
+		used := gp.stack.hi - gp.sched.sp
+		for newsize-used < needed {
 			newsize *= 2
 		}
 	}
diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go
index 6b535dfc..999300a 100644
--- a/src/runtime/symtab.go
+++ b/src/runtime/symtab.go
@@ -68,8 +68,15 @@
 	return f
 }
 
-// Next returns frame information for the next caller.
-// If more is false, there are no more callers (the Frame value is valid).
+// Next returns a Frame representing the next call frame in the slice
+// of PC values. If it has already returned all call frames, Next
+// returns a zero Frame.
+//
+// The more result indicates whether the next call to Next will return
+// a valid Frame. It does not necessarily indicate whether this call
+// returned one.
+//
+// See the Frames example for idiomatic usage.
 func (ci *Frames) Next() (frame Frame, more bool) {
 	for len(ci.frames) < 2 {
 		// Find the next frame.
diff --git a/src/runtime/sys_linux_ppc64x.s b/src/runtime/sys_linux_ppc64x.s
index 05b5916..005fa4d 100644
--- a/src/runtime/sys_linux_ppc64x.s
+++ b/src/runtime/sys_linux_ppc64x.s
@@ -216,15 +216,45 @@
 	MOVD	(g_sched+gobuf_sp)(R7), R1	// Set SP to g0 stack
 
 noswitch:
-	SUB	$16, R1			// Space for results
-	RLDICR	$0, R1, $59, R1		// Align for C code
+	SUB	$16, R1                 // Space for results
+	RLDICR	$0, R1, $59, R1         // Align for C code
 	MOVD	R12, CTR
 	MOVD	R1, R4
-	BL	(CTR)			// Call from VDSO
-	MOVD	$0, R0			// Restore R0
-	MOVD	0(R1), R3		// sec
-	MOVD	8(R1), R5		// nsec
-	MOVD	R15, R1			// Restore SP
+
+	// Store g on gsignal's stack, so if we receive a signal
+	// during VDSO code we can find the g.
+	// If we don't have a signal stack, we won't receive signal,
+	// so don't bother saving g.
+	// When using cgo, we already saved g on TLS, also don't save
+	// g here.
+	// Also don't save g if we are already on the signal stack.
+	// We won't get a nested signal.
+	MOVBZ	runtime·iscgo(SB), R22
+	CMP	R22, $0
+	BNE	nosaveg
+	MOVD	m_gsignal(R21), R22	// g.m.gsignal
+	CMP	R22, $0
+	BEQ	nosaveg
+
+	CMP	g, R22
+	BEQ	nosaveg
+	MOVD	(g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
+	MOVD	g, (R22)
+
+	BL	(CTR)	// Call from VDSO
+
+	MOVD	$0, (R22)	// clear g slot, R22 is unchanged by C code
+
+	JMP	finish
+
+nosaveg:
+	BL	(CTR)	// Call from VDSO
+
+finish:
+	MOVD	$0, R0		// Restore R0
+	MOVD	0(R1), R3	// sec
+	MOVD	8(R1), R5	// nsec
+	MOVD	R15, R1		// Restore SP
 
 	// Restore vdsoPC, vdsoSP
 	// We don't worry about being signaled between the two stores.
@@ -236,7 +266,7 @@
 	MOVD	32(R1), R6
 	MOVD	R6, m_vdsoPC(R21)
 
-finish:
+return:
 	MOVD	R3, sec+0(FP)
 	MOVW	R5, nsec+8(FP)
 	RET
@@ -247,7 +277,7 @@
 	SYSCALL $SYS_clock_gettime
 	MOVD	32(R1), R3
 	MOVD	40(R1), R5
-	JMP	finish
+	JMP	return
 
 TEXT runtime·nanotime1(SB),NOSPLIT,$16-8
 	MOVD	$1, R3		// CLOCK_MONOTONIC
@@ -283,7 +313,37 @@
 	RLDICR	$0, R1, $59, R1		// Align for C code
 	MOVD	R12, CTR
 	MOVD	R1, R4
-	BL	(CTR)			// Call from VDSO
+
+	// Store g on gsignal's stack, so if we receive a signal
+	// during VDSO code we can find the g.
+	// If we don't have a signal stack, we won't receive signal,
+	// so don't bother saving g.
+	// When using cgo, we already saved g on TLS, also don't save
+	// g here.
+	// Also don't save g if we are already on the signal stack.
+	// We won't get a nested signal.
+	MOVBZ	runtime·iscgo(SB), R22
+	CMP	R22, $0
+	BNE	nosaveg
+	MOVD	m_gsignal(R21), R22	// g.m.gsignal
+	CMP	R22, $0
+	BEQ	nosaveg
+
+	CMP	g, R22
+	BEQ	nosaveg
+	MOVD	(g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
+	MOVD	g, (R22)
+
+	BL	(CTR)	// Call from VDSO
+
+	MOVD	$0, (R22)	// clear g slot, R22 is unchanged by C code
+
+	JMP	finish
+
+nosaveg:
+	BL	(CTR)	// Call from VDSO
+
+finish:
 	MOVD	$0, R0			// Restore R0
 	MOVD	0(R1), R3		// sec
 	MOVD	8(R1), R5		// nsec
@@ -299,7 +359,7 @@
 	MOVD	32(R1), R6
 	MOVD	R6, m_vdsoPC(R21)
 
-finish:
+return:
 	// sec is in R3, nsec in R5
 	// return nsec in R3
 	MOVD	$1000000000, R4
@@ -314,7 +374,7 @@
 	SYSCALL $SYS_clock_gettime
 	MOVD	32(R1), R3
 	MOVD	40(R1), R5
-	JMP	finish
+	JMP	return
 
 TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
 	MOVW	how+0(FP), R3
@@ -469,7 +529,7 @@
 	// this might be called in external code context,
 	// where g is not set.
 	MOVBZ	runtime·iscgo(SB), R6
-	CMP 	R6, $0
+	CMP	R6, $0
 	BEQ	2(PC)
 	BL	runtime·load_g(SB)
 
diff --git a/src/runtime/testdata/testprog/checkptr.go b/src/runtime/testdata/testprog/checkptr.go
index e0a2794..f76b64a 100644
--- a/src/runtime/testdata/testprog/checkptr.go
+++ b/src/runtime/testdata/testprog/checkptr.go
@@ -13,6 +13,8 @@
 	register("CheckPtrArithmetic2", CheckPtrArithmetic2)
 	register("CheckPtrSize", CheckPtrSize)
 	register("CheckPtrSmall", CheckPtrSmall)
+	register("CheckPtrSliceOK", CheckPtrSliceOK)
+	register("CheckPtrSliceFail", CheckPtrSliceFail)
 }
 
 func CheckPtrAlignmentNoPtr() {
@@ -49,3 +51,14 @@
 func CheckPtrSmall() {
 	sink2 = unsafe.Pointer(uintptr(1))
 }
+
+func CheckPtrSliceOK() {
+	p := new([4]int64)
+	sink2 = unsafe.Slice(&p[1], 3)
+}
+
+func CheckPtrSliceFail() {
+	p := new(int64)
+	sink2 = p
+	sink2 = unsafe.Slice(p, 100)
+}
diff --git a/src/runtime/testdata/testprogcgo/aprof.go b/src/runtime/testdata/testprogcgo/aprof.go
index aabca9e..44a15b0 100644
--- a/src/runtime/testdata/testprogcgo/aprof.go
+++ b/src/runtime/testdata/testprogcgo/aprof.go
@@ -10,7 +10,7 @@
 // The test fails when the function is the first C function.
 // The exported functions are the first C functions, so we use that.
 
-// extern void GoNop();
+// extern void CallGoNop();
 import "C"
 
 import (
@@ -38,7 +38,7 @@
 					break
 				}
 			}
-			C.GoNop()
+			C.CallGoNop()
 		}
 		c <- true
 	}()
diff --git a/src/runtime/testdata/testprogcgo/aprof_c.c b/src/runtime/testdata/testprogcgo/aprof_c.c
new file mode 100644
index 0000000..d588e13
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/aprof_c.c
@@ -0,0 +1,9 @@
+// Copyright 2021 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.
+
+#include "_cgo_export.h"
+
+void CallGoNop() {
+	GoNop();
+}
diff --git a/src/runtime/testdata/testprogcgo/bigstack1_windows.c b/src/runtime/testdata/testprogcgo/bigstack1_windows.c
new file mode 100644
index 0000000..551fb68
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/bigstack1_windows.c
@@ -0,0 +1,12 @@
+// Copyright 2021 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.
+
+// This is not in bigstack_windows.c because it needs to be part of
+// testprogcgo but is not part of the DLL built from bigstack_windows.c.
+
+#include "_cgo_export.h"
+
+void CallGoBigStack1(char* p) {
+	goBigStack1(p);
+}
diff --git a/src/runtime/testdata/testprogcgo/bigstack_windows.go b/src/runtime/testdata/testprogcgo/bigstack_windows.go
index f58fcf9..135b5fc 100644
--- a/src/runtime/testdata/testprogcgo/bigstack_windows.go
+++ b/src/runtime/testdata/testprogcgo/bigstack_windows.go
@@ -6,7 +6,7 @@
 
 /*
 typedef void callback(char*);
-extern void goBigStack1(char*);
+extern void CallGoBigStack1(char*);
 extern void bigStack(callback*);
 */
 import "C"
@@ -18,7 +18,7 @@
 func BigStack() {
 	// Create a large thread stack and call back into Go to test
 	// if Go correctly determines the stack bounds.
-	C.bigStack((*C.callback)(C.goBigStack1))
+	C.bigStack((*C.callback)(C.CallGoBigStack1))
 }
 
 //export goBigStack1
diff --git a/src/runtime/type.go b/src/runtime/type.go
index 335fc57..4039273 100644
--- a/src/runtime/type.go
+++ b/src/runtime/type.go
@@ -11,7 +11,7 @@
 // tflag is documented in reflect/type.go.
 //
 // tflag values must be kept in sync with copies in:
-//	cmd/compile/internal/gc/reflect.go
+//	cmd/compile/internal/reflectdata/reflect.go
 //	cmd/link/internal/ld/decodesym.go
 //	reflect/type.go
 //      internal/reflectlite/type.go
@@ -25,7 +25,7 @@
 )
 
 // Needs to be in sync with ../cmd/link/internal/ld/decodesym.go:/^func.commonsize,
-// ../cmd/compile/internal/gc/reflect.go:/^func.dcommontype and
+// ../cmd/compile/internal/reflectdata/reflect.go:/^func.dcommontype and
 // ../reflect/type.go:/^type.rtype.
 // ../internal/reflectlite/type.go:/^type.rtype.
 type _type struct {
@@ -383,7 +383,7 @@
 }
 
 // Note: flag values must match those used in the TMAP case
-// in ../cmd/compile/internal/gc/reflect.go:writeType.
+// in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
 func (mt *maptype) indirectkey() bool { // store ptr to key instead of key itself
 	return mt.flags&1 != 0
 }
diff --git a/src/syscall/exec_linux_test.go b/src/syscall/exec_linux_test.go
index 7d89eaa..85b59ad 100644
--- a/src/syscall/exec_linux_test.go
+++ b/src/syscall/exec_linux_test.go
@@ -318,6 +318,7 @@
 		"uid=0(root) gid=0(root) groups=0(root),65534",
 		"uid=0(root) gid=0(root) groups=0(root),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody)", // Alpine; see https://golang.org/issue/19938
 		"uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023",                                                                               // CentOS with SELinux context, see https://golang.org/issue/34547
+		"uid=0(root) gid=0(root) groups=0(root),65534(nobody) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023",                                                                 // Fedora with SElinux context, see https://golang.org/issue/46752
 	}
 	for _, e := range expected {
 		if strOut == e {
diff --git a/src/syscall/syscall_windows_test.go b/src/syscall/syscall_windows_test.go
index ea8fa19..194c878 100644
--- a/src/syscall/syscall_windows_test.go
+++ b/src/syscall/syscall_windows_test.go
@@ -78,6 +78,7 @@
 
 func TestStdioAreInheritable(t *testing.T) {
 	testenv.MustHaveGoBuild(t)
+	testenv.MustHaveCGO(t)
 	testenv.MustHaveExecPath(t, "gcc")
 
 	tmpdir := t.TempDir()
@@ -110,18 +111,28 @@
 		t.Fatalf("failed to build go library: %s\n%s", err, out)
 	}
 
-	// run powershell script
-	psscript := fmt.Sprintf(`
-hostname;
-$signature = " [DllImport("%q")] public static extern void HelloWorld(); ";
-Add-Type -MemberDefinition $signature -Name World -Namespace Hello;
-[Hello.World]::HelloWorld();
-hostname;
-`, dll)
-	psscript = strings.ReplaceAll(psscript, "\n", "")
-	out, err = exec.Command("powershell", "-Command", psscript).CombinedOutput()
+	// build c exe
+	const exetext = `
+#include <stdlib.h>
+#include <windows.h>
+int main(int argc, char *argv[])
+{
+	system("hostname");
+	((void(*)(void))GetProcAddress(LoadLibraryA(%q), "HelloWorld"))();
+	system("hostname");
+	return 0;
+}
+`
+	exe := filepath.Join(tmpdir, "helloworld.exe")
+	cmd = exec.Command("gcc", "-o", exe, "-xc", "-")
+	cmd.Stdin = strings.NewReader(fmt.Sprintf(exetext, dll))
+	out, err = testenv.CleanCmdEnv(cmd).CombinedOutput()
 	if err != nil {
-		t.Fatalf("Powershell command failed: %v: %v", err, string(out))
+		t.Fatalf("failed to build c executable: %s\n%s", err, out)
+	}
+	out, err = exec.Command(exe).CombinedOutput()
+	if err != nil {
+		t.Fatalf("c program execution failed: %v: %v", err, string(out))
 	}
 
 	hostname, err := os.Hostname()
@@ -133,6 +144,6 @@
 	have = strings.ReplaceAll(have, "\r", "")
 	want := fmt.Sprintf("%sHello World%s", hostname, hostname)
 	if have != want {
-		t.Fatalf("Powershell command output is wrong: got %q, want %q", have, want)
+		t.Fatalf("c program output is wrong: got %q, want %q", have, want)
 	}
 }
diff --git a/src/testing/testing.go b/src/testing/testing.go
index 85a7fec..eeee0aa 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -252,6 +252,8 @@
 	"sync"
 	"sync/atomic"
 	"time"
+	"unicode"
+	"unicode/utf8"
 )
 
 var initRan bool
@@ -642,6 +644,7 @@
 	Log(args ...interface{})
 	Logf(format string, args ...interface{})
 	Name() string
+	Setenv(key, value string)
 	Skip(args ...interface{})
 	SkipNow()
 	Skipf(format string, args ...interface{})
@@ -908,11 +911,6 @@
 	c.cleanups = append(c.cleanups, fn)
 }
 
-var tempDirReplacer struct {
-	sync.Once
-	r *strings.Replacer
-}
-
 // TempDir returns a temporary directory for the test to use.
 // The directory is automatically removed by Cleanup when the test and
 // all its subtests complete.
@@ -936,13 +934,26 @@
 	if nonExistent {
 		c.Helper()
 
-		// os.MkdirTemp doesn't like path separators in its pattern,
-		// so mangle the name to accommodate subtests.
-		tempDirReplacer.Do(func() {
-			tempDirReplacer.r = strings.NewReplacer("/", "_", "\\", "_", ":", "_")
-		})
-		pattern := tempDirReplacer.r.Replace(c.Name())
-
+		// Drop unusual characters (such as path separators or
+		// characters interacting with globs) from the directory name to
+		// avoid surprising os.MkdirTemp behavior.
+		mapper := func(r rune) rune {
+			if r < utf8.RuneSelf {
+				const allowed = "!#$%&()+,-.=@^_{}~ "
+				if '0' <= r && r <= '9' ||
+					'a' <= r && r <= 'z' ||
+					'A' <= r && r <= 'Z' {
+					return r
+				}
+				if strings.ContainsRune(allowed, r) {
+					return r
+				}
+			} else if unicode.IsLetter(r) || unicode.IsNumber(r) {
+				return r
+			}
+			return -1
+		}
+		pattern := strings.Map(mapper, c.Name())
 		c.tempDir, c.tempDirErr = os.MkdirTemp("", pattern)
 		if c.tempDirErr == nil {
 			c.Cleanup(func() {
diff --git a/src/testing/testing_test.go b/src/testing/testing_test.go
index 55a4df4..08ae239 100644
--- a/src/testing/testing_test.go
+++ b/src/testing/testing_test.go
@@ -58,6 +58,9 @@
 	t.Run("test:subtest", testTempDir)
 	t.Run("test/..", testTempDir)
 	t.Run("../test", testTempDir)
+	t.Run("test[]", testTempDir)
+	t.Run("test*", testTempDir)
+	t.Run("äöüéè", testTempDir)
 }
 
 func testTempDir(t *testing.T) {
@@ -74,7 +77,7 @@
 			if err != nil {
 				t.Fatal(err)
 			}
-			t.Errorf("directory %q stil exists: %v, isDir=%v", dir, fi, fi.IsDir())
+			t.Errorf("directory %q still exists: %v, isDir=%v", dir, fi, fi.IsDir())
 		default:
 			if !t.Failed() {
 				t.Fatal("never received dir channel")
@@ -108,6 +111,11 @@
 	if len(files) > 0 {
 		t.Errorf("unexpected %d files in TempDir: %v", len(files), files)
 	}
+
+	glob := filepath.Join(dir, "*.txt")
+	if _, err := filepath.Glob(glob); err != nil {
+		t.Error(err)
+	}
 }
 
 func TestSetenv(t *testing.T) {
diff --git a/src/time/format.go b/src/time/format.go
index 6040ed5..bb173a2 100644
--- a/src/time/format.go
+++ b/src/time/format.go
@@ -751,8 +751,11 @@
 
 // These are borrowed from unicode/utf8 and strconv and replicate behavior in
 // that package, since we can't take a dependency on either.
-const runeSelf = 0x80
-const lowerhex = "0123456789abcdef"
+const (
+	lowerhex  = "0123456789abcdef"
+	runeSelf  = 0x80
+	runeError = '\uFFFD'
+)
 
 func quote(s string) string {
 	buf := make([]byte, 1, len(s)+2) // slice will be at least len(s) + quotes
@@ -765,7 +768,16 @@
 			// reproduce strconv.Quote's behavior with full fidelity but
 			// given how rarely we expect to hit these edge cases, speed and
 			// conciseness are better.
-			for j := 0; j < len(string(c)) && j < len(s); j++ {
+			var width int
+			if c == runeError {
+				width = 1
+				if i+2 < len(s) && s[i:i+3] == string(runeError) {
+					width = 3
+				}
+			} else {
+				width = len(string(c))
+			}
+			for j := 0; j < width; j++ {
 				buf = append(buf, `\x`...)
 				buf = append(buf, lowerhex[s[i+j]>>4])
 				buf = append(buf, lowerhex[s[i+j]&0xF])
diff --git a/src/time/time.go b/src/time/time.go
index cd756bb..1cf1e2b 100644
--- a/src/time/time.go
+++ b/src/time/time.go
@@ -1340,7 +1340,7 @@
 }
 
 // IsDST reports whether the time in the configured location is in Daylight Savings Time.
-func (t *Time) IsDST() bool {
+func (t Time) IsDST() bool {
 	_, _, _, _, isDST := t.loc.lookup(t.Unix())
 	return isDST
 }
diff --git a/src/time/time_test.go b/src/time/time_test.go
index f272bbd..cea5f2d 100644
--- a/src/time/time_test.go
+++ b/src/time/time_test.go
@@ -917,6 +917,11 @@
 	{".s", `".s"`},
 	{"+.s", `"+.s"`},
 	{"1d", `"1d"`},
+	{"\x85\x85", `"\x85\x85"`},
+	{"\xffff", `"\xffff"`},
+	{"hello \xffff world", `"hello \xffff world"`},
+	{"\uFFFD", `"\xef\xbf\xbd"`},                                             // utf8.RuneError
+	{"\uFFFD hello \uFFFD world", `"\xef\xbf\xbd hello \xef\xbf\xbd world"`}, // utf8.RuneError
 	// overflow
 	{"9223372036854775810ns", `"9223372036854775810ns"`},
 	{"9223372036854775808ns", `"9223372036854775808ns"`},
diff --git a/src/unsafe/unsafe.go b/src/unsafe/unsafe.go
index ecbd28c..16e3890 100644
--- a/src/unsafe/unsafe.go
+++ b/src/unsafe/unsafe.go
@@ -217,12 +217,17 @@
 func Add(ptr Pointer, len IntegerType) Pointer
 
 // The function Slice returns a slice whose underlying array starts at ptr
-// and whose length and capacity are len:
+// and whose length and capacity are len.
+// Slice(ptr, len) is equivalent to
 //
 //	(*[len]ArbitraryType)(unsafe.Pointer(ptr))[:]
 //
+// except that, as a special case, if ptr is nil and len is zero,
+// Slice returns nil.
+//
 // The len argument must be of integer type or an untyped constant.
 // A constant len argument must be non-negative and representable by a value of type int;
 // if it is an untyped constant it is given type int.
-// If ptr is nil or len is negative at run time, a run-time panic occurs.
+// At run time, if len is negative, or if ptr is nil and len is not zero,
+// a run-time panic occurs.
 func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType
diff --git a/test/declbad.go b/test/declbad.go
index 728eceb..b978652 100644
--- a/test/declbad.go
+++ b/test/declbad.go
@@ -23,13 +23,13 @@
 	{
 		// change of type for f
 		i, f, s := f3()
-		f, g, t := f3() // ERROR "redeclared|cannot assign|incompatible"
+		f, g, t := f3() // ERROR "redeclared|cannot assign|incompatible|cannot use"
 		_, _, _, _, _ = i, f, s, g, t
 	}
 	{
 		// change of type for i
 		i, f, s := f3()
-		j, i, t := f3() // ERROR "redeclared|cannot assign|incompatible"
+		j, i, t := f3() // ERROR "redeclared|cannot assign|incompatible|cannot use"
 		_, _, _, _, _ = i, f, s, j, t
 	}
 	{
diff --git a/test/fixedbugs/issue46720.go b/test/fixedbugs/issue46720.go
new file mode 100644
index 0000000..3b0151a
--- /dev/null
+++ b/test/fixedbugs/issue46720.go
@@ -0,0 +1,15 @@
+// compile
+
+// Copyright 2021 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() {
+	nonce := make([]byte, 24)
+	g((*[24]byte)(nonce))
+}
+
+//go:noinline
+func g(*[24]byte) {}
diff --git a/test/fixedbugs/issue46725.go b/test/fixedbugs/issue46725.go
new file mode 100644
index 0000000..29799c7
--- /dev/null
+++ b/test/fixedbugs/issue46725.go
@@ -0,0 +1,48 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "runtime"
+
+type T [4]int
+
+//go:noinline
+func g(x []*T) ([]*T, []*T) { return x, x }
+
+func main() {
+	const Jenny = 8675309
+	s := [10]*T{{Jenny}}
+
+	done := make(chan struct{})
+	runtime.SetFinalizer(s[0], func(p *T) { close(done) })
+
+	var h, _ interface{} = g(s[:])
+
+	if wait(done) {
+		panic("GC'd early")
+	}
+
+	if h.([]*T)[0][0] != Jenny {
+		panic("lost Jenny's number")
+	}
+
+	if !wait(done) {
+		panic("never GC'd")
+	}
+}
+
+func wait(done <-chan struct{}) bool {
+	for i := 0; i < 10; i++ {
+		runtime.GC()
+		select {
+		case <-done:
+			return true
+		default:
+		}
+	}
+	return false
+}
diff --git a/test/fixedbugs/issue46749.go b/test/fixedbugs/issue46749.go
new file mode 100644
index 0000000..63ed197
--- /dev/null
+++ b/test/fixedbugs/issue46749.go
@@ -0,0 +1,37 @@
+// errorcheck
+
+// Copyright 2021 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
+
+var s string
+var b bool
+var i int
+var iface interface{}
+
+var (
+	_ = "" + b   // ERROR "invalid operation.*mismatched types.*untyped string and bool"
+	_ = "" + i   // ERROR "invalid operation.*mismatched types.*untyped string and int"
+	_ = "" + nil // ERROR "invalid operation.*mismatched types.*untyped string and nil"
+)
+
+var (
+	_ = s + false // ERROR "invalid operation.*mismatched types.*string and untyped bool"
+	_ = s + 1     // ERROR "invalid operation.*mismatched types.*string and untyped int"
+	_ = s + nil   // ERROR "invalid operation.*mismatched types.*string and nil"
+)
+
+var (
+	_ = "" + false // ERROR "invalid operation.*mismatched types.*untyped string and untyped bool"
+	_ = "" + 1     // ERROR "invalid operation.*mismatched types.*untyped string and untyped int"
+)
+
+var (
+	_ = b + 1         // ERROR "invalid operation.*mismatched types.*bool and untyped int"
+	_ = i + false     // ERROR "invalid operation.*mismatched types.*int and untyped bool"
+	_ = iface + 1     // ERROR "invalid operation.*mismatched types.*interface {} and int"
+	_ = iface + 1.0   // ERROR "invalid operation.*mismatched types.*interface {} and float64"
+	_ = iface + false // ERROR "invalid operation.*mismatched types.*interface {} and bool"
+)
diff --git a/test/fixedbugs/issue46907.go b/test/fixedbugs/issue46907.go
new file mode 100644
index 0000000..bd82f4f
--- /dev/null
+++ b/test/fixedbugs/issue46907.go
@@ -0,0 +1,11 @@
+// compile
+
+// Copyright 2021 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(b []byte) []byte {
+	return (*[32]byte)(b[:32])[:]
+}
diff --git a/test/fixedbugs/issue46957.go b/test/fixedbugs/issue46957.go
new file mode 100644
index 0000000..f3ed3c3
--- /dev/null
+++ b/test/fixedbugs/issue46957.go
@@ -0,0 +1,13 @@
+// errorcheck
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func f(a int, b ...int) {}
+
+func main() {
+	f(nil...) // ERROR "not enough arguments in call to f$"
+}
diff --git a/test/fixedbugs/issue47087.dir/a.go b/test/fixedbugs/issue47087.dir/a.go
new file mode 100644
index 0000000..6093092
--- /dev/null
+++ b/test/fixedbugs/issue47087.dir/a.go
@@ -0,0 +1,9 @@
+// Copyright 2021 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 a
+
+func F() interface{} { return struct{ _ []int }{} }
+
+var X = F()
diff --git a/test/fixedbugs/issue47087.dir/b.go b/test/fixedbugs/issue47087.dir/b.go
new file mode 100644
index 0000000..8f96d25
--- /dev/null
+++ b/test/fixedbugs/issue47087.dir/b.go
@@ -0,0 +1,9 @@
+// Copyright 2021 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 b
+
+func F() interface{} { return struct{ _ []int }{} }
+
+var X = F()
diff --git a/test/fixedbugs/issue47087.dir/main.go b/test/fixedbugs/issue47087.dir/main.go
new file mode 100644
index 0000000..ccd0891
--- /dev/null
+++ b/test/fixedbugs/issue47087.dir/main.go
@@ -0,0 +1,19 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"a"
+	"b"
+)
+
+func main() {
+	if a.F() == b.F() {
+		panic("FAIL")
+	}
+	if a.X == b.X {
+		panic("FAIL")
+	}
+}
diff --git a/test/fixedbugs/issue47087.go b/test/fixedbugs/issue47087.go
new file mode 100644
index 0000000..40df49f
--- /dev/null
+++ b/test/fixedbugs/issue47087.go
@@ -0,0 +1,7 @@
+// rundir
+
+// Copyright 2021 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 ignored
diff --git a/test/run.go b/test/run.go
index 5e60de7..d7f5d02 100644
--- a/test/run.go
+++ b/test/run.go
@@ -2002,4 +2002,5 @@
 	"fixedbugs/issue7525c.go":  true, // types2 reports init cycle error on different line - ok otherwise
 	"fixedbugs/issue7525d.go":  true, // types2 reports init cycle error on different line - ok otherwise
 	"fixedbugs/issue7525e.go":  true, // types2 reports init cycle error on different line - ok otherwise
+	"fixedbugs/issue46749.go":  true, // types2 reports can not convert error instead of type mismatched
 }
diff --git a/test/unsafebuiltins.go b/test/unsafebuiltins.go
index c10f808..4c940aa 100644
--- a/test/unsafebuiltins.go
+++ b/test/unsafebuiltins.go
@@ -30,8 +30,11 @@
 		assert(len(s) == len(p))
 		assert(cap(s) == len(p))
 
-		// nil pointer
-		mustPanic(func() { _ = unsafe.Slice((*int)(nil), 0) })
+		// nil pointer with zero length returns nil
+		assert(unsafe.Slice((*int)(nil), 0) == nil)
+
+		// nil pointer with positive length panics
+		mustPanic(func() { _ = unsafe.Slice((*int)(nil), 1) })
 
 		// negative length
 		var neg int = -1