[dev.boringcrypto] all: merge master into dev.boringcrypto

Change-Id: Ia8ddd4e52dcfe87f9daef2edd37c8155fcae7f5a
This commit is contained in:
Filippo Valsorda 2018-09-06 13:25:27 -04:00
commit 4d1aa482b8
1291 changed files with 63258 additions and 17546 deletions

221
AUTHORS

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -362,17 +362,21 @@ pkg syscall (openbsd-386-cgo), const SYS_KILL = 37
pkg syscall (openbsd-amd64), const SYS_KILL = 37
pkg syscall (openbsd-amd64-cgo), const SYS_KILL = 37
pkg unicode, const Version = "9.0.0"
pkg syscall (windows-386), const TOKEN_ALL_ACCESS = 983295
pkg syscall (windows-386), type AddrinfoW struct, Addr uintptr
pkg syscall (windows-386), type CertChainPolicyPara struct, ExtraPolicyPara uintptr
pkg syscall (windows-386), type CertChainPolicyStatus struct, ExtraPolicyStatus uintptr
pkg syscall (windows-386), type CertContext struct, CertInfo uintptr
pkg syscall (windows-386), type CertRevocationInfo struct, CrlInfo uintptr
pkg syscall (windows-386), type CertRevocationInfo struct, OidSpecificInfo uintptr
pkg syscall (windows-386), type CertSimpleChain struct, TrustListInfo uintptr
pkg syscall (windows-386), const TOKEN_ALL_ACCESS = 983295
pkg syscall (windows-386), type RawSockaddrAny struct, Pad [96]int8
pkg syscall (windows-amd64), const TOKEN_ALL_ACCESS = 983295
pkg syscall (windows-amd64), type AddrinfoW struct, Addr uintptr
pkg syscall (windows-amd64), type CertChainPolicyPara struct, ExtraPolicyPara uintptr
pkg syscall (windows-amd64), type CertChainPolicyStatus struct, ExtraPolicyStatus uintptr
pkg syscall (windows-amd64), type CertContext struct, CertInfo uintptr
pkg syscall (windows-amd64), type CertRevocationInfo struct, CrlInfo uintptr
pkg syscall (windows-amd64), type CertRevocationInfo struct, OidSpecificInfo uintptr
pkg syscall (windows-amd64), type CertSimpleChain struct, TrustListInfo uintptr
pkg syscall (windows-amd64), const TOKEN_ALL_ACCESS = 983295
pkg syscall (windows-amd64), type RawSockaddrAny struct, Pad [96]int8

View file

@ -1,7 +1,7 @@
pkg crypto/cipher, func NewGCMWithTagSize(Block, int) (AEAD, error)
pkg crypto/rsa, method (*PrivateKey) Size() int
pkg crypto/rsa, method (*PublicKey) Size() int
pkg crypto/tls, type ConnectionState struct, ExportKeyingMaterial func(string, []uint8, int) ([]uint8, bool)
pkg crypto/tls, method (*ConnectionState) ExportKeyingMaterial(string, []uint8, int) ([]uint8, error)
pkg database/sql, method (IsolationLevel) String() string
pkg database/sql, type DBStats struct, Idle int
pkg database/sql, type DBStats struct, InUse int
@ -445,9 +445,20 @@ pkg net, method (*ListenConfig) ListenPacket(context.Context, string, string) (P
pkg net, type Dialer struct, Control func(string, string, syscall.RawConn) error
pkg net, type ListenConfig struct
pkg net, type ListenConfig struct, Control func(string, string, syscall.RawConn) error
pkg net/http, const SameSiteDefaultMode = 1
pkg net/http, const SameSiteDefaultMode SameSite
pkg net/http, const SameSiteLaxMode = 2
pkg net/http, const SameSiteLaxMode SameSite
pkg net/http, const SameSiteStrictMode = 3
pkg net/http, const SameSiteStrictMode SameSite
pkg net/http, const StatusMisdirectedRequest = 421
pkg net/http, const StatusMisdirectedRequest ideal-int
pkg net/http, type Cookie struct, SameSite SameSite
pkg net/http, type SameSite int
pkg net/http, type Transport struct, MaxConnsPerHost int
pkg net/http/httptrace, type ClientTrace struct, Got1xxResponse func(int, textproto.MIMEHeader) error
pkg net/http/httptrace, type ClientTrace struct, WroteHeaderField func(string, []string)
pkg net/http/httputil, type ReverseProxy struct, ErrorHandler func(http.ResponseWriter, *http.Request, error)
pkg os, const ModeIrregular = 524288
pkg os, const ModeIrregular FileMode
pkg os, const ModeType = 2399666176
@ -519,6 +530,7 @@ pkg syscall (openbsd-amd64-cgo), func Pipe2([]int, int) error
pkg syscall (windows-386), const TOKEN_ADJUST_SESSIONID = 256
pkg syscall (windows-386), const TOKEN_ADJUST_SESSIONID ideal-int
pkg syscall (windows-386), const TOKEN_ALL_ACCESS = 983551
pkg syscall (windows-386), type AddrinfoW struct, Addr Pointer
pkg syscall (windows-386), type CertChainPolicyPara struct, ExtraPolicyPara Pointer
pkg syscall (windows-386), type CertChainPolicyStatus struct, ExtraPolicyStatus Pointer
pkg syscall (windows-386), type CertContext struct, CertInfo *CertInfo
@ -532,6 +544,7 @@ pkg syscall (windows-386), type Pointer *struct
pkg syscall (windows-amd64), const TOKEN_ADJUST_SESSIONID = 256
pkg syscall (windows-amd64), const TOKEN_ADJUST_SESSIONID ideal-int
pkg syscall (windows-amd64), const TOKEN_ALL_ACCESS = 983551
pkg syscall (windows-amd64), type AddrinfoW struct, Addr Pointer
pkg syscall (windows-amd64), type CertChainPolicyPara struct, ExtraPolicyPara Pointer
pkg syscall (windows-amd64), type CertChainPolicyStatus struct, ExtraPolicyStatus Pointer
pkg syscall (windows-amd64), type CertContext struct, CertInfo *CertInfo

View file

@ -44,18 +44,16 @@ control repositories.
<h3 id="Workspaces">Workspaces</h3>
<p>
A workspace is a directory hierarchy with three directories at its root:
A workspace is a directory hierarchy with two directories at its root:
</p>
<ul>
<li><code>src</code> contains Go source files,
<li><code>pkg</code> contains package objects, and
<li><code>src</code> contains Go source files, and
<li><code>bin</code> contains executable commands.
</ul>
<p>
The <code>go</code> tool builds source packages and installs the resulting
binaries to the <code>pkg</code> and <code>bin</code> directories.
The <code>go</code> tool builds and installs binaries to the <code>bin</code> directory.
</p>
<p>
@ -72,10 +70,6 @@ To give you an idea of how a workspace looks in practice, here's an example:
bin/
hello # command executable
outyet # command executable
pkg/
linux_amd64/
github.com/golang/example/
stringutil.a # package object
src/
<a href="https://github.com/golang/example/">github.com/golang/example/</a>
.git/ # Git repository metadata
@ -374,9 +368,8 @@ $ <b>go build</b>
</pre>
<p>
This won't produce an output file. To do that, you must use <code>go
install</code>, which places the package object inside the <code>pkg</code>
directory of the workspace.
This won't produce an output file.
Instead it saves the compiled package in the local build cache.
</p>
<p>
@ -400,19 +393,13 @@ func main() {
</pre>
<p>
Whenever the <code>go</code> tool installs a package or binary, it also
installs whatever dependencies it has.
So when you install the <code>hello</code> program
Install the <code>hello</code> program:
</p>
<pre>
$ <b>go install github.com/user/hello</b>
</pre>
<p>
the <code>stringutil</code> package will be installed as well, automatically.
</p>
<p>
Running the new version of the program, you should see a new, reversed message:
</p>
@ -429,10 +416,6 @@ After the steps above, your workspace should look like this:
<pre>
bin/
hello # command executable
pkg/
linux_amd64/ # this will reflect your OS and architecture
github.com/user/
stringutil.a # package object
src/
github.com/user/
hello/
@ -441,22 +424,6 @@ src/
reverse.go # package source
</pre>
<p>
Note that <code>go install</code> placed the <code>stringutil.a</code> object
in a directory inside <code>pkg/linux_amd64</code> that mirrors its source
directory.
This is so that future invocations of the <code>go</code> tool can find the
package object and avoid recompiling the package unnecessarily.
The <code>linux_amd64</code> part is there to aid in cross-compilation,
and will reflect the operating system and architecture of your system.
</p>
<p>
Go command executables are statically linked; the package objects need not
be present to run Go programs.
</p>
<h3 id="PackageNames">Package names</h3>
<p>
@ -597,12 +564,6 @@ tree should now look like this:
<pre>
bin/
hello # command executable
pkg/
linux_amd64/
github.com/golang/example/
stringutil.a # package object
github.com/user/
stringutil.a # package object
src/
github.com/golang/example/
.git/ # Git repository metadata

View file

@ -73,7 +73,7 @@ $ go-contrib-init
<p>
The rest of this chapter elaborates on these instructions.
If you have completed the steps above (either manually or through the tool), jump to
<a href="#making_a_change">Making a change</a>.
<a href="#before_contributing">Before contributing code</a>.
</p>
<h3 id="google_account">Step 0: Select a Google Account</h3>
@ -292,6 +292,25 @@ Most issues will be marked with one of the following workflow labels:
</li>
</ul>
<p>
You can use GitHub's search functionality to find issues to help out with. Examples:
</p>
<ul>
<li>
Issues that need investigation: <a href="https://github.com/golang/go/issues?q=is%3Aissue+is%3Aopen+label%3ANeedsInvestigation"><code>is:issue is:open label:NeedsInvestigation</code></a>
</li>
<li>
Issues that need a fix: <a href="https://github.com/golang/go/issues?q=is%3Aissue+is%3Aopen+label%3ANeedsFix"><code>is:issue is:open label:NeedsFix</code></a>
</li>
<li>
Issues that need a fix and have a CL: <a href="https://github.com/golang/go/issues?q=is%3Aissue+is%3Aopen+label%3ANeedsFix+%22golang.org%2Fcl%22"><code>is:issue is:open label:NeedsFix "golang.org/cl"</code></a>
</li>
<li>
Issues that need a fix and do not have a CL: <a href="https://github.com/golang/go/issues?q=is%3Aissue+is%3Aopen+label%3ANeedsFix+NOT+%22golang.org%2Fcl%22"><code>is:issue is:open label:NeedsFix NOT "golang.org/cl"</code></a>
</li>
</ul>
<h3 id="design">Open an issue for any new problem</h3>
<p>
@ -386,7 +405,7 @@ This is an overview of the overall process:
<ul>
<li>
<b>Step 1:</b> Clone the Go source code from go.googlesource.com
<b>Step 1:</b> Clone the Go source code from <code>go.googlesource.com</code>
and make sure it's stable by compiling and testing it once:
<pre>
$ git clone https://go.googlesource.com/go
@ -450,12 +469,11 @@ In addition to a recent Go installation, you need to have a local copy of the so
checked out from the correct repository.
You can check out the Go source repo onto your local file system anywhere
you want as long as it's outside your <code>GOPATH</code>.
Either clone from
<code>go.googlesource.com</code> or from GitHub:
Clone from <code>go.googlesource.com</code> (not GitHub):
</p>
<pre>
$ git clone https://github.com/golang/go # or https://go.googlesource.com/go
$ git clone https://go.googlesource.com/go
$ cd go
</pre>
@ -678,7 +696,7 @@ Don't use HTML, Markdown, or any other markup language.
<p>
Add any relevant information, such as benchmark data if the change
affects performance.
The <a href="https://godoc.org/golang.org/x/tools/cmd/benchcmp">benchcmp</a>
The <a href="https://godoc.org/golang.org/x/perf/cmd/benchstat">benchstat</a>
tool is conventionally used to format
benchmark data for change descriptions.
</p>

View file

@ -23,6 +23,13 @@ in supported releases as needed by issuing minor revisions
(for example, Go 1.6.1, Go 1.6.2, and so on).
</p>
<h2 id="go1.11">go1.11 (released 2018/08/24)</h2>
<p>
Go 1.11 is a major release of Go.
Read the <a href="/doc/go1.11">Go 1.11 Release Notes</a> for more information.
</p>
<h2 id="go1.10">go1.10 (released 2018/02/16)</h2>
<p>
@ -57,6 +64,14 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.10.3">Go
1.10.3 milestone</a> on our issue tracker for details.
</p>
<p>
go1.10.4 (released 2018/08/24) includes fixes to the go command, linker, and the
<code>net/http</code>, <code>mime/multipart</code>, <code>ld/macho</code>,
<code>bytes</code>, and <code>strings</code> packages.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.10.4">Go
1.10.4 milestone</a> on our issue tracker for details.
</p>
<h2 id="go1.9">go1.9 (released 2017/08/24)</h2>
<p>

View file

@ -15,14 +15,7 @@ Do not send CLs removing the interior tags from such phrases.
ul li { margin: 0.5em 0; }
</style>
<h2 id="introduction">DRAFT RELEASE NOTES - Introduction to Go 1.11</h2>
<p>
<strong>
Go 1.11 is not yet released. These are work-in-progress
release notes. Go 1.11 is expected to be released in August 2018.
</strong>
</p>
<h2 id="introduction">Introduction to Go 1.11</h2>
<p>
The latest Go release, version 1.11, arrives six months after <a href="go1.10">Go 1.10</a>.
@ -39,10 +32,15 @@ Do not send CLs removing the interior tags from such phrases.
<h2 id="ports">Ports</h2>
<p>
<p> <!-- CL 94255, CL 115038, etc -->
As <a href="go1.10#ports">announced in the Go 1.10 release notes</a>, Go 1.11 now requires
OpenBSD 6.2 or later, macOS 10.10 Yosemite or later, or Windows 7 or later;
Support for previous versions of these operating systems has been removed.
support for previous versions of these operating systems has been removed.
</p>
<p> <!-- CL 121657 -->
Go 1.11 supports the upcoming OpenBSD 6.4 release. Due to changes in
the OpenBSD kernel, older versions of Go will not work on OpenBSD 6.4.
</p>
<p>
@ -50,21 +48,400 @@ Do not send CLs removing the interior tags from such phrases.
</p>
<p><!-- CL 107935 -->
TODO: PPC64LE race detector support
The race detector is now supported on <code>linux/ppc64le</code>
and, to a lesser extent, on <code>netbsd/amd64</code>. The NetBSD race detector support
has <a href="https://golang.org/issue/26403">known issues</a>.
</p>
<h3 id="package-versioning">Package Versioning (vgo)</h3>
<p>
<strong>
NOTE: This is not present in go1.11beta1 but will be available in future
betas and subsequent releases.
</strong>
Go 1.11 adds experimental, integrated support for package versioning.
<p><!-- CL 109255 -->
The memory sanitizer (<code>-msan</code>) is now supported on <code>linux/arm64</code>.
</p>
<p><!-- CL 93875 -->
The build modes <code>c-shared</code> and <code>c-archive</code> are now supported on
<code>freebsd/amd64</code>.
</p>
<p id="mips"><!-- CL 108475 -->
On 64-bit MIPS systems, the new environment variable settings
<code>GOMIPS64=hardfloat</code> (the default) and
<code>GOMIPS64=softfloat</code> select whether to use
hardware instructions or software emulation for floating-point computations.
For 32-bit systems, the environment variable is still <code>GOMIPS</code>,
as <a href="go1.10#mips">added in Go 1.10</a>.
</p>
<p><!-- CL 107475 -->
On soft-float ARM systems (<code>GOARM=5</code>), Go now uses a more
efficient software floating point interface. This is transparent to
Go code, but ARM assembly that uses floating-point instructions not
guarded on GOARM will break and must be ported to
the <a href="https://golang.org/cl/107475">new interface</a>.
</p>
<p><!-- CL 94076 -->
Go 1.11 on ARMv7 no longer requires a Linux kernel configured
with <code>KUSER_HELPERS</code>. This setting is enabled in default
kernel configurations, but is sometimes disabled in stripped-down
configurations.
</p>
<h3 id="wasm">WebAssembly</h3>
<p>
Go 1.11 adds an experimental port to WebAssembly (<code>js/wasm</code>).
Go 1.11 adds an experimental port to <a href="https://webassembly.org">WebAssembly</a>
(<code>js/wasm</code>).
</p>
<p>
Go programs currently compile to one WebAssembly module that
includes the Go runtime for goroutine scheduling, garbage
collection, maps, etc.
As a result, the resulting size is at minimum around
2 MB, or 500 KB compressed. Go programs can call into JavaScript
using the new experimental
<a href="/pkg/syscall/js/"><code>syscall/js</code></a> package.
Binary size and interop with other languages has not yet been a
priority but may be addressed in future releases.
</p>
<p>
As a result of the addition of the new <code>GOOS</code> value
"<code>js</code>" and <code>GOARCH</code> value "<code>wasm</code>",
Go files named <code>*_js.go</code> or <code>*_wasm.go</code> will
now be <a href="/pkg/go/build/#hdr-Build_Constraints">ignored by Go
tools</a> except when those GOOS/GOARCH values are being used.
If you have existing filenames matching those patterns, you will need to rename them.
</p>
<p>
More information can be found on the
<a href="https://golang.org/wiki/WebAssembly">WebAssembly wiki page</a>.
</p>
<h3 id="riscv">RISC-V GOARCH values reserved</h3>
<p><!-- CL 106256 -->
The main Go compiler does not yet support the RISC-V architecture <!-- is gonna change everything -->
but we've reserved the <code>GOARCH</code> values
"<code>riscv</code>" and "<code>riscv64</code>", as used by Gccgo,
which does support RISC-V. This means that Go files
named <code>*_riscv.go</code> will now also
be <a href="/pkg/go/build/#hdr-Build_Constraints">ignored by Go
tools</a> except when those GOOS/GOARCH values are being used.
</p>
<h2 id="tools">Tools</h2>
<h3 id="modules">Modules, package versioning, and dependency management</h3>
<p>
Go 1.11 adds preliminary support for a <a href="/cmd/go/#hdr-Modules__module_versions__and_more">new concept called “modules,”</a>
an alternative to GOPATH with integrated support for versioning and
package distribution.
Using modules, developers are no longer confined to working inside GOPATH,
version dependency information is explicit yet lightweight,
and builds are more reliable and reproducible.
</p>
<p>
Module support is considered experimental.
Details are likely to change in response to feedback from Go 1.11 users,
and we have more tools planned.
Although the details of module support may change, projects that convert
to modules using Go 1.11 will continue to work with Go 1.12 and later.
If you encounter bugs using modules,
please <a href="https://golang.org/issue/new">file issues</a>
so we can fix them. For more information, see the
<a href="/cmd/go#hdr-Modules__module_versions__and_more"><code>go</code> command documentation</a>.
</p>
<h3 id="importpath">Import path restriction</h3>
<p>
Because Go module support assigns special meaning to the
<code>@</code> symbol in command line operations,
the <code>go</code> command now disallows the use of
import paths containing <code>@</code> symbols.
Such import paths were never allowed by <code>go</code> <code>get</code>,
so this restriction can only affect users building
custom GOPATH trees by other means.
</p>
<h3 id="gopackages">Package loading</h3>
<p>
The new package
<a href="https://godoc.org/golang.org/x/tools/go/packages"><code>golang.org/x/tools/go/packages</code></a>
provides a simple API for locating and loading packages of Go source code.
Although not yet part of the standard library, for many tasks it
effectively replaces the <a href="/pkg/go/build"><code>go/build</code></a>
package, whose API is unable to fully support modules.
Because it runs an external query command such as
<a href="/cmd/go/#hdr-List_packages"><code>go list</code></a>
to obtain information about Go packages, it enables the construction of
analysis tools that work equally well with alternative build systems
such as <a href="https://bazel.build">Bazel</a>
and <a href="https://buckbuild.com">Buck</a>.
</p>
<h3 id="gocache">Build cache requirement</h3>
<p>
Go 1.11 will be the last release to support setting the environment
variable <code>GOCACHE=off</code> to disable the
<a href="/cmd/go/#hdr-Build_and_test_caching">build cache</a>,
introduced in Go 1.10.
Starting in Go 1.12, the build cache will be required,
as a step toward eliminating <code>$GOPATH/pkg</code>.
The module and package loading support described above
already require that the build cache be enabled.
If you have disabled the build cache to avoid problems you encountered,
please <a href="https://golang.org/issue/new">file an issue</a> to let us know about them.
</p>
<h3 id="compiler">Compiler toolchain</h3>
<p><!-- CL 109918 -->
More functions are now eligible for inlining by default, including
functions that call <code>panic</code>.
</p>
<p><!-- CL 97375 -->
The compiler toolchain now supports column information
in <a href="/cmd/compile/#hdr-Compiler_Directives">line
directives</a>.
</p>
<p><!-- CL 106797 -->
A new package export data format has been introduced.
This should be transparent to end users, except for speeding up
build times for large Go projects.
If it does cause problems, it can be turned off again by
passing <code>-gcflags=all=-iexport=false</code> to
the <code>go</code> tool when building a binary.
</p>
<p><!-- CL 100459 -->
The compiler now rejects unused variables declared in a type switch
guard, such as <code>x</code> in the following example:
</p>
<pre>
func f(v interface{}) {
switch x := v.(type) {
}
}
</pre>
<p>
This was already rejected by both <code>gccgo</code>
and <a href="/pkg/go/types/">go/types</a>.
</p>
<h3 id="assembler">Assembler</h3>
<p><!-- CL 113315 -->
The assembler for <code>amd64</code> now accepts AVX512 instructions.
</p>
<h3 id="debugging">Debugging</h3>
<p><!-- CL 100738, CL 93664 -->
The compiler now produces significantly more accurate debug
information for optimized binaries, including variable location
information, line numbers, and breakpoint locations.
This should make it possible to debug binaries
compiled <em>without</em> <code>-N</code>&nbsp;<code>-l</code>.
There are still limitations to the quality of the debug information,
some of which are fundamental, and some of which will continue to
improve with future releases.
</p>
<p><!-- CL 118276 -->
DWARF sections are now compressed by default because of the expanded
and more accurate debug information produced by the compiler.
This is transparent to most ELF tools (such as debuggers on Linux
and *BSD) and is supported by the Delve debugger on all platforms,
but has limited support in the native tools on macOS and Windows.
To disable DWARF compression,
pass <code>-ldflags=-compressdwarf=false</code> to
the <code>go</code> tool when building a binary.
</p>
<p><!-- CL 109699 -->
Go 1.11 adds experimental support for calling Go functions from
within a debugger.
This is useful, for example, to call <code>String</code> methods
when paused at a breakpoint.
This is currently only supported by Delve (version 1.1.0 and up).
</p>
<h3 id="test">Test</h3>
<p>
Since Go 1.10, the <code>go</code>&nbsp;<code>test</code> command runs
<code>go</code>&nbsp;<code>vet</code> on the package being tested,
to identify problems before running the test. Since <code>vet</code>
typechecks the code with <a href="/pkg/go/types/">go/types</a>
before running, tests that do not typecheck will now fail.
In particular, tests that contain an unused variable inside a
closure compiled with Go 1.10, because the Go compiler incorrectly
accepted them (<a href="https://golang.org/issues/3059">Issue #3059</a>),
but will now fail, since <code>go/types</code> correctly reports an
"unused variable" error in this case.
</p>
<p><!-- CL 102696 -->
The <code>-memprofile</code> flag
to <code>go</code>&nbsp;<code>test</code> now defaults to the
"allocs" profile, which records the total bytes allocated since the
test began (including garbage-collected bytes).
</p>
<h3 id="vet">Vet</h3>
<p><!-- CL 108555 -->
The <a href="/cmd/vet/"><code>go</code>&nbsp;<code>vet</code></a>
command now reports a fatal error when the package under analysis
does not typecheck. Previously, a type checking error simply caused
a warning to be printed, and <code>vet</code> to exit with status 1.
</p>
<p><!-- CL 108559 -->
Additionally, <a href="/cmd/vet"><code>go</code>&nbsp;<code>vet</code></a>
has become more robust when format-checking <code>printf</code> wrappers.
Vet now detects the mistake in this example:
</p>
<pre>
func wrapper(s string, args ...interface{}) {
fmt.Printf(s, args...)
}
func main() {
wrapper("%s", 42)
}
</pre>
<h3 id="trace">Trace</h3>
<p><!-- CL 63274 -->
With the new <code>runtime/trace</code>
package's <a href="/pkg/runtime/trace/#hdr-User_annotation">user
annotation API</a>, users can record application-level information
in execution traces and create groups of related goroutines.
The <code>go</code>&nbsp;<code>tool</code>&nbsp;<code>trace</code>
command visualizes this information in the trace view and the new
user task/region analysis page.
</p>
<h3 id="cgo">Cgo</h3>
<p>
Since Go 1.10, cgo has translated some C pointer types to the Go
type <code>uintptr</code>. These types include
the <code>CFTypeRef</code> hierarchy in Darwin's CoreFoundation
framework and the <code>jobject</code> hierarchy in Java's JNI
interface. In Go 1.11, several improvements have been made to the code
that detects these types. Code that uses these types may need some
updating. See the <a href="go1.10.html#cgo">Go 1.10 release notes</a> for
details. <!-- CL 126275, CL 127156, CL 122217, CL 122575, CL 123177 -->
</p>
<h3 id="godoc">Godoc</h3>
<p>
Go 1.11 will be the last release to support <code>godoc</code>'s command-line interface.
In future releases, <code>godoc</code> will only be a web server. Users should use
<code>go</code> <code>doc</code> for command-line help output instead.
</p>
<p><!-- CL 85396, CL 124495 -->
The <code>godoc</code> web server now shows which version of Go introduced
new API features. The initial Go version of types, funcs, and methods are shown
right-aligned. For example, see <a href="/pkg/os/#UserCacheDir"><code>UserCacheDir</code></a>, with "1.11"
on the right side. For struct fields, inline comments are added when the struct field was
added in a Go version other than when the type itself was introduced.
For a struct field example, see
<a href="/pkg/net/http/httptrace/#ClientTrace.Got1xxResponse"><code>ClientTrace.Got1xxResponse</code></a>.
</p>
<h3 id="gofmt">Gofmt</h3>
<p>
One minor detail of the default formatting of Go source code has changed.
When formatting expression lists with inline comments, the comments were
aligned according to a heuristic.
However, in some cases the alignment would be split up too easily, or
introduce too much whitespace.
The heuristic has been changed to behave better for human-written code.
</p>
<p>
Note that these kinds of minor updates to gofmt are expected from time to
time.
In general, systems that need consistent formatting of Go source code should
use a specific version of the <code>gofmt</code> binary.
See the <a href="/pkg/go/format/">go/format</a> package documentation for more
information.
</p>
<h2 id="runtime">Runtime</h2>
<p><!-- CL 85887 -->
The runtime now uses a sparse heap layout so there is no longer a
limit to the size of the Go heap (previously, the limit was 512GiB).
This also fixes rare "address space conflict" failures in mixed Go/C
binaries or binaries compiled with <code>-race</code>.
</p>
<p><!-- CL 108679, CL 106156 -->
On macOS and iOS, the runtime now uses <code>libSystem.dylib</code> instead of
calling the kernel directly. This should make Go binaries more
compatible with future versions of macOS and iOS.
The <a href="/pkg/syscall">syscall</a> package still makes direct
system calls; fixing this is planned for a future release.
</p>
<h2 id="performance">Performance</h2>
<p>
As always, the changes are so general and varied that precise
statements about performance are difficult to make. Most programs
should run a bit faster, due to better generated code and
optimizations in the core library.
</p>
<p><!-- CL 74851 -->
There were multiple performance changes to the <code>math/big</code>
package as well as many changes across the tree specific to <code>GOARCH=arm64</code>.
</p>
<h3 id="performance-compiler">Compiler toolchain</h3>
<p><!-- CL 110055 -->
The compiler now optimizes map clearing operations of the form:
</p>
<pre>
for k := range m {
delete(m, k)
}
</pre>
<p><!-- CL 109517 -->
The compiler now optimizes slice extension of the form
<code>append(s,</code>&nbsp;<code>make([]T,</code>&nbsp;<code>n)...)</code>.
</p>
<p><!-- CL 100277, CL 105635, CL 109776 -->
The compiler now performs significantly more aggressive bounds-check
and branch elimination. Notably, it now recognizes transitive
relations, so if <code>i&lt;j</code> and <code>j&lt;len(s)</code>,
it can use these facts to eliminate the bounds check
for <code>s[i]</code>. It also understands simple arithmetic such
as <code>s[i-10]</code> and can recognize more inductive cases in
loops. Furthermore, the compiler now uses bounds information to more
aggressively optimize shift operations.
</p>
<h2 id="library">Core library</h2>
@ -81,34 +458,19 @@ Do not send CLs removing the interior tags from such phrases.
in mind.
</p>
<!-- CL 113315: https://golang.org/cl/113315: cmd/asm: enable AVX512 -->
<!-- CL 100459: https://golang.org/cl/100459: cmd/compile: reject type switch with guarded declaration and no cases -->
<!-- CL 106797: https://golang.org/cl/106797: cmd/compile: enable indexed export format by default -->
<!-- CL 108475: https://golang.org/cl/108475: cmd/compile: add softfloat support to mips64{,le} -->
<!-- CL 97375: https://golang.org/cl/97375: cmd/compile, cmd/compile/internal/syntax: print relative column info -->
<!-- CL 115095: https://golang.org/cl/115095: yes (`go test pkg` now always builds pkg even if there are no test files): cmd/go: output coverage report even if there are no test files -->
<!-- CL 110395: https://golang.org/cl/110395: cmd/go, cmd/compile: use Windows response files to avoid arg length limits -->
<!-- CL 107475: https://golang.org/cl/107475: cmd/internal/obj/arm, runtime: delete old ARM softfloat code -->
<!-- CL 112436: https://golang.org/cl/112436: cmd/pprof: add readline support similar to upstream -->
<dl id="all"><dt><a href="/pkg/all/">all</a></dt>
<dd>
<p><!-- CL 93875 -->
TODO: <a href="https://golang.org/cl/93875">https://golang.org/cl/93875</a>: enable c-shared/c-archive support for freebsd/amd64
</p>
<p><!-- CL 94255 -->
TODO: <a href="https://golang.org/cl/94255">https://golang.org/cl/94255</a>: drop support for Windows Vista or below (Windows XP)
</p>
<p><!-- CL 115038 -->
TODO: <a href="https://golang.org/cl/115038">https://golang.org/cl/115038</a>: remove support for macOS 10.9 and earlier
</p>
</dl><!-- all -->
<dl id="crypto"><dt><a href="/pkg/crypto/">crypto</a></dt>
<dd>
<p><!-- CL 64451 -->
TODO: <a href="https://golang.org/cl/64451">https://golang.org/cl/64451</a>: randomly read an extra byte of randomness in some places.
Certain crypto operations, including
<a href="/pkg/crypto/ecdsa/#Sign"><code>ecdsa.Sign</code></a>,
<a href="/pkg/crypto/rsa/#EncryptPKCS1v15"><code>rsa.EncryptPKCS1v15</code></a> and
<a href="/pkg/crypto/rsa/#GenerateKey"><code>rsa.GenerateKey</code></a>,
now randomly read an extra byte of randomness to ensure tests don't rely on internal behavior.
</p>
</dl><!-- crypto -->
@ -116,7 +478,8 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="crypto/cipher"><dt><a href="/pkg/crypto/cipher/">crypto/cipher</a></dt>
<dd>
<p><!-- CL 48510, CL 116435 -->
TODO: <a href="https://golang.org/cl/48510">https://golang.org/cl/48510</a>: add NewGCMWithTagSize for custom tag sizes.
The new function <a href="/pkg/crypto/cipher/#NewGCMWithTagSize"><code>NewGCMWithTagSize</code></a>
implements Galois Counter Mode with non-standard tag lengths for compatibility with existing cryptosystems.
</p>
</dl><!-- crypto/cipher -->
@ -124,15 +487,55 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="crypto/rsa"><dt><a href="/pkg/crypto/rsa/">crypto/rsa</a></dt>
<dd>
<p><!-- CL 103876 -->
TODO: <a href="https://golang.org/cl/103876">https://golang.org/cl/103876</a>: add PublicKey.Size accessor
<a href="/pkg/crypto/rsa/#PublicKey"><code>PublicKey</code></a> now implements a
<a href="/pkg/crypto/rsa/#PublicKey.Size"><code>Size</code></a> method that
returns the modulus size in bytes.
</p>
</dl><!-- crypto/rsa -->
<dl id="crypto/tls"><dt><a href="/pkg/crypto/tls/">crypto/tls</a></dt>
<dd>
<p><!-- CL 85115 -->
<a href="/pkg/crypto/tls/#ConnectionState"><code>ConnectionState</code></a>'s new
<a href="/pkg/crypto/tls/#ConnectionState.ExportKeyingMaterial"><code>ExportKeyingMaterial</code></a>
method allows exporting keying material bound to the
connection according to RFC 5705.
</p>
</dl><!-- crypto/tls -->
<dl id="crypto/x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt>
<dd>
<p><!-- CL 123355, CL 123695 -->
The deprecated, legacy behavior of treating the <code>CommonName</code> field as
a hostname when no Subject Alternative Names are present is now disabled when the CN is not a
valid hostname.
The <code>CommonName</code> can be completely ignored by adding the experimental value
<code>x509ignoreCN=1</code> to the <code>GODEBUG</code> environment variable.
When the CN is ignored, certificates without SANs validate under chains with name constraints
instead of returning <code>NameConstraintsWithoutSANs</code>.
</p>
<p><!-- CL 113475 -->
Extended key usage restrictions are again checked only if they appear in the <code>KeyUsages</code>
field of <a href="/pkg/crypto/x509/#VerifyOptions"><code>VerifyOptions</code></a>, instead of always being checked.
This matches the behavior of Go 1.9 and earlier.
</p>
<p><!-- CL 102699 -->
The value returned by <a href="/pkg/crypto/x509/#SystemCertPool"><code>SystemCertPool</code></a>
is now cached and might not reflect system changes between invocations.
</p>
</dl><!-- crypto/x509 -->
<dl id="debug/elf"><dt><a href="/pkg/debug/elf/">debug/elf</a></dt>
<dd>
<p><!-- CL 112115 -->
TODO: <a href="https://golang.org/cl/112115">https://golang.org/cl/112115</a>: add machine and OSABI constants
More <a href="/pkg/debug/elf/#ELFOSABI_NONE"><code>ELFOSABI</code></a>
and <a href="/pkg/debug/elf/#EM_NONE"><code>EM</code></a>
constants have been added.
</p>
</dl><!-- debug/elf -->
@ -140,7 +543,8 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="encoding/asn1"><dt><a href="/pkg/encoding/asn1/">encoding/asn1</a></dt>
<dd>
<p><!-- CL 110561 -->
TODO: <a href="https://golang.org/cl/110561">https://golang.org/cl/110561</a>: allow Marshaling and Unmarshaling private tag class
<code>Marshal</code> and <code><a href="/pkg/encoding/asn1/#Unmarshal">Unmarshal</a></code>
now support "private" class annotations for fields.
</p>
</dl><!-- encoding/asn1 -->
@ -148,7 +552,10 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="encoding/base32"><dt><a href="/pkg/encoding/base32/">encoding/base32</a></dt>
<dd>
<p><!-- CL 112516 -->
TODO: <a href="https://golang.org/cl/112516">https://golang.org/cl/112516</a>: handle surplus padding consistently
The decoder now consistently
returns <code>io.ErrUnexpectedEOF</code> for an incomplete
chunk. Previously it would return <code>io.EOF</code> in some
cases.
</p>
</dl><!-- encoding/base32 -->
@ -156,23 +563,34 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="encoding/csv"><dt><a href="/pkg/encoding/csv/">encoding/csv</a></dt>
<dd>
<p><!-- CL 99696 -->
TODO: <a href="https://golang.org/cl/99696">https://golang.org/cl/99696</a>: disallow quote for use as Comma
The <code>Reader</code> now rejects attempts to set
the <a href="/pkg/encoding/csv/#Reader.Comma"><code>Comma</code></a>
field to a double-quote character, as double-quote characters
already have a special meaning in CSV.
</p>
</dl><!-- encoding/csv -->
<dl id="go/build, runtime/internal/sys"><dt><a href="/pkg/go/build, runtime/internal/sys/">go/build, runtime/internal/sys</a></dt>
<!-- CL 100235 was reverted -->
<dl id="html/template"><dt><a href="/pkg/html/template/">html/template</a></dt>
<dd>
<p><!-- CL 106256 -->
TODO: <a href="https://golang.org/cl/106256">https://golang.org/cl/106256</a>: reserve RISC-V arch names
<p><!-- CL 121815 -->
The package has changed its behavior when a typed interface
value is passed to an implicit escaper function. Previously such
a value was written out as (an escaped form)
of <code>&lt;nil&gt;</code>. Now such values are ignored, just
as an untyped <code>nil</code> value is (and always has been)
ignored.
</p>
</dl><!-- go/build, runtime/internal/sys -->
</dl><!-- html/template -->
<dl id="image/gif"><dt><a href="/pkg/image/gif/">image/gif</a></dt>
<dd>
<p><!-- CL 93076 -->
TODO: <a href="https://golang.org/cl/93076">https://golang.org/cl/93076</a>: support non-looping animated gifs (LoopCount=-1)
Non-looping animated GIFs are now supported. They are denoted by having a
<code><a href="/pkg/image/gif/#GIF.LoopCount">LoopCount</a></code> of -1.
</p>
</dl><!-- image/gif -->
@ -180,67 +598,182 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="io/ioutil"><dt><a href="/pkg/io/ioutil/">io/ioutil</a></dt>
<dd>
<p><!-- CL 105675 -->
TODO: <a href="https://golang.org/cl/105675">https://golang.org/cl/105675</a>: change TempFile prefix to a pattern
The <code><a href="/pkg/io/ioutil/#TempFile">TempFile</a></code>
function now supports specifying where the random characters in
the filename are placed. If the <code>prefix</code> argument
includes a "<code>*</code>", the random string replaces the
"<code>*</code>". For example, a <code>prefix</code> argument of "<code>myname.*.bat</code>" will
result in a random filename such as
"<code>myname.123456.bat</code>". If no "<code>*</code>" is
included the old behavior is retained, and the random digits are
appended to the end.
</p>
</dl><!-- io/ioutil -->
<dl id="math/big"><dt><a href="/pkg/math/big/">math/big</a></dt>
<dd>
<p><!-- CL 74851 -->
TODO: <a href="https://golang.org/cl/74851">https://golang.org/cl/74851</a>: speed-up addMulVVW on amd64
<p><!-- CL 108996 -->
<a href="/pkg/math/big/#Int.ModInverse"><code>ModInverse</code></a> now returns nil when g and n are not relatively prime. The result was previously undefined.
</p>
</dl><!-- math/big -->
<dl id="mime/multipart"><dt><a href="/pkg/mime/multipart/">mime/multipart</a></dt>
<dd>
<p><!-- CL 121055 -->
The handling of form-data with missing/empty file names has been
restored to the behavior in Go 1.9: in the
<a href="/pkg/mime/multipart/#Form"><code>Form</code></a> for
the form-data part the value is available in
the <code>Value</code> field rather than the <code>File</code>
field. In Go releases 1.10 through 1.10.3 a form-data part with
a missing/empty file name and a non-empty "Content-Type" field
was stored in the <code>File</code> field. This change was a
mistake in 1.10 and has been reverted to the 1.9 behavior.
</p>
</dl><!-- mime/multipart -->
<dl id="mime/quotedprintable"><dt><a href="/pkg/mime/quotedprintable/">mime/quotedprintable</a></dt>
<dd>
<p><!-- CL 121095 -->
To support invalid input found in the wild, the package now
permits non-ASCII bytes but does not validate their encoding.
</p>
</dl><!-- mime/quotedprintable -->
<dl id="net"><dt><a href="/pkg/net/">net</a></dt>
<dd>
<p><!-- CL 72810 -->
TODO: <a href="https://golang.org/cl/72810">https://golang.org/cl/72810</a>: add ListenConfig, Dialer.Control to permit socket opts before listen/dial
The new <a href="/pkg/net/#ListenConfig"><code>ListenConfig</code></a> type and the new
<a href="/pkg/net/#Dialer.Control"><code>Dialer.Control</code></a> field permit
setting socket options before accepting and creating connections, respectively.
</p>
<p><!-- CL 76391 -->
TODO: <a href="https://golang.org/cl/76391">https://golang.org/cl/76391</a>: implement (*syscall.RawConn).Read/Write on Windows
The <a href="/pkg/syscall/#RawConn"><code>syscall.RawConn</code></a> <code>Read</code>
and <code>Write</code> methods now work correctly on Windows.
</p>
<p><!-- CL 107715 -->
TODO: <a href="https://golang.org/cl/107715">https://golang.org/cl/107715</a>: add support for splice(2) in (*TCPConn).ReadFrom on Linux
The <code>net</code> package now automatically uses the
<a href="http://man7.org/linux/man-pages/man2/splice.2.html"><code>splice</code> system call</a>
on Linux when copying data between TCP connections in
<a href="/pkg/net/#TCPConn.ReadFrom"><code>TCPConn.ReadFrom</code></a>, as called by
<a href="/pkg/io/#Copy"><code>io.Copy</code></a>. The result is faster, more efficient TCP proxying.
</p>
<p><!-- CL 108297 -->
TODO: <a href="https://golang.org/cl/108297">https://golang.org/cl/108297</a>: calling File leaves the socket in nonblocking mode
The <a href="/pkg/net/#TCPConn.File"><code>TCPConn.File</code></a>,
<a href="/pkg/net/#UDPConn.File"><code>UDPConn.File</code></a>,
<a href="/pkg/net/#UnixCOnn.File"><code>UnixConn.File</code></a>,
and <a href="/pkg/net/#IPConn.File"><code>IPConn.File</code></a>
methods no longer put the returned <code>*os.File</code> into
blocking mode.
</p>
</dl><!-- net -->
<dl id="net/http"><dt><a href="/pkg/net/http/">net/http</a></dt>
<dd>
<p><!-- CL 89275 -->
TODO: <a href="https://golang.org/cl/89275">https://golang.org/cl/89275</a>: don&#39;t sniff Content-type in Server when X-Content-Type-Options:nosniff
<p><!-- CL 71272 -->
The <a href="/pkg/net/http/#Transport"><code>Transport</code></a> type has a
new <a href="/pkg/net/http/#Transport.MaxConnsPerHost"><code>MaxConnsPerHost</code></a>
option that permits limiting the maximum number of connections
per host.
</p>
<p><!-- CL 79919 -->
The <a href="/pkg/net/http/#Cookie"><code>Cookie</code></a> type has a new
<a href="/pkg/net/http/#Cookie.SameSite"><code>SameSite</code></a> field
(of new type also named
<a href="/pkg/net/http/#SameSite"><code>SameSite</code></a>) to represent the new cookie attribute recently supported by most browsers.
The <code>net/http</code>'s <code>Transport</code> does not use the <code>SameSite</code>
attribute itself, but the package supports parsing and serializing the
attribute for browsers to use.
</p>
<p><!-- CL 81778 -->
It is no longer allowed to reuse a <a href="/pkg/net/http/#Server"><code>Server</code></a>
after a call to
<a href="/pkg/net/http/#Server.Shutdown"><code>Shutdown</code></a> or
<a href="/pkg/net/http/#Server.Close"><code>Close</code></a>. It was never officially supported
in the past and had often surprising behavior. Now, all future calls to the server's <code>Serve</code>
methods will return errors after a shutdown or close.
</p>
<!-- CL 89275 was reverted before Go 1.11 -->
<p><!-- CL 93296 -->
TODO: <a href="https://golang.org/cl/93296">https://golang.org/cl/93296</a>: add StatusMisdirectedRequest (421)
The constant <code>StatusMisdirectedRequest</code> is now defined for HTTP status code 421.
</p>
<p><!-- CL 123875 -->
The HTTP server will no longer cancel contexts or send on
<a href="/pkg/net/http/#CloseNotifier"><code>CloseNotifier</code></a>
channels upon receiving pipelined HTTP/1.1 requests. Browsers do
not use HTTP pipelining, but some clients (such as
Debian's <code>apt</code>) may be configured to do so.
</p>
<p><!-- CL 115255 -->
<a href="/pkg/net/http/#ProxyFromEnvironment"><code>ProxyFromEnvironment</code></a>, which is used by the
<a href="/pkg/net/http/#DefaultTransport"><code>DefaultTransport</code></a>, now
supports CIDR notation and ports in the <code>NO_PROXY</code> environment variable.
</p>
</dl><!-- net/http -->
<dl id="net/http/httputil"><dt><a href="/pkg/net/http/httputil/">net/http/httputil</a></dt>
<dd>
<p><!-- CL 77410 -->
The
<a href="/pkg/net/http/httputil/#ReverseProxy"><code>ReverseProxy</code></a>
has a new
<a href="/pkg/net/http/httputil/#ReverseProxy.ErrorHandler"><code>ErrorHandler</code></a>
option to permit changing how errors are handled.
</p>
<p><!-- CL 115135 -->
The <code>ReverseProxy</code> now also passes
"<code>TE:</code>&nbsp;<code>trailers</code>" request headers
through to the backend, as required by the gRPC protocol.
</p>
</dl><!-- net/http/httputil -->
<dl id="os"><dt><a href="/pkg/os/">os</a></dt>
<dd>
<p><!-- CL 78835 -->
TODO: <a href="https://golang.org/cl/78835">https://golang.org/cl/78835</a>: add UserCacheDir
The new <a href="/pkg/os/#UserCacheDir"><code>UserCacheDir</code></a> function
returns the default root directory to use for user-specific cached data.
</p>
<p><!-- CL 94856 -->
TODO: <a href="https://golang.org/cl/94856">https://golang.org/cl/94856</a>: add ModeIrregular flag
The new <a href="/pkg/os/#ModeIrregular"><code>ModeIrregular</code></a>
is a <a href="/pkg/os/#FileMode"><code>FileMode</code></a> bit to represent
that a file is not a regular file, but nothing else is known about it, or that
it's not a socket, device, named pipe, symlink, or other file type for which
Go has a defined mode bit.
</p>
<p><!-- CL 99337 -->
TODO: <a href="https://golang.org/cl/99337">https://golang.org/cl/99337</a>: enable symlink creation on Windows 10
<a href="/pkg/os/#Symlink"><code>Symlink</code></a> now works
for unprivileged users on Windows 10 on machines with Developer
Mode enabled.
</p>
<p><!-- CL 100077 -->
TODO: <a href="https://golang.org/cl/100077">https://golang.org/cl/100077</a>: use poller when NewFile is called with a blocking descriptor.
When a non-blocking descriptor is passed
to <a href="/pkg/os#NewFile"><code>NewFile</code></a>, the
resulting <code>*File</code> will be kept in non-blocking
mode. This means that I/O for that <code>*File</code> will use
the runtime poller rather than a separate thread, and that
the <a href="/pkg/os/#File.SetDeadline"><code>SetDeadline</code></a>
methods will work.
</p>
</dl><!-- os -->
@ -248,7 +781,8 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="os/signal"><dt><a href="/pkg/os/signal/">os/signal</a></dt>
<dd>
<p><!-- CL 108376 -->
TODO: <a href="https://golang.org/cl/108376">https://golang.org/cl/108376</a>: add func Ignored(sig Signal) bool
The new <a href="/pkg/os/signal/#Ignored"><code>Ignored</code></a> function reports
whether a signal is currently ignored.
</p>
</dl><!-- os/signal -->
@ -256,59 +790,50 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="os/user"><dt><a href="/pkg/os/user/">os/user</a></dt>
<dd>
<p><!-- CL 92456 -->
TODO: <a href="https://golang.org/cl/92456">https://golang.org/cl/92456</a>: add a way to enforce pure Go implementation
The <code>os/user</code> package can now be built in pure Go
mode using the build tag "<code>osusergo</code>",
independent of the use of the environment
variable <code>CGO_ENABLED=0</code>. Previously the only way to use
the package's pure Go implementation was to disable <code>cgo</code>
support across the entire program.
</p>
</dl><!-- os/user -->
<dl id="runtime"><dt><a href="/pkg/runtime/">runtime</a></dt>
<!-- CL 101715 was reverted -->
<dl id="runtime-again"><dt><a href="/pkg/runtime/">runtime</a></dt>
<dd>
<p><!-- CL 85887 -->
TODO: <a href="https://golang.org/cl/85887">https://golang.org/cl/85887</a>: use sparse mappings for the heap
</p>
<p><!-- CL 94076 -->
TODO: <a href="https://golang.org/cl/94076">https://golang.org/cl/94076</a>: use native CAS and memory barrier on ARMv7
</p>
<p><!-- CL 106156 -->
TODO: <a href="https://golang.org/cl/106156">https://golang.org/cl/106156</a>: use fixed TLS offsets on darwin/amd64 and darwin/386
</p>
<p><!-- CL 109255 -->
TODO: <a href="https://golang.org/cl/109255">https://golang.org/cl/109255</a>: enable memory sanitizer on arm64
<p><!-- CL 70993 -->
Setting the <code>GODEBUG=tracebackancestors=<em>N</em></code>
environment variable now extends tracebacks with the stacks at
which goroutines were created, where <em>N</em> limits the
number of ancestor goroutines to report.
</p>
</dl><!-- runtime -->
<dl id="runtime,cmd/ld"><dt><a href="/pkg/runtime,cmd/ld/">runtime,cmd/ld</a></dt>
<dd>
<p><!-- CL 108679 -->
TODO: <a href="https://golang.org/cl/108679">https://golang.org/cl/108679</a>: on darwin, create theads using libc
</p>
</dl><!-- runtime,cmd/ld -->
<dl id="runtime/pprof"><dt><a href="/pkg/runtime/pprof/">runtime/pprof</a></dt>
<dd>
<p><!-- CL 102696 -->
TODO: <a href="https://golang.org/cl/102696">https://golang.org/cl/102696</a>: introduce &#34;allocs&#34; profile
This release adds a new "allocs" profile type that profiles
total number of bytes allocated since the program began
(including garbage-collected bytes). This is identical to the
existing "heap" profile viewed in <code>-alloc_space</code> mode.
Now <code>go test -memprofile=...</code> reports an "allocs" profile
instead of "heap" profile.
</p>
</dl><!-- runtime/pprof -->
<dl id="runtime/traceback"><dt><a href="/pkg/runtime/traceback/">runtime/traceback</a></dt>
<dd>
<p><!-- CL 70993 -->
TODO: <a href="https://golang.org/cl/70993">https://golang.org/cl/70993</a>: support tracking goroutine ancestor tracebacks with GODEBUG=&#34;tracebackancestors=N&#34;
</p>
</dl><!-- runtime/traceback -->
<dl id="sync"><dt><a href="/pkg/sync/">sync</a></dt>
<dd>
<p><!-- CL 87095 -->
TODO: <a href="https://golang.org/cl/87095">https://golang.org/cl/87095</a>: enable profiling of RWMutex
The mutex profile now includes reader/writer contention
for <a href="/pkg/sync/#RWMutex"><code>RWMutex</code></a>.
Writer/writer contention was already included in the mutex
profile.
</p>
</dl><!-- sync -->
@ -316,7 +841,28 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="syscall"><dt><a href="/pkg/syscall/">syscall</a></dt>
<dd>
<p><!-- CL 106275 -->
TODO: <a href="https://golang.org/cl/106275">https://golang.org/cl/106275</a>: introduce Pointer type and use it instead of uintptr
On Windows, several fields were changed from <code>uintptr</code> to a new
<a href="/pkg/syscall/?GOOS=windows&GOARCH=amd64#Pointer"><code>Pointer</code></a>
type to avoid problems with Go's garbage collector. The same change was made
to the <a href="https://godoc.org/golang.org/x/sys/windows"><code>golang.org/x/sys/windows</code></a>
package. For any code affected, users should first migrate away from the <code>syscall</code>
package to the <code>golang.org/x/sys/windows</code> package, and then change
to using the <code>Pointer</code>, while obeying the
<a href="/pkg/unsafe/#Pointer"><code>unsafe.Pointer</code> conversion rules</a>.
</p>
<p><!-- CL 118658 -->
On Linux, the <code>flags</code> parameter to
<a href="/pkg/syscall/?GOOS=linux&GOARCH=amd64#Faccessat"><code>Faccessat</code></a>
is now implemented just as in glibc. In earlier Go releases the
flags parameter was ignored.
</p>
<p><!-- CL 118658 -->
On Linux, the <code>flags</code> parameter to
<a href="/pkg/syscall/?GOOS=linux&GOARCH=amd64#Fchmodat"><code>Fchmodat</code></a>
is now validated. Linux's <code>fchmodat</code> doesn't support the <code>flags</code> parameter
so we now mimic glibc's behavior and return an error if it's non-zero.
</p>
</dl><!-- syscall -->
@ -324,7 +870,10 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="text/scanner"><dt><a href="/pkg/text/scanner/">text/scanner</a></dt>
<dd>
<p><!-- CL 112037 -->
TODO: <a href="https://golang.org/cl/112037">https://golang.org/cl/112037</a>: return RawString token rather than String for raw string literals
The <a href="/pkg/text/scanner/#Scanner.Scan"><code>Scanner.Scan</code></a> method now returns
the <a href="/pkg/text/scanner/#RawString"><code>RawString</code></a> token
instead of <a href="/pkg/text/scanner/#String"><code>String</code></a>
for raw string literals.
</p>
</dl><!-- text/scanner -->
@ -332,7 +881,19 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="text/template"><dt><a href="/pkg/text/template/">text/template</a></dt>
<dd>
<p><!-- CL 84480 -->
TODO: <a href="https://golang.org/cl/84480">https://golang.org/cl/84480</a>: add variable assignments
Modifying template variables via assignments is now permitted via the <code>=</code> token:
</p>
<pre>
{{"{{"}} $v := "init" {{"}}"}}
{{"{{"}} if true {{"}}"}}
{{"{{"}} $v = "changed" {{"}}"}}
{{"{{"}} end {{"}}"}}
v: {{"{{"}} $v {{"}}"}} {{"{{"}}/* "changed" */{{"}}"}}</pre>
<p><!-- CL 95215 -->
In previous versions untyped <code>nil</code> values passed to
template functions were ignored. They are now passed as normal
arguments.
</p>
</dl><!-- text/template -->
@ -340,7 +901,10 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="time"><dt><a href="/pkg/time/">time</a></dt>
<dd>
<p><!-- CL 98157 -->
TODO: <a href="https://golang.org/cl/98157">https://golang.org/cl/98157</a>: add support for parsing timezones denoted by sign and offset
Parsing of timezones denoted by sign and offset is now
supported. In previous versions, numeric timezone names
(such as <code>+03</code>) were not considered valid, and only
three-letter abbreviations (such as <code>MST</code>) were accepted
when expecting a timezone name.
</p>
</dl><!-- time -->

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
<!--{
"Title": "The Go Programming Language Specification",
"Subtitle": "Version of May 9, 2018",
"Subtitle": "Version of August 30, 2018",
"Path": "/ref/spec"
}-->
@ -2112,8 +2112,8 @@ with initializer expressions but no types:
i, j := 0, 10
f := func() int { return 7 }
ch := make(chan int)
r, w := os.Pipe(fd) // os.Pipe() returns two values
_, y, _ := coord(p) // coord() returns three values; only interested in y coordinate
r, w, _ := os.Pipe() // os.Pipe() returns a connected pair of Files and an error, if any
_, y, _ := coord(p) // coord() returns three values; only interested in y coordinate
</pre>
<p>

BIN
doc/gopher/modelsheet.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View file

@ -639,14 +639,10 @@ contains further details regarding Go's ARM support.
</p>
</li>
<li><code>$GOMIPS</code> (for <code>mips</code> and <code>mipsle</code> only)
<li><code>$GOMIPS</code> (for <code>mips</code> and <code>mipsle</code> only) <br> <code>$GOMIPS64</code> (for <code>mips64</code> and <code>mips64le</code> only)
<p>
This sets whether to use floating point instructions.
These variables set whether to use floating point instructions. Set to "<code>hardfloat</code>" to use floating point instructions; this is the default. Set to "<code>softfloat</code>" to use soft floating point.
</p>
<ul>
<li><code>GOMIPS=hardfloat</code>: use floating point instructions (the default)</li>
<li><code>GOMIPS=softfloat</code>: use soft floating point</li>
</ul>
</li>
</ul>

View file

@ -50,7 +50,7 @@ If your OS or architecture is not on the list, you may be able to
<tr><td>FreeBSD 10.3 or later</td> <td>amd64, 386</td> <td>Debian GNU/kFreeBSD not supported</td></tr>
<tr valign='top'><td>Linux 2.6.23 or later with glibc</td> <td>amd64, 386, arm, arm64,<br>s390x, ppc64le</td> <td>CentOS/RHEL 5.x not supported.<br>Install from source for other libc.</td></tr>
<tr><td>macOS 10.10 or later</td> <td>amd64</td> <td>use the clang or gcc<sup>&#8224;</sup> that comes with Xcode<sup>&#8225;</sup> for <code>cgo</code> support</td></tr>
<tr><td>Windows XP SP2 or later</td> <td>amd64, 386</td> <td>use MinGW gcc<sup>&#8224;</sup>. No need for cygwin or msys.</td></tr>
<tr><td>Windows 7, Server 2008R2 or later</td> <td>amd64, 386</td> <td>use MinGW gcc<sup>&#8224;</sup>. No need for cygwin or msys.</td></tr>
</table>
<p>

View file

@ -38,7 +38,7 @@ security team directly:
</p>
<ul>
<li>Primary security coordinator: <a href="mailto:adg@golang.org">Andrew Gerrand</a> (<a href="https://drive.google.com/a/google.com/file/d/0B42ZAZN5yFufRldybEVNandRN2c/view">public key</a>).</li>
<li>Primary security coordinator: <a href="mailto:filippo@golang.org">Filippo Valsorda</a> (<a href="https://keybase.io/filippo/pgp_keys.asc">public key</a>).</li>
<li>Secondary coordinator: <a href="mailto:agl@golang.org">Adam Langley</a> (<a href="https://www.imperialviolet.org/key.asc">public key</a>).</li>
<li>If you receive no response, mail <a href="mailto:golang-dev@googlegroups.com">golang-dev@googlegroups.com</a> or use the <a href="https://groups.google.com/forum/#!forum/golang-dev">golang-dev web interface</a>.</li>
</ul>

View file

@ -90,6 +90,8 @@ func Test22906(t *testing.T) { test22906(t) }
func Test24206(t *testing.T) { test24206(t) }
func Test25143(t *testing.T) { test25143(t) }
func Test23356(t *testing.T) { test23356(t) }
func Test26066(t *testing.T) { test26066(t) }
func Test26213(t *testing.T) { test26213(t) }
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
func BenchmarkGoString(b *testing.B) { benchGoString(b) }

View file

@ -2,7 +2,16 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin,cgo,!internal
// We skip this test in race mode because, for unknown reasons,
// linking against CoreFoundation on macOS 10.10 causes mmap to ignore
// the hint address, which makes the Go allocator incompatible with
// TSAN. See golang.org/issue/26475.
//
// TODO(austin): Once support for macOS 10.10 is dropped, remove the
// race constraint (and the one in issue21897b.go). See
// golang.org/issue/26513.
// +build darwin,cgo,!internal,!race
package cgotest

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !darwin !cgo internal
// +build !darwin !cgo internal race
package cgotest

View file

@ -0,0 +1,39 @@
// Copyright 2018 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.
// See issue21897.go and golang.org/issue/26475 for why this is
// skipped in race mode.
//
// TODO(austin): Once support for macOS 10.10 is dropped, remove the
// race constraint. See golang.org/issue/26513.
// +build !race
package cgotest
import (
"testing"
"./issue24161arg"
"./issue24161e0"
"./issue24161e1"
"./issue24161e2"
"./issue24161res"
)
func Test24161Arg(t *testing.T) {
issue24161arg.Test(t)
}
func Test24161Res(t *testing.T) {
issue24161res.Test(t)
}
func Test24161Example0(t *testing.T) {
issue24161e0.Test(t)
}
func Test24161Example1(t *testing.T) {
issue24161e1.Test(t)
}
func Test24161Example2(t *testing.T) {
issue24161e2.Test(t)
}

View file

@ -0,0 +1,17 @@
// Copyright 2018 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.
// +build darwin
package issue24161arg
/*
#cgo LDFLAGS: -framework CoreFoundation
#include <CoreFoundation/CoreFoundation.h>
*/
import "C"
func test24161array() C.CFArrayRef {
return C.CFArrayCreate(0, nil, 0, nil)
}

View file

@ -0,0 +1,19 @@
// Copyright 2018 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.
// +build darwin
package issue24161arg
/*
#cgo LDFLAGS: -framework CoreFoundation
#include <CoreFoundation/CoreFoundation.h>
*/
import "C"
import "testing"
func Test(t *testing.T) {
a := test24161array()
C.CFArrayCreateCopy(0, a)
}

View file

@ -0,0 +1,29 @@
// Copyright 2018 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.
// +build darwin
package issue24161e0
/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework CoreFoundation -framework Security
#include <TargetConditionals.h>
#include <CoreFoundation/CoreFoundation.h>
#include <Security/Security.h>
#if TARGET_OS_IPHONE == 0 && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200
typedef CFStringRef SecKeyAlgorithm;
static CFDataRef SecKeyCreateSignature(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef dataToSign, CFErrorRef *error){return NULL;}
#define kSecKeyAlgorithmECDSASignatureDigestX962SHA1 foo()
static SecKeyAlgorithm foo(void){return NULL;}
#endif
*/
import "C"
import "testing"
func f1() {
C.SecKeyCreateSignature(0, C.kSecKeyAlgorithmECDSASignatureDigestX962SHA1, 0, nil)
}
func Test(t *testing.T) {}

View file

@ -0,0 +1,38 @@
// Copyright 2018 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.
// +build darwin
package issue24161e1
/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework CoreFoundation -framework Security
#include <TargetConditionals.h>
#include <CoreFoundation/CoreFoundation.h>
#include <Security/Security.h>
#if TARGET_OS_IPHONE == 0 && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200
typedef CFStringRef SecKeyAlgorithm;
static CFDataRef SecKeyCreateSignature(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef dataToSign, CFErrorRef *error){return NULL;}
#define kSecKeyAlgorithmECDSASignatureDigestX962SHA1 foo()
static SecKeyAlgorithm foo(void){return NULL;}
#endif
*/
import "C"
import (
"fmt"
"testing"
)
func f1() {
C.SecKeyCreateSignature(0, C.kSecKeyAlgorithmECDSASignatureDigestX962SHA1, 0, nil)
}
func f2(e C.CFErrorRef) {
if desc := C.CFErrorCopyDescription(e); desc != 0 {
fmt.Println(desc)
}
}
func Test(t *testing.T) {}

View file

@ -0,0 +1,40 @@
// Copyright 2018 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.
// +build darwin
package issue24161e2
/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework CoreFoundation -framework Security
#include <TargetConditionals.h>
#include <CoreFoundation/CoreFoundation.h>
#include <Security/Security.h>
#if TARGET_OS_IPHONE == 0 && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200
typedef CFStringRef SecKeyAlgorithm;
static CFDataRef SecKeyCreateSignature(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef dataToSign, CFErrorRef *error){return NULL;}
#define kSecKeyAlgorithmECDSASignatureDigestX962SHA1 foo()
static SecKeyAlgorithm foo(void){return NULL;}
#endif
*/
import "C"
import (
"fmt"
"testing"
)
var _ C.CFStringRef
func f1() {
C.SecKeyCreateSignature(0, C.kSecKeyAlgorithmECDSASignatureDigestX962SHA1, 0, nil)
}
func f2(e C.CFErrorRef) {
if desc := C.CFErrorCopyDescription(e); desc != 0 {
fmt.Println(desc)
}
}
func Test(t *testing.T) {}

View file

@ -0,0 +1,23 @@
// Copyright 2018 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.
// +build darwin
package issue24161res
/*
#cgo LDFLAGS: -framework CoreFoundation
#include <CoreFoundation/CoreFoundation.h>
*/
import "C"
import (
"reflect"
"testing"
)
func Test(t *testing.T) {
if k := reflect.TypeOf(C.CFArrayCreate(0, nil, 0, nil)).Kind(); k != reflect.Uintptr {
t.Fatalf("bad kind %s\n", k)
}
}

View file

@ -0,0 +1,19 @@
// Copyright 2018 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.
// Wrong type of constant with GCC 8 and newer.
package cgotest
// const unsigned long long int issue26066 = (const unsigned long long) -1;
import "C"
import "testing"
func test26066(t *testing.T) {
var i = int64(C.issue26066)
if i != -1 {
t.Errorf("got %d, want -1", i)
}
}

View file

@ -0,0 +1,29 @@
// Copyright 2018 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.
// It's going to be hard to include a whole real JVM to test this.
// So we'll simulate a really easy JVM using just the parts we need.
// This is the relevant part of jni.h.
// On Android NDK16, jobject is defined like this in C and C++
typedef void* jobject;
typedef jobject jclass;
typedef jobject jthrowable;
typedef jobject jstring;
typedef jobject jarray;
typedef jarray jbooleanArray;
typedef jarray jbyteArray;
typedef jarray jcharArray;
typedef jarray jshortArray;
typedef jarray jintArray;
typedef jarray jlongArray;
typedef jarray jfloatArray;
typedef jarray jdoubleArray;
typedef jarray jobjectArray;
typedef jobject jweak;
// Note: jvalue is already a non-pointer type due to it being a C union.

View file

@ -0,0 +1,46 @@
// Copyright 2018 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 issue26213
/*
#include "jni.h"
*/
import "C"
import (
"testing"
)
func Test26213(t *testing.T) {
var x1 C.jobject = 0 // Note: 0, not nil. That makes sure we use uintptr for these types.
_ = x1
var x2 C.jclass = 0
_ = x2
var x3 C.jthrowable = 0
_ = x3
var x4 C.jstring = 0
_ = x4
var x5 C.jarray = 0
_ = x5
var x6 C.jbooleanArray = 0
_ = x6
var x7 C.jbyteArray = 0
_ = x7
var x8 C.jcharArray = 0
_ = x8
var x9 C.jshortArray = 0
_ = x9
var x10 C.jintArray = 0
_ = x10
var x11 C.jlongArray = 0
_ = x11
var x12 C.jfloatArray = 0
_ = x12
var x13 C.jdoubleArray = 0
_ = x13
var x14 C.jobjectArray = 0
_ = x14
var x15 C.jweak = 0
_ = x15
}

View file

@ -0,0 +1,10 @@
// Copyright 2018 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.
// Issue 26430: incomplete typedef leads to inconsistent typedefs error.
// No runtime test; just make sure it compiles.
package cgotest
import _ "./issue26430"

View file

@ -2,6 +2,12 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This file is here just to make the go tool happy. It allows
// empty function declarations (no function body).
// It is used with "go:linkname".
package a
// typedef struct S ST;
// static ST* F() { return 0; }
import "C"
func F1() {
C.F()
}

View file

@ -0,0 +1,13 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package a
// typedef struct S ST;
// struct S { int f; };
import "C"
func F2(p *C.ST) {
p.f = 1
}

View file

@ -0,0 +1,23 @@
// Copyright 2018 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 cgotest
// Introduce two pointer types which are distinct, but have the same
// base type. Make sure that both of those pointer types get resolved
// correctly. Before the fix for 26517 if one of these pointer types
// was resolved before the other one was processed, the second one
// would never be resolved.
// Before this issue was fixed this test failed on Windows,
// where va_list expands to a named char* type.
/*
#include <stdarg.h>
typedef va_list TypeOne;
typedef char *TypeTwo;
*/
import "C"
var a C.TypeOne
var b C.TypeTwo

View file

@ -0,0 +1,10 @@
// Copyright 2018 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.
// Issue 26743: typedef of uint leads to inconsistent typedefs error.
// No runtime test; just make sure it compiles.
package cgotest
import _ "./issue26743"

View file

@ -0,0 +1,11 @@
// Copyright 2018 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 issue26743
// typedef unsigned int uint;
// int C1(uint x) { return x; }
import "C"
var V1 = C.C1(0)

View file

@ -0,0 +1,9 @@
// Copyright 2018 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 issue26743
import "C"
var V2 C.uint

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !windows
// +build !windows,!static
#include <stdint.h>
#include <dlfcn.h>

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !windows
// +build !windows,!static
package cgotest

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
// +build windows static
package cgotest

View file

@ -41,7 +41,7 @@ func test9400(t *testing.T) {
// Grow the stack and put down a test pattern
const pattern = 0x123456789abcdef
var big [1024]uint64 // len must match assmebly
var big [1024]uint64 // len must match assembly
for i := range big {
big[i] = pattern
}

View file

@ -0,0 +1,15 @@
// Copyright 2018 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 cgotest
import (
"testing"
"./issue26213"
)
func test26213(t *testing.T) {
issue26213.Test26213(t)
}

View file

@ -14,6 +14,7 @@ import (
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strings"
"syscall"
"testing"
@ -83,13 +84,17 @@ func init() {
cc = append(cc, []string{"-framework", "CoreFoundation", "-framework", "Foundation"}...)
}
libgodir = GOOS + "_" + GOARCH
switch GOOS {
case "darwin":
if GOARCH == "arm" || GOARCH == "arm64" {
if runtime.Compiler == "gccgo" {
libgodir = "gccgo_" + libgodir + "_fPIC"
} else {
switch GOOS {
case "darwin":
if GOARCH == "arm" || GOARCH == "arm64" {
libgodir += "_shared"
}
case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
libgodir += "_shared"
}
case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
libgodir += "_shared"
}
cc = append(cc, "-I", filepath.Join("pkg", libgodir))
@ -155,6 +160,9 @@ func testInstall(t *testing.T, exe, libgoa, libgoh string, buildcmd ...string) {
} else {
ccArgs = append(ccArgs, "main_unix.c", libgoa)
}
if runtime.Compiler == "gccgo" {
ccArgs = append(ccArgs, "-lgo")
}
t.Log(ccArgs)
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
t.Logf("%s", out)
@ -163,7 +171,11 @@ func testInstall(t *testing.T, exe, libgoa, libgoh string, buildcmd ...string) {
defer os.Remove(exe)
binArgs := append(cmdToRun(exe), "arg1", "arg2")
if out, err := exec.Command(binArgs[0], binArgs[1:]...).CombinedOutput(); err != nil {
cmd = exec.Command(binArgs[0], binArgs[1:]...)
if runtime.Compiler == "gccgo" {
cmd.Env = append(os.Environ(), "GCCGO=1")
}
if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
}
@ -194,8 +206,13 @@ func checkLineComments(t *testing.T, hdrname string) {
func TestInstall(t *testing.T) {
defer os.RemoveAll("pkg")
libgoa := "libgo.a"
if runtime.Compiler == "gccgo" {
libgoa = "liblibgo.a"
}
testInstall(t, "./testp1"+exeSuffix,
filepath.Join("pkg", libgodir, "libgo.a"),
filepath.Join("pkg", libgodir, libgoa),
filepath.Join("pkg", libgodir, "libgo.h"),
"go", "install", "-i", "-buildmode=c-archive", "libgo")
@ -235,6 +252,9 @@ func TestEarlySignalHandler(t *testing.T) {
checkLineComments(t, "libgo2.h")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main2.c", "libgo2.a")
if runtime.Compiler == "gccgo" {
ccArgs = append(ccArgs, "-lgo")
}
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
@ -265,6 +285,9 @@ func TestSignalForwarding(t *testing.T) {
checkLineComments(t, "libgo2.h")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main5.c", "libgo2.a")
if runtime.Compiler == "gccgo" {
ccArgs = append(ccArgs, "-lgo")
}
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
@ -306,6 +329,9 @@ func TestSignalForwardingExternal(t *testing.T) {
checkLineComments(t, "libgo2.h")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main5.c", "libgo2.a")
if runtime.Compiler == "gccgo" {
ccArgs = append(ccArgs, "-lgo")
}
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
@ -419,6 +445,9 @@ func TestOsSignal(t *testing.T) {
checkLineComments(t, "libgo3.h")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main3.c", "libgo3.a")
if runtime.Compiler == "gccgo" {
ccArgs = append(ccArgs, "-lgo")
}
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
@ -452,6 +481,9 @@ func TestSigaltstack(t *testing.T) {
checkLineComments(t, "libgo4.h")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main4.c", "libgo4.a")
if runtime.Compiler == "gccgo" {
ccArgs = append(ccArgs, "-lgo")
}
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
@ -476,6 +508,9 @@ func TestExtar(t *testing.T) {
case "windows":
t.Skip("skipping signal test on Windows")
}
if runtime.Compiler == "gccgo" {
t.Skip("skipping -extar test when using gccgo")
}
defer func() {
os.Remove("libgo4.a")
@ -530,14 +565,26 @@ func TestPIE(t *testing.T) {
t.Fatal(err)
}
ccArgs := append(cc, "-fPIE", "-pie", "-o", "testp"+exeSuffix, "main.c", "main_unix.c", filepath.Join("pkg", libgodir, "libgo.a"))
libgoa := "libgo.a"
if runtime.Compiler == "gccgo" {
libgoa = "liblibgo.a"
}
ccArgs := append(cc, "-fPIE", "-pie", "-o", "testp"+exeSuffix, "main.c", "main_unix.c", filepath.Join("pkg", libgodir, libgoa))
if runtime.Compiler == "gccgo" {
ccArgs = append(ccArgs, "-lgo")
}
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
}
binArgs := append(bin, "arg1", "arg2")
if out, err := exec.Command(binArgs[0], binArgs[1:]...).CombinedOutput(); err != nil {
cmd = exec.Command(binArgs[0], binArgs[1:]...)
if runtime.Compiler == "gccgo" {
cmd.Env = append(os.Environ(), "GCCGO=1")
}
if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
}
@ -605,6 +652,9 @@ func TestSIGPROF(t *testing.T) {
checkLineComments(t, "libgo6.h")
ccArgs := append(cc, "-o", "testp6"+exeSuffix, "main6.c", "libgo6.a")
if runtime.Compiler == "gccgo" {
ccArgs = append(ccArgs, "-lgo")
}
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
@ -648,6 +698,9 @@ func TestCompileWithoutShared(t *testing.T) {
// In some cases, -no-pie is needed here, but not accepted everywhere. First try
// if -no-pie is accepted. See #22126.
ccArgs := append(cc, "-o", exe, "-no-pie", "main5.c", "libgo2.a")
if runtime.Compiler == "gccgo" {
ccArgs = append(ccArgs, "-lgo")
}
t.Log(ccArgs)
out, err = exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput()

View file

@ -5,6 +5,7 @@
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct sigaction sa;
@ -30,7 +31,12 @@ int install_handler() {
perror("sigaction");
return 2;
}
if (osa.sa_handler == SIG_DFL || (osa.sa_flags&SA_ONSTACK) == 0) {
if (osa.sa_handler == SIG_DFL) {
fprintf(stderr, "Go runtime did not install signal handler\n");
return 2;
}
// gccgo does not set SA_ONSTACK for SIGSEGV.
if (getenv("GCCGO") == "" && (osa.sa_flags&SA_ONSTACK) == 0) {
fprintf(stderr, "Go runtime did not install signal handler\n");
return 2;
}

View file

@ -29,13 +29,13 @@ func ResetSIGIO() {
signal.Reset(syscall.SIGIO)
}
// SawSIGIO returns whether we saw a SIGIO within a brief pause.
// SawSIGIO reports whether we saw a SIGIO.
//export SawSIGIO
func SawSIGIO() C.int {
select {
case <-sigioChan:
return 1
case <-time.After(100 * time.Millisecond):
case <-time.After(5 * time.Second):
return 0
}
}

View file

@ -201,6 +201,16 @@ func run(t *testing.T, env []string, args ...string) string {
t.Helper()
cmd := exec.Command(args[0], args[1:]...)
cmd.Env = env
if GOOS != "windows" {
// TestUnexportedSymbols relies on file descriptor 30
// being closed when the program starts, so enforce
// that in all cases. (The first three descriptors are
// stdin/stdout/stderr, so we just need to make sure
// that cmd.ExtraFiles[27] exists and is nil.)
cmd.ExtraFiles = make([]*os.File, 28)
}
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("command failed: %v\n%v\n%s\n", args, err, out)

View file

@ -0,0 +1,18 @@
// Copyright 2018 The Go Authors. All rights reserve d.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// +build ignore
package main
/*
struct S1 { int f1; };
struct S2 { struct S1 s1; };
typedef struct S1 S1Type;
typedef struct S2 S2Type;
*/
import "C"
type S1 C.S1Type
type S2 C.S2Type

View file

@ -7,7 +7,7 @@
# We are testing cgo -godefs, which translates Go files that use
# import "C" into Go files with Go definitions of types defined in the
# import "C" block. Add more tests here.
FILE_PREFIXES="anonunion issue8478"
FILE_PREFIXES="anonunion issue8478 fieldtypedef"
RM=
for FP in $FILE_PREFIXES

View file

@ -0,0 +1,106 @@
// Copyright 2018 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.
// Usage:
//
// checkdwarf <exe> <suffix>
//
// Opens <exe>, which must be an executable or a library and checks that
// there is an entry in .debug_info whose name ends in <suffix>
package main
import (
"debug/dwarf"
"debug/elf"
"debug/macho"
"debug/pe"
"fmt"
"os"
"strings"
)
func usage() {
fmt.Fprintf(os.Stderr, "checkdwarf executable-or-library DIE-suffix\n")
}
type dwarfer interface {
DWARF() (*dwarf.Data, error)
}
func openElf(path string) dwarfer {
exe, err := elf.Open(path)
if err != nil {
return nil
}
return exe
}
func openMacho(path string) dwarfer {
exe, err := macho.Open(path)
if err != nil {
return nil
}
return exe
}
func openPE(path string) dwarfer {
exe, err := pe.Open(path)
if err != nil {
return nil
}
return exe
}
func main() {
if len(os.Args) != 3 {
usage()
}
exePath := os.Args[1]
dieSuffix := os.Args[2]
var exe dwarfer
for _, openfn := range []func(string) dwarfer{openMacho, openPE, openElf} {
exe = openfn(exePath)
if exe != nil {
break
}
}
if exe == nil {
fmt.Fprintf(os.Stderr, "could not open %s\n", exePath)
os.Exit(1)
}
data, err := exe.DWARF()
if err != nil {
fmt.Fprintf(os.Stderr, "%s: error opening DWARF: %v\n", exePath, err)
os.Exit(1)
}
rdr := data.Reader()
for {
e, err := rdr.Next()
if err != nil {
fmt.Fprintf(os.Stderr, "%s: error reading DWARF: %v\n", exePath, err)
os.Exit(1)
}
if e == nil {
break
}
name, hasname := e.Val(dwarf.AttrName).(string)
if !hasname {
continue
}
if strings.HasSuffix(name, dieSuffix) {
// found
os.Exit(0)
}
}
fmt.Fprintf(os.Stderr, "%s: no entry with a name ending in %q was found\n", exePath, dieSuffix)
os.Exit(1)
}

View file

@ -32,6 +32,14 @@ GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o=unnamed1.so u
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o=unnamed2.so unnamed2/main.go
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" host
# test that DWARF sections are emitted for plugins and programs importing "plugin"
if [ $GOOS != "darwin" ]; then
# On macOS, for some reason, the linker doesn't add debug sections to .so,
# see issue #27502.
go run src/checkdwarf/main.go plugin2.so plugin2.UnexportedNameReuse
fi
go run src/checkdwarf/main.go host main.main
LD_LIBRARY_PATH=$(pwd) ./host
# Test that types and itabs get properly uniqified.

View file

@ -381,12 +381,13 @@ func (c *config) checkRuntime() (skip bool, err error) {
return false, err
}
cmd.Args = append(cmd.Args, "-dM", "-E", "../../../src/runtime/cgo/libcgo.h")
cmdStr := strings.Join(cmd.Args, " ")
out, err := cmd.CombinedOutput()
if err != nil {
return false, fmt.Errorf("%#q exited with %v\n%s", strings.Join(cmd.Args, " "), err, out)
return false, fmt.Errorf("%#q exited with %v\n%s", cmdStr, err, out)
}
if !bytes.Contains(out, []byte("#define CGO_TSAN")) {
return true, fmt.Errorf("%#q did not define CGO_TSAN")
return true, fmt.Errorf("%#q did not define CGO_TSAN", cmdStr)
}
return false, nil
}

View file

@ -27,6 +27,7 @@ func TestMSAN(t *testing.T) {
{src: "msan3.go"},
{src: "msan4.go"},
{src: "msan5.go"},
{src: "msan6.go"},
{src: "msan_fail.go", wantErr: true},
}
for _, tc := range cases {

View file

@ -0,0 +1,72 @@
// Copyright 2018 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
// A C function returning a value on the Go stack could leave the Go
// stack marked as uninitialized, potentially causing a later error
// when the stack is used for something else. Issue 26209.
/*
#cgo LDFLAGS: -fsanitize=memory
#cgo CPPFLAGS: -fsanitize=memory
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
uintptr_t a[20];
} S;
S f() {
S *p;
p = (S *)(malloc(sizeof(S)));
p->a[0] = 0;
return *p;
}
*/
import "C"
// allocateStack extends the stack so that stack copying doesn't
// confuse the msan data structures.
//go:noinline
func allocateStack(i int) int {
if i == 0 {
return i
}
return allocateStack(i - 1)
}
// F1 marks a chunk of stack as uninitialized.
// C.f returns an uninitialized struct on the stack, so msan will mark
// the stack as uninitialized.
//go:noinline
func F1() uintptr {
s := C.f()
return uintptr(s.a[0])
}
// F2 allocates a struct on the stack and converts it to an empty interface,
// which will call msanread and see that the data appears uninitialized.
//go:noinline
func F2() interface{} {
return C.S{}
}
func poisonStack(i int) int {
if i == 0 {
return int(F1())
}
F1()
r := poisonStack(i - 1)
F2()
return r
}
func main() {
allocateStack(16384)
poisonStack(128)
}

View file

@ -560,7 +560,7 @@ func TestNotes(t *testing.T) {
abiHashNoteFound = true
case 3: // ELF_NOTE_GODEPS_TAG
if depsNoteFound {
t.Error("multiple depedency list notes")
t.Error("multiple dependency list notes")
}
testDepsNote(t, f, note)
depsNoteFound = true
@ -905,3 +905,9 @@ func TestGlobal(t *testing.T) {
AssertIsLinkedTo(t, "./bin/global", soname)
AssertHasRPath(t, "./bin/global", gorootInstallDir)
}
// Run a test using -linkshared of an installed shared package.
// Issue 26400.
func TestTestInstalledShared(t *testing.T) {
goCmd(nil, "test", "-linkshared", "-test.short", "sync/atomic")
}

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//+build !gccgo
// +build !gccgo
#include "textflag.h"

View file

@ -1,3 +1,7 @@
// Copyright 2016 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 depBase
import (

View file

@ -1,4 +1,8 @@
//+build gccgo
// Copyright 2016 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.
// +build gccgo
package depBase

View file

@ -1,4 +1,8 @@
//+build !gccgo
// Copyright 2016 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.
// +build !gccgo
package depBase

View file

@ -27,6 +27,8 @@ license that can be found in the LICENSE file.
mod = result.module;
inst = result.instance;
document.getElementById("runButton").disabled = false;
}).catch((err) => {
console.error(err);
});
async function run() {

View file

@ -27,11 +27,17 @@
global.TextEncoder = util.TextEncoder;
global.TextDecoder = util.TextDecoder;
} else {
window.global = window;
if (typeof window !== "undefined") {
window.global = window;
} else if (typeof self !== "undefined") {
self.global = self;
} else {
throw new Error("cannot export Go (neither window nor self is defined)");
}
let outputBuf = "";
global.fs = {
constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1, O_NONBLOCK: -1, O_SYNC: -1 }, // unused
constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1 }, // unused
writeSync(fd, buf) {
outputBuf += decoder.decode(buf);
const nl = outputBuf.lastIndexOf("\n");
@ -91,9 +97,11 @@
}
const storeValue = (addr, v) => {
const nanHead = 0x7FF80000;
if (typeof v === "number") {
if (isNaN(v)) {
mem().setUint32(addr + 4, 0x7FF80000, true); // NaN
mem().setUint32(addr + 4, nanHead, true);
mem().setUint32(addr, 0, true);
return;
}
@ -101,51 +109,44 @@
return;
}
mem().setUint32(addr + 4, 0x7FF80000, true); // NaN
switch (v) {
case undefined:
mem().setUint32(addr + 4, nanHead, true);
mem().setUint32(addr, 1, true);
return;
case null:
mem().setUint32(addr + 4, nanHead, true);
mem().setUint32(addr, 2, true);
return;
case true:
mem().setUint32(addr + 4, nanHead, true);
mem().setUint32(addr, 3, true);
return;
case false:
mem().setUint32(addr + 4, nanHead, true);
mem().setUint32(addr, 4, true);
return;
}
if (typeof v === "string") {
let ref = this._stringRefs.get(v);
if (ref === undefined) {
ref = this._values.length;
this._values.push(v);
this._stringRefs.set(v, ref);
}
mem().setUint32(addr, ref, true);
return;
}
if (typeof v === "symbol") {
let ref = this._symbolRefs.get(v);
if (ref === undefined) {
ref = this._values.length;
this._values.push(v);
this._symbolRefs.set(v, ref);
}
mem().setUint32(addr, ref, true);
return;
}
let ref = v[this._refProp];
let ref = this._refs.get(v);
if (ref === undefined) {
ref = this._values.length;
this._values.push(v);
v[this._refProp] = ref;
this._refs.set(v, ref);
}
let typeFlag = 0;
switch (typeof v) {
case "string":
typeFlag = 1;
break;
case "symbol":
typeFlag = 2;
break;
case "function":
typeFlag = 3;
break;
}
mem().setUint32(addr + 4, nanHead | typeFlag, true);
mem().setUint32(addr, ref, true);
}
@ -176,8 +177,12 @@
go: {
// func wasmExit(code int32)
"runtime.wasmExit": (sp) => {
const code = mem().getInt32(sp + 8, true);
this.exited = true;
this.exit(mem().getInt32(sp + 8, true));
delete this._inst;
delete this._values;
delete this._refs;
this.exit(code);
},
// func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)
@ -328,16 +333,10 @@
false,
global,
this._inst.exports.mem,
() => { // resolveCallbackPromise
if (this.exited) {
throw new Error("bad callback: Go program has already exited");
}
setTimeout(this._resolveCallbackPromise, 0); // make sure it is asynchronous
},
this,
];
this._stringRefs = new Map();
this._symbolRefs = new Map();
this._refProp = Symbol();
this._refs = new Map();
this._callbackShutdown = false;
this.exited = false;
const mem = new DataView(this._inst.exports.mem.buffer)
@ -374,7 +373,12 @@
while (true) {
const callbackPromise = new Promise((resolve) => {
this._resolveCallbackPromise = resolve;
this._resolveCallbackPromise = () => {
if (this.exited) {
throw new Error("bad callback: Go program has already exited");
}
setTimeout(resolve, 0); // make sure it is asynchronous
};
});
this._inst.exports.run(argc, argv);
if (this.exited) {
@ -383,6 +387,28 @@
await callbackPromise;
}
}
static _makeCallbackHelper(id, pendingCallbacks, go) {
return function() {
pendingCallbacks.push({ id: id, args: arguments });
go._resolveCallbackPromise();
};
}
static _makeEventCallbackHelper(preventDefault, stopPropagation, stopImmediatePropagation, fn) {
return function(event) {
if (preventDefault) {
event.preventDefault();
}
if (stopPropagation) {
event.stopPropagation();
}
if (stopImmediatePropagation) {
event.stopImmediatePropagation();
}
fn(event);
};
}
}
if (isNodeJS) {
@ -396,17 +422,16 @@
go.env = process.env;
go.exit = process.exit;
WebAssembly.instantiate(fs.readFileSync(process.argv[2]), go.importObject).then((result) => {
process.on("exit", () => { // Node.js exits if no callback is pending
if (!go.exited) {
console.error("error: all goroutines asleep and no JavaScript callback pending - deadlock!");
process.exit(1);
process.on("exit", (code) => { // Node.js exits if no callback is pending
if (code === 0 && !go.exited) {
// deadlock, make Go print error and stack traces
go._callbackShutdown = true;
go._inst.exports.run();
}
});
return go.run(result.instance);
}).catch((err) => {
console.error(err);
go.exited = true;
process.exit(1);
throw err;
});
}
})();

View file

@ -160,7 +160,7 @@ func (b *block) V7() *headerV7 { return (*headerV7)(b) }
func (b *block) GNU() *headerGNU { return (*headerGNU)(b) }
func (b *block) STAR() *headerSTAR { return (*headerSTAR)(b) }
func (b *block) USTAR() *headerUSTAR { return (*headerUSTAR)(b) }
func (b *block) Sparse() sparseArray { return (sparseArray)(b[:]) }
func (b *block) Sparse() sparseArray { return sparseArray(b[:]) }
// GetFormat checks that the block is a valid tar header based on the checksum.
// It then attempts to guess the specific format based on magic values.
@ -263,7 +263,7 @@ func (h *headerGNU) DevMajor() []byte { return h[329:][:8] }
func (h *headerGNU) DevMinor() []byte { return h[337:][:8] }
func (h *headerGNU) AccessTime() []byte { return h[345:][:12] }
func (h *headerGNU) ChangeTime() []byte { return h[357:][:12] }
func (h *headerGNU) Sparse() sparseArray { return (sparseArray)(h[386:][:24*4+1]) }
func (h *headerGNU) Sparse() sparseArray { return sparseArray(h[386:][:24*4+1]) }
func (h *headerGNU) RealSize() []byte { return h[483:][:12] }
type headerSTAR [blockSize]byte
@ -293,7 +293,7 @@ func (h *headerUSTAR) Prefix() []byte { return h[345:][:155] }
type sparseArray []byte
func (s sparseArray) Entry(i int) sparseElem { return (sparseElem)(s[i*24:]) }
func (s sparseArray) Entry(i int) sparseElem { return sparseElem(s[i*24:]) }
func (s sparseArray) IsExtended() []byte { return s[24*s.MaxEntries():][:1] }
func (s sparseArray) MaxEntries() int { return len(s) / 24 }

View file

@ -69,6 +69,9 @@ func OpenReader(name string) (*ReadCloser, error) {
// NewReader returns a new Reader reading from r, which is assumed to
// have the given size in bytes.
func NewReader(r io.ReaderAt, size int64) (*Reader, error) {
if size < 0 {
return nil, errors.New("zip: size cannot be negative")
}
zr := new(Reader)
if err := zr.init(r, size); err != nil {
return nil, err

View file

@ -658,6 +658,12 @@ func TestInvalidFiles(t *testing.T) {
if err != ErrFormat {
t.Errorf("sigs: error=%v, want %v", err, ErrFormat)
}
// negative size
_, err = NewReader(bytes.NewReader([]byte("foobar")), -1)
if err == nil {
t.Errorf("archive/zip.NewReader: expected error when negative size is passed")
}
}
func messWith(fileName string, corrupter func(b []byte)) (r io.ReaderAt, size int64) {

View file

@ -303,8 +303,8 @@ func (h *FileHeader) SetMode(mode os.FileMode) {
}
// isZip64 reports whether the file size exceeds the 32 bit limit
func (fh *FileHeader) isZip64() bool {
return fh.CompressedSize64 >= uint32max || fh.UncompressedSize64 >= uint32max
func (h *FileHeader) isZip64() bool {
return h.CompressedSize64 >= uint32max || h.UncompressedSize64 >= uint32max
}
func msdosModeToFileMode(m uint32) (mode os.FileMode) {

View file

@ -336,6 +336,12 @@ func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
fh.Method = Store
fh.Flags &^= 0x8 // we will not write a data descriptor
// Explicitly clear sizes as they have no meaning for directories.
fh.CompressedSize = 0
fh.CompressedSize64 = 0
fh.UncompressedSize = 0
fh.UncompressedSize64 = 0
ow = dirWriter{}
} else {
fh.Flags |= 0x8 // we will write a data descriptor
@ -419,7 +425,10 @@ func (w *Writer) compressor(method uint16) Compressor {
type dirWriter struct{}
func (dirWriter) Write([]byte) (int, error) {
func (dirWriter) Write(b []byte) (int, error) {
if len(b) == 0 {
return 0, nil
}
return 0, errors.New("zip: write to directory")
}

View file

@ -306,21 +306,28 @@ func TestWriterDir(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if _, err := dw.Write(nil); err != nil {
t.Errorf("Write(nil) to directory: got %v, want nil", err)
}
if _, err := dw.Write([]byte("hello")); err == nil {
t.Error("Write to directory: got nil error, want non-nil")
t.Error(`Write("hello") to directory: got nil error, want non-nil`)
}
}
func TestWriterDirAttributes(t *testing.T) {
var buf bytes.Buffer
w := NewWriter(&buf)
if _, err := w.Create("dir/"); err != nil {
if _, err := w.CreateHeader(&FileHeader{
Name: "dir/",
Method: Deflate,
CompressedSize64: 1234,
UncompressedSize64: 5678,
}); err != nil {
t.Fatal(err)
}
if err := w.Close(); err != nil {
t.Fatal(err)
}
b := buf.Bytes()
var sig [4]byte

View file

@ -63,7 +63,7 @@ func NewReader(rd io.Reader) *Reader {
}
// Size returns the size of the underlying buffer in bytes.
func (r *Reader) Size() int { return len(r.buf) }
func (b *Reader) Size() int { return len(b.buf) }
// Reset discards any buffered data, resets all state, and switches
// the buffered reader to read from r.
@ -314,9 +314,11 @@ func (b *Reader) Buffered() int { return b.w - b.r }
// ReadBytes or ReadString instead.
// ReadSlice returns err != nil if and only if line does not end in delim.
func (b *Reader) ReadSlice(delim byte) (line []byte, err error) {
s := 0 // search start index
for {
// Search buffer.
if i := bytes.IndexByte(b.buf[b.r:b.w], delim); i >= 0 {
if i := bytes.IndexByte(b.buf[b.r+s:b.w], delim); i >= 0 {
i += s
line = b.buf[b.r : b.r+i+1]
b.r += i + 1
break
@ -338,6 +340,8 @@ func (b *Reader) ReadSlice(delim byte) (line []byte, err error) {
break
}
s = b.w - b.r // do not rescan area we scanned before
b.fill() // buffer is not full
}

View file

@ -441,9 +441,9 @@ func (b *Buffer) ReadString(delim byte) (line string, err error) {
// NewBuffer creates and initializes a new Buffer using buf as its
// initial contents. The new Buffer takes ownership of buf, and the
// caller should not use buf after this call. NewBuffer is intended to
// prepare a Buffer to read existing data. It can also be used to size
// the internal buffer for writing. To do that, buf should have the
// desired capacity but a length of zero.
// prepare a Buffer to read existing data. It can also be used to set
// the initial size of the internal buffer for writing. To do that,
// buf should have the desired capacity but a length of zero.
//
// In most cases, new(Buffer) (or just declaring a Buffer variable) is
// sufficient to initialize a Buffer.

View file

@ -293,7 +293,7 @@ func TestReadFromPanicReader(t *testing.T) {
}
check(t, "TestReadFromPanicReader (1)", &buf, "")
// Confirm that when Reader panics, the emtpy buffer remains empty
// Confirm that when Reader panics, the empty buffer remains empty
var buf2 Buffer
defer func() {
recover()

View file

@ -489,19 +489,19 @@ func ToTitle(s []byte) []byte { return Map(unicode.ToTitle, s) }
// ToUpperSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
// upper case, giving priority to the special casing rules.
func ToUpperSpecial(c unicode.SpecialCase, s []byte) []byte {
return Map(func(r rune) rune { return c.ToUpper(r) }, s)
return Map(c.ToUpper, s)
}
// ToLowerSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
// lower case, giving priority to the special casing rules.
func ToLowerSpecial(c unicode.SpecialCase, s []byte) []byte {
return Map(func(r rune) rune { return c.ToLower(r) }, s)
return Map(c.ToLower, s)
}
// ToTitleSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
// title case, giving priority to the special casing rules.
func ToTitleSpecial(c unicode.SpecialCase, s []byte) []byte {
return Map(func(r rune) rune { return c.ToTitle(r) }, s)
return Map(c.ToTitle, s)
}
// isSeparator reports whether the rune could mark a word boundary.

View file

@ -6,6 +6,7 @@ package bytes_test
import (
. "bytes"
"internal/testenv"
"testing"
)
@ -58,10 +59,20 @@ func TestCompareIdenticalSlice(t *testing.T) {
}
func TestCompareBytes(t *testing.T) {
n := 128
lengths := make([]int, 0) // lengths to test in ascending order
for i := 0; i <= 128; i++ {
lengths = append(lengths, i)
}
lengths = append(lengths, 256, 512, 1024, 1333, 4095, 4096, 4097)
if !testing.Short() || testenv.Builder() != "" {
lengths = append(lengths, 65535, 65536, 65537, 99999)
}
n := lengths[len(lengths)-1]
a := make([]byte, n+1)
b := make([]byte, n+1)
for len := 0; len < 128; len++ {
for _, len := range lengths {
// randomish but deterministic data. No 0 or 255.
for i := 0; i < len; i++ {
a[i] = byte(1 + 31*i%254)

View file

@ -39,6 +39,14 @@ func ExampleBuffer_Grow() {
// Output: "64 bytes or fewer"
}
func ExampleBuffer_Len() {
var b bytes.Buffer
b.Grow(64)
b.Write([]byte("abcde"))
fmt.Printf("%d", b.Len())
// Output: 5
}
func ExampleCompare() {
// Interpret Compare's result by comparing it to zero.
var a, b []byte

View file

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package arch defines architecture-specific information and support functions.
package arch
import (

View file

@ -74,11 +74,12 @@ func IsARM64STLXR(op obj.As) bool {
arm64.ASTXRB, arm64.ASTXRH, arm64.ASTXRW, arm64.ASTXR,
arm64.ASTXP, arm64.ASTXPW, arm64.ASTLXP, arm64.ASTLXPW,
arm64.ASWPB, arm64.ASWPH, arm64.ASWPW, arm64.ASWPD,
arm64.ASWPALB, arm64.ASWPALH, arm64.ASWPALW, arm64.ASWPALD,
arm64.ALDADDB, arm64.ALDADDH, arm64.ALDADDW, arm64.ALDADDD,
arm64.ALDANDB, arm64.ALDANDH, arm64.ALDANDW, arm64.ALDANDD,
arm64.ALDEORB, arm64.ALDEORH, arm64.ALDEORW, arm64.ALDEORD,
arm64.ALDORB, arm64.ALDORH, arm64.ALDORW, arm64.ALDORD,
arm64.ALDADDALD, arm64.ALDADDALW:
arm64.ALDADDALD, arm64.ALDADDALW, arm64.ALDADDALH, arm64.ALDADDALB:
return true
}
return false

View file

@ -137,7 +137,7 @@ func (p *Parser) asmText(operands [][]lex.Token) {
// Bizarre syntax: $frameSize-argSize is two words, not subtraction.
// Both frameSize and argSize must be simple integers; only frameSize
// can be negative.
// The "-argSize" may be missing; if so, set it to obj.ArgsSizeUnknown.
// The "-argSize" may be missing; if so, set it to objabi.ArgsSizeUnknown.
// Parse left to right.
op := operands[next]
if len(op) < 2 || op[0].ScanToken != '$' {

View file

@ -33,7 +33,7 @@ func newParser(goarch string) *Parser {
// tryParse executes parse func in panicOnError=true context.
// parse is expected to call any parsing methods that may panic.
// Returns error gathered from recover; nil if no parse errors occured.
// Returns error gathered from recover; nil if no parse errors occurred.
//
// For unexpected panics, calls t.Fatal.
func tryParse(t *testing.T, parse func()) (err error) {

View file

@ -911,7 +911,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
VADDPD.BCST.Z (AX), Z2, K1, Z1 // 62f1edd95808
VMAXPD.BCST (AX), Z2, K1, Z1 // 62f1ed595f08
VMAXPD.BCST.Z (AX), Z2, K1, Z1 // 62f1edd95f08
// EVEX: surpress all exceptions (SAE).
// EVEX: suppress all exceptions (SAE).
VMAXPD.SAE Z3, Z2, K1, Z1 // 62f1ed595fcb or 62f1ed195fcb
VMAXPD.SAE.Z Z3, Z2, K1, Z1 // 62f1edd95fcb or 62f1ed995fcb
VMAXPD (AX), Z2, K1, Z1 // 62f1ed495f08

View file

@ -163,6 +163,21 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
MOVB (R29)(R30<<0), R14 // ae7bbe38
MOVB (R29)(R30), R14 // MOVB (R29)(R30*1), R14 // ae6bbe38
MOVB R4, (R2)(R6.SXTX) // 44e82638
FMOVS $(4.0), F0 // 0010221e
FMOVD $(4.0), F0 // 0010621e
FMOVS $(0.265625), F1 // 01302a1e
FMOVD $(0.1796875), F2 // 02f0681e
FMOVS $(0.96875), F3 // 03f02d1e
FMOVD $(28.0), F4 // 0490671e
FMOVS (R2)(R6), F4 // FMOVS (R2)(R6*1), F4 // 446866bc
FMOVS (R2)(R6<<2), F4 // 447866bc
FMOVD (R2)(R6), F4 // FMOVD (R2)(R6*1), F4 // 446866fc
FMOVD (R2)(R6<<3), F4 // 447866fc
FMOVS F4, (R2)(R6) // FMOVS F4, (R2)(R6*1) // 446826bc
FMOVS F4, (R2)(R6<<2) // 447826bc
FMOVD F4, (R2)(R6) // FMOVD F4, (R2)(R6*1) // 446826fc
FMOVD F4, (R2)(R6<<3) // 447826fc
// LTYPE1 imsr ',' spreg ','
// {
@ -470,14 +485,14 @@ again:
// {
// outcode($1, &$2, NREG, &$4);
// }
FADDD $0.5, F1 // FADDD $(0.5), F1
// FADDD $0.5, F1 // FADDD $(0.5), F1
FADDD F1, F2
// LTYPEK frcon ',' freg ',' freg
// {
// outcode($1, &$2, $4.reg, &$6);
// }
FADDD $0.7, F1, F2 // FADDD $(0.69999999999999996), F1, F2
// FADDD $0.7, F1, F2 // FADDD $(0.69999999999999996), F1, F2
FADDD F1, F2, F3
//
@ -572,6 +587,14 @@ again:
SWPH R5, (RSP), R7 // e7832578
SWPB R5, (R6), R7 // c7802538
SWPB R5, (RSP), R7 // e7832538
SWPALD R5, (R6), R7 // c780e5f8
SWPALD R5, (RSP), R7 // e783e5f8
SWPALW R5, (R6), R7 // c780e5b8
SWPALW R5, (RSP), R7 // e783e5b8
SWPALH R5, (R6), R7 // c780e578
SWPALH R5, (RSP), R7 // e783e578
SWPALB R5, (R6), R7 // c780e538
SWPALB R5, (RSP), R7 // e783e538
LDADDD R5, (R6), R7 // c70025f8
LDADDD R5, (RSP), R7 // e70325f8
LDADDW R5, (R6), R7 // c70025b8
@ -605,7 +628,9 @@ again:
LDORB R5, (R6), R7 // c7302538
LDORB R5, (RSP), R7 // e7332538
LDADDALD R2, (R1), R3 // 2300e2f8
LDADDALW R5, (R4), R6 // 8600e5b8
LDADDALW R2, (R1), R3 // 2300e2b8
LDADDALH R2, (R1), R3 // 2300e278
LDADDALB R2, (R1), R3 // 2300e238
// RET
//
@ -716,6 +741,86 @@ again:
STPW (R3, R4), x(SB)
STPW (R3, R4), x+8(SB)
// bit field operation
BFI $0, R1, $1, R2 // 220040b3
BFIW $0, R1, $1, R2 // 22000033
SBFIZ $0, R1, $1, R2 // 22004093
SBFIZW $0, R1, $1, R2 // 22000013
UBFIZ $0, R1, $1, R2 // 220040d3
UBFIZW $0, R1, $1, R2 // 22000053
// FSTPD/FSTPS/FLDPD/FLDPS
FLDPD (R0), (F1, F2) // 0108406d
FLDPD 8(R0), (F1, F2) // 0188406d
FLDPD -8(R0), (F1, F2) // 01887f6d
FLDPD 11(R0), (F1, F2) // 1b2c0091610b406d
FLDPD 1024(R0), (F1, F2) // 1b001091610b406d
FLDPD.W 8(R0), (F1, F2) // 0188c06d
FLDPD.P 8(R0), (F1, F2) // 0188c06c
FLDPD (RSP), (F1, F2) // e10b406d
FLDPD 8(RSP), (F1, F2) // e18b406d
FLDPD -8(RSP), (F1, F2) // e18b7f6d
FLDPD 11(RSP), (F1, F2) // fb2f0091610b406d
FLDPD 1024(RSP), (F1, F2) // fb031091610b406d
FLDPD.W 8(RSP), (F1, F2) // e18bc06d
FLDPD.P 8(RSP), (F1, F2) // e18bc06c
FLDPD -31(R0), (F1, F2) // 1b7c00d1610b406d
FLDPD -4(R0), (F1, F2) // 1b1000d1610b406d
FLDPD -8(R0), (F1, F2) // 01887f6d
FLDPD x(SB), (F1, F2)
FLDPD x+8(SB), (F1, F2)
FLDPS -5(R0), (F1, F2) // 1b1400d1610b402d
FLDPS (R0), (F1, F2) // 0108402d
FLDPS 4(R0), (F1, F2) // 0188402d
FLDPS -4(R0), (F1, F2) // 01887f2d
FLDPS.W 4(R0), (F1, F2) // 0188c02d
FLDPS.P 4(R0), (F1, F2) // 0188c02c
FLDPS 11(R0), (F1, F2) // 1b2c0091610b402d
FLDPS 1024(R0), (F1, F2) // 1b001091610b402d
FLDPS (RSP), (F1, F2) // e10b402d
FLDPS 4(RSP), (F1, F2) // e18b402d
FLDPS -4(RSP), (F1, F2) // e18b7f2d
FLDPS.W 4(RSP), (F1, F2) // e18bc02d
FLDPS.P 4(RSP), (F1, F2) // e18bc02c
FLDPS 11(RSP), (F1, F2) // fb2f0091610b402d
FLDPS 1024(RSP), (F1, F2) // fb031091610b402d
FLDPS x(SB), (F1, F2)
FLDPS x+8(SB), (F1, F2)
FSTPD (F3, F4), (R5) // a310006d
FSTPD (F3, F4), 8(R5) // a390006d
FSTPD.W (F3, F4), 8(R5) // a390806d
FSTPD.P (F3, F4), 8(R5) // a390806c
FSTPD (F3, F4), -8(R5) // a3903f6d
FSTPD (F3, F4), -4(R5) // bb1000d16313006d
FSTPD (F3, F4), 11(R0) // 1b2c00916313006d
FSTPD (F3, F4), 1024(R0) // 1b0010916313006d
FSTPD (F3, F4), (RSP) // e313006d
FSTPD (F3, F4), 8(RSP) // e393006d
FSTPD.W (F3, F4), 8(RSP) // e393806d
FSTPD.P (F3, F4), 8(RSP) // e393806c
FSTPD (F3, F4), -8(RSP) // e3933f6d
FSTPD (F3, F4), 11(RSP) // fb2f00916313006d
FSTPD (F3, F4), 1024(RSP) // fb0310916313006d
FSTPD (F3, F4), x(SB)
FSTPD (F3, F4), x+8(SB)
FSTPS (F3, F4), (R5) // a310002d
FSTPS (F3, F4), 4(R5) // a390002d
FSTPS.W (F3, F4), 4(R5) // a390802d
FSTPS.P (F3, F4), 4(R5) // a390802c
FSTPS (F3, F4), -4(R5) // a3903f2d
FSTPS (F3, F4), -5(R5) // bb1400d16313002d
FSTPS (F3, F4), 11(R0) // 1b2c00916313002d
FSTPS (F3, F4), 1024(R0) // 1b0010916313002d
FSTPS (F3, F4), (RSP) // e313002d
FSTPS (F3, F4), 4(RSP) // e393002d
FSTPS.W (F3, F4), 4(RSP) // e393802d
FSTPS.P (F3, F4), 4(RSP) // e393802c
FSTPS (F3, F4), -4(RSP) // e3933f2d
FSTPS (F3, F4), 11(RSP) // fb2f00916313002d
FSTPS (F3, F4), 1024(RSP) // fb0310916313002d
FSTPS (F3, F4), x(SB)
FSTPS (F3, F4), x+8(SB)
// END
//
// LTYPEE comma

View file

@ -89,4 +89,9 @@ TEXT errors(SB),$0
CSEL LT, R1, R2 // ERROR "illegal combination"
AND $0x22220000, R2, RSP // ERROR "illegal combination"
ANDS $0x22220000, R2, RSP // ERROR "illegal combination"
LDP (R0), (F0, F1) // ERROR "invalid register pair"
LDP (R0), (R3, ZR) // ERROR "invalid register pair"
STP (F2, F3), (R0) // ERROR "invalid register pair"
FLDPD (R0), (R1, R2) // ERROR "invalid register pair"
FSTPD (R1, R2), (R0) // ERROR "invalid register pair"
RET

View file

@ -115,6 +115,7 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
NEGW R1 // b9130011
NEGW R1, R2 // b9130021
FLOGR R2, R2 // b9830022
POPCNT R3, R4 // b9e10043
AND R1, R2 // b9800021
AND R1, R2, R3 // b9e42031

View file

@ -95,7 +95,7 @@ func (f *File) ParseGo(name string, src []byte) {
}
}
if !sawC {
error_(token.NoPos, `cannot find import "C"`)
error_(ast1.Package, `cannot find import "C"`)
}
// In ast2, strip the import "C" line.

View file

@ -104,10 +104,13 @@ compiled with the C compiler. Any .cc, .cpp, or .cxx files will be
compiled with the C++ compiler. Any .f, .F, .for or .f90 files will be
compiled with the fortran compiler. Any .h, .hh, .hpp, or .hxx files will
not be compiled separately, but, if these header files are changed,
the C and C++ files will be recompiled. The default C and C++
compilers may be changed by the CC and CXX environment variables,
respectively; those environment variables may include command line
options.
the package (including its non-Go source files) will be recompiled.
Note that changes to files in other directories do not cause the package
to be recompiled, so all non-Go source code for the package should be
stored in the package directory, not in subdirectories.
The default C and C++ compilers may be changed by the CC and CXX
environment variables, respectively; those environment variables
may include command line options.
The cgo tool is enabled by default for native builds on systems where
it is expected to work. It is disabled by default when
@ -377,6 +380,14 @@ and of course there is nothing stopping the C code from doing anything
it likes. However, programs that break these rules are likely to fail
in unexpected and unpredictable ways.
Note: the current implementation has a bug. While Go code is permitted
to write nil or a C pointer (but not a Go pointer) to C memory, the
current implementation may sometimes cause a runtime error if the
contents of the C memory appear to be a Go pointer. Therefore, avoid
passing uninitialized C memory to Go code if the Go code is going to
store pointer values in it. Zero out the memory in C before passing it
to Go.
Special cases
A few special C types which would normally be represented by a pointer

View file

@ -164,9 +164,29 @@ func (p *Package) Translate(f *File) {
cref.Name.C = cname(cref.Name.Go)
}
p.loadDefines(f)
needType := p.guessKinds(f)
if len(needType) > 0 {
p.loadDWARF(f, needType)
p.typedefs = map[string]bool{}
p.typedefList = nil
numTypedefs := -1
for len(p.typedefs) > numTypedefs {
numTypedefs = len(p.typedefs)
// Also ask about any typedefs we've seen so far.
for _, a := range p.typedefList {
f.Name[a] = &Name{
Go: a,
C: a,
}
}
needType := p.guessKinds(f)
if len(needType) > 0 {
p.loadDWARF(f, needType)
}
// In godefs mode we're OK with the typedefs, which
// will presumably also be defined in the file, we
// don't want to resolve them to their base types.
if *godefs {
break
}
}
if p.rewriteCalls(f) {
// Add `import _cgo_unsafe "unsafe"` after the package statement.
@ -551,6 +571,7 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
fatalf("malformed __cgo__ name: %s", name)
}
types[i] = t.Type
p.recordTypedefs(t.Type)
}
if e.Tag != dwarf.TagCompileUnit {
r.SkipChildren()
@ -586,7 +607,25 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
}
}
case "fconst":
if i < len(floats) {
if i >= len(floats) {
break
}
switch base(types[i]).(type) {
case *dwarf.IntType, *dwarf.UintType:
// This has an integer type so it's
// not really a floating point
// constant. This can happen when the
// C compiler complains about using
// the value as an integer constant,
// but not as a general constant.
// Treat this as a variable of the
// appropriate type, not a constant,
// to get C-style type handling,
// avoiding the problem that C permits
// uint64(-1) but Go does not.
// See issue 26066.
n.Kind = "var"
default:
n.Const = fmt.Sprintf("%f", floats[i])
}
case "sconst":
@ -599,6 +638,47 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
}
}
// recordTypedefs remembers in p.typedefs all the typedefs used in dtypes and its children.
func (p *Package) recordTypedefs(dtype dwarf.Type) {
p.recordTypedefs1(dtype, map[dwarf.Type]bool{})
}
func (p *Package) recordTypedefs1(dtype dwarf.Type, visited map[dwarf.Type]bool) {
if dtype == nil {
return
}
if visited[dtype] {
return
}
visited[dtype] = true
switch dt := dtype.(type) {
case *dwarf.TypedefType:
if strings.HasPrefix(dt.Name, "__builtin") {
// Don't look inside builtin types. There be dragons.
return
}
if !p.typedefs[dt.Name] {
p.typedefs[dt.Name] = true
p.typedefList = append(p.typedefList, dt.Name)
p.recordTypedefs1(dt.Type, visited)
}
case *dwarf.PtrType:
p.recordTypedefs1(dt.Type, visited)
case *dwarf.ArrayType:
p.recordTypedefs1(dt.Type, visited)
case *dwarf.QualType:
p.recordTypedefs1(dt.Type, visited)
case *dwarf.FuncType:
p.recordTypedefs1(dt.ReturnType, visited)
for _, a := range dt.ParamType {
p.recordTypedefs1(a, visited)
}
case *dwarf.StructType:
for _, f := range dt.Field {
p.recordTypedefs1(f.Type, visited)
}
}
}
// mangleName does name mangling to translate names
// from the original Go source files to the names
// used in the final Go files generated by cgo.
@ -1613,6 +1693,9 @@ func (p *Package) gccErrors(stdin []byte) string {
}
}
// Force -O0 optimization
nargs = append(nargs, "-O0")
if *debugGcc {
fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(nargs, " "))
os.Stderr.Write(stdin)
@ -1659,6 +1742,7 @@ type typeConv struct {
// Map from types to incomplete pointers to those types.
ptrs map[dwarf.Type][]*Type
// Keys of ptrs in insertion order (deterministic worklist)
// ptrKeys contains exactly the keys in ptrs.
ptrKeys []dwarf.Type
// Type names X for which there exists an XGetTypeID function with type func() CFTypeID.
@ -1801,14 +1885,15 @@ func (c *typeConv) FinishType(pos token.Pos) {
for len(c.ptrKeys) > 0 {
dtype := c.ptrKeys[0]
c.ptrKeys = c.ptrKeys[1:]
ptrs := c.ptrs[dtype]
delete(c.ptrs, dtype)
// Note Type might invalidate c.ptrs[dtype].
t := c.Type(dtype, pos)
for _, ptr := range c.ptrs[dtype] {
for _, ptr := range ptrs {
ptr.Go.(*ast.StarExpr).X = t.Go
ptr.C.Set("%s*", t.C)
}
c.ptrs[dtype] = nil // retain the map key
}
}
@ -2085,6 +2170,10 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
s := *sub
s.Go = c.uintptr
sub = &s
// Make sure we update any previously computed type.
if oldType := typedef[name.Name]; oldType != nil {
oldType.Go = sub.Go
}
}
t.Go = name
if unionWithPointer[sub.Go] {
@ -2246,7 +2335,7 @@ func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
}
// ...or the typedef is one in which we expect bad pointers.
// It will be a uintptr instead of *X.
if c.badPointerTypedef(dt) {
if c.baseBadPointerTypedef(dt) {
break
}
@ -2598,6 +2687,19 @@ func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
return false
}
// baseBadPointerTypedef reports whether the base of a chain of typedefs is a bad typedef
// as badPointerTypedef reports.
func (c *typeConv) baseBadPointerTypedef(dt *dwarf.TypedefType) bool {
for {
if t, ok := dt.Type.(*dwarf.TypedefType); ok {
dt = t
continue
}
break
}
return c.badPointerTypedef(dt)
}
func (c *typeConv) badCFType(dt *dwarf.TypedefType) bool {
// The real bad types are CFNumberRef and CFDateRef.
// Sometimes non-pointers are stored in these types.
@ -2686,13 +2788,31 @@ func (c *typeConv) badJNI(dt *dwarf.TypedefType) bool {
}
}
// Check that the typedef is:
// struct _jobject;
// typedef struct _jobject *jobject;
// Check that the typedef is either:
// 1:
// struct _jobject;
// typedef struct _jobject *jobject;
// 2: (in NDK16 in C++)
// class _jobject {};
// typedef _jobject* jobject;
// 3: (in NDK16 in C)
// typedef void* jobject;
if ptr, ok := w.Type.(*dwarf.PtrType); ok {
if str, ok := ptr.Type.(*dwarf.StructType); ok {
if str.StructName == "_jobject" && str.Kind == "struct" && len(str.Field) == 0 && str.Incomplete {
return true
switch v := ptr.Type.(type) {
case *dwarf.VoidType:
return true
case *dwarf.StructType:
if v.StructName == "_jobject" && len(v.Field) == 0 {
switch v.Kind {
case "struct":
if v.Incomplete {
return true
}
case "class":
if !v.Incomplete {
return true
}
}
}
}
}

View file

@ -43,9 +43,11 @@ type Package struct {
Name map[string]*Name // accumulated Name from Files
ExpFunc []*ExpFunc // accumulated ExpFunc from Files
Decl []ast.Decl
GoFiles []string // list of Go files
GccFiles []string // list of gcc output files
Preamble string // collected preamble for _cgo_export.h
GoFiles []string // list of Go files
GccFiles []string // list of gcc output files
Preamble string // collected preamble for _cgo_export.h
typedefs map[string]bool // type names that appear in the types of the objects we're interested in
typedefList []string
}
// A File collects information about a single Go input file.
@ -261,6 +263,9 @@ func main() {
if arg == "-fsanitize=thread" {
tsanProlog = yesTsanProlog
}
if arg == "-fsanitize=memory" {
msanProlog = yesMsanProlog
}
}
p := newPackage(args[:i])
@ -394,6 +399,14 @@ func (p *Package) Record(f *File) {
for k, v := range f.Name {
if p.Name[k] == nil {
p.Name[k] = v
} else if p.incompleteTypedef(p.Name[k].Type) {
p.Name[k] = v
} else if p.incompleteTypedef(v.Type) {
// Nothing to do.
} else if _, ok := nameToC[k]; ok {
// Names we predefine may appear inconsistent
// if some files typedef them and some don't.
// Issue 26743.
} else if !reflect.DeepEqual(p.Name[k], v) {
error_(token.NoPos, "inconsistent definitions for C.%s", fixGo(k))
}
@ -406,3 +419,9 @@ func (p *Package) Record(f *File) {
}
p.Decl = append(p.Decl, f.AST.Decls...)
}
// incompleteTypedef reports whether t appears to be an incomplete
// typedef definition.
func (p *Package) incompleteTypedef(t *Type) bool {
return t == nil || (t.Size == 0 && t.Align == -1)
}

View file

@ -272,10 +272,7 @@ func dynimport(obj string) {
}
}
}
sym, err := f.ImportedSymbols()
if err != nil {
fatalf("cannot load imported symbols from ELF file %s: %v", obj, err)
}
sym, _ := f.ImportedSymbols()
for _, s := range sym {
targ := s.Name
if s.Version != "" {
@ -283,10 +280,7 @@ func dynimport(obj string) {
}
fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", s.Name, targ, s.Library)
}
lib, err := f.ImportedLibraries()
if err != nil {
fatalf("cannot load imported libraries from ELF file %s: %v", obj, err)
}
lib, _ := f.ImportedLibraries()
for _, l := range lib {
fmt.Fprintf(stdout, "//go:cgo_import_dynamic _ _ %q\n", l)
}
@ -294,20 +288,14 @@ func dynimport(obj string) {
}
if f, err := macho.Open(obj); err == nil {
sym, err := f.ImportedSymbols()
if err != nil {
fatalf("cannot load imported symbols from Mach-O file %s: %v", obj, err)
}
sym, _ := f.ImportedSymbols()
for _, s := range sym {
if len(s) > 0 && s[0] == '_' {
s = s[1:]
}
fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", s, s, "")
}
lib, err := f.ImportedLibraries()
if err != nil {
fatalf("cannot load imported libraries from Mach-O file %s: %v", obj, err)
}
lib, _ := f.ImportedLibraries()
for _, l := range lib {
fmt.Fprintf(stdout, "//go:cgo_import_dynamic _ _ %q\n", l)
}
@ -315,10 +303,7 @@ func dynimport(obj string) {
}
if f, err := pe.Open(obj); err == nil {
sym, err := f.ImportedSymbols()
if err != nil {
fatalf("cannot load imported symbols from PE file %s: %v", obj, err)
}
sym, _ := f.ImportedSymbols()
for _, s := range sym {
ss := strings.Split(s, ":")
name := strings.Split(ss[0], "@")[0]
@ -537,7 +522,7 @@ func (p *Package) writeOutput(f *File, srcfile string) {
// Write Go output: Go input with rewrites of C.xxx to _C_xxx.
fmt.Fprintf(fgo1, "// Code generated by cmd/cgo; DO NOT EDIT.\n\n")
fmt.Fprintf(fgo1, "//line %s:1\n", srcfile)
fmt.Fprintf(fgo1, "//line %s:1:1\n", srcfile)
fgo1.Write(f.Edit.Bytes())
// While we process the vars and funcs, also write gcc output.
@ -546,6 +531,7 @@ func (p *Package) writeOutput(f *File, srcfile string) {
fmt.Fprintf(fgcc, "%s\n", f.Preamble)
fmt.Fprintf(fgcc, "%s\n", gccProlog)
fmt.Fprintf(fgcc, "%s\n", tsanProlog)
fmt.Fprintf(fgcc, "%s\n", msanProlog)
for _, key := range nameKeys(f.Name) {
n := f.Name[key]
@ -651,6 +637,16 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
fmt.Fprintf(fgcc, "\t_cgo_a = (void*)((char*)_cgo_a + (_cgo_topofstack() - _cgo_stktop));\n")
// Save the return value.
fmt.Fprintf(fgcc, "\t_cgo_a->r = _cgo_r;\n")
// The return value is on the Go stack. If we are using msan,
// and if the C value is partially or completely uninitialized,
// the assignment will mark the Go stack as uninitialized.
// The Go compiler does not update msan for changes to the
// stack. It is possible that the stack will remain
// uninitialized, and then later be used in a way that is
// visible to msan, possibly leading to a false positive.
// Mark the stack space as written, to avoid this problem.
// See issue 26209.
fmt.Fprintf(fgcc, "\t_cgo_msan_write(&_cgo_a->r, sizeof(_cgo_a->r));\n")
}
if n.AddError {
fmt.Fprintf(fgcc, "\treturn _cgo_errno;\n")
@ -749,6 +745,7 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) {
fmt.Fprintf(fgcc, "extern void _cgo_release_context(__SIZE_TYPE__);\n\n")
fmt.Fprintf(fgcc, "extern char* _cgo_topofstack(void);")
fmt.Fprintf(fgcc, "%s\n", tsanProlog)
fmt.Fprintf(fgcc, "%s\n", msanProlog)
for _, exp := range p.ExpFunc {
fn := exp.Func
@ -986,6 +983,7 @@ func (p *Package) writeGccgoExports(fgo2, fm, fgcc, fgcch io.Writer) {
fmt.Fprintf(fgcc, "%s\n", gccgoExportFileProlog)
fmt.Fprintf(fgcc, "%s\n", tsanProlog)
fmt.Fprintf(fgcc, "%s\n", msanProlog)
for _, exp := range p.ExpFunc {
fn := exp.Func
@ -1398,6 +1396,25 @@ static void _cgo_tsan_release() {
// Set to yesTsanProlog if we see -fsanitize=thread in the flags for gcc.
var tsanProlog = noTsanProlog
// noMsanProlog is a prologue defining an MSAN function in C.
// This is used when not compiling with -fsanitize=memory.
const noMsanProlog = `
#define _cgo_msan_write(addr, sz)
`
// yesMsanProlog is a prologue defining an MSAN function in C.
// This is used when compiling with -fsanitize=memory.
// See the comment above where _cgo_msan_write is called.
const yesMsanProlog = `
extern void __msan_unpoison(const volatile void *, size_t);
#define _cgo_msan_write(addr, sz) __msan_unpoison((addr), (sz))
`
// msanProlog is set to yesMsanProlog if we see -fsanitize=memory in the flags
// for the C compiler.
var msanProlog = noMsanProlog
const builtinProlog = `
#line 1 "cgo-builtin-prolog"
#include <stddef.h> /* for ptrdiff_t and size_t below */
@ -1415,7 +1432,7 @@ void *CBytes(_GoBytes_);
void *_CMalloc(size_t);
__attribute__ ((unused))
static size_t _GoStringLen(_GoString_ s) { return s.n; }
static size_t _GoStringLen(_GoString_ s) { return (size_t)s.n; }
__attribute__ ((unused))
static const char *_GoStringPtr(_GoString_ s) { return s.p; }

View file

@ -59,6 +59,8 @@ func run(stdin []byte, argv []string) (stdout, stderr []byte, ok bool) {
var bout, berr bytes.Buffer
p.Stdout = &bout
p.Stderr = &berr
// Disable escape codes in clang error messages.
p.Env = append(os.Environ(), "TERM=dumb")
err := p.Run()
if _, ok := err.(*exec.ExitError); err != nil && !ok {
fatalf("%s", err)
@ -97,6 +99,8 @@ func error_(pos token.Pos, msg string, args ...interface{}) {
nerrors++
if pos.IsValid() {
fmt.Fprintf(os.Stderr, "%s: ", fset.Position(pos).String())
} else {
fmt.Fprintf(os.Stderr, "cgo: ")
}
fmt.Fprintf(os.Stderr, msg, args...)
fmt.Fprintf(os.Stderr, "\n")

View file

@ -1,6 +1,8 @@
<!---
// Copyright 2018 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.
-->
## Introduction to the Go compiler
@ -19,7 +21,7 @@ the `go/*` packages were developed to enable writing tools working with Go code,
such as `gofmt` and `vet`.
It should be clarified that the name "gc" stands for "Go compiler", and has
little to do with uppercase GC, which stands for garbage collection.
little to do with uppercase "GC", which stands for garbage collection.
### 1. Parsing
@ -113,4 +115,4 @@ and debugging information.
### Further reading
To dig deeper into how the SSA package works, including its passes and rules,
head to `cmd/compile/internal/ssa/README.md`.
head to [cmd/compile/internal/ssa/README.md](internal/ssa/README.md).

View file

@ -73,6 +73,9 @@ type File struct {
}
func TestFormats(t *testing.T) {
if testing.Short() {
t.Skip("Skipping in short mode")
}
testenv.MustHaveGoBuild(t) // more restrictive than necessary, but that's ok
// process all directories
@ -721,6 +724,7 @@ var knownFormats = map[string]string{
"uint16 %d": "",
"uint16 %v": "",
"uint16 %x": "",
"uint32 %#x": "",
"uint32 %d": "",
"uint32 %v": "",
"uint32 %x": "",

View file

@ -524,6 +524,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
case ssa.OpAMD64LEAQ1, ssa.OpAMD64LEAQ2, ssa.OpAMD64LEAQ4, ssa.OpAMD64LEAQ8,
ssa.OpAMD64LEAL1, ssa.OpAMD64LEAL2, ssa.OpAMD64LEAL4, ssa.OpAMD64LEAL8,
ssa.OpAMD64LEAW1, ssa.OpAMD64LEAW2, ssa.OpAMD64LEAW4, ssa.OpAMD64LEAW8:
o := v.Reg()
r := v.Args[0].Reg()
i := v.Args[1].Reg()
p := s.Prog(v.Op.Asm())
@ -543,9 +544,24 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.From.Type = obj.TYPE_MEM
p.From.Reg = r
p.From.Index = i
gc.AddAux(&p.From, v)
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
p.To.Reg = o
if v.AuxInt != 0 && v.Aux == nil {
// Emit an additional LEA to add the displacement instead of creating a slow 3 operand LEA.
switch v.Op {
case ssa.OpAMD64LEAQ1, ssa.OpAMD64LEAQ2, ssa.OpAMD64LEAQ4, ssa.OpAMD64LEAQ8:
p = s.Prog(x86.ALEAQ)
case ssa.OpAMD64LEAL1, ssa.OpAMD64LEAL2, ssa.OpAMD64LEAL4, ssa.OpAMD64LEAL8:
p = s.Prog(x86.ALEAL)
case ssa.OpAMD64LEAW1, ssa.OpAMD64LEAW2, ssa.OpAMD64LEAW4, ssa.OpAMD64LEAW8:
p = s.Prog(x86.ALEAW)
}
p.From.Type = obj.TYPE_MEM
p.From.Reg = o
p.To.Type = obj.TYPE_REG
p.To.Reg = o
}
gc.AddAux(&p.From, v)
case ssa.OpAMD64LEAQ, ssa.OpAMD64LEAL, ssa.OpAMD64LEAW:
p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_MEM
@ -683,7 +699,9 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
gc.AddAux(&p.From, v)
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
case ssa.OpAMD64MOVQstore, ssa.OpAMD64MOVSSstore, ssa.OpAMD64MOVSDstore, ssa.OpAMD64MOVLstore, ssa.OpAMD64MOVWstore, ssa.OpAMD64MOVBstore, ssa.OpAMD64MOVOstore:
case ssa.OpAMD64MOVQstore, ssa.OpAMD64MOVSSstore, ssa.OpAMD64MOVSDstore, ssa.OpAMD64MOVLstore, ssa.OpAMD64MOVWstore, ssa.OpAMD64MOVBstore, ssa.OpAMD64MOVOstore,
ssa.OpAMD64ADDQmodify, ssa.OpAMD64SUBQmodify, ssa.OpAMD64ANDQmodify, ssa.OpAMD64ORQmodify, ssa.OpAMD64XORQmodify,
ssa.OpAMD64ADDLmodify, ssa.OpAMD64SUBLmodify, ssa.OpAMD64ANDLmodify, ssa.OpAMD64ORLmodify, ssa.OpAMD64XORLmodify:
p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG
p.From.Reg = v.Args[1].Reg()
@ -754,6 +772,17 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Reg = v.Args[0].Reg()
gc.AddAux2(&p.To, v, off)
}
case ssa.OpAMD64ANDQconstmodify, ssa.OpAMD64ANDLconstmodify, ssa.OpAMD64ORQconstmodify, ssa.OpAMD64ORLconstmodify,
ssa.OpAMD64XORQconstmodify, ssa.OpAMD64XORLconstmodify:
sc := v.AuxValAndOff()
off := sc.Off()
val := sc.Val()
p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST
p.From.Offset = val
p.To.Type = obj.TYPE_MEM
p.To.Reg = v.Args[0].Reg()
gc.AddAux2(&p.To, v, off)
case ssa.OpAMD64MOVQstoreconst, ssa.OpAMD64MOVLstoreconst, ssa.OpAMD64MOVWstoreconst, ssa.OpAMD64MOVBstoreconst:
p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST
@ -810,7 +839,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
case ssa.OpAMD64ADDQload, ssa.OpAMD64ADDLload, ssa.OpAMD64SUBQload, ssa.OpAMD64SUBLload,
ssa.OpAMD64ANDQload, ssa.OpAMD64ANDLload, ssa.OpAMD64ORQload, ssa.OpAMD64ORLload,
ssa.OpAMD64XORQload, ssa.OpAMD64XORLload, ssa.OpAMD64ADDSDload, ssa.OpAMD64ADDSSload,
ssa.OpAMD64SUBSDload, ssa.OpAMD64SUBSSload, ssa.OpAMD64MULSDload, ssa.OpAMD64MULSSload:
ssa.OpAMD64SUBSDload, ssa.OpAMD64SUBSSload, ssa.OpAMD64MULSDload, ssa.OpAMD64MULSSload,
ssa.OpAMD64DIVSDload, ssa.OpAMD64DIVSSload:
p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_MEM
p.From.Reg = v.Args[1].Reg()

View file

@ -14,10 +14,10 @@ import (
var darwin = objabi.GOOS == "darwin"
func padframe(frame int64) int64 {
// arm64 requires that the frame size (not counting saved LR)
// be empty or be 8 mod 16. If not, pad it.
if frame != 0 && frame%16 != 8 {
frame += 8
// arm64 requires that the frame size (not counting saved FP&LR)
// be 16 bytes aligned. If not, pad it.
if frame%16 != 0 {
frame += 16 - (frame % 16)
}
return frame
}

View file

@ -212,7 +212,11 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
ssa.OpARM64FMSUBS,
ssa.OpARM64FMSUBD,
ssa.OpARM64FNMSUBS,
ssa.OpARM64FNMSUBD:
ssa.OpARM64FNMSUBD,
ssa.OpARM64MADD,
ssa.OpARM64MADDW,
ssa.OpARM64MSUB,
ssa.OpARM64MSUBW:
rt := v.Reg()
ra := v.Args[0].Reg()
rm := v.Args[1].Reg()
@ -369,6 +373,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
ssa.OpARM64MOVWloadidx,
ssa.OpARM64MOVWUloadidx,
ssa.OpARM64MOVDloadidx,
ssa.OpARM64FMOVSloadidx,
ssa.OpARM64FMOVDloadidx,
ssa.OpARM64MOVHloadidx2,
ssa.OpARM64MOVHUloadidx2,
ssa.OpARM64MOVWloadidx4,
@ -404,6 +410,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
ssa.OpARM64MOVHstoreidx,
ssa.OpARM64MOVWstoreidx,
ssa.OpARM64MOVDstoreidx,
ssa.OpARM64FMOVSstoreidx,
ssa.OpARM64FMOVDstoreidx,
ssa.OpARM64MOVHstoreidx2,
ssa.OpARM64MOVWstoreidx4,
ssa.OpARM64MOVDstoreidx8:

View file

@ -464,19 +464,22 @@ func (p *exporter) markType(t *types.Type) {
}
// Recursively mark any types that can be produced given a
// value of type t: dereferencing a pointer; indexing an
// array, slice, or map; receiving from a channel; accessing a
// struct field or interface method; or calling a function.
// value of type t: dereferencing a pointer; indexing or
// iterating over an array, slice, or map; receiving from a
// channel; accessing a struct field or interface method; or
// calling a function.
//
// Notably, we don't mark map key or function parameter types,
// because the user already needs some way to construct values
// of those types.
//
// It's not critical for correctness that this algorithm is
// perfect. Worst case, we might miss opportunities to inline
// some function calls in downstream packages.
// Notably, we don't mark function parameter types, because
// the user already needs some way to construct values of
// those types.
switch t.Etype {
case TPTR32, TPTR64, TARRAY, TSLICE, TCHAN, TMAP:
case TPTR32, TPTR64, TARRAY, TSLICE, TCHAN:
// TODO(mdempsky): Skip marking element type for
// send-only channels?
p.markType(t.Elem())
case TMAP:
p.markType(t.Key())
p.markType(t.Elem())
case TSTRUCT:

View file

@ -227,17 +227,6 @@ type bvecSet struct {
uniq []bvec // unique bvecs, in insertion order
}
func newBvecSet(size int) bvecSet {
// bvecSet is a linear probing hash table.
// The hash table has 4n entries to keep the linear
// scan short.
index := make([]int, size*4)
for i := range index {
index[i] = -1
}
return bvecSet{index, nil}
}
func (m *bvecSet) grow() {
// Allocate new index.
n := len(m.index) * 2

View file

@ -382,10 +382,7 @@ func walkclosure(clo *Node, init *Nodes) *Node {
clos.List.Set(append([]*Node{nod(OCFUNC, xfunc.Func.Nname, nil)}, clo.Func.Enter.Slice()...))
// Force type conversion from *struct to the func type.
clos = nod(OCONVNOP, clos, nil)
clos.Type = clo.Type
clos = typecheck(clos, Erv)
clos = convnop(clos, clo.Type)
// typecheck will insert a PTRLIT node under CONVNOP,
// tag it with escape analysis result.
@ -511,10 +508,7 @@ func walkpartialcall(n *Node, init *Nodes) *Node {
clos.List.Append(n.Left)
// Force type conversion from *struct to the func type.
clos = nod(OCONVNOP, clos, nil)
clos.Type = n.Type
clos = typecheck(clos, Erv)
clos = convnop(clos, n.Type)
// typecheck will insert a PTRLIT node under CONVNOP,
// tag it with escape analysis result.

View file

@ -121,6 +121,17 @@ func (n *Node) Int64() int64 {
return n.Val().U.(*Mpint).Int64()
}
// CanInt64 reports whether it is safe to call Int64() on n.
func (n *Node) CanInt64() bool {
if !Isconst(n, CTINT) {
return false
}
// if the value inside n cannot be represented as an int64, the
// return value of Int64 is undefined
return n.Val().U.(*Mpint).CmpInt64(n.Int64()) == 0
}
// Bool returns n as a bool.
// n must be a boolean constant.
func (n *Node) Bool() bool {
@ -766,7 +777,7 @@ func evconst(n *Node) {
v.U.(*Mpint).Neg()
case OCOM_ | CTINT_:
var et types.EType = Txxx
et := Txxx
if nl.Type != nil {
et = nl.Type.Etype
}

View file

@ -8,7 +8,6 @@ import (
"cmd/internal/dwarf"
"cmd/internal/obj"
"cmd/internal/src"
"sort"
"strings"
)
@ -96,7 +95,6 @@ func assembleInlines(fnsym *obj.LSym, dwVars []*dwarf.Var) dwarf.InlCalls {
// the pre-inlining decls for the target function and assign child
// index accordingly.
for ii, sl := range vmap {
sort.Sort(byClassThenName(sl))
var m map[varPos]int
if ii == 0 {
if !fnsym.WasInlined() {
@ -142,7 +140,7 @@ func assembleInlines(fnsym *obj.LSym, dwVars []*dwarf.Var) dwarf.InlCalls {
// return temps (~r%d) that were created during
// lowering, or unnamed params ("_").
v.ChildIndex = int32(synthCount)
synthCount += 1
synthCount++
}
}
}
@ -311,31 +309,6 @@ func beginRange(calls []dwarf.InlCall, p *obj.Prog, ii int, imap map[int]int) *d
return &call.Ranges[len(call.Ranges)-1]
}
func cmpDwarfVar(a, b *dwarf.Var) bool {
// named before artificial
aart := 0
if strings.HasPrefix(a.Name, "~r") {
aart = 1
}
bart := 0
if strings.HasPrefix(b.Name, "~r") {
bart = 1
}
if aart != bart {
return aart < bart
}
// otherwise sort by name
return a.Name < b.Name
}
// byClassThenName implements sort.Interface for []*dwarf.Var using cmpDwarfVar.
type byClassThenName []*dwarf.Var
func (s byClassThenName) Len() int { return len(s) }
func (s byClassThenName) Less(i, j int) bool { return cmpDwarfVar(s[i], s[j]) }
func (s byClassThenName) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func dumpInlCall(inlcalls dwarf.InlCalls, idx, ilevel int) {
for i := 0; i < ilevel; i++ {
Ctxt.Logf(" ")

View file

@ -502,8 +502,6 @@ func escAnalyze(all []*Node, recursive bool) {
}
}
// print("escapes: %d e.dsts, %d edges\n", e.dstcount, e.edgecount);
// visit the upstream of each dst, mark address nodes with
// addrescapes, mark parameters unsafe
escapes := make([]uint16, len(e.dsts))
@ -551,7 +549,6 @@ func escAnalyze(all []*Node, recursive bool) {
}
func (e *EscState) escfunc(fn *Node) {
// print("escfunc %N %s\n", fn.Func.Nname, e.recursive?"(recursive)":"");
if fn.Esc != EscFuncPlanned {
Fatalf("repeat escfunc %v", fn.Func.Nname)
}
@ -630,8 +627,6 @@ func (e *EscState) escloopdepth(n *Node) {
// Walk will complain about this label being already defined, but that's not until
// after escape analysis. in the future, maybe pull label & goto analysis out of walk and put before esc
// if(n.Left.Sym.Label != nil)
// fatal("escape analysis messed up analyzing label: %+N", n);
n.Left.Sym.Label = asTypesNode(&nonlooping)
case OGOTO:
@ -659,6 +654,58 @@ func (e *EscState) esclist(l Nodes, parent *Node) {
}
}
// isSelfAssign reports whether assignment from src to dst can
// be ignored by the escape analysis as it's effectively a self-assignment.
func (e *EscState) isSelfAssign(dst, src *Node) bool {
if dst == nil || src == nil || dst.Op != src.Op {
return false
}
switch dst.Op {
case ODOT, ODOTPTR:
// Safe trailing accessors that are permitted to differ.
case OINDEX:
if e.mayAffectMemory(dst.Right) || e.mayAffectMemory(src.Right) {
return false
}
default:
return false
}
// The expression prefix must be both "safe" and identical.
return samesafeexpr(dst.Left, src.Left)
}
// mayAffectMemory reports whether n evaluation may affect program memory state.
// If expression can't affect it, then it can be safely ignored by the escape analysis.
func (e *EscState) mayAffectMemory(n *Node) bool {
// We may want to use "memory safe" black list instead of general
// "side-effect free", which can include all calls and other ops
// that can affect allocate or change global state.
// It's safer to start from a whitelist for now.
//
// We're ignoring things like division by zero, index out of range,
// and nil pointer dereference here.
switch n.Op {
case ONAME, OCLOSUREVAR, OLITERAL:
return false
case ODOT, ODOTPTR:
return e.mayAffectMemory(n.Left)
case OIND, OCONVNOP:
return e.mayAffectMemory(n.Left)
case OCONV:
return e.mayAffectMemory(n.Left)
case OINDEX:
return e.mayAffectMemory(n.Left) || e.mayAffectMemory(n.Right)
case OADD, OSUB, OOR, OXOR, OMUL, OLSH, ORSH, OAND, OANDNOT, ODIV, OMOD:
return e.mayAffectMemory(n.Left) || e.mayAffectMemory(n.Right)
case ONOT, OCOM, OPLUS, OMINUS, OALIGNOF, OOFFSETOF, OSIZEOF:
return e.mayAffectMemory(n.Left)
default:
return true
}
}
func (e *EscState) esc(n *Node, parent *Node) {
if n == nil {
return
@ -756,10 +803,6 @@ opSwitch:
e.loopdepth++
}
// See case OLABEL in escloopdepth above
// else if(n.Left.Sym.Label == nil)
// fatal("escape analysis missed or messed up a label: %+N", n);
n.Left.Sym.Label = nil
case ORANGE:
@ -822,13 +865,30 @@ opSwitch:
break
}
// Also skip trivial assignments that assign back to the same object.
//
// It covers these cases:
// val.x = val.y
// val.x[i] = val.y[j]
// val.x1.x2 = val.x1.y2
// ... etc
//
// These assignments do not change assigned object lifetime.
if e.isSelfAssign(n.Left, n.Right) {
if Debug['m'] != 0 {
Warnl(n.Pos, "%v ignoring self-assignment in %S", e.curfnSym(n), n)
}
break
}
e.escassign(n.Left, n.Right, e.stepAssignWhere(nil, nil, "", n))
case OAS2: // x,y = a,b
if n.List.Len() == n.Rlist.Len() {
rs := n.Rlist.Slice()
where := n
for i, n := range n.List.Slice() {
e.escassignWhyWhere(n, rs[i], "assign-pair", n)
e.escassignWhyWhere(n, rs[i], "assign-pair", where)
}
}
@ -869,11 +929,12 @@ opSwitch:
// esccall already done on n.Rlist.First(). tie it's Retval to n.List
case OAS2FUNC: // x,y = f()
rs := e.nodeEscState(n.Rlist.First()).Retval.Slice()
where := n
for i, n := range n.List.Slice() {
if i >= len(rs) {
break
}
e.escassignWhyWhere(n, rs[i], "assign-pair-func-call", n)
e.escassignWhyWhere(n, rs[i], "assign-pair-func-call", where)
}
if n.List.Len() != len(rs) {
Fatalf("esc oas2func")
@ -1561,12 +1622,11 @@ func (e *EscState) esccall(call *Node, parent *Node) {
cE := e.nodeEscState(call)
if fn != nil && fn.Op == ONAME && fn.Class() == PFUNC &&
fn.Name.Defn != nil && fn.Name.Defn.Nbody.Len() != 0 && fn.Name.Param.Ntype != nil && fn.Name.Defn.Esc < EscFuncTagged {
// function in same mutually recursive group. Incorporate into flow graph.
if Debug['m'] > 3 {
fmt.Printf("%v::esccall:: %S in recursive group\n", linestr(lineno), call)
}
// function in same mutually recursive group. Incorporate into flow graph.
// print("esc local fn: %N\n", fn.Func.Ntype);
if fn.Name.Defn.Esc == EscFuncUnknown || cE.Retval.Len() != 0 {
Fatalf("graph inconsistency")
}
@ -1629,8 +1689,6 @@ func (e *EscState) esccall(call *Node, parent *Node) {
// set up out list on this call node with dummy auto ONAMES in the current (calling) function.
e.initEscRetval(call, fntype)
// print("esc analyzed fn: %#N (%+T) returning (%+H)\n", fn, fntype, e.nodeEscState(call).Retval);
// Receiver.
if call.Op != OCALLFUNC {
rf := fntype.Recv()

View file

@ -88,7 +88,7 @@ func dumpexport(bout *bio.Writer) {
}
}
func importsym(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op) *Node {
func importsym(ipkg *types.Pkg, s *types.Sym, op Op) *Node {
n := asNode(s.PkgDef())
if n == nil {
// iimport should have created a stub ONONAME
@ -113,7 +113,7 @@ func importsym(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op) *Node {
// If no such type has been declared yet, a forward declaration is returned.
// ipkg is the package being imported
func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *types.Type {
n := importsym(ipkg, pos, s, OTYPE)
n := importsym(ipkg, s, OTYPE)
if n.Op != OTYPE {
t := types.New(TFORW)
t.Sym = s
@ -135,7 +135,7 @@ func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *types.Type {
// importobj declares symbol s as an imported object representable by op.
// ipkg is the package being imported
func importobj(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op, ctxt Class, t *types.Type) *Node {
n := importsym(ipkg, pos, s, op)
n := importsym(ipkg, s, op)
if n.Op != ONONAME {
if n.Op == op && (n.Class() != ctxt || !eqtype(n.Type, t)) {
redeclare(lineno, s, fmt.Sprintf("during import %q", ipkg.Path))

View file

@ -362,6 +362,117 @@ func TestFloatConvertFolded(t *testing.T) {
}
}
func TestFloat32StoreToLoadConstantFold(t *testing.T) {
// Test that math.Float32{,from}bits constant fold correctly.
// In particular we need to be careful that signalling NaN (sNaN) values
// are not converted to quiet NaN (qNaN) values during compilation.
// See issue #27193 for more information.
// signalling NaNs
{
const nan = uint32(0x7f800001) // sNaN
if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
t.Errorf("got %#x, want %#x", x, nan)
}
}
{
const nan = uint32(0x7fbfffff) // sNaN
if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
t.Errorf("got %#x, want %#x", x, nan)
}
}
{
const nan = uint32(0xff800001) // sNaN
if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
t.Errorf("got %#x, want %#x", x, nan)
}
}
{
const nan = uint32(0xffbfffff) // sNaN
if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
t.Errorf("got %#x, want %#x", x, nan)
}
}
// quiet NaNs
{
const nan = uint32(0x7fc00000) // qNaN
if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
t.Errorf("got %#x, want %#x", x, nan)
}
}
{
const nan = uint32(0x7fffffff) // qNaN
if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
t.Errorf("got %#x, want %#x", x, nan)
}
}
{
const nan = uint32(0x8fc00000) // qNaN
if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
t.Errorf("got %#x, want %#x", x, nan)
}
}
{
const nan = uint32(0x8fffffff) // qNaN
if x := math.Float32bits(math.Float32frombits(nan)); x != nan {
t.Errorf("got %#x, want %#x", x, nan)
}
}
// infinities
{
const inf = uint32(0x7f800000) // +∞
if x := math.Float32bits(math.Float32frombits(inf)); x != inf {
t.Errorf("got %#x, want %#x", x, inf)
}
}
{
const negInf = uint32(0xff800000) // -∞
if x := math.Float32bits(math.Float32frombits(negInf)); x != negInf {
t.Errorf("got %#x, want %#x", x, negInf)
}
}
// numbers
{
const zero = uint32(0) // +0.0
if x := math.Float32bits(math.Float32frombits(zero)); x != zero {
t.Errorf("got %#x, want %#x", x, zero)
}
}
{
const negZero = uint32(1 << 31) // -0.0
if x := math.Float32bits(math.Float32frombits(negZero)); x != negZero {
t.Errorf("got %#x, want %#x", x, negZero)
}
}
{
const one = uint32(0x3f800000) // 1.0
if x := math.Float32bits(math.Float32frombits(one)); x != one {
t.Errorf("got %#x, want %#x", x, one)
}
}
{
const negOne = uint32(0xbf800000) // -1.0
if x := math.Float32bits(math.Float32frombits(negOne)); x != negOne {
t.Errorf("got %#x, want %#x", x, negOne)
}
}
{
const frac = uint32(0x3fc00000) // +1.5
if x := math.Float32bits(math.Float32frombits(frac)); x != frac {
t.Errorf("got %#x, want %#x", x, frac)
}
}
{
const negFrac = uint32(0xbfc00000) // -1.5
if x := math.Float32bits(math.Float32frombits(negFrac)); x != negFrac {
t.Errorf("got %#x, want %#x", x, negFrac)
}
}
}
var sinkFloat float64
func BenchmarkMul2(b *testing.B) {

View file

@ -7,6 +7,7 @@ package gc
import (
"cmd/compile/internal/types"
"fmt"
"io"
"strconv"
"strings"
"unicode/utf8"
@ -1836,6 +1837,10 @@ func dumplist(s string, l Nodes) {
fmt.Printf("%s%+v\n", s, l)
}
func fdumplist(w io.Writer, s string, l Nodes) {
fmt.Fprintf(w, "%s%+v\n", s, l)
}
func Dump(s string, n *Node) {
fmt.Printf("%s [%p]%+v\n", s, n, n)
}

View file

@ -281,7 +281,7 @@ var (
assertE2I2,
assertI2I,
assertI2I2,
Deferproc,
deferproc,
Deferreturn,
Duffcopy,
Duffzero,
@ -290,7 +290,7 @@ var (
growslice,
msanread,
msanwrite,
Newproc,
newproc,
panicdivide,
panicdottypeE,
panicdottypeI,

View file

@ -595,7 +595,7 @@ func (p *iexporter) typOff(t *types.Type) uint64 {
if !ok {
w := p.newWriter()
w.doTyp(t)
off = predeclReserved + uint64(w.flush())
off = predeclReserved + w.flush()
p.typIndex[t] = off
}
return off
@ -952,6 +952,16 @@ func (w *exportWriter) funcExt(n *Node) {
if n.Func.ExportInline() {
w.p.doInline(n)
}
// Endlineno for inlined function.
if n.Name.Defn != nil {
w.pos(n.Name.Defn.Func.Endlineno)
} else {
// When the exported node was defined externally,
// e.g. io exports atomic.(*Value).Load or bytes exports errors.New.
// Keep it as we don't distinguish this case in iimport.go.
w.pos(n.Func.Endlineno)
}
} else {
w.uint64(0)
}

View file

@ -296,8 +296,23 @@ func (r *importReader) doDecl(n *Node) {
// declaration before recursing.
t := importtype(r.p.ipkg, pos, n.Sym)
// We also need to defer width calculations until
// after the underlying type has been assigned.
//
// TODO(mdempsky): Add nesting support directly to
// {defer,resume}checkwidth? Width calculations are
// already deferred during initial typechecking, but
// not when we're expanding inline function bodies, so
// we currently need to handle both cases here.
deferring := defercalc != 0
if !deferring {
defercheckwidth()
}
underlying := r.typ()
copytype(typenod(t), underlying)
if !deferring {
resumecheckwidth()
}
if underlying.IsInterface() {
break
@ -576,6 +591,10 @@ func (r *importReader) typ1() *types.Type {
t := types.New(TINTER)
t.SetPkg(r.currPkg)
t.SetInterface(append(embeddeds, methods...))
// Ensure we expand the interface in the frontend (#25055).
checkwidth(t)
return t
}
}
@ -660,6 +679,7 @@ func (r *importReader) funcExt(n *Node) {
n.Func.Inl = &Inline{
Cost: int32(u - 1),
}
n.Func.Endlineno = r.pos()
}
}

Some files were not shown because too many files have changed in this diff Show more