aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Broadfoot <cbro@golang.org>2017-08-07 10:28:03 -0700
committerChris Broadfoot <cbro@golang.org>2017-08-07 10:28:35 -0700
commitcff0de3da338f8aa4682253a9cc045bd70a8c9c4 (patch)
tree8bd04b4ff762c8ccbdf3ea785ac183e327d93081
parent196492a299337f532d743556a6f6be37e9dff94f (diff)
parent579120323fdf0c6939fa3e3c6c63b669b6437e31 (diff)
downloadgo-cff0de3da338f8aa4682253a9cc045bd70a8c9c4.tar.gz
go-cff0de3da338f8aa4682253a9cc045bd70a8c9c4.zip
[release-branch.go1.9] all: merge master into release-branch.go1.9
579120323f runtime: mapassign_* should use typedmemmove to update keys 380525598c all: remove some manual hyphenation f096b5b340 runtime: mark activeModules nosplit/nowritebarrier 3e3da54633 math/bits: fix example for OnesCount64 9b1e7cf2ac math/bits: add examples for OnesCount functions b01db023b1 misc/cgo/testsanitizers: also skip tsan11/tsan12 when using GCC a279b53a18 reflect: document how DeepEqual handles cycles 909f409a8d doc: mention handling of moved GOROOT in 1.9 release notes 58ad0176ca doc: use better wording to explain type-aware completion 92dac21d29 doc: replace paid with commercial 9bb98e02de doc/1.9: add CL 43712, ReverseProxy of HTTP/2 trailers to the release notes. 78d74fc2cd doc: clarify that Gogland is for paid IntelliJ platform IDEs 5495047223 doc/1.9: fix broken html link in CL 53030/53210 890e0e862f doc: fix bad link in go1.9 release notes be596f049a doc/1.9: fix stray html in CL 53030 0173631d53 encoding/binary: add examples for varint functions ac0ccf3cd2 doc/1.9: add CL 36696 for crypto/x509 to the release notes cc402c2c4d doc: hide blog content for golang.google.cn f396fa4285 internal/poll: don't add non-sockets to runtime poller 664cd26c89 cmd/vet: don't exit with failure on type checking error a8730cd93a doc: hide video and share if being served from CN b63db76c4a testsanitizers: check that tsan program runs, skip tsan10 on gcc 193eda7291 time: skip ZoneAbbr test in timezones with no abbreviation 6f08c935a9 cmd/go: show examples with empty output in go test -list f20944de78 cmd/compile: set/unset base register for better assembly print 623e2c4603 runtime: map bitmap and spans during heap initialization 780249eed4 runtime: fall back to small mmaps if we fail to grow reservation 31b2c4cc25 .github: add .md extension to SUPPORT file ac29f30dbb plugin: mention that there are known bugs with plugins 45a4609c0a cmd/dist: skip moved GOROOT on Go's Windows builders when not sharding tests e157fac02d test: add README 835dfef939 runtime/pprof: prevent a deadlock that SIGPROF might create on mips{,le} df91b8044d doc: list editor options by name, not plugin name 3d9475c04b doc: cleanup editor page b9661a14ea doc: add Atom to editor guide ee392ac10c cmd/compile: consider exported flag in namedata Change-Id: I3a48493e8c05d97cb3b61635503ef0ccd646e5cb
-rw-r--r--.github/SUPPORT.md (renamed from .github/SUPPORT)0
-rw-r--r--doc/editors.html49
-rw-r--r--doc/editors/go-plus.pngbin0 -> 15558 bytes
-rw-r--r--doc/go1.9.html36
-rw-r--r--doc/root.html152
-rw-r--r--misc/cgo/errors/ptr.go8
-rwxr-xr-xmisc/cgo/testsanitizers/test.bash29
-rw-r--r--src/cmd/compile/internal/arm/ssa.go2
-rw-r--r--src/cmd/compile/internal/arm64/ssa.go2
-rw-r--r--src/cmd/compile/internal/gc/asm_test.go24
-rw-r--r--src/cmd/compile/internal/mips/ssa.go2
-rw-r--r--src/cmd/compile/internal/mips64/ssa.go2
-rw-r--r--src/cmd/compile/internal/ppc64/ssa.go2
-rw-r--r--src/cmd/go/go_test.go17
-rw-r--r--src/cmd/go/testdata/src/testlist/bench_test.go14
-rw-r--r--src/cmd/go/testdata/src/testlist/example_test.go21
-rw-r--r--src/cmd/go/testdata/src/testlist/test_test.go10
-rw-r--r--src/cmd/internal/obj/arm/asm5.go20
-rw-r--r--src/cmd/internal/obj/arm64/asm7.go20
-rw-r--r--src/cmd/internal/obj/mips/asm0.go20
-rw-r--r--src/cmd/internal/obj/ppc64/asm9.go20
-rw-r--r--src/cmd/internal/obj/s390x/asmz.go20
-rw-r--r--src/cmd/vet/main.go5
-rw-r--r--src/cmd/vet/testdata/cgo/cgo3.go13
-rw-r--r--src/cmd/vet/vet_test.go12
-rw-r--r--src/encoding/binary/example_test.go91
-rw-r--r--src/go/ast/ast.go8
-rw-r--r--src/go/parser/parser.go4
-rw-r--r--src/internal/poll/fd_windows.go21
-rw-r--r--src/math/big/ratconv.go4
-rw-r--r--src/math/bits/example_test.go40
-rw-r--r--src/plugin/plugin.go5
-rw-r--r--src/reflect/deepequal.go6
-rw-r--r--src/runtime/cpuprof.go9
-rw-r--r--src/runtime/hashmap_fast.go8
-rw-r--r--src/runtime/pprof/pprof_test.go31
-rw-r--r--src/runtime/proc.go31
-rw-r--r--src/runtime/symtab.go5
-rw-r--r--src/testing/testing.go2
-rw-r--r--src/time/zoneinfo_windows_test.go8
-rw-r--r--test/README.md15
41 files changed, 662 insertions, 126 deletions
diff --git a/.github/SUPPORT b/.github/SUPPORT.md
index 9a4d7b2759..9a4d7b2759 100644
--- a/.github/SUPPORT
+++ b/.github/SUPPORT.md
diff --git a/doc/editors.html b/doc/editors.html
index 1448781036..264f5af920 100644
--- a/doc/editors.html
+++ b/doc/editors.html
@@ -19,11 +19,12 @@ editing, navigation, testing, and debugging experience.
</p>
<ul>
-<li><a href="https://github.com/fatih/vim-go">Vim Go</a>: a plugin for Vim to provide Go programming language support</li>
-<li><a href="https://marketplace.visualstudio.com/items?itemName=lukehoban.Go">Visual Studio Code Go</a>:
-an extension for Visual Studio Code to provide support for the Go programming language</li>
+<li><a href="https://github.com/fatih/vim-go">vim</a>: vim-go plugin provides Go programming language support</li>
+<li><a href="https://marketplace.visualstudio.com/items?itemName=lukehoban.Go">Visual Studio Code</a>:
+Go extension provides support for the Go programming language</li>
<li><a href="https://www.jetbrains.com/go">Gogland</a>: Gogland is distributed either as a standalone IDE
-or as a plugin for the IntelliJ Platform IDEs</li>
+or as a plugin for the commercial IntelliJ Platform IDEs</li>
+<li><a href="https://atom.io/packages/go-plus">Atom</a>: Go-Plus is an Atom package that provides enhanced Go support</li>
</ul>
<p>
@@ -41,133 +42,155 @@ The following feature matrix lists and compares the most significant features.
<table class="features-matrix">
<tr>
<th></th>
- <th><img title="Vim Go" src="/doc/editors/vimgo.png"><br>Vim Go</th>
- <th><img title="Visual Studio Code" src="/doc/editors/vscodego.png"><br>Visual Studio Code Go</th>
+ <th><img title="Vim Go" src="/doc/editors/vimgo.png"><br>vim</th>
+ <th><img title="Visual Studio Code" src="/doc/editors/vscodego.png"><br>Visual Studio Code</th>
<th><img title="Gogland" src="/doc/editors/gogland.png"><br>Gogland</th>
+ <th><img title="Go-Plus" src="/doc/editors/go-plus.png"><br>Atom</th>
</tr>
<tr>
- <td class="feature-row" colspan="4">Editing features</td>
+ <td class="feature-row" colspan="5">Editing features</td>
</tr>
<tr>
<td>Build and run from the editor/IDE</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
+ <td class="yes">Yes</td>
</tr>
<tr>
<td>Autocompletion of identifers (variable, method, and function names)</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
+ <td class="yes">Yes</td>
</tr>
<tr>
- <td>Autocompletion based on type</td>
+ <td>Type-aware autocompletion</td>
<td class="no">No</td>
<td class="no">No</td>
<td class="yes">Yes</td>
+ <td class="no">No</td>
</tr>
<tr>
<td>Rename identifiers</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
+ <td class="yes">Yes</td>
</tr>
<tr>
<td>Auto format, build, vet, and lint on save</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes<sup>1</sup></td>
+ <td class="yes">Yes</td>
</tr>
<tr>
<td>Auto insert import paths and remove unused on save</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes<sup>2</sup></td>
+ <td class="yes">Yes</td>
</tr>
<tr>
<td>Auto generate JSON, XML tags for struct fields</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
+ <td class="yes">Yes</td>
</tr>
<tr>
- <td class="feature-row" colspan="4">Navigation features</td>
+ <td class="feature-row" colspan="5">Navigation features</td>
</tr>
<tr>
<td>Display documentation inline, or open godoc in browser</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
+ <td class="yes">Yes</td>
</tr>
<tr>
<td>Switch between <code>*.go</code> and <code>*_test.go</code> file</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
+ <td class="yes">No</td>
</tr>
<tr>
<td>Jump to definition and referees</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
+ <td class="yes">Yes</td>
</tr>
<tr>
<td>Look up for interface implementations</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
+ <td class="yes">Yes</td>
</tr>
<tr>
<td>Search for callers and callees</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
+ <td class="yes">Yes</td>
</tr>
<tr>
- <td class="feature-row" colspan="4">Testing and debugging features</td>
+ <td class="feature-row" colspan="5">Testing and debugging features</td>
</tr>
<tr>
<td>Debugger support</td>
<td class="no">No</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
+ <td class="yes">Yes<sup>3</sup></td>
+
</tr>
<tr>
<td>Run a single test case, all tests from file, or all tests from a package</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
+ <td class="no">No</td>
</tr>
<tr>
<td>Auto generate tests for packages, files and identifiers</td>
<td class="no">No</td>
<td class="yes">Yes</td>
<td class="no">No</td>
+ <td class="no">No</td>
</tr>
<tr>
<td>Debug tests</td>
<td class="no">No</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
+ <td class="yes">Yes<sup>3</sup></td>
</tr>
<tr>
<td>Display test coverage</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
+ <td class="yes">Yes</td>
</tr>
<tr class="download">
<td></td>
<td><a href="https://github.com/fatih/vim-go">Install<a/></td>
<td><a href="https://marketplace.visualstudio.com/items?itemName=lukehoban.Go">Install<a/></td>
<td><a href="https://www.jetbrains.com/go">Install<a/></td>
+ <td><a href="https://atom.io/packages/go-plus">Install</a></td>
</tr>
</table>
<p>
-<sup>1</sup>: Possible when enabled via Settings &gt; Go &gt; On Save, <code>go</code> <code>vet</code> and <code>golint</code> are available via plugins. Also runs tests on save if configured.
+<sup>1</sup>Possible when enabled via Settings &gt; Go &gt; On Save, <code>go</code> <code>vet</code> and <code>golint</code> are available via plugins. Also runs tests on save if configured.
<br>
-<sup>2</sup>: Additionally, user input can disambiguate when two or more options are available.
+<sup>2</sup>Additionally, user input can disambiguate when two or more options are available.
+<br>
+<sup>3</sup>Available if the <a href="https://atom.io/packages/go-debug">go-debug</a> package is installed.
</p>
</div>
@@ -206,5 +229,3 @@ The following feature matrix lists and compares the most significant features.
font-weight: bold;
}
</style>
-
-<!--TODO(jbd): Add the Atom comparison--> \ No newline at end of file
diff --git a/doc/editors/go-plus.png b/doc/editors/go-plus.png
new file mode 100644
index 0000000000..c09c7fe675
--- /dev/null
+++ b/doc/editors/go-plus.png
Binary files differ
diff --git a/doc/go1.9.html b/doc/go1.9.html
index be0ceefcd5..7cee379c45 100644
--- a/doc/go1.9.html
+++ b/doc/go1.9.html
@@ -156,6 +156,21 @@ type T1 = T2
directories, write <code>./vendor/...</code>.
</p>
+<h3 id="goroot">Moved GOROOT</h3>
+
+<p><!-- CL 42533 -->
+ The <a href="/cmd/go/">go tool</a> will now use the path from which it
+ was invoked to attempt to locate the root of the Go install tree.
+ This means that if the entire Go installation is moved to a new
+ location, the go tool should continue to work as usual.
+ This may be overriden by setting <code>GOROOT</code> in the environment,
+ which should only be done in unusual circumstances.
+ Note that this does not affect the result of
+ the <a href="/pkg/runtime/#GOROOT">runtime.GOROOT</a> function, which
+ will continue to report the original installation location;
+ this may be fixed in later releases.
+</p>
+
<h3 id="compiler">Compiler Toolchain</h3>
<p><!-- CL 37441 -->
@@ -473,6 +488,15 @@ version of gccgo.
populated.
</p>
+ <p><!-- CL 36696 -->
+
+ If any SAN extension, including with no DSN names, is present
+ in the certificate, then the Common Name from
+ <a href="/pkg/crypto/x509/#Certificate.Subject"><code>Subject</code></a> is ignored.
+ In previous releases, the code tested only whether DNS-name SANs were
+ present in a certificate.
+ </p>
+
</dl><!-- crypto/x509 -->
<dl id="database/sql"><dt><a href="/pkg/database/sql/">database/sql</a></dt>
@@ -728,7 +752,7 @@ version of gccgo.
<li><!-- CL 35488 -->
The <a href="/pkg/net/http/#Transport"><code>Transport</code></a>
now supports making requests via SOCKS5 proxy when the URL returned by
- <a href="/net/http/#Transport.Proxy"><code>Transport.Proxy</code></a>
+ <a href="/pkg/net/http/#Transport.Proxy"><code>Transport.Proxy</code></a>
has the scheme <code>socks5</code>.
</li>
</ul>
@@ -764,6 +788,16 @@ version of gccgo.
</dl><!-- net/http/httptest -->
+<dl id="net/http/httputil"><dt><a href="/pkg/net/http/httputil/">net/http/httputil</a></dt>
+ <dd>
+ <p><!-- CL 43712 -->
+ The <a href="/pkg/net/http/httputil/#ReverseProxy"><code>ReverseProxy</code></a>
+ now proxies all HTTP/2 response trailers, even those not declared in the initial response
+ header. Such undeclared trailers are used by the gRPC protocol.
+ </p>
+
+</dl><!-- net/http/httputil -->
+
<dl id="os"><dt><a href="/pkg/os/">os</a></dt>
<dd>
<p><!-- CL 36800 -->
diff --git a/doc/root.html b/doc/root.html
index 27dbc74ab6..9bdf927480 100644
--- a/doc/root.html
+++ b/doc/root.html
@@ -6,7 +6,9 @@
<div class="left">
<div id="learn">
+{{if not $.GoogleCN}}
<a class="popout share">Pop-out</a>
+{{end}}
<div class="rootHeading">Try Go</div>
<div class="input">
<textarea spellcheck="false" class="code">// You can edit this code!
@@ -26,10 +28,10 @@ Hello, 世界
</div>
<div class="buttons">
<a class="run" href="#" title="Run this code [shift-enter]">Run</a>
-{{if $.Share}}
+{{if not $.GoogleCN}}
<a class="share" href="#" title="Share this code">Share</a>
-{{end}}
<a class="tour" href="//tour.golang.org/" title="Learn Go from your browser">Tour</a>
+{{end}}
</div>
<div class="toys">
<select>
@@ -68,85 +70,91 @@ Linux, Mac OS X, Windows, and more.
<div style="clear: both"></div>
+{{if not $.GoogleCN}}
<div class="left">
-
-<div id="video">
-<div class="rootHeading">Featured video</div>
-<iframe width="415" height="241" src="//www.youtube.com/embed/ytEkHepK08c" frameborder="0" allowfullscreen></iframe>
-</div>
-
+ <div id="video">
+ <div class="rootHeading">Featured video</div>
+ <iframe width="415" height="241" src="//www.youtube.com/embed/ytEkHepK08c" frameborder="0" allowfullscreen></iframe>
+ </div>
</div>
<div class="right">
-
-<div id="blog">
-<div class="rootHeading">Featured articles</div>
-<div class="read"><a href="//blog.golang.org/">Read more</a></div>
-</div>
-
+ <div id="blog">
+ <div class="rootHeading">Featured articles</div>
+ <div class="read"><a href="//blog.golang.org/">Read more</a></div>
+ </div>
</div>
+{{end}}
<div style="clear: both;"></div>
-<script type="text/javascript">
-
-function readableTime(t) {
- var m = ["January", "February", "March", "April", "May", "June", "July",
- "August", "September", "October", "November", "December"];
- var p = t.substring(0, t.indexOf("T")).split("-");
- var d = new Date(p[0], p[1]-1, p[2]);
- return d.getDate() + " " + m[d.getMonth()] + " " + d.getFullYear();
-}
-
-function feedLoaded(result) {
- var blog = document.getElementById("blog");
- var read = blog.getElementsByClassName("read")[0];
- for (var i = 0; i < result.length && i < 2; i++) {
- var entry = result[i];
- var title = document.createElement("a");
- title.className = "title";
- title.href = entry.Link;
- title.innerHTML = entry.Title;
- blog.insertBefore(title, read);
- var extract = document.createElement("div");
- extract.className = "extract";
- extract.innerHTML = entry.Summary;
- blog.insertBefore(extract, read);
- var when = document.createElement("div");
- when.className = "when";
- when.innerHTML = "Published " + readableTime(entry.Time);
- blog.insertBefore(when, read);
- }
-}
-
-window.initFuncs.push(function() {
- // Set up playground if enabled.
- if (window.playground) {
- window.playground({
- "codeEl": "#learn .code",
- "outputEl": "#learn .output",
- "runEl": "#learn .run",
- "shareEl": "#learn .share",
- "shareRedirect": "//play.golang.org/p/",
- "toysEl": "#learn .toys select"
- });
- } else {
- $('#learn').hide()
+<script>
+(function() {
+ 'use strict';
+
+ window.initFuncs.push(function() {
+ // Set up playground if enabled.
+ if (window.playground) {
+ window.playground({
+ "codeEl": "#learn .code",
+ "outputEl": "#learn .output",
+ "runEl": "#learn .run",
+ "shareEl": "#learn .share",
+ "shareRedirect": "//play.golang.org/p/",
+ "toysEl": "#learn .toys select"
+ });
+ } else {
+ $('#learn').hide()
+ }
+ });
+
+ {{if not $.GoogleCN}}
+
+ function readableTime(t) {
+ var m = ["January", "February", "March", "April", "May", "June", "July",
+ "August", "September", "October", "November", "December"];
+ var p = t.substring(0, t.indexOf("T")).split("-");
+ var d = new Date(p[0], p[1]-1, p[2]);
+ return d.getDate() + " " + m[d.getMonth()] + " " + d.getFullYear();
}
- // Load blog feed.
- $('<script/>').attr('text', 'text/javascript')
- .attr('src', '//blog.golang.org/.json?jsonp=feedLoaded')
- .appendTo('body');
-
- // Set the video at random.
- var videos = [
- {h: 241, s: "//www.youtube.com/embed/ytEkHepK08c"}, // Tour of Go
- {h: 241, s: "//www.youtube.com/embed/f6kdp27TYZs"}, // Concurrency Patterns
- {h: 233, s: "//player.vimeo.com/video/69237265"} // Simple environment
- ];
- var v = videos[Math.floor(Math.random()*videos.length)];
- $('#video iframe').attr('height', v.h).attr('src', v.s);
-});
+ window.feedLoaded = function(result) {
+ var blog = document.getElementById("blog");
+ var read = blog.getElementsByClassName("read")[0];
+ for (var i = 0; i < result.length && i < 2; i++) {
+ var entry = result[i];
+ var title = document.createElement("a");
+ title.className = "title";
+ title.href = entry.Link;
+ title.innerHTML = entry.Title;
+ blog.insertBefore(title, read);
+ var extract = document.createElement("div");
+ extract.className = "extract";
+ extract.innerHTML = entry.Summary;
+ blog.insertBefore(extract, read);
+ var when = document.createElement("div");
+ when.className = "when";
+ when.innerHTML = "Published " + readableTime(entry.Time);
+ blog.insertBefore(when, read);
+ }
+ }
+ window.initFuncs.push(function() {
+ // Load blog feed.
+ $('<script/>').attr('text', 'text/javascript')
+ .attr('src', '//blog.golang.org/.json?jsonp=feedLoaded')
+ .appendTo('body');
+
+ // Set the video at random.
+ var videos = [
+ {h: 241, s: "//www.youtube.com/embed/ytEkHepK08c"}, // Tour of Go
+ {h: 241, s: "//www.youtube.com/embed/f6kdp27TYZs"}, // Concurrency Patterns
+ {h: 233, s: "//player.vimeo.com/video/69237265"} // Simple environment
+ ];
+ var v = videos[Math.floor(Math.random()*videos.length)];
+ $('#video iframe').attr('height', v.h).attr('src', v.s);
+ });
+
+ {{end}}
+})();
</script>
diff --git a/misc/cgo/errors/ptr.go b/misc/cgo/errors/ptr.go
index 4dafbdf3c0..3e117666bf 100644
--- a/misc/cgo/errors/ptr.go
+++ b/misc/cgo/errors/ptr.go
@@ -343,6 +343,14 @@ var ptrTests = []ptrTest{
body: `var b C.char; p := &b; C.f((*C.u)(unsafe.Pointer(&p)))`,
fail: false,
},
+ {
+ // Issue #21306.
+ name: "preempt-during-call",
+ c: `void f() {}`,
+ imports: []string{"runtime", "sync"},
+ body: `var wg sync.WaitGroup; wg.Add(100); for i := 0; i < 100; i++ { go func(i int) { for j := 0; j < 100; j++ { C.f(); runtime.GOMAXPROCS(i) }; wg.Done() }(i) }; wg.Wait()`,
+ fail: false,
+ },
}
func main() {
diff --git a/misc/cgo/testsanitizers/test.bash b/misc/cgo/testsanitizers/test.bash
index ea08f37432..9f80af6c50 100755
--- a/misc/cgo/testsanitizers/test.bash
+++ b/misc/cgo/testsanitizers/test.bash
@@ -156,15 +156,18 @@ if test "$tsan" = "yes"; then
if ! $CC -fsanitize=thread ${TMPDIR}/testsanitizers$$.c -o ${TMPDIR}/testsanitizers$$ &> ${TMPDIR}/testsanitizers$$.err; then
ok=no
fi
- if grep "unrecognized" ${TMPDIR}/testsanitizers$$.err >& /dev/null; then
+ if grep "unrecognized" ${TMPDIR}/testsanitizers$$.err >& /dev/null; then
echo "skipping tsan tests: -fsanitize=thread not supported"
tsan=no
- elif test "$ok" != "yes"; then
- cat ${TMPDIR}/testsanitizers$$.err
- echo "skipping tsan tests: -fsanitizer=thread build failed"
- tsan=no
- fi
- rm -f ${TMPDIR}/testsanitizers$$*
+ elif test "$ok" != "yes"; then
+ cat ${TMPDIR}/testsanitizers$$.err
+ echo "skipping tsan tests: -fsanitizer=thread build failed"
+ tsan=no
+ elif ! ${TMPDIR}/testsanitizers$$ 2>&1; then
+ echo "skipping tsan tests: running tsan program failed"
+ tsan=no
+ fi
+ rm -f ${TMPDIR}/testsanitizers$$*
fi
# Run a TSAN test.
@@ -196,8 +199,10 @@ if test "$tsan" = "yes"; then
# These tests are only reliable using clang or GCC version 7 or later.
# Otherwise runtime/cgo/libcgo.h can't tell whether TSAN is in use.
ok=false
+ clang=false
if ${CC} --version | grep clang >/dev/null 2>&1; then
ok=true
+ clang=true
else
ver=$($CC -dumpversion)
major=$(echo $ver | sed -e 's/\([0-9]*\).*/\1/')
@@ -213,9 +218,13 @@ if test "$tsan" = "yes"; then
testtsan tsan5.go "CGO_CFLAGS=-fsanitize=thread CGO_LDFLAGS=-fsanitize=thread" "-installsuffix=tsan"
testtsan tsan6.go "CGO_CFLAGS=-fsanitize=thread CGO_LDFLAGS=-fsanitize=thread" "-installsuffix=tsan"
testtsan tsan7.go "CGO_CFLAGS=-fsanitize=thread CGO_LDFLAGS=-fsanitize=thread" "-installsuffix=tsan"
- testtsan tsan10.go "CGO_CFLAGS=-fsanitize=thread CGO_LDFLAGS=-fsanitize=thread" "-installsuffix=tsan"
- testtsan tsan11.go "CGO_CFLAGS=-fsanitize=thread CGO_LDFLAGS=-fsanitize=thread" "-installsuffix=tsan"
- testtsan tsan12.go "CGO_CFLAGS=-fsanitize=thread CGO_LDFLAGS=-fsanitize=thread" "-installsuffix=tsan"
+
+ # The remaining tests reportedly hang when built with GCC; issue #21196.
+ if test "$clang" = "true"; then
+ testtsan tsan10.go "CGO_CFLAGS=-fsanitize=thread CGO_LDFLAGS=-fsanitize=thread" "-installsuffix=tsan"
+ testtsan tsan11.go "CGO_CFLAGS=-fsanitize=thread CGO_LDFLAGS=-fsanitize=thread" "-installsuffix=tsan"
+ testtsan tsan12.go "CGO_CFLAGS=-fsanitize=thread CGO_LDFLAGS=-fsanitize=thread" "-installsuffix=tsan"
+ fi
testtsanshared
fi
diff --git a/src/cmd/compile/internal/arm/ssa.go b/src/cmd/compile/internal/arm/ssa.go
index 343f2d3aec..93abee3da0 100644
--- a/src/cmd/compile/internal/arm/ssa.go
+++ b/src/cmd/compile/internal/arm/ssa.go
@@ -464,6 +464,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
case ssa.OpARMMOVWaddr:
p := s.Prog(arm.AMOVW)
p.From.Type = obj.TYPE_ADDR
+ p.From.Reg = v.Args[0].Reg()
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
@@ -485,7 +486,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
case nil:
// No sym, just MOVW $off(SP), R
wantreg = "SP"
- p.From.Reg = arm.REGSP
p.From.Offset = v.AuxInt
}
if reg := v.Args[0].RegName(); reg != wantreg {
diff --git a/src/cmd/compile/internal/arm64/ssa.go b/src/cmd/compile/internal/arm64/ssa.go
index dec6a4e93e..0f9e82c727 100644
--- a/src/cmd/compile/internal/arm64/ssa.go
+++ b/src/cmd/compile/internal/arm64/ssa.go
@@ -260,6 +260,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
case ssa.OpARM64MOVDaddr:
p := s.Prog(arm64.AMOVD)
p.From.Type = obj.TYPE_ADDR
+ p.From.Reg = v.Args[0].Reg()
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
@@ -281,7 +282,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
case nil:
// No sym, just MOVD $off(SP), R
wantreg = "SP"
- p.From.Reg = arm64.REGSP
p.From.Offset = v.AuxInt
}
if reg := v.Args[0].RegName(); reg != wantreg {
diff --git a/src/cmd/compile/internal/gc/asm_test.go b/src/cmd/compile/internal/gc/asm_test.go
index 221b8497f1..08ec638f44 100644
--- a/src/cmd/compile/internal/gc/asm_test.go
+++ b/src/cmd/compile/internal/gc/asm_test.go
@@ -898,6 +898,17 @@ var linuxAMD64Tests = []*asmTest{
}`,
[]string{"\tCMPL\t[A-Z]"},
},
+ {
+ // make sure assembly output has matching offset and base register.
+ `
+ func f72(a, b int) int {
+ var x [16]byte // use some frame
+ _ = x
+ return b
+ }
+ `,
+ []string{"b\\+40\\(SP\\)"},
+ },
}
var linux386Tests = []*asmTest{
@@ -1302,6 +1313,17 @@ var linuxARMTests = []*asmTest{
`,
[]string{"\tCLZ\t"},
},
+ {
+ // make sure assembly output has matching offset and base register.
+ `
+ func f13(a, b int) int {
+ var x [16]byte // use some frame
+ _ = x
+ return b
+ }
+ `,
+ []string{"b\\+4\\(FP\\)"},
+ },
}
var linuxARM64Tests = []*asmTest{
@@ -1473,7 +1495,7 @@ var linuxARM64Tests = []*asmTest{
return
}
`,
- []string{"\tMOVD\t\"\"\\.a\\+[0-9]+\\(RSP\\), R[0-9]+", "\tMOVD\tR[0-9]+, \"\"\\.b\\+[0-9]+\\(RSP\\)"},
+ []string{"\tMOVD\t\"\"\\.a\\+[0-9]+\\(FP\\), R[0-9]+", "\tMOVD\tR[0-9]+, \"\"\\.b\\+[0-9]+\\(FP\\)"},
},
}
diff --git a/src/cmd/compile/internal/mips/ssa.go b/src/cmd/compile/internal/mips/ssa.go
index d2b4885eaa..e65515a85b 100644
--- a/src/cmd/compile/internal/mips/ssa.go
+++ b/src/cmd/compile/internal/mips/ssa.go
@@ -273,6 +273,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
case ssa.OpMIPSMOVWaddr:
p := s.Prog(mips.AMOVW)
p.From.Type = obj.TYPE_ADDR
+ p.From.Reg = v.Args[0].Reg()
var wantreg string
// MOVW $sym+off(base), R
// the assembler expands it as the following:
@@ -291,7 +292,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
case nil:
// No sym, just MOVW $off(SP), R
wantreg = "SP"
- p.From.Reg = mips.REGSP
p.From.Offset = v.AuxInt
}
if reg := v.Args[0].RegName(); reg != wantreg {
diff --git a/src/cmd/compile/internal/mips64/ssa.go b/src/cmd/compile/internal/mips64/ssa.go
index 5a7a601942..db163f3e9d 100644
--- a/src/cmd/compile/internal/mips64/ssa.go
+++ b/src/cmd/compile/internal/mips64/ssa.go
@@ -247,6 +247,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
case ssa.OpMIPS64MOVVaddr:
p := s.Prog(mips.AMOVV)
p.From.Type = obj.TYPE_ADDR
+ p.From.Reg = v.Args[0].Reg()
var wantreg string
// MOVV $sym+off(base), R
// the assembler expands it as the following:
@@ -265,7 +266,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
case nil:
// No sym, just MOVV $off(SP), R
wantreg = "SP"
- p.From.Reg = mips.REGSP
p.From.Offset = v.AuxInt
}
if reg := v.Args[0].RegName(); reg != wantreg {
diff --git a/src/cmd/compile/internal/ppc64/ssa.go b/src/cmd/compile/internal/ppc64/ssa.go
index a95dabccf0..5fe140fdcf 100644
--- a/src/cmd/compile/internal/ppc64/ssa.go
+++ b/src/cmd/compile/internal/ppc64/ssa.go
@@ -638,6 +638,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
case ssa.OpPPC64MOVDaddr:
p := s.Prog(ppc64.AMOVD)
p.From.Type = obj.TYPE_ADDR
+ p.From.Reg = v.Args[0].Reg()
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
@@ -660,7 +661,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
case nil:
// No sym, just MOVD $off(SP), R
wantreg = "SP"
- p.From.Reg = ppc64.REGSP
p.From.Offset = v.AuxInt
}
if reg := v.Args[0].RegName(); reg != wantreg {
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index e706e27bdf..7d80d965ae 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -4314,3 +4314,20 @@ func TestTestRegexps(t *testing.T) {
t.Errorf("reduced output:<<<\n%s>>> want:<<<\n%s>>>", have, want)
}
}
+
+func TestListTests(t *testing.T) {
+ var tg *testgoData
+ testWith := func(listName, expected string) func(*testing.T) {
+ return func(t *testing.T) {
+ tg = testgo(t)
+ defer tg.cleanup()
+ tg.run("test", "./testdata/src/testlist/...", fmt.Sprintf("-list=%s", listName))
+ tg.grepStdout(expected, fmt.Sprintf("-test.list=%s returned %q, expected %s", listName, tg.getStdout(), expected))
+ }
+ }
+
+ t.Run("Test", testWith("Test", "TestSimple"))
+ t.Run("Bench", testWith("Benchmark", "BenchmarkSimple"))
+ t.Run("Example1", testWith("Example", "ExampleSimple"))
+ t.Run("Example2", testWith("Example", "ExampleWithEmptyOutput"))
+}
diff --git a/src/cmd/go/testdata/src/testlist/bench_test.go b/src/cmd/go/testdata/src/testlist/bench_test.go
new file mode 100644
index 0000000000..22f147b633
--- /dev/null
+++ b/src/cmd/go/testdata/src/testlist/bench_test.go
@@ -0,0 +1,14 @@
+package testlist
+
+import (
+ "fmt"
+ "testing"
+)
+
+func BenchmarkSimplefunc(b *testing.B) {
+ b.StopTimer()
+ b.StartTimer()
+ for i := 0; i < b.N; i++ {
+ _ = fmt.Sprint("Test for bench")
+ }
+}
diff --git a/src/cmd/go/testdata/src/testlist/example_test.go b/src/cmd/go/testdata/src/testlist/example_test.go
new file mode 100644
index 0000000000..0298dfde81
--- /dev/null
+++ b/src/cmd/go/testdata/src/testlist/example_test.go
@@ -0,0 +1,21 @@
+package testlist
+
+import (
+ "fmt"
+)
+
+func ExampleSimple() {
+ fmt.Println("Test with Output.")
+
+ // Output: Test with Output.
+}
+
+func ExampleWithEmptyOutput() {
+ fmt.Println("")
+
+ // Output:
+}
+
+func ExampleNoOutput() {
+ _ = fmt.Sprint("Test with no output")
+}
diff --git a/src/cmd/go/testdata/src/testlist/test_test.go b/src/cmd/go/testdata/src/testlist/test_test.go
new file mode 100644
index 0000000000..bdc09f27c5
--- /dev/null
+++ b/src/cmd/go/testdata/src/testlist/test_test.go
@@ -0,0 +1,10 @@
+package testlist
+
+import (
+ "fmt"
+ "testing"
+)
+
+func TestSimple(t *testing.T) {
+ _ = fmt.Sprint("Test simple")
+}
diff --git a/src/cmd/internal/obj/arm/asm5.go b/src/cmd/internal/obj/arm/asm5.go
index cfda99f602..8abf732b2c 100644
--- a/src/cmd/internal/obj/arm/asm5.go
+++ b/src/cmd/internal/obj/arm/asm5.go
@@ -1167,6 +1167,11 @@ func (c *ctxt5) aclass(a *obj.Addr) int {
return C_ADDR
case obj.NAME_AUTO:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-SP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = c.autosize + a.Offset
if t := immaddr(int32(c.instoffset)); t != 0 {
if immhalf(int32(c.instoffset)) {
@@ -1185,6 +1190,11 @@ func (c *ctxt5) aclass(a *obj.Addr) int {
return C_LAUTO
case obj.NAME_PARAM:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-FP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = c.autosize + a.Offset + 4
if t := immaddr(int32(c.instoffset)); t != 0 {
if immhalf(int32(c.instoffset)) {
@@ -1285,10 +1295,20 @@ func (c *ctxt5) aclass(a *obj.Addr) int {
return C_LCONADDR
case obj.NAME_AUTO:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-SP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = c.autosize + a.Offset
return c.aconsize()
case obj.NAME_PARAM:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-FP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = c.autosize + a.Offset + 4
return c.aconsize()
}
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go
index 04a481863a..4419909f69 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -1149,10 +1149,20 @@ func (c *ctxt7) aclass(a *obj.Addr) int {
return C_GOTADDR
case obj.NAME_AUTO:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-SP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = int64(c.autosize) + a.Offset
return autoclass(c.instoffset)
case obj.NAME_PARAM:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-FP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = int64(c.autosize) + a.Offset + 8
return autoclass(c.instoffset)
@@ -1228,10 +1238,20 @@ func (c *ctxt7) aclass(a *obj.Addr) int {
return C_VCONADDR
case obj.NAME_AUTO:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-SP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = int64(c.autosize) + a.Offset
goto aconsize
case obj.NAME_PARAM:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-FP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = int64(c.autosize) + a.Offset + 8
goto aconsize
}
diff --git a/src/cmd/internal/obj/mips/asm0.go b/src/cmd/internal/obj/mips/asm0.go
index 3cfb260d60..6257e5b83d 100644
--- a/src/cmd/internal/obj/mips/asm0.go
+++ b/src/cmd/internal/obj/mips/asm0.go
@@ -556,6 +556,11 @@ func (c *ctxt0) aclass(a *obj.Addr) int {
return C_LEXT
case obj.NAME_AUTO:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-SP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = int64(c.autosize) + a.Offset
if c.instoffset >= -BIG && c.instoffset < BIG {
return C_SAUTO
@@ -563,6 +568,11 @@ func (c *ctxt0) aclass(a *obj.Addr) int {
return C_LAUTO
case obj.NAME_PARAM:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-FP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
if c.instoffset >= -BIG && c.instoffset < BIG {
return C_SAUTO
@@ -616,6 +626,11 @@ func (c *ctxt0) aclass(a *obj.Addr) int {
return C_LECON
case obj.NAME_AUTO:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-SP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = int64(c.autosize) + a.Offset
if c.instoffset >= -BIG && c.instoffset < BIG {
return C_SACON
@@ -623,6 +638,11 @@ func (c *ctxt0) aclass(a *obj.Addr) int {
return C_LACON
case obj.NAME_PARAM:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-FP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
if c.instoffset >= -BIG && c.instoffset < BIG {
return C_SACON
diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go
index bdbac03f9c..4d787b1c35 100644
--- a/src/cmd/internal/obj/ppc64/asm9.go
+++ b/src/cmd/internal/obj/ppc64/asm9.go
@@ -758,6 +758,11 @@ func (c *ctxt9) aclass(a *obj.Addr) int {
return C_GOTADDR
case obj.NAME_AUTO:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-SP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = int64(c.autosize) + a.Offset
if c.instoffset >= -BIG && c.instoffset < BIG {
return C_SAUTO
@@ -765,6 +770,11 @@ func (c *ctxt9) aclass(a *obj.Addr) int {
return C_LAUTO
case obj.NAME_PARAM:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-FP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
if c.instoffset >= -BIG && c.instoffset < BIG {
return C_SAUTO
@@ -817,6 +827,11 @@ func (c *ctxt9) aclass(a *obj.Addr) int {
return C_LCON
case obj.NAME_AUTO:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-SP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = int64(c.autosize) + a.Offset
if c.instoffset >= -BIG && c.instoffset < BIG {
return C_SACON
@@ -824,6 +839,11 @@ func (c *ctxt9) aclass(a *obj.Addr) int {
return C_LACON
case obj.NAME_PARAM:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-FP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
if c.instoffset >= -BIG && c.instoffset < BIG {
return C_SACON
diff --git a/src/cmd/internal/obj/s390x/asmz.go b/src/cmd/internal/obj/s390x/asmz.go
index 3bba7b2a5c..6d2b870f0a 100644
--- a/src/cmd/internal/obj/s390x/asmz.go
+++ b/src/cmd/internal/obj/s390x/asmz.go
@@ -505,6 +505,11 @@ func (c *ctxtz) aclass(a *obj.Addr) int {
return C_GOTADDR
case obj.NAME_AUTO:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-SP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = int64(c.autosize) + a.Offset
if c.instoffset >= -BIG && c.instoffset < BIG {
return C_SAUTO
@@ -512,6 +517,11 @@ func (c *ctxtz) aclass(a *obj.Addr) int {
return C_LAUTO
case obj.NAME_PARAM:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-FP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
if c.instoffset >= -BIG && c.instoffset < BIG {
return C_SAUTO
@@ -567,6 +577,11 @@ func (c *ctxtz) aclass(a *obj.Addr) int {
return C_SYMADDR
case obj.NAME_AUTO:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-SP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = int64(c.autosize) + a.Offset
if c.instoffset >= -BIG && c.instoffset < BIG {
return C_SACON
@@ -574,6 +589,11 @@ func (c *ctxtz) aclass(a *obj.Addr) int {
return C_LACON
case obj.NAME_PARAM:
+ if a.Reg == REGSP {
+ // unset base register for better printing, since
+ // a.Offset is still relative to pseudo-FP.
+ a.Reg = obj.REG_NONE
+ }
c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
if c.instoffset >= -BIG && c.instoffset < BIG {
return C_SACON
diff --git a/src/cmd/vet/main.go b/src/cmd/vet/main.go
index 77376c90ed..34c5297b89 100644
--- a/src/cmd/vet/main.go
+++ b/src/cmd/vet/main.go
@@ -349,8 +349,9 @@ func doPackage(directory string, names []string, basePkg *Package) *Package {
pkg.files = files
// Type check the package.
err := pkg.check(fs, astFiles)
- if err != nil && *verbose {
- warnf("%s", err)
+ if err != nil {
+ // Note that we only report this error when *verbose.
+ Println(err)
}
// Check.
diff --git a/src/cmd/vet/testdata/cgo/cgo3.go b/src/cmd/vet/testdata/cgo/cgo3.go
new file mode 100644
index 0000000000..0b1518e1f9
--- /dev/null
+++ b/src/cmd/vet/testdata/cgo/cgo3.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.
+
+// Used by TestVetVerbose to test that vet -v doesn't fail because it
+// can't find "C".
+
+package testdata
+
+import "C"
+
+func F() {
+}
diff --git a/src/cmd/vet/vet_test.go b/src/cmd/vet/vet_test.go
index b3d5c663a7..8db8ff4d20 100644
--- a/src/cmd/vet/vet_test.go
+++ b/src/cmd/vet/vet_test.go
@@ -205,3 +205,15 @@ func TestTags(t *testing.T) {
})
}
}
+
+// Issue #21188.
+func TestVetVerbose(t *testing.T) {
+ t.Parallel()
+ Build(t)
+ cmd := exec.Command("./"+binary, "-v", "-all", "testdata/cgo/cgo3.go")
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Logf("%s", out)
+ t.Error(err)
+ }
+}
diff --git a/src/encoding/binary/example_test.go b/src/encoding/binary/example_test.go
index 2b52a47d12..a8b8dba650 100644
--- a/src/encoding/binary/example_test.go
+++ b/src/encoding/binary/example_test.go
@@ -68,3 +68,94 @@ func ExampleByteOrder_get() {
// Output:
// 0x03e8 0x07d0
}
+
+func ExamplePutUvarint() {
+ buf := make([]byte, binary.MaxVarintLen64)
+
+ for _, x := range []uint64{1, 2, 127, 128, 255, 256} {
+ n := binary.PutUvarint(buf, x)
+ fmt.Printf("%x\n", buf[:n])
+ }
+ // Output:
+ // 01
+ // 02
+ // 7f
+ // 8001
+ // ff01
+ // 8002
+}
+
+func ExamplePutVarint() {
+ buf := make([]byte, binary.MaxVarintLen64)
+
+ for _, x := range []int64{-65, -64, -2, -1, 0, 1, 2, 63, 64} {
+ n := binary.PutVarint(buf, x)
+ fmt.Printf("%x\n", buf[:n])
+ }
+ // Output:
+ // 8101
+ // 7f
+ // 03
+ // 01
+ // 00
+ // 02
+ // 04
+ // 7e
+ // 8001
+}
+
+func ExampleUvarint() {
+ inputs := [][]byte{
+ []byte{0x01},
+ []byte{0x02},
+ []byte{0x7f},
+ []byte{0x80, 0x01},
+ []byte{0xff, 0x01},
+ []byte{0x80, 0x02},
+ }
+ for _, b := range inputs {
+ x, n := binary.Uvarint(b)
+ if n != len(b) {
+ fmt.Println("Uvarint did not consume all of in")
+ }
+ fmt.Println(x)
+ }
+ // Output:
+ // 1
+ // 2
+ // 127
+ // 128
+ // 255
+ // 256
+}
+
+func ExampleVarint() {
+ inputs := [][]byte{
+ []byte{0x81, 0x01},
+ []byte{0x7f},
+ []byte{0x03},
+ []byte{0x01},
+ []byte{0x00},
+ []byte{0x02},
+ []byte{0x04},
+ []byte{0x7e},
+ []byte{0x80, 0x01},
+ }
+ for _, b := range inputs {
+ x, n := binary.Varint(b)
+ if n != len(b) {
+ fmt.Println("Varint did not consume all of in")
+ }
+ fmt.Println(x)
+ }
+ // Output:
+ // -65
+ // -64
+ // -2
+ // -1
+ // 0
+ // 1
+ // 2
+ // 63
+ // 64
+}
diff --git a/src/go/ast/ast.go b/src/go/ast/ast.go
index 77ef98ceaf..9ab7b1e625 100644
--- a/src/go/ast/ast.go
+++ b/src/go/ast/ast.go
@@ -969,14 +969,14 @@ func (*FuncDecl) declNode() {}
//
// For correct printing of source code containing comments (using packages
// go/format and go/printer), special care must be taken to update comments
-// when a File's syntax tree is modified: For printing, comments are inter-
-// spersed between tokens based on their position. If syntax tree nodes are
+// when a File's syntax tree is modified: For printing, comments are interspersed
+// between tokens based on their position. If syntax tree nodes are
// removed or moved, relevant comments in their vicinity must also be removed
// (from the File.Comments list) or moved accordingly (by updating their
// positions). A CommentMap may be used to facilitate some of these operations.
//
-// Whether and how a comment is associated with a node depends on the inter-
-// pretation of the syntax tree by the manipulating program: Except for Doc
+// Whether and how a comment is associated with a node depends on the
+// interpretation of the syntax tree by the manipulating program: Except for Doc
// and Comment comments directly associated with nodes, the remaining comments
// are "free-floating" (see also issues #18593, #20744).
//
diff --git a/src/go/parser/parser.go b/src/go/parser/parser.go
index 1b4309b5da..2b58724521 100644
--- a/src/go/parser/parser.go
+++ b/src/go/parser/parser.go
@@ -1707,8 +1707,8 @@ func (p *parser) parseSimpleStmt(mode int) (ast.Stmt, bool) {
}
// The label declaration typically starts at x[0].Pos(), but the label
// declaration may be erroneous due to a token after that position (and
- // before the ':'). If SpuriousErrors is not set, the (only) error re-
- // ported for the line is the illegal label error instead of the token
+ // before the ':'). If SpuriousErrors is not set, the (only) error
+ // reported for the line is the illegal label error instead of the token
// before the ':' that caused the problem. Thus, use the (latest) colon
// position for error reporting.
p.error(colon, "illegal label declaration")
diff --git a/src/internal/poll/fd_windows.go b/src/internal/poll/fd_windows.go
index 9f40886d08..655f9348c6 100644
--- a/src/internal/poll/fd_windows.go
+++ b/src/internal/poll/fd_windows.go
@@ -154,6 +154,10 @@ func (s *ioSrv) ProcessRemoteIO() {
// is available. Alternatively, it passes the request onto
// runtime netpoll and waits for completion or cancels request.
func (s *ioSrv) ExecIO(o *operation, submit func(o *operation) error) (int, error) {
+ if o.fd.pd.runtimeCtx == 0 {
+ return 0, errors.New("internal error: polling on unsupported descriptor type")
+ }
+
if !canCancelIO {
onceStartServer.Do(startServer)
}
@@ -315,8 +319,21 @@ func (fd *FD) Init(net string) (string, error) {
return "", errors.New("internal error: unknown network type " + net)
}
- if err := fd.pd.init(fd); err != nil {
- return "", err
+ if !fd.isFile && !fd.isConsole && !fd.isDir {
+ // Only call init for a network socket.
+ // This means that we don't add files to the runtime poller.
+ // Adding files to the runtime poller can confuse matters
+ // if the user is doing their own overlapped I/O.
+ // See issue #21172.
+ //
+ // In general the code below avoids calling the ExecIO
+ // method for non-network sockets. If some method does
+ // somehow call ExecIO, then ExecIO, and therefore the
+ // calling method, will return an error, because
+ // fd.pd.runtimeCtx will be 0.
+ if err := fd.pd.init(fd); err != nil {
+ return "", err
+ }
}
if hasLoadSetFileCompletionNotificationModes {
// We do not use events, so we can skip them always.
diff --git a/src/math/big/ratconv.go b/src/math/big/ratconv.go
index a6a401c857..4bc6ef7e80 100644
--- a/src/math/big/ratconv.go
+++ b/src/math/big/ratconv.go
@@ -40,8 +40,8 @@ func (z *Rat) Scan(s fmt.ScanState, ch rune) error {
// SetString sets z to the value of s and returns z and a boolean indicating
// success. s can be given as a fraction "a/b" or as a floating-point number
// optionally followed by an exponent. The entire string (not just a prefix)
-// must be valid for success. If the operation failed, the value of z is un-
-// defined but the returned value is nil.
+// must be valid for success. If the operation failed, the value of z is
+// undefined but the returned value is nil.
func (z *Rat) SetString(s string) (*Rat, bool) {
if len(s) == 0 {
return nil, false
diff --git a/src/math/bits/example_test.go b/src/math/bits/example_test.go
index 5d30f4b259..a43d1f365f 100644
--- a/src/math/bits/example_test.go
+++ b/src/math/bits/example_test.go
@@ -36,3 +36,43 @@ func ExampleLeadingZeros64() {
// 64
// 63
}
+
+func ExampleOnesCount() {
+ fmt.Printf("%b\n", 14)
+ fmt.Println(bits.OnesCount(14))
+ // Output:
+ // 1110
+ // 3
+}
+
+func ExampleOnesCount8() {
+ fmt.Printf("%b\n", 14)
+ fmt.Println(bits.OnesCount8(14))
+ // Output:
+ // 1110
+ // 3
+}
+
+func ExampleOnesCount16() {
+ fmt.Printf("%b\n", 14)
+ fmt.Println(bits.OnesCount16(14))
+ // Output:
+ // 1110
+ // 3
+}
+
+func ExampleOnesCount32() {
+ fmt.Printf("%b\n", 14)
+ fmt.Println(bits.OnesCount32(14))
+ // Output:
+ // 1110
+ // 3
+}
+
+func ExampleOnesCount64() {
+ fmt.Printf("%b\n", 14)
+ fmt.Println(bits.OnesCount64(14))
+ // Output:
+ // 1110
+ // 3
+}
diff --git a/src/plugin/plugin.go b/src/plugin/plugin.go
index 3dc7964048..c774465812 100644
--- a/src/plugin/plugin.go
+++ b/src/plugin/plugin.go
@@ -4,8 +4,6 @@
// Package plugin implements loading and symbol resolution of Go plugins.
//
-// Currently plugins only work on Linux.
-//
// A plugin is a Go main package with exported functions and variables that
// has been built with:
//
@@ -14,6 +12,9 @@
// When a plugin is first opened, the init functions of all packages not
// already part of the program are called. The main function is not run.
// A plugin is only initialized once, and cannot be closed.
+//
+// The plugin support is currently incomplete, only supports Linux,
+// and has known bugs. Please report any issues.
package plugin
// Plugin is a loaded Go plugin.
diff --git a/src/reflect/deepequal.go b/src/reflect/deepequal.go
index f3fd7043e5..2fdd6a3d82 100644
--- a/src/reflect/deepequal.go
+++ b/src/reflect/deepequal.go
@@ -178,6 +178,12 @@ func deepValueEqual(v1, v2 Value, visited map[visit]bool, depth int) bool {
// DeepEqual has been defined so that the same short-cut applies
// to slices and maps: if x and y are the same slice or the same map,
// they are deeply equal regardless of content.
+//
+// As DeepEqual traverses the data values it may find a cycle. The
+// second and subsequent times that DeepEqual compares two pointer
+// values that have been compared before, it treats the values as
+// equal rather than examining the values to which they point.
+// This ensures that DeepEqual terminates.
func DeepEqual(x, y interface{}) bool {
if x == nil || y == nil {
return x == y
diff --git a/src/runtime/cpuprof.go b/src/runtime/cpuprof.go
index c761e440b6..fb841a9f3d 100644
--- a/src/runtime/cpuprof.go
+++ b/src/runtime/cpuprof.go
@@ -163,6 +163,15 @@ func (p *cpuProfile) addExtra() {
}
}
+func (p *cpuProfile) addLostAtomic64(count uint64) {
+ hdr := [1]uint64{count}
+ lostStk := [2]uintptr{
+ funcPC(_LostSIGPROFDuringAtomic64) + sys.PCQuantum,
+ funcPC(_System) + sys.PCQuantum,
+ }
+ cpuprof.log.write(nil, 0, hdr[:], lostStk[:])
+}
+
// CPUProfile panics.
// It formerly provided raw access to chunks of
// a pprof-format profile generated by the runtime.
diff --git a/src/runtime/hashmap_fast.go b/src/runtime/hashmap_fast.go
index 1f9b313219..67b9787909 100644
--- a/src/runtime/hashmap_fast.go
+++ b/src/runtime/hashmap_fast.go
@@ -495,7 +495,7 @@ again:
}
// store new key/value at insert position
- *((*uint32)(insertk)) = key
+ typedmemmove(t.key, insertk, unsafe.Pointer(&key))
*inserti = top
h.count++
@@ -583,7 +583,7 @@ again:
}
// store new key/value at insert position
- *((*uint64)(insertk)) = key
+ typedmemmove(t.key, insertk, unsafe.Pointer(&key))
*inserti = top
h.count++
@@ -723,7 +723,7 @@ func mapdelete_fast32(t *maptype, h *hmap, key uint32) {
if key != *k {
continue
}
- *k = 0
+ typedmemclr(t.key, unsafe.Pointer(k))
v := unsafe.Pointer(uintptr(unsafe.Pointer(b)) + dataOffset + bucketCnt*4 + i*uintptr(t.valuesize))
typedmemclr(t.elem, v)
b.tophash[i] = empty
@@ -778,7 +778,7 @@ func mapdelete_fast64(t *maptype, h *hmap, key uint64) {
if key != *k {
continue
}
- *k = 0
+ typedmemclr(t.key, unsafe.Pointer(k))
v := unsafe.Pointer(uintptr(unsafe.Pointer(b)) + dataOffset + bucketCnt*8 + i*uintptr(t.valuesize))
typedmemclr(t.elem, v)
b.tophash[i] = empty
diff --git a/src/runtime/pprof/pprof_test.go b/src/runtime/pprof/pprof_test.go
index 22fea0a52f..992d2abb6a 100644
--- a/src/runtime/pprof/pprof_test.go
+++ b/src/runtime/pprof/pprof_test.go
@@ -12,6 +12,7 @@ import (
"fmt"
"internal/testenv"
"io"
+ "io/ioutil"
"math/big"
"os"
"os/exec"
@@ -20,6 +21,7 @@ import (
"runtime/pprof/internal/profile"
"strings"
"sync"
+ "sync/atomic"
"testing"
"time"
)
@@ -713,3 +715,32 @@ func TestCPUProfileLabel(t *testing.T) {
})
})
}
+
+// Check that there is no deadlock when the program receives SIGPROF while in
+// 64bit atomics' critical section. Used to happen on mips{,le}. See #20146.
+func TestAtomicLoadStore64(t *testing.T) {
+ f, err := ioutil.TempFile("", "profatomic")
+ if err != nil {
+ t.Fatalf("TempFile: %v", err)
+ }
+ defer os.Remove(f.Name())
+ defer f.Close()
+
+ if err := StartCPUProfile(f); err != nil {
+ t.Fatal(err)
+ }
+ defer StopCPUProfile()
+
+ var flag uint64
+ done := make(chan bool, 1)
+
+ go func() {
+ for atomic.LoadUint64(&flag) == 0 {
+ runtime.Gosched()
+ }
+ done <- true
+ }()
+ time.Sleep(50 * time.Millisecond)
+ atomic.StoreUint64(&flag, 1)
+ <-done
+}
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index a5ada4f6db..ed333bb92e 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -3232,10 +3232,14 @@ var prof struct {
hz int32
}
-func _System() { _System() }
-func _ExternalCode() { _ExternalCode() }
-func _LostExternalCode() { _LostExternalCode() }
-func _GC() { _GC() }
+func _System() { _System() }
+func _ExternalCode() { _ExternalCode() }
+func _LostExternalCode() { _LostExternalCode() }
+func _GC() { _GC() }
+func _LostSIGPROFDuringAtomic64() { _LostSIGPROFDuringAtomic64() }
+
+// Counts SIGPROFs received while in atomic64 critical section, on mips{,le}
+var lostAtomic64Count uint64
// Called if we receive a SIGPROF signal.
// Called by the signal handler, may run during STW.
@@ -3245,6 +3249,21 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
return
}
+ // On mips{,le}, 64bit atomics are emulated with spinlocks, in
+ // runtime/internal/atomic. If SIGPROF arrives while the program is inside
+ // the critical section, it creates a deadlock (when writing the sample).
+ // As a workaround, create a counter of SIGPROFs while in critical section
+ // to store the count, and pass it to sigprof.add() later when SIGPROF is
+ // received from somewhere else (with _LostSIGPROFDuringAtomic64 as pc).
+ if GOARCH == "mips" || GOARCH == "mipsle" {
+ if f := findfunc(pc); f.valid() {
+ if hasprefix(funcname(f), "runtime/internal/atomic") {
+ lostAtomic64Count++
+ return
+ }
+ }
+ }
+
// Profiling runs concurrently with GC, so it must not allocate.
// Set a trap in case the code does allocate.
// Note that on windows, one thread takes profiles of all the
@@ -3371,6 +3390,10 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
}
if prof.hz != 0 {
+ if (GOARCH == "mips" || GOARCH == "mipsle") && lostAtomic64Count > 0 {
+ cpuprof.addLostAtomic64(lostAtomic64Count)
+ lostAtomic64Count = 0
+ }
cpuprof.add(gp, stk[:n])
}
getg().m.mallocing--
diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go
index 8e410c4560..e1b41ca4ff 100644
--- a/src/runtime/symtab.go
+++ b/src/runtime/symtab.go
@@ -409,6 +409,11 @@ var modulesSlice unsafe.Pointer // see activeModules
//
// A module is active once its gcdatamask and gcbssmask have been
// assembled and it is usable by the GC.
+//
+// This is nosplit/nowritebarrier because it is called by the
+// cgo pointer checking code.
+//go:nosplit
+//go:nowritebarrier
func activeModules() []*moduledata {
p := (*[]*moduledata)(atomic.Loadp(unsafe.Pointer(&modulesSlice)))
if p == nil {
diff --git a/src/testing/testing.go b/src/testing/testing.go
index 3d1c0c6947..11af926c80 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -970,7 +970,7 @@ func listTests(matchString func(pat, str string) (bool, error), tests []Internal
}
}
for _, example := range examples {
- if ok, _ := matchString(*matchList, example.Name); ok && example.Output != "" {
+ if ok, _ := matchString(*matchList, example.Name); ok {
fmt.Println(example.Name)
}
}
diff --git a/src/time/zoneinfo_windows_test.go b/src/time/zoneinfo_windows_test.go
index 7ac1e86822..cf3b428c09 100644
--- a/src/time/zoneinfo_windows_test.go
+++ b/src/time/zoneinfo_windows_test.go
@@ -14,6 +14,14 @@ func testZoneAbbr(t *testing.T) {
t1 := Now()
// discard nsec
t1 = Date(t1.Year(), t1.Month(), t1.Day(), t1.Hour(), t1.Minute(), t1.Second(), 0, t1.Location())
+
+ // Skip the test if we're in a timezone with no abbreviation.
+ // Format will fallback to the numeric abbreviation, and
+ // Parse(RFC1123, ..) will fail (see Issue 21183).
+ if tz := t1.Format("MST"); tz[0] == '-' || tz[0] == '+' {
+ t.Skip("No zone abbreviation")
+ }
+
t2, err := Parse(RFC1123, t1.Format(RFC1123))
if err != nil {
t.Fatalf("Parse failed: %v", err)
diff --git a/test/README.md b/test/README.md
new file mode 100644
index 0000000000..ca6a8c6580
--- /dev/null
+++ b/test/README.md
@@ -0,0 +1,15 @@
+The test directory contains tests of the Go tool chain and runtime.
+It includes black box tests, regression tests, and error output tests.
+They are run as part of all.bash.
+
+To run just these tests, execute:
+
+ go run run.go
+
+Standard library tests should be written as regular Go tests in the appropriate package.
+
+The tool chain and runtime also have regular Go tests in their packages.
+The main reasons to add a new test to this directory are:
+
+* it is most naturally expressed using the test runner; or
+* it is also applicable to `gccgo` and other Go tool chains.