aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Broadfoot <cbro@golang.org>2017-01-19 12:36:22 -0800
committerChris Broadfoot <cbro@golang.org>2017-01-19 12:36:53 -0800
commitd18087cb25d05b13f43e8bf83d0320e67a1d75a3 (patch)
tree2b1ae774643671d71b95c5068c95045366fab604
parent3de6e96e4b8147f5267a2e8218a7c780b09a434f (diff)
parent6593d8650da5d19787bea9383dabe94f36fa04be (diff)
downloadgo-d18087cb25d05b13f43e8bf83d0320e67a1d75a3.tar.gz
go-d18087cb25d05b13f43e8bf83d0320e67a1d75a3.zip
[release-branch.go1.8] all: merge master into release-branch.go1.8
6593d8650d go/ast: fix Object's doc comment about Data c1730ae424 runtime: force workers out before checking mark roots d10eddcba3 testing: make parallel t.Run safe again 2c8b70eacf crypto/x509: revert SystemCertPool implementation for Windows fcfd91858b doc/go1.8: document Plan 9 requirements 81a61a96c9 runtime: for plugins, don't add duplicate itabs f674537cc9 README.md: update and simplify d8711919db cmd/go: fix bug help message 48d8edb5b2 crypto/tls: disable CBC cipher suites with SHA-256 by default 92ecd78933 cmd/compile: add ZeroWB case in writebarrier 787125abab doc: 2017 is the Year of the Gopher 5b708a6b6a cmd/compile: lvalues are only required for == when calling runtime fns e83d506714 vendor/golang_org/x/crypto/poly1305: revendor to pick up fix for #18673 76f981c8d8 net/http: skip TestServerHijackGetsBackgroundByte on Plan 9 e395e3246a net/http: skip TestServerHijackGetsBackgroundByte_big on Plan 9 6a3c6c0de8 net/http: add another hijack-after-background-read test 467109bf56 all: test adjustments for the iOS builder b2a3b54b95 net/http: make sure Hijack's bufio.Reader includes pre-read background byte 593ea3b360 cmd/go, misc: rework cwd handling for iOS tests 0642b8a2f1 syscall: export Fsid.X__val on s390x 4601eae6ba doc/gdb: mention GOTRACEBACK=crash 4c4c5fc7a3 misc/cgo/testplugin: test that types and itabs are unique 22689c4450 reflect: keep makeFuncImpl live across makeFuncStub 9cf06ed6cd cmd/link: only exclude C-only symbols on darwin 9c3630f578 compress/flate: avoid large stack growth in fillDeflate 4f0aac52d9 cmd/go: add comment about SIGUSR2 on iOS 333f764df3 cmd/go, misc: switch from breakpoint to SIGUSR2 39e31d5ec0 doc/go1.8: update timezone database version 08da8201ca misc/cgo/testshared: test that types and itabs are unique fdde7ba2a2 runtime: avoid clobbering C callee-save register in cgoSigtramp f65abf6ddc cmd/compile: hide testdclstack behind debug flag 641ef2a733 compress/gzip: skip TestGZIPFilesHaveZeroMTimes on non-builders 0724aa813f crypto/dsa: gofmt ac05542985 net/http: deflake TestRetryIdempotentRequestsOnError b842c9aac7 doc: remove inline styles Change-Id: I642c056732fe1e8081e9d73e086e38ea0b2568cc
-rw-r--r--README.md46
-rw-r--r--doc/contribute.html2
-rw-r--r--doc/debugging_with_gdb.html17
-rw-r--r--doc/go1.8.html12
-rw-r--r--doc/install.html4
-rw-r--r--misc/cgo/testplugin/src/iface/main.go46
-rw-r--r--misc/cgo/testplugin/src/iface_a/a.go17
-rw-r--r--misc/cgo/testplugin/src/iface_b/b.go17
-rw-r--r--misc/cgo/testplugin/src/iface_i/i.go17
-rw-r--r--misc/cgo/testplugin/src/issue18676/dynamodbstreamsevt/definition.go13
-rw-r--r--misc/cgo/testplugin/src/issue18676/main.go31
-rw-r--r--misc/cgo/testplugin/src/issue18676/plugin.go11
-rwxr-xr-xmisc/cgo/testplugin/test.bash16
-rw-r--r--misc/cgo/testshared/shared_test.go11
-rw-r--r--misc/cgo/testshared/src/iface/main.go17
-rw-r--r--misc/cgo/testshared/src/iface_a/a.go17
-rw-r--r--misc/cgo/testshared/src/iface_b/b.go17
-rw-r--r--misc/cgo/testshared/src/iface_i/i.go17
-rw-r--r--misc/ios/go_darwin_arm_exec.go27
-rw-r--r--src/cmd/compile/internal/gc/alg.go8
-rw-r--r--src/cmd/compile/internal/gc/bimport.go4
-rw-r--r--src/cmd/compile/internal/gc/main.go13
-rw-r--r--src/cmd/compile/internal/gc/noder.go1
-rw-r--r--src/cmd/compile/internal/gc/subr.go4
-rw-r--r--src/cmd/compile/internal/gc/walk.go8
-rw-r--r--src/cmd/compile/internal/ssa/writebarrier.go2
-rw-r--r--src/cmd/go/bug.go7
-rw-r--r--src/cmd/go/test.go41
-rw-r--r--src/cmd/link/internal/ld/pcln.go2
-rw-r--r--src/compress/bzip2/bzip2_test.go24
-rw-r--r--src/compress/flate/deflate.go7
-rw-r--r--src/compress/flate/deflate_test.go31
-rw-r--r--src/compress/flate/deflatefast.go19
-rw-r--r--src/compress/gzip/issue14937_test.go14
-rw-r--r--src/crypto/dsa/dsa_test.go4
-rw-r--r--src/crypto/tls/cipher_suites.go6
-rw-r--r--src/crypto/tls/tls.go4
-rw-r--r--src/crypto/x509/cert_pool.go11
-rw-r--r--src/crypto/x509/root_windows.go5
-rw-r--r--src/crypto/x509/x509_test.go4
-rw-r--r--src/go/ast/scope.go4
-rw-r--r--src/go/doc/doc_test.go5
-rw-r--r--src/go/parser/performance_test.go13
-rw-r--r--src/net/http/serve_test.go139
-rw-r--r--src/net/http/server.go10
-rw-r--r--src/net/http/transport_test.go114
-rw-r--r--src/os/os_test.go5
-rw-r--r--src/reflect/all_test.go68
-rw-r--r--src/reflect/value.go8
-rw-r--r--src/runtime/mgc.go12
-rw-r--r--src/runtime/plugin.go4
-rw-r--r--src/runtime/sys_linux_amd64.s4
-rw-r--r--src/syscall/mkpost.go7
-rw-r--r--src/syscall/ztypes_linux_s390x.go2
-rw-r--r--src/testing/benchmark.go7
-rw-r--r--src/testing/sub_test.go17
-rw-r--r--src/testing/testing.go12
-rw-r--r--src/vendor/golang_org/x/crypto/poly1305/sum_amd64.s10
-rw-r--r--src/vendor/golang_org/x/crypto/poly1305/sum_arm.s14
-rw-r--r--test/fixedbugs/issue18661.go18
60 files changed, 855 insertions, 192 deletions
diff --git a/README.md b/README.md
index 281deecdfb..672cdf5568 100644
--- a/README.md
+++ b/README.md
@@ -5,39 +5,37 @@ reliable, and efficient software.
![Gopher image](doc/gopher/fiveyears.jpg)
-For documentation about how to install and use Go,
-visit https://golang.org/ or load doc/install-source.html
-in your web browser.
-
Our canonical Git repository is located at https://go.googlesource.com/go.
There is a mirror of the repository at https://github.com/golang/go.
-Go is the work of hundreds of contributors. We appreciate your help!
+Unless otherwise noted, the Go source files are distributed under the
+BSD-style license found in the LICENSE file.
-To contribute, please read the contribution guidelines:
- https://golang.org/doc/contribute.html
+### Download and Install
-##### Note that we do not accept pull requests and that we use the issue tracker for bug reports and proposals only. Please ask questions on https://forum.golangbridge.org or https://groups.google.com/forum/#!forum/golang-nuts.
+#### Binary Distributions
-Unless otherwise noted, the Go source files are distributed
-under the BSD-style license found in the LICENSE file.
+Official binary distributions are available at https://golang.org/dl/.
---
+After downloading a binary release, visit https://golang.org/doc/install
+or load doc/install.html in your web browser for installation
+instructions.
-## Binary Distribution Notes
+#### Install From Source
-If you have just untarred a binary Go distribution, you need to set
-the environment variable $GOROOT to the full path of the go
-directory (the one containing this file). You can omit the
-variable if you unpack it into /usr/local/go, or if you rebuild
-from sources by running all.bash (see doc/install-source.html).
-You should also add the Go binary directory $GOROOT/bin
-to your shell's path.
+If a binary distribution is not available for your combination of
+operating system and architecture, visit
+https://golang.org/doc/install/source or load doc/install-source.html
+in your web browser for source installation instructions.
-For example, if you extracted the tar file into $HOME/go, you might
-put the following in your .profile:
+### Contributing
- export GOROOT=$HOME/go
- export PATH=$PATH:$GOROOT/bin
+Go is the work of hundreds of contributors. We appreciate your help!
+
+To contribute, please read the contribution guidelines:
+ https://golang.org/doc/contribute.html
-See https://golang.org/doc/install or doc/install.html for more details.
+Note that the Go project does not use GitHub pull requests, and that
+we use the issue tracker for bug reports and proposals only. See
+https://golang.org/wiki/Questions for a list of places to ask
+questions about the Go language.
diff --git a/doc/contribute.html b/doc/contribute.html
index bcf7b25c51..f1a5b27998 100644
--- a/doc/contribute.html
+++ b/doc/contribute.html
@@ -698,7 +698,7 @@ These files will be periodically updated based on the commit logs.
<p>Code that you contribute should use the standard copyright header:</p>
<pre>
-// Copyright 2016 The Go Authors. All rights reserved.
+// Copyright 2017 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.
</pre>
diff --git a/doc/debugging_with_gdb.html b/doc/debugging_with_gdb.html
index 52a6e76723..f0e65ea291 100644
--- a/doc/debugging_with_gdb.html
+++ b/doc/debugging_with_gdb.html
@@ -4,7 +4,8 @@
}-->
<p><i>
-This applies to the <code>gc</code> toolchain. Gccgo has native gdb support.
+This applies to the standard toolchain (the <code>gc</code> Go
+compiler and tools). Gccgo has native gdb support.
Besides this overview you might want to consult the
<a href="http://sourceware.org/gdb/current/onlinedocs/gdb/">GDB manual</a>.
</i></p>
@@ -49,6 +50,14 @@ when debugging, pass the flags <code>-gcflags "-N -l"</code> to the
debugged.
</p>
+<p>
+If you want to use gdb to inspect a core dump, you can trigger a dump
+on a program crash, on systems that permit it, by setting
+<code>GOTRACEBACK=crash</code> in the environment (see the
+<a href="/pkg/runtime/#hdr-Environment_Variables"> runtime package
+documentation</a> for more info).
+</p>
+
<h3 id="Common_Operations">Common Operations</h3>
<ul>
@@ -130,7 +139,7 @@ the DWARF code.
<p>
If you're interested in what the debugging information looks like, run
-'<code>objdump -W 6.out</code>' and browse through the <code>.debug_*</code>
+'<code>objdump -W a.out</code>' and browse through the <code>.debug_*</code>
sections.
</p>
@@ -377,7 +386,9 @@ $3 = struct hchan&lt;*testing.T&gt;
</pre>
<p>
-That <code>struct hchan&lt;*testing.T&gt;</code> is the runtime-internal representation of a channel. It is currently empty, or gdb would have pretty-printed it's contents.
+That <code>struct hchan&lt;*testing.T&gt;</code> is the
+runtime-internal representation of a channel. It is currently empty,
+or gdb would have pretty-printed its contents.
</p>
<p>
diff --git a/doc/go1.8.html b/doc/go1.8.html
index 2ac478632e..337f13d630 100644
--- a/doc/go1.8.html
+++ b/doc/go1.8.html
@@ -93,7 +93,8 @@ On OpenBSD, Go now requires OpenBSD 5.9 or later. <!-- CL 34093 -->
<p>
The Plan 9 port's networking support is now much more complete
and matches the behavior of Unix and Windows with respect to deadlines
-and cancelation.
+and cancelation. For Plan 9 kernel requirements, see the
+<a href="https://golang.org/wiki/Plan9">Plan 9 wiki page</a>.
</p>
<p>
@@ -808,11 +809,6 @@ Optimizations and minor bug fixes are not listed.
<dl id="crypto_x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt>
<dd>
- <p> <!-- CL 30578 -->
- <a href="/pkg/crypto/x509/#SystemCertPool"><code>SystemCertPool</code></a>
- is now implemented on Windows.
- </p>
-
<p> <!-- CL 24743 -->
PSS signatures are now supported.
</p>
@@ -1617,9 +1613,9 @@ crypto/x509: return error for missing SerialNumber (CL 27238)
June 31 and July 32.
</p>
- <p> <!-- CL 33029 -->
+ <p> <!-- CL 33029 --> <!-- CL 34816 -->
The <code>tzdata</code> database has been updated to version
- 2016i for systems that don't already have a local time zone
+ 2016j for systems that don't already have a local time zone
database.
</p>
diff --git a/doc/install.html b/doc/install.html
index 2143d591cb..6bff75c5a0 100644
--- a/doc/install.html
+++ b/doc/install.html
@@ -250,7 +250,7 @@ $ <b>cd $HOME/go/src/hello</b>
$ <b>go build</b>
</pre>
-<pre class="testWindows" style="display: none">
+<pre class="testWindows">
C:\&gt; <b>cd %USERPROFILE%\go\src\hello</b>
C:\Users\Gopher\go\src\hello&gt; <b>go build</b>
</pre>
@@ -267,7 +267,7 @@ $ <b>./hello</b>
hello, world
</pre>
-<pre class="testWindows" style="display: none">
+<pre class="testWindows">
C:\Users\Gopher\go\src\hello&gt; <b>hello</b>
hello, world
</pre>
diff --git a/misc/cgo/testplugin/src/iface/main.go b/misc/cgo/testplugin/src/iface/main.go
new file mode 100644
index 0000000000..5e7e4d8b48
--- /dev/null
+++ b/misc/cgo/testplugin/src/iface/main.go
@@ -0,0 +1,46 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "iface_i"
+ "log"
+ "plugin"
+)
+
+func main() {
+ a, err := plugin.Open("iface_a.so")
+ if err != nil {
+ log.Fatalf(`plugin.Open("iface_a.so"): %v`, err)
+ }
+ b, err := plugin.Open("iface_b.so")
+ if err != nil {
+ log.Fatalf(`plugin.Open("iface_b.so"): %v`, err)
+ }
+
+ af, err := a.Lookup("F")
+ if err != nil {
+ log.Fatalf(`a.Lookup("F") failed: %v`, err)
+ }
+ bf, err := b.Lookup("F")
+ if err != nil {
+ log.Fatalf(`b.Lookup("F") failed: %v`, err)
+ }
+ if af.(func() interface{})() != bf.(func() interface{})() {
+ panic("empty interfaces not equal")
+ }
+
+ ag, err := a.Lookup("G")
+ if err != nil {
+ log.Fatalf(`a.Lookup("G") failed: %v`, err)
+ }
+ bg, err := b.Lookup("G")
+ if err != nil {
+ log.Fatalf(`b.Lookup("G") failed: %v`, err)
+ }
+ if ag.(func() iface_i.I)() != bg.(func() iface_i.I)() {
+ panic("nonempty interfaces not equal")
+ }
+}
diff --git a/misc/cgo/testplugin/src/iface_a/a.go b/misc/cgo/testplugin/src/iface_a/a.go
new file mode 100644
index 0000000000..29d2e27764
--- /dev/null
+++ b/misc/cgo/testplugin/src/iface_a/a.go
@@ -0,0 +1,17 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "iface_i"
+
+//go:noinline
+func F() interface{} {
+ return (*iface_i.T)(nil)
+}
+
+//go:noinline
+func G() iface_i.I {
+ return (*iface_i.T)(nil)
+}
diff --git a/misc/cgo/testplugin/src/iface_b/b.go b/misc/cgo/testplugin/src/iface_b/b.go
new file mode 100644
index 0000000000..29d2e27764
--- /dev/null
+++ b/misc/cgo/testplugin/src/iface_b/b.go
@@ -0,0 +1,17 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "iface_i"
+
+//go:noinline
+func F() interface{} {
+ return (*iface_i.T)(nil)
+}
+
+//go:noinline
+func G() iface_i.I {
+ return (*iface_i.T)(nil)
+}
diff --git a/misc/cgo/testplugin/src/iface_i/i.go b/misc/cgo/testplugin/src/iface_i/i.go
new file mode 100644
index 0000000000..31c80387c7
--- /dev/null
+++ b/misc/cgo/testplugin/src/iface_i/i.go
@@ -0,0 +1,17 @@
+// Copyright 2017 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 iface_i
+
+type I interface {
+ M()
+}
+
+type T struct {
+}
+
+func (t *T) M() {
+}
+
+// *T implements I
diff --git a/misc/cgo/testplugin/src/issue18676/dynamodbstreamsevt/definition.go b/misc/cgo/testplugin/src/issue18676/dynamodbstreamsevt/definition.go
new file mode 100644
index 0000000000..70fd054d08
--- /dev/null
+++ b/misc/cgo/testplugin/src/issue18676/dynamodbstreamsevt/definition.go
@@ -0,0 +1,13 @@
+// Copyright 2017 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 dynamodbstreamsevt
+
+import "encoding/json"
+
+var foo json.RawMessage
+
+type Event struct{}
+
+func (e *Event) Dummy() {}
diff --git a/misc/cgo/testplugin/src/issue18676/main.go b/misc/cgo/testplugin/src/issue18676/main.go
new file mode 100644
index 0000000000..c75409dafe
--- /dev/null
+++ b/misc/cgo/testplugin/src/issue18676/main.go
@@ -0,0 +1,31 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The bug happened like this:
+// 1) The main binary adds an itab for *json.UnsupportedValueError / error
+// (concrete type / interface type). This itab goes in hash bucket 0x111.
+// 2) The plugin adds that same itab again. That makes a cycle in the itab
+// chain rooted at hash bucket 0x111.
+// 3) The main binary then asks for the itab for *dynamodbstreamsevt.Event /
+// json.Unmarshaler. This itab happens to also live in bucket 0x111.
+// The lookup code goes into an infinite loop searching for this itab.
+// The code is carefully crafted so that the two itabs are both from the
+// same bucket, and so that the second itab doesn't exist in
+// the itab hashmap yet (so the entire linked list must be searched).
+package main
+
+import (
+ "encoding/json"
+ "issue18676/dynamodbstreamsevt"
+ "plugin"
+)
+
+func main() {
+ plugin.Open("plugin.so")
+
+ var x interface{} = (*dynamodbstreamsevt.Event)(nil)
+ if _, ok := x.(json.Unmarshaler); !ok {
+ println("something")
+ }
+}
diff --git a/misc/cgo/testplugin/src/issue18676/plugin.go b/misc/cgo/testplugin/src/issue18676/plugin.go
new file mode 100644
index 0000000000..8a3b85a75c
--- /dev/null
+++ b/misc/cgo/testplugin/src/issue18676/plugin.go
@@ -0,0 +1,11 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "C"
+
+import "issue18676/dynamodbstreamsevt"
+
+func F(evt *dynamodbstreamsevt.Event) {}
diff --git a/misc/cgo/testplugin/test.bash b/misc/cgo/testplugin/test.bash
index fee99a758c..ab7430acc3 100755
--- a/misc/cgo/testplugin/test.bash
+++ b/misc/cgo/testplugin/test.bash
@@ -15,8 +15,8 @@ goos=$(go env GOOS)
goarch=$(go env GOARCH)
function cleanup() {
- rm -f plugin*.so unnamed*.so
- rm -rf host pkg sub
+ rm -f plugin*.so unnamed*.so iface*.so
+ rm -rf host pkg sub iface issue18676
}
trap cleanup EXIT
@@ -32,3 +32,15 @@ GOPATH=$(pwd) go build -buildmode=plugin unnamed2.go
GOPATH=$(pwd) go build host
LD_LIBRARY_PATH=$(pwd) ./host
+
+# Test that types and itabs get properly uniqified.
+GOPATH=$(pwd) go build -buildmode=plugin iface_a
+GOPATH=$(pwd) go build -buildmode=plugin iface_b
+GOPATH=$(pwd) go build iface
+LD_LIBRARY_PATH=$(pwd) ./iface
+
+# Test for issue 18676 - make sure we don't add the same itab twice.
+# The buggy code hangs forever, so use a timeout to check for that.
+GOPATH=$(pwd) go build -buildmode=plugin -o plugin.so src/issue18676/plugin.go
+GOPATH=$(pwd) go build -o issue18676 src/issue18676/main.go
+timeout 10s ./issue18676
diff --git a/misc/cgo/testshared/shared_test.go b/misc/cgo/testshared/shared_test.go
index af4f91550f..f0766e511e 100644
--- a/misc/cgo/testshared/shared_test.go
+++ b/misc/cgo/testshared/shared_test.go
@@ -815,3 +815,14 @@ func TestImplicitInclusion(t *testing.T) {
goCmd(t, "install", "-linkshared", "implicitcmd")
run(t, "running executable linked against library that contains same package as it", "./bin/implicitcmd")
}
+
+// Tests to make sure that the type fields of empty interfaces and itab
+// fields of nonempty interfaces are unique even across modules,
+// so that interface equality works correctly.
+func TestInterface(t *testing.T) {
+ goCmd(t, "install", "-buildmode=shared", "-linkshared", "iface_a")
+ // Note: iface_i gets installed implicitly as a dependency of iface_a.
+ goCmd(t, "install", "-buildmode=shared", "-linkshared", "iface_b")
+ goCmd(t, "install", "-linkshared", "iface")
+ run(t, "running type/itab uniqueness tester", "./bin/iface")
+}
diff --git a/misc/cgo/testshared/src/iface/main.go b/misc/cgo/testshared/src/iface/main.go
new file mode 100644
index 0000000000..3d5b54e73b
--- /dev/null
+++ b/misc/cgo/testshared/src/iface/main.go
@@ -0,0 +1,17 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "iface_a"
+import "iface_b"
+
+func main() {
+ if iface_a.F() != iface_b.F() {
+ panic("empty interfaces not equal")
+ }
+ if iface_a.G() != iface_b.G() {
+ panic("non-empty interfaces not equal")
+ }
+}
diff --git a/misc/cgo/testshared/src/iface_a/a.go b/misc/cgo/testshared/src/iface_a/a.go
new file mode 100644
index 0000000000..e11047c166
--- /dev/null
+++ b/misc/cgo/testshared/src/iface_a/a.go
@@ -0,0 +1,17 @@
+// Copyright 2017 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 iface_a
+
+import "iface_i"
+
+//go:noinline
+func F() interface{} {
+ return (*iface_i.T)(nil)
+}
+
+//go:noinline
+func G() iface_i.I {
+ return (*iface_i.T)(nil)
+}
diff --git a/misc/cgo/testshared/src/iface_b/b.go b/misc/cgo/testshared/src/iface_b/b.go
new file mode 100644
index 0000000000..47aee2e77e
--- /dev/null
+++ b/misc/cgo/testshared/src/iface_b/b.go
@@ -0,0 +1,17 @@
+// Copyright 2017 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 iface_b
+
+import "iface_i"
+
+//go:noinline
+func F() interface{} {
+ return (*iface_i.T)(nil)
+}
+
+//go:noinline
+func G() iface_i.I {
+ return (*iface_i.T)(nil)
+}
diff --git a/misc/cgo/testshared/src/iface_i/i.go b/misc/cgo/testshared/src/iface_i/i.go
new file mode 100644
index 0000000000..31c80387c7
--- /dev/null
+++ b/misc/cgo/testshared/src/iface_i/i.go
@@ -0,0 +1,17 @@
+// Copyright 2017 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 iface_i
+
+type I interface {
+ M()
+}
+
+type T struct {
+}
+
+func (t *T) M() {
+}
+
+// *T implements I
diff --git a/misc/ios/go_darwin_arm_exec.go b/misc/ios/go_darwin_arm_exec.go
index 1eeb289c7d..3de341b9c5 100644
--- a/misc/ios/go_darwin_arm_exec.go
+++ b/misc/ios/go_darwin_arm_exec.go
@@ -99,7 +99,7 @@ func main() {
// Approximately 1 in a 100 binaries fail to start. If it happens,
// try again. These failures happen for several reasons beyond
// our control, but all of them are safe to retry as they happen
- // before lldb encounters the initial getwd breakpoint. As we
+ // before lldb encounters the initial SIGUSR2 stop. As we
// know the tests haven't started, we are not hiding flaky tests
// with this retry.
for i := 0; i < 5; i++ {
@@ -204,6 +204,11 @@ func run(bin string, args []string) (err error) {
var opts options
opts, args = parseArgs(args)
+ // Pass the suffix for the current working directory as the
+ // first argument to the test. For iOS, cmd/go generates
+ // special handling of this argument.
+ args = append([]string{"cwdSuffix=" + pkgpath}, args...)
+
// ios-deploy invokes lldb to give us a shell session with the app.
s, err := newSession(appdir, args, opts)
if err != nil {
@@ -224,6 +229,7 @@ func run(bin string, args []string) (err error) {
s.do(`process handle SIGHUP --stop false --pass true --notify false`)
s.do(`process handle SIGPIPE --stop false --pass true --notify false`)
s.do(`process handle SIGUSR1 --stop false --pass true --notify false`)
+ s.do(`process handle SIGUSR2 --stop true --pass false --notify true`) // sent by test harness
s.do(`process handle SIGCONT --stop false --pass true --notify false`)
s.do(`process handle SIGSEGV --stop false --pass true --notify false`) // does not work
s.do(`process handle SIGBUS --stop false --pass true --notify false`) // does not work
@@ -236,20 +242,9 @@ func run(bin string, args []string) (err error) {
return nil
}
- s.do(`breakpoint set -n getwd`) // in runtime/cgo/gcc_darwin_arm.go
-
started = true
- s.doCmd("run", "stop reason = breakpoint", 20*time.Second)
-
- // Move the current working directory into the faux gopath.
- if pkgpath != "src" {
- s.do(`breakpoint delete 1`)
- s.do(`expr char* $mem = (char*)malloc(512)`)
- s.do(`expr $mem = (char*)getwd($mem, 512)`)
- s.do(`expr $mem = (char*)strcat($mem, "/` + pkgpath + `")`)
- s.do(`call (void)chdir($mem)`)
- }
+ s.doCmd("run", "stop reason = signal SIGUSR2", 20*time.Second)
startTestsLen := s.out.Len()
fmt.Fprintln(s.in, `process continue`)
@@ -520,13 +515,11 @@ func copyLocalData(dstbase string) (pkgpath string, err error) {
// Copy timezone file.
//
- // Typical apps have the zoneinfo.zip in the root of their app bundle,
+ // Apps have the zoneinfo.zip in the root of their app bundle,
// read by the time package as the working directory at initialization.
- // As we move the working directory to the GOROOT pkg directory, we
- // install the zoneinfo.zip file in the pkgpath.
if underGoRoot {
err := cp(
- filepath.Join(dstbase, pkgpath),
+ dstbase,
filepath.Join(cwd, "lib", "time", "zoneinfo.zip"),
)
if err != nil {
diff --git a/src/cmd/compile/internal/gc/alg.go b/src/cmd/compile/internal/gc/alg.go
index 8113710e39..d4f3d9884e 100644
--- a/src/cmd/compile/internal/gc/alg.go
+++ b/src/cmd/compile/internal/gc/alg.go
@@ -303,7 +303,9 @@ func genhash(sym *Sym, t *Type) {
typecheckslice(fn.Nbody.Slice(), Etop)
Curfn = nil
popdcl()
- testdclstack()
+ if debug_dclstack != 0 {
+ testdclstack()
+ }
// Disable safemode while compiling this code: the code we
// generate internally can refer to unsafe.Pointer.
@@ -493,7 +495,9 @@ func geneq(sym *Sym, t *Type) {
typecheckslice(fn.Nbody.Slice(), Etop)
Curfn = nil
popdcl()
- testdclstack()
+ if debug_dclstack != 0 {
+ testdclstack()
+ }
// Disable safemode while compiling this code: the code we
// generate internally can refer to unsafe.Pointer.
diff --git a/src/cmd/compile/internal/gc/bimport.go b/src/cmd/compile/internal/gc/bimport.go
index 1d668412a1..94c1184138 100644
--- a/src/cmd/compile/internal/gc/bimport.go
+++ b/src/cmd/compile/internal/gc/bimport.go
@@ -217,7 +217,9 @@ func Import(in *bufio.Reader) {
typecheckok = tcok
resumecheckwidth()
- testdclstack() // debugging only
+ if debug_dclstack != 0 {
+ testdclstack()
+ }
}
func formatErrorf(format string, args ...interface{}) {
diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go
index 75f58a731c..1690944b3d 100644
--- a/src/cmd/compile/internal/gc/main.go
+++ b/src/cmd/compile/internal/gc/main.go
@@ -30,11 +30,12 @@ var (
)
var (
- Debug_append int
- Debug_closure int
- Debug_panic int
- Debug_slice int
- Debug_wb int
+ Debug_append int
+ Debug_closure int
+ debug_dclstack int
+ Debug_panic int
+ Debug_slice int
+ Debug_wb int
)
// Debug arguments.
@@ -48,6 +49,7 @@ var debugtab = []struct {
{"append", &Debug_append}, // print information about append compilation
{"closure", &Debug_closure}, // print information about closure compilation
{"disablenil", &disable_checknil}, // disable nil checks
+ {"dclstack", &debug_dclstack}, // run internal dclstack checks
{"gcprog", &Debug_gcprog}, // print dump of GC programs
{"nil", &Debug_checknil}, // print information about nil checks
{"panic", &Debug_panic}, // do not hide any compiler panic
@@ -325,7 +327,6 @@ func Main() {
timings.Stop()
timings.AddEvent(int64(lexlineno-lexlineno0), "lines")
- testdclstack()
mkpackage(localpkg.Name) // final import not used checks
finishUniverse()
diff --git a/src/cmd/compile/internal/gc/noder.go b/src/cmd/compile/internal/gc/noder.go
index ca99adea27..ce18297ac3 100644
--- a/src/cmd/compile/internal/gc/noder.go
+++ b/src/cmd/compile/internal/gc/noder.go
@@ -34,6 +34,7 @@ func parseFile(filename string) {
}
if nsyntaxerrors == 0 {
+ // Always run testdclstack here, even when debug_dclstack is not set, as a sanity measure.
testdclstack()
}
}
diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go
index 9b9a3f1210..7d008dfa65 100644
--- a/src/cmd/compile/internal/gc/subr.go
+++ b/src/cmd/compile/internal/gc/subr.go
@@ -1833,7 +1833,9 @@ func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) {
funcbody(fn)
Curfn = fn
popdcl()
- testdclstack()
+ if debug_dclstack != 0 {
+ testdclstack()
+ }
// wrappers where T is anonymous (struct or interface) can be duplicated.
if rcvr.IsStruct() || rcvr.IsInterface() || rcvr.IsPtr() && rcvr.Elem().IsStruct() {
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index efe2016e46..7c2e2ab442 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -3117,12 +3117,12 @@ func walkcompare(n *Node, init *Nodes) *Node {
cmpr = cmpr.Left
}
- if !islvalue(cmpl) || !islvalue(cmpr) {
- Fatalf("arguments of comparison must be lvalues - %v %v", cmpl, cmpr)
- }
-
// Chose not to inline. Call equality function directly.
if !inline {
+ if !islvalue(cmpl) || !islvalue(cmpr) {
+ Fatalf("arguments of comparison must be lvalues - %v %v", cmpl, cmpr)
+ }
+
// eq algs take pointers
pl := temp(ptrto(t))
al := nod(OAS, pl, nod(OADDR, cmpl, nil))
diff --git a/src/cmd/compile/internal/ssa/writebarrier.go b/src/cmd/compile/internal/ssa/writebarrier.go
index 1eb4d7bb1a..054ba1f85c 100644
--- a/src/cmd/compile/internal/ssa/writebarrier.go
+++ b/src/cmd/compile/internal/ssa/writebarrier.go
@@ -35,7 +35,7 @@ func writebarrier(f *Func) {
valueLoop:
for i, v := range b.Values {
switch v.Op {
- case OpStoreWB, OpMoveWB, OpMoveWBVolatile:
+ case OpStoreWB, OpMoveWB, OpMoveWBVolatile, OpZeroWB:
if IsStackAddr(v.Args[0]) {
switch v.Op {
case OpStoreWB:
diff --git a/src/cmd/go/bug.go b/src/cmd/go/bug.go
index cbd258b80b..658f6dabd9 100644
--- a/src/cmd/go/bug.go
+++ b/src/cmd/go/bug.go
@@ -20,11 +20,10 @@ import (
var cmdBug = &Command{
Run: runBug,
UsageLine: "bug",
- Short: "print information for bug reports",
+ Short: "start a bug report",
Long: `
-Bug prints information that helps file effective bug reports.
-
-Bugs may be reported at https://golang.org/issue/new.
+Bug opens the default browser and starts a new bug report.
+The report includes useful system information.
`,
}
diff --git a/src/cmd/go/test.go b/src/cmd/go/test.go
index cdb167de75..6482f0fd32 100644
--- a/src/cmd/go/test.go
+++ b/src/cmd/go/test.go
@@ -894,9 +894,13 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
if buildContext.GOOS == "darwin" {
if buildContext.GOARCH == "arm" || buildContext.GOARCH == "arm64" {
- t.NeedCgo = true
+ t.IsIOS = true
+ t.NeedOS = true
}
}
+ if t.TestMain == nil {
+ t.NeedOS = true
+ }
for _, cp := range pmain.imports {
if len(cp.coverVars) > 0 {
@@ -1343,7 +1347,8 @@ type testFuncs struct {
NeedTest bool
ImportXtest bool
NeedXtest bool
- NeedCgo bool
+ NeedOS bool
+ IsIOS bool
Cover []coverInfo
}
@@ -1444,7 +1449,7 @@ var testmainTmpl = template.Must(template.New("main").Parse(`
package main
import (
-{{if not .TestMain}}
+{{if .NeedOS}}
"os"
{{end}}
"testing"
@@ -1460,8 +1465,10 @@ import (
_cover{{$i}} {{$p.Package.ImportPath | printf "%q"}}
{{end}}
-{{if .NeedCgo}}
+{{if .IsIOS}}
+ "os/signal"
_ "runtime/cgo"
+ "syscall"
{{end}}
)
@@ -1523,6 +1530,32 @@ func coverRegisterFile(fileName string, counter []uint32, pos []uint32, numStmts
{{end}}
func main() {
+{{if .IsIOS}}
+ // Send a SIGUSR2, which will be intercepted by LLDB to
+ // tell the test harness that installation was successful.
+ // See misc/ios/go_darwin_arm_exec.go.
+ signal.Notify(make(chan os.Signal), syscall.SIGUSR2)
+ syscall.Kill(0, syscall.SIGUSR2)
+ signal.Reset(syscall.SIGUSR2)
+
+ // The first argument supplied to an iOS test is an offset
+ // suffix for the current working directory.
+ // Process it here, and remove it from os.Args.
+ const hdr = "cwdSuffix="
+ if len(os.Args) < 2 || len(os.Args[1]) <= len(hdr) || os.Args[1][:len(hdr)] != hdr {
+ panic("iOS test not passed a working directory suffix")
+ }
+ suffix := os.Args[1][len(hdr):]
+ dir, err := os.Getwd()
+ if err != nil {
+ panic(err)
+ }
+ if err := os.Chdir(dir + "/" + suffix); err != nil {
+ panic(err)
+ }
+ os.Args = append([]string{os.Args[0]}, os.Args[2:]...)
+{{end}}
+
{{if .CoverEnabled}}
testing.RegisterCover(testing.Cover{
Mode: {{printf "%q" .CoverMode}},
diff --git a/src/cmd/link/internal/ld/pcln.go b/src/cmd/link/internal/ld/pcln.go
index 1ebd7de662..479425f211 100644
--- a/src/cmd/link/internal/ld/pcln.go
+++ b/src/cmd/link/internal/ld/pcln.go
@@ -168,7 +168,7 @@ func container(s *Symbol) int {
if s == nil {
return 0
}
- if Buildmode == BuildmodePlugin && onlycsymbol(s) {
+ if Buildmode == BuildmodePlugin && Headtype == obj.Hdarwin && onlycsymbol(s) {
return 1
}
// We want to generate func table entries only for the "lowest level" symbols,
diff --git a/src/compress/bzip2/bzip2_test.go b/src/compress/bzip2/bzip2_test.go
index a6c3080db3..95fb189585 100644
--- a/src/compress/bzip2/bzip2_test.go
+++ b/src/compress/bzip2/bzip2_test.go
@@ -204,12 +204,6 @@ func TestMTF(t *testing.T) {
}
}
-var (
- digits = mustLoadFile("testdata/e.txt.bz2")
- twain = mustLoadFile("testdata/Mark.Twain-Tom.Sawyer.txt.bz2")
- random = mustLoadFile("testdata/random.data.bz2")
-)
-
func benchmarkDecode(b *testing.B, compressed []byte) {
// Determine the uncompressed size of testfile.
uncompressedSize, err := io.Copy(ioutil.Discard, NewReader(bytes.NewReader(compressed)))
@@ -227,6 +221,18 @@ func benchmarkDecode(b *testing.B, compressed []byte) {
}
}
-func BenchmarkDecodeDigits(b *testing.B) { benchmarkDecode(b, digits) }
-func BenchmarkDecodeTwain(b *testing.B) { benchmarkDecode(b, twain) }
-func BenchmarkDecodeRand(b *testing.B) { benchmarkDecode(b, random) }
+func BenchmarkDecodeDigits(b *testing.B) {
+ digits := mustLoadFile("testdata/e.txt.bz2")
+ b.ResetTimer()
+ benchmarkDecode(b, digits)
+}
+func BenchmarkDecodeTwain(b *testing.B) {
+ twain := mustLoadFile("testdata/Mark.Twain-Tom.Sawyer.txt.bz2")
+ b.ResetTimer()
+ benchmarkDecode(b, twain)
+}
+func BenchmarkDecodeRand(b *testing.B) {
+ random := mustLoadFile("testdata/random.data.bz2")
+ b.ResetTimer()
+ benchmarkDecode(b, random)
+}
diff --git a/src/compress/flate/deflate.go b/src/compress/flate/deflate.go
index 97265b3ca2..4d6a5357d8 100644
--- a/src/compress/flate/deflate.go
+++ b/src/compress/flate/deflate.go
@@ -136,14 +136,17 @@ func (d *compressor) fillDeflate(b []byte) int {
delta := d.hashOffset - 1
d.hashOffset -= delta
d.chainHead -= delta
- for i, v := range d.hashPrev {
+
+ // Iterate over slices instead of arrays to avoid copying
+ // the entire table onto the stack (Issue #18625).
+ for i, v := range d.hashPrev[:] {
if int(v) > delta {
d.hashPrev[i] = uint32(int(v) - delta)
} else {
d.hashPrev[i] = 0
}
}
- for i, v := range d.hashHead {
+ for i, v := range d.hashHead[:] {
if int(v) > delta {
d.hashHead[i] = uint32(int(v) - delta)
} else {
diff --git a/src/compress/flate/deflate_test.go b/src/compress/flate/deflate_test.go
index 521a260365..fbea761721 100644
--- a/src/compress/flate/deflate_test.go
+++ b/src/compress/flate/deflate_test.go
@@ -12,6 +12,7 @@ import (
"io"
"io/ioutil"
"reflect"
+ "runtime/debug"
"sync"
"testing"
)
@@ -864,3 +865,33 @@ func TestBestSpeedMaxMatchOffset(t *testing.T) {
}
}
}
+
+func TestMaxStackSize(t *testing.T) {
+ // This test must not run in parallel with other tests as debug.SetMaxStack
+ // affects all goroutines.
+ n := debug.SetMaxStack(1 << 16)
+ defer debug.SetMaxStack(n)
+
+ var wg sync.WaitGroup
+ defer wg.Wait()
+
+ b := make([]byte, 1<<20)
+ for level := HuffmanOnly; level <= BestCompression; level++ {
+ // Run in separate goroutine to increase probability of stack regrowth.
+ wg.Add(1)
+ go func(level int) {
+ defer wg.Done()
+ zw, err := NewWriter(ioutil.Discard, level)
+ if err != nil {
+ t.Errorf("level %d, NewWriter() = %v, want nil", level, err)
+ }
+ if n, err := zw.Write(b); n != len(b) || err != nil {
+ t.Errorf("level %d, Write() = (%d, %v), want (%d, nil)", level, n, err, len(b))
+ }
+ if err := zw.Close(); err != nil {
+ t.Errorf("level %d, Close() = %v, want nil", level, err)
+ }
+ zw.Reset(ioutil.Discard)
+ }(level)
+ }
+}
diff --git a/src/compress/flate/deflatefast.go b/src/compress/flate/deflatefast.go
index a1636a37d6..08298b76bb 100644
--- a/src/compress/flate/deflatefast.go
+++ b/src/compress/flate/deflatefast.go
@@ -60,7 +60,7 @@ func newDeflateFast() *deflateFast {
func (e *deflateFast) encode(dst []token, src []byte) []token {
// Ensure that e.cur doesn't wrap.
if e.cur > 1<<30 {
- *e = deflateFast{cur: maxStoreBlockSize, prev: e.prev[:0]}
+ e.resetAll()
}
// This check isn't in the Snappy implementation, but there, the caller
@@ -265,6 +265,21 @@ func (e *deflateFast) reset() {
// Protect against e.cur wraparound.
if e.cur > 1<<30 {
- *e = deflateFast{cur: maxStoreBlockSize, prev: e.prev[:0]}
+ e.resetAll()
+ }
+}
+
+// resetAll resets the deflateFast struct and is only called in rare
+// situations to prevent integer overflow. It manually resets each field
+// to avoid causing large stack growth.
+//
+// See https://golang.org/issue/18636.
+func (e *deflateFast) resetAll() {
+ // This is equivalent to:
+ // *e = deflateFast{cur: maxStoreBlockSize, prev: e.prev[:0]}
+ e.cur = maxStoreBlockSize
+ e.prev = e.prev[:0]
+ for i := range e.table {
+ e.table[i] = tableEntry{}
}
}
diff --git a/src/compress/gzip/issue14937_test.go b/src/compress/gzip/issue14937_test.go
index e76d47cc4e..30c1390dfd 100644
--- a/src/compress/gzip/issue14937_test.go
+++ b/src/compress/gzip/issue14937_test.go
@@ -9,11 +9,17 @@ import (
"testing"
)
-// Per golang.org/issue/14937, check that every .gz file
-// in the tree has a zero mtime.
+// TestGZIPFilesHaveZeroMTimes checks that every .gz file in the tree
+// has a zero MTIME. This is a requirement for the Debian maintainers
+// to be able to have deterministic packages.
+//
+// See https://golang.org/issue/14937.
func TestGZIPFilesHaveZeroMTimes(t *testing.T) {
- if testing.Short() && testenv.Builder() == "" {
- t.Skip("skipping in short mode")
+ // To avoid spurious false positives due to untracked GZIP files that
+ // may be in the user's GOROOT (Issue 18604), we only run this test on
+ // the builders, which should have a clean checkout of the tree.
+ if testenv.Builder() == "" {
+ t.Skip("skipping test on non-builder")
}
goroot, err := filepath.EvalSymlinks(runtime.GOROOT())
if err != nil {
diff --git a/src/crypto/dsa/dsa_test.go b/src/crypto/dsa/dsa_test.go
index b89aeaebea..8600059f03 100644
--- a/src/crypto/dsa/dsa_test.go
+++ b/src/crypto/dsa/dsa_test.go
@@ -95,7 +95,7 @@ func TestSignAndVerify(t *testing.T) {
func TestSigningWithDegenerateKeys(t *testing.T) {
// Signing with degenerate private keys should not cause an infinite
// loop.
- badKeys := []struct{
+ badKeys := []struct {
p, q, g, y, x string
}{
{"00", "01", "00", "00", "00"},
@@ -105,7 +105,7 @@ func TestSigningWithDegenerateKeys(t *testing.T) {
for i, test := range badKeys {
priv := PrivateKey{
PublicKey: PublicKey{
- Parameters: Parameters {
+ Parameters: Parameters{
P: fromHex(test.p),
Q: fromHex(test.q),
G: fromHex(test.g),
diff --git a/src/crypto/tls/cipher_suites.go b/src/crypto/tls/cipher_suites.go
index 05146743ac..beb0f1926d 100644
--- a/src/crypto/tls/cipher_suites.go
+++ b/src/crypto/tls/cipher_suites.go
@@ -84,15 +84,15 @@ var cipherSuites = []*cipherSuite{
{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM},
{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
- {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12, cipherAES, macSHA256, nil},
+ {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
- {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, cipherAES, macSHA256, nil},
+ {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
{TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, rsaKA, suiteTLS12, nil, nil, aeadAESGCM},
{TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
- {TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12, cipherAES, macSHA256, nil},
+ {TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
diff --git a/src/crypto/tls/tls.go b/src/crypto/tls/tls.go
index f2e5aea2bc..615d1e5576 100644
--- a/src/crypto/tls/tls.go
+++ b/src/crypto/tls/tls.go
@@ -6,8 +6,8 @@
package tls
// BUG(agl): The crypto/tls package only implements some countermeasures
-// against Lucky13 attacks on CBC-mode encryption. See
-// http://www.isg.rhul.ac.uk/tls/TLStiming.pdf and
+// against Lucky13 attacks on CBC-mode encryption, and only on SHA1
+// variants. See http://www.isg.rhul.ac.uk/tls/TLStiming.pdf and
// https://www.imperialviolet.org/2013/02/04/luckythirteen.html.
import (
diff --git a/src/crypto/x509/cert_pool.go b/src/crypto/x509/cert_pool.go
index fea33df379..71ffbdf0e0 100644
--- a/src/crypto/x509/cert_pool.go
+++ b/src/crypto/x509/cert_pool.go
@@ -4,7 +4,11 @@
package x509
-import "encoding/pem"
+import (
+ "encoding/pem"
+ "errors"
+ "runtime"
+)
// CertPool is a set of certificates.
type CertPool struct {
@@ -26,6 +30,11 @@ func NewCertPool() *CertPool {
// Any mutations to the returned pool are not written to disk and do
// not affect any other pool.
func SystemCertPool() (*CertPool, error) {
+ if runtime.GOOS == "windows" {
+ // Issue 16736, 18609:
+ return nil, errors.New("crypto/x509: system root pool is not available on Windows")
+ }
+
return loadSystemRoots()
}
diff --git a/src/crypto/x509/root_windows.go b/src/crypto/x509/root_windows.go
index ca2fba5cb4..a936fec7d8 100644
--- a/src/crypto/x509/root_windows.go
+++ b/src/crypto/x509/root_windows.go
@@ -226,6 +226,11 @@ func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate
}
func loadSystemRoots() (*CertPool, error) {
+ // TODO: restore this functionality on Windows. We tried to do
+ // it in Go 1.8 but had to revert it. See Issue 18609.
+ // Returning (nil, nil) was the old behavior, prior to CL 30578.
+ return nil, nil
+
const CRYPT_E_NOT_FOUND = 0x80092004
store, err := syscall.CertOpenSystemStore(0, syscall.StringToUTF16Ptr("ROOT"))
diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go
index aa30d85b7d..b085dad90f 100644
--- a/src/crypto/x509/x509_test.go
+++ b/src/crypto/x509/x509_test.go
@@ -24,6 +24,7 @@ import (
"net"
"os/exec"
"reflect"
+ "runtime"
"strings"
"testing"
"time"
@@ -1477,6 +1478,9 @@ func TestMultipleRDN(t *testing.T) {
}
func TestSystemCertPool(t *testing.T) {
+ if runtime.GOOS == "windows" {
+ t.Skip("not implemented on Windows; Issue 16736, 18609")
+ }
_, err := SystemCertPool()
if err != nil {
t.Fatal(err)
diff --git a/src/go/ast/scope.go b/src/go/ast/scope.go
index 1ce5e2e84b..a400c7152a 100644
--- a/src/go/ast/scope.go
+++ b/src/go/ast/scope.go
@@ -70,10 +70,8 @@ func (s *Scope) String() string {
// The Data fields contains object-specific data:
//
// Kind Data type Data value
-// Pkg *types.Package package scope
+// Pkg *Scope package scope
// Con int iota for the respective declaration
-// Con != nil constant value
-// Typ *Scope (used as method scope during type checking - transient)
//
type Object struct {
Kind ObjKind
diff --git a/src/go/doc/doc_test.go b/src/go/doc/doc_test.go
index ad8ba5378f..82e63100d4 100644
--- a/src/go/doc/doc_test.go
+++ b/src/go/doc/doc_test.go
@@ -25,7 +25,7 @@ var files = flag.String("files", "", "consider only Go test files matching this
const dataDir = "testdata"
-var templateTxt = readTemplate("template.txt")
+var templateTxt *template.Template
func readTemplate(filename string) *template.Template {
t := template.New(filename)
@@ -96,6 +96,9 @@ func test(t *testing.T, mode Mode) {
if err != nil {
t.Fatal(err)
}
+ if templateTxt == nil {
+ templateTxt = readTemplate("template.txt")
+ }
// test packages
for _, pkg := range pkgs {
diff --git a/src/go/parser/performance_test.go b/src/go/parser/performance_test.go
index f2732c0e2b..b2e1c11e9d 100644
--- a/src/go/parser/performance_test.go
+++ b/src/go/parser/performance_test.go
@@ -10,17 +10,12 @@ import (
"testing"
)
-var src = readFile("parser.go")
-
-func readFile(filename string) []byte {
- data, err := ioutil.ReadFile(filename)
+func BenchmarkParse(b *testing.B) {
+ src, err := ioutil.ReadFile("parser.go")
if err != nil {
- panic(err)
+ b.Fatal(err)
}
- return data
-}
-
-func BenchmarkParse(b *testing.B) {
+ b.ResetTimer()
b.SetBytes(int64(len(src)))
for i := 0; i < b.N; i++ {
if _, err := ParseFile(token.NewFileSet(), "", src, ParseComments); err != nil {
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
index 072da2552b..681dff193a 100644
--- a/src/net/http/serve_test.go
+++ b/src/net/http/serve_test.go
@@ -5173,3 +5173,142 @@ func TestServerDuplicateBackgroundRead(t *testing.T) {
}
wg.Wait()
}
+
+// Test that the bufio.Reader returned by Hijack includes any buffered
+// byte (from the Server's backgroundRead) in its buffer. We want the
+// Handler code to be able to tell that a byte is available via
+// bufio.Reader.Buffered(), without resorting to Reading it
+// (potentially blocking) to get at it.
+func TestServerHijackGetsBackgroundByte(t *testing.T) {
+ if runtime.GOOS == "plan9" {
+ t.Skip("skipping test; see https://golang.org/issue/18657")
+ }
+ setParallel(t)
+ defer afterTest(t)
+ done := make(chan struct{})
+ inHandler := make(chan bool, 1)
+ ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+ defer close(done)
+
+ // Tell the client to send more data after the GET request.
+ inHandler <- true
+
+ // Wait until the HTTP server sees the extra data
+ // after the GET request. The HTTP server fires the
+ // close notifier here, assuming it's a pipelined
+ // request, as documented.
+ select {
+ case <-w.(CloseNotifier).CloseNotify():
+ case <-time.After(5 * time.Second):
+ t.Error("timeout")
+ return
+ }
+
+ conn, buf, err := w.(Hijacker).Hijack()
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ defer conn.Close()
+ n := buf.Reader.Buffered()
+ if n != 1 {
+ t.Errorf("buffered data = %d; want 1", n)
+ }
+ peek, err := buf.Reader.Peek(3)
+ if string(peek) != "foo" || err != nil {
+ t.Errorf("Peek = %q, %v; want foo, nil", peek, err)
+ }
+ }))
+ defer ts.Close()
+
+ cn, err := net.Dial("tcp", ts.Listener.Addr().String())
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer cn.Close()
+ if _, err := cn.Write([]byte("GET / HTTP/1.1\r\nHost: e.com\r\n\r\n")); err != nil {
+ t.Fatal(err)
+ }
+ <-inHandler
+ if _, err := cn.Write([]byte("foo")); err != nil {
+ t.Fatal(err)
+ }
+
+ if err := cn.(*net.TCPConn).CloseWrite(); err != nil {
+ t.Fatal(err)
+ }
+ select {
+ case <-done:
+ case <-time.After(2 * time.Second):
+ t.Error("timeout")
+ }
+}
+
+// Like TestServerHijackGetsBackgroundByte above but sending a
+// immediate 1MB of data to the server to fill up the server's 4KB
+// buffer.
+func TestServerHijackGetsBackgroundByte_big(t *testing.T) {
+ if runtime.GOOS == "plan9" {
+ t.Skip("skipping test; see https://golang.org/issue/18657")
+ }
+ setParallel(t)
+ defer afterTest(t)
+ done := make(chan struct{})
+ const size = 8 << 10
+ ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+ defer close(done)
+
+ // Wait until the HTTP server sees the extra data
+ // after the GET request. The HTTP server fires the
+ // close notifier here, assuming it's a pipelined
+ // request, as documented.
+ select {
+ case <-w.(CloseNotifier).CloseNotify():
+ case <-time.After(5 * time.Second):
+ t.Error("timeout")
+ return
+ }
+
+ conn, buf, err := w.(Hijacker).Hijack()
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ defer conn.Close()
+ slurp, err := ioutil.ReadAll(buf.Reader)
+ if err != nil {
+ t.Error("Copy: %v", err)
+ }
+ allX := true
+ for _, v := range slurp {
+ if v != 'x' {
+ allX = false
+ }
+ }
+ if len(slurp) != size {
+ t.Errorf("read %d; want %d", len(slurp), size)
+ } else if !allX {
+ t.Errorf("read %q; want %d 'x'", slurp, size)
+ }
+ }))
+ defer ts.Close()
+
+ cn, err := net.Dial("tcp", ts.Listener.Addr().String())
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer cn.Close()
+ if _, err := fmt.Fprintf(cn, "GET / HTTP/1.1\r\nHost: e.com\r\n\r\n%s",
+ strings.Repeat("x", size)); err != nil {
+ t.Fatal(err)
+ }
+ if err := cn.(*net.TCPConn).CloseWrite(); err != nil {
+ t.Fatal(err)
+ }
+
+ select {
+ case <-done:
+ case <-time.After(2 * time.Second):
+ t.Error("timeout")
+ }
+}
diff --git a/src/net/http/server.go b/src/net/http/server.go
index 96236489bd..df70a15193 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -164,7 +164,7 @@ type Flusher interface {
// should always test for this ability at runtime.
type Hijacker interface {
// Hijack lets the caller take over the connection.
- // After a call to Hijack(), the HTTP server library
+ // After a call to Hijack the HTTP server library
// will not do anything else with the connection.
//
// It becomes the caller's responsibility to manage
@@ -174,6 +174,9 @@ type Hijacker interface {
// already set, depending on the configuration of the
// Server. It is the caller's responsibility to set
// or clear those deadlines as needed.
+ //
+ // The returned bufio.Reader may contain unprocessed buffered
+ // data from the client.
Hijack() (net.Conn, *bufio.ReadWriter, error)
}
@@ -293,6 +296,11 @@ func (c *conn) hijackLocked() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
rwc.SetDeadline(time.Time{})
buf = bufio.NewReadWriter(c.bufr, bufio.NewWriter(rwc))
+ if c.r.hasByte {
+ if _, err := c.bufr.Peek(c.bufr.Buffered() + 1); err != nil {
+ return nil, nil, fmt.Errorf("unexpected Peek failure reading buffered byte: %v", err)
+ }
+ }
c.setState(rwc, StateHijacked)
return
}
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index d5ddf6a123..a58b1839cc 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -36,6 +36,7 @@ import (
"strconv"
"strings"
"sync"
+ "sync/atomic"
"testing"
"time"
)
@@ -2545,6 +2546,13 @@ type closerFunc func() error
func (f closerFunc) Close() error { return f() }
+type writerFuncConn struct {
+ net.Conn
+ write func(p []byte) (n int, err error)
+}
+
+func (c writerFuncConn) Write(p []byte) (n int, err error) { return c.write(p) }
+
// Issue 4677. If we try to reuse a connection that the server is in the
// process of closing, we may end up successfully writing out our request (or a
// portion of our request) only to find a connection error when we try to read
@@ -2557,66 +2565,78 @@ func (f closerFunc) Close() error { return f() }
func TestRetryIdempotentRequestsOnError(t *testing.T) {
defer afterTest(t)
+ var (
+ mu sync.Mutex
+ logbuf bytes.Buffer
+ )
+ logf := func(format string, args ...interface{}) {
+ mu.Lock()
+ defer mu.Unlock()
+ fmt.Fprintf(&logbuf, format, args...)
+ logbuf.WriteByte('\n')
+ }
+
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+ logf("Handler")
+ w.Header().Set("X-Status", "ok")
}))
defer ts.Close()
- tr := &Transport{}
+ var writeNumAtomic int32
+ tr := &Transport{
+ Dial: func(network, addr string) (net.Conn, error) {
+ logf("Dial")
+ c, err := net.Dial(network, ts.Listener.Addr().String())
+ if err != nil {
+ logf("Dial error: %v", err)
+ return nil, err
+ }
+ return &writerFuncConn{
+ Conn: c,
+ write: func(p []byte) (n int, err error) {
+ if atomic.AddInt32(&writeNumAtomic, 1) == 2 {
+ logf("intentional write failure")
+ return 0, errors.New("second write fails")
+ }
+ logf("Write(%q)", p)
+ return c.Write(p)
+ },
+ }, nil
+ },
+ }
+ defer tr.CloseIdleConnections()
c := &Client{Transport: tr}
- const N = 2
- retryc := make(chan struct{}, N)
SetRoundTripRetried(func() {
- retryc <- struct{}{}
+ logf("Retried.")
})
defer SetRoundTripRetried(nil)
- for n := 0; n < 100; n++ {
- // open 2 conns
- errc := make(chan error, N)
- for i := 0; i < N; i++ {
- // start goroutines, send on errc
- go func() {
- res, err := c.Get(ts.URL)
- if err == nil {
- res.Body.Close()
- }
- errc <- err
- }()
- }
- for i := 0; i < N; i++ {
- if err := <-errc; err != nil {
- t.Fatal(err)
- }
- }
-
- ts.CloseClientConnections()
- for i := 0; i < N; i++ {
- go func() {
- res, err := c.Get(ts.URL)
- if err == nil {
- res.Body.Close()
- }
- errc <- err
- }()
+ for i := 0; i < 3; i++ {
+ res, err := c.Get("http://fake.golang/")
+ if err != nil {
+ t.Fatalf("i=%d: Get = %v", i, err)
}
+ res.Body.Close()
+ }
- for i := 0; i < N; i++ {
- if err := <-errc; err != nil {
- t.Fatal(err)
- }
- }
- for i := 0; i < N; i++ {
- select {
- case <-retryc:
- // we triggered a retry, test was successful
- t.Logf("finished after %d runs\n", n)
- return
- default:
- }
- }
+ mu.Lock()
+ got := logbuf.String()
+ mu.Unlock()
+ const want = `Dial
+Write("GET / HTTP/1.1\r\nHost: fake.golang\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n")
+Handler
+intentional write failure
+Retried.
+Dial
+Write("GET / HTTP/1.1\r\nHost: fake.golang\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n")
+Handler
+Write("GET / HTTP/1.1\r\nHost: fake.golang\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n")
+Handler
+`
+ if got != want {
+ t.Errorf("Log of events differs. Got:\n%s\nWant:\n%s", got, want)
}
- t.Fatal("did not trigger any retries")
}
// Issue 6981
diff --git a/src/os/os_test.go b/src/os/os_test.go
index b7300cd38c..7ad9aac70e 100644
--- a/src/os/os_test.go
+++ b/src/os/os_test.go
@@ -54,12 +54,15 @@ var sysdir = func() *sysDir {
case "darwin":
switch runtime.GOARCH {
case "arm", "arm64":
+ /// At this point the test harness has not had a chance
+ // to move us into the ./src/os directory, so the
+ // current working directory is the root of the app.
wd, err := syscall.Getwd()
if err != nil {
wd = err.Error()
}
return &sysDir{
- filepath.Join(wd, "..", ".."),
+ wd,
[]string{
"ResourceRules.plist",
"Info.plist",
diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go
index 033a18171d..022350b322 100644
--- a/src/reflect/all_test.go
+++ b/src/reflect/all_test.go
@@ -26,6 +26,8 @@ import (
"unsafe"
)
+var sink interface{}
+
func TestBool(t *testing.T) {
v := ValueOf(true)
if v.Bool() != true {
@@ -5331,6 +5333,72 @@ func TestCallGC(t *testing.T) {
f2("four", "five5", "six666", "seven77", "eight888")
}
+// Issue 18635 (function version).
+func TestKeepFuncLive(t *testing.T) {
+ // Test that we keep makeFuncImpl live as long as it is
+ // referenced on the stack.
+ typ := TypeOf(func(i int) {})
+ var f, g func(in []Value) []Value
+ f = func(in []Value) []Value {
+ clobber()
+ i := int(in[0].Int())
+ if i > 0 {
+ // We can't use Value.Call here because
+ // runtime.call* will keep the makeFuncImpl
+ // alive. However, by converting it to an
+ // interface value and calling that,
+ // reflect.callReflect is the only thing that
+ // can keep the makeFuncImpl live.
+ //
+ // Alternate between f and g so that if we do
+ // reuse the memory prematurely it's more
+ // likely to get obviously corrupted.
+ MakeFunc(typ, g).Interface().(func(i int))(i - 1)
+ }
+ return nil
+ }
+ g = func(in []Value) []Value {
+ clobber()
+ i := int(in[0].Int())
+ MakeFunc(typ, f).Interface().(func(i int))(i)
+ return nil
+ }
+ MakeFunc(typ, f).Call([]Value{ValueOf(10)})
+}
+
+// Issue 18635 (method version).
+type KeepMethodLive struct{}
+
+func (k KeepMethodLive) Method1(i int) {
+ clobber()
+ if i > 0 {
+ ValueOf(k).MethodByName("Method2").Interface().(func(i int))(i - 1)
+ }
+}
+
+func (k KeepMethodLive) Method2(i int) {
+ clobber()
+ ValueOf(k).MethodByName("Method1").Interface().(func(i int))(i)
+}
+
+func TestKeepMethodLive(t *testing.T) {
+ // Test that we keep methodValue live as long as it is
+ // referenced on the stack.
+ KeepMethodLive{}.Method1(10)
+}
+
+// clobber tries to clobber unreachable memory.
+func clobber() {
+ runtime.GC()
+ for i := 1; i < 32; i++ {
+ for j := 0; j < 10; j++ {
+ obj := make([]*byte, i)
+ sink = obj
+ }
+ }
+ runtime.GC()
+}
+
type funcLayoutTest struct {
rcvr, t Type
size, argsize, retOffset uintptr
diff --git a/src/reflect/value.go b/src/reflect/value.go
index 042414ffe7..699ba69408 100644
--- a/src/reflect/value.go
+++ b/src/reflect/value.go
@@ -538,6 +538,11 @@ func callReflect(ctxt *makeFuncImpl, frame unsafe.Pointer) {
off += typ.size
}
}
+
+ // runtime.getArgInfo expects to be able to find ctxt on the
+ // stack when it finds our caller, makeFuncStub. Make sure it
+ // doesn't get garbage collected.
+ runtime.KeepAlive(ctxt)
}
// methodReceiver returns information about the receiver
@@ -650,6 +655,9 @@ func callMethod(ctxt *methodValue, frame unsafe.Pointer) {
// though it's a heap object.
memclrNoHeapPointers(args, frametype.size)
framePool.Put(args)
+
+ // See the comment in callReflect.
+ runtime.KeepAlive(ctxt)
}
// funcName returns the name of f, for use in error messages.
diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go
index 64a2f3abef..0b996d8950 100644
--- a/src/runtime/mgc.go
+++ b/src/runtime/mgc.go
@@ -1129,8 +1129,6 @@ top:
// sitting in the per-P work caches.
// Flush and disable work caches.
- gcMarkRootCheck()
-
// Disallow caching workbufs and indicate that we're in mark 2.
gcBlackenPromptly = true
@@ -1153,6 +1151,16 @@ top:
})
})
+ // Check that roots are marked. We should be able to
+ // do this before the forEachP, but based on issue
+ // #16083 there may be a (harmless) race where we can
+ // enter mark 2 while some workers are still scanning
+ // stacks. The forEachP ensures these scans are done.
+ //
+ // TODO(austin): Figure out the race and fix this
+ // properly.
+ gcMarkRootCheck()
+
// Now we can start up mark 2 workers.
atomic.Xaddint64(&gcController.dedicatedMarkWorkersNeeded, 0xffffffff)
atomic.Xaddint64(&gcController.fractionalMarkWorkersNeeded, 0xffffffff)
diff --git a/src/runtime/plugin.go b/src/runtime/plugin.go
index 80869e1b1c..8edb29c9fe 100644
--- a/src/runtime/plugin.go
+++ b/src/runtime/plugin.go
@@ -56,7 +56,9 @@ func plugin_lastmoduleinit() (path string, syms map[string]interface{}, mismatch
lock(&ifaceLock)
for _, i := range md.itablinks {
- additab(i, true, false)
+ if i.inhash == 0 {
+ additab(i, true, false)
+ }
}
unlock(&ifaceLock)
diff --git a/src/runtime/sys_linux_amd64.s b/src/runtime/sys_linux_amd64.s
index 839df16406..6ddcb30ae2 100644
--- a/src/runtime/sys_linux_amd64.s
+++ b/src/runtime/sys_linux_amd64.s
@@ -330,9 +330,9 @@ sigtrampnog:
// Lock sigprofCallersUse.
MOVL $0, AX
MOVL $1, CX
- MOVQ $runtime·sigprofCallersUse(SB), BX
+ MOVQ $runtime·sigprofCallersUse(SB), R11
LOCK
- CMPXCHGL CX, 0(BX)
+ CMPXCHGL CX, 0(R11)
JNZ sigtramp // Skip stack trace if already locked.
// Jump to the traceback function in runtime/cgo.
diff --git a/src/syscall/mkpost.go b/src/syscall/mkpost.go
index 26aeec843f..e75ba1502a 100644
--- a/src/syscall/mkpost.go
+++ b/src/syscall/mkpost.go
@@ -18,6 +18,7 @@ import (
"log"
"os"
"regexp"
+ "strings"
)
func main() {
@@ -38,10 +39,16 @@ func main() {
re = regexp.MustCompile("Pad_cgo[A-Za-z0-9_]*")
s = re.ReplaceAllString(s, "_")
+ // We want to keep X__val in Fsid. Hide it and restore it later.
+ s = strings.Replace(s, "X__val", "MKPOSTFSIDVAL", 1)
+
// Replace other unwanted fields with blank identifiers.
re = regexp.MustCompile("X_[A-Za-z0-9_]*")
s = re.ReplaceAllString(s, "_")
+ // Restore X__val in Fsid.
+ s = strings.Replace(s, "MKPOSTFSIDVAL", "X__val", 1)
+
// Force the type of RawSockaddr.Data to [14]int8 to match
// the existing gccgo API.
re = regexp.MustCompile("(Data\\s+\\[14\\])uint8")
diff --git a/src/syscall/ztypes_linux_s390x.go b/src/syscall/ztypes_linux_s390x.go
index cdde47863f..63c4a83b19 100644
--- a/src/syscall/ztypes_linux_s390x.go
+++ b/src/syscall/ztypes_linux_s390x.go
@@ -140,7 +140,7 @@ type Dirent struct {
}
type Fsid struct {
- _ [2]int32
+ X__val [2]int32
}
type Flock_t struct {
diff --git a/src/testing/benchmark.go b/src/testing/benchmark.go
index c033ce5fec..bcebb418c4 100644
--- a/src/testing/benchmark.go
+++ b/src/testing/benchmark.go
@@ -219,7 +219,7 @@ func (b *B) run1() bool {
}
// Only print the output if we know we are not going to proceed.
// Otherwise it is printed in processBench.
- if b.hasSub || b.finished {
+ if atomic.LoadInt32(&b.hasSub) != 0 || b.finished {
tag := "BENCH"
if b.skipped {
tag = "SKIP"
@@ -460,10 +460,13 @@ func (ctx *benchContext) processBench(b *B) {
//
// A subbenchmark is like any other benchmark. A benchmark that calls Run at
// least once will not be measured itself and will be called once with N=1.
+//
+// Run may be called simultaneously from multiple goroutines, but all such
+// calls must happen before the outer benchmark function for b returns.
func (b *B) Run(name string, f func(b *B)) bool {
// Since b has subbenchmarks, we will no longer run it as a benchmark itself.
// Release the lock and acquire it on exit to ensure locks stay paired.
- b.hasSub = true
+ atomic.StoreInt32(&b.hasSub, 1)
benchmarkLock.Unlock()
defer benchmarkLock.Lock()
diff --git a/src/testing/sub_test.go b/src/testing/sub_test.go
index 8d5d9206f0..bb7b3e0925 100644
--- a/src/testing/sub_test.go
+++ b/src/testing/sub_test.go
@@ -6,6 +6,7 @@ package testing
import (
"bytes"
+ "fmt"
"regexp"
"strings"
"sync/atomic"
@@ -515,3 +516,19 @@ func TestBenchmarkOutput(t *T) {
Benchmark(func(b *B) { b.Error("do not print this output") })
Benchmark(func(b *B) {})
}
+
+func TestParallelSub(t *T) {
+ c := make(chan int)
+ block := make(chan int)
+ for i := 0; i < 10; i++ {
+ go func(i int) {
+ <-block
+ t.Run(fmt.Sprint(i), func(t *T) {})
+ c <- 1
+ }(i)
+ }
+ close(block)
+ for i := 0; i < 10; i++ {
+ <-c
+ }
+}
diff --git a/src/testing/testing.go b/src/testing/testing.go
index c972b2737f..ddbdc25bf1 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -216,6 +216,7 @@ import (
"strconv"
"strings"
"sync"
+ "sync/atomic"
"time"
)
@@ -267,8 +268,8 @@ type common struct {
skipped bool // Test of benchmark has been skipped.
finished bool // Test function has completed.
done bool // Test is finished and all subtests have completed.
- hasSub bool
- raceErrors int // number of races detected during test
+ hasSub int32 // written atomically
+ raceErrors int // number of races detected during test
parent *common
level int // Nesting depth of test or benchmark.
@@ -645,7 +646,7 @@ func tRunner(t *T, fn func(t *T)) {
// Do not lock t.done to allow race detector to detect race in case
// the user does not appropriately synchronizes a goroutine.
t.done = true
- if t.parent != nil && !t.hasSub {
+ if t.parent != nil && atomic.LoadInt32(&t.hasSub) == 0 {
t.setRan()
}
t.signal <- true
@@ -659,8 +660,11 @@ func tRunner(t *T, fn func(t *T)) {
// Run runs f as a subtest of t called name. It reports whether f succeeded.
// Run will block until all its parallel subtests have completed.
+//
+// Run may be called simultaneously from multiple goroutines, but all such
+// calls must happen before the outer test function for t returns.
func (t *T) Run(name string, f func(t *T)) bool {
- t.hasSub = true
+ atomic.StoreInt32(&t.hasSub, 1)
testName, ok := t.context.match.fullName(&t.common, name)
if !ok {
return true
diff --git a/src/vendor/golang_org/x/crypto/poly1305/sum_amd64.s b/src/vendor/golang_org/x/crypto/poly1305/sum_amd64.s
index bc75c61afc..2edae63828 100644
--- a/src/vendor/golang_org/x/crypto/poly1305/sum_amd64.s
+++ b/src/vendor/golang_org/x/crypto/poly1305/sum_amd64.s
@@ -54,9 +54,9 @@
ADCQ t3, h1; \
ADCQ $0, h2
-DATA poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
-DATA poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
-GLOBL poly1305Mask<>(SB), RODATA, $16
+DATA ·poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
+DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
+GLOBL ·poly1305Mask<>(SB), RODATA, $16
// func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]key)
TEXT ·poly1305(SB), $0-32
@@ -67,8 +67,8 @@ TEXT ·poly1305(SB), $0-32
MOVQ 0(AX), R11
MOVQ 8(AX), R12
- ANDQ poly1305Mask<>(SB), R11 // r0
- ANDQ poly1305Mask<>+8(SB), R12 // r1
+ ANDQ ·poly1305Mask<>(SB), R11 // r0
+ ANDQ ·poly1305Mask<>+8(SB), R12 // r1
XORQ R8, R8 // h0
XORQ R9, R9 // h1
XORQ R10, R10 // h2
diff --git a/src/vendor/golang_org/x/crypto/poly1305/sum_arm.s b/src/vendor/golang_org/x/crypto/poly1305/sum_arm.s
index 93167b2712..f70b4ac484 100644
--- a/src/vendor/golang_org/x/crypto/poly1305/sum_arm.s
+++ b/src/vendor/golang_org/x/crypto/poly1305/sum_arm.s
@@ -9,12 +9,12 @@
// This code was translated into a form compatible with 5a from the public
// domain source by Andrew Moon: github.com/floodyberry/poly1305-opt/blob/master/app/extensions/poly1305.
-DATA poly1305_init_constants_armv6<>+0x00(SB)/4, $0x3ffffff
-DATA poly1305_init_constants_armv6<>+0x04(SB)/4, $0x3ffff03
-DATA poly1305_init_constants_armv6<>+0x08(SB)/4, $0x3ffc0ff
-DATA poly1305_init_constants_armv6<>+0x0c(SB)/4, $0x3f03fff
-DATA poly1305_init_constants_armv6<>+0x10(SB)/4, $0x00fffff
-GLOBL poly1305_init_constants_armv6<>(SB), 8, $20
+DATA ·poly1305_init_constants_armv6<>+0x00(SB)/4, $0x3ffffff
+DATA ·poly1305_init_constants_armv6<>+0x04(SB)/4, $0x3ffff03
+DATA ·poly1305_init_constants_armv6<>+0x08(SB)/4, $0x3ffc0ff
+DATA ·poly1305_init_constants_armv6<>+0x0c(SB)/4, $0x3f03fff
+DATA ·poly1305_init_constants_armv6<>+0x10(SB)/4, $0x00fffff
+GLOBL ·poly1305_init_constants_armv6<>(SB), 8, $20
// Warning: the linker may use R11 to synthesize certain instructions. Please
// take care and verify that no synthetic instructions use it.
@@ -27,7 +27,7 @@ TEXT poly1305_init_ext_armv6<>(SB), NOSPLIT, $0
ADD $4, R13, R8
MOVM.IB [R4-R7], (R8)
MOVM.IA.W (R1), [R2-R5]
- MOVW $poly1305_init_constants_armv6<>(SB), R7
+ MOVW $·poly1305_init_constants_armv6<>(SB), R7
MOVW R2, R8
MOVW R2>>26, R9
MOVW R3>>20, g
diff --git a/test/fixedbugs/issue18661.go b/test/fixedbugs/issue18661.go
new file mode 100644
index 0000000000..8c83775200
--- /dev/null
+++ b/test/fixedbugs/issue18661.go
@@ -0,0 +1,18 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+var (
+ e interface{}
+ s = struct{ a *int }{}
+ b = e == s
+)
+
+func test(obj interface{}) {
+ if obj != struct{ a *string }{} {
+ }
+}