mirror of
https://github.com/golang/go
synced 2024-11-26 03:07:57 -07:00
[release-branch.go1.9] all: merge master into release-branch.go1.9
579120323f
runtime: mapassign_* should use typedmemmove to update keys380525598c
all: remove some manual hyphenationf096b5b340
runtime: mark activeModules nosplit/nowritebarrier3e3da54633
math/bits: fix example for OnesCount649b1e7cf2ac
math/bits: add examples for OnesCount functionsb01db023b1
misc/cgo/testsanitizers: also skip tsan11/tsan12 when using GCCa279b53a18
reflect: document how DeepEqual handles cycles909f409a8d
doc: mention handling of moved GOROOT in 1.9 release notes58ad0176ca
doc: use better wording to explain type-aware completion92dac21d29
doc: replace paid with commercial9bb98e02de
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 IDEs5495047223
doc/1.9: fix broken html link in CL 53030/53210890e0e862f
doc: fix bad link in go1.9 release notesbe596f049a
doc/1.9: fix stray html in CL 530300173631d53
encoding/binary: add examples for varint functionsac0ccf3cd2
doc/1.9: add CL 36696 for crypto/x509 to the release notescc402c2c4d
doc: hide blog content for golang.google.cnf396fa4285
internal/poll: don't add non-sockets to runtime poller664cd26c89
cmd/vet: don't exit with failure on type checking errora8730cd93a
doc: hide video and share if being served from CNb63db76c4a
testsanitizers: check that tsan program runs, skip tsan10 on gcc193eda7291
time: skip ZoneAbbr test in timezones with no abbreviation6f08c935a9
cmd/go: show examples with empty output in go test -listf20944de78
cmd/compile: set/unset base register for better assembly print623e2c4603
runtime: map bitmap and spans during heap initialization780249eed4
runtime: fall back to small mmaps if we fail to grow reservation31b2c4cc25
.github: add .md extension to SUPPORT fileac29f30dbb
plugin: mention that there are known bugs with plugins45a4609c0a
cmd/dist: skip moved GOROOT on Go's Windows builders when not sharding testse157fac02d
test: add README835dfef939
runtime/pprof: prevent a deadlock that SIGPROF might create on mips{,le}df91b8044d
doc: list editor options by name, not plugin name3d9475c04b
doc: cleanup editor pageb9661a14ea
doc: add Atom to editor guideee392ac10c
cmd/compile: consider exported flag in namedata Change-Id: I3a48493e8c05d97cb3b61635503ef0ccd646e5cb
This commit is contained in:
commit
cff0de3da3
0
.github/SUPPORT → .github/SUPPORT.md
vendored
0
.github/SUPPORT → .github/SUPPORT.md
vendored
@ -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>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Autocompletion based on type</td>
|
||||
<td class="no">No</td>
|
||||
<td class="no">No</td>
|
||||
<td class="yes">Yes</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<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 > Go > 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 > Go > 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-->
|
BIN
doc/editors/go-plus.png
Normal file
BIN
doc/editors/go-plus.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
@ -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 -->
|
||||
|
144
doc/root.html
144
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">
|
||||
<script>
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
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();
|
||||
}
|
||||
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()
|
||||
}
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
{{if not $.GoogleCN}}
|
||||
|
||||
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()
|
||||
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');
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// 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.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>
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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\\)"},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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"))
|
||||
}
|
||||
|
14
src/cmd/go/testdata/src/testlist/bench_test.go
vendored
Normal file
14
src/cmd/go/testdata/src/testlist/bench_test.go
vendored
Normal file
@ -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")
|
||||
}
|
||||
}
|
21
src/cmd/go/testdata/src/testlist/example_test.go
vendored
Normal file
21
src/cmd/go/testdata/src/testlist/example_test.go
vendored
Normal file
@ -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")
|
||||
}
|
10
src/cmd/go/testdata/src/testlist/test_test.go
vendored
Normal file
10
src/cmd/go/testdata/src/testlist/test_test.go
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
package testlist
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSimple(t *testing.T) {
|
||||
_ = fmt.Sprint("Test simple")
|
||||
}
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
13
src/cmd/vet/testdata/cgo/cgo3.go
vendored
Normal file
13
src/cmd/vet/testdata/cgo/cgo3.go
vendored
Normal file
@ -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() {
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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).
|
||||
//
|
||||
|
@ -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")
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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--
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
15
test/README.md
Normal file
15
test/README.md
Normal file
@ -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.
|
Loading…
Reference in New Issue
Block a user