diff --git a/doc/go1.16.html b/doc/go1.16.html
index 92cadff713..6e371b9617 100644
--- a/doc/go1.16.html
+++ b/doc/go1.16.html
@@ -33,7 +33,7 @@ Do not send CLs removing the interior tags from such phrases.
Darwin
-
+
Go 1.16 adds support of 64-bit ARM architecture on macOS (also known as
Apple Silicon) with GOOS=darwin
, GOARCH=arm64
.
Like the darwin/amd64
port, the darwin/arm64
@@ -42,7 +42,7 @@ Do not send CLs removing the interior tags from such phrases.
detector.
-
+
The iOS port, which was previously darwin/arm64
, is now
moved to ios/arm64
. GOOS=ios
implies the
darwin
build tag, just as GOOS=android
@@ -80,6 +80,15 @@ Do not send CLs removing the interior tags from such phrases.
Go command
+
+ TODO
+
+
+
+
+
+
+
Modules
@@ -207,7 +216,7 @@ Do not send CLs removing the interior tags from such phrases.
Cgo
-
+
The cgo tool will no longer try to translate
C struct bitfields into Go struct fields, even if their size can be
represented in Go. The order in which C bitfields appear in memory
@@ -215,8 +224,12 @@ Do not send CLs removing the interior tags from such phrases.
results that were silently incorrect.
+Vet
+
TODO
+
+
Runtime
@@ -245,7 +258,7 @@ Do not send CLs removing the interior tags from such phrases.
Linker
-
+
This release includes additional improvements to the Go linker,
reducing linker resource usage (both time and memory) and improving
code robustness/maintainability. These changes form the second half
@@ -268,7 +281,7 @@ Do not send CLs removing the interior tags from such phrases.
TODO: update with final numbers later in the release.
-
+
On Windows, go build -buildmode=c-shared
now generates Windows
ASLR DLLs by default. ASLR can be disabled with --ldflags=-aslr=false
.
@@ -276,135 +289,13 @@ Do not send CLs removing the interior tags from such phrases.
Core library
- TODO
+ TODO: mention significant additions like new packages (io/fs
),
+ new proposal-scoped features (//go:embed
), and so on
-
-
-
- New will now panic if separate calls to
- the hash generation function fail to return new values. Previously, the
- behavior was undefined and invalid outputs were sometimes generated.
-
-
-
-
-
- I/O operations on closing or closed TLS connections can now be detected using
- the new ErrClosed error. A typical use
- would be errors.Is(err, net.ErrClosed)
. In earlier releases
- the only way to reliably detect this case was to match the string returned
- by the Error
method with "tls: use of closed connection"
.
-
-
-
- A default deadline is set in Close
- before sending the close notify alert, in order to prevent blocking
- indefinitely.
-
-
-
- (*Conn).HandshakeContext was added to
- allow the user to control cancellation of an in-progress TLS Handshake.
- The context provided is propagated into the
- ClientHelloInfo
- and CertificateRequestInfo
- structs and accessible through the new
- (*ClientHelloInfo).Context
- and
-
- (*CertificateRequestInfo).Context
- methods respectively. Canceling the context after the handshake has finished
- has no effect.
-
-
-
- Clients now ensure that the server selects
-
- an ALPN protocol from
-
- the list advertised by the client.
-
-
-
- TLS servers will now prefer other AEAD cipher suites (such as ChaCha20Poly1305)
- over AES-GCM cipher suites if either the client or server doesn't have AES hardware
- support, unless the application set both
- Config.PreferServerCipherSuites
- and Config.CipherSuites
- or there are no other AEAD cipher suites supported.
- The client is assumed not to have AES hardware support if it does not signal a
- preference for AES-GCM cipher suites.
-
-
-
-
-
- ParseCertificate and
- CreateCertificate both
- now enforce string encoding restrictions for the fields DNSNames
,
- EmailAddresses
, and URIs
. These fields can only
- contain strings with characters within the ASCII range.
-
-
-
- CreateCertificate now
- verifies the generated certificate's signature using the signer's
- public key. If the signature is invalid, an error is returned, instead
- of a malformed certificate.
-
-
-
- A number of additional fields have been added to the
- CertificateRequest type.
- These fields are now parsed in ParseCertificateRequest
- and marshalled in CreateCertificateRequest.
-
-
-
-
-
- The error message for
- SyntaxError
- now begins with "json: ", matching the other errors in the package.
-
-
-
-
-
- The case of I/O on a closed network connection, or I/O on a network
- connection that is closed before any of the I/O completes, can now
- be detected using the new ErrClosed error.
- A typical use would be errors.Is(err, net.ErrClosed)
.
- In earlier releases the only way to reliably detect this case was to
- match the string returned by the Error
method
- with "use of closed network connection"
.
-
-
-
- In previous Go releases the default TCP listener backlog size on Linux systems,
- set by /proc/sys/net/core/somaxconn
, was limited to a maximum of 65535
.
- On Linux kernel version 4.1 and above, the maximum is now 4294967295
.
-
-
-
-
-
- A new CommentNode
- was added to the parse tree. The Mode
- field in the parse.Tree
enables access to it.
-
-
-
-
-
-
- The unicode
package and associated
- support throughout the system has been upgraded from Unicode 12.0.0 to
- Unicode 13.0.0,
- which adds 5,930 new characters, including four new scripts, and 55 new emoji.
- Unicode 13.0.0 also designates plane 3 (U+30000-U+3FFFF) as the tertiary
- ideographic plane.
+
+ TODO: when the "Minor changes to the library" section is close to completion,
+ decide if any changes are worth factoring out and highlighting in "Core library"
Minor changes to the library
@@ -416,7 +307,7 @@ Do not send CLs removing the interior tags from such phrases.
- TODO
+ TODO: complete this section, resolve TODOs below, add missing entries
- crypto/dsa
@@ -428,16 +319,126 @@ Do not send CLs removing the interior tags from such phrases.
+- crypto/hmac
+ -
+
+ New will now panic if separate calls to
+ the hash generation function fail to return new values. Previously, the
+ behavior was undefined and invalid outputs were sometimes generated.
+
+
+
+
+- crypto/tls
+ -
+
+ I/O operations on closing or closed TLS connections can now be detected using
+ the new ErrClosed error. A typical use
+ would be errors.Is(err, net.ErrClosed)
. In earlier releases
+ the only way to reliably detect this case was to match the string returned
+ by the Error
method with "tls: use of closed connection"
.
+
+
+
+ A default deadline is set in Close
+ before sending the close notify alert, in order to prevent blocking
+ indefinitely.
+
+
+
+ (*Conn).HandshakeContext was added to
+ allow the user to control cancellation of an in-progress TLS Handshake.
+ The context provided is propagated into the
+ ClientHelloInfo
+ and CertificateRequestInfo
+ structs and accessible through the new
+ (*ClientHelloInfo).Context
+ and
+
+ (*CertificateRequestInfo).Context
+ methods respectively. Canceling the context after the handshake has finished
+ has no effect.
+
+
+
+ Clients now ensure that the server selects
+
+ an ALPN protocol from
+
+ the list advertised by the client.
+
+
+
+ TLS servers will now prefer other AEAD cipher suites (such as ChaCha20Poly1305)
+ over AES-GCM cipher suites if either the client or server doesn't have AES hardware
+ support, unless the application set both
+ Config.PreferServerCipherSuites
+ and Config.CipherSuites
+ or there are no other AEAD cipher suites supported.
+ The client is assumed not to have AES hardware support if it does not signal a
+ preference for AES-GCM cipher suites.
+
+
+
+ TODO: https://golang.org/cl/246637: make config.Clone return nil if the source is nil
+
+
+
+
- crypto/x509
-
+
+ ParseCertificate and
+ CreateCertificate both
+ now enforce string encoding restrictions for the fields DNSNames
,
+ EmailAddresses
, and URIs
. These fields can only
+ contain strings with characters within the ASCII range.
+
+
+
+ CreateCertificate now
+ verifies the generated certificate's signature using the signer's
+ public key. If the signature is invalid, an error is returned, instead
+ of a malformed certificate.
+
+
+
+ A number of additional fields have been added to the
+ CertificateRequest type.
+ These fields are now parsed in ParseCertificateRequest
+ and marshalled in CreateCertificateRequest.
+
+
DSA signature verification is no longer supported. Note that DSA signature
generation was never supported.
See issue #40337.
+
+
+ TODO: https://golang.org/cl/257257: return additional chains from Verify on Windows
+
+
+
+ TODO: https://golang.org/cl/262343: add Unwrap to SystemRootsError
+
+- encoding/json
+ -
+
+ The error message for
+ SyntaxError
+ now begins with "json: ", matching the other errors in the package.
+
+
+
+ TODO: https://golang.org/cl/234818: allow semicolon in field key / struct tag
+
+
+
+
- encoding/xml
-
@@ -452,6 +453,70 @@ Do not send CLs removing the interior tags from such phrases.
+- flag
+ -
+
+ TODO: https://golang.org/cl/240014: add Func
+
+
+
+
+- io
+ -
+
+ TODO: https://golang.org/cl/261577: add a new ReadSeekCloser interface
+
+
+
+
+- log
+ -
+
+ TODO: https://golang.org/cl/264460: expose std via new Default function
+
+
+
+
+- log/syslog
+ -
+
+ TODO: https://golang.org/cl/264297: set local to true if network is any of "unix", or "unixgram"
+
+
+
+
+- mime/multipart
+ -
+
+ TODO: https://golang.org/cl/247477: return overflow errors in Reader.ReadForm
+
+
+
+
+- net
+ -
+
+ The case of I/O on a closed network connection, or I/O on a network
+ connection that is closed before any of the I/O completes, can now
+ be detected using the new ErrClosed error.
+ A typical use would be errors.Is(err, net.ErrClosed)
.
+ In earlier releases the only way to reliably detect this case was to
+ match the string returned by the Error
method
+ with "use of closed network connection"
.
+
+
+
+ In previous Go releases the default TCP listener backlog size on Linux systems,
+ set by /proc/sys/net/core/somaxconn
, was limited to a maximum of 65535
.
+ On Linux kernel version 4.1 and above, the maximum is now 4294967295
.
+
+
+
+ TODO: https://golang.org/cl/238629: prefer /etc/hosts over DNS when no /etc/nsswitch.conf is present
+
+
+
+
- net/http
-
@@ -469,14 +534,14 @@ Do not send CLs removing the interior tags from such phrases.
- The net/http
package now rejects HTTP range requests
- of the form "Range": "bytes=--N"
where "-N"
is a negative suffix length, for
- example "Range": "bytes=--2"
. It now replies with a 416 "Range Not Satisfiable"
response.
+ The net/http
package now rejects HTTP range requests
+ of the form "Range": "bytes=--N"
where "-N"
is a negative suffix length, for
+ example "Range": "bytes=--2"
. It now replies with a 416 "Range Not Satisfiable"
response.
- Cookies set with SameSiteDefaultMode
now behave according to the current
- spec (no attribute is set) instead of generating a SameSite key without a value.
+ Cookies set with SameSiteDefaultMode
now behave according to the current
+ spec (no attribute is set) instead of generating a SameSite key without a value.
@@ -485,9 +550,89 @@ Do not send CLs removing the interior tags from such phrases.
with the Request
context
when performing TLS handshakes in the client or server.
+
+
+ TODO: https://golang.org/cl/250039: set Content-Length:0 for empty PATCH requests as with POST, PATCH
+
+
+
+ TODO: https://golang.org/cl/249440: match http scheme when selecting http_proxy
+
+- net/http/httputil
+ -
+
+ TODO: https://golang.org/cl/260637: flush ReverseProxy immediately if Content-Length is -1
+
+
+
+
+- net/smtp
+ -
+
+ TODO: https://golang.org/cl/247257: adds support for the SMTPUTF8 extension
+
+
+
+
+- os
+ -
+
+ TODO: https://golang.org/cl/242998: export errFinished as ErrProcessDone
+
+
+
+
+- os/signal
+ -
+
+ TODO: https://golang.org/cl/219640: add NotifyContext to cancel context using system signals
+
+
+
+
+- path
+ -
+
+ TODO: https://golang.org/cl/264397: validate patterns in Match, Glob
+
+
+
+
+- path/filepath
+ -
+
+ TODO: https://golang.org/cl/264397: validate patterns in Match, Glob
+
+
+
+
+- reflect
+ -
+
+ TODO: https://golang.org/cl/248341: support multiple keys in struct tags
+
+
+
+
+- runtime
+ -
+
+ TODO: https://golang.org/cl/37222: make stack traces of endless recursion print only top and bottom 50
+
+
+
+ TODO: https://golang.org/cl/242258: add 24 byte allocation size class
+
+
+
+ TODO: https://golang.org/cl/254659: implement GODEBUG=inittrace=1 support
+
+
+
+
- runtime/debug
-
@@ -496,18 +641,6 @@ Do not send CLs removing the interior tags from such phrases.
-- syscall
- -
-
- SysProcAttr
on Windows has a new NoInheritHandles field that disables inheriting handles when creating a new process.
-
-
-
- DLLError
on Windows now has an Unwrap function for unwrapping its underlying error.
-
-
-
-
- strconv
-
@@ -520,3 +653,60 @@ Do not send CLs removing the interior tags from such phrases.
+
+- syscall
+ -
+
+ SysProcAttr
on Windows has a new NoInheritHandles field that disables inheriting handles when creating a new process.
+
+
+
+ DLLError
on Windows now has an Unwrap function for unwrapping its underlying error.
+
+
+
+ TODO: https://golang.org/cl/210639: support POSIX semantics for Linux syscalls
+
+
+
+
+- text/template
+ -
+
+ TODO: https://golang.org/cl/254257: allow newlines inside action delimiters
+
+
+
+
+- text/template/parse
+ -
+
+ A new CommentNode
+ was added to the parse tree. The Mode
+ field in the parse.Tree
enables access to it.
+
+
+
+
+- time/tzdata
+ -
+
+ The slim timezone data format is now used for the timezone database in
+ $GOROOT/lib/time/zoneinfo.zip
and the embedded copy in this
+ package. This reduces the size of the timezone database by about 350 KB.
+
+
+
+
+- unicode
+ -
+
+ The unicode
package and associated
+ support throughout the system has been upgraded from Unicode 12.0.0 to
+ Unicode 13.0.0,
+ which adds 5,930 new characters, including four new scripts, and 55 new emoji.
+ Unicode 13.0.0 also designates plane 3 (U+30000-U+3FFFF) as the tertiary
+ ideographic plane.
+
+
+
diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go
index 180afab33b..f266e49327 100644
--- a/src/cmd/compile/internal/ssa/expand_calls.go
+++ b/src/cmd/compile/internal/ssa/expand_calls.go
@@ -250,6 +250,9 @@ func expandCalls(f *Func) {
if leafType != selector.Type && !selector.Type.IsEmptyInterface() { // empty interface for #42727
f.Fatalf("Unexpected Load as selector, leaf=%s, selector=%s\n", leaf.LongString(), selector.LongString())
}
+ if selector.Type.IsEmptyInterface() {
+ selector.Type = typ.BytePtr
+ }
leaf.copyOf(selector)
for _, s := range namedSelects[selector] {
locs = append(locs, f.Names[s.locIndex])
diff --git a/src/cmd/internal/objabi/reloctype.go b/src/cmd/internal/objabi/reloctype.go
index 938954e07a..649f690194 100644
--- a/src/cmd/internal/objabi/reloctype.go
+++ b/src/cmd/internal/objabi/reloctype.go
@@ -156,6 +156,9 @@ const (
// R_ARM64_LDST8 sets a LD/ST immediate value to bits [11:0] of a local address.
R_ARM64_LDST8
+ // R_ARM64_LDST16 sets a LD/ST immediate value to bits [11:1] of a local address.
+ R_ARM64_LDST16
+
// R_ARM64_LDST32 sets a LD/ST immediate value to bits [11:2] of a local address.
R_ARM64_LDST32
diff --git a/src/cmd/internal/objabi/reloctype_string.go b/src/cmd/internal/objabi/reloctype_string.go
index 693d9631f5..658a44f8b8 100644
--- a/src/cmd/internal/objabi/reloctype_string.go
+++ b/src/cmd/internal/objabi/reloctype_string.go
@@ -46,32 +46,33 @@ func _() {
_ = x[R_ARM64_GOT-36]
_ = x[R_ARM64_PCREL-37]
_ = x[R_ARM64_LDST8-38]
- _ = x[R_ARM64_LDST32-39]
- _ = x[R_ARM64_LDST64-40]
- _ = x[R_ARM64_LDST128-41]
- _ = x[R_POWER_TLS_LE-42]
- _ = x[R_POWER_TLS_IE-43]
- _ = x[R_POWER_TLS-44]
- _ = x[R_ADDRPOWER_DS-45]
- _ = x[R_ADDRPOWER_GOT-46]
- _ = x[R_ADDRPOWER_PCREL-47]
- _ = x[R_ADDRPOWER_TOCREL-48]
- _ = x[R_ADDRPOWER_TOCREL_DS-49]
- _ = x[R_RISCV_PCREL_ITYPE-50]
- _ = x[R_RISCV_PCREL_STYPE-51]
- _ = x[R_RISCV_TLS_IE_ITYPE-52]
- _ = x[R_RISCV_TLS_IE_STYPE-53]
- _ = x[R_PCRELDBL-54]
- _ = x[R_ADDRMIPSU-55]
- _ = x[R_ADDRMIPSTLS-56]
- _ = x[R_ADDRCUOFF-57]
- _ = x[R_WASMIMPORT-58]
- _ = x[R_XCOFFREF-59]
+ _ = x[R_ARM64_LDST16-39]
+ _ = x[R_ARM64_LDST32-40]
+ _ = x[R_ARM64_LDST64-41]
+ _ = x[R_ARM64_LDST128-42]
+ _ = x[R_POWER_TLS_LE-43]
+ _ = x[R_POWER_TLS_IE-44]
+ _ = x[R_POWER_TLS-45]
+ _ = x[R_ADDRPOWER_DS-46]
+ _ = x[R_ADDRPOWER_GOT-47]
+ _ = x[R_ADDRPOWER_PCREL-48]
+ _ = x[R_ADDRPOWER_TOCREL-49]
+ _ = x[R_ADDRPOWER_TOCREL_DS-50]
+ _ = x[R_RISCV_PCREL_ITYPE-51]
+ _ = x[R_RISCV_PCREL_STYPE-52]
+ _ = x[R_RISCV_TLS_IE_ITYPE-53]
+ _ = x[R_RISCV_TLS_IE_STYPE-54]
+ _ = x[R_PCRELDBL-55]
+ _ = x[R_ADDRMIPSU-56]
+ _ = x[R_ADDRMIPSTLS-57]
+ _ = x[R_ADDRCUOFF-58]
+ _ = x[R_WASMIMPORT-59]
+ _ = x[R_XCOFFREF-60]
}
-const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_WEAKADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CALLRISCVR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF"
+const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_WEAKADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CALLRISCVR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF"
-var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 60, 66, 72, 81, 92, 101, 112, 122, 133, 140, 147, 155, 163, 171, 177, 183, 189, 199, 208, 218, 234, 245, 256, 266, 275, 288, 302, 316, 330, 346, 357, 370, 383, 397, 411, 426, 440, 454, 465, 479, 494, 511, 529, 550, 569, 588, 608, 628, 638, 649, 662, 673, 685, 695}
+var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 60, 66, 72, 81, 92, 101, 112, 122, 133, 140, 147, 155, 163, 171, 177, 183, 189, 199, 208, 218, 234, 245, 256, 266, 275, 288, 302, 316, 330, 346, 357, 370, 383, 397, 411, 425, 440, 454, 468, 479, 493, 508, 525, 543, 564, 583, 602, 622, 642, 652, 663, 676, 687, 699, 709}
func (i RelocType) String() string {
i -= 1
diff --git a/src/cmd/internal/objabi/util.go b/src/cmd/internal/objabi/util.go
index 9479ab2cd9..a73ab479a1 100644
--- a/src/cmd/internal/objabi/util.go
+++ b/src/cmd/internal/objabi/util.go
@@ -40,7 +40,12 @@ const (
)
func goarm() int {
- switch v := envOr("GOARM", defaultGOARM); v {
+ def := defaultGOARM
+ if GOOS == "android" && GOARCH == "arm" {
+ // Android arm devices always support GOARM=7.
+ def = "7"
+ }
+ switch v := envOr("GOARM", def); v {
case "5":
return 5
case "6":
diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go
index cb16180657..a7af855646 100644
--- a/src/cmd/link/internal/arm64/asm.go
+++ b/src/cmd/link/internal/arm64/asm.go
@@ -177,6 +177,14 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade
su.SetRelocType(rIdx, objabi.R_ARM64_LDST8)
return true
+ case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_LDST16_ABS_LO12_NC):
+ if targType == sym.SDYNIMPORT {
+ ldr.Errorf(s, "unexpected relocation for dynamic symbol %s", ldr.SymName(targ))
+ }
+ su := ldr.MakeSymbolUpdater(s)
+ su.SetRelocType(rIdx, objabi.R_ARM64_LDST16)
+ return true
+
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_LDST32_ABS_LO12_NC):
if targType == sym.SDYNIMPORT {
ldr.Errorf(s, "unexpected relocation for dynamic symbol %s", ldr.SymName(targ))
@@ -769,6 +777,14 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade
o0 := uint32(t&0xfff) << 10
return val | int64(o0), noExtReloc, true
+ case objabi.R_ARM64_LDST16:
+ t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xfff)
+ if t&1 != 0 {
+ ldr.Errorf(s, "invalid address: %x for relocation type: R_AARCH64_LDST16_ABS_LO12_NC", t)
+ }
+ o0 := (uint32(t&0xfff) >> 1) << 10
+ return val | int64(o0), noExtReloc, true
+
case objabi.R_ARM64_LDST32:
t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xfff)
if t&3 != 0 {
diff --git a/src/cmd/link/internal/loadelf/ldelf.go b/src/cmd/link/internal/loadelf/ldelf.go
index 5260c6bdcb..db543a5e50 100644
--- a/src/cmd/link/internal/loadelf/ldelf.go
+++ b/src/cmd/link/internal/loadelf/ldelf.go
@@ -1019,6 +1019,7 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) {
ARM64 | uint32(elf.R_AARCH64_ADR_PREL_PG_HI21)<<16,
ARM64 | uint32(elf.R_AARCH64_ADD_ABS_LO12_NC)<<16,
ARM64 | uint32(elf.R_AARCH64_LDST8_ABS_LO12_NC)<<16,
+ ARM64 | uint32(elf.R_AARCH64_LDST16_ABS_LO12_NC)<<16,
ARM64 | uint32(elf.R_AARCH64_LDST32_ABS_LO12_NC)<<16,
ARM64 | uint32(elf.R_AARCH64_LDST64_ABS_LO12_NC)<<16,
ARM64 | uint32(elf.R_AARCH64_LDST128_ABS_LO12_NC)<<16,
diff --git a/src/go/constant/value.go b/src/go/constant/value.go
index 4a89ef3b94..223c363d9b 100644
--- a/src/go/constant/value.go
+++ b/src/go/constant/value.go
@@ -371,16 +371,13 @@ func MakeUint64(x uint64) Value {
}
// MakeFloat64 returns the Float value for x.
+// If x is -0.0, the result is 0.0.
// If x is not finite, the result is an Unknown.
func MakeFloat64(x float64) Value {
if math.IsInf(x, 0) || math.IsNaN(x) {
return unknownVal{}
}
- // convert -0 to 0
- if x == 0 {
- return int64Val(0)
- }
- return ratVal{newRat().SetFloat64(x)}
+ return ratVal{newRat().SetFloat64(x + 0)} // convert -0 to 0
}
// MakeFromLiteral returns the corresponding integer, floating-point,
@@ -595,11 +592,11 @@ func Make(x interface{}) Value {
case int64:
return int64Val(x)
case *big.Int:
- return intVal{x}
+ return makeInt(x)
case *big.Rat:
- return ratVal{x}
+ return makeRat(x)
case *big.Float:
- return floatVal{x}
+ return makeFloat(x)
default:
return unknownVal{}
}
diff --git a/src/go/constant/value_test.go b/src/go/constant/value_test.go
index 1ad6784f9a..91ad0b0c2b 100644
--- a/src/go/constant/value_test.go
+++ b/src/go/constant/value_test.go
@@ -7,6 +7,7 @@ package constant
import (
"fmt"
"go/token"
+ "math"
"math/big"
"strings"
"testing"
@@ -620,18 +621,68 @@ func TestUnknown(t *testing.T) {
}
}
-func TestMake(t *testing.T) {
- for _, want := range []interface{}{
- false,
- "hello",
- int64(1),
- big.NewInt(10),
- big.NewFloat(2.0),
- big.NewRat(1, 3),
+func TestMakeFloat64(t *testing.T) {
+ var zero float64
+ for _, arg := range []float64{
+ -math.MaxFloat32,
+ -10,
+ -0.5,
+ -zero,
+ zero,
+ 1,
+ 10,
+ 123456789.87654321e-23,
+ 1e10,
+ math.MaxFloat64,
} {
- got := Val(Make(want))
- if got != want {
- t.Errorf("got %v; want %v", got, want)
+ val := MakeFloat64(arg)
+ if val.Kind() != Float {
+ t.Errorf("%v: got kind = %d; want %d", arg, val.Kind(), Float)
+ }
+
+ // -0.0 is mapped to 0.0
+ got, exact := Float64Val(val)
+ if !exact || math.Float64bits(got) != math.Float64bits(arg+0) {
+ t.Errorf("%v: got %v (exact = %v)", arg, got, exact)
+ }
+ }
+
+ // infinity
+ for sign := range []int{-1, 1} {
+ arg := math.Inf(sign)
+ val := MakeFloat64(arg)
+ if val.Kind() != Unknown {
+ t.Errorf("%v: got kind = %d; want %d", arg, val.Kind(), Unknown)
+ }
+ }
+}
+
+type makeTestCase struct {
+ kind Kind
+ arg, want interface{}
+}
+
+func dup(k Kind, x interface{}) makeTestCase { return makeTestCase{k, x, x} }
+
+func TestMake(t *testing.T) {
+ for _, test := range []makeTestCase{
+ {Bool, false, false},
+ {String, "hello", "hello"},
+
+ {Int, int64(1), int64(1)},
+ {Int, big.NewInt(10), int64(10)},
+ {Int, new(big.Int).Lsh(big.NewInt(1), 62), int64(1 << 62)},
+ dup(Int, new(big.Int).Lsh(big.NewInt(1), 63)),
+
+ {Float, big.NewFloat(0), floatVal0.val},
+ dup(Float, big.NewFloat(2.0)),
+ dup(Float, big.NewRat(1, 3)),
+ } {
+ val := Make(test.arg)
+ got := Val(val)
+ if val.Kind() != test.kind || got != test.want {
+ t.Errorf("got %v (%T, kind = %d); want %v (%T, kind = %d)",
+ got, got, val.Kind(), test.want, test.want, test.kind)
}
}
}
diff --git a/src/regexp/syntax/doc.go b/src/regexp/syntax/doc.go
index efc0b43571..b3f9136b5f 100644
--- a/src/regexp/syntax/doc.go
+++ b/src/regexp/syntax/doc.go
@@ -66,7 +66,7 @@ Grouping:
Empty strings:
^ at beginning of text or line (flag m=true)
- $ at end of text (like \z not Perl's \Z) or line (flag m=true)
+ $ at end of text (like \z not \Z) or line (flag m=true)
\A at beginning of text
\b at ASCII word boundary (\w on one side and \W, \A, or \z on the other)
\B not at ASCII word boundary
@@ -127,5 +127,6 @@ ASCII character classes:
[[:word:]] word characters (== [0-9A-Za-z_])
[[:xdigit:]] hex digit (== [0-9A-Fa-f])
+Unicode character classes are those in unicode.Categories and unicode.Scripts.
*/
package syntax
diff --git a/src/runtime/chan.go b/src/runtime/chan.go
index 254816e369..ba56e2cc40 100644
--- a/src/runtime/chan.go
+++ b/src/runtime/chan.go
@@ -215,7 +215,7 @@ func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool {
// Space is available in the channel buffer. Enqueue the element to send.
qp := chanbuf(c, c.sendx)
if raceenabled {
- racereleaseacquire(qp)
+ racenotify(c, c.sendx, nil)
}
typedmemmove(c.elemtype, qp, ep)
c.sendx++
@@ -297,9 +297,8 @@ func send(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func(), skip int) {
// Pretend we go through the buffer, even though
// we copy directly. Note that we need to increment
// the head/tail locations only when raceenabled.
- qp := chanbuf(c, c.recvx)
- racereleaseacquire(qp)
- racereleaseacquireg(sg.g, qp)
+ racenotify(c, c.recvx, nil)
+ racenotify(c, c.recvx, sg)
c.recvx++
if c.recvx == c.dataqsiz {
c.recvx = 0
@@ -532,7 +531,7 @@ func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool)
// Receive directly from queue
qp := chanbuf(c, c.recvx)
if raceenabled {
- racereleaseacquire(qp)
+ racenotify(c, c.recvx, nil)
}
if ep != nil {
typedmemmove(c.elemtype, ep, qp)
@@ -621,8 +620,8 @@ func recv(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func(), skip int) {
// queue is full, those are both the same slot.
qp := chanbuf(c, c.recvx)
if raceenabled {
- racereleaseacquire(qp)
- racereleaseacquireg(sg.g, qp)
+ racenotify(c, c.recvx, nil)
+ racenotify(c, c.recvx, sg)
}
// copy data from queue to receiver
if ep != nil {
@@ -833,3 +832,38 @@ func racesync(c *hchan, sg *sudog) {
racereleaseg(sg.g, chanbuf(c, 0))
raceacquire(chanbuf(c, 0))
}
+
+// Notify the race detector of a send or receive involving buffer entry idx
+// and a channel c or its communicating partner sg.
+// This function handles the special case of c.elemsize==0.
+func racenotify(c *hchan, idx uint, sg *sudog) {
+ // We could have passed the unsafe.Pointer corresponding to entry idx
+ // instead of idx itself. However, in a future version of this function,
+ // we can use idx to better handle the case of elemsize==0.
+ // A future improvement to the detector is to call TSan with c and idx:
+ // this way, Go will continue to not allocating buffer entries for channels
+ // of elemsize==0, yet the race detector can be made to handle multiple
+ // sync objects underneath the hood (one sync object per idx)
+ qp := chanbuf(c, idx)
+ // When elemsize==0, we don't allocate a full buffer for the channel.
+ // Instead of individual buffer entries, the race detector uses the
+ // c.buf as the only buffer entry. This simplification prevents us from
+ // following the memory model's happens-before rules (rules that are
+ // implemented in racereleaseacquire). Instead, we accumulate happens-before
+ // information in the synchronization object associated with c.buf.
+ if c.elemsize == 0 {
+ if sg == nil {
+ raceacquire(qp)
+ racerelease(qp)
+ } else {
+ raceacquireg(sg.g, qp)
+ racereleaseg(sg.g, qp)
+ }
+ } else {
+ if sg == nil {
+ racereleaseacquire(qp)
+ } else {
+ racereleaseacquireg(sg.g, qp)
+ }
+ }
+}
diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
index 0680d07a32..140c170ddc 100644
--- a/src/runtime/crash_cgo_test.go
+++ b/src/runtime/crash_cgo_test.go
@@ -254,6 +254,24 @@ func TestCgoCrashTraceback(t *testing.T) {
}
}
+func TestCgoCrashTracebackGo(t *testing.T) {
+ t.Parallel()
+ switch platform := runtime.GOOS + "/" + runtime.GOARCH; platform {
+ case "darwin/amd64":
+ case "linux/amd64":
+ case "linux/ppc64le":
+ default:
+ t.Skipf("not yet supported on %s", platform)
+ }
+ got := runTestProg(t, "testprogcgo", "CrashTracebackGo")
+ for i := 1; i <= 3; i++ {
+ want := fmt.Sprintf("main.h%d", i)
+ if !strings.Contains(got, want) {
+ t.Errorf("missing %s", want)
+ }
+ }
+}
+
func TestCgoTracebackContext(t *testing.T) {
t.Parallel()
got := runTestProg(t, "testprogcgo", "TracebackContext")
diff --git a/src/runtime/race/testdata/chan_test.go b/src/runtime/race/testdata/chan_test.go
index 3e57b8221c..e39ad4f99c 100644
--- a/src/runtime/race/testdata/chan_test.go
+++ b/src/runtime/race/testdata/chan_test.go
@@ -763,3 +763,25 @@ func TestNoRaceCloseHappensBeforeRead(t *testing.T) {
<-read
}
}
+
+// Test that we call the proper race detector function when c.elemsize==0.
+// See https://github.com/golang/go/issues/42598
+func TestNoRaceElemetSize0(t *testing.T) {
+ var x, y int
+ var c = make(chan struct{}, 2)
+ c <- struct{}{}
+ c <- struct{}{}
+ go func() {
+ x += 1
+ <-c
+ }()
+ go func() {
+ y += 1
+ <-c
+ }()
+ time.Sleep(10 * time.Millisecond)
+ c <- struct{}{}
+ c <- struct{}{}
+ x += 1
+ y += 1
+}
diff --git a/src/runtime/select.go b/src/runtime/select.go
index f04b130b15..e72761bfa9 100644
--- a/src/runtime/select.go
+++ b/src/runtime/select.go
@@ -415,7 +415,7 @@ bufrecv:
if cas.elem != nil {
raceWriteObjectPC(c.elemtype, cas.elem, casePC(casi), chanrecvpc)
}
- racereleaseacquire(chanbuf(c, c.recvx))
+ racenotify(c, c.recvx, nil)
}
if msanenabled && cas.elem != nil {
msanwrite(cas.elem, c.elemtype.size)
@@ -437,7 +437,7 @@ bufrecv:
bufsend:
// can send to buffer
if raceenabled {
- racereleaseacquire(chanbuf(c, c.sendx))
+ racenotify(c, c.sendx, nil)
raceReadObjectPC(c.elemtype, cas.elem, casePC(casi), chansendpc)
}
if msanenabled {
diff --git a/src/runtime/stack_test.go b/src/runtime/stack_test.go
index adfc65384a..43fc5cac55 100644
--- a/src/runtime/stack_test.go
+++ b/src/runtime/stack_test.go
@@ -17,6 +17,7 @@ import (
"sync/atomic"
"testing"
"time"
+ _ "unsafe" // for go:linkname
)
// TestStackMem measures per-thread stack segment cache behavior.
@@ -851,3 +852,43 @@ func deferHeapAndStack(n int) (r int) {
// Pass a value to escapeMe to force it to escape.
var escapeMe = func(x interface{}) {}
+
+// Test that when F -> G is inlined and F is excluded from stack
+// traces, G still appears.
+func TestTracebackInlineExcluded(t *testing.T) {
+ defer func() {
+ recover()
+ buf := make([]byte, 4<<10)
+ stk := string(buf[:Stack(buf, false)])
+
+ t.Log(stk)
+
+ if not := "tracebackExcluded"; strings.Contains(stk, not) {
+ t.Errorf("found but did not expect %q", not)
+ }
+ if want := "tracebackNotExcluded"; !strings.Contains(stk, want) {
+ t.Errorf("expected %q in stack", want)
+ }
+ }()
+ tracebackExcluded()
+}
+
+// tracebackExcluded should be excluded from tracebacks. There are
+// various ways this could come up. Linking it to a "runtime." name is
+// rather synthetic, but it's easy and reliable. See issue #42754 for
+// one way this happened in real code.
+//
+//go:linkname tracebackExcluded runtime.tracebackExcluded
+//go:noinline
+func tracebackExcluded() {
+ // Call an inlined function that should not itself be excluded
+ // from tracebacks.
+ tracebackNotExcluded()
+}
+
+// tracebackNotExcluded should be inlined into tracebackExcluded, but
+// should not itself be excluded from the traceback.
+func tracebackNotExcluded() {
+ var x *int
+ *x = 0
+}
diff --git a/src/runtime/sys_windows_386.s b/src/runtime/sys_windows_386.s
index 2e5e82879c..ef8a3dd3c2 100644
--- a/src/runtime/sys_windows_386.s
+++ b/src/runtime/sys_windows_386.s
@@ -415,12 +415,15 @@ TEXT runtime·usleep2(SB),NOSPLIT,$20
// Runs on OS stack. duration (in 100ns units) is in BX.
TEXT runtime·usleep2HighRes(SB),NOSPLIT,$36
+ get_tls(CX)
+ CMPL CX, $0
+ JE gisnotset
+
// Want negative 100ns units.
NEGL BX
MOVL $-1, hi-4(SP)
MOVL BX, lo-8(SP)
- get_tls(CX)
MOVL g(CX), CX
MOVL g_m(CX), CX
MOVL (m_mOS+mOS_highResTimer)(CX), CX
@@ -449,6 +452,12 @@ TEXT runtime·usleep2HighRes(SB),NOSPLIT,$36
RET
+gisnotset:
+ // TLS is not configured. Call usleep2 instead.
+ MOVL $runtime·usleep2(SB), AX
+ CALL AX
+ RET
+
// Runs on OS stack.
TEXT runtime·switchtothread(SB),NOSPLIT,$0
MOVL SP, BP
diff --git a/src/runtime/sys_windows_amd64.s b/src/runtime/sys_windows_amd64.s
index e9ec99a51d..d1690cad58 100644
--- a/src/runtime/sys_windows_amd64.s
+++ b/src/runtime/sys_windows_amd64.s
@@ -454,11 +454,14 @@ TEXT runtime·usleep2(SB),NOSPLIT|NOFRAME,$48
// Runs on OS stack. duration (in 100ns units) is in BX.
TEXT runtime·usleep2HighRes(SB),NOSPLIT|NOFRAME,$72
+ get_tls(CX)
+ CMPQ CX, $0
+ JE gisnotset
+
MOVQ SP, AX
ANDQ $~15, SP // alignment as per Windows requirement
MOVQ AX, 64(SP)
- get_tls(CX)
MOVQ g(CX), CX
MOVQ g_m(CX), CX
MOVQ (m_mOS+mOS_highResTimer)(CX), CX // hTimer
@@ -484,6 +487,12 @@ TEXT runtime·usleep2HighRes(SB),NOSPLIT|NOFRAME,$72
MOVQ 64(SP), SP
RET
+gisnotset:
+ // TLS is not configured. Call usleep2 instead.
+ MOVQ $runtime·usleep2(SB), AX
+ CALL AX
+ RET
+
// Runs on OS stack.
TEXT runtime·switchtothread(SB),NOSPLIT|NOFRAME,$0
MOVQ SP, AX
diff --git a/src/runtime/testdata/testprogcgo/traceback.go b/src/runtime/testdata/testprogcgo/traceback.go
index 2a023f66ca..e2d7599131 100644
--- a/src/runtime/testdata/testprogcgo/traceback.go
+++ b/src/runtime/testdata/testprogcgo/traceback.go
@@ -11,58 +11,11 @@ package main
/*
#cgo CFLAGS: -g -O0
-#include
-
-char *p;
-
-static int f3(void) {
- *p = 0;
- return 0;
-}
-
-static int f2(void) {
- return f3();
-}
-
-static int f1(void) {
- return f2();
-}
-
-struct cgoTracebackArg {
- uintptr_t context;
- uintptr_t sigContext;
- uintptr_t* buf;
- uintptr_t max;
-};
-
-struct cgoSymbolizerArg {
- uintptr_t pc;
- const char* file;
- uintptr_t lineno;
- const char* func;
- uintptr_t entry;
- uintptr_t more;
- uintptr_t data;
-};
-
-void cgoTraceback(void* parg) {
- struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg);
- arg->buf[0] = 1;
- arg->buf[1] = 2;
- arg->buf[2] = 3;
- arg->buf[3] = 0;
-}
-
-void cgoSymbolizer(void* parg) {
- struct cgoSymbolizerArg* arg = (struct cgoSymbolizerArg*)(parg);
- if (arg->pc != arg->data + 1) {
- arg->file = "unexpected data";
- } else {
- arg->file = "cgo symbolizer";
- }
- arg->lineno = arg->data + 1;
- arg->data++;
-}
+// Defined in traceback_c.c.
+extern int crashInGo;
+int tracebackF1(void);
+void cgoTraceback(void* parg);
+void cgoSymbolizer(void* parg);
*/
import "C"
@@ -73,9 +26,29 @@ import (
func init() {
register("CrashTraceback", CrashTraceback)
+ register("CrashTracebackGo", CrashTracebackGo)
}
func CrashTraceback() {
runtime.SetCgoTraceback(0, unsafe.Pointer(C.cgoTraceback), nil, unsafe.Pointer(C.cgoSymbolizer))
- C.f1()
+ C.tracebackF1()
+}
+
+func CrashTracebackGo() {
+ C.crashInGo = 1
+ CrashTraceback()
+}
+
+//export h1
+func h1() {
+ h2()
+}
+
+func h2() {
+ h3()
+}
+
+func h3() {
+ var x *int
+ *x = 0
}
diff --git a/src/runtime/testdata/testprogcgo/traceback_c.c b/src/runtime/testdata/testprogcgo/traceback_c.c
new file mode 100644
index 0000000000..56eda8fa8c
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/traceback_c.c
@@ -0,0 +1,65 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The C definitions for traceback.go. That file uses //export so
+// it can't put function definitions in the "C" import comment.
+
+#include
+
+char *p;
+
+int crashInGo;
+extern void h1(void);
+
+int tracebackF3(void) {
+ if (crashInGo)
+ h1();
+ else
+ *p = 0;
+ return 0;
+}
+
+int tracebackF2(void) {
+ return tracebackF3();
+}
+
+int tracebackF1(void) {
+ return tracebackF2();
+}
+
+struct cgoTracebackArg {
+ uintptr_t context;
+ uintptr_t sigContext;
+ uintptr_t* buf;
+ uintptr_t max;
+};
+
+struct cgoSymbolizerArg {
+ uintptr_t pc;
+ const char* file;
+ uintptr_t lineno;
+ const char* func;
+ uintptr_t entry;
+ uintptr_t more;
+ uintptr_t data;
+};
+
+void cgoTraceback(void* parg) {
+ struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg);
+ arg->buf[0] = 1;
+ arg->buf[1] = 2;
+ arg->buf[2] = 3;
+ arg->buf[3] = 0;
+}
+
+void cgoSymbolizer(void* parg) {
+ struct cgoSymbolizerArg* arg = (struct cgoSymbolizerArg*)(parg);
+ if (arg->pc != arg->data + 1) {
+ arg->file = "unexpected data";
+ } else {
+ arg->file = "cgo symbolizer";
+ }
+ arg->lineno = arg->data + 1;
+ arg->data++;
+}
diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go
index f3df152535..0825e9e707 100644
--- a/src/runtime/traceback.go
+++ b/src/runtime/traceback.go
@@ -396,13 +396,21 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
// If there is inlining info, print the inner frames.
if inldata := funcdata(f, _FUNCDATA_InlTree); inldata != nil {
inltree := (*[1 << 20]inlinedCall)(inldata)
+ var inlFunc _func
+ inlFuncInfo := funcInfo{&inlFunc, f.datap}
for {
ix := pcdatavalue(f, _PCDATA_InlTreeIndex, tracepc, nil)
if ix < 0 {
break
}
- if (flags&_TraceRuntimeFrames) != 0 || showframe(f, gp, nprint == 0, inltree[ix].funcID, lastFuncID) {
- name := funcnameFromNameoff(f, inltree[ix].func_)
+
+ // Create a fake _func for the
+ // inlined function.
+ inlFunc.nameoff = inltree[ix].func_
+ inlFunc.funcID = inltree[ix].funcID
+
+ if (flags&_TraceRuntimeFrames) != 0 || showframe(inlFuncInfo, gp, nprint == 0, inlFuncInfo.funcID, lastFuncID) {
+ name := funcname(inlFuncInfo)
file, line := funcline(f, tracepc)
print(name, "(...)\n")
print("\t", file, ":", line, "\n")
@@ -811,6 +819,9 @@ func showframe(f funcInfo, gp *g, firstFrame bool, funcID, childID funcID) bool
// showfuncinfo reports whether a function with the given characteristics should
// be printed during a traceback.
func showfuncinfo(f funcInfo, firstFrame bool, funcID, childID funcID) bool {
+ // Note that f may be a synthesized funcInfo for an inlined
+ // function, in which case only nameoff and funcID are set.
+
level, _, _ := gotraceback()
if level > 1 {
// Show all frames.
diff --git a/test/fixedbugs/issue42784.go b/test/fixedbugs/issue42784.go
new file mode 100644
index 0000000000..e2b06e9307
--- /dev/null
+++ b/test/fixedbugs/issue42784.go
@@ -0,0 +1,26 @@
+// compile
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Ensure that late expansion correctly set OpLoad argument type interface{}
+
+package p
+
+type iface interface {
+ m()
+}
+
+type it interface{}
+
+type makeIface func() iface
+
+func f() {
+ var im makeIface
+ e := im().(it)
+ g(e)
+}
+
+//go:noinline
+func g(i it) {}