[release-branch.go1.20] all: merge master (db36eca) into release-branch.go1.20

Merge List:

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

Change-Id: I037343df0fe5b171b5f5726fcc55c01108d2563e
diff --git a/doc/go1.20.html b/doc/go1.20.html
index 28d3c82..aec3e25 100644
--- a/doc/go1.20.html
+++ b/doc/go1.20.html
@@ -30,7 +30,7 @@
 </p>
 
 <p><!-- https://go.dev/issue/46505 -->
-  Go 1.17 added <a href="/ref/spec#Conversions_from_slice_to_array_pointer">conversions from slice to an array pointer</a>.
+  Go 1.17 added <a href="/ref/spec#Conversions_from_slice_to_array_or_array_pointer">conversions from slice to an array pointer</a>.
   Go 1.20 extends this to allow conversions from a slice to an array:
   given a slice <code>x</code>, <code>[4]byte(x)</code> can now be written
   instead of <code>*(*[4]byte)(x)</code>.
@@ -67,9 +67,16 @@
 
 <h2 id="ports">Ports</h2>
 
+<h3 id="windows">Windows</h3>
+
+<p><!-- https://go.dev/issue/57003, https://go.dev/issue/57004 -->
+  Go 1.20 is the last release that will run on any release of Windows 7, 8, Server 2008 and Server 2012.
+  Go 1.21 will require at least Windows 10 or Server 2016.
+</p>
+
 <h3 id="darwin">Darwin and iOS</h3>
 
-<p><!-- golang.org/issue/23011 -->
+<p><!-- https://go.dev/issue/23011 -->
   Go 1.20 is the last release that will run on macOS 10.13 High Sierra or 10.14 Mojave.
   Go 1.21 will require macOS 10.15 Catalina or later.
 </p>
@@ -102,9 +109,9 @@
   Programs that run <code>go</code> <code>test</code> <code>-json</code>
   do not need any updates.
   Programs that invoke <code>go</code> <code>tool</code> <code>test2json</code>
-  directly should now run the test binary with <code>-v=json</code>
-  (for example, <code>go</code> <code>test</code> <code>-v=json</code>
-  or <code>./pkg.test</code> <code>-test.v=json</code>)
+  directly should now run the test binary with <code>-v=test2json</code>
+  (for example, <code>go</code> <code>test</code> <code>-v=test2json</code>
+  or <code>./pkg.test</code> <code>-test.v=test2json</code>)
   instead of plain <code>-v</code>.
 </p>
 
@@ -285,7 +292,7 @@
 <p><!-- CL 423359, https://go.dev/issue/51317 -->
   The runtime now has experimental support for memory-safe arena allocation
   that makes it possible to eagerly free memory in bulk.
-  When used appopriately, it has the potential to improve CPU performance by
+  When used appropriately, it has the potential to improve CPU performance by
   up to 15% in memory-allocation-heavy applications.
   To try it out, build your Go program with <code>GOEXPERIMENT=arenas</code>,
   which will make the <code>arena</code> package visible to your program.
@@ -308,7 +315,7 @@
 <p><!-- https://go.dev/issue/51430 -->
   Go 1.20 adds a new <code>runtime/coverage</code> package
   containing APIs for writing coverage profile data at
-  runtime from a long-running and/or server programs that
+  runtime from long-running and/or server programs that
   do not terminate via <code>os.Exit()</code>.
 </p>
 
@@ -374,7 +381,7 @@
   <code>$HOME/go1.4</code> (<code>%HOMEDRIVE%%HOMEPATH%\go1.4</code> on Windows).
   Go 1.18 and Go 1.19 looked first for <code>$HOME/go1.17</code> or <code>$HOME/sdk/go1.17</code>
   before falling back to <code>$HOME/go1.4</code>,
-  in ancitipation of requiring Go 1.17 for use when bootstrapping Go 1.20.
+  in anticipation of requiring Go 1.17 for use when bootstrapping Go 1.20.
   Go 1.20 does require a Go 1.17 release for bootstrapping, but we realized that we should
   adopt the latest point release of the bootstrap toolchain, so it requires Go 1.17.13.
   Go 1.20 looks for <code>$HOME/go1.17.13</code> or <code>$HOME/sdk/go1.17.13</code>
@@ -417,7 +424,7 @@
 </p>
 <p>
   The <a href="/pkg/fmt/#Errorf"><code>fmt.Errorf</code></a> function
-  now supports multiple occurrances of the <code>%w</code> format verb,
+  now supports multiple occurrences of the <code>%w</code> format verb,
   which will cause it to return an error that wraps all of those error operands.
 </p>
 <p>
@@ -808,7 +815,7 @@
       The new <a href="/pkg/go/types/#Satisfies"><code>Satisfies</code></a> function reports
       whether a type satisfies a constraint.
       This change aligns with the <a href="#language">new language semantics</a>
-      that distinguish satsifying a constraint from implementing an interface.
+      that distinguish satisfying a constraint from implementing an interface.
     </p>
   </dd>
 </dl><!-- go/types -->
@@ -883,7 +890,7 @@
       if a <code>CNAME</code> record referred to a name that with no <code>A</code>,
       <code>AAAA</code>, or <code>CNAME</code> record. This change modifies
       <code>LookupCNAME</code> to match the previous behavior on Windows,
-      allowing allowing <code>LookupCNAME</code> to succeed whenever a
+      allowing <code>LookupCNAME</code> to succeed whenever a
       <code>CNAME</code> exists.
     </p>
 
diff --git a/doc/go_spec.html b/doc/go_spec.html
index 3bc610f..f93f2ab 100644
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,6 +1,6 @@
 <!--{
 	"Title": "The Go Programming Language Specification",
-	"Subtitle": "Version of November 21, 2022",
+	"Subtitle": "Version of December 15, 2022",
 	"Path": "/ref/spec"
 }-->
 
@@ -944,6 +944,29 @@
 [2][2][2]float64  // same as [2]([2]([2]float64))
 </pre>
 
+<p>
+An array type <code>T</code> may not have an element of type <code>T</code>,
+or of a type containing <code>T</code> as a component, directly or indirectly,
+if those containing types are only array or struct types.
+</p>
+
+<pre>
+// invalid array types
+type (
+	T1 [10]T1                 // element type of T1 is T1
+	T2 [10]struct{ f T2 }     // T2 contains T2 as component of a struct
+	T3 [10]T4                 // T3 contains T3 as component of a struct in T4
+	T4 struct{ f T3 }         // T4 contains T4 as component of array T3 in a struct
+)
+
+// valid array types
+type (
+	T5 [10]*T5                // T5 contains T5 as component of a pointer
+	T6 [10]func() T6          // T6 contains T6 as component of a function type
+	T7 [10]struct{ f []T7 }   // T7 contains T7 as component of a slice in a struct
+)
+</pre>
+
 <h3 id="Slice_types">Slice types</h3>
 
 <p>
@@ -1136,6 +1159,29 @@
 }
 </pre>
 
+<p>
+A struct type <code>T</code> may not contain a field of type <code>T</code>,
+or of a type containing <code>T</code> as a component, directly or indirectly,
+if those containing types are only array or struct types.
+</p>
+
+<pre>
+// invalid struct types
+type (
+	T1 struct{ T1 }            // T1 contains a field of T1
+	T2 struct{ f [10]T2 }      // T2 contains T2 as component of an array
+	T3 struct{ T4 }            // T3 contains T3 as component of an array in struct T4
+	T4 struct{ f [10]T3 }      // T4 contains T4 as component of struct T3 in an array
+)
+
+// valid struct types
+type (
+	T5 struct{ f *T5 }         // T5 contains T5 as component of a pointer
+	T6 struct{ f func() T6 }   // T6 contains T6 as component of a function type
+	T7 struct{ f [10][]T7 }    // T7 contains T7 as component of a slice in an array
+)
+</pre>
+
 <h3 id="Pointer_types">Pointer types</h3>
 
 <p>
@@ -1511,17 +1557,17 @@
 </pre>
 
 <p>
-An interface type <code>T</code> may not embed any type element
-that is, contains, or embeds <code>T</code>, recursively.
+An interface type <code>T</code> may not embed a type element
+that is, contains, or embeds <code>T</code>, directly or indirectly.
 </p>
 
 <pre>
-// illegal: Bad cannot embed itself
+// illegal: Bad may not embed itself
 type Bad interface {
 	Bad
 }
 
-// illegal: Bad1 cannot embed itself using Bad2
+// illegal: Bad1 may not embed itself using Bad2
 type Bad1 interface {
 	Bad2
 }
@@ -1529,10 +1575,15 @@
 	Bad1
 }
 
-// illegal: Bad3 cannot embed a union containing Bad3
+// illegal: Bad3 may not embed a union containing Bad3
 type Bad3 interface {
 	~int | ~string | Bad3
 }
+
+// illegal: Bad4 may not embed an array containing Bad4 as element type
+type Bad4 interface {
+	[10]Bad4
+}
 </pre>
 
 <h4 id="Implementing_an_interface">Implementing an interface</h4>
@@ -2644,15 +2695,26 @@
 with a generic type.
 </p>
 
-<!--
-This section needs to explain if and what kind of cycles are permitted
-using type parameters in a type parameter list.
--->
+<p>
+Within a type parameter list of a generic type <code>T</code>, a type constraint
+may not (directly, or indirectly through the type parameter list of another
+generic type) refer to <code>T</code>.
+</p>
+
+<pre>
+type T1[P T1[P]] …                    // illegal: T1 refers to itself
+type T2[P interface{ T2[int] }] …     // illegal: T2 refers to itself
+type T3[P interface{ m(T3[int])}] …   // illegal: T3 refers to itself
+type T4[P T5[P]] …                    // illegal: T4 refers to T5 and
+type T5[P T4[P]] …                    //          T5 refers to T4
+
+type T6[P int] struct{ f *T6[P] }     // ok: reference to T6 is not in type parameter list
+</pre>
 
 <h4 id="Type_constraints">Type constraints</h4>
 
 <p>
-A type constraint is an <a href="#Interface_types">interface</a> that defines the
+A <i>type constraint</i> is an <a href="#Interface_types">interface</a> that defines the
 set of permissible type arguments for the respective type parameter and controls the
 operations supported by values of that type parameter.
 </p>
@@ -2663,7 +2725,7 @@
 
 <p>
 If the constraint is an interface literal of the form <code>interface{E}</code> where
-<code>E</code> is an embedded type element (not a method), in a type parameter list
+<code>E</code> is an embedded <a href="#Interface_types">type element</a> (not a method), in a type parameter list
 the enclosing <code>interface{ … }</code> may be omitted for convenience:
 </p>
 
@@ -2671,7 +2733,7 @@
 [T []P]                      // = [T interface{[]P}]
 [T ~int]                     // = [T interface{~int}]
 [T int|string]               // = [T interface{int|string}]
-type Constraint ~int         // illegal: ~int is not inside a type parameter list
+type Constraint ~int         // illegal: ~int is not in a type parameter list
 </pre>
 
 <!--
@@ -2684,35 +2746,23 @@
 The <a href="#Predeclared_identifiers">predeclared</a>
 <a href="#Interface_types">interface type</a> <code>comparable</code>
 denotes the set of all non-interface types that are
-<a href="#Comparison_operators">comparable</a>. Specifically,
-a type <code>T</code> implements <code>comparable</code> if:
+<a href="#Comparison_operators">strictly comparable</a>.
 </p>
 
-<ul>
-<li>
-	<code>T</code> is not an interface type and <code>T</code> supports the operations
-	<code>==</code> and <code>!=</code>; or
-</li>
-<li>
-	<code>T</code> is an interface type and each type in <code>T</code>'s
-	<a href="#Interface_types">type set</a> implements <code>comparable</code>.
-</li>
-</ul>
-
 <p>
-Even though interfaces that are not type parameters can be
-<a href="#Comparison_operators">compared</a>
-(possibly causing a run-time panic) they do not implement
-<code>comparable</code>.
+Even though interfaces that are not type parameters are <a href="#Comparison_operators">comparable</a>,
+they are not strictly comparable and therefore they do not implement <code>comparable</code>.
+However, they <a href="#Satisfying_a_type_constraint">satisfy</a> <code>comparable</code>.
 </p>
 
 <pre>
-int                          // implements comparable
+int                          // implements comparable (int is strictly comparable)
 []byte                       // does not implement comparable (slices cannot be compared)
 interface{}                  // does not implement comparable (see above)
-interface{ ~int | ~string }  // type parameter only: implements comparable
-interface{ comparable }      // type parameter only: implements comparable
-interface{ ~int | ~[]byte }  // type parameter only: does not implement comparable (not all types in the type set are comparable)
+interface{ ~int | ~string }  // type parameter only: implements comparable (int, string types are stricly comparable)
+interface{ comparable }      // type parameter only: implements comparable (comparable implements itself)
+interface{ ~int | ~[]byte }  // type parameter only: does not implement comparable (slices are not comparable)
+interface{ ~struct{ any } }  // type parameter only: does not implement comparable (field any is not strictly comparable)
 </pre>
 
 <p>
@@ -2721,6 +2771,51 @@
 values or variables, or components of other, non-interface types.
 </p>
 
+<h4 id="Satisfying_a_type_constraint">Satisfying a type constraint</h4>
+
+<p>
+A type argument <code>T</code><i> satisfies</i> a type constraint <code>C</code>
+if <code>T</code> is an element of the type set defined by <code>C</code>; i.e.,
+if <code>T</code> <a href="#Implementing_an_interface">implements</a> <code>C</code>.
+As an exception, a <a href="#Comparison_operators">strictly comparable</a>
+type constraint may also be satisfied by a <a href="#Comparison_operators">comparable</a>
+(not necessarily strictly comparable) type argument.
+More precisely:
+</p>
+
+<p>
+A type T <i>satisfies</i> a constraint <code>C</code> if
+</p>
+
+<ul>
+<li>
+	<code>T</code> <a href="#Implementing_an_interface">implements</a> <code>C</code>; or
+</li>
+<li>
+	<code>C</code> can be written in the form <code>interface{ comparable; E }</code>,
+	where <code>E</code> is a <a href="#Basic_interfaces">basic interface</a> and
+	<code>T</code> is <a href="#Comparison_operators">comparable</a> and implements <code>E</code>.
+</li>
+</ul>
+
+<pre>
+type argument      type constraint                // constraint satisfaction
+
+int                interface{ ~int }              // satisfied: int implements interface{ ~int }
+string             comparable                     // satisfied: string implements comparable (string is stricty comparable)
+[]byte             comparable                     // not satisfied: slices are not comparable
+any                interface{ comparable; int }   // not satisfied: any does not implement interface{ int }
+any                comparable                     // satisfied: any is comparable and implements the basic interface any
+struct{f any}      comparable                     // satisfied: struct{f any} is comparable and implements the basic interface any
+any                interface{ comparable; m() }   // not satisfied: any does not implement the basic interface interface{ m() }
+interface{ m() }   interface{ comparable; m() }   // satisfied: interface{ m() } is comparable and implements the basic interface interface{ m() }
+</pre>
+
+<p>
+Because of the exception in the constraint satisfaction rule, comparing operands of type parameter type
+may panic at run-time (even though comparable type parameters are always strictly comparable).
+</p>
+
 <h3 id="Variable_declarations">Variable declarations</h3>
 
 <p>
@@ -4221,7 +4316,7 @@
 </li>
 
 <li>
-After substitution, each type argument must <a href="#Interface_types">implement</a>
+After substitution, each type argument must <a href="#Satisfying_a_type_constraint">satisfy</a>
 the <a href="#Type_parameter_declarations">constraint</a> (instantiated, if necessary)
 of the corresponding type parameter. Otherwise instantiation fails.
 </li>
@@ -4235,9 +4330,10 @@
 <pre>
 type parameter list    type arguments    after substitution
 
-[P any]                int               int implements any
-[S ~[]E, E any]        []int, int        []int implements ~[]int, int implements any
-[P io.Writer]          string            illegal: string doesn't implement io.Writer
+[P any]                int               int satisfies any
+[S ~[]E, E any]        []int, int        []int satisfies ~[]int, int satisfies any
+[P io.Writer]          string            illegal: string doesn't satisfy io.Writer
+[P comparable]         any               any satisfies (but does not implement) comparable
 </pre>
 
 <p>
@@ -5019,69 +5115,71 @@
 </p>
 <p>
 The equality operators <code>==</code> and <code>!=</code> apply
-to operands that are <i>comparable</i>.
+to operands of <i>comparable</i> types.
 The ordering operators <code>&lt;</code>, <code>&lt;=</code>, <code>&gt;</code>, and <code>&gt;=</code>
-apply to operands that are <i>ordered</i>.
+apply to operands of <i>ordered</i> types.
 These terms and the result of the comparisons are defined as follows:
 </p>
 
 <ul>
 	<li>
-	Boolean values are comparable.
+	Boolean types are comparable.
 	Two boolean values are equal if they are either both
 	<code>true</code> or both <code>false</code>.
 	</li>
 
 	<li>
-	Integer values are comparable and ordered, in the usual way.
+	Integer types are comparable and ordered.
+	Two integer values are compared in the usual way.
 	</li>
 
 	<li>
-	Floating-point values are comparable and ordered,
-	as defined by the IEEE-754 standard.
+	Floating-point types are comparable and ordered.
+	Two floating-point values are compared as defined by the IEEE-754 standard.
 	</li>
 
 	<li>
-	Complex values are comparable.
+	Complex types are comparable.
 	Two complex values <code>u</code> and <code>v</code> are
 	equal if both <code>real(u) == real(v)</code> and
 	<code>imag(u) == imag(v)</code>.
 	</li>
 
 	<li>
-	String values are comparable and ordered, lexically byte-wise.
+	String types are comparable and ordered.
+	Two string values are compared lexically byte-wise.
 	</li>
 
 	<li>
-	Pointer values are comparable.
+	Pointer types are comparable.
 	Two pointer values are equal if they point to the same variable or if both have value <code>nil</code>.
 	Pointers to distinct <a href="#Size_and_alignment_guarantees">zero-size</a> variables may or may not be equal.
 	</li>
 
 	<li>
-	Channel values are comparable.
+	Channel types are comparable.
 	Two channel values are equal if they were created by the same call to
 	<a href="#Making_slices_maps_and_channels"><code>make</code></a>
 	or if both have value <code>nil</code>.
 	</li>
 
 	<li>
-	Interface values are comparable.
+	Interface types that are not type parameters are comparable.
 	Two interface values are equal if they have <a href="#Type_identity">identical</a> dynamic types
 	and equal dynamic values or if both have value <code>nil</code>.
 	</li>
 
 	<li>
 	A value <code>x</code> of non-interface type <code>X</code> and
-	a value <code>t</code> of interface type <code>T</code> are comparable when values
-	of type <code>X</code> are comparable and
+	a value <code>t</code> of interface type <code>T</code> can be compared
+	if type <code>X</code> is comparable and
 	<code>X</code> <a href="#Implementing_an_interface">implements</a> <code>T</code>.
 	They are equal if <code>t</code>'s dynamic type is identical to <code>X</code>
 	and <code>t</code>'s dynamic value is equal to <code>x</code>.
 	</li>
 
 	<li>
-	Struct values are comparable if all their fields are comparable.
+	Struct types are comparable if all their field types are comparable.
 	Two struct values are equal if their corresponding
 	non-<a href="#Blank_identifier">blank</a> field values are equal.
 	The fields are compared in source order, and comparison stops as
@@ -5089,23 +5187,27 @@
 	</li>
 
 	<li>
-	Array values are comparable if values of the array element type are comparable.
+	Array types are comparable if their array element types are comparable.
 	Two array values are equal if their corresponding element values are equal.
 	The elements are compared in ascending index order, and comparison stops
 	as soon as two element values differ (or all elements have been compared).
 	</li>
+
+	<li>
+	Type parameters are comparable if they are strictly comparable (see below).
+	</li>
 </ul>
 
 <p>
 A comparison of two interface values with identical dynamic types
-causes a <a href="#Run_time_panics">run-time panic</a> if values
-of that type are not comparable.  This behavior applies not only to direct interface
+causes a <a href="#Run_time_panics">run-time panic</a> if that type
+is not comparable.  This behavior applies not only to direct interface
 value comparisons but also when comparing arrays of interface values
 or structs with interface-valued fields.
 </p>
 
 <p>
-Slice, map, and function values are not comparable.
+Slice, map, and function types are not comparable.
 However, as a special case, a slice, map, or function value may
 be compared to the predeclared identifier <code>nil</code>.
 Comparison of pointer, channel, and interface values to <code>nil</code>
@@ -5126,6 +5228,30 @@
 )
 </pre>
 
+<p>
+A type is <i>strictly comparable</i> if it is comparable and not an interface
+type nor composed of interface types.
+Specifically:
+</p>
+
+<ul>
+	<li>
+	Boolean, numeric, string, pointer, and channel types are strictly comparable.
+	</li>
+
+	<li>
+	Struct types are strictly comparable if all their field types are strictly comparable.
+	</li>
+
+	<li>
+	Array types are strictly comparable if their array element types are strictly comparable.
+	</li>
+
+	<li>
+	Type parameters are strictly comparable if all types in their type set are strictly comparable.
+	</li>
+</ul>
+
 <h3 id="Logical_operators">Logical operators</h3>
 
 <p>
@@ -8013,7 +8139,7 @@
 
 <!--
 These conversions also apply to type parameters with suitable core types.
-Determine if we can simply use core type insted of underlying type here,
+Determine if we can simply use core type instead of underlying type here,
 of if the general conversion rules take care of this.
 -->
 
diff --git a/misc/cgo/testsanitizers/cc_test.go b/misc/cgo/testsanitizers/cc_test.go
index af85f99..8eda137 100644
--- a/misc/cgo/testsanitizers/cc_test.go
+++ b/misc/cgo/testsanitizers/cc_test.go
@@ -353,6 +353,9 @@
 		// Set the debug mode to print the C stack trace.
 		c.cFlags = append(c.cFlags, "-g")
 
+	case "fuzzer":
+		c.goFlags = append(c.goFlags, "-tags=libfuzzer", "-gcflags=-d=libfuzzer")
+
 	default:
 		panic(fmt.Sprintf("unrecognized sanitizer: %q", sanitizer))
 	}
@@ -405,6 +408,13 @@
 }
 `)
 
+var cLibFuzzerInput = []byte(`
+#include <stddef.h>
+int LLVMFuzzerTestOneInput(char *data, size_t size) {
+	return 0;
+}
+`)
+
 func (c *config) checkCSanitizer() (skip bool, err error) {
 	dir, err := os.MkdirTemp("", c.sanitizer)
 	if err != nil {
@@ -413,7 +423,12 @@
 	defer os.RemoveAll(dir)
 
 	src := filepath.Join(dir, "return0.c")
-	if err := os.WriteFile(src, cMain, 0600); err != nil {
+	cInput := cMain
+	if c.sanitizer == "fuzzer" {
+		// libFuzzer generates the main function itself, and uses a different input.
+		cInput = cLibFuzzerInput
+	}
+	if err := os.WriteFile(src, cInput, 0600); err != nil {
 		return false, fmt.Errorf("failed to write C source file: %v", err)
 	}
 
@@ -434,6 +449,11 @@
 		return true, fmt.Errorf("%#q failed: %v\n%s", strings.Join(cmd.Args, " "), err, out)
 	}
 
+	if c.sanitizer == "fuzzer" {
+		// For fuzzer, don't try running the test binary. It never finishes.
+		return false, nil
+	}
+
 	if out, err := exec.Command(dst).CombinedOutput(); err != nil {
 		if os.IsNotExist(err) {
 			return true, fmt.Errorf("%#q failed to produce executable: %v", strings.Join(cmd.Args, " "), err)
@@ -505,6 +525,10 @@
 	}
 }
 
+func (d *tempDir) Base() string {
+	return d.base
+}
+
 func (d *tempDir) Join(name string) string {
 	return filepath.Join(d.base, name)
 }
@@ -535,7 +559,7 @@
 }
 
 // mSanSupported is a copy of the function cmd/internal/sys.MSanSupported,
-// because the internal pacakage can't be used here.
+// because the internal package can't be used here.
 func mSanSupported(goos, goarch string) bool {
 	switch goos {
 	case "linux":
@@ -548,7 +572,7 @@
 }
 
 // aSanSupported is a copy of the function cmd/internal/sys.ASanSupported,
-// because the internal pacakage can't be used here.
+// because the internal package can't be used here.
 func aSanSupported(goos, goarch string) bool {
 	switch goos {
 	case "linux":
diff --git a/misc/cgo/testsanitizers/libfuzzer_test.go b/misc/cgo/testsanitizers/libfuzzer_test.go
new file mode 100644
index 0000000..345751b
--- /dev/null
+++ b/misc/cgo/testsanitizers/libfuzzer_test.go
@@ -0,0 +1,91 @@
+// Copyright 2022 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 sanitizers_test
+
+import (
+	"strings"
+	"testing"
+)
+
+func TestLibFuzzer(t *testing.T) {
+	goos, err := goEnv("GOOS")
+	if err != nil {
+		t.Fatal(err)
+	}
+	goarch, err := goEnv("GOARCH")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !libFuzzerSupported(goos, goarch) {
+		t.Skipf("skipping on %s/%s; libfuzzer option is not supported.", goos, goarch)
+	}
+	config := configure("fuzzer")
+	config.skipIfCSanitizerBroken(t)
+
+	cases := []struct {
+		goSrc         string
+		cSrc          string
+		expectedError string
+	}{
+		{goSrc: "libfuzzer1.go", expectedError: "panic: found it"},
+		{goSrc: "libfuzzer2.go", cSrc: "libfuzzer2.c", expectedError: "panic: found it"},
+	}
+	for _, tc := range cases {
+		tc := tc
+		name := strings.TrimSuffix(tc.goSrc, ".go")
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+
+			dir := newTempDir(t)
+			defer dir.RemoveAll(t)
+
+			// build Go code in libfuzzer mode to a c-archive
+			outPath := dir.Join(name)
+			archivePath := dir.Join(name + ".a")
+			mustRun(t, config.goCmd("build", "-buildmode=c-archive", "-o", archivePath, srcPath(tc.goSrc)))
+
+			// build C code (if any) and link with Go code
+			cmd, err := cc(config.cFlags...)
+			if err != nil {
+				t.Fatalf("error running cc: %v", err)
+			}
+			cmd.Args = append(cmd.Args, config.ldFlags...)
+			cmd.Args = append(cmd.Args, "-o", outPath, "-I", dir.Base())
+			if tc.cSrc != "" {
+				cmd.Args = append(cmd.Args, srcPath(tc.cSrc))
+			}
+			cmd.Args = append(cmd.Args, archivePath)
+			mustRun(t, cmd)
+
+			cmd = hangProneCmd(outPath)
+			cmd.Dir = dir.Base()
+			outb, err := cmd.CombinedOutput()
+			out := string(outb)
+			if err == nil {
+				t.Fatalf("fuzzing succeeded unexpectedly; output:\n%s", out)
+			}
+			if !strings.Contains(out, tc.expectedError) {
+				t.Errorf("exited without expected error %q; got\n%s", tc.expectedError, out)
+			}
+		})
+	}
+}
+
+// libFuzzerSupported is a copy of the function internal/platform.FuzzInstrumented,
+// because the internal package can't be used here.
+func libFuzzerSupported(goos, goarch string) bool {
+	switch goarch {
+	case "amd64", "arm64":
+		// TODO(#14565): support more architectures.
+		switch goos {
+		case "darwin", "freebsd", "linux", "windows":
+			return true
+		default:
+			return false
+		}
+	default:
+		return false
+	}
+}
diff --git a/misc/cgo/testsanitizers/testdata/libfuzzer1.go b/misc/cgo/testsanitizers/testdata/libfuzzer1.go
new file mode 100644
index 0000000..d178fb1
--- /dev/null
+++ b/misc/cgo/testsanitizers/testdata/libfuzzer1.go
@@ -0,0 +1,16 @@
+package main
+
+import "C"
+
+import "unsafe"
+
+//export LLVMFuzzerTestOneInput
+func LLVMFuzzerTestOneInput(p unsafe.Pointer, sz C.int) C.int {
+	b := C.GoBytes(p, sz)
+	if len(b) >= 6 && b[0] == 'F' && b[1] == 'u' && b[2] == 'z' && b[3] == 'z' && b[4] == 'M' && b[5] == 'e' {
+		panic("found it")
+	}
+	return 0
+}
+
+func main() {}
diff --git a/misc/cgo/testsanitizers/testdata/libfuzzer2.c b/misc/cgo/testsanitizers/testdata/libfuzzer2.c
new file mode 100644
index 0000000..567ff5a
--- /dev/null
+++ b/misc/cgo/testsanitizers/testdata/libfuzzer2.c
@@ -0,0 +1,11 @@
+#include <stddef.h>
+
+#include "libfuzzer2.h"
+
+int LLVMFuzzerTestOneInput(char *data, size_t size) {
+ 	if (size > 0 && data[0] == 'H')
+		if (size > 1 && data[1] == 'I')
+			if (size > 2 && data[2] == '!')
+				FuzzMe(data, size);
+	return 0;
+}
diff --git a/misc/cgo/testsanitizers/testdata/libfuzzer2.go b/misc/cgo/testsanitizers/testdata/libfuzzer2.go
new file mode 100644
index 0000000..c7a4325
--- /dev/null
+++ b/misc/cgo/testsanitizers/testdata/libfuzzer2.go
@@ -0,0 +1,16 @@
+package main
+
+import "C"
+
+import "unsafe"
+
+//export FuzzMe
+func FuzzMe(p unsafe.Pointer, sz C.int) {
+	b := C.GoBytes(p, sz)
+	b = b[3:]
+	if len(b) >= 4 && b[0] == 'f' && b[1] == 'u' && b[2] == 'z' && b[3] == 'z' {
+		panic("found it")
+	}
+}
+
+func main() {}
diff --git a/misc/cgo/testshared/shared_test.go b/misc/cgo/testshared/shared_test.go
index cd8a144..b14fb1c 100644
--- a/misc/cgo/testshared/shared_test.go
+++ b/misc/cgo/testshared/shared_test.go
@@ -1105,3 +1105,15 @@
 	goCmd(t, "install", "-buildmode=shared", "-linkshared", "./issue47837/a")
 	goCmd(t, "run", "-linkshared", "./issue47837/main")
 }
+
+// Test that we can build std in shared mode.
+func TestStd(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skip in short mode")
+	}
+	t.Parallel()
+	// Use a temporary pkgdir to not interfere with other tests, and not write to GOROOT.
+	// Cannot use goCmd as it runs with cloned GOROOT which is incomplete.
+	runWithEnv(t, "building std", []string{"GOROOT=" + oldGOROOT},
+		filepath.Join(oldGOROOT, "bin", "go"), "install", "-buildmode=shared", "-pkgdir="+t.TempDir(), "std")
+}
diff --git a/src/archive/tar/reader.go b/src/archive/tar/reader.go
index 52a3150..82a5a5a 100644
--- a/src/archive/tar/reader.go
+++ b/src/archive/tar/reader.go
@@ -45,15 +45,6 @@
 // Any remaining data in the current file is automatically discarded.
 //
 // io.EOF is returned at the end of the input.
-//
-// ErrInsecurePath and a valid *Header are returned if the next file's name is:
-//
-//   - absolute;
-//   - a relative path escaping the current directory, such as "../a"; or
-//   - on Windows, a reserved file name such as "NUL".
-//
-// The caller may ignore the ErrInsecurePath error,
-// but is then responsible for sanitizing paths as appropriate.
 func (tr *Reader) Next() (*Header, error) {
 	if tr.err != nil {
 		return nil, tr.err
diff --git a/src/archive/zip/reader.go b/src/archive/zip/reader.go
index 10e835f..a2ae74e 100644
--- a/src/archive/zip/reader.go
+++ b/src/archive/zip/reader.go
@@ -87,17 +87,6 @@
 
 // NewReader returns a new Reader reading from r, which is assumed to
 // have the given size in bytes.
-//
-// ErrInsecurePath and a valid *Reader are returned if the names of any
-// files in the archive:
-//
-//   - are absolute;
-//   - are a relative path escaping the current directory, such as "../a";
-//   - contain a backslash (\) character; or
-//   - on Windows, are a reserved file name such as "NUL".
-//
-// The caller may ignore the ErrInsecurePath error,
-// but is then responsible for sanitizing paths as appropriate.
 func NewReader(r io.ReaderAt, size int64) (*Reader, error) {
 	if size < 0 {
 		return nil, errors.New("zip: size cannot be negative")
diff --git a/src/cmd/compile/internal/devirtualize/devirtualize.go b/src/cmd/compile/internal/devirtualize/devirtualize.go
index 7350a6f..554e935 100644
--- a/src/cmd/compile/internal/devirtualize/devirtualize.go
+++ b/src/cmd/compile/internal/devirtualize/devirtualize.go
@@ -152,4 +152,7 @@
 	default:
 		call.SetType(ft.Results())
 	}
+
+	// Desugar OCALLMETH, if we created one (#57309).
+	typecheck.FixMethodCall(call)
 }
diff --git a/src/cmd/compile/internal/ssa/_gen/ARM64.rules b/src/cmd/compile/internal/ssa/_gen/ARM64.rules
index 727204d..0c5a2e6 100644
--- a/src/cmd/compile/internal/ssa/_gen/ARM64.rules
+++ b/src/cmd/compile/internal/ssa/_gen/ARM64.rules
@@ -342,9 +342,9 @@
 (FCMPD x (FMOVDconst [0])) => (FCMPD0 x)
 (FCMPD (FMOVDconst [0]) x) => (InvertFlags (FCMPD0 x))
 
-// CSEL needs a flag-generating argument. Synthesize a CMPW if necessary.
+// CSEL needs a flag-generating argument. Synthesize a TSTW if necessary.
 (CondSelect x y boolval) && flagArg(boolval) != nil => (CSEL [boolval.Op] x y flagArg(boolval))
-(CondSelect x y boolval) && flagArg(boolval) == nil => (CSEL [OpARM64NotEqual] x y (CMPWconst [0] boolval))
+(CondSelect x y boolval) && flagArg(boolval) == nil => (CSEL [OpARM64NotEqual] x y (TSTWconst [1] boolval))
 
 (OffPtr [off] ptr:(SP)) && is32Bit(off) => (MOVDaddr [int32(off)] ptr)
 (OffPtr [off] ptr) => (ADDconst [off] ptr)
diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules
index 2810f0a..1caaf13 100644
--- a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules
+++ b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules
@@ -400,7 +400,8 @@
 
 (AtomicAdd(32|64) ...) => (LoweredAtomicAdd(32|64) ...)
 
-(AtomicCompareAndSwap(32|64) ...) => (LoweredAtomicCas(32|64) ...)
+(AtomicCompareAndSwap32 ptr old new mem) => (LoweredAtomicCas32 ptr (SignExt32to64 old) new mem)
+(AtomicCompareAndSwap64 ...) => (LoweredAtomicCas64 ...)
 
 // checks
 (NilCheck ...) => (LoweredNilCheck ...)
diff --git a/src/cmd/compile/internal/ssa/_gen/MIPS64.rules b/src/cmd/compile/internal/ssa/_gen/MIPS64.rules
index 17634af..a594df2 100644
--- a/src/cmd/compile/internal/ssa/_gen/MIPS64.rules
+++ b/src/cmd/compile/internal/ssa/_gen/MIPS64.rules
@@ -392,7 +392,8 @@
 
 (AtomicAdd(32|64) ...) => (LoweredAtomicAdd(32|64) ...)
 
-(AtomicCompareAndSwap(32|64) ...) => (LoweredAtomicCas(32|64) ...)
+(AtomicCompareAndSwap32 ptr old new mem) => (LoweredAtomicCas32 ptr (SignExt32to64 old) new mem)
+(AtomicCompareAndSwap64 ...) => (LoweredAtomicCas64 ...)
 
 // checks
 (NilCheck ...) => (LoweredNilCheck ...)
diff --git a/src/cmd/compile/internal/ssa/_gen/PPC64.rules b/src/cmd/compile/internal/ssa/_gen/PPC64.rules
index aee53d4..5a68de0 100644
--- a/src/cmd/compile/internal/ssa/_gen/PPC64.rules
+++ b/src/cmd/compile/internal/ssa/_gen/PPC64.rules
@@ -409,9 +409,9 @@
 ((EQ|NE|LT|LE|GT|GE) (CMPconst [0] z:(XOR x y)) yes no) && z.Uses == 1 => ((EQ|NE|LT|LE|GT|GE) (Select1 <types.TypeFlags> (XORCC x y)) yes no)
 
 // Only lower after bool is lowered. It should always lower. This helps ensure the folding below happens reliably.
-(CondSelect x y bool) && flagArg(bool) == nil => (ISEL [6] x y (CMPWconst [0] bool))
+(CondSelect x y bool) && flagArg(bool) == nil => (ISEL [6] x y (Select1 <types.TypeFlags> (ANDCCconst [1] bool)))
 // Fold any CR -> GPR -> CR transfers when applying the above rule.
-(ISEL [6] x y (CMPWconst [0] (ISELB [c] one cmp))) => (ISEL [c] x y cmp)
+(ISEL [6] x y (Select1 (ANDCCconst [1] (ISELB [c] one cmp)))) => (ISEL [c] x y cmp)
 
 // Lowering loads
 (Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) => (MOVDload ptr mem)
diff --git a/src/cmd/compile/internal/ssa/_gen/PPC64Ops.go b/src/cmd/compile/internal/ssa/_gen/PPC64Ops.go
index baa783e..2d651dd 100644
--- a/src/cmd/compile/internal/ssa/_gen/PPC64Ops.go
+++ b/src/cmd/compile/internal/ssa/_gen/PPC64Ops.go
@@ -8,8 +8,8 @@
 
 // Notes:
 //  - Less-than-64-bit integer types live in the low portion of registers.
-//    For now, the upper portion is junk; sign/zero-extension might be optimized in the future, but not yet.
-//  - Boolean types are zero or 1; stored in a byte, but loaded with AMOVBZ so the upper bytes of a register are zero.
+//    The upper portion is junk.
+//  - Boolean types are zero or 1; stored in a byte, with upper bytes of the register containing junk.
 //  - *const instructions may use a constant larger than the instruction can encode.
 //    In this case the assembler expands to multiple instructions and uses tmp
 //    register (R31).
diff --git a/src/cmd/compile/internal/ssa/_gen/RISCV64.rules b/src/cmd/compile/internal/ssa/_gen/RISCV64.rules
index 78c3375..59f71be 100644
--- a/src/cmd/compile/internal/ssa/_gen/RISCV64.rules
+++ b/src/cmd/compile/internal/ssa/_gen/RISCV64.rules
@@ -577,7 +577,7 @@
 
 (AtomicAnd32 ...) => (LoweredAtomicAnd32 ...)
 
-(AtomicCompareAndSwap32 ...) => (LoweredAtomicCas32 ...)
+(AtomicCompareAndSwap32 ptr old new mem) => (LoweredAtomicCas32 ptr (SignExt32to64 old) new mem)
 (AtomicCompareAndSwap64 ...) => (LoweredAtomicCas64 ...)
 
 (AtomicExchange32 ...) => (LoweredAtomicExchange32 ...)
diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go
index d738672..e82a49c 100644
--- a/src/cmd/compile/internal/ssa/rewriteARM64.go
+++ b/src/cmd/compile/internal/ssa/rewriteARM64.go
@@ -23561,7 +23561,7 @@
 	}
 	// match: (CondSelect x y boolval)
 	// cond: flagArg(boolval) == nil
-	// result: (CSEL [OpARM64NotEqual] x y (CMPWconst [0] boolval))
+	// result: (CSEL [OpARM64NotEqual] x y (TSTWconst [1] boolval))
 	for {
 		x := v_0
 		y := v_1
@@ -23571,8 +23571,8 @@
 		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64NotEqual)
-		v0 := b.NewValue0(v.Pos, OpARM64CMPWconst, types.TypeFlags)
-		v0.AuxInt = int32ToAuxInt(0)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
+		v0.AuxInt = int32ToAuxInt(1)
 		v0.AddArg(boolval)
 		v.AddArg3(x, y, v0)
 		return true
diff --git a/src/cmd/compile/internal/ssa/rewriteLOONG64.go b/src/cmd/compile/internal/ssa/rewriteLOONG64.go
index 26d6594..f6da0b7 100644
--- a/src/cmd/compile/internal/ssa/rewriteLOONG64.go
+++ b/src/cmd/compile/internal/ssa/rewriteLOONG64.go
@@ -52,8 +52,7 @@
 		v.Op = OpLOONG64LoweredAtomicAdd64
 		return true
 	case OpAtomicCompareAndSwap32:
-		v.Op = OpLOONG64LoweredAtomicCas32
-		return true
+		return rewriteValueLOONG64_OpAtomicCompareAndSwap32(v)
 	case OpAtomicCompareAndSwap64:
 		v.Op = OpLOONG64LoweredAtomicCas64
 		return true
@@ -705,6 +704,27 @@
 		return true
 	}
 }
+func rewriteValueLOONG64_OpAtomicCompareAndSwap32(v *Value) bool {
+	v_3 := v.Args[3]
+	v_2 := v.Args[2]
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (AtomicCompareAndSwap32 ptr old new mem)
+	// result: (LoweredAtomicCas32 ptr (SignExt32to64 old) new mem)
+	for {
+		ptr := v_0
+		old := v_1
+		new := v_2
+		mem := v_3
+		v.reset(OpLOONG64LoweredAtomicCas32)
+		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
+		v0.AddArg(old)
+		v.AddArg4(ptr, v0, new, mem)
+		return true
+	}
+}
 func rewriteValueLOONG64_OpAvg64u(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
diff --git a/src/cmd/compile/internal/ssa/rewriteMIPS64.go b/src/cmd/compile/internal/ssa/rewriteMIPS64.go
index 998b27d..c0d42b5 100644
--- a/src/cmd/compile/internal/ssa/rewriteMIPS64.go
+++ b/src/cmd/compile/internal/ssa/rewriteMIPS64.go
@@ -52,8 +52,7 @@
 		v.Op = OpMIPS64LoweredAtomicAdd64
 		return true
 	case OpAtomicCompareAndSwap32:
-		v.Op = OpMIPS64LoweredAtomicCas32
-		return true
+		return rewriteValueMIPS64_OpAtomicCompareAndSwap32(v)
 	case OpAtomicCompareAndSwap64:
 		v.Op = OpMIPS64LoweredAtomicCas64
 		return true
@@ -697,6 +696,27 @@
 		return true
 	}
 }
+func rewriteValueMIPS64_OpAtomicCompareAndSwap32(v *Value) bool {
+	v_3 := v.Args[3]
+	v_2 := v.Args[2]
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (AtomicCompareAndSwap32 ptr old new mem)
+	// result: (LoweredAtomicCas32 ptr (SignExt32to64 old) new mem)
+	for {
+		ptr := v_0
+		old := v_1
+		new := v_2
+		mem := v_3
+		v.reset(OpMIPS64LoweredAtomicCas32)
+		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
+		v0.AddArg(old)
+		v.AddArg4(ptr, v0, new, mem)
+		return true
+	}
+}
 func rewriteValueMIPS64_OpAvg64u(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go
index 8b5ea14..bc59312 100644
--- a/src/cmd/compile/internal/ssa/rewritePPC64.go
+++ b/src/cmd/compile/internal/ssa/rewritePPC64.go
@@ -1172,9 +1172,10 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
+	typ := &b.Func.Config.Types
 	// match: (CondSelect x y bool)
 	// cond: flagArg(bool) == nil
-	// result: (ISEL [6] x y (CMPWconst [0] bool))
+	// result: (ISEL [6] x y (Select1 <types.TypeFlags> (ANDCCconst [1] bool)))
 	for {
 		x := v_0
 		y := v_1
@@ -1184,9 +1185,11 @@
 		}
 		v.reset(OpPPC64ISEL)
 		v.AuxInt = int32ToAuxInt(6)
-		v0 := b.NewValue0(v.Pos, OpPPC64CMPWconst, types.TypeFlags)
-		v0.AuxInt = int32ToAuxInt(0)
-		v0.AddArg(bool)
+		v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v1.AuxInt = int64ToAuxInt(1)
+		v1.AddArg(bool)
+		v0.AddArg(v1)
 		v.AddArg3(x, y, v0)
 		return true
 	}
@@ -5355,7 +5358,7 @@
 		v.AddArg(v0)
 		return true
 	}
-	// match: (ISEL [6] x y (CMPWconst [0] (ISELB [c] one cmp)))
+	// match: (ISEL [6] x y (Select1 (ANDCCconst [1] (ISELB [c] one cmp))))
 	// result: (ISEL [c] x y cmp)
 	for {
 		if auxIntToInt32(v.AuxInt) != 6 {
@@ -5363,15 +5366,19 @@
 		}
 		x := v_0
 		y := v_1
-		if v_2.Op != OpPPC64CMPWconst || auxIntToInt32(v_2.AuxInt) != 0 {
+		if v_2.Op != OpSelect1 {
 			break
 		}
 		v_2_0 := v_2.Args[0]
-		if v_2_0.Op != OpPPC64ISELB {
+		if v_2_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_2_0.AuxInt) != 1 {
 			break
 		}
-		c := auxIntToInt32(v_2_0.AuxInt)
-		cmp := v_2_0.Args[1]
+		v_2_0_0 := v_2_0.Args[0]
+		if v_2_0_0.Op != OpPPC64ISELB {
+			break
+		}
+		c := auxIntToInt32(v_2_0_0.AuxInt)
+		cmp := v_2_0_0.Args[1]
 		v.reset(OpPPC64ISEL)
 		v.AuxInt = int32ToAuxInt(c)
 		v.AddArg3(x, y, cmp)
diff --git a/src/cmd/compile/internal/ssa/rewriteRISCV64.go b/src/cmd/compile/internal/ssa/rewriteRISCV64.go
index f94e90f..961230d8 100644
--- a/src/cmd/compile/internal/ssa/rewriteRISCV64.go
+++ b/src/cmd/compile/internal/ssa/rewriteRISCV64.go
@@ -61,8 +61,7 @@
 	case OpAtomicAnd8:
 		return rewriteValueRISCV64_OpAtomicAnd8(v)
 	case OpAtomicCompareAndSwap32:
-		v.Op = OpRISCV64LoweredAtomicCas32
-		return true
+		return rewriteValueRISCV64_OpAtomicCompareAndSwap32(v)
 	case OpAtomicCompareAndSwap64:
 		v.Op = OpRISCV64LoweredAtomicCas64
 		return true
@@ -776,6 +775,27 @@
 		return true
 	}
 }
+func rewriteValueRISCV64_OpAtomicCompareAndSwap32(v *Value) bool {
+	v_3 := v.Args[3]
+	v_2 := v.Args[2]
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (AtomicCompareAndSwap32 ptr old new mem)
+	// result: (LoweredAtomicCas32 ptr (SignExt32to64 old) new mem)
+	for {
+		ptr := v_0
+		old := v_1
+		new := v_2
+		mem := v_3
+		v.reset(OpRISCV64LoweredAtomicCas32)
+		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
+		v0.AddArg(old)
+		v.AddArg4(ptr, v0, new, mem)
+		return true
+	}
+}
 func rewriteValueRISCV64_OpAtomicOr8(v *Value) bool {
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go
index 40d6e5d..9a0348e 100644
--- a/src/cmd/compile/internal/types2/expr.go
+++ b/src/cmd/compile/internal/types2/expr.go
@@ -1103,26 +1103,50 @@
 		return
 	}
 
-	// TODO(gri) make canMix more efficient - called for each binary operation
-	canMix := func(x, y *operand) bool {
+	// mayConvert reports whether the operands x and y may
+	// possibly have matching types after converting one
+	// untyped operand to the type of the other.
+	// If mayConvert returns true, we try to convert the
+	// operands to each other's types, and if that fails
+	// we report a conversion failure.
+	// If mayConvert returns false, we continue without an
+	// attempt at conversion, and if the operand types are
+	// not compatible, we report a type mismatch error.
+	mayConvert := func(x, y *operand) bool {
+		// If both operands are typed, there's no need for an implicit conversion.
+		if isTyped(x.typ) && isTyped(y.typ) {
+			return false
+		}
+		// An untyped operand may convert to its default type when paired with an empty interface
+		// TODO(gri) This should only matter for comparisons (the only binary operation that is
+		//           valid with interfaces), but in that case the assignability check should take
+		//           care of the conversion. Verify and possibly eliminate this extra test.
 		if isNonTypeParamInterface(x.typ) || isNonTypeParamInterface(y.typ) {
 			return true
 		}
+		// A boolean type can only convert to another boolean type.
 		if allBoolean(x.typ) != allBoolean(y.typ) {
 			return false
 		}
+		// A string type can only convert to another string type.
 		if allString(x.typ) != allString(y.typ) {
 			return false
 		}
-		if x.isNil() && !hasNil(y.typ) {
-			return false
+		// Untyped nil can only convert to a type that has a nil.
+		if x.isNil() {
+			return hasNil(y.typ)
 		}
-		if y.isNil() && !hasNil(x.typ) {
+		if y.isNil() {
+			return hasNil(x.typ)
+		}
+		// An untyped operand cannot convert to a pointer.
+		// TODO(gri) generalize to type parameters
+		if isPointer(x.typ) || isPointer(y.typ) {
 			return false
 		}
 		return true
 	}
-	if canMix(x, &y) {
+	if mayConvert(x, &y) {
 		check.convertUntyped(x, y.typ)
 		if x.mode == invalid {
 			return
diff --git a/src/cmd/compile/internal/types2/infer.go b/src/cmd/compile/internal/types2/infer.go
index 1075457..5750ece 100644
--- a/src/cmd/compile/internal/types2/infer.go
+++ b/src/cmd/compile/internal/types2/infer.go
@@ -89,34 +89,22 @@
 		//    f(p)
 		//  }
 		//
-		// We can turn the first example into the second example by renaming type
-		// parameters in the original signature to give them a new identity. As an
-		// optimization, we do this only for self-recursive calls.
-
-		// We can detect if we are in a self-recursive call by comparing the
-		// identity of the first type parameter in the current function with the
-		// first type parameter in tparams. This works because type parameters are
-		// unique to their type parameter list.
-		selfRecursive := check.sig != nil && check.sig.tparams.Len() > 0 && tparams[0] == check.sig.tparams.At(0)
-
-		if selfRecursive {
-			// In self-recursive inference, rename the type parameters with new type
-			// parameters that are the same but for their pointer identity.
-			tparams2 := make([]*TypeParam, len(tparams))
-			for i, tparam := range tparams {
-				tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
-				tparams2[i] = NewTypeParam(tname, nil)
-				tparams2[i].index = tparam.index // == i
-			}
-
-			renameMap := makeRenameMap(tparams, tparams2)
-			for i, tparam := range tparams {
-				tparams2[i].bound = check.subst(pos, tparam.bound, renameMap, nil, check.context())
-			}
-
-			tparams = tparams2
-			params = check.subst(pos, params, renameMap, nil, check.context()).(*Tuple)
+		// We turn the first example into the second example by renaming type
+		// parameters in the original signature to give them a new identity.
+		tparams2 := make([]*TypeParam, len(tparams))
+		for i, tparam := range tparams {
+			tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
+			tparams2[i] = NewTypeParam(tname, nil)
+			tparams2[i].index = tparam.index // == i
 		}
+
+		renameMap := makeRenameMap(tparams, tparams2)
+		for i, tparam := range tparams {
+			tparams2[i].bound = check.subst(pos, tparam.bound, renameMap, nil, check.context())
+		}
+
+		tparams = tparams2
+		params = check.subst(pos, params, renameMap, nil, check.context()).(*Tuple)
 	}
 
 	// If we have more than 2 arguments, we may have arguments with named and unnamed types.
diff --git a/src/cmd/compile/internal/types2/typeset.go b/src/cmd/compile/internal/types2/typeset.go
index 391ea8c..673cadc 100644
--- a/src/cmd/compile/internal/types2/typeset.go
+++ b/src/cmd/compile/internal/types2/typeset.go
@@ -352,7 +352,7 @@
 		i := 0
 		for _, t := range terms {
 			assert(t.typ != nil)
-			if Comparable(t.typ) {
+			if comparable(t.typ, false /* strictly comparable */, nil, nil) {
 				terms[i] = t
 				i++
 			}
diff --git a/src/cmd/covdata/tool_test.go b/src/cmd/covdata/tool_test.go
index 9396266..42334ea 100644
--- a/src/cmd/covdata/tool_test.go
+++ b/src/cmd/covdata/tool_test.go
@@ -111,6 +111,8 @@
 	}
 }
 
+const mainPkgPath = "prog"
+
 func buildProg(t *testing.T, prog string, dir string, tag string, flags []string) (string, string) {
 	// Create subdirs.
 	subdir := filepath.Join(dir, prog+"dir"+tag)
@@ -132,7 +134,7 @@
 
 	// Emit go.mod.
 	mod := filepath.Join(subdir, "go.mod")
-	modsrc := "\nmodule prog\n\ngo 1.19\n"
+	modsrc := "\nmodule " + mainPkgPath + "\n\ngo 1.19\n"
 	if err := os.WriteFile(mod, []byte(modsrc), 0666); err != nil {
 		t.Fatal(err)
 	}
@@ -305,7 +307,7 @@
 
 func testDump(t *testing.T, s state) {
 	// Run the dumper on the two dirs we generated.
-	dargs := []string{"-pkg=main", "-live", "-i=" + s.outdirs[0] + "," + s.outdirs[1]}
+	dargs := []string{"-pkg=" + mainPkgPath, "-live", "-i=" + s.outdirs[0] + "," + s.outdirs[1]}
 	lines := runToolOp(t, s, "debugdump", dargs)
 
 	// Sift through the output to make sure it has some key elements.
@@ -319,7 +321,7 @@
 		},
 		{
 			"main package",
-			regexp.MustCompile(`^Package path: main\s*$`),
+			regexp.MustCompile(`^Package path: ` + mainPkgPath + `\s*$`),
 		},
 		{
 			"main function",
@@ -337,7 +339,7 @@
 			}
 		}
 		if !found {
-			t.Errorf("dump output regexp match failed for %s", testpoint.tag)
+			t.Errorf("dump output regexp match failed for %q", testpoint.tag)
 			bad = true
 		}
 	}
@@ -348,7 +350,7 @@
 
 func testPercent(t *testing.T, s state) {
 	// Run the dumper on the two dirs we generated.
-	dargs := []string{"-pkg=main", "-i=" + s.outdirs[0] + "," + s.outdirs[1]}
+	dargs := []string{"-pkg=" + mainPkgPath, "-i=" + s.outdirs[0] + "," + s.outdirs[1]}
 	lines := runToolOp(t, s, "percent", dargs)
 
 	// Sift through the output to make sure it has the needful.
@@ -380,11 +382,12 @@
 		dumplines(lines)
 	}
 }
+
 func testPkgList(t *testing.T, s state) {
 	dargs := []string{"-i=" + s.outdirs[0] + "," + s.outdirs[1]}
 	lines := runToolOp(t, s, "pkglist", dargs)
 
-	want := []string{"main", "prog/dep"}
+	want := []string{mainPkgPath, mainPkgPath + "/dep"}
 	bad := false
 	if len(lines) != 2 {
 		t.Errorf("expect pkglist to return two lines")
@@ -405,7 +408,7 @@
 
 func testTextfmt(t *testing.T, s state) {
 	outf := s.dir + "/" + "t.txt"
-	dargs := []string{"-pkg=main", "-i=" + s.outdirs[0] + "," + s.outdirs[1],
+	dargs := []string{"-pkg=" + mainPkgPath, "-i=" + s.outdirs[0] + "," + s.outdirs[1],
 		"-o", outf}
 	lines := runToolOp(t, s, "textfmt", dargs)
 
@@ -426,7 +429,7 @@
 		dumplines(lines[0:10])
 		t.Errorf("textfmt: want %s got %s", want0, lines[0])
 	}
-	want1 := "prog/prog1.go:13.14,15.2 1 1"
+	want1 := mainPkgPath + "/prog1.go:13.14,15.2 1 1"
 	if lines[1] != want1 {
 		dumplines(lines[0:10])
 		t.Errorf("textfmt: want %s got %s", want1, lines[1])
@@ -571,7 +574,7 @@
 			nonzero: true,
 		},
 	}
-	flags := []string{"-live", "-pkg=main"}
+	flags := []string{"-live", "-pkg=" + mainPkgPath}
 	runDumpChecks(t, s, outdir, flags, testpoints)
 }
 
@@ -585,7 +588,7 @@
 	// based on package.
 	ins := fmt.Sprintf("-i=%s,%s", indir1, indir2)
 	out := fmt.Sprintf("-o=%s", outdir)
-	margs := []string{"-pkg=prog/dep", ins, out}
+	margs := []string{"-pkg=" + mainPkgPath + "/dep", ins, out}
 	lines := runToolOp(t, s, "merge", margs)
 	if len(lines) != 0 {
 		t.Errorf("merge run produced %d lines of unexpected output", len(lines))
@@ -600,9 +603,9 @@
 		t.Fatalf("dump run produced no output")
 	}
 	want := map[string]int{
-		"Package path: prog/dep": 0,
-		"Func: Dep1":             0,
-		"Func: PDep":             0,
+		"Package path: " + mainPkgPath + "/dep": 0,
+		"Func: Dep1":                            0,
+		"Func: PDep":                            0,
 	}
 	bad := false
 	for _, line := range lines {
@@ -696,7 +699,7 @@
 		},
 	}
 
-	flags := []string{"-live", "-pkg=main"}
+	flags := []string{"-live", "-pkg=" + mainPkgPath}
 	runDumpChecks(t, s, moutdir, flags, testpoints)
 }
 
@@ -717,7 +720,7 @@
 	}
 
 	// Dump the files in the subtract output dir and examine the result.
-	dargs := []string{"-pkg=main", "-live", "-i=" + soutdir}
+	dargs := []string{"-pkg=" + mainPkgPath, "-live", "-i=" + soutdir}
 	lines = runToolOp(t, s, "debugdump", dargs)
 	if len(lines) == 0 {
 		t.Errorf("dump run produced no output")
@@ -774,7 +777,7 @@
 	}
 
 	// Dump the files in the subtract output dir and examine the result.
-	dargs := []string{"-pkg=main", "-live", "-i=" + ioutdir}
+	dargs := []string{"-pkg=" + mainPkgPath, "-live", "-i=" + ioutdir}
 	lines = runToolOp(t, s, "debugdump", dargs)
 	if len(lines) == 0 {
 		t.Errorf("dump run produced no output")
diff --git a/src/cmd/cover/cover.go b/src/cmd/cover/cover.go
index 989c109..f4f225e 100644
--- a/src/cmd/cover/cover.go
+++ b/src/cmd/cover/cover.go
@@ -542,9 +542,6 @@
 	if *pkgcfg != "" {
 		pp := pkgconfig.PkgPath
 		pn := pkgconfig.PkgName
-		if pn == "main" {
-			pp = "main"
-		}
 		mp := pkgconfig.ModulePath
 		mdb, err := encodemeta.NewCoverageMetaDataBuilder(pp, pn, mp)
 		if err != nil {
diff --git a/src/cmd/go/internal/test/test.go b/src/cmd/go/internal/test/test.go
index 5a56009..0051970 100644
--- a/src/cmd/go/internal/test/test.go
+++ b/src/cmd/go/internal/test/test.go
@@ -1306,6 +1306,7 @@
 		cmd.Env = env
 	}
 
+	base.StartSigHandlers()
 	t0 := time.Now()
 	err = cmd.Start()
 
@@ -1314,7 +1315,6 @@
 	// running.
 	if err == nil {
 		tick := time.NewTimer(testKillTimeout)
-		base.StartSigHandlers()
 		done := make(chan error)
 		go func() {
 			done <- cmd.Wait()
diff --git a/src/cmd/go/terminal_test.go b/src/cmd/go/terminal_test.go
index 03ca772..a5ad919 100644
--- a/src/cmd/go/terminal_test.go
+++ b/src/cmd/go/terminal_test.go
@@ -71,31 +71,37 @@
 	cmd.Env = append(cmd.Environ(), "GO_TEST_TERMINAL_PASSTHROUGH=1")
 	cmd.Stdout = w
 	cmd.Stderr = w
+
+	// The behavior of reading from a PTY after the child closes it is very
+	// strange: on Linux, Read returns EIO, and on at least some versions of
+	// macOS, unread output may be discarded (see https://go.dev/issue/57141).
+	//
+	// To avoid that situation, we keep the child process running until the
+	// parent has finished reading from the PTY, at which point we unblock the
+	// child by closing its stdin pipe.
+	stdin, err := cmd.StdinPipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+
 	t.Logf("running %s", cmd)
-	err := cmd.Start()
+	err = cmd.Start()
 	if err != nil {
 		t.Fatalf("starting subprocess: %s", err)
 	}
 	w.Close()
-	// Read the subprocess output. The behavior of reading from a PTY after the
-	// child closes it is very strange (e.g., on Linux, read returns EIO), so we
-	// ignore errors as long as we get everything we need. We still try to read
-	// all of the output so we can report it in case of failure.
-	buf, err := io.ReadAll(r)
-	if len(buf) != 2 || !(buf[0] == '1' || buf[0] == 'X') || !(buf[1] == '2' || buf[1] == 'X') {
-		t.Errorf("expected exactly 2 bytes matching [1X][2X]")
-		if err != nil {
-			// An EIO here might be expected depending on OS.
-			t.Errorf("error reading from subprocess: %s", err)
+	t.Cleanup(func() {
+		stdin.Close()
+		if err := cmd.Wait(); err != nil {
+			t.Errorf("suprocess failed with: %s", err)
 		}
-	}
-	err = cmd.Wait()
-	if err != nil {
-		t.Errorf("suprocess failed with: %s", err)
-	}
-	if t.Failed() {
-		t.Logf("subprocess output:\n%s", string(buf))
-		t.FailNow()
+	})
+
+	buf := make([]byte, 2)
+	n, err := io.ReadFull(r, buf)
+	if err != nil || !(buf[0] == '1' || buf[0] == 'X') || !(buf[1] == '2' || buf[1] == 'X') {
+		t.Logf("read error: %v", err)
+		t.Fatalf("expected 2 bytes matching `[1X][2X]`; got %q", buf[:n])
 	}
 	return buf[0] == '1', buf[1] == '2'
 }
@@ -106,14 +112,19 @@
 	}
 
 	if term.IsTerminal(1) {
-		print("1")
+		os.Stdout.WriteString("1")
 	} else {
-		print("X")
+		os.Stdout.WriteString("X")
 	}
 	if term.IsTerminal(2) {
-		print("2")
+		os.Stdout.WriteString("2")
 	} else {
-		print("X")
+		os.Stdout.WriteString("X")
 	}
+
+	// Before exiting, wait for the parent process to read the PTY output,
+	// at which point it will close stdin.
+	io.Copy(io.Discard, os.Stdin)
+
 	os.Exit(0)
 }
diff --git a/src/cmd/go/testdata/script/cover_build_cmdline_pkgs.txt b/src/cmd/go/testdata/script/cover_build_cmdline_pkgs.txt
index 4748a85..ba38263 100644
--- a/src/cmd/go/testdata/script/cover_build_cmdline_pkgs.txt
+++ b/src/cmd/go/testdata/script/cover_build_cmdline_pkgs.txt
@@ -26,7 +26,7 @@
 # Check to make sure we instrumented just the main package, not
 # any dependencies.
 go tool covdata pkglist -i=$WORK/covdata
-stdout main
+stdout cmd/nm
 ! stdout cmd/internal/goobj pkglist.txt
 
 # ... now collect a coverage profile from a Go file
@@ -41,7 +41,7 @@
 
 # Check to make sure we instrumented just the main package.
 go tool covdata pkglist -i=$WORK/covdata2
-stdout main
+stdout command-line-arguments
 ! stdout fmt
 
 -- go.mod --
diff --git a/src/cmd/go/testdata/script/cover_main_import_path.txt b/src/cmd/go/testdata/script/cover_main_import_path.txt
new file mode 100644
index 0000000..3a2f3c3
--- /dev/null
+++ b/src/cmd/go/testdata/script/cover_main_import_path.txt
@@ -0,0 +1,54 @@
+
+# This test is intended to verify that coverage reporting is consistent
+# between "go test -cover" and "go build -cover" with respect to how
+# the "main" package is handled. See issue 57169 for details.
+
+[short] skip
+
+# Build this program with -cover and run to collect a profile.
+
+go build -cover -o $WORK/prog.exe .
+
+# Save off old GOCOVERDIR setting
+env SAVEGOCOVERDIR=$GOCOVERDIR
+
+mkdir $WORK/covdata
+env GOCOVERDIR=$WORK/covdata
+exec $WORK/prog.exe
+
+# Restore previous GOCOVERDIR setting
+env GOCOVERDIR=$SAVEGOCOVERDIR
+
+# Report percent lines covered.
+go tool covdata percent -i=$WORK/covdata
+stdout '\s*mainwithtest\s+coverage:'
+! stdout 'main\s+coverage:'
+
+# Go test -cover should behave the same way.
+go test -cover .
+stdout 'ok\s+mainwithtest\s+\S+\s+coverage:'
+! stdout 'ok\s+main\s+.*'
+
+
+-- go.mod --
+module mainwithtest
+
+go 1.20
+-- mymain.go --
+package main
+
+func main() {
+	println("hi mom")
+}
+
+func Mainer() int {
+	return 42
+}
+-- main_test.go --
+package main
+
+import "testing"
+
+func TestCoverage(t *testing.T) {
+	println(Mainer())
+}
diff --git a/src/cmd/go/testdata/script/test2json_interrupt.txt b/src/cmd/go/testdata/script/test2json_interrupt.txt
index 5828e86..763c336 100644
--- a/src/cmd/go/testdata/script/test2json_interrupt.txt
+++ b/src/cmd/go/testdata/script/test2json_interrupt.txt
@@ -7,8 +7,8 @@
 stdout -count=1 '"Action":"pass","Package":"example","Elapsed":'
 
 mkdir $WORK/fuzzcache
-go test -c . -fuzz=. -o test2json_interrupt_obj
-? go tool test2json -p example -t ./test2json_interrupt_obj -test.v -test.paniconexit0 -test.fuzzcachedir $WORK/fuzzcache -test.fuzz FuzzInterrupt -test.run '^$' -test.parallel 1
+go test -c . -fuzz=. -o example_test.exe
+? go tool test2json -p example -t ./example_test.exe -test.v -test.paniconexit0 -test.fuzzcachedir $WORK/fuzzcache -test.fuzz FuzzInterrupt -test.run '^$' -test.parallel 1
 stdout -count=1 '"Action":"pass","Package":"example","Test":"FuzzInterrupt"'
 stdout -count=1 '"Action":"pass","Package":"example","Elapsed":'
 
@@ -37,19 +37,22 @@
 		os.Setenv("GO_TEST_INTERRUPT_PIDS", fmt.Sprintf("%d,%d", ppid, pid))
 	}
 
+	sentInterrupt := false
 	f.Fuzz(func(t *testing.T, orig string) {
-		// Simulate a ctrl-C on the keyboard by sending SIGINT
-		// to the main test process and its parent.
-		for _, pid := range strings.Split(pids, ",") {
-			i, err := strconv.Atoi(pid)
-			if err != nil {
-				t.Fatal(err)
-			}
-			if p, err := os.FindProcess(i); err == nil {
-				p.Signal(os.Interrupt)
-				time.Sleep(10 * time.Millisecond)
-				pids = ""  // Only interrupt once.
+		if !sentInterrupt {
+			// Simulate a ctrl-C on the keyboard by sending SIGINT
+			// to the main test process and its parent.
+			for _, pid := range strings.Split(pids, ",") {
+				i, err := strconv.Atoi(pid)
+				if err != nil {
+					t.Fatal(err)
+				}
+				if p, err := os.FindProcess(i); err == nil {
+					p.Signal(os.Interrupt)
+					sentInterrupt = true // Only send interrupts once.
+				}
 			}
 		}
+		time.Sleep(1 * time.Millisecond)  // Delay the fuzzer a bit to avoid wasting CPU.
 	})
 }
diff --git a/src/cmd/link/internal/amd64/obj.go b/src/cmd/link/internal/amd64/obj.go
index f46045b..c5e2117 100644
--- a/src/cmd/link/internal/amd64/obj.go
+++ b/src/cmd/link/internal/amd64/obj.go
@@ -65,7 +65,7 @@
 		TLSIEtoLE:        tlsIEtoLE,
 
 		Linuxdynld:     "/lib64/ld-linux-x86-64.so.2",
-		LinuxdynldMusl: "/lib/ld-musl-x84_64.so.1",
+		LinuxdynldMusl: "/lib/ld-musl-x86_64.so.1",
 		Freebsddynld:   "/libexec/ld-elf.so.1",
 		Openbsddynld:   "/usr/libexec/ld.so",
 		Netbsddynld:    "/libexec/ld.elf_so",
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
index faae153..94f8fc3 100644
--- a/src/cmd/link/internal/ld/data.go
+++ b/src/cmd/link/internal/ld/data.go
@@ -1860,9 +1860,9 @@
 
 	// Coverage instrumentation counters for libfuzzer.
 	if len(state.data[sym.SLIBFUZZER_8BIT_COUNTER]) > 0 {
-		sect := state.allocateNamedSectionAndAssignSyms(&Segdata, "__sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, sym.Sxxx, 06)
-		ldr.SetSymSect(ldr.LookupOrCreateSym("__start___sancov_cntrs", 0), sect)
-		ldr.SetSymSect(ldr.LookupOrCreateSym("__stop___sancov_cntrs", 0), sect)
+		sect := state.allocateNamedSectionAndAssignSyms(&Segdata, ".go.fuzzcntrs", sym.SLIBFUZZER_8BIT_COUNTER, sym.Sxxx, 06)
+		ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.__start___sancov_cntrs", 0), sect)
+		ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.__stop___sancov_cntrs", 0), sect)
 		ldr.SetSymSect(ldr.LookupOrCreateSym("internal/fuzz._counters", 0), sect)
 		ldr.SetSymSect(ldr.LookupOrCreateSym("internal/fuzz._ecounters", 0), sect)
 	}
@@ -2643,7 +2643,7 @@
 			bss = s
 		case ".noptrbss":
 			noptrbss = s
-		case "__sancov_cntrs":
+		case ".go.fuzzcntrs":
 			fuzzCounters = s
 		}
 	}
@@ -2764,8 +2764,8 @@
 	ctxt.xdefine("runtime.end", sym.SBSS, int64(Segdata.Vaddr+Segdata.Length))
 
 	if fuzzCounters != nil {
-		ctxt.xdefine("__start___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr))
-		ctxt.xdefine("__stop___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr+fuzzCounters.Length))
+		ctxt.xdefine("runtime.__start___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr))
+		ctxt.xdefine("runtime.__stop___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr+fuzzCounters.Length))
 		ctxt.xdefine("internal/fuzz._counters", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr))
 		ctxt.xdefine("internal/fuzz._ecounters", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr+fuzzCounters.Length))
 	}
diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go
index 082adcc..a1ae7ea 100644
--- a/src/cmd/link/internal/ld/elf.go
+++ b/src/cmd/link/internal/ld/elf.go
@@ -1371,7 +1371,7 @@
 	shstrtab.Addstring(".data")
 	shstrtab.Addstring(".bss")
 	shstrtab.Addstring(".noptrbss")
-	shstrtab.Addstring("__sancov_cntrs")
+	shstrtab.Addstring(".go.fuzzcntrs")
 	shstrtab.Addstring(".go.buildinfo")
 	if ctxt.IsMIPS() {
 		shstrtab.Addstring(".MIPS.abiflags")
diff --git a/src/crypto/x509/internal/macos/corefoundation.go b/src/crypto/x509/internal/macos/corefoundation.go
index 5387c5a..b4032a5 100644
--- a/src/crypto/x509/internal/macos/corefoundation.go
+++ b/src/crypto/x509/internal/macos/corefoundation.go
@@ -186,6 +186,13 @@
 }
 func x509_CFErrorCopyDescription_trampoline()
 
+//go:cgo_import_dynamic x509_CFErrorGetCode CFErrorGetCode "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
+
+func CFErrorGetCode(errRef CFRef) int {
+	return int(syscall(abi.FuncPCABI0(x509_CFErrorGetCode_trampoline), uintptr(errRef), 0, 0, 0, 0, 0))
+}
+func x509_CFErrorGetCode_trampoline()
+
 //go:cgo_import_dynamic x509_CFStringCreateExternalRepresentation CFStringCreateExternalRepresentation "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
 
 func CFStringCreateExternalRepresentation(strRef CFRef) (CFRef, error) {
diff --git a/src/crypto/x509/internal/macos/corefoundation.s b/src/crypto/x509/internal/macos/corefoundation.s
index d69f72f..49cd084 100644
--- a/src/crypto/x509/internal/macos/corefoundation.s
+++ b/src/crypto/x509/internal/macos/corefoundation.s
@@ -37,5 +37,7 @@
 	JMP x509_CFDataCreate(SB)
 TEXT ·x509_CFErrorCopyDescription_trampoline(SB),NOSPLIT,$0-0
 	JMP x509_CFErrorCopyDescription(SB)
+TEXT ·x509_CFErrorGetCode_trampoline(SB),NOSPLIT,$0-0
+	JMP x509_CFErrorGetCode(SB)
 TEXT ·x509_CFStringCreateExternalRepresentation_trampoline(SB),NOSPLIT,$0-0
 	JMP x509_CFStringCreateExternalRepresentation(SB)
diff --git a/src/crypto/x509/internal/macos/security.go b/src/crypto/x509/internal/macos/security.go
index 0fc218c..a6972c0 100644
--- a/src/crypto/x509/internal/macos/security.go
+++ b/src/crypto/x509/internal/macos/security.go
@@ -8,7 +8,6 @@
 
 import (
 	"errors"
-	"fmt"
 	"internal/abi"
 	"strconv"
 	"unsafe"
@@ -52,6 +51,15 @@
 	SecTrustSettingsDomainSystem
 )
 
+const (
+	// various macOS error codes that can be returned from
+	// SecTrustEvaluateWithError that we can map to Go cert
+	// verification error types.
+	ErrSecCertificateExpired = -67818
+	ErrSecHostNameMismatch   = -67602
+	ErrSecNotTrusted         = -67843
+)
+
 type OSStatus struct {
 	call   string
 	status int32
@@ -191,17 +199,18 @@
 
 //go:cgo_import_dynamic x509_SecTrustEvaluateWithError SecTrustEvaluateWithError "/System/Library/Frameworks/Security.framework/Versions/A/Security"
 
-func SecTrustEvaluateWithError(trustObj CFRef) error {
+func SecTrustEvaluateWithError(trustObj CFRef) (int, error) {
 	var errRef CFRef
 	ret := syscall(abi.FuncPCABI0(x509_SecTrustEvaluateWithError_trampoline), uintptr(trustObj), uintptr(unsafe.Pointer(&errRef)), 0, 0, 0, 0)
 	if int32(ret) != 1 {
 		errStr := CFErrorCopyDescription(errRef)
-		err := fmt.Errorf("x509: %s", CFStringToString(errStr))
+		err := errors.New(CFStringToString(errStr))
+		errCode := CFErrorGetCode(errRef)
 		CFRelease(errRef)
 		CFRelease(errStr)
-		return err
+		return errCode, err
 	}
-	return nil
+	return 0, nil
 }
 func x509_SecTrustEvaluateWithError_trampoline()
 
diff --git a/src/crypto/x509/root_darwin.go b/src/crypto/x509/root_darwin.go
index 20f627c..de2ff89 100644
--- a/src/crypto/x509/root_darwin.go
+++ b/src/crypto/x509/root_darwin.go
@@ -7,6 +7,7 @@
 import (
 	macOS "crypto/x509/internal/macos"
 	"errors"
+	"fmt"
 )
 
 func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
@@ -57,8 +58,17 @@
 	// always enforce its SCT requirements, and there are still _some_ people
 	// using TLS or OCSP for that.
 
-	if err := macOS.SecTrustEvaluateWithError(trustObj); err != nil {
-		return nil, err
+	if ret, err := macOS.SecTrustEvaluateWithError(trustObj); err != nil {
+		switch ret {
+		case macOS.ErrSecCertificateExpired:
+			return nil, CertificateInvalidError{c, Expired, err.Error()}
+		case macOS.ErrSecHostNameMismatch:
+			return nil, HostnameError{c, opts.DNSName}
+		case macOS.ErrSecNotTrusted:
+			return nil, UnknownAuthorityError{Cert: c}
+		default:
+			return nil, fmt.Errorf("x509: %s", err)
+		}
 	}
 
 	chain := [][]*Certificate{{}}
diff --git a/src/crypto/x509/root_darwin_test.go b/src/crypto/x509/root_darwin_test.go
index 90a464f..299cecf 100644
--- a/src/crypto/x509/root_darwin_test.go
+++ b/src/crypto/x509/root_darwin_test.go
@@ -42,23 +42,23 @@
 		{
 			name:        "expired leaf",
 			host:        "expired.badssl.com",
-			expectedErr: "x509: “*.badssl.com” certificate is expired",
+			expectedErr: "x509: certificate has expired or is not yet valid: “*.badssl.com” certificate is expired",
 		},
 		{
 			name:        "wrong host for leaf",
 			host:        "wrong.host.badssl.com",
 			verifyName:  "wrong.host.badssl.com",
-			expectedErr: "x509: “*.badssl.com” certificate name does not match input",
+			expectedErr: "x509: certificate is valid for *.badssl.com, badssl.com, not wrong.host.badssl.com",
 		},
 		{
 			name:        "self-signed leaf",
 			host:        "self-signed.badssl.com",
-			expectedErr: "x509: “*.badssl.com” certificate is not trusted",
+			expectedErr: "x509: certificate signed by unknown authority",
 		},
 		{
 			name:        "untrusted root",
 			host:        "untrusted-root.badssl.com",
-			expectedErr: "x509: “BadSSL Untrusted Root Certificate Authority” certificate is not trusted",
+			expectedErr: "x509: certificate signed by unknown authority",
 		},
 		{
 			name:        "revoked leaf",
@@ -74,7 +74,7 @@
 			name:        "expired leaf (custom time)",
 			host:        "google.com",
 			verifyTime:  time.Time{}.Add(time.Hour),
-			expectedErr: "x509: “*.google.com” certificate is expired",
+			expectedErr: "x509: certificate has expired or is not yet valid: “*.google.com” certificate is expired",
 		},
 		{
 			name:       "valid chain (custom time)",
diff --git a/src/debug/buildinfo/buildinfo.go b/src/debug/buildinfo/buildinfo.go
index 255e6d3..8bc5753 100644
--- a/src/debug/buildinfo/buildinfo.go
+++ b/src/debug/buildinfo/buildinfo.go
@@ -192,8 +192,10 @@
 		var readPtr func([]byte) uint64
 		if ptrSize == 4 {
 			readPtr = func(b []byte) uint64 { return uint64(bo.Uint32(b)) }
-		} else {
+		} else if ptrSize == 8 {
 			readPtr = bo.Uint64
+		} else {
+			return "", "", errNotGoExe
 		}
 		vers = readString(x, ptrSize, readPtr, readPtr(data[16:]))
 		mod = readString(x, ptrSize, readPtr, readPtr(data[16+ptrSize:]))
diff --git a/src/debug/buildinfo/buildinfo_test.go b/src/debug/buildinfo/buildinfo_test.go
index ae04b4c..290e370 100644
--- a/src/debug/buildinfo/buildinfo_test.go
+++ b/src/debug/buildinfo/buildinfo_test.go
@@ -248,6 +248,18 @@
 	}
 }
 
+// FuzzIssue57002 is a regression test for golang.org/issue/57002.
+//
+// The cause of issue 57002 is when pointerSize is not being checked,
+// the read can panic with slice bounds out of range
+func FuzzIssue57002(f *testing.F) {
+	// input from issue
+	f.Add([]byte{0x4d, 0x5a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x45, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x20, 0x20, 0x20, 0x20, 0x0, 0x0, 0x0, 0x0, 0x20, 0x3f, 0x0, 0x20, 0x0, 0x0, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0x20, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x9, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x20, 0x20, 0x20, 0x20, 0xef, 0x20, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, 0x0, 0x2, 0x0, 0x20, 0x0, 0x0, 0x9, 0x0, 0x4, 0x0, 0x20, 0xf6, 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x1, 0x0, 0x0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xa, 0x20, 0xa, 0x20, 0x20, 0x20, 0xff, 0x20, 0x20, 0xff, 0x20, 0x47, 0x6f, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x66, 0x3a, 0xde, 0xb5, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x7f, 0x7f, 0x7f, 0x20, 0xf4, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x20, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x20, 0x20, 0x20, 0x20, 0x0, 0x0, 0x0, 0x0, 0x20, 0x3f, 0x27, 0x20, 0x0, 0xd, 0x0, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0x20, 0x20, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0, 0x20, 0x20, 0x0, 0x0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20})
+	f.Fuzz(func(t *testing.T, input []byte) {
+		buildinfo.Read(bytes.NewReader(input))
+	})
+}
+
 // TestIssue54968 is a regression test for golang.org/issue/54968.
 //
 // The cause of issue 54968 is when the first buildInfoMagic is invalid, it
diff --git a/src/go/types/expr.go b/src/go/types/expr.go
index da9cd67..e09b461 100644
--- a/src/go/types/expr.go
+++ b/src/go/types/expr.go
@@ -1084,26 +1084,50 @@
 		return
 	}
 
-	// TODO(gri) make canMix more efficient - called for each binary operation
-	canMix := func(x, y *operand) bool {
+	// mayConvert reports whether the operands x and y may
+	// possibly have matching types after converting one
+	// untyped operand to the type of the other.
+	// If mayConvert returns true, we try to convert the
+	// operands to each other's types, and if that fails
+	// we report a conversion failure.
+	// If mayConvert returns false, we continue without an
+	// attempt at conversion, and if the operand types are
+	// not compatible, we report a type mismatch error.
+	mayConvert := func(x, y *operand) bool {
+		// If both operands are typed, there's no need for an implicit conversion.
+		if isTyped(x.typ) && isTyped(y.typ) {
+			return false
+		}
+		// An untyped operand may convert to its default type when paired with an empty interface
+		// TODO(gri) This should only matter for comparisons (the only binary operation that is
+		//           valid with interfaces), but in that case the assignability check should take
+		//           care of the conversion. Verify and possibly eliminate this extra test.
 		if isNonTypeParamInterface(x.typ) || isNonTypeParamInterface(y.typ) {
 			return true
 		}
+		// A boolean type can only convert to another boolean type.
 		if allBoolean(x.typ) != allBoolean(y.typ) {
 			return false
 		}
+		// A string type can only convert to another string type.
 		if allString(x.typ) != allString(y.typ) {
 			return false
 		}
-		if x.isNil() && !hasNil(y.typ) {
-			return false
+		// Untyped nil can only convert to a type that has a nil.
+		if x.isNil() {
+			return hasNil(y.typ)
 		}
-		if y.isNil() && !hasNil(x.typ) {
+		if y.isNil() {
+			return hasNil(x.typ)
+		}
+		// An untyped operand cannot convert to a pointer.
+		// TODO(gri) generalize to type parameters
+		if isPointer(x.typ) || isPointer(y.typ) {
 			return false
 		}
 		return true
 	}
-	if canMix(x, &y) {
+	if mayConvert(x, &y) {
 		check.convertUntyped(x, y.typ)
 		if x.mode == invalid {
 			return
diff --git a/src/go/types/infer.go b/src/go/types/infer.go
index 1c1d4e0..dc87902 100644
--- a/src/go/types/infer.go
+++ b/src/go/types/infer.go
@@ -89,34 +89,22 @@
 		//    f(p)
 		//  }
 		//
-		// We can turn the first example into the second example by renaming type
-		// parameters in the original signature to give them a new identity. As an
-		// optimization, we do this only for self-recursive calls.
-
-		// We can detect if we are in a self-recursive call by comparing the
-		// identity of the first type parameter in the current function with the
-		// first type parameter in tparams. This works because type parameters are
-		// unique to their type parameter list.
-		selfRecursive := check.sig != nil && check.sig.tparams.Len() > 0 && tparams[0] == check.sig.tparams.At(0)
-
-		if selfRecursive {
-			// In self-recursive inference, rename the type parameters with new type
-			// parameters that are the same but for their pointer identity.
-			tparams2 := make([]*TypeParam, len(tparams))
-			for i, tparam := range tparams {
-				tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
-				tparams2[i] = NewTypeParam(tname, nil)
-				tparams2[i].index = tparam.index // == i
-			}
-
-			renameMap := makeRenameMap(tparams, tparams2)
-			for i, tparam := range tparams {
-				tparams2[i].bound = check.subst(posn.Pos(), tparam.bound, renameMap, nil, check.context())
-			}
-
-			tparams = tparams2
-			params = check.subst(posn.Pos(), params, renameMap, nil, check.context()).(*Tuple)
+		// We turn the first example into the second example by renaming type
+		// parameters in the original signature to give them a new identity.
+		tparams2 := make([]*TypeParam, len(tparams))
+		for i, tparam := range tparams {
+			tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
+			tparams2[i] = NewTypeParam(tname, nil)
+			tparams2[i].index = tparam.index // == i
 		}
+
+		renameMap := makeRenameMap(tparams, tparams2)
+		for i, tparam := range tparams {
+			tparams2[i].bound = check.subst(posn.Pos(), tparam.bound, renameMap, nil, check.context())
+		}
+
+		tparams = tparams2
+		params = check.subst(posn.Pos(), params, renameMap, nil, check.context()).(*Tuple)
 	}
 
 	// If we have more than 2 arguments, we may have arguments with named and unnamed types.
diff --git a/src/go/types/typeset.go b/src/go/types/typeset.go
index 35a3297..d68446d 100644
--- a/src/go/types/typeset.go
+++ b/src/go/types/typeset.go
@@ -350,7 +350,7 @@
 		i := 0
 		for _, t := range terms {
 			assert(t.typ != nil)
-			if Comparable(t.typ) {
+			if comparable(t.typ, false /* strictly comparable */, nil, nil) {
 				terms[i] = t
 				i++
 			}
diff --git a/src/internal/poll/sock_cloexec.go b/src/internal/poll/sock_cloexec.go
index 4fb9f00..f5be2aa 100644
--- a/src/internal/poll/sock_cloexec.go
+++ b/src/internal/poll/sock_cloexec.go
@@ -5,7 +5,7 @@
 // This file implements accept for platforms that provide a fast path for
 // setting SetNonblock and CloseOnExec.
 
-//go:build dragonfly || freebsd || linux || netbsd || openbsd || solaris
+//go:build dragonfly || freebsd || (linux && !arm) || netbsd || openbsd || solaris
 
 package poll
 
diff --git a/src/internal/poll/sock_cloexec_accept.go b/src/internal/poll/sock_cloexec_accept.go
new file mode 100644
index 0000000..4b86de59e
--- /dev/null
+++ b/src/internal/poll/sock_cloexec_accept.go
@@ -0,0 +1,51 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements accept for platforms that provide a fast path for
+// setting SetNonblock and CloseOnExec, but don't necessarily have accept4.
+// This is the code we used for accept in Go 1.17 and earlier.
+// On Linux the accept4 system call was introduced in 2.6.28 kernel,
+// and our minimum requirement is 2.6.32, so we simplified the function.
+// Unfortunately, on ARM accept4 wasn't added until 2.6.36, so for ARM
+// only we continue using the older code.
+
+//go:build linux && arm
+
+package poll
+
+import "syscall"
+
+// Wrapper around the accept system call that marks the returned file
+// descriptor as nonblocking and close-on-exec.
+func accept(s int) (int, syscall.Sockaddr, string, error) {
+	ns, sa, err := Accept4Func(s, syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC)
+	switch err {
+	case nil:
+		return ns, sa, "", nil
+	default: // errors other than the ones listed
+		return -1, sa, "accept4", err
+	case syscall.ENOSYS: // syscall missing
+	case syscall.EINVAL: // some Linux use this instead of ENOSYS
+	case syscall.EACCES: // some Linux use this instead of ENOSYS
+	case syscall.EFAULT: // some Linux use this instead of ENOSYS
+	}
+
+	// See ../syscall/exec_unix.go for description of ForkLock.
+	// It is probably okay to hold the lock across syscall.Accept
+	// because we have put fd.sysfd into non-blocking mode.
+	// However, a call to the File method will put it back into
+	// blocking mode. We can't take that risk, so no use of ForkLock here.
+	ns, sa, err = AcceptFunc(s)
+	if err == nil {
+		syscall.CloseOnExec(ns)
+	}
+	if err != nil {
+		return -1, nil, "accept", err
+	}
+	if err = syscall.SetNonblock(ns, true); err != nil {
+		CloseFunc(ns)
+		return -1, nil, "setnonblock", err
+	}
+	return ns, sa, "", nil
+}
diff --git a/src/internal/safefilepath/path_other.go b/src/internal/safefilepath/path_other.go
index f93da18..974e775 100644
--- a/src/internal/safefilepath/path_other.go
+++ b/src/internal/safefilepath/path_other.go
@@ -11,7 +11,7 @@
 func fromFS(path string) (string, error) {
 	if runtime.GOOS == "plan9" {
 		if len(path) > 0 && path[0] == '#' {
-			return path, errInvalidPath
+			return "", errInvalidPath
 		}
 	}
 	for i := range path {
diff --git a/src/internal/types/errors/codes.go b/src/internal/types/errors/codes.go
index 7a0c0e1..acddcbb 100644
--- a/src/internal/types/errors/codes.go
+++ b/src/internal/types/errors/codes.go
@@ -882,7 +882,7 @@
 	// context in which it is used.
 	//
 	// Example:
-	//  var _ = 1 + new(int)
+	//  var _ = 1 + []int{}
 	InvalidUntypedConversion
 
 	// BadOffsetofSyntax occurs when unsafe.Offsetof is called with an argument
diff --git a/src/internal/types/testdata/fixedbugs/issue57155.go b/src/internal/types/testdata/fixedbugs/issue57155.go
new file mode 100644
index 0000000..ec9fb2b
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue57155.go
@@ -0,0 +1,14 @@
+// Copyright 2022 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[P *Q, Q any](p P, q Q) {
+	func() {
+		_ = f[P]
+		f(p, q)
+		f[P](p, q)
+		f[P, Q](p, q)
+	}()
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue57160.go b/src/internal/types/testdata/fixedbugs/issue57160.go
new file mode 100644
index 0000000..446d019
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue57160.go
@@ -0,0 +1,10 @@
+// Copyright 2022 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 _(x *int) {
+	_ = 0 < x // ERROR "invalid operation"
+	_ = x < 0 // ERROR "invalid operation"
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue57486.go b/src/internal/types/testdata/fixedbugs/issue57486.go
new file mode 100644
index 0000000..ff9e3d1
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue57486.go
@@ -0,0 +1,29 @@
+// Copyright 2022 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
+
+type C1 interface {
+	comparable
+}
+
+type C2 interface {
+	comparable
+	[2]any | int
+}
+
+func G1[T C1](t T) { _ = t == t }
+func G2[T C2](t T) { _ = t == t }
+
+func F1[V [2]any](v V) {
+	_ = G1[V /* ERROR "V does not implement comparable" */]
+	_ = G1[[2]any]
+	_ = G1[int]
+}
+
+func F2[V [2]any](v V) {
+	_ = G2[V /* ERROR "V does not implement C2" */]
+	_ = G2[[ /* ERROR "\[2\]any does not implement C2 \(\[2\]any missing in int\)" */ 2]any]
+	_ = G2[int]
+}
diff --git a/src/net/cgo_unix.go b/src/net/cgo_unix.go
index 5b0df56..6a2c369 100644
--- a/src/net/cgo_unix.go
+++ b/src/net/cgo_unix.go
@@ -383,8 +383,9 @@
 	s := _C_CString(hostname)
 	defer _C_FreeCString(s)
 
+	var size int
 	for {
-		size, _ := _C_res_nsearch(state, s, class, rtype, buf, bufSize)
+		size, _ = _C_res_nsearch(state, s, class, rtype, buf, bufSize)
 		if size <= 0 || size > 0xffff {
 			return nil, errors.New("res_nsearch failure")
 		}
@@ -399,7 +400,7 @@
 	}
 
 	var p dnsmessage.Parser
-	if _, err := p.Start(unsafe.Slice((*byte)(unsafe.Pointer(buf)), bufSize)); err != nil {
+	if _, err := p.Start(unsafe.Slice((*byte)(unsafe.Pointer(buf)), size)); err != nil {
 		return nil, err
 	}
 	p.SkipAllQuestions()
diff --git a/src/net/cgo_unix_cgo.go b/src/net/cgo_unix_cgo.go
index 3e7282b..97427e6 100644
--- a/src/net/cgo_unix_cgo.go
+++ b/src/net/cgo_unix_cgo.go
@@ -7,6 +7,7 @@
 package net
 
 /*
+#cgo CFLAGS: -fno-stack-protector
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go
index 190279c..58064a5 100644
--- a/src/net/http/httputil/reverseproxy.go
+++ b/src/net/http/httputil/reverseproxy.go
@@ -131,17 +131,17 @@
 	// Director must not access the provided Request
 	// after returning.
 	//
-	// By default, the X-Forwarded-For, X-Forwarded-Host, and
-	// X-Forwarded-Proto headers of the ourgoing request are
-	// set as by the ProxyRequest.SetXForwarded function.
+	// By default, the X-Forwarded-For header is set to the
+	// value of the client IP address. If an X-Forwarded-For
+	// header already exists, the client IP is appended to the
+	// existing values. As a special case, if the header
+	// exists in the Request.Header map but has a nil value
+	// (such as when set by the Director func), the X-Forwarded-For
+	// header is not modified.
 	//
-	// If an X-Forwarded-For header already exists, the client IP is
-	// appended to the existing values. To prevent IP spoofing, be
-	// sure to delete any pre-existing X-Forwarded-For header
-	// coming from the client or an untrusted proxy.
-	//
-	// If a header exists in the Request.Header map but has a nil value
-	// (such as when set by the Director func), it is not modified.
+	// To prevent IP spoofing, be sure to delete any pre-existing
+	// X-Forwarded-For header coming from the client or
+	// an untrusted proxy.
 	//
 	// Hop-by-hop headers are removed from the request after
 	// Director returns, which can remove headers added by
@@ -446,16 +446,6 @@
 				outreq.Header.Set("X-Forwarded-For", clientIP)
 			}
 		}
-		if prior, ok := outreq.Header["X-Forwarded-Host"]; !(ok && prior == nil) {
-			outreq.Header.Set("X-Forwarded-Host", req.Host)
-		}
-		if prior, ok := outreq.Header["X-Forwarded-Proto"]; !(ok && prior == nil) {
-			if req.TLS == nil {
-				outreq.Header.Set("X-Forwarded-Proto", "http")
-			} else {
-				outreq.Header.Set("X-Forwarded-Proto", "https")
-			}
-		}
 	}
 
 	if _, ok := outreq.Header["User-Agent"]; !ok {
diff --git a/src/net/http/httputil/reverseproxy_test.go b/src/net/http/httputil/reverseproxy_test.go
index 5b882d3..d5b0fb4 100644
--- a/src/net/http/httputil/reverseproxy_test.go
+++ b/src/net/http/httputil/reverseproxy_test.go
@@ -52,12 +52,6 @@
 		if r.Header.Get("X-Forwarded-For") == "" {
 			t.Errorf("didn't get X-Forwarded-For header")
 		}
-		if r.Header.Get("X-Forwarded-Host") == "" {
-			t.Errorf("didn't get X-Forwarded-Host header")
-		}
-		if r.Header.Get("X-Forwarded-Proto") == "" {
-			t.Errorf("didn't get X-Forwarded-Proto header")
-		}
 		if c := r.Header.Get("Connection"); c != "" {
 			t.Errorf("handler got Connection header value %q", c)
 		}
@@ -307,7 +301,6 @@
 	const prevForwardedFor = "client ip"
 	const backendResponse = "I am the backend"
 	const backendStatus = 404
-	const host = "some-name"
 	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		if r.Header.Get("X-Forwarded-For") == "" {
 			t.Errorf("didn't get X-Forwarded-For header")
@@ -315,12 +308,6 @@
 		if !strings.Contains(r.Header.Get("X-Forwarded-For"), prevForwardedFor) {
 			t.Errorf("X-Forwarded-For didn't contain prior data")
 		}
-		if got, want := r.Header.Get("X-Forwarded-Host"), host; got != want {
-			t.Errorf("X-Forwarded-Host = %q, want %q", got, want)
-		}
-		if got, want := r.Header.Get("X-Forwarded-Proto"), "http"; got != want {
-			t.Errorf("X-Forwarded-Proto = %q, want %q", got, want)
-		}
 		w.WriteHeader(backendStatus)
 		w.Write([]byte(backendResponse))
 	}))
@@ -334,7 +321,6 @@
 	defer frontend.Close()
 
 	getReq, _ := http.NewRequest("GET", frontend.URL, nil)
-	getReq.Host = host
 	getReq.Header.Set("Connection", "close")
 	getReq.Header.Set("X-Forwarded-For", prevForwardedFor)
 	getReq.Close = true
@@ -351,36 +337,11 @@
 	}
 }
 
-func TestXForwardedProtoTLS(t *testing.T) {
-	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		if got, want := r.Header.Get("X-Forwarded-Proto"), "https"; got != want {
-			t.Errorf("X-Forwarded-Proto = %q, want %q", got, want)
-		}
-	}))
-	defer backend.Close()
-	backendURL, err := url.Parse(backend.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	proxyHandler := NewSingleHostReverseProxy(backendURL)
-	frontend := httptest.NewTLSServer(proxyHandler)
-	defer frontend.Close()
-
-	getReq, _ := http.NewRequest("GET", frontend.URL, nil)
-	getReq.Host = "some-host"
-	_, err = frontend.Client().Do(getReq)
-	if err != nil {
-		t.Fatalf("Get: %v", err)
-	}
-}
-
 // Issue 38079: don't append to X-Forwarded-For if it's present but nil
 func TestXForwardedFor_Omit(t *testing.T) {
 	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		for _, h := range []string{"X-Forwarded-For", "X-Forwarded-Host", "X-Forwarded-Proto"} {
-			if v := r.Header.Get(h); v != "" {
-				t.Errorf("got %v header: %q", h, v)
-			}
+		if v := r.Header.Get("X-Forwarded-For"); v != "" {
+			t.Errorf("got X-Forwarded-For header: %q", v)
 		}
 		w.Write([]byte("hi"))
 	}))
@@ -396,8 +357,6 @@
 	oldDirector := proxyHandler.Director
 	proxyHandler.Director = func(r *http.Request) {
 		r.Header["X-Forwarded-For"] = nil
-		r.Header["X-Forwarded-Host"] = nil
-		r.Header["X-Forwarded-Proto"] = nil
 		oldDirector(r)
 	}
 
@@ -1106,8 +1065,6 @@
 	for _, h := range []string{
 		"From-Director",
 		"X-Forwarded-For",
-		"X-Forwarded-Host",
-		"X-Forwarded-Proto",
 	} {
 		if req.Header.Get(h) != "" {
 			t.Errorf("%v header mutation modified caller's request", h)
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index 2bc83fd4..245f73b 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -6565,7 +6565,8 @@
 	var wg sync.WaitGroup
 
 	wg.Add(1)
-	putidlec := make(chan chan struct{})
+	putidlec := make(chan chan struct{}, 1)
+	reqerrc := make(chan error, 1)
 	go func() {
 		defer wg.Done()
 		ctx := httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
@@ -6574,24 +6575,31 @@
 				// and wait for the order to proceed.
 				ch := make(chan struct{})
 				putidlec <- ch
+				close(putidlec) // panic if PutIdleConn runs twice for some reason
 				<-ch
 			},
 		})
 		req, _ := NewRequestWithContext(ctx, "GET", ts.URL, nil)
 		res, err := client.Do(req)
+		reqerrc <- err
 		if err == nil {
 			res.Body.Close()
 		}
-		if err != nil {
-			t.Errorf("request 1: got err %v, want nil", err)
-		}
 	}()
 
 	// Wait for the first request to receive a response and return the
 	// connection to the idle pool.
 	r1c := <-reqc
 	close(r1c)
-	idlec := <-putidlec
+	var idlec chan struct{}
+	select {
+	case err := <-reqerrc:
+		if err != nil {
+			t.Fatalf("request 1: got err %v, want nil", err)
+		}
+		idlec = <-putidlec
+	case idlec = <-putidlec:
+	}
 
 	wg.Add(1)
 	cancelctx, cancel := context.WithCancel(context.Background())
diff --git a/src/os/exec/lp_linux_test.go b/src/os/exec/lp_linux_test.go
index 98c3a7b..845573f 100644
--- a/src/os/exec/lp_linux_test.go
+++ b/src/os/exec/lp_linux_test.go
@@ -5,6 +5,7 @@
 package exec
 
 import (
+	"errors"
 	"internal/syscall/unix"
 	"os"
 	"path/filepath"
@@ -48,8 +49,20 @@
 		t.Fatalf("findExecutable: got %v, want nil", err)
 	}
 
-	if err := Command(path).Run(); err != nil {
-		t.Fatalf("exec: got %v, want nil", err)
+	for {
+		err = Command(path).Run()
+		if err == nil {
+			break
+		}
+		if errors.Is(err, syscall.ETXTBSY) {
+			// A fork+exec in another process may be holding open the FD that we used
+			// to write the executable (see https://go.dev/issue/22315).
+			// Since the descriptor should have CLOEXEC set, the problem should resolve
+			// as soon as the forked child reaches its exec call.
+			// Keep retrying until that happens.
+		} else {
+			t.Fatalf("exec: got %v, want nil", err)
+		}
 	}
 
 	// Remount with noexec flag.
diff --git a/src/os/os_test.go b/src/os/os_test.go
index f410390..277b245 100644
--- a/src/os/os_test.go
+++ b/src/os/os_test.go
@@ -274,9 +274,11 @@
 	if !equal(sfname, dir.Name()) {
 		t.Error("name should be ", sfname, "; is", dir.Name())
 	}
-	filesize := size(path, t)
-	if dir.Size() != filesize {
-		t.Error("size should be", filesize, "; is", dir.Size())
+	if dir.Mode()&ModeSymlink == 0 {
+		filesize := size(path, t)
+		if dir.Size() != filesize {
+			t.Error("size should be", filesize, "; is", dir.Size())
+		}
 	}
 }
 
@@ -2606,9 +2608,6 @@
 	// See issue 37161. Read only one entry from a directory,
 	// seek to the beginning, and read again. We should not see
 	// duplicate entries.
-	if runtime.GOOS == "windows" {
-		testenv.SkipFlaky(t, 36019)
-	}
 	wd, err := Getwd()
 	if err != nil {
 		t.Fatal(err)
diff --git a/src/os/user/cgo_lookup_cgo.go b/src/os/user/cgo_lookup_cgo.go
index 1799573..4f78dca 100644
--- a/src/os/user/cgo_lookup_cgo.go
+++ b/src/os/user/cgo_lookup_cgo.go
@@ -12,42 +12,48 @@
 
 /*
 #cgo solaris CFLAGS: -D_POSIX_PTHREAD_SEMANTICS
+#cgo CFLAGS: -fno-stack-protector
 #include <unistd.h>
 #include <sys/types.h>
 #include <pwd.h>
 #include <grp.h>
 #include <stdlib.h>
+#include <string.h>
 
 static struct passwd mygetpwuid_r(int uid, char *buf, size_t buflen, int *found, int *perr) {
 	struct passwd pwd;
-        struct passwd *result;
-        *perr = getpwuid_r(uid, &pwd, buf, buflen, &result);
-        *found = result != NULL;
-        return pwd;
+	struct passwd *result;
+	memset (&pwd, 0, sizeof(pwd));
+	*perr = getpwuid_r(uid, &pwd, buf, buflen, &result);
+	*found = result != NULL;
+	return pwd;
 }
 
 static struct passwd mygetpwnam_r(const char *name, char *buf, size_t buflen, int *found, int *perr) {
 	struct passwd pwd;
-        struct passwd *result;
-        *perr = getpwnam_r(name, &pwd, buf, buflen, &result);
-        *found = result != NULL;
-        return pwd;
+	struct passwd *result;
+	memset(&pwd, 0, sizeof(pwd));
+	*perr = getpwnam_r(name, &pwd, buf, buflen, &result);
+	*found = result != NULL;
+	return pwd;
 }
 
 static struct group mygetgrgid_r(int gid, char *buf, size_t buflen, int *found, int *perr) {
 	struct group grp;
-        struct group *result;
-        *perr = getgrgid_r(gid, &grp, buf, buflen, &result);
-        *found = result != NULL;
-        return grp;
+	struct group *result;
+	memset(&grp, 0, sizeof(grp));
+	*perr = getgrgid_r(gid, &grp, buf, buflen, &result);
+	*found = result != NULL;
+	return grp;
 }
 
 static struct group mygetgrnam_r(const char *name, char *buf, size_t buflen, int *found, int *perr) {
 	struct group grp;
-        struct group *result;
-        *perr = getgrnam_r(name, &grp, buf, buflen, &result);
-        *found = result != NULL;
-        return grp;
+	struct group *result;
+	memset(&grp, 0, sizeof(grp));
+	*perr = getgrnam_r(name, &grp, buf, buflen, &result);
+	*found = result != NULL;
+	return grp;
 }
 */
 import "C"
diff --git a/src/os/user/cgo_lookup_unix.go b/src/os/user/cgo_lookup_unix.go
index b745ffd..3735971 100644
--- a/src/os/user/cgo_lookup_unix.go
+++ b/src/os/user/cgo_lookup_unix.go
@@ -8,6 +8,7 @@
 
 import (
 	"fmt"
+	"runtime"
 	"strconv"
 	"strings"
 	"syscall"
@@ -170,6 +171,9 @@
 		errno := f(buf)
 		if errno == 0 {
 			return nil
+		} else if runtime.GOOS == "aix" && errno+1 == 0 {
+			// On AIX getpwuid_r appears to return -1,
+			// not ERANGE, on buffer overflow.
 		} else if errno != syscall.ERANGE {
 			return errno
 		}
diff --git a/src/runtime/coverage/emitdata_test.go b/src/runtime/coverage/emitdata_test.go
index 0ccb2d2..3839e44 100644
--- a/src/runtime/coverage/emitdata_test.go
+++ b/src/runtime/coverage/emitdata_test.go
@@ -157,7 +157,7 @@
 
 func testForSpecificFunctions(t *testing.T, dir string, want []string, avoid []string) string {
 	args := []string{"tool", "covdata", "debugdump",
-		"-live", "-pkg=main", "-i=" + dir}
+		"-live", "-pkg=command-line-arguments", "-i=" + dir}
 	t.Logf("running: go %v\n", args)
 	cmd := exec.Command(testenv.GoToolPath(t), args...)
 	b, err := cmd.CombinedOutput()
@@ -167,18 +167,21 @@
 	output := string(b)
 	rval := ""
 	for _, f := range want {
-		wf := "Func: " + f
+		wf := "Func: " + f + "\n"
 		if strings.Contains(output, wf) {
 			continue
 		}
 		rval += fmt.Sprintf("error: output should contain %q but does not\n", wf)
 	}
 	for _, f := range avoid {
-		wf := "Func: " + f
+		wf := "Func: " + f + "\n"
 		if strings.Contains(output, wf) {
 			rval += fmt.Sprintf("error: output should not contain %q but does\n", wf)
 		}
 	}
+	if rval != "" {
+		t.Logf("=-= begin output:\n" + output + "\n=-= end output\n")
+	}
 	return rval
 }
 
diff --git a/src/runtime/coverage/testsupport.go b/src/runtime/coverage/testsupport.go
index 462d06c..1d90ebd 100644
--- a/src/runtime/coverage/testsupport.go
+++ b/src/runtime/coverage/testsupport.go
@@ -136,13 +136,16 @@
 		return err
 	}
 
-	// Read counter data files.
+	// A map to store counter data, indexed by pkgid/fnid tuple.
 	pmm := make(map[pkfunc][]uint32)
-	for _, cdf := range p.CounterDataFiles {
+
+	// Helper to read a single counter data file.
+	readcdf := func(cdf string) error {
 		cf, err := os.Open(cdf)
 		if err != nil {
 			return fmt.Errorf("opening counter data file %s: %s", cdf, err)
 		}
+		defer cf.Close()
 		var cdr *decodecounter.CounterDataReader
 		cdr, err = decodecounter.NewCounterDataReader(cdf, cf)
 		if err != nil {
@@ -170,6 +173,14 @@
 			copy(c, data.Counters)
 			pmm[key] = c
 		}
+		return nil
+	}
+
+	// Read counter data files.
+	for _, cdf := range p.CounterDataFiles {
+		if err := readcdf(cdf); err != nil {
+			return err
+		}
 	}
 
 	// Visit meta-data file.
diff --git a/src/runtime/internal/atomic/atomic_test.go b/src/runtime/internal/atomic/atomic_test.go
index 2ae60b8..2427bfd 100644
--- a/src/runtime/internal/atomic/atomic_test.go
+++ b/src/runtime/internal/atomic/atomic_test.go
@@ -345,6 +345,36 @@
 	}
 }
 
+func TestCasRel(t *testing.T) {
+	const _magic = 0x5a5aa5a5
+	var x struct {
+		before uint32
+		i      uint32
+		after  uint32
+		o      uint32
+		n      uint32
+	}
+
+	x.before = _magic
+	x.after = _magic
+	for j := 0; j < 32; j += 1 {
+		x.i = (1 << j) + 0
+		x.o = (1 << j) + 0
+		x.n = (1 << j) + 1
+		if !atomic.CasRel(&x.i, x.o, x.n) {
+			t.Fatalf("should have swapped %#x %#x", x.o, x.n)
+		}
+
+		if x.i != x.n {
+			t.Fatalf("wrong x.i after swap: x.i=%#x x.n=%#x", x.i, x.n)
+		}
+
+		if x.before != _magic || x.after != _magic {
+			t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, _magic, _magic)
+		}
+	}
+}
+
 func TestStorepNoWB(t *testing.T) {
 	var p [2]*int
 	for i := range p {
diff --git a/src/runtime/internal/startlinetest/func_amd64.go b/src/runtime/internal/startlinetest/func_amd64.go
index 6cd9a3f..ab7063d 100644
--- a/src/runtime/internal/startlinetest/func_amd64.go
+++ b/src/runtime/internal/startlinetest/func_amd64.go
@@ -8,3 +8,6 @@
 // Defined in func_amd64.s, this is a trivial assembly function that calls
 // runtime_test.callerStartLine.
 func AsmFunc() int
+
+// Provided by runtime_test.
+var CallerStartLine func(bool) int
diff --git a/src/runtime/internal/startlinetest/func_amd64.s b/src/runtime/internal/startlinetest/func_amd64.s
index ace5b34..96982be 100644
--- a/src/runtime/internal/startlinetest/func_amd64.s
+++ b/src/runtime/internal/startlinetest/func_amd64.s
@@ -23,5 +23,6 @@
 TEXT	·AsmFunc<ABIInternal>(SB),NOSPLIT,$8-0
 	NO_LOCAL_POINTERS
 	MOVQ	$0, AX // wantInlined
-	CALL    runtime_test·callerStartLine<ABIInternal>(SB)
+	MOVQ	·CallerStartLine(SB), DX
+	CALL	(DX)
 	RET
diff --git a/src/runtime/libfuzzer.go b/src/runtime/libfuzzer.go
index 013e716..0ece035 100644
--- a/src/runtime/libfuzzer.go
+++ b/src/runtime/libfuzzer.go
@@ -148,13 +148,8 @@
 //go:cgo_import_static __sanitizer_cov_8bit_counters_init
 var __sanitizer_cov_8bit_counters_init byte
 
-//go:linkname __start___sancov_cntrs __start___sancov_cntrs
-//go:cgo_import_static __start___sancov_cntrs
-var __start___sancov_cntrs byte
-
-//go:linkname __stop___sancov_cntrs __stop___sancov_cntrs
-//go:cgo_import_static __stop___sancov_cntrs
-var __stop___sancov_cntrs byte
+// start, stop markers of counters, set by the linker
+var __start___sancov_cntrs, __stop___sancov_cntrs byte
 
 //go:linkname __sanitizer_cov_pcs_init __sanitizer_cov_pcs_init
 //go:cgo_import_static __sanitizer_cov_pcs_init
diff --git a/src/runtime/mfinal_test.go b/src/runtime/mfinal_test.go
index 902ccc5..61d625a 100644
--- a/src/runtime/mfinal_test.go
+++ b/src/runtime/mfinal_test.go
@@ -53,7 +53,7 @@
 		}},
 	}
 
-	for i, tt := range finalizerTests {
+	for _, tt := range finalizerTests {
 		done := make(chan bool, 1)
 		go func() {
 			// allocate struct with pointer to avoid hitting tinyalloc.
@@ -71,11 +71,7 @@
 		}()
 		<-done
 		runtime.GC()
-		select {
-		case <-ch:
-		case <-time.After(time.Second * 4):
-			t.Errorf("#%d: finalizer for type %T didn't run", i, tt.finalizer)
-		}
+		<-ch
 	}
 }
 
@@ -109,11 +105,7 @@
 	}()
 	<-done
 	runtime.GC()
-	select {
-	case <-ch:
-	case <-time.After(4 * time.Second):
-		t.Errorf("finalizer for type *bigValue didn't run")
-	}
+	<-ch
 }
 
 func fin(v *int) {
@@ -188,11 +180,7 @@
 	fin := make(chan bool, 1)
 	runtime.SetFinalizer(y, func(z *objtype) { fin <- true })
 	runtime.GC()
-	select {
-	case <-fin:
-	case <-time.After(4 * time.Second):
-		t.Errorf("finalizer of next object in memory didn't run")
-	}
+	<-fin
 	xsglobal = xs // keep empty slice alive until here
 }
 
@@ -220,11 +208,7 @@
 	// set finalizer on string contents of y
 	runtime.SetFinalizer(y, func(z *objtype) { fin <- true })
 	runtime.GC()
-	select {
-	case <-fin:
-	case <-time.After(4 * time.Second):
-		t.Errorf("finalizer of next string in memory didn't run")
-	}
+	<-fin
 	ssglobal = ss // keep 0-length string live until here
 }
 
diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go
index c4f3bb6..af5c18c 100644
--- a/src/runtime/os_darwin.go
+++ b/src/runtime/os_darwin.go
@@ -136,8 +136,6 @@
 
 	ncpu = getncpu()
 	physPageSize = getPageSize()
-
-	osinit_hack()
 }
 
 func sysctlbynameInt32(name []byte) (int32, int32) {
diff --git a/src/runtime/race/internal/amd64v1/doc.go b/src/runtime/race/internal/amd64v1/doc.go
index 130b290..ccb088c 100644
--- a/src/runtime/race/internal/amd64v1/doc.go
+++ b/src/runtime/race/internal/amd64v1/doc.go
@@ -5,4 +5,6 @@
 // This package holds the race detector .syso for
 // amd64 architectures with GOAMD64<v3.
 
+//go:build amd64 && ((linux && !amd64.v3) || darwin || freebsd || netbsd || openbsd || windows)
+
 package amd64v1
diff --git a/src/runtime/race/internal/amd64v3/doc.go b/src/runtime/race/internal/amd64v3/doc.go
index 6983335..215998a 100644
--- a/src/runtime/race/internal/amd64v3/doc.go
+++ b/src/runtime/race/internal/amd64v3/doc.go
@@ -5,4 +5,6 @@
 // This package holds the race detector .syso for
 // amd64 architectures with GOAMD64>=v3.
 
+//go:build amd64 && linux && amd64.v3
+
 package amd64v3
diff --git a/src/runtime/race/race_v1_amd64.go b/src/runtime/race/race_v1_amd64.go
index b8a2031..7c40db1 100644
--- a/src/runtime/race/race_v1_amd64.go
+++ b/src/runtime/race/race_v1_amd64.go
@@ -3,7 +3,6 @@
 // license that can be found in the LICENSE file.
 
 //go:build (linux && !amd64.v3) || darwin || freebsd || netbsd || openbsd || windows
-// +build linux,!amd64.v3 darwin freebsd netbsd openbsd windows
 
 package race
 
diff --git a/src/runtime/race/race_v3_amd64.go b/src/runtime/race/race_v3_amd64.go
index 913bb77..80728d8 100644
--- a/src/runtime/race/race_v3_amd64.go
+++ b/src/runtime/race/race_v3_amd64.go
@@ -3,7 +3,6 @@
 // license that can be found in the LICENSE file.
 
 //go:build linux && amd64.v3
-// +build linux,amd64.v3
 
 package race
 
diff --git a/src/runtime/start_line_amd64_test.go b/src/runtime/start_line_amd64_test.go
index 57001e7..305ed0b 100644
--- a/src/runtime/start_line_amd64_test.go
+++ b/src/runtime/start_line_amd64_test.go
@@ -13,6 +13,8 @@
 // is only tested on amd64 to avoid the need for a proliferation of per-arch
 // copies of this function.
 func TestStartLineAsm(t *testing.T) {
+	startlinetest.CallerStartLine = callerStartLine
+
 	const wantLine = 23
 	got := startlinetest.AsmFunc()
 	if got != wantLine {
diff --git a/src/runtime/string_test.go b/src/runtime/string_test.go
index 1ea7f5e..cfc0ad7 100644
--- a/src/runtime/string_test.go
+++ b/src/runtime/string_test.go
@@ -223,6 +223,19 @@
 	}
 }
 
+func TestConcatTempString(t *testing.T) {
+	s := "bytes"
+	b := []byte(s)
+	n := testing.AllocsPerRun(1000, func() {
+		if "prefix "+string(b)+" suffix" != "prefix bytes suffix" {
+			t.Fatalf("strings are not equal: '%v' and '%v'", "prefix "+string(b)+" suffix", "prefix bytes suffix")
+		}
+	})
+	if n != 0 {
+		t.Fatalf("want 0 allocs, got %v", n)
+	}
+}
+
 func TestCompareTempString(t *testing.T) {
 	s := strings.Repeat("x", sizeNoStack)
 	b := []byte(s)
@@ -230,10 +243,24 @@
 		if string(b) != s {
 			t.Fatalf("strings are not equal: '%v' and '%v'", string(b), s)
 		}
+		if string(b) < s {
+			t.Fatalf("strings are not equal: '%v' and '%v'", string(b), s)
+		}
+		if string(b) > s {
+			t.Fatalf("strings are not equal: '%v' and '%v'", string(b), s)
+		}
 		if string(b) == s {
 		} else {
 			t.Fatalf("strings are not equal: '%v' and '%v'", string(b), s)
 		}
+		if string(b) <= s {
+		} else {
+			t.Fatalf("strings are not equal: '%v' and '%v'", string(b), s)
+		}
+		if string(b) >= s {
+		} else {
+			t.Fatalf("strings are not equal: '%v' and '%v'", string(b), s)
+		}
 	})
 	if n != 0 {
 		t.Fatalf("want 0 allocs, got %v", n)
diff --git a/src/runtime/sys_darwin.go b/src/runtime/sys_darwin.go
index 28dc291..61b7f8c 100644
--- a/src/runtime/sys_darwin.go
+++ b/src/runtime/sys_darwin.go
@@ -179,51 +179,6 @@
 }
 func pthread_kill_trampoline()
 
-// osinit_hack is a clumsy hack to work around Apple libc bugs
-// causing fork+exec to hang in the child process intermittently.
-// See go.dev/issue/33565 and go.dev/issue/56784 for a few reports.
-//
-// The stacks obtained from the hung child processes are in
-// libSystem_atfork_child, which is supposed to reinitialize various
-// parts of the C library in the new process.
-//
-// One common stack dies in _notify_fork_child calling _notify_globals
-// (inlined) calling _os_alloc_once, because _os_alloc_once detects that
-// the once lock is held by the parent process and then calls
-// _os_once_gate_corruption_abort. The allocation is setting up the
-// globals for the notification subsystem. See the source code at [1].
-// To work around this, we can allocate the globals earlier in the Go
-// program's lifetime, before any execs are involved, by calling any
-// notify routine that is exported, calls _notify_globals, and doesn't do
-// anything too expensive otherwise. notify_is_valid_token(0) fits the bill.
-//
-// The other common stack dies in xpc_atfork_child calling
-// _objc_msgSend_uncached which ends up in
-// WAITING_FOR_ANOTHER_THREAD_TO_FINISH_CALLING_+initialize. Of course,
-// whatever thread the child is waiting for is in the parent process and
-// is not going to finish anything in the child process. There is no
-// public source code for these routines, so it is unclear exactly what
-// the problem is. However, xpc_atfork_child turns out to be exported
-// (for use by libSystem_atfork_child, which is in a different library,
-// so xpc_atfork_child is unlikely to be unexported any time soon).
-// It also stands to reason that since xpc_atfork_child is called at the
-// start of any forked child process, it can't be too harmful to call at
-// the start of an ordinary Go process. And whatever caches it needs for
-// a non-deadlocking fast path during exec empirically do get initialized
-// by calling it at startup.
-//
-// So osinit_hack_trampoline (in sys_darwin_$GOARCH.s) calls
-// notify_is_valid_token(0) and xpc_atfork_child(), which makes the
-// fork+exec hangs stop happening. If Apple fixes the libc bug in
-// some future version of macOS, then we can remove this awful code.
-//
-//go:nosplit
-func osinit_hack() {
-	libcCall(unsafe.Pointer(abi.FuncPCABI0(osinit_hack_trampoline)), nil)
-	return
-}
-func osinit_hack_trampoline()
-
 // mmap is used to do low-level memory allocation via mmap. Don't allow stack
 // splits, since this function (used by sysAlloc) is called in a lot of low-level
 // parts of the runtime and callers often assume it won't acquire any locks.
@@ -593,6 +548,3 @@
 //go:cgo_import_dynamic libc_pthread_cond_wait pthread_cond_wait "/usr/lib/libSystem.B.dylib"
 //go:cgo_import_dynamic libc_pthread_cond_timedwait_relative_np pthread_cond_timedwait_relative_np "/usr/lib/libSystem.B.dylib"
 //go:cgo_import_dynamic libc_pthread_cond_signal pthread_cond_signal "/usr/lib/libSystem.B.dylib"
-
-//go:cgo_import_dynamic libc_notify_is_valid_token notify_is_valid_token "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_xpc_atfork_child xpc_atfork_child "/usr/lib/libSystem.B.dylib"
diff --git a/src/runtime/sys_darwin_amd64.s b/src/runtime/sys_darwin_amd64.s
index 16783a4..369b12e 100644
--- a/src/runtime/sys_darwin_amd64.s
+++ b/src/runtime/sys_darwin_amd64.s
@@ -597,15 +597,6 @@
 	POPQ	BP
 	RET
 
-TEXT runtime·osinit_hack_trampoline(SB),NOSPLIT,$0
-	PUSHQ	BP
-	MOVQ	SP, BP
-	MOVQ	$0, DI	// arg 1 val
-	CALL	libc_notify_is_valid_token(SB)
-	CALL	libc_xpc_atfork_child(SB)
-	POPQ	BP
-	RET
-
 // syscall calls a function in libc on behalf of the syscall package.
 // syscall takes a pointer to a struct like:
 // struct {
diff --git a/src/runtime/sys_darwin_arm64.s b/src/runtime/sys_darwin_arm64.s
index 3cbac77..4fa99cc 100644
--- a/src/runtime/sys_darwin_arm64.s
+++ b/src/runtime/sys_darwin_arm64.s
@@ -458,12 +458,6 @@
 	BL	libc_pthread_setspecific(SB)
 	RET
 
-TEXT runtime·osinit_hack_trampoline(SB),NOSPLIT,$0
-	MOVD	$0, R0	// arg 1 val
-	BL	libc_notify_is_valid_token(SB)
-	BL	libc_xpc_atfork_child(SB)
-	RET
-
 // syscall calls a function in libc on behalf of the syscall package.
 // syscall takes a pointer to a struct like:
 // struct {
diff --git a/src/sync/map_bench_test.go b/src/sync/map_bench_test.go
index 4815f57..eebec3b 100644
--- a/src/sync/map_bench_test.go
+++ b/src/sync/map_bench_test.go
@@ -389,7 +389,6 @@
 }
 
 func BenchmarkCompareAndSwapValueNotEqual(b *testing.B) {
-	const n = 1 << 10
 	benchMap(b, bench{
 		setup: func(_ *testing.B, m mapInterface) {
 			m.Store(0, 0)
diff --git a/src/syscall/exec_freebsd.go b/src/syscall/exec_freebsd.go
index b85bcd9..af5a415 100644
--- a/src/syscall/exec_freebsd.go
+++ b/src/syscall/exec_freebsd.go
@@ -205,7 +205,7 @@
 		r1, _, _ = RawSyscall(SYS_GETPPID, 0, 0, 0)
 		if r1 != ppid {
 			pid, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
-			_, _, err1 := RawSyscall(SYS_KILL, pid, uintptr(sys.Pdeathsig), 0)
+			_, _, err1 = RawSyscall(SYS_KILL, pid, uintptr(sys.Pdeathsig), 0)
 			if err1 != 0 {
 				goto childerror
 			}
diff --git a/src/syscall/exec_libc2.go b/src/syscall/exec_libc2.go
index 41bc79a..6e3c2bf 100644
--- a/src/syscall/exec_libc2.go
+++ b/src/syscall/exec_libc2.go
@@ -78,7 +78,7 @@
 	// About to call fork.
 	// No more allocation or calls of non-assembly functions.
 	runtime_BeforeFork()
-	r1, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
+	r1, _, err1 = rawSyscall(forkTrampoline, 0, 0, 0)
 	if err1 != 0 {
 		runtime_AfterFork()
 		return 0, err1
@@ -276,6 +276,6 @@
 	// send error code on pipe
 	rawSyscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(pipe), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
 	for {
-		rawSyscall(abi.FuncPCABI0(libc_exit_trampoline), 253, 0, 0)
+		rawSyscall(exitTrampoline, 253, 0, 0)
 	}
 }
diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
index b61b51d..7e0c3d2 100644
--- a/src/syscall/exec_linux.go
+++ b/src/syscall/exec_linux.go
@@ -470,7 +470,7 @@
 		// so it is safe to always use _LINUX_CAPABILITY_VERSION_3.
 		caps.hdr.version = _LINUX_CAPABILITY_VERSION_3
 
-		if _, _, err1 := RawSyscall(SYS_CAPGET, uintptr(unsafe.Pointer(&caps.hdr)), uintptr(unsafe.Pointer(&caps.data[0])), 0); err1 != 0 {
+		if _, _, err1 = RawSyscall(SYS_CAPGET, uintptr(unsafe.Pointer(&caps.hdr)), uintptr(unsafe.Pointer(&caps.data[0])), 0); err1 != 0 {
 			goto childerror
 		}
 
@@ -481,7 +481,7 @@
 			caps.data[capToIndex(c)].inheritable |= capToMask(c)
 		}
 
-		if _, _, err1 := RawSyscall(SYS_CAPSET, uintptr(unsafe.Pointer(&caps.hdr)), uintptr(unsafe.Pointer(&caps.data[0])), 0); err1 != 0 {
+		if _, _, err1 = RawSyscall(SYS_CAPSET, uintptr(unsafe.Pointer(&caps.hdr)), uintptr(unsafe.Pointer(&caps.data[0])), 0); err1 != 0 {
 			goto childerror
 		}
 
@@ -514,7 +514,7 @@
 		r1, _ = rawSyscallNoError(SYS_GETPPID, 0, 0, 0)
 		if r1 != ppid {
 			pid, _ := rawSyscallNoError(SYS_GETPID, 0, 0, 0)
-			_, _, err1 := RawSyscall(SYS_KILL, pid, uintptr(sys.Pdeathsig), 0)
+			_, _, err1 = RawSyscall(SYS_KILL, pid, uintptr(sys.Pdeathsig), 0)
 			if err1 != 0 {
 				goto childerror
 			}
diff --git a/src/syscall/exec_linux_test.go b/src/syscall/exec_linux_test.go
index a035d41..1e21fff 100644
--- a/src/syscall/exec_linux_test.go
+++ b/src/syscall/exec_linux_test.go
@@ -8,6 +8,7 @@
 
 import (
 	"bytes"
+	"errors"
 	"flag"
 	"fmt"
 	"internal/testenv"
@@ -504,7 +505,8 @@
 	// Need an ability to create a sub-cgroup.
 	subCgroup, err := os.MkdirTemp(prefix+string(bytes.TrimSpace(cg)), "subcg-")
 	if err != nil {
-		if os.IsPermission(err) {
+		// Running in an unprivileged container, this may also return EROFS #57262.
+		if os.IsPermission(err) || errors.Is(err, syscall.EROFS) {
 			t.Skip(err)
 		}
 		t.Fatal(err)
diff --git a/src/syscall/exec_plan9.go b/src/syscall/exec_plan9.go
index d6b7890f..8f28b5a 100644
--- a/src/syscall/exec_plan9.go
+++ b/src/syscall/exec_plan9.go
@@ -276,7 +276,7 @@
 
 	// Pass 3: close fd[i] if it was moved in the previous pass.
 	for i = 0; i < len(fd); i++ {
-		if fd[i] >= 0 && fd[i] != int(i) {
+		if fd[i] >= len(fd) {
 			RawSyscall(SYS_CLOSE, uintptr(fd[i]), 0, 0)
 		}
 	}
diff --git a/src/syscall/syscall_darwin.go b/src/syscall/syscall_darwin.go
index a39e99d..5ec3119 100644
--- a/src/syscall/syscall_darwin.go
+++ b/src/syscall/syscall_darwin.go
@@ -22,7 +22,34 @@
 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
 
-var dupTrampoline = abi.FuncPCABI0(libc_dup2_trampoline)
+// These are called from exec_libc2.go in the child of fork.
+// The names differ between macOS and OpenBSD, so we need
+// to declare the specific ones used here to keep the exec_libc2.go
+// code portable.
+//
+// We use __fork and __exit, not fork and exit, to avoid the libc atfork
+// and atexit handlers. The atfork handlers have caused fork child
+// hangs in the past (see #33565, #56784). The atexit handlers have
+// not, but the non-libc ports all invoke the system call, so doing
+// the same here makes sense. In general we wouldn't expect
+// atexit handlers to work terribly well in a fork child anyway.
+// (Also, perhaps the atfork handlers clear the atexit handlers,
+// in which case we definitely need to avoid calling the libc exit
+// if we bypass the libc fork.)
+//
+// Other calls that are made in the child after the fork are
+// ptrace, setsid, setpgid, getpid, ioctl, chroot, setgroups,
+// setgid, setuid, chdir, dup2, fcntl, close, execve, and write.
+// Those are all simple kernel wrappers that should be safe
+// to be called directly. The fcntl and ioctl functions do run
+// some code around the kernel call, but they don't call any
+// other functions, so for now we keep using them instead of
+// calling the lower-level __fcntl and __ioctl functions.
+var (
+	dupTrampoline  = abi.FuncPCABI0(libc_dup2_trampoline)
+	exitTrampoline = abi.FuncPCABI0(libc___exit_trampoline)
+	forkTrampoline = abi.FuncPCABI0(libc___fork_trampoline)
+)
 
 type SockaddrDatalink struct {
 	Len    uint8
@@ -210,11 +237,12 @@
 //sys	writev(fd int, iovecs []Iovec) (cnt uintptr, err error)
 //sys   mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
 //sys   munmap(addr uintptr, length uintptr) (err error)
-//sysnb fork() (pid int, err error)
+//sysnb __fork() (pid int, err error)
 //sysnb ioctl(fd int, req int, arg int) (err error)
 //sysnb ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_ioctl
 //sysnb execve(path *byte, argv **byte, envp **byte) (err error)
 //sysnb exit(res int) (err error)
+//sysnb __exit(res int) (err error)
 //sys	sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error)
 //sys	fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (val int, err error) = SYS_fcntl
 //sys   unlinkat(fd int, path string, flags int) (err error)
diff --git a/src/syscall/syscall_linux.go b/src/syscall/syscall_linux.go
index bdee570..d4cc34b 100644
--- a/src/syscall/syscall_linux.go
+++ b/src/syscall/syscall_linux.go
@@ -13,6 +13,7 @@
 
 import (
 	"internal/itoa"
+	"runtime"
 	"unsafe"
 )
 
@@ -145,8 +146,17 @@
 		return faccessat(dirfd, path, mode)
 	}
 
-	if err := faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM {
-		return err
+	// Attempt to use the newer faccessat2, which supports flags directly,
+	// falling back if it doesn't exist.
+	//
+	// Don't attempt on Android, which does not allow faccessat2 through
+	// its seccomp policy [1] on any version of Android as of 2022-12-20.
+	//
+	// [1] https://cs.android.com/android/platform/superproject/+/master:bionic/libc/SECCOMP_BLOCKLIST_APP.TXT;l=4;drc=dbb8670dfdcc677f7e3b9262e93800fa14c4e417
+	if runtime.GOOS != "android" {
+		if err := faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM {
+			return err
+		}
 	}
 
 	// The Linux kernel faccessat system call does not take any flags.
@@ -643,21 +653,6 @@
 	return nil, EAFNOSUPPORT
 }
 
-func Accept(fd int) (nfd int, sa Sockaddr, err error) {
-	var rsa RawSockaddrAny
-	var len _Socklen = SizeofSockaddrAny
-	nfd, err = accept4(fd, &rsa, &len, 0)
-	if err != nil {
-		return
-	}
-	sa, err = anyToSockaddr(&rsa)
-	if err != nil {
-		Close(nfd)
-		nfd = 0
-	}
-	return
-}
-
 func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
 	var rsa RawSockaddrAny
 	var len _Socklen = SizeofSockaddrAny
diff --git a/src/syscall/syscall_linux_accept.go b/src/syscall/syscall_linux_accept.go
new file mode 100644
index 0000000..66c0f84
--- /dev/null
+++ b/src/syscall/syscall_linux_accept.go
@@ -0,0 +1,34 @@
+// Copyright 2009 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.
+
+// We require Linux kernel version 2.6.32. The accept4 system call was
+// added in version 2.6.28, so in general we can use accept4.
+// Unfortunately, for ARM only, accept4 was added in version 2.6.36.
+// Handle that case here, by using a copy of the Accept function that
+// we used in Go 1.17.
+
+//go:build linux && arm
+
+package syscall
+
+//sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
+
+func Accept(fd int) (nfd int, sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	var len _Socklen = SizeofSockaddrAny
+	// Try accept4 first for Android and newer kernels.
+	nfd, err = accept4(fd, &rsa, &len, 0)
+	if err == ENOSYS {
+		nfd, err = accept(fd, &rsa, &len)
+	}
+	if err != nil {
+		return
+	}
+	sa, err = anyToSockaddr(&rsa)
+	if err != nil {
+		Close(nfd)
+		nfd = 0
+	}
+	return
+}
diff --git a/src/syscall/syscall_linux_accept4.go b/src/syscall/syscall_linux_accept4.go
new file mode 100644
index 0000000..7489867
--- /dev/null
+++ b/src/syscall/syscall_linux_accept4.go
@@ -0,0 +1,25 @@
+// Copyright 2009 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 file provides the Accept function used on all systems
+// other than arm. See syscall_linux_accept.go for why.
+
+//go:build linux && !arm
+
+package syscall
+
+func Accept(fd int) (nfd int, sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	var len _Socklen = SizeofSockaddrAny
+	nfd, err = accept4(fd, &rsa, &len, 0)
+	if err != nil {
+		return
+	}
+	sa, err = anyToSockaddr(&rsa)
+	if err != nil {
+		Close(nfd)
+		nfd = 0
+	}
+	return
+}
diff --git a/src/syscall/syscall_openbsd_libc.go b/src/syscall/syscall_openbsd_libc.go
index 516d029..6358a9a 100644
--- a/src/syscall/syscall_openbsd_libc.go
+++ b/src/syscall/syscall_openbsd_libc.go
@@ -10,7 +10,11 @@
 	"internal/abi"
 )
 
-var dupTrampoline = abi.FuncPCABI0(libc_dup3_trampoline)
+var (
+	dupTrampoline  = abi.FuncPCABI0(libc_dup3_trampoline)
+	exitTrampoline = abi.FuncPCABI0(libc_exit_trampoline)
+	forkTrampoline = abi.FuncPCABI0(libc_fork_trampoline)
+)
 
 func init() {
 	execveOpenBSD = execve
diff --git a/src/syscall/zsyscall_darwin_amd64.go b/src/syscall/zsyscall_darwin_amd64.go
index 6b3fff3..5e3f6cc 100644
--- a/src/syscall/zsyscall_darwin_amd64.go
+++ b/src/syscall/zsyscall_darwin_amd64.go
@@ -1734,8 +1734,8 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fork() (pid int, err error) {
-	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
+func __fork() (pid int, err error) {
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc___fork_trampoline), 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1743,9 +1743,9 @@
 	return
 }
 
-func libc_fork_trampoline()
+func libc___fork_trampoline()
 
-//go:cgo_import_dynamic libc_fork fork "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc___fork __fork "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
@@ -1801,6 +1801,20 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func __exit(res int) (err error) {
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc___exit_trampoline), uintptr(res), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc___exit_trampoline()
+
+//go:cgo_import_dynamic libc___exit __exit "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
 	var _p0 unsafe.Pointer
 	if len(mib) > 0 {
diff --git a/src/syscall/zsyscall_darwin_amd64.s b/src/syscall/zsyscall_darwin_amd64.s
index 90e51fb..cbb4496 100644
--- a/src/syscall/zsyscall_darwin_amd64.s
+++ b/src/syscall/zsyscall_darwin_amd64.s
@@ -221,14 +221,16 @@
 	JMP	libc_mmap(SB)
 TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_munmap(SB)
-TEXT ·libc_fork_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fork(SB)
+TEXT ·libc___fork_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc___fork(SB)
 TEXT ·libc_ioctl_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_ioctl(SB)
 TEXT ·libc_execve_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_execve(SB)
 TEXT ·libc_exit_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_exit(SB)
+TEXT ·libc___exit_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc___exit(SB)
 TEXT ·libc_sysctl_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_sysctl(SB)
 TEXT ·libc_unlinkat_trampoline(SB),NOSPLIT,$0-0
diff --git a/src/syscall/zsyscall_darwin_arm64.go b/src/syscall/zsyscall_darwin_arm64.go
index 6160144..d4c56be 100644
--- a/src/syscall/zsyscall_darwin_arm64.go
+++ b/src/syscall/zsyscall_darwin_arm64.go
@@ -1734,8 +1734,8 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fork() (pid int, err error) {
-	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
+func __fork() (pid int, err error) {
+	r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc___fork_trampoline), 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1743,9 +1743,9 @@
 	return
 }
 
-func libc_fork_trampoline()
+func libc___fork_trampoline()
 
-//go:cgo_import_dynamic libc_fork fork "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc___fork __fork "/usr/lib/libSystem.B.dylib"
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
@@ -1801,6 +1801,20 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func __exit(res int) (err error) {
+	_, _, e1 := rawSyscall(abi.FuncPCABI0(libc___exit_trampoline), uintptr(res), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc___exit_trampoline()
+
+//go:cgo_import_dynamic libc___exit __exit "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
 	var _p0 unsafe.Pointer
 	if len(mib) > 0 {
diff --git a/src/syscall/zsyscall_darwin_arm64.s b/src/syscall/zsyscall_darwin_arm64.s
index f007479..ce1850e 100644
--- a/src/syscall/zsyscall_darwin_arm64.s
+++ b/src/syscall/zsyscall_darwin_arm64.s
@@ -221,14 +221,16 @@
 	JMP	libc_mmap(SB)
 TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_munmap(SB)
-TEXT ·libc_fork_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fork(SB)
+TEXT ·libc___fork_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc___fork(SB)
 TEXT ·libc_ioctl_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_ioctl(SB)
 TEXT ·libc_execve_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_execve(SB)
 TEXT ·libc_exit_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_exit(SB)
+TEXT ·libc___exit_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc___exit(SB)
 TEXT ·libc_sysctl_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_sysctl(SB)
 TEXT ·libc_unlinkat_trampoline(SB),NOSPLIT,$0-0
diff --git a/src/syscall/zsyscall_linux_arm.go b/src/syscall/zsyscall_linux_arm.go
index db5ec60..69f811a 100644
--- a/src/syscall/zsyscall_linux_arm.go
+++ b/src/syscall/zsyscall_linux_arm.go
@@ -1,4 +1,4 @@
-// mksyscall.pl -l32 -arm -tags linux,arm syscall_linux.go syscall_linux_arm.go
+// mksyscall.pl -l32 -arm -tags linux,arm syscall_linux.go syscall_linux_arm.go syscall_linux_accept.go
 // Code generated by the command above; DO NOT EDIT.
 
 //go:build linux && arm
@@ -1601,3 +1601,14 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/src/testing/testing.go b/src/testing/testing.go
index acd2866..fc34cbf 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -13,8 +13,9 @@
 //
 // Within these functions, use the Error, Fail or related methods to signal failure.
 //
-// To write a new test suite, create a file whose name ends _test.go that
-// contains the TestXxx functions as described here.
+// To write a new test suite, create a file that
+// contains the TestXxx functions as described here,
+// and give that file a name ending in "_test.go".
 // The file will be excluded from regular
 // package builds but will be included when the "go test" command is run.
 //
diff --git a/test/fixedbugs/issue57184.go b/test/fixedbugs/issue57184.go
new file mode 100644
index 0000000..1384b50
--- /dev/null
+++ b/test/fixedbugs/issue57184.go
@@ -0,0 +1,40 @@
+// run
+
+// Copyright 2022 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 (
+	"log"
+	"reflect"
+	"sort"
+)
+
+func main() {
+	const length = 257
+	x := make([]int64, length)
+	for i := 0; i < length; i++ {
+		x[i] = int64(i) * 27644437 % int64(length)
+	}
+
+	isLessStatic := func(i, j int) bool {
+		return x[i] < x[j]
+	}
+
+	isLessReflect := reflect.MakeFunc(reflect.TypeOf(isLessStatic), func(args []reflect.Value) []reflect.Value {
+		i := args[0].Int()
+		j := args[1].Int()
+		b := x[i] < x[j]
+		return []reflect.Value{reflect.ValueOf(b)}
+	}).Interface().(func(i, j int) bool)
+
+	sort.SliceStable(x, isLessReflect)
+
+	for i := 0; i < length-1; i++ {
+		if x[i] >= x[i+1] {
+			log.Fatalf("not sorted! (length=%v, idx=%v)\n%v\n", length, i, x)
+		}
+	}
+}
diff --git a/test/fixedbugs/issue57309.go b/test/fixedbugs/issue57309.go
new file mode 100644
index 0000000..ec6a397
--- /dev/null
+++ b/test/fixedbugs/issue57309.go
@@ -0,0 +1,23 @@
+// run
+
+// Copyright 2022 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
+
+type I interface {
+	M()
+}
+
+type S struct {
+}
+
+func (*S) M() {
+}
+
+func main() {
+	func() {
+		I(&S{}).M()
+	}()
+}