1
0
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 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
This commit is contained in:
Chris Broadfoot 2017-08-07 10:28:03 -07:00
commit cff0de3da3
41 changed files with 662 additions and 126 deletions

View File

@ -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 &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-->

BIN
doc/editors/go-plus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -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 -->

View File

@ -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>

View File

@ -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() {

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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\\)"},
},
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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"))
}

View 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")
}
}

View 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")
}

View File

@ -0,0 +1,10 @@
package testlist
import (
"fmt"
"testing"
)
func TestSimple(t *testing.T) {
_ = fmt.Sprint("Test simple")
}

View File

@ -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()
}

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
View 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() {
}

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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).
//

View File

@ -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")

View File

@ -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.

View File

@ -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

View File

@ -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
}

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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
}

View File

@ -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--

View File

@ -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 {

View File

@ -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)
}
}

View File

@ -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
View 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.