aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Anthony Knyszek <mknyszek@google.com>2021-12-03 11:56:22 -0500
committerMichael Anthony Knyszek <mknyszek@google.com>2021-12-03 11:56:22 -0500
commit95e6359f6a5d040c7773ea943443536a07b543ec (patch)
treed7dd1d946eebacebf82ec731a35a10a9e9aa56ae
parent5a371e30afcb9377c21b3b2e3028a28f80e02b01 (diff)
parent0f2d0d0694c8680909252ca45dbffbcaff8e430a (diff)
downloadgo-95e6359f6a5d040c7773ea943443536a07b543ec.tar.gz
go-95e6359f6a5d040c7773ea943443536a07b543ec.zip
[dev.boringcrypto.go1.17] all: merge go1.17.4 into dev.boringcrypto.go1.17
Change-Id: I1fdbced0ec670a133ced9702c24266dcadc47faf
-rw-r--r--src/cmd/compile/internal/noder/transform.go9
-rw-r--r--src/cmd/compile/internal/ssa/expand_calls.go2
-rw-r--r--src/cmd/compile/internal/ssa/fuse_branchredirect.go6
-rw-r--r--src/cmd/compile/internal/typecheck/stmt.go9
-rw-r--r--src/cmd/go/script_test.go1
-rw-r--r--src/cmd/go/testdata/script/mod_get_direct.txt2
-rw-r--r--src/cmd/link/internal/arm64/asm.go2
-rw-r--r--src/cmd/link/link_test.go18
-rw-r--r--src/go.mod2
-rw-r--r--src/go.sum4
-rw-r--r--src/go/types/decl.go1
-rw-r--r--src/go/types/testdata/fixedbugs/issue48819.src15
-rw-r--r--src/go/types/type.go3
-rw-r--r--src/net/http/client.go1
-rw-r--r--src/net/http/client_test.go27
-rw-r--r--src/net/http/clientserver_test.go34
-rw-r--r--src/net/http/h2_bundle.go81
-rw-r--r--src/net/http/server.go7
-rw-r--r--src/runtime/sys_darwin.go94
-rw-r--r--src/runtime/sys_darwin_arm64.go4
-rw-r--r--src/runtime/sys_openbsd.go22
-rw-r--r--src/runtime/sys_openbsd1.go5
-rw-r--r--src/runtime/sys_openbsd2.go36
-rw-r--r--src/runtime/sys_plan9_amd64.s2
-rw-r--r--src/runtime/sys_windows_amd64.s13
-rw-r--r--src/runtime/sys_windows_arm.s2
-rw-r--r--src/runtime/sys_windows_arm64.s10
-rw-r--r--src/runtime/syscall_solaris.go2
-rw-r--r--src/runtime/syscall_windows.go4
-rw-r--r--src/runtime/time_windows.h1
-rw-r--r--src/runtime/time_windows_amd64.s21
-rw-r--r--src/runtime/time_windows_arm.s4
-rw-r--r--src/runtime/time_windows_arm64.s31
-rw-r--r--src/time/time.go14
-rw-r--r--src/time/time_test.go42
-rw-r--r--src/vendor/modules.txt2
-rw-r--r--test/fixedbugs/issue48289.go28
-rw-r--r--test/fixedbugs/issue49122.go16
-rw-r--r--test/fixedbugs/issue49249.go55
-rw-r--r--test/fixedbugs/issue49378.go25
40 files changed, 508 insertions, 149 deletions
diff --git a/src/cmd/compile/internal/noder/transform.go b/src/cmd/compile/internal/noder/transform.go
index 2859089e69b..1a0c4d94c7e 100644
--- a/src/cmd/compile/internal/noder/transform.go
+++ b/src/cmd/compile/internal/noder/transform.go
@@ -495,10 +495,11 @@ func transformSelect(sel *ir.SelectStmt) {
if ncase.Comm != nil {
n := ncase.Comm
oselrecv2 := func(dst, recv ir.Node, def bool) {
- n := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, []ir.Node{dst, ir.BlankNode}, []ir.Node{recv})
- n.Def = def
- n.SetTypecheck(1)
- ncase.Comm = n
+ selrecv := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, []ir.Node{dst, ir.BlankNode}, []ir.Node{recv})
+ selrecv.Def = def
+ selrecv.SetTypecheck(1)
+ selrecv.SetInit(n.Init())
+ ncase.Comm = selrecv
}
switch n.Op() {
case ir.OAS:
diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go
index 7e973ab2059..0c4a7fba4d0 100644
--- a/src/cmd/compile/internal/ssa/expand_calls.go
+++ b/src/cmd/compile/internal/ssa/expand_calls.go
@@ -952,6 +952,7 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
}
eltRO := x.regWidth(elt)
+ source.Type = t
for i := int64(0); i < t.NumElem(); i++ {
sel := source.Block.NewValue1I(pos, OpArraySelect, elt, i, source)
mem = x.storeArgOrLoad(pos, b, sel, mem, elt, storeOffset+i*elt.Width, loadRegOffset, storeRc.at(t, 0))
@@ -985,6 +986,7 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
}
+ source.Type = t
for i := 0; i < t.NumFields(); i++ {
fld := t.Field(i)
sel := source.Block.NewValue1I(pos, OpStructSelect, fld.Type, int64(i), source)
diff --git a/src/cmd/compile/internal/ssa/fuse_branchredirect.go b/src/cmd/compile/internal/ssa/fuse_branchredirect.go
index 1b8b307bcac..ba5220bd87c 100644
--- a/src/cmd/compile/internal/ssa/fuse_branchredirect.go
+++ b/src/cmd/compile/internal/ssa/fuse_branchredirect.go
@@ -78,7 +78,11 @@ func fuseBranchRedirect(f *Func) bool {
if v.Op != OpPhi {
continue
}
- v.RemoveArg(k)
+ n := len(v.Args)
+ v.Args[k].Uses--
+ v.Args[k] = v.Args[n-1]
+ v.Args[n-1] = nil
+ v.Args = v.Args[:n-1]
phielimValue(v)
}
// Fix up child to have one more predecessor.
diff --git a/src/cmd/compile/internal/typecheck/stmt.go b/src/cmd/compile/internal/typecheck/stmt.go
index 922a01bfbe9..2fc6d04e854 100644
--- a/src/cmd/compile/internal/typecheck/stmt.go
+++ b/src/cmd/compile/internal/typecheck/stmt.go
@@ -383,10 +383,11 @@ func tcSelect(sel *ir.SelectStmt) {
n := Stmt(ncase.Comm)
ncase.Comm = n
oselrecv2 := func(dst, recv ir.Node, def bool) {
- n := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, []ir.Node{dst, ir.BlankNode}, []ir.Node{recv})
- n.Def = def
- n.SetTypecheck(1)
- ncase.Comm = n
+ selrecv := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, []ir.Node{dst, ir.BlankNode}, []ir.Node{recv})
+ selrecv.Def = def
+ selrecv.SetTypecheck(1)
+ selrecv.SetInit(n.Init())
+ ncase.Comm = selrecv
}
switch n.Op() {
default:
diff --git a/src/cmd/go/script_test.go b/src/cmd/go/script_test.go
index 639e907db07..c0156d02627 100644
--- a/src/cmd/go/script_test.go
+++ b/src/cmd/go/script_test.go
@@ -142,6 +142,7 @@ var extraEnvKeys = []string{
"GO_TESTING_GOTOOLS", // for gccgo testing
"GCCGO", // for gccgo testing
"GCCGOTOOLDIR", // for gccgo testing
+ "MallocNanoZone", // Needed to work around an apparent kernel bug in macOS 12; see https://golang.org/issue/49138.
}
// setup sets up the test execution temporary directory and environment.
diff --git a/src/cmd/go/testdata/script/mod_get_direct.txt b/src/cmd/go/testdata/script/mod_get_direct.txt
index 42ccbcd38a1..856e05bc329 100644
--- a/src/cmd/go/testdata/script/mod_get_direct.txt
+++ b/src/cmd/go/testdata/script/mod_get_direct.txt
@@ -10,7 +10,7 @@ env GO111MODULE=on
env GOPROXY=direct
env GOSUMDB=off
-go list -m cloud.google.com/go@master
+go list -m cloud.google.com/go@main
! stdout 'v0.0.0-'
-- go.mod --
diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go
index c10bdc4120a..734ab3a3793 100644
--- a/src/cmd/link/internal/arm64/asm.go
+++ b/src/cmd/link/internal/arm64/asm.go
@@ -602,7 +602,7 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym,
rs := r.Xsym
rt := r.Type
- if r.Xadd != signext21(r.Xadd) {
+ if rt == objabi.R_ADDRARM64 && r.Xadd != signext21(r.Xadd) {
// If the relocation target would overflow the addend, then target
// a linker-manufactured label symbol with a smaller addend instead.
label := ldr.Lookup(offsetLabelName(ldr, rs, r.Xadd/peRelocLimit*peRelocLimit), ldr.SymVersion(rs))
diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go
index 7230054bedd..a9b597b3236 100644
--- a/src/cmd/link/link_test.go
+++ b/src/cmd/link/link_test.go
@@ -993,13 +993,31 @@ package main
var x = [1<<25]byte{1<<23: 23, 1<<24: 24}
+var addr = [...]*byte{
+ &x[1<<23-1],
+ &x[1<<23],
+ &x[1<<23+1],
+ &x[1<<24-1],
+ &x[1<<24],
+ &x[1<<24+1],
+}
+
func main() {
+ // check relocations in instructions
check(x[1<<23-1], 0)
check(x[1<<23], 23)
check(x[1<<23+1], 0)
check(x[1<<24-1], 0)
check(x[1<<24], 24)
check(x[1<<24+1], 0)
+
+ // check absolute address relocations in data
+ check(*addr[0], 0)
+ check(*addr[1], 23)
+ check(*addr[2], 0)
+ check(*addr[3], 0)
+ check(*addr[4], 24)
+ check(*addr[5], 0)
}
func check(x, y byte) {
diff --git a/src/go.mod b/src/go.mod
index 386b51a6569..1971741efa5 100644
--- a/src/go.mod
+++ b/src/go.mod
@@ -4,7 +4,7 @@ go 1.17
require (
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e
- golang.org/x/net v0.0.0-20211101194204-95aca89e93de
+ golang.org/x/net v0.0.0-20211201233630-85e122b1a9b3
)
require (
diff --git a/src/go.sum b/src/go.sum
index 1f328206ecb..32c714d1edf 100644
--- a/src/go.sum
+++ b/src/go.sum
@@ -1,8 +1,8 @@
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e h1:8foAy0aoO5GkqCvAEJ4VC4P3zksTg4X4aJCDpZzmgQI=
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20211101194204-95aca89e93de h1:dKoXPECQZ51dGVSkuiD9YzeNpLT4UPUY4d3xo0sWrkU=
-golang.org/x/net v0.0.0-20211101194204-95aca89e93de/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211201233630-85e122b1a9b3 h1:0tKANouoxlq5b2OS7rABX92sfG5Dkz24NFtLSu09W3o=
+golang.org/x/net v0.0.0-20211201233630-85e122b1a9b3/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 h1:yhBbb4IRs2HS9PPlAg6DMC6mUOKexJBNsLf4Z+6En1Q=
diff --git a/src/go/types/decl.go b/src/go/types/decl.go
index 9211febc6da..ec173ad1ccc 100644
--- a/src/go/types/decl.go
+++ b/src/go/types/decl.go
@@ -343,6 +343,7 @@ func (check *Checker) validType(typ Type, path []Object) typeInfo {
if tn == t.obj {
check.cycleError(path[i:])
t.info = invalid
+ t.underlying = Typ[Invalid]
return t.info
}
}
diff --git a/src/go/types/testdata/fixedbugs/issue48819.src b/src/go/types/testdata/fixedbugs/issue48819.src
new file mode 100644
index 00000000000..9262110ea09
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue48819.src
@@ -0,0 +1,15 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import "unsafe"
+
+type T /* ERROR illegal cycle in declaration of T */ struct {
+ T
+}
+
+func _(t T) {
+ _ = unsafe.Sizeof(t) // should not go into infinite recursion here
+}
diff --git a/src/go/types/type.go b/src/go/types/type.go
index 2660ce4408c..20c4bec0bce 100644
--- a/src/go/types/type.go
+++ b/src/go/types/type.go
@@ -759,6 +759,9 @@ func (check *Checker) newTypeParam(obj *TypeName, index int, bound Type) *_TypeP
func (t *_TypeParam) Bound() *Interface {
iface := asInterface(t.bound)
+ if iface == nil {
+ return &emptyInterface
+ }
// use the type bound position if we have one
pos := token.NoPos
if n, _ := t.bound.(*Named); n != nil {
diff --git a/src/net/http/client.go b/src/net/http/client.go
index 4d380c65db9..22db96b2674 100644
--- a/src/net/http/client.go
+++ b/src/net/http/client.go
@@ -965,7 +965,6 @@ func (b *cancelTimerBody) Read(p []byte) (n int, err error) {
if err == nil {
return n, nil
}
- b.stop()
if err == io.EOF {
return n, err
}
diff --git a/src/net/http/client_test.go b/src/net/http/client_test.go
index 01d605c3519..9788c7a9c38 100644
--- a/src/net/http/client_test.go
+++ b/src/net/http/client_test.go
@@ -1353,6 +1353,33 @@ func TestClientTimeoutCancel(t *testing.T) {
}
}
+func TestClientTimeoutDoesNotExpire_h1(t *testing.T) { testClientTimeoutDoesNotExpire(t, h1Mode) }
+func TestClientTimeoutDoesNotExpire_h2(t *testing.T) { testClientTimeoutDoesNotExpire(t, h2Mode) }
+
+// Issue 49366: if Client.Timeout is set but not hit, no error should be returned.
+func testClientTimeoutDoesNotExpire(t *testing.T, h2 bool) {
+ setParallel(t)
+ defer afterTest(t)
+
+ cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+ w.Write([]byte("body"))
+ }))
+ defer cst.close()
+
+ cst.c.Timeout = 1 * time.Hour
+ req, _ := NewRequest("GET", cst.ts.URL, nil)
+ res, err := cst.c.Do(req)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if _, err = io.Copy(io.Discard, res.Body); err != nil {
+ t.Fatalf("io.Copy(io.Discard, res.Body) = %v, want nil", err)
+ }
+ if err = res.Body.Close(); err != nil {
+ t.Fatalf("res.Body.Close() = %v, want nil", err)
+ }
+}
+
func TestClientRedirectEatsBody_h1(t *testing.T) { testClientRedirectEatsBody(t, h1Mode) }
func TestClientRedirectEatsBody_h2(t *testing.T) { testClientRedirectEatsBody(t, h2Mode) }
func testClientRedirectEatsBody(t *testing.T, h2 bool) {
diff --git a/src/net/http/clientserver_test.go b/src/net/http/clientserver_test.go
index 5e227181acb..125d63566bc 100644
--- a/src/net/http/clientserver_test.go
+++ b/src/net/http/clientserver_test.go
@@ -1582,3 +1582,37 @@ func TestH12_WebSocketUpgrade(t *testing.T) {
},
}.run(t)
}
+
+func TestIdentityTransferEncoding_h1(t *testing.T) { testIdentityTransferEncoding(t, h1Mode) }
+func TestIdentityTransferEncoding_h2(t *testing.T) { testIdentityTransferEncoding(t, h2Mode) }
+
+func testIdentityTransferEncoding(t *testing.T, h2 bool) {
+ setParallel(t)
+ defer afterTest(t)
+
+ const body = "body"
+ cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+ gotBody, _ := io.ReadAll(r.Body)
+ if got, want := string(gotBody), body; got != want {
+ t.Errorf("got request body = %q; want %q", got, want)
+ }
+ w.Header().Set("Transfer-Encoding", "identity")
+ w.WriteHeader(StatusOK)
+ w.(Flusher).Flush()
+ io.WriteString(w, body)
+ }))
+ defer cst.close()
+ req, _ := NewRequest("GET", cst.ts.URL, strings.NewReader(body))
+ res, err := cst.c.Do(req)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer res.Body.Close()
+ gotBody, err := io.ReadAll(res.Body)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if got, want := string(gotBody), body; got != want {
+ t.Errorf("got response body = %q; want %q", got, want)
+ }
+}
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
index 9112079a224..7e1195cfd77 100644
--- a/src/net/http/h2_bundle.go
+++ b/src/net/http/h2_bundle.go
@@ -7658,36 +7658,49 @@ func (cc *http2ClientConn) RoundTrip(req *Request) (*Response, error) {
}
}
+ handleResponseHeaders := func() (*Response, error) {
+ res := cs.res
+ if res.StatusCode > 299 {
+ // On error or status code 3xx, 4xx, 5xx, etc abort any
+ // ongoing write, assuming that the server doesn't care
+ // about our request body. If the server replied with 1xx or
+ // 2xx, however, then assume the server DOES potentially
+ // want our body (e.g. full-duplex streaming:
+ // golang.org/issue/13444). If it turns out the server
+ // doesn't, they'll RST_STREAM us soon enough. This is a
+ // heuristic to avoid adding knobs to Transport. Hopefully
+ // we can keep it.
+ cs.abortRequestBodyWrite()
+ }
+ res.Request = req
+ res.TLS = cc.tlsState
+ if res.Body == http2noBody && http2actualContentLength(req) == 0 {
+ // If there isn't a request or response body still being
+ // written, then wait for the stream to be closed before
+ // RoundTrip returns.
+ if err := waitDone(); err != nil {
+ return nil, err
+ }
+ }
+ return res, nil
+ }
+
for {
select {
case <-cs.respHeaderRecv:
- res := cs.res
- if res.StatusCode > 299 {
- // On error or status code 3xx, 4xx, 5xx, etc abort any
- // ongoing write, assuming that the server doesn't care
- // about our request body. If the server replied with 1xx or
- // 2xx, however, then assume the server DOES potentially
- // want our body (e.g. full-duplex streaming:
- // golang.org/issue/13444). If it turns out the server
- // doesn't, they'll RST_STREAM us soon enough. This is a
- // heuristic to avoid adding knobs to Transport. Hopefully
- // we can keep it.
- cs.abortRequestBodyWrite()
- }
- res.Request = req
- res.TLS = cc.tlsState
- if res.Body == http2noBody && http2actualContentLength(req) == 0 {
- // If there isn't a request or response body still being
- // written, then wait for the stream to be closed before
- // RoundTrip returns.
- if err := waitDone(); err != nil {
- return nil, err
- }
- }
- return res, nil
+ return handleResponseHeaders()
case <-cs.abort:
- waitDone()
- return nil, cs.abortErr
+ select {
+ case <-cs.respHeaderRecv:
+ // If both cs.respHeaderRecv and cs.abort are signaling,
+ // pick respHeaderRecv. The server probably wrote the
+ // response and immediately reset the stream.
+ // golang.org/issue/49645
+ return handleResponseHeaders()
+ default:
+ waitDone()
+ return nil, cs.abortErr
+ }
case <-ctx.Done():
err := ctx.Err()
cs.abortStream(err)
@@ -7747,6 +7760,9 @@ func (cs *http2clientStream) writeRequest(req *Request) (err error) {
return err
}
cc.addStreamLocked(cs) // assigns stream ID
+ if http2isConnectionCloseRequest(req) {
+ cc.doNotReuse = true
+ }
cc.mu.Unlock()
// TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?
@@ -7770,12 +7786,12 @@ func (cs *http2clientStream) writeRequest(req *Request) (err error) {
}
continueTimeout := cc.t.expectContinueTimeout()
- if continueTimeout != 0 &&
- !httpguts.HeaderValuesContainsToken(
- req.Header["Expect"],
- "100-continue") {
- continueTimeout = 0
- cs.on100 = make(chan struct{}, 1)
+ if continueTimeout != 0 {
+ if !httpguts.HeaderValuesContainsToken(req.Header["Expect"], "100-continue") {
+ continueTimeout = 0
+ } else {
+ cs.on100 = make(chan struct{}, 1)
+ }
}
// Past this point (where we send request headers), it is possible for
@@ -7844,6 +7860,7 @@ func (cs *http2clientStream) writeRequest(req *Request) (err error) {
case <-respHeaderTimer:
return http2errTimeout
case <-respHeaderRecv:
+ respHeaderRecv = nil
respHeaderTimer = nil // keep waiting for END_STREAM
case <-cs.abort:
return cs.abortErr
diff --git a/src/net/http/server.go b/src/net/http/server.go
index 5b113cff970..4fc8fedfcda 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -1404,11 +1404,11 @@ func (cw *chunkWriter) writeHeader(p []byte) {
hasCL = false
}
- if w.req.Method == "HEAD" || !bodyAllowedForStatus(code) {
- // do nothing
- } else if code == StatusNoContent {
+ if w.req.Method == "HEAD" || !bodyAllowedForStatus(code) || code == StatusNoContent {
+ // Response has no body.
delHeader("Transfer-Encoding")
} else if hasCL {
+ // Content-Length has been provided, so no chunking is to be done.
delHeader("Transfer-Encoding")
} else if w.req.ProtoAtLeast(1, 1) {
// HTTP/1.1 or greater: Transfer-Encoding has been set to identity, and no
@@ -1419,6 +1419,7 @@ func (cw *chunkWriter) writeHeader(p []byte) {
if hasTE && te == "identity" {
cw.chunking = false
w.closeAfterReply = true
+ delHeader("Transfer-Encoding")
} else {
// HTTP/1.1 or greater: use chunked transfer encoding
// to avoid closing the connection at EOF.
diff --git a/src/runtime/sys_darwin.go b/src/runtime/sys_darwin.go
index 0f91685d6ca..83450fd64d7 100644
--- a/src/runtime/sys_darwin.go
+++ b/src/runtime/sys_darwin.go
@@ -105,28 +105,38 @@ func syscallNoErr()
//go:nosplit
//go:cgo_unsafe_args
func pthread_attr_init(attr *pthreadattr) int32 {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_init_trampoline)), unsafe.Pointer(&attr))
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_init_trampoline)), unsafe.Pointer(&attr))
+ KeepAlive(attr)
+ return ret
}
func pthread_attr_init_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_attr_getstacksize(attr *pthreadattr, size *uintptr) int32 {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_getstacksize_trampoline)), unsafe.Pointer(&attr))
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_getstacksize_trampoline)), unsafe.Pointer(&attr))
+ KeepAlive(attr)
+ KeepAlive(size)
+ return ret
}
func pthread_attr_getstacksize_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_attr_setdetachstate(attr *pthreadattr, state int) int32 {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_setdetachstate_trampoline)), unsafe.Pointer(&attr))
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_setdetachstate_trampoline)), unsafe.Pointer(&attr))
+ KeepAlive(attr)
+ return ret
}
func pthread_attr_setdetachstate_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_create(attr *pthreadattr, start uintptr, arg unsafe.Pointer) int32 {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_create_trampoline)), unsafe.Pointer(&attr))
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_create_trampoline)), unsafe.Pointer(&attr))
+ KeepAlive(attr)
+ KeepAlive(arg) // Just for consistency. Arg of course needs to be kept alive for the start function.
+ return ret
}
func pthread_create_trampoline()
@@ -175,6 +185,7 @@ func mmap_trampoline()
//go:cgo_unsafe_args
func munmap(addr unsafe.Pointer, n uintptr) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(munmap_trampoline)), unsafe.Pointer(&addr))
+ KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
}
func munmap_trampoline()
@@ -182,6 +193,7 @@ func munmap_trampoline()
//go:cgo_unsafe_args
func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(madvise_trampoline)), unsafe.Pointer(&addr))
+ KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
}
func madvise_trampoline()
@@ -189,13 +201,16 @@ func madvise_trampoline()
//go:cgo_unsafe_args
func mlock(addr unsafe.Pointer, n uintptr) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(mlock_trampoline)), unsafe.Pointer(&addr))
+ KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
}
func mlock_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func read(fd int32, p unsafe.Pointer, n int32) int32 {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(read_trampoline)), unsafe.Pointer(&fd))
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(read_trampoline)), unsafe.Pointer(&fd))
+ KeepAlive(p)
+ return ret
}
func read_trampoline()
@@ -239,14 +254,18 @@ func usleep_no_g(usec uint32) {
//go:nosplit
//go:cgo_unsafe_args
func write1(fd uintptr, p unsafe.Pointer, n int32) int32 {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(write_trampoline)), unsafe.Pointer(&fd))
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(write_trampoline)), unsafe.Pointer(&fd))
+ KeepAlive(p)
+ return ret
}
func write_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func open(name *byte, mode, perm int32) (ret int32) {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(open_trampoline)), unsafe.Pointer(&name))
+ ret = libcCall(unsafe.Pointer(abi.FuncPCABI0(open_trampoline)), unsafe.Pointer(&name))
+ KeepAlive(name)
+ return
}
func open_trampoline()
@@ -285,6 +304,8 @@ func walltime_trampoline()
//go:cgo_unsafe_args
func sigaction(sig uint32, new *usigactiont, old *usigactiont) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaction_trampoline)), unsafe.Pointer(&sig))
+ KeepAlive(new)
+ KeepAlive(old)
}
func sigaction_trampoline()
@@ -292,6 +313,8 @@ func sigaction_trampoline()
//go:cgo_unsafe_args
func sigprocmask(how uint32, new *sigset, old *sigset) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(sigprocmask_trampoline)), unsafe.Pointer(&how))
+ KeepAlive(new)
+ KeepAlive(old)
}
func sigprocmask_trampoline()
@@ -306,6 +329,8 @@ func sigaltstack(new *stackt, old *stackt) {
new.ss_size = 32768
}
libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaltstack_trampoline)), unsafe.Pointer(&new))
+ KeepAlive(new)
+ KeepAlive(old)
}
func sigaltstack_trampoline()
@@ -320,20 +345,32 @@ func raiseproc_trampoline()
//go:cgo_unsafe_args
func setitimer(mode int32, new, old *itimerval) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(setitimer_trampoline)), unsafe.Pointer(&mode))
+ KeepAlive(new)
+ KeepAlive(old)
}
func setitimer_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func sysctl(mib *uint32, miblen uint32, oldp *byte, oldlenp *uintptr, newp *byte, newlen uintptr) int32 {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctl_trampoline)), unsafe.Pointer(&mib))
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctl_trampoline)), unsafe.Pointer(&mib))
+ KeepAlive(mib)
+ KeepAlive(oldp)
+ KeepAlive(oldlenp)
+ KeepAlive(newp)
+ return ret
}
func sysctl_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func sysctlbyname(name *byte, oldp *byte, oldlenp *uintptr, newp *byte, newlen uintptr) int32 {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctlbyname_trampoline)), unsafe.Pointer(&name))
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctlbyname_trampoline)), unsafe.Pointer(&name))
+ KeepAlive(name)
+ KeepAlive(oldp)
+ KeepAlive(oldlenp)
+ KeepAlive(newp)
+ return ret
}
func sysctlbyname_trampoline()
@@ -355,56 +392,79 @@ func kqueue_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(kevent_trampoline)), unsafe.Pointer(&kq))
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(kevent_trampoline)), unsafe.Pointer(&kq))
+ KeepAlive(ch)
+ KeepAlive(ev)
+ KeepAlive(ts)
+ return ret
}
func kevent_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_mutex_init(m *pthreadmutex, attr *pthreadmutexattr) int32 {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_init_trampoline)), unsafe.Pointer(&m))
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_init_trampoline)), unsafe.Pointer(&m))
+ KeepAlive(m)
+ KeepAlive(attr)
+ return ret
}
func pthread_mutex_init_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_mutex_lock(m *pthreadmutex) int32 {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_lock_trampoline)), unsafe.Pointer(&m))
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_lock_trampoline)), unsafe.Pointer(&m))
+ KeepAlive(m)
+ return ret
}
func pthread_mutex_lock_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_mutex_unlock(m *pthreadmutex) int32 {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_unlock_trampoline)), unsafe.Pointer(&m))
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_unlock_trampoline)), unsafe.Pointer(&m))
+ KeepAlive(m)
+ return ret
}
func pthread_mutex_unlock_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_cond_init(c *pthreadcond, attr *pthreadcondattr) int32 {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_init_trampoline)), unsafe.Pointer(&c))
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_init_trampoline)), unsafe.Pointer(&c))
+ KeepAlive(c)
+ KeepAlive(attr)
+ return ret
}
func pthread_cond_init_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_cond_wait(c *pthreadcond, m *pthreadmutex) int32 {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_wait_trampoline)), unsafe.Pointer(&c))
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_wait_trampoline)), unsafe.Pointer(&c))
+ KeepAlive(c)
+ KeepAlive(m)
+ return ret
}
func pthread_cond_wait_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_cond_timedwait_relative_np(c *pthreadcond, m *pthreadmutex, t *timespec) int32 {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_timedwait_relative_np_trampoline)), unsafe.Pointer(&c))
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_timedwait_relative_np_trampoline)), unsafe.Pointer(&c))
+ KeepAlive(c)
+ KeepAlive(m)
+ KeepAlive(t)
+ return ret
}
func pthread_cond_timedwait_relative_np_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_cond_signal(c *pthreadcond) int32 {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_signal_trampoline)), unsafe.Pointer(&c))
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_signal_trampoline)), unsafe.Pointer(&c))
+ KeepAlive(c)
+ return ret
}
func pthread_cond_signal_trampoline()
diff --git a/src/runtime/sys_darwin_arm64.go b/src/runtime/sys_darwin_arm64.go
index 9c14f33a1ce..471e93cb71c 100644
--- a/src/runtime/sys_darwin_arm64.go
+++ b/src/runtime/sys_darwin_arm64.go
@@ -14,7 +14,9 @@ import (
//go:nosplit
//go:cgo_unsafe_args
func g0_pthread_key_create(k *pthreadkey, destructor uintptr) int32 {
- return asmcgocall(unsafe.Pointer(funcPC(pthread_key_create_trampoline)), unsafe.Pointer(&k))
+ ret := asmcgocall(unsafe.Pointer(funcPC(pthread_key_create_trampoline)), unsafe.Pointer(&k))
+ KeepAlive(k)
+ return ret
}
func pthread_key_create_trampoline()
diff --git a/src/runtime/sys_openbsd.go b/src/runtime/sys_openbsd.go
index ab3149558b3..25fd03863b4 100644
--- a/src/runtime/sys_openbsd.go
+++ b/src/runtime/sys_openbsd.go
@@ -15,35 +15,47 @@ import "unsafe"
//go:nosplit
//go:cgo_unsafe_args
func pthread_attr_init(attr *pthreadattr) int32 {
- return libcCall(unsafe.Pointer(funcPC(pthread_attr_init_trampoline)), unsafe.Pointer(&attr))
+ ret := libcCall(unsafe.Pointer(funcPC(pthread_attr_init_trampoline)), unsafe.Pointer(&attr))
+ KeepAlive(attr)
+ return ret
}
func pthread_attr_init_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_attr_destroy(attr *pthreadattr) int32 {
- return libcCall(unsafe.Pointer(funcPC(pthread_attr_destroy_trampoline)), unsafe.Pointer(&attr))
+ ret := libcCall(unsafe.Pointer(funcPC(pthread_attr_destroy_trampoline)), unsafe.Pointer(&attr))
+ KeepAlive(attr)
+ return ret
}
func pthread_attr_destroy_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_attr_getstacksize(attr *pthreadattr, size *uintptr) int32 {
- return libcCall(unsafe.Pointer(funcPC(pthread_attr_getstacksize_trampoline)), unsafe.Pointer(&attr))
+ ret := libcCall(unsafe.Pointer(funcPC(pthread_attr_getstacksize_trampoline)), unsafe.Pointer(&attr))
+ KeepAlive(attr)
+ KeepAlive(size)
+ return ret
}
func pthread_attr_getstacksize_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_attr_setdetachstate(attr *pthreadattr, state int) int32 {
- return libcCall(unsafe.Pointer(funcPC(pthread_attr_setdetachstate_trampoline)), unsafe.Pointer(&attr))
+ ret := libcCall(unsafe.Pointer(funcPC(pthread_attr_setdetachstate_trampoline)), unsafe.Pointer(&attr))
+ KeepAlive(attr)
+ return ret
}
func pthread_attr_setdetachstate_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_create(attr *pthreadattr, start uintptr, arg unsafe.Pointer) int32 {
- return libcCall(unsafe.Pointer(funcPC(pthread_create_trampoline)), unsafe.Pointer(&attr))
+ ret := libcCall(unsafe.Pointer(funcPC(pthread_create_trampoline)), unsafe.Pointer(&attr))
+ KeepAlive(attr)
+ KeepAlive(arg) // Just for consistency. Arg of course needs to be kept alive for the start function.
+ return ret
}
func pthread_create_trampoline()
diff --git a/src/runtime/sys_openbsd1.go b/src/runtime/sys_openbsd1.go
index cb5d35879cd..00a57ddb29d 100644
--- a/src/runtime/sys_openbsd1.go
+++ b/src/runtime/sys_openbsd1.go
@@ -12,7 +12,10 @@ import "unsafe"
//go:nosplit
//go:cgo_unsafe_args
func thrsleep(ident uintptr, clock_id int32, tsp *timespec, lock uintptr, abort *uint32) int32 {
- return libcCall(unsafe.Pointer(funcPC(thrsleep_trampoline)), unsafe.Pointer(&ident))
+ ret := libcCall(unsafe.Pointer(funcPC(thrsleep_trampoline)), unsafe.Pointer(&ident))
+ KeepAlive(tsp)
+ KeepAlive(abort)
+ return ret
}
func thrsleep_trampoline()
diff --git a/src/runtime/sys_openbsd2.go b/src/runtime/sys_openbsd2.go
index cd1a4e879fb..25d04e5d5a6 100644
--- a/src/runtime/sys_openbsd2.go
+++ b/src/runtime/sys_openbsd2.go
@@ -54,6 +54,7 @@ func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (un
ret2 int
}{addr, n, prot, flags, fd, off, nil, 0}
libcCall(unsafe.Pointer(funcPC(mmap_trampoline)), unsafe.Pointer(&args))
+ KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
return args.ret1, args.ret2
}
func mmap_trampoline()
@@ -62,6 +63,7 @@ func mmap_trampoline()
//go:cgo_unsafe_args
func munmap(addr unsafe.Pointer, n uintptr) {
libcCall(unsafe.Pointer(funcPC(munmap_trampoline)), unsafe.Pointer(&addr))
+ KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
}
func munmap_trampoline()
@@ -69,13 +71,16 @@ func munmap_trampoline()
//go:cgo_unsafe_args
func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
libcCall(unsafe.Pointer(funcPC(madvise_trampoline)), unsafe.Pointer(&addr))
+ KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
}
func madvise_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func open(name *byte, mode, perm int32) (ret int32) {
- return libcCall(unsafe.Pointer(funcPC(open_trampoline)), unsafe.Pointer(&name))
+ ret = libcCall(unsafe.Pointer(funcPC(open_trampoline)), unsafe.Pointer(&name))
+ KeepAlive(name)
+ return
}
func open_trampoline()
@@ -89,14 +94,18 @@ func close_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func read(fd int32, p unsafe.Pointer, n int32) int32 {
- return libcCall(unsafe.Pointer(funcPC(read_trampoline)), unsafe.Pointer(&fd))
+ ret := libcCall(unsafe.Pointer(funcPC(read_trampoline)), unsafe.Pointer(&fd))
+ KeepAlive(p)
+ return ret
}
func read_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func write1(fd uintptr, p unsafe.Pointer, n int32) int32 {
- return libcCall(unsafe.Pointer(funcPC(write_trampoline)), unsafe.Pointer(&fd))
+ ret := libcCall(unsafe.Pointer(funcPC(write_trampoline)), unsafe.Pointer(&fd))
+ KeepAlive(p)
+ return ret
}
func write_trampoline()
@@ -119,6 +128,8 @@ func pipe2_trampoline()
//go:cgo_unsafe_args
func setitimer(mode int32, new, old *itimerval) {
libcCall(unsafe.Pointer(funcPC(setitimer_trampoline)), unsafe.Pointer(&mode))
+ KeepAlive(new)
+ KeepAlive(old)
}
func setitimer_trampoline()
@@ -138,7 +149,12 @@ func usleep_no_g(usec uint32) {
//go:nosplit
//go:cgo_unsafe_args
func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32 {
- return libcCall(unsafe.Pointer(funcPC(sysctl_trampoline)), unsafe.Pointer(&mib))
+ ret := libcCall(unsafe.Pointer(funcPC(sysctl_trampoline)), unsafe.Pointer(&mib))
+ KeepAlive(mib)
+ KeepAlive(out)
+ KeepAlive(size)
+ KeepAlive(dst)
+ return ret
}
func sysctl_trampoline()
@@ -182,7 +198,11 @@ func kqueue_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 {
- return libcCall(unsafe.Pointer(funcPC(kevent_trampoline)), unsafe.Pointer(&kq))
+ ret := libcCall(unsafe.Pointer(funcPC(kevent_trampoline)), unsafe.Pointer(&kq))
+ KeepAlive(ch)
+ KeepAlive(ev)
+ KeepAlive(ts)
+ return ret
}
func kevent_trampoline()
@@ -190,6 +210,8 @@ func kevent_trampoline()
//go:cgo_unsafe_args
func sigaction(sig uint32, new *sigactiont, old *sigactiont) {
libcCall(unsafe.Pointer(funcPC(sigaction_trampoline)), unsafe.Pointer(&sig))
+ KeepAlive(new)
+ KeepAlive(old)
}
func sigaction_trampoline()
@@ -197,6 +219,8 @@ func sigaction_trampoline()
//go:cgo_unsafe_args
func sigprocmask(how uint32, new *sigset, old *sigset) {
libcCall(unsafe.Pointer(funcPC(sigprocmask_trampoline)), unsafe.Pointer(&how))
+ KeepAlive(new)
+ KeepAlive(old)
}
func sigprocmask_trampoline()
@@ -204,6 +228,8 @@ func sigprocmask_trampoline()
//go:cgo_unsafe_args
func sigaltstack(new *stackt, old *stackt) {
libcCall(unsafe.Pointer(funcPC(sigaltstack_trampoline)), unsafe.Pointer(&new))
+ KeepAlive(new)
+ KeepAlive(old)
}
func sigaltstack_trampoline()
diff --git a/src/runtime/sys_plan9_amd64.s b/src/runtime/sys_plan9_amd64.s
index 731306ab448..068200b7f36 100644
--- a/src/runtime/sys_plan9_amd64.s
+++ b/src/runtime/sys_plan9_amd64.s
@@ -94,7 +94,7 @@ TEXT runtime·walltime(SB),NOSPLIT,$8-12
MOVQ 0(SP), AX
// generated code for
- // func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 }
+ // func f(x uint64) (uint64, uint64) { return x/1000000000, x%1000000000 }
// adapted to reduce duplication
MOVQ AX, CX
MOVQ $1360296554856532783, AX
diff --git a/src/runtime/sys_windows_amd64.s b/src/runtime/sys_windows_amd64.s
index e7782846b25..64fa6791f46 100644
--- a/src/runtime/sys_windows_amd64.s
+++ b/src/runtime/sys_windows_amd64.s
@@ -348,16 +348,9 @@ TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
CMPB runtime·useQPCTime(SB), $0
JNE useQPC
MOVQ $_INTERRUPT_TIME, DI
-loop:
- MOVL time_hi1(DI), AX
- MOVL time_lo(DI), BX
- MOVL time_hi2(DI), CX
- CMPL AX, CX
- JNE loop
- SHLQ $32, CX
- ORQ BX, CX
- IMULQ $100, CX
- MOVQ CX, ret+0(FP)
+ MOVQ time_lo(DI), AX
+ IMULQ $100, AX
+ MOVQ AX, ret+0(FP)
RET
useQPC:
JMP runtime·nanotimeQPC(SB)
diff --git a/src/runtime/sys_windows_arm.s b/src/runtime/sys_windows_arm.s
index 48f8c7dedff..d7ad244161e 100644
--- a/src/runtime/sys_windows_arm.s
+++ b/src/runtime/sys_windows_arm.s
@@ -350,7 +350,9 @@ TEXT runtime·nanotime1(SB),NOSPLIT|NOFRAME,$0-8
MOVW $_INTERRUPT_TIME, R3
loop:
MOVW time_hi1(R3), R1
+ DMB MB_ISH
MOVW time_lo(R3), R0
+ DMB MB_ISH
MOVW time_hi2(R3), R2
CMP R1, R2
BNE loop
diff --git a/src/runtime/sys_windows_arm64.s b/src/runtime/sys_windows_arm64.s
index 7a2e11f5ae2..183128dd09a 100644
--- a/src/runtime/sys_windows_arm64.s
+++ b/src/runtime/sys_windows_arm64.s
@@ -415,15 +415,7 @@ TEXT runtime·nanotime1(SB),NOSPLIT|NOFRAME,$0-8
CMP $0, R0
BNE useQPC
MOVD $_INTERRUPT_TIME, R3
-loop:
- MOVWU time_hi1(R3), R1
- MOVWU time_lo(R3), R0
- MOVWU time_hi2(R3), R2
- CMP R1, R2
- BNE loop
-
- // wintime = R1:R0, multiply by 100
- ORR R1<<32, R0
+ MOVD time_lo(R3), R0
MOVD $100, R1
MUL R1, R0
MOVD R0, ret+0(FP)
diff --git a/src/runtime/syscall_solaris.go b/src/runtime/syscall_solaris.go
index 094516927f3..ed5b7d19f90 100644
--- a/src/runtime/syscall_solaris.go
+++ b/src/runtime/syscall_solaris.go
@@ -303,6 +303,8 @@ func syscall_wait4(pid uintptr, wstatus *uint32, options uintptr, rusage unsafe.
entersyscallblock()
asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
exitsyscall()
+ KeepAlive(wstatus)
+ KeepAlive(rusage)
return int(call.r1), call.err
}
diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go
index 4763a440e7e..94a61c8823c 100644
--- a/src/runtime/syscall_windows.go
+++ b/src/runtime/syscall_windows.go
@@ -422,6 +422,8 @@ func syscall_loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (hand
}
cgocall(asmstdcallAddr, unsafe.Pointer(c))
+ KeepAlive(filename)
+ KeepAlive(absoluteFilepath)
handle = c.r1
if handle == 0 {
err = c.err
@@ -441,6 +443,7 @@ func syscall_loadlibrary(filename *uint16) (handle, err uintptr) {
c.n = 1
c.args = uintptr(noescape(unsafe.Pointer(&filename)))
cgocall(asmstdcallAddr, unsafe.Pointer(c))
+ KeepAlive(filename)
handle = c.r1
if handle == 0 {
err = c.err
@@ -459,6 +462,7 @@ func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uint
c.n = 2
c.args = uintptr(noescape(unsafe.Pointer(&handle)))
cgocall(asmstdcallAddr, unsafe.Pointer(c))
+ KeepAlive(procname)
outhandle = c.r1
if outhandle == 0 {
err = c.err
diff --git a/src/runtime/time_windows.h b/src/runtime/time_windows.h
index cd16fd163bb..7c2e65c328b 100644
--- a/src/runtime/time_windows.h
+++ b/src/runtime/time_windows.h
@@ -9,6 +9,7 @@
// http://web.archive.org/web/20210411000829/https://wrkhpi.wordpress.com/2007/08/09/getting-os-information-the-kuser_shared_data-structure/
// Must read hi1, then lo, then hi2. The snapshot is valid if hi1 == hi2.
+// Or, on 64-bit, just read lo:hi1 all at once atomically.
#define _INTERRUPT_TIME 0x7ffe0008
#define _SYSTEM_TIME 0x7ffe0014
#define time_lo 0
diff --git a/src/runtime/time_windows_amd64.s b/src/runtime/time_windows_amd64.s
index 93ab960b067..70f6a008cdd 100644
--- a/src/runtime/time_windows_amd64.s
+++ b/src/runtime/time_windows_amd64.s
@@ -12,33 +12,20 @@
TEXT time·now(SB),NOSPLIT,$0-24
CMPB runtime·useQPCTime(SB), $0
JNE useQPC
+
MOVQ $_INTERRUPT_TIME, DI
-loop:
- MOVL time_hi1(DI), AX
- MOVL time_lo(DI), BX
- MOVL time_hi2(DI), CX
- CMPL AX, CX
- JNE loop
- SHLQ $32, AX
- ORQ BX, AX
+ MOVQ time_lo(DI), AX
IMULQ $100, AX
MOVQ AX, mono+16(FP)
MOVQ $_SYSTEM_TIME, DI
-wall:
- MOVL time_hi1(DI), AX
- MOVL time_lo(DI), BX
- MOVL time_hi2(DI), CX
- CMPL AX, CX
- JNE wall
- SHLQ $32, AX
- ORQ BX, AX
+ MOVQ time_lo(DI), AX
MOVQ $116444736000000000, DI
SUBQ DI, AX
IMULQ $100, AX
// generated code for
- // func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 }
+ // func f(x uint64) (uint64, uint64) { return x/1000000000, x%1000000000 }
// adapted to reduce duplication
MOVQ AX, CX
MOVQ $1360296554856532783, AX
diff --git a/src/runtime/time_windows_arm.s b/src/runtime/time_windows_arm.s
index 7c763b66edd..6552d75ff1c 100644
--- a/src/runtime/time_windows_arm.s
+++ b/src/runtime/time_windows_arm.s
@@ -17,7 +17,9 @@ TEXT time·now(SB),NOSPLIT|NOFRAME,$0-20
MOVW $_INTERRUPT_TIME, R3
loop:
MOVW time_hi1(R3), R1
+ DMB MB_ISH
MOVW time_lo(R3), R0
+ DMB MB_ISH
MOVW time_hi2(R3), R2
CMP R1, R2
BNE loop
@@ -34,7 +36,9 @@ loop:
MOVW $_SYSTEM_TIME, R3
wall:
MOVW time_hi1(R3), R1
+ DMB MB_ISH
MOVW time_lo(R3), R0
+ DMB MB_ISH
MOVW time_hi2(R3), R2
CMP R1, R2
BNE wall
diff --git a/src/runtime/time_windows_arm64.s b/src/runtime/time_windows_arm64.s
index ef52ce4c994..ef5b8484737 100644
--- a/src/runtime/time_windows_arm64.s
+++ b/src/runtime/time_windows_arm64.s
@@ -13,34 +13,18 @@ TEXT time·now(SB),NOSPLIT|NOFRAME,$0-24
MOVB runtime·useQPCTime(SB), R0
CMP $0, R0
BNE useQPC
- MOVD $_INTERRUPT_TIME, R3
-loop:
- MOVWU time_hi1(R3), R1
- MOVWU time_lo(R3), R0
- MOVWU time_hi2(R3), R2
- CMP R1, R2
- BNE loop
- // wintime = R1:R0, multiply by 100
- ORR R1<<32, R0
+ MOVD $_INTERRUPT_TIME, R3
+ MOVD time_lo(R3), R0
MOVD $100, R1
MUL R1, R0
MOVD R0, mono+16(FP)
MOVD $_SYSTEM_TIME, R3
-wall:
- MOVWU time_hi1(R3), R1
- MOVWU time_lo(R3), R0
- MOVWU time_hi2(R3), R2
- CMP R1, R2
- BNE wall
-
- // w = R1:R0 in 100ns units
+ MOVD time_lo(R3), R0
// convert to Unix epoch (but still 100ns units)
#define delta 116444736000000000
- ORR R1<<32, R0
SUB $delta, R0
-
// Convert to nSec
MOVD $100, R1
MUL R1, R0
@@ -48,17 +32,14 @@ wall:
// Code stolen from compiler output for:
//
// var x uint64
- // func f() (sec uint64, nsec uint32) { return x / 1000000000, uint32(x % 100000000) }
+ // func f() (sec uint64, nsec uint32) { return x / 1000000000, uint32(x % 1000000000) }
//
LSR $1, R0, R1
MOVD $-8543223759426509416, R2
- UMULH R2, R1, R1
+ UMULH R1, R2, R1
LSR $28, R1, R1
MOVD R1, sec+0(FP)
- MOVD $-6067343680855748867, R1
- UMULH R0, R1, R1
- LSR $26, R1, R1
- MOVD $100000000, R2
+ MOVD $1000000000, R2
MSUB R1, R0, R2, R0
MOVW R0, nsec+8(FP)
RET
diff --git a/src/time/time.go b/src/time/time.go
index 4ecc3d82dcc..a7d06cdef3f 100644
--- a/src/time/time.go
+++ b/src/time/time.go
@@ -1416,17 +1416,17 @@ func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) T
unix := int64(abs) + (absoluteToInternal + internalToUnix)
- // Look for zone offset for t, so we can adjust to UTC.
- // The lookup function expects UTC, so we pass t in the
+ // Look for zone offset for expected time, so we can adjust to UTC.
+ // The lookup function expects UTC, so first we pass unix in the
// hope that it will not be too close to a zone transition,
// and then adjust if it is.
_, offset, start, end, _ := loc.lookup(unix)
if offset != 0 {
- switch utc := unix - int64(offset); {
- case utc < start:
- _, offset, _, _, _ = loc.lookup(start - 1)
- case utc >= end:
- _, offset, _, _, _ = loc.lookup(end)
+ utc := unix - int64(offset)
+ // If utc is valid for the time zone we found, then we have the right offset.
+ // If not, we get the correct offset by looking up utc in the location.
+ if utc < start || utc >= end {
+ _, offset, _, _, _ = loc.lookup(utc)
}
unix -= int64(offset)
}
diff --git a/src/time/time_test.go b/src/time/time_test.go
index cea5f2d3f5a..906ceb8defb 100644
--- a/src/time/time_test.go
+++ b/src/time/time_test.go
@@ -1569,3 +1569,45 @@ func TestTimeAddSecOverflow(t *testing.T) {
}
}
}
+
+// Issue 49284: time: ParseInLocation incorrectly because of Daylight Saving Time
+func TestTimeWithZoneTransition(t *testing.T) {
+ ForceZipFileForTesting(true)
+ defer ForceZipFileForTesting(false)
+
+ loc, err := LoadLocation("Asia/Shanghai")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ tests := [...]struct {
+ give Time
+ want Time
+ }{
+ // 14 Apr 1991 - Daylight Saving Time Started
+ // When time of "Asia/Shanghai" was about to reach
+ // Sunday, 14 April 1991, 02:00:00 clocks were turned forward 1 hour to
+ // Sunday, 14 April 1991, 03:00:00 local daylight time instead.
+ // The UTC time was 13 April 1991, 18:00:00
+ 0: {Date(1991, April, 13, 17, 50, 0, 0, loc), Date(1991, April, 13, 9, 50, 0, 0, UTC)},
+ 1: {Date(1991, April, 13, 18, 0, 0, 0, loc), Date(1991, April, 13, 10, 0, 0, 0, UTC)},
+ 2: {Date(1991, April, 14, 1, 50, 0, 0, loc), Date(1991, April, 13, 17, 50, 0, 0, UTC)},
+ 3: {Date(1991, April, 14, 3, 0, 0, 0, loc), Date(1991, April, 13, 18, 0, 0, 0, UTC)},
+
+ // 15 Sep 1991 - Daylight Saving Time Ended
+ // When local daylight time of "Asia/Shanghai" was about to reach
+ // Sunday, 15 September 1991, 02:00:00 clocks were turned backward 1 hour to
+ // Sunday, 15 September 1991, 01:00:00 local standard time instead.
+ // The UTC time was 14 September 1991, 17:00:00
+ 4: {Date(1991, September, 14, 16, 50, 0, 0, loc), Date(1991, September, 14, 7, 50, 0, 0, UTC)},
+ 5: {Date(1991, September, 14, 17, 0, 0, 0, loc), Date(1991, September, 14, 8, 0, 0, 0, UTC)},
+ 6: {Date(1991, September, 15, 0, 50, 0, 0, loc), Date(1991, September, 14, 15, 50, 0, 0, UTC)},
+ 7: {Date(1991, September, 15, 2, 00, 0, 0, loc), Date(1991, September, 14, 18, 00, 0, 0, UTC)},
+ }
+
+ for i, tt := range tests {
+ if !tt.give.Equal(tt.want) {
+ t.Errorf("#%d:: %#v is not equal to %#v", i, tt.give.Format(RFC3339), tt.want.Format(RFC3339))
+ }
+ }
+}
diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt
index f61fc51ba82..0981b7f333f 100644
--- a/src/vendor/modules.txt
+++ b/src/vendor/modules.txt
@@ -8,7 +8,7 @@ golang.org/x/crypto/curve25519
golang.org/x/crypto/hkdf
golang.org/x/crypto/internal/subtle
golang.org/x/crypto/poly1305
-# golang.org/x/net v0.0.0-20211101194204-95aca89e93de
+# golang.org/x/net v0.0.0-20211201233630-85e122b1a9b3
## explicit; go 1.17
golang.org/x/net/dns/dnsmessage
golang.org/x/net/http/httpguts
diff --git a/test/fixedbugs/issue48289.go b/test/fixedbugs/issue48289.go
new file mode 100644
index 00000000000..94dbeee34cf
--- /dev/null
+++ b/test/fixedbugs/issue48289.go
@@ -0,0 +1,28 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "fmt"
+
+func main() {
+ ch := make(chan int, 1)
+
+ var ptrs [2]*int
+ for i := range ptrs {
+ ch <- i
+ select {
+ case x := <-ch:
+ ptrs[i] = &x
+ }
+ }
+
+ for i, ptr := range ptrs {
+ if *ptr != i {
+ panic(fmt.Sprintf("got *ptr %d, want %d", *ptr, i))
+ }
+ }
+}
diff --git a/test/fixedbugs/issue49122.go b/test/fixedbugs/issue49122.go
new file mode 100644
index 00000000000..c62a627dae0
--- /dev/null
+++ b/test/fixedbugs/issue49122.go
@@ -0,0 +1,16 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+var B []bool
+var N int
+
+func f(p bool, m map[bool]bool) bool {
+ var q bool
+ _ = p || N&N < N || B[0] || B[0]
+ return p && q && m[q]
+}
diff --git a/test/fixedbugs/issue49249.go b/test/fixedbugs/issue49249.go
new file mode 100644
index 00000000000..f152a5a7012
--- /dev/null
+++ b/test/fixedbugs/issue49249.go
@@ -0,0 +1,55 @@
+// compile -l
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f() int {
+ var a, b struct {
+ s struct {
+ s struct {
+ byte
+ float32
+ }
+ }
+ }
+ _ = a
+
+ return func() int {
+ return func() int {
+ a = struct {
+ s struct {
+ s struct {
+ byte
+ float32
+ }
+ }
+ }{b.s}
+ return 0
+ }()
+ }()
+}
+
+func g() int {
+ var a, b struct {
+ s [1][1]struct {
+ byte
+ float32
+ }
+ }
+ _ = a
+
+ return func() int {
+ return func() int {
+ a = struct {
+ s [1][1]struct {
+ byte
+ float32
+ }
+ }{b.s}
+ return 0
+ }()
+ }()
+}
diff --git a/test/fixedbugs/issue49378.go b/test/fixedbugs/issue49378.go
new file mode 100644
index 00000000000..70f466c929f
--- /dev/null
+++ b/test/fixedbugs/issue49378.go
@@ -0,0 +1,25 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f(i int) {
+ var s1 struct {
+ s struct{ s struct{ i int } }
+ }
+ var s2, s3 struct {
+ a struct{ i int }
+ b int
+ }
+ func() {
+ i = 1 + 2*i + s3.a.i + func() int {
+ s2.a, s2.b = s3.a, s3.b
+ return 0
+ }() + func(*int) int {
+ return s1.s.s.i
+ }(new(int))
+ }()
+}