mirror of
https://github.com/golang/go.git
synced 2026-01-29 15:12:08 +03:00
Compare commits
86 Commits
dev.boring
...
go1.12.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a1b4e75f8 | ||
|
|
4a1d39bb80 | ||
|
|
e02d81890f | ||
|
|
df6ecb1272 | ||
|
|
794e22552b | ||
|
|
a17d091120 | ||
|
|
dc6db5f434 | ||
|
|
9ac7093984 | ||
|
|
fd3676302e | ||
|
|
438b1a5dae | ||
|
|
a1a9d8a84d | ||
|
|
f1a077df10 | ||
|
|
a115501eae | ||
|
|
323ac9c7da | ||
|
|
371a99d256 | ||
|
|
4605817875 | ||
|
|
eda3401e80 | ||
|
|
19009ae948 | ||
|
|
62ec3dd260 | ||
|
|
d29b4ea305 | ||
|
|
ba83a7c452 | ||
|
|
35c41e21bb | ||
|
|
19dea72f5f | ||
|
|
ac02fdec7c | ||
|
|
4fc9d3bc58 | ||
|
|
92e78f7e8d | ||
|
|
c4e9966a32 | ||
|
|
5ca2cf89e7 | ||
|
|
fcc527344f | ||
|
|
731ebf4d87 | ||
|
|
8b086a2b7f | ||
|
|
499088f6dd | ||
|
|
991583017c | ||
|
|
578e281583 | ||
|
|
8acc2ea68b | ||
|
|
ec06e9ba45 | ||
|
|
aeb9d03e4a | ||
|
|
827c5d5355 | ||
|
|
e552f772f7 | ||
|
|
fc6457d1d2 | ||
|
|
ff048033e4 | ||
|
|
c1d8d9d8be | ||
|
|
0380c9ad38 | ||
|
|
100b6739fc | ||
|
|
82d12bdcf7 | ||
|
|
32355f5c31 | ||
|
|
35ddc140c4 | ||
|
|
746edd459d | ||
|
|
ad8ebb9e85 | ||
|
|
6fc1242ea8 | ||
|
|
f9d0594a47 | ||
|
|
7294ede961 | ||
|
|
f062f48c1f | ||
|
|
a40b76a40c | ||
|
|
7e880151b1 | ||
|
|
4dd46a678f | ||
|
|
0ea746023f | ||
|
|
6ff06c19fd | ||
|
|
71b8a3bc87 | ||
|
|
91fd14b824 | ||
|
|
162b3610e6 | ||
|
|
a2884af3b6 | ||
|
|
c55fb33612 | ||
|
|
4754cba67f | ||
|
|
491b7bcff5 | ||
|
|
05e77d4191 | ||
|
|
297d394cab | ||
|
|
6e501da62e | ||
|
|
6ae7c0bc6d | ||
|
|
efc6d86965 | ||
|
|
a718f939d2 | ||
|
|
da1f5d376a | ||
|
|
35e6a10c90 | ||
|
|
320da8d149 | ||
|
|
b840ae1e16 | ||
|
|
fc60d9dd6e | ||
|
|
96d39207d1 | ||
|
|
a4aee30cb4 | ||
|
|
e3a53db2b8 | ||
|
|
52d020260d | ||
|
|
9527a465f3 | ||
|
|
fa5e4baf87 | ||
|
|
0cfe46ce74 | ||
|
|
74f0f6939c | ||
|
|
7ab5e0c5e2 | ||
|
|
1af509d46e |
@@ -18,10 +18,8 @@ underlying binary with arguments appropriate to package-level processing.
|
||||
|
||||
<p>
|
||||
The programs can also be run as stand-alone binaries, with unmodified arguments,
|
||||
using the go <code>tool</code> subcommand, such as <code>go tool vet</code>.
|
||||
This style of invocation allows, for instance, checking a single source file
|
||||
rather than an entire package: <code>go tool vet myprogram.go</code> as
|
||||
compared to <code>go vet mypackage</code>.
|
||||
using the go <code>tool</code> subcommand, such as <code>go tool cgo</code>.
|
||||
For most commands this is mainly useful for debugging.
|
||||
Some of the commands, such as <code>pprof</code>, are accessible only through
|
||||
the go <code>tool</code> subcommand.
|
||||
</p>
|
||||
@@ -76,7 +74,7 @@ and rewrites them to use newer ones.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><a href="/cmd/go/">fmt</a></td>
|
||||
<td><a href="/cmd/gofmt/">fmt</a></td>
|
||||
<td> </td>
|
||||
<td>Fmt formats Go packages, it is also available as an independent <a href="/cmd/gofmt/">
|
||||
gofmt</a> command with more general options.</td>
|
||||
|
||||
@@ -34,6 +34,7 @@ We encourage all Go users to subscribe to
|
||||
<p>A <a href="/doc/devel/release.html">summary</a> of the changes between Go releases. Notes for the major releases:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="/doc/go1.12">Go 1.12</a> <small>(February 2019)</small></li>
|
||||
<li><a href="/doc/go1.11">Go 1.11</a> <small>(August 2018)</small></li>
|
||||
<li><a href="/doc/go1.10">Go 1.10</a> <small>(February 2018)</small></li>
|
||||
<li><a href="/doc/go1.9">Go 1.9</a> <small>(August 2017)</small></li>
|
||||
|
||||
@@ -46,7 +46,8 @@ CLA (Contributor License Agreement).
|
||||
<li>
|
||||
<b>Step 2</b>: Configure authentication credentials for the Go Git repository.
|
||||
Visit <a href="https://go.googlesource.com/">go.googlesource.com</a>, click
|
||||
on "Generate Password" (top right), and follow the instructions.
|
||||
on the gear icon (top right), then on "Obtain password", and follow the
|
||||
instructions.
|
||||
</li>
|
||||
<li>
|
||||
<b>Step 3</b>: Register for Gerrit, the code review tool used by the Go team,
|
||||
|
||||
@@ -23,6 +23,52 @@ in supported releases as needed by issuing minor revisions
|
||||
(for example, Go 1.6.1, Go 1.6.2, and so on).
|
||||
</p>
|
||||
|
||||
<h2 id="go1.12">go1.12 (released 2019/02/25)</h2>
|
||||
|
||||
<p>
|
||||
Go 1.12 is a major release of Go.
|
||||
Read the <a href="/doc/go1.12">Go 1.12 Release Notes</a> for more information.
|
||||
</p>
|
||||
|
||||
<h3 id="go1.12.minor">Minor revisions</h3>
|
||||
|
||||
<p>
|
||||
go1.12.1 (released 2019/03/14) includes fixes to cgo, the compiler, the go
|
||||
command, and the <code>fmt</code>, <code>net/smtp</code>, <code>os</code>,
|
||||
<code>path/filepath</code>, <code>sync</code>, and <code>text/template</code>
|
||||
packages. See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.12.1">Go
|
||||
1.12.1 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.12.2 (released 2019/04/05) includes fixes to the compiler, the go
|
||||
command, the runtime, and the <code>doc</code>, <code>net</code>,
|
||||
<code>net/http/httputil</code>, and <code>os</code> packages. See the
|
||||
<a href="https://github.com/golang/go/issues?q=milestone%3AGo1.12.2">Go
|
||||
1.12.2 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.12.3 (released 2019/04/08) was accidentally released without its
|
||||
intended fix. It is identical to go1.12.2, except for its version
|
||||
number. The intended fix is in go1.12.4.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.12.4 (released 2019/04/11) fixes an issue where using the prebuilt binary
|
||||
releases on older versions of GNU/Linux
|
||||
<a href="https://golang.org/issues/31293">led to failures</a>
|
||||
when linking programs that used cgo.
|
||||
Only Linux users who hit this issue need to update.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.12.5 (released 2019/05/06) includes fixes to the compiler, the linker,
|
||||
the go command, the runtime, and the <code>os</code> package. See the
|
||||
<a href="https://github.com/golang/go/issues?q=milestone%3AGo1.12.5">Go
|
||||
1.12.5 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<h2 id="go1.11">go1.11 (released 2018/08/24)</h2>
|
||||
|
||||
<p>
|
||||
@@ -66,6 +112,48 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.11.4+labe
|
||||
1.11.4 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.11.5 (released 2019/01/23) includes a security fix to the
|
||||
<code>crypto/elliptic</code> package. See
|
||||
the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.11.5">Go
|
||||
1.11.5 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.11.6 (released 2019/03/14) includes fixes to cgo, the compiler, linker,
|
||||
runtime, go command, and the <code>crypto/x509</code>, <code>encoding/json</code>,
|
||||
<code>net</code>, and <code>net/url</code> packages. See the
|
||||
<a href="https://github.com/golang/go/issues?q=milestone%3AGo1.11.6">Go
|
||||
1.11.6 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.11.7 (released 2019/04/05) includes fixes to the runtime and the
|
||||
<code>net</code> packages. See the
|
||||
<a href="https://github.com/golang/go/issues?q=milestone%3AGo1.11.7">Go
|
||||
1.11.7 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.11.8 (released 2019/04/08) was accidentally released without its
|
||||
intended fix. It is identical to go1.11.7, except for its version
|
||||
number. The intended fix is in go1.11.9.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.11.9 (released 2019/04/11) fixes an issue where using the prebuilt binary
|
||||
releases on older versions of GNU/Linux
|
||||
<a href="https://golang.org/issues/31293">led to failures</a>
|
||||
when linking programs that used cgo.
|
||||
Only Linux users who hit this issue need to update.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.11.10 (released 2019/05/06) includes fixes to the runtime and the linker.
|
||||
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.11.10">Go
|
||||
1.11.10 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<h2 id="go1.10">go1.10 (released 2018/02/16)</h2>
|
||||
|
||||
<p>
|
||||
@@ -131,6 +219,13 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.10.7+labe
|
||||
Go 1.10.7 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.10.8 (released 2019/01/23) includes a security fix to the
|
||||
<code>crypto/elliptic</code> package. See
|
||||
the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.10.8">Go
|
||||
1.10.8 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<h2 id="go1.9">go1.9 (released 2017/08/24)</h2>
|
||||
|
||||
<p>
|
||||
|
||||
@@ -15,14 +15,7 @@ Do not send CLs removing the interior tags from such phrases.
|
||||
ul li { margin: 0.5em 0; }
|
||||
</style>
|
||||
|
||||
<h2 id="introduction">DRAFT RELEASE NOTES - Introduction to Go 1.12</h2>
|
||||
|
||||
<p>
|
||||
<strong>
|
||||
Go 1.12 is not yet released. These are work-in-progress
|
||||
release notes. Go 1.12 is expected to be released in February 2019.
|
||||
</strong>
|
||||
</p>
|
||||
<h2 id="introduction">Introduction to Go 1.12</h2>
|
||||
|
||||
<p>
|
||||
The latest Go release, version 1.12, arrives six months after <a href="go1.11">Go 1.11</a>.
|
||||
@@ -109,7 +102,7 @@ Do not send CLs removing the interior tags from such phrases.
|
||||
is no longer available with <code>go vet</code>. Checking for
|
||||
variable shadowing may now be done using
|
||||
<pre>
|
||||
go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow
|
||||
go get -u golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow
|
||||
go vet -vettool=$(which shadow)
|
||||
</pre>
|
||||
</p>
|
||||
@@ -121,7 +114,7 @@ The Go tour is no longer included in the main binary distribution. To
|
||||
run the tour locally, instead of running <code>go</code> <code>tool</code> <code>tour</code>,
|
||||
manually install it:
|
||||
<pre>
|
||||
go install golang.org/x/tour
|
||||
go get -u golang.org/x/tour
|
||||
tour
|
||||
</pre>
|
||||
</p>
|
||||
@@ -192,6 +185,17 @@ tour
|
||||
that build fails.
|
||||
</p>
|
||||
|
||||
<p><!-- CL 147282, 147281 -->
|
||||
This changed use of the <code>go</code> directive means that if you
|
||||
use Go 1.12 to build a module, thus recording <code>go 1.12</code>
|
||||
in the <code>go.mod</code> file, you will get an error when
|
||||
attempting to build the same module with Go 1.11 through Go 1.11.3.
|
||||
Go 1.11.4 or later will work fine, as will releases older than Go 1.11.
|
||||
If you must use Go 1.11 through 1.11.3, you can avoid the problem by
|
||||
setting the language version to 1.11, using the Go 1.12 go tool,
|
||||
via <code>go mod edit -go=1.11</code>.
|
||||
</p>
|
||||
|
||||
<p><!-- CL 152739 -->
|
||||
When an import cannot be resolved using the active modules,
|
||||
the <code>go</code> command will now try to use the modules mentioned in the
|
||||
@@ -303,7 +307,9 @@ for {
|
||||
<p>
|
||||
In Go 1.12, <code>godoc</code> no longer has a command-line interface and
|
||||
is only a web server. Users should use <code>go</code> <code>doc</code>
|
||||
for command-line help output instead.
|
||||
for command-line help output instead. Go 1.12 is the last release that will
|
||||
include the <code>godoc</code> webserver; in Go 1.13 it will be available
|
||||
via <code>go</code> <code>get</code>.
|
||||
</p>
|
||||
|
||||
<p><!-- CL 141977 -->
|
||||
@@ -493,8 +499,11 @@ for {
|
||||
<dl id="crypto/rc4"><dt><a href="/pkg/crypto/rc4/">crypto/rc4</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 130397 -->
|
||||
This release removes the optimized assembly implementations. RC4 is insecure
|
||||
and should only be used for compatibility with legacy systems.
|
||||
This release removes the assembly implementations, leaving only
|
||||
the pure Go version. The Go compiler generates code that is
|
||||
either slightly better or slightly worse, depending on the exact
|
||||
CPU. RC4 is insecure and should only be used for compatibility
|
||||
with legacy systems.
|
||||
</p>
|
||||
|
||||
</dl><!-- crypto/rc4 -->
|
||||
@@ -602,17 +611,6 @@ for {
|
||||
|
||||
</dl><!-- io -->
|
||||
|
||||
<dl id="lib/time"><dt><a href="/pkg/lib/time/">lib/time</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 151299 -->
|
||||
The time zone database in <code>$GOROOT/lib/time/zoneinfo.zip</code>
|
||||
has been updated to version 2018i. Note that this ZIP file is
|
||||
only used if a time zone database is not provided by the operating
|
||||
system.
|
||||
</p>
|
||||
|
||||
</dl><!-- lib/time -->
|
||||
|
||||
<dl id="math"><dt><a href="/pkg/math/">math</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 153059 -->
|
||||
@@ -689,6 +687,20 @@ for {
|
||||
|
||||
</dl><!-- net/http -->
|
||||
|
||||
<dl id="net/url"><dt><a href="/pkg/net/url/">net/url</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 159157, CL 160178 -->
|
||||
<a href="/pkg/net/url/#Parse"><code>Parse</code></a>,
|
||||
<a href="/pkg/net/url/#ParseRequestURI"><code>ParseRequestURI</code></a>,
|
||||
and
|
||||
<a href="/pkg/net/url/#URL.Parse"><code>URL.Parse</code></a>
|
||||
now return an
|
||||
error for URLs containing ASCII control characters, which includes NULL,
|
||||
tab, and newlines.
|
||||
</p>
|
||||
|
||||
</dl><!-- net/url -->
|
||||
|
||||
<dl id="net/http/httputil"><dt><a href="/pkg/net/http/httputil/">net/http/httputil</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 146437 -->
|
||||
@@ -779,7 +791,7 @@ for {
|
||||
A new <a href="/pkg/runtime/debug/#BuildInfo"><code>BuildInfo</code></a> type
|
||||
exposes the build information read from the running binary, available only in
|
||||
binaries built with module support. This includes the main package path, main
|
||||
module information, and the module dependencies. This type is given though the
|
||||
module information, and the module dependencies. This type is given through the
|
||||
<a href="/pkg/runtime/debug/#ReadBuildInfo"><code>ReadBuildInfo</code></a> function
|
||||
on <a href="/pkg/runtime/debug/#BuildInfo"><code>BuildInfo</code></a>.
|
||||
</p>
|
||||
@@ -912,6 +924,17 @@ for {
|
||||
</p>
|
||||
</dl><!-- text/template -->
|
||||
|
||||
<dl id="time"><dt><a href="/pkg/time/">time</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 151299 -->
|
||||
The time zone database in <code>$GOROOT/lib/time/zoneinfo.zip</code>
|
||||
has been updated to version 2018i. Note that this ZIP file is
|
||||
only used if a time zone database is not provided by the operating
|
||||
system.
|
||||
</p>
|
||||
|
||||
</dl><!-- time -->
|
||||
|
||||
<dl id="unsafe"><dt><a href="/pkg/unsafe/">unsafe</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 146058 -->
|
||||
|
||||
@@ -349,15 +349,7 @@ provides <b>essential setup instructions</b> for using the Go tools.
|
||||
<p>
|
||||
The source code for several Go tools (including <a href="/cmd/godoc/">godoc</a>)
|
||||
is kept in <a href="https://golang.org/x/tools">the go.tools repository</a>.
|
||||
To install all of them, run the <code>go</code> <code>get</code> command:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ go get golang.org/x/tools/cmd/...
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Or if you just want to install a specific command (<code>godoc</code> in this case):
|
||||
To install one of the tools (<code>godoc</code> in this case):
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
@@ -374,16 +366,6 @@ You must also have a workspace (<code>GOPATH</code>) set up;
|
||||
see <a href="/doc/code.html">How to Write Go Code</a> for the details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Note</b>: The <code>go</code> command will install the <code>godoc</code>
|
||||
binary to <code>$GOROOT/bin</code> (or <code>$GOBIN</code>) and the
|
||||
<code>cover</code> and <code>vet</code> binaries to
|
||||
<code>$GOROOT/pkg/tool/$GOOS_$GOARCH</code>.
|
||||
You can access the latter commands with
|
||||
"<code>go</code> <code>tool</code> <code>cover</code>" and
|
||||
"<code>go</code> <code>tool</code> <code>vet</code>".
|
||||
</p>
|
||||
|
||||
<h2 id="community">Community resources</h2>
|
||||
|
||||
<p>
|
||||
|
||||
14
misc/cgo/test/testdata/issue30527.go
vendored
Normal file
14
misc/cgo/test/testdata/issue30527.go
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Issue 30527: function call rewriting casts untyped
|
||||
// constants to int because of ":=" usage.
|
||||
|
||||
package cgotest
|
||||
|
||||
import "cgotest/issue30527"
|
||||
|
||||
func issue30527G() {
|
||||
issue30527.G(nil)
|
||||
}
|
||||
19
misc/cgo/test/testdata/issue30527/a.go
vendored
Normal file
19
misc/cgo/test/testdata/issue30527/a.go
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package issue30527
|
||||
|
||||
import "math"
|
||||
|
||||
/*
|
||||
#include <inttypes.h>
|
||||
|
||||
static void issue30527F(char **p, uint64_t mod, uint32_t unused) {}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
func G(p **C.char) {
|
||||
C.issue30527F(p, math.MaxUint64, 1)
|
||||
C.issue30527F(p, 1<<64-1, Z)
|
||||
}
|
||||
11
misc/cgo/test/testdata/issue30527/b.go
vendored
Normal file
11
misc/cgo/test/testdata/issue30527/b.go
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package issue30527
|
||||
|
||||
const (
|
||||
X = 1 << iota
|
||||
Y
|
||||
Z
|
||||
)
|
||||
12
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
12
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
@@ -261,6 +261,18 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
|
||||
ORRW $0x1b000, R2, R3 // ORRW $110592, R2, R3 // 1b0096523b00a07243001b2a
|
||||
TSTW $0x500000, R1 // TSTW $5242880, R1 // 1b0aa0523f001b6a
|
||||
TSTW $0xff00ff, R1 // TSTW $16711935, R1 // 3f9c0072
|
||||
TSTW $0x60060, R5 // TSTW $393312, R5 // 1b0c8052db00a072bf001b6a
|
||||
TSTW $0x6006000060060, R5 // TSTW $1689262177517664, R5 // 1b0c8052db00a072bf001b6a
|
||||
ANDW $0x6006000060060, R5 // ANDW $1689262177517664, R5 // 1b0c8052db00a072a5001b0a
|
||||
ANDSW $0x6006000060060, R5 // ANDSW $1689262177517664, R5 // 1b0c8052db00a072a5001b6a
|
||||
EORW $0x6006000060060, R5 // EORW $1689262177517664, R5 // 1b0c8052db00a072a5001b4a
|
||||
ORRW $0x6006000060060, R5 // ORRW $1689262177517664, R5 // 1b0c8052db00a072a5001b2a
|
||||
BICW $0x6006000060060, R5 // BICW $1689262177517664, R5 // 1b0c8052db00a072a5003b0a
|
||||
EONW $0x6006000060060, R5 // EONW $1689262177517664, R5 // 1b0c8052db00a072a5003b4a
|
||||
ORNW $0x6006000060060, R5 // ORNW $1689262177517664, R5 // 1b0c8052db00a072a5003b2a
|
||||
BICSW $0x6006000060060, R5 // BICSW $1689262177517664, R5 // 1b0c8052db00a072a5003b6a
|
||||
ADDW $0x60060, R2 // ADDW $393312, R2 // 4280011142804111
|
||||
CMPW $0x60060, R2 // CMPW $393312, R2 // 1b0c8052db00a0725f001b6b
|
||||
|
||||
AND $8, R0, RSP // 1f007d92
|
||||
ORR $8, R0, RSP // 1f007db2
|
||||
|
||||
@@ -200,18 +200,6 @@ func (f *File) saveExprs(x interface{}, context astContext) {
|
||||
}
|
||||
case *ast.CallExpr:
|
||||
f.saveCall(x, context)
|
||||
case *ast.GenDecl:
|
||||
if x.Tok == token.CONST {
|
||||
for _, spec := range x.Specs {
|
||||
vs := spec.(*ast.ValueSpec)
|
||||
if vs.Type == nil {
|
||||
for _, name := range spec.(*ast.ValueSpec).Names {
|
||||
consts[name.Name] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -897,21 +897,16 @@ func (p *Package) rewriteCall(f *File, call *Call) (string, bool) {
|
||||
needsUnsafe = true
|
||||
}
|
||||
|
||||
// Explicitly convert untyped constants to the
|
||||
// parameter type, to avoid a type mismatch.
|
||||
if p.isConst(f, arg) {
|
||||
ptype := p.rewriteUnsafe(param.Go)
|
||||
// Use "var x T = ..." syntax to explicitly convert untyped
|
||||
// constants to the parameter type, to avoid a type mismatch.
|
||||
ptype := p.rewriteUnsafe(param.Go)
|
||||
|
||||
if !p.needsPointerCheck(f, param.Go, args[i]) || param.BadPointer {
|
||||
if ptype != param.Go {
|
||||
needsUnsafe = true
|
||||
}
|
||||
arg = &ast.CallExpr{
|
||||
Fun: ptype,
|
||||
Args: []ast.Expr{arg},
|
||||
}
|
||||
}
|
||||
|
||||
if !p.needsPointerCheck(f, param.Go, args[i]) {
|
||||
fmt.Fprintf(&sb, "_cgo%d := %s; ", i, gofmtPos(arg, origArg.Pos()))
|
||||
fmt.Fprintf(&sb, "var _cgo%d %s = %s; ", i,
|
||||
gofmtLine(ptype), gofmtPos(arg, origArg.Pos()))
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -1254,47 +1249,6 @@ func (p *Package) isType(t ast.Expr) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// isConst reports whether x is an untyped constant expression.
|
||||
func (p *Package) isConst(f *File, x ast.Expr) bool {
|
||||
switch x := x.(type) {
|
||||
case *ast.BasicLit:
|
||||
return true
|
||||
case *ast.SelectorExpr:
|
||||
id, ok := x.X.(*ast.Ident)
|
||||
if !ok || id.Name != "C" {
|
||||
return false
|
||||
}
|
||||
name := f.Name[x.Sel.Name]
|
||||
if name != nil {
|
||||
return name.IsConst()
|
||||
}
|
||||
case *ast.Ident:
|
||||
return x.Name == "nil" ||
|
||||
strings.HasPrefix(x.Name, "_Ciconst_") ||
|
||||
strings.HasPrefix(x.Name, "_Cfconst_") ||
|
||||
strings.HasPrefix(x.Name, "_Csconst_") ||
|
||||
consts[x.Name]
|
||||
case *ast.UnaryExpr:
|
||||
return p.isConst(f, x.X)
|
||||
case *ast.BinaryExpr:
|
||||
return p.isConst(f, x.X) && p.isConst(f, x.Y)
|
||||
case *ast.ParenExpr:
|
||||
return p.isConst(f, x.X)
|
||||
case *ast.CallExpr:
|
||||
// Calling the builtin function complex on two untyped
|
||||
// constants returns an untyped constant.
|
||||
// TODO: It's possible to construct a case that will
|
||||
// erroneously succeed if there is a local function
|
||||
// named "complex", shadowing the builtin, that returns
|
||||
// a numeric type. I can't think of any cases that will
|
||||
// erroneously fail.
|
||||
if id, ok := x.Fun.(*ast.Ident); ok && id.Name == "complex" && len(x.Args) == 2 {
|
||||
return p.isConst(f, x.Args[0]) && p.isConst(f, x.Args[1])
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// isVariable reports whether x is a variable, possibly with field references.
|
||||
func (p *Package) isVariable(x ast.Expr) bool {
|
||||
switch x := x.(type) {
|
||||
@@ -2511,13 +2465,16 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
|
||||
// Treat this typedef as a uintptr.
|
||||
s := *sub
|
||||
s.Go = c.uintptr
|
||||
s.BadPointer = true
|
||||
sub = &s
|
||||
// Make sure we update any previously computed type.
|
||||
if oldType := typedef[name.Name]; oldType != nil {
|
||||
oldType.Go = sub.Go
|
||||
oldType.BadPointer = true
|
||||
}
|
||||
}
|
||||
t.Go = name
|
||||
t.BadPointer = sub.BadPointer
|
||||
if unionWithPointer[sub.Go] {
|
||||
unionWithPointer[t.Go] = true
|
||||
}
|
||||
@@ -2527,6 +2484,7 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
|
||||
if oldType == nil {
|
||||
tt := *t
|
||||
tt.Go = sub.Go
|
||||
tt.BadPointer = sub.BadPointer
|
||||
typedef[name.Name] = &tt
|
||||
}
|
||||
|
||||
|
||||
@@ -71,9 +71,6 @@ type File struct {
|
||||
Edit *edit.Buffer
|
||||
}
|
||||
|
||||
// Untyped constants in the current package.
|
||||
var consts = make(map[string]bool)
|
||||
|
||||
func (f *File) offset(p token.Pos) int {
|
||||
return fset.Position(p).Offset
|
||||
}
|
||||
@@ -154,6 +151,7 @@ type Type struct {
|
||||
Go ast.Expr
|
||||
EnumValues map[string]int64
|
||||
Typedef string
|
||||
BadPointer bool
|
||||
}
|
||||
|
||||
// A FuncType collects information about a function type in both the C and Go worlds.
|
||||
|
||||
@@ -24,6 +24,7 @@ func Init(arch *gc.Arch) {
|
||||
arch.ZeroRange = zerorange
|
||||
arch.ZeroAuto = zeroAuto
|
||||
arch.Ginsnop = ginsnop
|
||||
arch.Ginsnopdefer = ginsnop
|
||||
|
||||
arch.SSAMarkMoves = ssaMarkMoves
|
||||
arch.SSAGenValue = ssaGenValue
|
||||
|
||||
@@ -19,6 +19,7 @@ func Init(arch *gc.Arch) {
|
||||
arch.ZeroRange = zerorange
|
||||
arch.ZeroAuto = zeroAuto
|
||||
arch.Ginsnop = ginsnop
|
||||
arch.Ginsnopdefer = ginsnop
|
||||
|
||||
arch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
|
||||
arch.SSAGenValue = ssaGenValue
|
||||
|
||||
@@ -19,6 +19,7 @@ func Init(arch *gc.Arch) {
|
||||
arch.ZeroRange = zerorange
|
||||
arch.ZeroAuto = zeroAuto
|
||||
arch.Ginsnop = ginsnop
|
||||
arch.Ginsnopdefer = ginsnop
|
||||
|
||||
arch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
|
||||
arch.SSAGenValue = ssaGenValue
|
||||
|
||||
@@ -127,7 +127,7 @@ func assembleInlines(fnsym *obj.LSym, dwVars []*dwarf.Var) dwarf.InlCalls {
|
||||
DeclLine: v.DeclLine,
|
||||
DeclCol: v.DeclCol,
|
||||
}
|
||||
synthesized := strings.HasPrefix(v.Name, "~r") || canonName == "_"
|
||||
synthesized := strings.HasPrefix(v.Name, "~r") || canonName == "_" || strings.HasPrefix(v.Name, "~b")
|
||||
if idx, found := m[vp]; found {
|
||||
v.ChildIndex = int32(idx)
|
||||
v.IsInAbstract = !synthesized
|
||||
|
||||
@@ -2105,6 +2105,16 @@ func (e *EscState) escwalkBody(level Level, dst *Node, src *Node, step *EscStep,
|
||||
step.describe(src)
|
||||
}
|
||||
extraloopdepth = modSrcLoopdepth
|
||||
if src.Op == OCONVIFACE {
|
||||
lt := src.Left.Type
|
||||
if !lt.IsInterface() && !isdirectiface(lt) && types.Haspointers(lt) {
|
||||
// We're converting from a non-direct interface type.
|
||||
// The interface will hold a heap copy of the data
|
||||
// (by calling convT2I or friend). Flow the data to heap.
|
||||
// See issue 29353.
|
||||
e.escwalk(level, &e.theSink, src.Left, e.stepWalk(dst, src.Left, "interface-converted", step))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case ODOT,
|
||||
|
||||
@@ -255,9 +255,10 @@ type Arch struct {
|
||||
Use387 bool // should 386 backend use 387 FP instructions instead of sse2.
|
||||
SoftFloat bool
|
||||
|
||||
PadFrame func(int64) int64
|
||||
ZeroRange func(*Progs, *obj.Prog, int64, int64, *uint32) *obj.Prog
|
||||
Ginsnop func(*Progs) *obj.Prog
|
||||
PadFrame func(int64) int64
|
||||
ZeroRange func(*Progs, *obj.Prog, int64, int64, *uint32) *obj.Prog
|
||||
Ginsnop func(*Progs) *obj.Prog
|
||||
Ginsnopdefer func(*Progs) *obj.Prog // special ginsnop for deferreturn
|
||||
|
||||
// SSAMarkMoves marks any MOVXconst ops that need to avoid clobbering flags.
|
||||
SSAMarkMoves func(*SSAGenState, *ssa.Block)
|
||||
|
||||
@@ -287,7 +287,7 @@ func addGCLocals() {
|
||||
}
|
||||
}
|
||||
if x := s.Func.StackObjects; x != nil {
|
||||
ggloblsym(x, int32(len(x.P)), obj.RODATA|obj.LOCAL)
|
||||
ggloblsym(x, int32(len(x.P)), obj.RODATA|obj.DUPOK)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1108,10 +1108,10 @@ func (o *Order) expr(n, lhs *Node) *Node {
|
||||
if n.Left.Type.IsInterface() {
|
||||
break
|
||||
}
|
||||
if _, needsaddr := convFuncName(n.Left.Type, n.Type); needsaddr || consttype(n.Left) > 0 {
|
||||
if _, needsaddr := convFuncName(n.Left.Type, n.Type); needsaddr || isStaticCompositeLiteral(n.Left) {
|
||||
// Need a temp if we need to pass the address to the conversion function.
|
||||
// We also process constants here, making a named static global whose
|
||||
// address we can put directly in an interface (see OCONVIFACE case in walk).
|
||||
// We also process static composite literal node here, making a named static global
|
||||
// whose address we can put directly in an interface (see OCONVIFACE case in walk).
|
||||
n.Left = o.addrTemp(n.Left)
|
||||
}
|
||||
|
||||
@@ -1130,14 +1130,40 @@ func (o *Order) expr(n, lhs *Node) *Node {
|
||||
}
|
||||
|
||||
case OANDAND, OOROR:
|
||||
mark := o.markTemp()
|
||||
n.Left = o.expr(n.Left, nil)
|
||||
// ... = LHS && RHS
|
||||
//
|
||||
// var r bool
|
||||
// r = LHS
|
||||
// if r { // or !r, for OROR
|
||||
// r = RHS
|
||||
// }
|
||||
// ... = r
|
||||
|
||||
// Clean temporaries from first branch at beginning of second.
|
||||
// Leave them on the stack so that they can be killed in the outer
|
||||
// context in case the short circuit is taken.
|
||||
n.Right = addinit(n.Right, o.cleanTempNoPop(mark))
|
||||
n.Right = o.exprInPlace(n.Right)
|
||||
r := o.newTemp(n.Type, false)
|
||||
|
||||
// Evaluate left-hand side.
|
||||
lhs := o.expr(n.Left, nil)
|
||||
o.out = append(o.out, typecheck(nod(OAS, r, lhs), ctxStmt))
|
||||
|
||||
// Evaluate right-hand side, save generated code.
|
||||
saveout := o.out
|
||||
o.out = nil
|
||||
t := o.markTemp()
|
||||
rhs := o.expr(n.Right, nil)
|
||||
o.out = append(o.out, typecheck(nod(OAS, r, rhs), ctxStmt))
|
||||
o.cleanTemp(t)
|
||||
gen := o.out
|
||||
o.out = saveout
|
||||
|
||||
// If left-hand side doesn't cause a short-circuit, issue right-hand side.
|
||||
nif := nod(OIF, r, nil)
|
||||
if n.Op == OANDAND {
|
||||
nif.Nbody.Set(gen)
|
||||
} else {
|
||||
nif.Rlist.Set(gen)
|
||||
}
|
||||
o.out = append(o.out, nif)
|
||||
n = r
|
||||
|
||||
case OCALLFUNC,
|
||||
OCALLINTER,
|
||||
|
||||
@@ -267,7 +267,7 @@ func compile(fn *Node) {
|
||||
// Also make sure we allocate a linker symbol
|
||||
// for the stack object data, for the same reason.
|
||||
if fn.Func.lsym.Func.StackObjects == nil {
|
||||
fn.Func.lsym.Func.StackObjects = lookup(fmt.Sprintf("%s.stkobj", fn.funcname())).Linksym()
|
||||
fn.Func.lsym.Func.StackObjects = Ctxt.Lookup(fn.Func.lsym.Name + ".stkobj")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -597,8 +597,22 @@ func createDwarfVars(fnsym *obj.LSym, fn *Func, automDecls []*Node) ([]*Node, []
|
||||
typename := dwarf.InfoPrefix + typesymname(n.Type)
|
||||
decls = append(decls, n)
|
||||
abbrev := dwarf.DW_ABRV_AUTO_LOCLIST
|
||||
isReturnValue := (n.Class() == PPARAMOUT)
|
||||
if n.Class() == PPARAM || n.Class() == PPARAMOUT {
|
||||
abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
|
||||
} else if n.Class() == PAUTOHEAP {
|
||||
// If dcl in question has been promoted to heap, do a bit
|
||||
// of extra work to recover original class (auto or param);
|
||||
// see issue 30908. This insures that we get the proper
|
||||
// signature in the abstract function DIE, but leaves a
|
||||
// misleading location for the param (we want pointer-to-heap
|
||||
// and not stack).
|
||||
// TODO(thanm): generate a better location expression
|
||||
stackcopy := n.Name.Param.Stackcopy
|
||||
if stackcopy != nil && (stackcopy.Class() == PPARAM || stackcopy.Class() == PPARAMOUT) {
|
||||
abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
|
||||
isReturnValue = (stackcopy.Class() == PPARAMOUT)
|
||||
}
|
||||
}
|
||||
inlIndex := 0
|
||||
if genDwarfInline > 1 {
|
||||
@@ -612,7 +626,7 @@ func createDwarfVars(fnsym *obj.LSym, fn *Func, automDecls []*Node) ([]*Node, []
|
||||
declpos := Ctxt.InnermostPos(n.Pos)
|
||||
vars = append(vars, &dwarf.Var{
|
||||
Name: n.Sym.Name,
|
||||
IsReturnValue: n.Class() == PPARAMOUT,
|
||||
IsReturnValue: isReturnValue,
|
||||
Abbrev: abbrev,
|
||||
StackOffset: int32(n.Xoffset),
|
||||
Type: Ctxt.Lookup(typename),
|
||||
|
||||
@@ -993,26 +993,32 @@ func (s *state) stmt(n *Node) {
|
||||
s.assign(n.Left, r, deref, skip)
|
||||
|
||||
case OIF:
|
||||
bThen := s.f.NewBlock(ssa.BlockPlain)
|
||||
bEnd := s.f.NewBlock(ssa.BlockPlain)
|
||||
var bElse *ssa.Block
|
||||
var likely int8
|
||||
if n.Likely() {
|
||||
likely = 1
|
||||
}
|
||||
var bThen *ssa.Block
|
||||
if n.Nbody.Len() != 0 {
|
||||
bThen = s.f.NewBlock(ssa.BlockPlain)
|
||||
} else {
|
||||
bThen = bEnd
|
||||
}
|
||||
var bElse *ssa.Block
|
||||
if n.Rlist.Len() != 0 {
|
||||
bElse = s.f.NewBlock(ssa.BlockPlain)
|
||||
s.condBranch(n.Left, bThen, bElse, likely)
|
||||
} else {
|
||||
s.condBranch(n.Left, bThen, bEnd, likely)
|
||||
bElse = bEnd
|
||||
}
|
||||
s.condBranch(n.Left, bThen, bElse, likely)
|
||||
|
||||
s.startBlock(bThen)
|
||||
s.stmtList(n.Nbody)
|
||||
if b := s.endBlock(); b != nil {
|
||||
b.AddEdgeTo(bEnd)
|
||||
if n.Nbody.Len() != 0 {
|
||||
s.startBlock(bThen)
|
||||
s.stmtList(n.Nbody)
|
||||
if b := s.endBlock(); b != nil {
|
||||
b.AddEdgeTo(bEnd)
|
||||
}
|
||||
}
|
||||
|
||||
if n.Rlist.Len() != 0 {
|
||||
s.startBlock(bElse)
|
||||
s.stmtList(n.Rlist)
|
||||
@@ -5597,7 +5603,7 @@ func (s *SSAGenState) PrepareCall(v *ssa.Value) {
|
||||
// insert an actual hardware NOP that will have the right line number.
|
||||
// This is different from obj.ANOP, which is a virtual no-op
|
||||
// that doesn't make it into the instruction stream.
|
||||
thearch.Ginsnop(s.pp)
|
||||
thearch.Ginsnopdefer(s.pp)
|
||||
}
|
||||
|
||||
if sym, ok := v.Aux.(*obj.LSym); ok {
|
||||
|
||||
@@ -22,6 +22,7 @@ func Init(arch *gc.Arch) {
|
||||
arch.ZeroRange = zerorange
|
||||
arch.ZeroAuto = zeroAuto
|
||||
arch.Ginsnop = ginsnop
|
||||
arch.Ginsnopdefer = ginsnop
|
||||
arch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
|
||||
arch.SSAGenValue = ssaGenValue
|
||||
arch.SSAGenBlock = ssaGenBlock
|
||||
|
||||
@@ -22,6 +22,7 @@ func Init(arch *gc.Arch) {
|
||||
arch.ZeroRange = zerorange
|
||||
arch.ZeroAuto = zeroAuto
|
||||
arch.Ginsnop = ginsnop
|
||||
arch.Ginsnopdefer = ginsnop
|
||||
|
||||
arch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
|
||||
arch.SSAGenValue = ssaGenValue
|
||||
|
||||
@@ -20,7 +20,8 @@ func Init(arch *gc.Arch) {
|
||||
|
||||
arch.ZeroRange = zerorange
|
||||
arch.ZeroAuto = zeroAuto
|
||||
arch.Ginsnop = ginsnop2
|
||||
arch.Ginsnop = ginsnop
|
||||
arch.Ginsnopdefer = ginsnop2
|
||||
|
||||
arch.SSAMarkMoves = ssaMarkMoves
|
||||
arch.SSAGenValue = ssaGenValue
|
||||
|
||||
@@ -17,6 +17,7 @@ func Init(arch *gc.Arch) {
|
||||
arch.ZeroRange = zerorange
|
||||
arch.ZeroAuto = zeroAuto
|
||||
arch.Ginsnop = ginsnop
|
||||
arch.Ginsnopdefer = ginsnop
|
||||
|
||||
arch.SSAMarkMoves = ssaMarkMoves
|
||||
arch.SSAGenValue = ssaGenValue
|
||||
|
||||
@@ -1220,6 +1220,13 @@ func (s *regAllocState) regalloc(f *Func) {
|
||||
// This forces later liveness analysis to make the
|
||||
// value live at this point.
|
||||
v.SetArg(0, s.makeSpill(a, b))
|
||||
} else if _, ok := a.Aux.(GCNode); ok && vi.rematerializeable {
|
||||
// Rematerializeable value with a gc.Node. This is the address of
|
||||
// a stack object (e.g. an LEAQ). Keep the object live.
|
||||
// Change it to VarLive, which is what plive expects for locals.
|
||||
v.Op = OpVarLive
|
||||
v.SetArgs1(v.Args[1])
|
||||
v.Aux = a.Aux
|
||||
} else {
|
||||
// In-register and rematerializeable values are already live.
|
||||
// These are typically rematerializeable constants like nil,
|
||||
|
||||
@@ -1141,7 +1141,7 @@ func symIsRO(sym interface{}) bool {
|
||||
// read8 reads one byte from the read-only global sym at offset off.
|
||||
func read8(sym interface{}, off int64) uint8 {
|
||||
lsym := sym.(*obj.LSym)
|
||||
if off >= int64(len(lsym.P)) {
|
||||
if off >= int64(len(lsym.P)) || off < 0 {
|
||||
// Invalid index into the global sym.
|
||||
// This can happen in dead code, so we don't want to panic.
|
||||
// Just return any value, it will eventually get ignored.
|
||||
@@ -1154,7 +1154,7 @@ func read8(sym interface{}, off int64) uint8 {
|
||||
// read16 reads two bytes from the read-only global sym at offset off.
|
||||
func read16(sym interface{}, off int64, bigEndian bool) uint16 {
|
||||
lsym := sym.(*obj.LSym)
|
||||
if off >= int64(len(lsym.P))-1 {
|
||||
if off >= int64(len(lsym.P))-1 || off < 0 {
|
||||
return 0
|
||||
}
|
||||
if bigEndian {
|
||||
@@ -1167,7 +1167,7 @@ func read16(sym interface{}, off int64, bigEndian bool) uint16 {
|
||||
// read32 reads four bytes from the read-only global sym at offset off.
|
||||
func read32(sym interface{}, off int64, bigEndian bool) uint32 {
|
||||
lsym := sym.(*obj.LSym)
|
||||
if off >= int64(len(lsym.P))-3 {
|
||||
if off >= int64(len(lsym.P))-3 || off < 0 {
|
||||
return 0
|
||||
}
|
||||
if bigEndian {
|
||||
@@ -1180,7 +1180,7 @@ func read32(sym interface{}, off int64, bigEndian bool) uint32 {
|
||||
// read64 reads eight bytes from the read-only global sym at offset off.
|
||||
func read64(sym interface{}, off int64, bigEndian bool) uint64 {
|
||||
lsym := sym.(*obj.LSym)
|
||||
if off >= int64(len(lsym.P))-7 {
|
||||
if off >= int64(len(lsym.P))-7 || off < 0 {
|
||||
return 0
|
||||
}
|
||||
if bigEndian {
|
||||
|
||||
@@ -196,6 +196,43 @@ func writebarrier(f *Func) {
|
||||
// and simple store version to bElse
|
||||
memThen := mem
|
||||
memElse := mem
|
||||
|
||||
// If the source of a MoveWB is volatile (will be clobbered by a
|
||||
// function call), we need to copy it to a temporary location, as
|
||||
// marshaling the args of typedmemmove might clobber the value we're
|
||||
// trying to move.
|
||||
// Look for volatile source, copy it to temporary before we emit any
|
||||
// call.
|
||||
// It is unlikely to have more than one of them. Just do a linear
|
||||
// search instead of using a map.
|
||||
type volatileCopy struct {
|
||||
src *Value // address of original volatile value
|
||||
tmp *Value // address of temporary we've copied the volatile value into
|
||||
}
|
||||
var volatiles []volatileCopy
|
||||
copyLoop:
|
||||
for _, w := range stores {
|
||||
if w.Op == OpMoveWB {
|
||||
val := w.Args[1]
|
||||
if isVolatile(val) {
|
||||
for _, c := range volatiles {
|
||||
if val == c.src {
|
||||
continue copyLoop // already copied
|
||||
}
|
||||
}
|
||||
|
||||
t := val.Type.Elem()
|
||||
tmp := f.fe.Auto(w.Pos, t)
|
||||
memThen = bThen.NewValue1A(w.Pos, OpVarDef, types.TypeMem, tmp, memThen)
|
||||
tmpaddr := bThen.NewValue2A(w.Pos, OpLocalAddr, t.PtrTo(), tmp, sp, memThen)
|
||||
siz := t.Size()
|
||||
memThen = bThen.NewValue3I(w.Pos, OpMove, types.TypeMem, siz, tmpaddr, val, memThen)
|
||||
memThen.Aux = t
|
||||
volatiles = append(volatiles, volatileCopy{val, tmpaddr})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, w := range stores {
|
||||
ptr := w.Args[0]
|
||||
pos := w.Pos
|
||||
@@ -222,11 +259,19 @@ func writebarrier(f *Func) {
|
||||
// then block: emit write barrier call
|
||||
switch w.Op {
|
||||
case OpStoreWB, OpMoveWB, OpZeroWB:
|
||||
volatile := w.Op == OpMoveWB && isVolatile(val)
|
||||
if w.Op == OpStoreWB {
|
||||
memThen = bThen.NewValue3A(pos, OpWB, types.TypeMem, gcWriteBarrier, ptr, val, memThen)
|
||||
} else {
|
||||
memThen = wbcall(pos, bThen, fn, typ, ptr, val, memThen, sp, sb, volatile)
|
||||
srcval := val
|
||||
if w.Op == OpMoveWB && isVolatile(srcval) {
|
||||
for _, c := range volatiles {
|
||||
if srcval == c.src {
|
||||
srcval = c.tmp
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
memThen = wbcall(pos, bThen, fn, typ, ptr, srcval, memThen, sp, sb)
|
||||
}
|
||||
// Note that we set up a writebarrier function call.
|
||||
f.fe.SetWBPos(pos)
|
||||
@@ -249,6 +294,12 @@ func writebarrier(f *Func) {
|
||||
}
|
||||
}
|
||||
|
||||
// mark volatile temps dead
|
||||
for _, c := range volatiles {
|
||||
tmpNode := c.tmp.Aux
|
||||
memThen = bThen.NewValue1A(memThen.Pos, OpVarKill, types.TypeMem, tmpNode, memThen)
|
||||
}
|
||||
|
||||
// merge memory
|
||||
// Splice memory Phi into the last memory of the original sequence,
|
||||
// which may be used in subsequent blocks. Other memories in the
|
||||
@@ -302,25 +353,9 @@ func writebarrier(f *Func) {
|
||||
}
|
||||
|
||||
// wbcall emits write barrier runtime call in b, returns memory.
|
||||
// if valIsVolatile, it moves val into temp space before making the call.
|
||||
func wbcall(pos src.XPos, b *Block, fn, typ *obj.LSym, ptr, val, mem, sp, sb *Value, valIsVolatile bool) *Value {
|
||||
func wbcall(pos src.XPos, b *Block, fn, typ *obj.LSym, ptr, val, mem, sp, sb *Value) *Value {
|
||||
config := b.Func.Config
|
||||
|
||||
var tmp GCNode
|
||||
if valIsVolatile {
|
||||
// Copy to temp location if the source is volatile (will be clobbered by
|
||||
// a function call). Marshaling the args to typedmemmove might clobber the
|
||||
// value we're trying to move.
|
||||
t := val.Type.Elem()
|
||||
tmp = b.Func.fe.Auto(val.Pos, t)
|
||||
mem = b.NewValue1A(pos, OpVarDef, types.TypeMem, tmp, mem)
|
||||
tmpaddr := b.NewValue2A(pos, OpLocalAddr, t.PtrTo(), tmp, sp, mem)
|
||||
siz := t.Size()
|
||||
mem = b.NewValue3I(pos, OpMove, types.TypeMem, siz, tmpaddr, val, mem)
|
||||
mem.Aux = t
|
||||
val = tmpaddr
|
||||
}
|
||||
|
||||
// put arguments on stack
|
||||
off := config.ctxt.FixedFrameSize()
|
||||
|
||||
@@ -348,11 +383,6 @@ func wbcall(pos src.XPos, b *Block, fn, typ *obj.LSym, ptr, val, mem, sp, sb *Va
|
||||
// issue call
|
||||
mem = b.NewValue1A(pos, OpStaticCall, types.TypeMem, fn, mem)
|
||||
mem.AuxInt = off - config.ctxt.FixedFrameSize()
|
||||
|
||||
if valIsVolatile {
|
||||
mem = b.NewValue1A(pos, OpVarKill, types.TypeMem, tmp, mem) // mark temp dead
|
||||
}
|
||||
|
||||
return mem
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ func Init(arch *gc.Arch) {
|
||||
arch.ZeroRange = zeroRange
|
||||
arch.ZeroAuto = zeroAuto
|
||||
arch.Ginsnop = ginsnop
|
||||
arch.Ginsnopdefer = ginsnop
|
||||
|
||||
arch.SSAMarkMoves = ssaMarkMoves
|
||||
arch.SSAGenValue = ssaGenValue
|
||||
|
||||
@@ -32,6 +32,7 @@ func Init(arch *gc.Arch) {
|
||||
arch.ZeroRange = zerorange
|
||||
arch.ZeroAuto = zeroAuto
|
||||
arch.Ginsnop = ginsnop
|
||||
arch.Ginsnopdefer = ginsnop
|
||||
|
||||
arch.SSAMarkMoves = ssaMarkMoves
|
||||
}
|
||||
|
||||
7
src/cmd/go/internal/cache/default.go
vendored
7
src/cmd/go/internal/cache/default.go
vendored
@@ -37,7 +37,7 @@ See golang.org to learn more about Go.
|
||||
// the first time Default is called.
|
||||
func initDefaultCache() {
|
||||
dir := DefaultDir()
|
||||
if dir == "off" || dir == "" {
|
||||
if dir == "off" {
|
||||
if defaultDirErr != nil {
|
||||
base.Fatalf("build cache is required, but could not be located: %v", defaultDirErr)
|
||||
}
|
||||
@@ -74,7 +74,12 @@ func DefaultDir() string {
|
||||
|
||||
defaultDirOnce.Do(func() {
|
||||
defaultDir = os.Getenv("GOCACHE")
|
||||
if filepath.IsAbs(defaultDir) || defaultDir == "off" {
|
||||
return
|
||||
}
|
||||
if defaultDir != "" {
|
||||
defaultDir = "off"
|
||||
defaultDirErr = fmt.Errorf("GOCACHE is not an absolute path")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -424,8 +424,8 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool)
|
||||
cmd.Dir = dir
|
||||
cmd.Env = base.EnvForDir(cmd.Dir, os.Environ())
|
||||
if cfg.BuildX {
|
||||
fmt.Printf("cd %s\n", dir)
|
||||
fmt.Printf("%s %s\n", v.cmd, strings.Join(args, " "))
|
||||
fmt.Fprintf(os.Stderr, "cd %s\n", dir)
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", v.cmd, strings.Join(args, " "))
|
||||
}
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
|
||||
@@ -26,7 +26,7 @@ func ScanDir(dir string, tags map[string]bool) ([]string, []string, error) {
|
||||
// If the directory entry is a symlink, stat it to obtain the info for the
|
||||
// link target instead of the link itself.
|
||||
if info.Mode()&os.ModeSymlink != 0 {
|
||||
info, err = os.Stat(name)
|
||||
info, err = os.Stat(filepath.Join(dir, name))
|
||||
if err != nil {
|
||||
continue // Ignore broken symlinks.
|
||||
}
|
||||
|
||||
@@ -1178,6 +1178,36 @@ var cgoSyscallExclude = map[string]bool{
|
||||
|
||||
var foldPath = make(map[string]string)
|
||||
|
||||
// DefaultExecName returns the default executable name
|
||||
// for a package with the import path importPath.
|
||||
//
|
||||
// The default executable name is the last element of the import path.
|
||||
// In module-aware mode, an additional rule is used. If the last element
|
||||
// is a vN path element specifying the major version, then the second last
|
||||
// element of the import path is used instead.
|
||||
func DefaultExecName(importPath string) string {
|
||||
_, elem := pathpkg.Split(importPath)
|
||||
if cfg.ModulesEnabled {
|
||||
// If this is example.com/mycmd/v2, it's more useful to install it as mycmd than as v2.
|
||||
// See golang.org/issue/24667.
|
||||
isVersion := func(v string) bool {
|
||||
if len(v) < 2 || v[0] != 'v' || v[1] < '1' || '9' < v[1] {
|
||||
return false
|
||||
}
|
||||
for i := 2; i < len(v); i++ {
|
||||
if c := v[i]; c < '0' || '9' < c {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
if isVersion(elem) {
|
||||
_, elem = pathpkg.Split(pathpkg.Dir(importPath))
|
||||
}
|
||||
}
|
||||
return elem
|
||||
}
|
||||
|
||||
// load populates p using information from bp, err, which should
|
||||
// be the result of calling build.Context.Import.
|
||||
func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
|
||||
@@ -1220,7 +1250,7 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
|
||||
}
|
||||
_, elem := filepath.Split(p.Dir)
|
||||
if cfg.ModulesEnabled {
|
||||
// NOTE(rsc): Using p.ImportPath instead of p.Dir
|
||||
// NOTE(rsc,dmitshur): Using p.ImportPath instead of p.Dir
|
||||
// makes sure we install a package in the root of a
|
||||
// cached module directory as that package name
|
||||
// not name@v1.2.3.
|
||||
@@ -1229,26 +1259,9 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
|
||||
// even for non-module-enabled code,
|
||||
// but I'm not brave enough to change the
|
||||
// non-module behavior this late in the
|
||||
// release cycle. Maybe for Go 1.12.
|
||||
// release cycle. Can be done for Go 1.13.
|
||||
// See golang.org/issue/26869.
|
||||
_, elem = pathpkg.Split(p.ImportPath)
|
||||
|
||||
// If this is example.com/mycmd/v2, it's more useful to install it as mycmd than as v2.
|
||||
// See golang.org/issue/24667.
|
||||
isVersion := func(v string) bool {
|
||||
if len(v) < 2 || v[0] != 'v' || v[1] < '1' || '9' < v[1] {
|
||||
return false
|
||||
}
|
||||
for i := 2; i < len(v); i++ {
|
||||
if c := v[i]; c < '0' || '9' < c {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
if isVersion(elem) {
|
||||
_, elem = pathpkg.Split(pathpkg.Dir(p.ImportPath))
|
||||
}
|
||||
elem = DefaultExecName(p.ImportPath)
|
||||
}
|
||||
full := cfg.BuildContext.GOOS + "_" + cfg.BuildContext.GOARCH + "/" + elem
|
||||
if cfg.BuildContext.GOOS != base.ToolGOOS || cfg.BuildContext.GOARCH != base.ToolGOARCH {
|
||||
|
||||
@@ -129,6 +129,7 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
|
||||
ptest.Internal.Imports = append(imports, p.Internal.Imports...)
|
||||
ptest.Internal.RawImports = str.StringList(rawTestImports, p.Internal.RawImports)
|
||||
ptest.Internal.ForceLibrary = true
|
||||
ptest.Internal.BuildInfo = ""
|
||||
ptest.Internal.Build = new(build.Package)
|
||||
*ptest.Internal.Build = *p.Internal.Build
|
||||
m := map[string][]token.Position{}
|
||||
@@ -186,6 +187,7 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
|
||||
},
|
||||
Internal: PackageInternal{
|
||||
Build: &build.Package{Name: "main"},
|
||||
BuildInfo: p.Internal.BuildInfo,
|
||||
Asmflags: p.Internal.Asmflags,
|
||||
Gcflags: p.Internal.Gcflags,
|
||||
Ldflags: p.Internal.Ldflags,
|
||||
@@ -266,17 +268,8 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
|
||||
pmain.Imports = pmain.Imports[:w]
|
||||
pmain.Internal.RawImports = str.StringList(pmain.Imports)
|
||||
|
||||
if ptest != p {
|
||||
// We have made modifications to the package p being tested
|
||||
// and are rebuilding p (as ptest).
|
||||
// Arrange to rebuild all packages q such that
|
||||
// the test depends on q and q depends on p.
|
||||
// This makes sure that q sees the modifications to p.
|
||||
// Strictly speaking, the rebuild is only necessary if the
|
||||
// modifications to p change its export metadata, but
|
||||
// determining that is a bit tricky, so we rebuild always.
|
||||
recompileForTest(pmain, p, ptest, pxtest)
|
||||
}
|
||||
// Replace pmain's transitive dependencies with test copies, as necessary.
|
||||
recompileForTest(pmain, p, ptest, pxtest)
|
||||
|
||||
// Should we apply coverage analysis locally,
|
||||
// only for this package and only for this test?
|
||||
@@ -323,6 +316,14 @@ Search:
|
||||
return stk
|
||||
}
|
||||
|
||||
// recompileForTest copies and replaces certain packages in pmain's dependency
|
||||
// graph. This is necessary for two reasons. First, if ptest is different than
|
||||
// preal, packages that import the package under test should get ptest instead
|
||||
// of preal. This is particularly important if pxtest depends on functionality
|
||||
// exposed in test sources in ptest. Second, if there is a main package
|
||||
// (other than pmain) anywhere, we need to clear p.Internal.BuildInfo in
|
||||
// the test copy to prevent link conflicts. This may happen if both -coverpkg
|
||||
// and the command line patterns include multiple main packages.
|
||||
func recompileForTest(pmain, preal, ptest, pxtest *Package) {
|
||||
// The "test copy" of preal is ptest.
|
||||
// For each package that depends on preal, make a "test copy"
|
||||
@@ -352,6 +353,7 @@ func recompileForTest(pmain, preal, ptest, pxtest *Package) {
|
||||
copy(p1.Imports, p.Imports)
|
||||
p = p1
|
||||
p.Target = ""
|
||||
p.Internal.BuildInfo = ""
|
||||
}
|
||||
|
||||
// Update p.Internal.Imports to use test copies.
|
||||
@@ -361,6 +363,13 @@ func recompileForTest(pmain, preal, ptest, pxtest *Package) {
|
||||
p.Internal.Imports[i] = p1
|
||||
}
|
||||
}
|
||||
|
||||
// Don't compile build info from a main package. This can happen
|
||||
// if -coverpkg patterns include main packages, since those packages
|
||||
// are imported by pmain. See golang.org/issue/30907.
|
||||
if p.Internal.BuildInfo != "" && p != pmain {
|
||||
split()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,55 +23,99 @@ import (
|
||||
type codeRepo struct {
|
||||
modPath string
|
||||
|
||||
code codehost.Repo
|
||||
// code is the repository containing this module.
|
||||
code codehost.Repo
|
||||
// codeRoot is the import path at the root of code.
|
||||
codeRoot string
|
||||
codeDir string
|
||||
// codeDir is the directory (relative to root) at which we expect to find the module.
|
||||
// If pathMajor is non-empty and codeRoot is not the full modPath,
|
||||
// then we look in both codeDir and codeDir+modPath
|
||||
codeDir string
|
||||
|
||||
path string
|
||||
pathPrefix string
|
||||
pathMajor string
|
||||
// pathMajor is the suffix of modPath that indicates its major version,
|
||||
// or the empty string if modPath is at major version 0 or 1.
|
||||
//
|
||||
// pathMajor is typically of the form "/vN", but possibly ".vN", or
|
||||
// ".vN-unstable" for modules resolved using gopkg.in.
|
||||
pathMajor string
|
||||
// pathPrefix is the prefix of modPath that excludes pathMajor.
|
||||
// It is used only for logging.
|
||||
pathPrefix string
|
||||
|
||||
// pseudoMajor is the major version prefix to use when generating
|
||||
// pseudo-versions for this module, derived from the module path.
|
||||
//
|
||||
// TODO(golang.org/issue/29262): We can't distinguish v0 from v1 using the
|
||||
// path alone: we have to compute it by examining the tags at a particular
|
||||
// revision.
|
||||
pseudoMajor string
|
||||
}
|
||||
|
||||
func newCodeRepo(code codehost.Repo, root, path string) (Repo, error) {
|
||||
if !hasPathPrefix(path, root) {
|
||||
return nil, fmt.Errorf("mismatched repo: found %s for %s", root, path)
|
||||
// newCodeRepo returns a Repo that reads the source code for the module with the
|
||||
// given path, from the repo stored in code, with the root of the repo
|
||||
// containing the path given by codeRoot.
|
||||
func newCodeRepo(code codehost.Repo, codeRoot, path string) (Repo, error) {
|
||||
if !hasPathPrefix(path, codeRoot) {
|
||||
return nil, fmt.Errorf("mismatched repo: found %s for %s", codeRoot, path)
|
||||
}
|
||||
pathPrefix, pathMajor, ok := module.SplitPathVersion(path)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid module path %q", path)
|
||||
}
|
||||
if codeRoot == path {
|
||||
pathPrefix = path
|
||||
}
|
||||
pseudoMajor := "v0"
|
||||
if pathMajor != "" {
|
||||
pseudoMajor = pathMajor[1:]
|
||||
}
|
||||
|
||||
// Compute codeDir = bar, the subdirectory within the repo
|
||||
// corresponding to the module root.
|
||||
//
|
||||
// At this point we might have:
|
||||
// codeRoot = github.com/rsc/foo
|
||||
// path = github.com/rsc/foo/bar/v2
|
||||
// codeRoot = github.com/rsc/foo
|
||||
// pathPrefix = github.com/rsc/foo/bar
|
||||
// pathMajor = /v2
|
||||
// pseudoMajor = v2
|
||||
//
|
||||
// Compute codeDir = bar, the subdirectory within the repo
|
||||
// corresponding to the module root.
|
||||
codeDir := strings.Trim(strings.TrimPrefix(pathPrefix, root), "/")
|
||||
if strings.HasPrefix(path, "gopkg.in/") {
|
||||
// But gopkg.in is a special legacy case, in which pathPrefix does not start with codeRoot.
|
||||
// For example we might have:
|
||||
// codeRoot = gopkg.in/yaml.v2
|
||||
// pathPrefix = gopkg.in/yaml
|
||||
// pathMajor = .v2
|
||||
// pseudoMajor = v2
|
||||
// codeDir = pathPrefix (because codeRoot is not a prefix of pathPrefix)
|
||||
// Clear codeDir - the module root is the repo root for gopkg.in repos.
|
||||
codeDir = ""
|
||||
// which gives
|
||||
// codeDir = bar
|
||||
//
|
||||
// We know that pathPrefix is a prefix of path, and codeRoot is a prefix of
|
||||
// path, but codeRoot may or may not be a prefix of pathPrefix, because
|
||||
// codeRoot may be the entire path (in which case codeDir should be empty).
|
||||
// That occurs in two situations.
|
||||
//
|
||||
// One is when a go-import meta tag resolves the complete module path,
|
||||
// including the pathMajor suffix:
|
||||
// path = nanomsg.org/go/mangos/v2
|
||||
// codeRoot = nanomsg.org/go/mangos/v2
|
||||
// pathPrefix = nanomsg.org/go/mangos
|
||||
// pathMajor = /v2
|
||||
// pseudoMajor = v2
|
||||
//
|
||||
// The other is similar: for gopkg.in only, the major version is encoded
|
||||
// with a dot rather than a slash, and thus can't be in a subdirectory.
|
||||
// path = gopkg.in/yaml.v2
|
||||
// codeRoot = gopkg.in/yaml.v2
|
||||
// pathPrefix = gopkg.in/yaml
|
||||
// pathMajor = .v2
|
||||
// pseudoMajor = v2
|
||||
//
|
||||
codeDir := ""
|
||||
if codeRoot != path {
|
||||
if !hasPathPrefix(pathPrefix, codeRoot) {
|
||||
return nil, fmt.Errorf("repository rooted at %s cannot contain module %s", codeRoot, path)
|
||||
}
|
||||
codeDir = strings.Trim(pathPrefix[len(codeRoot):], "/")
|
||||
}
|
||||
|
||||
r := &codeRepo{
|
||||
modPath: path,
|
||||
code: code,
|
||||
codeRoot: root,
|
||||
codeRoot: codeRoot,
|
||||
codeDir: codeDir,
|
||||
pathPrefix: pathPrefix,
|
||||
pathMajor: pathMajor,
|
||||
@@ -149,9 +193,6 @@ func (r *codeRepo) Stat(rev string) (*RevInfo, error) {
|
||||
return r.Latest()
|
||||
}
|
||||
codeRev := r.revToRev(rev)
|
||||
if semver.IsValid(codeRev) && r.codeDir != "" {
|
||||
codeRev = r.codeDir + "/" + codeRev
|
||||
}
|
||||
info, err := r.code.Stat(codeRev)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -290,7 +331,7 @@ func (r *codeRepo) findDir(version string) (rev, dir string, gomod []byte, err e
|
||||
found1 := err1 == nil && isMajor(mpath1, r.pathMajor)
|
||||
|
||||
var file2 string
|
||||
if r.pathMajor != "" && !strings.HasPrefix(r.pathMajor, ".") {
|
||||
if r.pathMajor != "" && r.codeRoot != r.modPath && !strings.HasPrefix(r.pathMajor, ".") {
|
||||
// Suppose pathMajor is "/v2".
|
||||
// Either go.mod should claim v2 and v2/go.mod should not exist,
|
||||
// or v2/go.mod should exist and claim v2. Not both.
|
||||
@@ -298,6 +339,9 @@ func (r *codeRepo) findDir(version string) (rev, dir string, gomod []byte, err e
|
||||
// because of replacement modules. This might be a fork of
|
||||
// the real module, found at a different path, usable only in
|
||||
// a replace directive.
|
||||
//
|
||||
// TODO(bcmills): This doesn't seem right. Investigate futher.
|
||||
// (Notably: why can't we replace foo/v2 with fork-of-foo/v3?)
|
||||
dir2 := path.Join(r.codeDir, r.pathMajor[1:])
|
||||
file2 = path.Join(dir2, "go.mod")
|
||||
gomod2, err2 := r.code.ReadFile(rev, file2, codehost.MaxGoMod)
|
||||
@@ -418,7 +462,7 @@ func (r *codeRepo) Zip(dst io.Writer, version string) error {
|
||||
}
|
||||
defer dl.Close()
|
||||
if actualDir != "" && !hasPathPrefix(dir, actualDir) {
|
||||
return fmt.Errorf("internal error: downloading %v %v: dir=%q but actualDir=%q", r.path, rev, dir, actualDir)
|
||||
return fmt.Errorf("internal error: downloading %v %v: dir=%q but actualDir=%q", r.modPath, rev, dir, actualDir)
|
||||
}
|
||||
subdir := strings.Trim(strings.TrimPrefix(dir, actualDir), "/")
|
||||
|
||||
|
||||
@@ -323,6 +323,15 @@ var codeRepoTests = []struct {
|
||||
time: time.Date(2017, 5, 31, 16, 3, 50, 0, time.UTC),
|
||||
gomod: "module gopkg.in/natefinch/lumberjack.v2\n",
|
||||
},
|
||||
{
|
||||
path: "nanomsg.org/go/mangos/v2",
|
||||
rev: "v2.0.2",
|
||||
version: "v2.0.2",
|
||||
name: "63f66a65137b9a648ac9f7bf0160b4a4d17d7999",
|
||||
short: "63f66a65137b",
|
||||
time: time.Date(2018, 12, 1, 15, 7, 40, 0, time.UTC),
|
||||
gomod: "module nanomsg.org/go/mangos/v2\n\nrequire (\n\tgithub.com/Microsoft/go-winio v0.4.11\n\tgithub.com/droundy/goopt v0.0.0-20170604162106-0b8effe182da\n\tgithub.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e // indirect\n\tgithub.com/gorilla/websocket v1.4.0\n\tgithub.com/jtolds/gls v4.2.1+incompatible // indirect\n\tgithub.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect\n\tgithub.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c\n\tgolang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 // indirect\n)\n",
|
||||
},
|
||||
}
|
||||
|
||||
func TestCodeRepo(t *testing.T) {
|
||||
|
||||
@@ -805,7 +805,7 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin
|
||||
if p.ImportPath == "command-line-arguments" {
|
||||
elem = p.Name
|
||||
} else {
|
||||
_, elem = path.Split(p.ImportPath)
|
||||
elem = load.DefaultExecName(p.ImportPath)
|
||||
}
|
||||
testBinary := elem + ".test"
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"go/build"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
@@ -285,7 +284,7 @@ func runBuild(cmd *base.Command, args []string) {
|
||||
pkgs := load.PackagesForBuild(args)
|
||||
|
||||
if len(pkgs) == 1 && pkgs[0].Name == "main" && cfg.BuildO == "" {
|
||||
_, cfg.BuildO = path.Split(pkgs[0].ImportPath)
|
||||
cfg.BuildO = load.DefaultExecName(pkgs[0].ImportPath)
|
||||
cfg.BuildO += cfg.ExeSuffix
|
||||
}
|
||||
|
||||
@@ -518,7 +517,7 @@ func InstallPackages(patterns []string, pkgs []*load.Package) {
|
||||
if len(patterns) == 0 && len(pkgs) == 1 && pkgs[0].Name == "main" {
|
||||
// Compute file 'go build' would have created.
|
||||
// If it exists and is an executable file, remove it.
|
||||
_, targ := filepath.Split(pkgs[0].ImportPath)
|
||||
targ := load.DefaultExecName(pkgs[0].ImportPath)
|
||||
targ += cfg.ExeSuffix
|
||||
if filepath.Join(pkgs[0].Dir, targ) != pkgs[0].Target { // maybe $GOBIN is the current directory
|
||||
fi, err := os.Stat(targ)
|
||||
|
||||
@@ -214,6 +214,7 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID {
|
||||
if p.Internal.CoverMode != "" {
|
||||
fmt.Fprintf(h, "cover %q %q\n", p.Internal.CoverMode, b.toolID("cover"))
|
||||
}
|
||||
fmt.Fprintf(h, "modinfo %q\n", p.Internal.BuildInfo)
|
||||
|
||||
// Configuration specific to compiler toolchain.
|
||||
switch cfg.BuildToolchainName {
|
||||
@@ -655,7 +656,7 @@ func (b *Builder) build(a *Action) (err error) {
|
||||
if len(out) > 0 {
|
||||
output := b.processOutput(out)
|
||||
if p.Module != nil && !allowedVersion(p.Module.GoVersion) {
|
||||
output += "note: module requires Go " + p.Module.GoVersion
|
||||
output += "note: module requires Go " + p.Module.GoVersion + "\n"
|
||||
}
|
||||
b.showOutput(a, a.Package.Dir, a.Package.Desc(), output)
|
||||
if err != nil {
|
||||
|
||||
@@ -13,3 +13,9 @@ import "rsc.io/quote"
|
||||
func main() {
|
||||
println(quote.Hello())
|
||||
}
|
||||
-- fortune_test.go --
|
||||
package main
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestFortuneV2(t *testing.T) {}
|
||||
|
||||
5
src/cmd/go/testdata/script/build_nocache.txt
vendored
5
src/cmd/go/testdata/script/build_nocache.txt
vendored
@@ -10,6 +10,11 @@ env HOME=
|
||||
! go build -o triv triv.go
|
||||
stderr 'build cache is required, but could not be located: GOCACHE is not defined and .*'
|
||||
|
||||
# If GOCACHE is set but is not an absolute path, and we cannot build.
|
||||
env GOCACHE=test
|
||||
! go build -o triv triv.go
|
||||
stderr 'build cache is required, but could not be located: GOCACHE is not an absolute path'
|
||||
|
||||
# An explicit GOCACHE=off also disables builds.
|
||||
env GOCACHE=off
|
||||
! go build -o triv triv.go
|
||||
|
||||
43
src/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt
vendored
Normal file
43
src/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
# This test checks that multiple main packages can be tested
|
||||
# with -coverpkg=all without duplicate symbol errors.
|
||||
# Verifies golang.org/issue/30374.
|
||||
|
||||
env GO111MODULE=on
|
||||
|
||||
[short] skip
|
||||
|
||||
go test -coverpkg=all ./...
|
||||
|
||||
-- go.mod --
|
||||
module example.com/cov
|
||||
|
||||
-- mainonly/mainonly.go --
|
||||
package main
|
||||
|
||||
func main() {}
|
||||
|
||||
-- mainwithtest/mainwithtest.go --
|
||||
package main
|
||||
|
||||
func main() {}
|
||||
|
||||
func Foo() {}
|
||||
|
||||
-- mainwithtest/mainwithtest_test.go --
|
||||
package main
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestFoo(t *testing.T) {
|
||||
Foo()
|
||||
}
|
||||
|
||||
-- xtest/x.go --
|
||||
package x
|
||||
|
||||
-- xtest/x_test.go --
|
||||
package x_test
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestX(t *testing.T) {}
|
||||
16
src/cmd/go/testdata/script/mod_build_versioned.txt
vendored
Normal file
16
src/cmd/go/testdata/script/mod_build_versioned.txt
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
env GO111MODULE=on
|
||||
|
||||
go get -m rsc.io/fortune/v2
|
||||
|
||||
# The default executable name shouldn't be v2$exe
|
||||
go build rsc.io/fortune/v2
|
||||
! exists v2$exe
|
||||
exists fortune$exe
|
||||
|
||||
# The default test binary name shouldn't be v2.test$exe
|
||||
go test -c rsc.io/fortune/v2
|
||||
! exists v2.test$exe
|
||||
exists fortune.test$exe
|
||||
|
||||
-- go.mod --
|
||||
module scratch
|
||||
33
src/cmd/go/testdata/script/mod_symlink.txt
vendored
33
src/cmd/go/testdata/script/mod_symlink.txt
vendored
@@ -2,16 +2,31 @@ env GO111MODULE=on
|
||||
[!symlink] skip
|
||||
|
||||
# 'go list' should resolve modules of imported packages.
|
||||
go list -deps -f '{{.Module}}'
|
||||
go list -deps -f '{{.Module}}' .
|
||||
stdout golang.org/x/text
|
||||
|
||||
# They should continue to resolve if the importing file is a symlink.
|
||||
mkdir links
|
||||
cd links
|
||||
symlink go.mod -> ../go.mod
|
||||
symlink issue.go -> ../issue.go
|
||||
go list -deps -f '{{.Module}}' ./subpkg
|
||||
stdout golang.org/x/text
|
||||
|
||||
go list -deps -f '{{.Module}}'
|
||||
# Create a copy of the module using symlinks in src/links.
|
||||
mkdir links
|
||||
symlink links/go.mod -> $GOPATH/src/go.mod
|
||||
symlink links/issue.go -> $GOPATH/src/issue.go
|
||||
mkdir links/subpkg
|
||||
symlink links/subpkg/issue.go -> $GOPATH/src/subpkg/issue.go
|
||||
|
||||
# We should see the copy as a valid module root.
|
||||
cd links
|
||||
go env GOMOD
|
||||
stdout links[/\\]go.mod
|
||||
go list -m
|
||||
stdout golang.org/issue/28107
|
||||
|
||||
# The symlink-based copy should contain the same packages
|
||||
# and have the same dependencies as the original.
|
||||
go list -deps -f '{{.Module}}' .
|
||||
stdout golang.org/x/text
|
||||
go list -deps -f '{{.Module}}' ./subpkg
|
||||
stdout golang.org/x/text
|
||||
|
||||
-- go.mod --
|
||||
@@ -21,3 +36,7 @@ module golang.org/issue/28107
|
||||
package issue
|
||||
|
||||
import _ "golang.org/x/text/language"
|
||||
-- subpkg/issue.go --
|
||||
package issue
|
||||
|
||||
import _ "golang.org/x/text/language"
|
||||
|
||||
@@ -2986,7 +2986,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
|
||||
num := uint8(0)
|
||||
cls := oclass(&p.From)
|
||||
if isADDWop(p.As) {
|
||||
if (cls != C_LCON) && (cls != C_ADDCON2) {
|
||||
if !cmp(C_LCON, cls) {
|
||||
c.ctxt.Diag("illegal combination: %v", p)
|
||||
}
|
||||
num = c.omovlconst(AMOVW, p, &p.From, REGTMP, os[:])
|
||||
@@ -3271,7 +3271,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
|
||||
num := uint8(0)
|
||||
cls := oclass(&p.From)
|
||||
if isANDWop(p.As) {
|
||||
if (cls != C_LCON) && (cls != C_ADDCON) {
|
||||
if !cmp(C_LCON, cls) {
|
||||
c.ctxt.Diag("illegal combination: %v", p)
|
||||
}
|
||||
num = c.omovlconst(AMOVW, p, &p.From, REGTMP, os[:])
|
||||
|
||||
113
src/cmd/link/elf_test.go
Normal file
113
src/cmd/link/elf_test.go
Normal file
@@ -0,0 +1,113 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build dragonfly freebsd linux netbsd openbsd
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"internal/testenv"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var asmSource = `
|
||||
.section .text1,"ax"
|
||||
s1:
|
||||
.byte 0
|
||||
.section .text2,"ax"
|
||||
s2:
|
||||
.byte 0
|
||||
`
|
||||
|
||||
var goSource = `
|
||||
package main
|
||||
func main() {}
|
||||
`
|
||||
|
||||
// The linker used to crash if an ELF input file had multiple text sections
|
||||
// with the same name.
|
||||
func TestSectionsWithSameName(t *testing.T) {
|
||||
testenv.MustHaveGoBuild(t)
|
||||
testenv.MustHaveCGO(t)
|
||||
t.Parallel()
|
||||
|
||||
objcopy, err := exec.LookPath("objcopy")
|
||||
if err != nil {
|
||||
t.Skipf("can't find objcopy: %v", err)
|
||||
}
|
||||
|
||||
dir, err := ioutil.TempDir("", "go-link-TestSectionsWithSameName")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
gopath := filepath.Join(dir, "GOPATH")
|
||||
env := append(os.Environ(), "GOPATH="+gopath)
|
||||
|
||||
if err := ioutil.WriteFile(filepath.Join(dir, "go.mod"), []byte("module elf_test\n"), 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
asmFile := filepath.Join(dir, "x.s")
|
||||
if err := ioutil.WriteFile(asmFile, []byte(asmSource), 0444); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
goTool := testenv.GoToolPath(t)
|
||||
cmd := exec.Command(goTool, "env", "CC")
|
||||
cmd.Env = env
|
||||
ccb, err := cmd.Output()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cc := strings.TrimSpace(string(ccb))
|
||||
|
||||
cmd = exec.Command(goTool, "env", "GOGCCFLAGS")
|
||||
cmd.Env = env
|
||||
cflagsb, err := cmd.Output()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cflags := strings.Fields(string(cflagsb))
|
||||
|
||||
asmObj := filepath.Join(dir, "x.o")
|
||||
t.Logf("%s %v -c -o %s %s", cc, cflags, asmObj, asmFile)
|
||||
if out, err := exec.Command(cc, append(cflags, "-c", "-o", asmObj, asmFile)...).CombinedOutput(); err != nil {
|
||||
t.Logf("%s", out)
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
asm2Obj := filepath.Join(dir, "x2.syso")
|
||||
t.Logf("%s --rename-section .text2=.text1 %s %s", objcopy, asmObj, asm2Obj)
|
||||
if out, err := exec.Command(objcopy, "--rename-section", ".text2=.text1", asmObj, asm2Obj).CombinedOutput(); err != nil {
|
||||
t.Logf("%s", out)
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, s := range []string{asmFile, asmObj} {
|
||||
if err := os.Remove(s); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
goFile := filepath.Join(dir, "main.go")
|
||||
if err := ioutil.WriteFile(goFile, []byte(goSource), 0444); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cmd = exec.Command(goTool, "build")
|
||||
cmd.Dir = dir
|
||||
cmd.Env = env
|
||||
t.Logf("%s build", goTool)
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
t.Logf("%s", out)
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -678,6 +678,8 @@ func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length i
|
||||
// as well use one large chunk.
|
||||
|
||||
// create symbols for elfmapped sections
|
||||
sectsymNames := make(map[string]bool)
|
||||
counter := 0
|
||||
for i := 0; uint(i) < elfobj.nsect; i++ {
|
||||
sect = &elfobj.sect[i]
|
||||
if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" {
|
||||
@@ -709,6 +711,12 @@ func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length i
|
||||
}
|
||||
|
||||
name := fmt.Sprintf("%s(%s)", pkg, sect.name)
|
||||
for sectsymNames[name] {
|
||||
counter++
|
||||
name = fmt.Sprintf("%s(%s%d)", pkg, sect.name, counter)
|
||||
}
|
||||
sectsymNames[name] = true
|
||||
|
||||
s := syms.Lookup(name, localSymVersion)
|
||||
|
||||
switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) {
|
||||
|
||||
1
src/cmd/vendor/golang.org/x/tools/go/analysis/analysis.go
generated
vendored
1
src/cmd/vendor/golang.org/x/tools/go/analysis/analysis.go
generated
vendored
@@ -87,6 +87,7 @@ type Pass struct {
|
||||
OtherFiles []string // names of non-Go files of this package
|
||||
Pkg *types.Package // type information about the package
|
||||
TypesInfo *types.Info // type information about the syntax trees
|
||||
TypesSizes types.Sizes // function for computing sizes of types
|
||||
|
||||
// Report reports a Diagnostic, a finding about a specific location
|
||||
// in the analyzed source code such as a potential mistake.
|
||||
|
||||
2
src/cmd/vendor/golang.org/x/tools/go/analysis/doc.go
generated
vendored
2
src/cmd/vendor/golang.org/x/tools/go/analysis/doc.go
generated
vendored
@@ -246,7 +246,7 @@ An Analyzer that uses facts must declare their types:
|
||||
|
||||
var Analyzer = &analysis.Analyzer{
|
||||
Name: "printf",
|
||||
FactTypes: []reflect.Type{reflect.TypeOf(new(isWrapper))},
|
||||
FactTypes: []analysis.Fact{new(isWrapper)},
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
3
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go
generated
vendored
3
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go
generated
vendored
@@ -114,7 +114,8 @@ func init() {
|
||||
// library we cannot assume types.SizesFor is consistent with arches.
|
||||
// For now, assume 64-bit norms and print a warning.
|
||||
// But this warning should really be deferred until we attempt to use
|
||||
// arch, which is very unlikely.
|
||||
// arch, which is very unlikely. Better would be
|
||||
// to defer size computation until we have Pass.TypesSizes.
|
||||
arch.sizes = types.SizesFor("gc", "amd64")
|
||||
log.Printf("unknown architecture %s", arch.name)
|
||||
}
|
||||
|
||||
8
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/cgocall/cgocall.go
generated
vendored
8
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/cgocall/cgocall.go
generated
vendored
@@ -9,7 +9,6 @@ package cgocall
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/build"
|
||||
"go/format"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
@@ -45,7 +44,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
|
||||
return nil, nil // doesn't use cgo
|
||||
}
|
||||
|
||||
cgofiles, info, err := typeCheckCgoSourceFiles(pass.Fset, pass.Pkg, pass.Files, pass.TypesInfo)
|
||||
cgofiles, info, err := typeCheckCgoSourceFiles(pass.Fset, pass.Pkg, pass.Files, pass.TypesInfo, pass.TypesSizes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -171,7 +170,7 @@ func checkCgo(fset *token.FileSet, f *ast.File, info *types.Info, reportf func(t
|
||||
// limited ourselves here to preserving function bodies and initializer
|
||||
// expressions since that is all that the cgocall analyzer needs.
|
||||
//
|
||||
func typeCheckCgoSourceFiles(fset *token.FileSet, pkg *types.Package, files []*ast.File, info *types.Info) ([]*ast.File, *types.Info, error) {
|
||||
func typeCheckCgoSourceFiles(fset *token.FileSet, pkg *types.Package, files []*ast.File, info *types.Info, sizes types.Sizes) ([]*ast.File, *types.Info, error) {
|
||||
const thispkg = "·this·"
|
||||
|
||||
// Which files are cgo files?
|
||||
@@ -269,8 +268,7 @@ func typeCheckCgoSourceFiles(fset *token.FileSet, pkg *types.Package, files []*a
|
||||
Importer: importerFunc(func(path string) (*types.Package, error) {
|
||||
return importMap[path], nil
|
||||
}),
|
||||
// TODO(adonovan): Sizes should probably be provided by analysis.Pass.
|
||||
Sizes: types.SizesFor("gc", build.Default.GOARCH),
|
||||
Sizes: sizes,
|
||||
Error: func(error) {}, // ignore errors (e.g. unused import)
|
||||
}
|
||||
|
||||
|
||||
11
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/composite/composite.go
generated
vendored
11
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/composite/composite.go
generated
vendored
@@ -21,7 +21,16 @@ const Doc = `check for unkeyed composite literals
|
||||
This analyzer reports a diagnostic for composite literals of struct
|
||||
types imported from another package that do not use the field-keyed
|
||||
syntax. Such literals are fragile because the addition of a new field
|
||||
(even if unexported) to the struct will cause compilation to fail.`
|
||||
(even if unexported) to the struct will cause compilation to fail.
|
||||
|
||||
As an example,
|
||||
|
||||
err = &net.DNSConfigError{err}
|
||||
|
||||
should be replaced by:
|
||||
|
||||
err = &net.DNSConfigError{Err: err}
|
||||
`
|
||||
|
||||
var Analyzer = &analysis.Analyzer{
|
||||
Name: "composites",
|
||||
|
||||
6
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/inspect/inspect.go
generated
vendored
6
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/inspect/inspect.go
generated
vendored
@@ -8,7 +8,11 @@
|
||||
//
|
||||
// Example of use in another analysis:
|
||||
//
|
||||
// import "golang.org/x/tools/go/analysis/passes/inspect"
|
||||
// import (
|
||||
// "golang.org/x/tools/go/analysis"
|
||||
// "golang.org/x/tools/go/analysis/passes/inspect"
|
||||
// "golang.org/x/tools/go/ast/inspector"
|
||||
// )
|
||||
//
|
||||
// var Analyzer = &analysis.Analyzer{
|
||||
// ...
|
||||
|
||||
28
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go
generated
vendored
28
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go
generated
vendored
@@ -453,15 +453,23 @@ func printfNameAndKind(pass *analysis.Pass, call *ast.CallExpr) (fn *types.Func,
|
||||
}
|
||||
|
||||
// isFormatter reports whether t satisfies fmt.Formatter.
|
||||
// Unlike fmt.Stringer, it's impossible to satisfy fmt.Formatter without importing fmt.
|
||||
func isFormatter(pass *analysis.Pass, t types.Type) bool {
|
||||
for _, imp := range pass.Pkg.Imports() {
|
||||
if imp.Path() == "fmt" {
|
||||
formatter := imp.Scope().Lookup("Formatter").Type().Underlying().(*types.Interface)
|
||||
return types.Implements(t, formatter)
|
||||
}
|
||||
// The only interface method to look for is "Format(State, rune)".
|
||||
func isFormatter(typ types.Type) bool {
|
||||
obj, _, _ := types.LookupFieldOrMethod(typ, false, nil, "Format")
|
||||
fn, ok := obj.(*types.Func)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
sig := fn.Type().(*types.Signature)
|
||||
return sig.Params().Len() == 2 &&
|
||||
sig.Results().Len() == 0 &&
|
||||
isNamed(sig.Params().At(0).Type(), "fmt", "State") &&
|
||||
types.Identical(sig.Params().At(1).Type(), types.Typ[types.Rune])
|
||||
}
|
||||
|
||||
func isNamed(T types.Type, pkgpath, name string) bool {
|
||||
named, ok := T.(*types.Named)
|
||||
return ok && named.Obj().Pkg().Path() == pkgpath && named.Obj().Name() == name
|
||||
}
|
||||
|
||||
// formatState holds the parsed representation of a printf directive such as "%3.*[4]d".
|
||||
@@ -753,7 +761,7 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (o
|
||||
formatter := false
|
||||
if state.argNum < len(call.Args) {
|
||||
if tv, ok := pass.TypesInfo.Types[call.Args[state.argNum]]; ok {
|
||||
formatter = isFormatter(pass, tv.Type)
|
||||
formatter = isFormatter(tv.Type)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -831,7 +839,7 @@ func recursiveStringer(pass *analysis.Pass, e ast.Expr) bool {
|
||||
typ := pass.TypesInfo.Types[e].Type
|
||||
|
||||
// It's unlikely to be a recursive stringer if it has a Format method.
|
||||
if isFormatter(pass, typ) {
|
||||
if isFormatter(typ) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
5
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/types.go
generated
vendored
5
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/types.go
generated
vendored
@@ -2,7 +2,6 @@ package printf
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/build"
|
||||
"go/types"
|
||||
|
||||
"golang.org/x/tools/go/analysis"
|
||||
@@ -39,7 +38,7 @@ func matchArgTypeInternal(pass *analysis.Pass, t printfArgType, typ types.Type,
|
||||
}
|
||||
}
|
||||
// If the type implements fmt.Formatter, we have nothing to check.
|
||||
if isFormatter(pass, typ) {
|
||||
if isFormatter(typ) {
|
||||
return true
|
||||
}
|
||||
// If we can use a string, might arg (dynamically) implement the Stringer or Error interface?
|
||||
@@ -235,5 +234,3 @@ func matchStructArgType(pass *analysis.Pass, t printfArgType, typ *types.Struct,
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
var archSizes = types.SizesFor("gc", build.Default.GOARCH)
|
||||
|
||||
31
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/shift/shift.go
generated
vendored
31
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/shift/shift.go
generated
vendored
@@ -12,10 +12,8 @@ package shift
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/build"
|
||||
"go/constant"
|
||||
"go/token"
|
||||
"go/types"
|
||||
|
||||
"golang.org/x/tools/go/analysis"
|
||||
"golang.org/x/tools/go/analysis/passes/inspect"
|
||||
@@ -93,36 +91,9 @@ func checkLongShift(pass *analysis.Pass, node ast.Node, x, y ast.Expr) {
|
||||
if t == nil {
|
||||
return
|
||||
}
|
||||
b, ok := t.Underlying().(*types.Basic)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var size int64
|
||||
switch b.Kind() {
|
||||
case types.Uint8, types.Int8:
|
||||
size = 8
|
||||
case types.Uint16, types.Int16:
|
||||
size = 16
|
||||
case types.Uint32, types.Int32:
|
||||
size = 32
|
||||
case types.Uint64, types.Int64:
|
||||
size = 64
|
||||
case types.Int, types.Uint:
|
||||
size = uintBitSize
|
||||
case types.Uintptr:
|
||||
size = uintptrBitSize
|
||||
default:
|
||||
return
|
||||
}
|
||||
size := 8 * pass.TypesSizes.Sizeof(t)
|
||||
if amt >= size {
|
||||
ident := analysisutil.Format(pass.Fset, x)
|
||||
pass.Reportf(node.Pos(), "%s (%d bits) too small for shift of %d", ident, size, amt)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
uintBitSize = 8 * archSizes.Sizeof(types.Typ[types.Uint])
|
||||
uintptrBitSize = 8 * archSizes.Sizeof(types.Typ[types.Uintptr])
|
||||
)
|
||||
|
||||
var archSizes = types.SizesFor("gc", build.Default.GOARCH)
|
||||
|
||||
5
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag/structtag.go
generated
vendored
5
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag/structtag.go
generated
vendored
@@ -96,6 +96,11 @@ func checkTagDuplicates(pass *analysis.Pass, tag, key string, nearest, field *ty
|
||||
}
|
||||
if val == "" || val[0] == ',' {
|
||||
if field.Anonymous() {
|
||||
// Disable this check enhancement in Go 1.12.1; some
|
||||
// false positives were spotted in the initial 1.12
|
||||
// release. See https://golang.org/issues/30465.
|
||||
return
|
||||
|
||||
typ, ok := field.Type().Underlying().(*types.Struct)
|
||||
if !ok {
|
||||
return
|
||||
|
||||
1
src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go
generated
vendored
1
src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go
generated
vendored
@@ -329,6 +329,7 @@ func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]re
|
||||
OtherFiles: cfg.NonGoFiles,
|
||||
Pkg: pkg,
|
||||
TypesInfo: info,
|
||||
TypesSizes: tc.Sizes,
|
||||
ResultOf: inputs,
|
||||
Report: func(d analysis.Diagnostic) { act.diagnostics = append(act.diagnostics, d) },
|
||||
ImportObjectFact: facts.ImportObjectFact,
|
||||
|
||||
2
src/cmd/vendor/golang.org/x/tools/go/ast/inspector/inspector.go
generated
vendored
2
src/cmd/vendor/golang.org/x/tools/go/ast/inspector/inspector.go
generated
vendored
@@ -14,7 +14,7 @@
|
||||
// Experiments suggest the inspector's traversals are about 2.5x faster
|
||||
// than ast.Inspect, but it may take around 5 traversals for this
|
||||
// benefit to amortize the inspector's construction cost.
|
||||
// If efficiency is the primary concern, do not use use Inspector for
|
||||
// If efficiency is the primary concern, do not use Inspector for
|
||||
// one-off traversals.
|
||||
package inspector
|
||||
|
||||
|
||||
17
src/cmd/vet/testdata/src/print2/big.go
vendored
Normal file
17
src/cmd/vet/testdata/src/print2/big.go
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package print2
|
||||
|
||||
import ( // NOTE: Does not import "fmt"
|
||||
"log"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
var fmt int
|
||||
|
||||
func f() {
|
||||
log.Printf("%d", new(big.Int))
|
||||
log.Printf("%d", 1.0) // ERROR "Printf format %d has arg 1.0 of wrong type float64"
|
||||
}
|
||||
14
src/cmd/vet/testdata/src/structtag/structtag.go
vendored
14
src/cmd/vet/testdata/src/structtag/structtag.go
vendored
@@ -6,6 +6,20 @@
|
||||
|
||||
package structtag
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
type StructTagTest struct {
|
||||
A int "hello" // ERROR "`hello` not compatible with reflect.StructTag.Get: bad syntax for struct tag pair"
|
||||
}
|
||||
|
||||
func Issue30465() {
|
||||
type T1 struct {
|
||||
X string `json:"x"`
|
||||
}
|
||||
type T2 struct {
|
||||
T1
|
||||
X string `json:"x"`
|
||||
}
|
||||
var t2 T2
|
||||
json.Marshal(&t2)
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ func TestVet(t *testing.T) {
|
||||
"method",
|
||||
"nilfunc",
|
||||
"print",
|
||||
"print2",
|
||||
"rangeloop",
|
||||
"shift",
|
||||
"structtag",
|
||||
|
||||
@@ -45,8 +45,10 @@ func NewCipher(key []byte) (*Cipher, error) {
|
||||
return &c, nil
|
||||
}
|
||||
|
||||
// Reset zeros the key data so that it will no longer appear in the
|
||||
// process's memory.
|
||||
// Reset zeros the key data and makes the Cipher unusable.
|
||||
//
|
||||
// Deprecated: Reset can't guarantee that the key will be entirely removed from
|
||||
// the process's memory.
|
||||
func (c *Cipher) Reset() {
|
||||
for i := range c.s {
|
||||
c.s[i] = 0
|
||||
|
||||
@@ -573,7 +573,7 @@ func (hs *clientHandshakeState) doFullHandshake() error {
|
||||
return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey)
|
||||
}
|
||||
|
||||
signatureAlgorithm, sigType, hashFunc, err := pickSignatureAlgorithm(key.Public(), certReq.supportedSignatureAlgorithms, hs.hello.supportedSignatureAlgorithms, c.vers)
|
||||
signatureAlgorithm, sigType, hashFunc, err := pickSignatureAlgorithm(key.Public(), certReq.supportedSignatureAlgorithms, supportedSignatureAlgorithmsTLS12, c.vers)
|
||||
if err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return err
|
||||
|
||||
@@ -873,10 +873,41 @@ func TestHandshakeClientCertPSSDisabled(t *testing.T) {
|
||||
supportedSignatureAlgorithmsTLS12 = savedSupportedSignatureAlgorithmsTLS12
|
||||
|
||||
// Use t.Run to ensure the defer runs after all parallel tests end.
|
||||
t.Run("", func(t *testing.T) {
|
||||
t.Run("1024", func(t *testing.T) {
|
||||
runClientTestTLS12(t, test)
|
||||
runClientTestTLS13(t, test)
|
||||
})
|
||||
|
||||
// Use a 512-bit key to check that the TLS 1.2 handshake is actually using
|
||||
// PKCS#1 v1.5. PSS would be failing here.
|
||||
cert, err := X509KeyPair([]byte(`-----BEGIN CERTIFICATE-----
|
||||
MIIBcTCCARugAwIBAgIQGjQnkCFlUqaFlt6ixyz/tDANBgkqhkiG9w0BAQsFADAS
|
||||
MRAwDgYDVQQKEwdBY21lIENvMB4XDTE5MDExODIzMjMyOFoXDTIwMDExODIzMjMy
|
||||
OFowEjEQMA4GA1UEChMHQWNtZSBDbzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDd
|
||||
ez1rFUDwax2HTxbcnFUP9AhcgEGMHVV2nn4VVEWFJB6I8C/Nkx0XyyQlrmFYBzEQ
|
||||
nIPhKls4T0hFoLvjJnXpAgMBAAGjTTBLMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUE
|
||||
DDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBYGA1UdEQQPMA2CC2V4YW1wbGUu
|
||||
Y29tMA0GCSqGSIb3DQEBCwUAA0EAxDuUS+BrrS3c+h+k+fQPOmOScy6yTX9mHw0Q
|
||||
KbucGamXYEy0URIwOdO0tQ3LHPc1YGvYSPwkDjkjqECs2Vm/AA==
|
||||
-----END CERTIFICATE-----`), []byte(`-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOgIBAAJBAN17PWsVQPBrHYdPFtycVQ/0CFyAQYwdVXaefhVURYUkHojwL82T
|
||||
HRfLJCWuYVgHMRCcg+EqWzhPSEWgu+MmdekCAwEAAQJBALjQYNTdXF4CFBbXwUz/
|
||||
yt9QFDYT9B5WT/12jeGAe653gtYS6OOi/+eAkGmzg1GlRnw6fOfn+HYNFDORST7z
|
||||
4j0CIQDn2xz9hVWQEu9ee3vecNT3f60huDGTNoRhtqgweQGX0wIhAPSLj1VcRZEz
|
||||
nKpbtU22+PbIMSJ+e80fmY9LIPx5N4HTAiAthGSimMR9bloz0EY3GyuUEyqoDgMd
|
||||
hXxjuno2WesoJQIgemilbcALXpxsLmZLgcQ2KSmaVr7jb5ECx9R+hYKTw1sCIG4s
|
||||
T+E0J8wlH24pgwQHzy7Ko2qLwn1b5PW8ecrlvP1g
|
||||
-----END RSA PRIVATE KEY-----`))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
test.name = "ClientCert-RSA-PSS-Disabled-512"
|
||||
config.Certificates = []Certificate{cert}
|
||||
|
||||
t.Run("512", func(t *testing.T) {
|
||||
runClientTestTLS12(t, test)
|
||||
})
|
||||
}
|
||||
|
||||
func TestClientKeyUpdate(t *testing.T) {
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
000000e0 a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 |.G.bC.(.._.).0..|
|
||||
000000f0 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 |........_X.;t|
|
||||
>>> Flow 2 (server to client)
|
||||
00000000 16 03 03 00 59 02 00 00 55 03 03 33 ad 8d f8 90 |....Y...U..3....|
|
||||
00000010 d1 72 5d ef e8 94 0f d7 58 15 59 9f 0b f9 ec 73 |.r].....X.Y....s|
|
||||
00000020 99 53 f7 03 81 53 1a aa 05 f0 17 20 55 a1 9e 4e |.S...S..... U..N|
|
||||
00000030 98 26 6b b8 d5 bc 2c 3e ca f6 a0 d9 bb f2 3b dd |.&k...,>......;.|
|
||||
00000040 be 99 f1 35 de 1c f6 51 5b 19 4f 55 c0 2f 00 00 |...5...Q[.OU./..|
|
||||
00000000 16 03 03 00 59 02 00 00 55 03 03 05 c1 62 2b 2f |....Y...U....b+/|
|
||||
00000010 12 46 4d c5 47 61 bd 43 6d bb 3a 60 42 c1 cf da |.FM.Ga.Cm.:`B...|
|
||||
00000020 47 96 0a 11 35 f0 71 d8 f6 39 69 20 0f 9c c1 3f |G...5.q..9i ...?|
|
||||
00000030 9c 68 e7 86 13 7c 1f 83 6b 56 39 ee 0d c0 82 0b |.h...|..kV9.....|
|
||||
00000040 24 1b 8a 39 a6 dc bf 57 79 27 02 e4 c0 2f 00 00 |$..9...Wy'.../..|
|
||||
00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
|
||||
00000060 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 |..Y...U..R..O0..|
|
||||
00000070 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d |K0..............|
|
||||
@@ -60,17 +60,17 @@
|
||||
00000290 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d |w.......@.a.Lr+.|
|
||||
000002a0 ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db |..F..M...>...B..|
|
||||
000002b0 fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 |.=.`.\!.;.......|
|
||||
000002c0 ac 0c 00 00 a8 03 00 1d 20 2d c8 0c d2 27 fc f9 |........ -...'..|
|
||||
000002d0 79 71 c4 17 ea 45 ec 0b dd 66 ce af ec 49 96 7d |yq...E...f...I.}|
|
||||
000002e0 43 ff 88 68 b1 a8 bb e1 38 08 04 00 80 5a ab 5b |C..h....8....Z.[|
|
||||
000002f0 e6 b3 32 e2 98 ae c3 ed 7c f9 90 c4 a4 ea dd 70 |..2.....|......p|
|
||||
00000300 fc a4 f8 ef d1 15 0d b7 ad b8 e3 1f 3e c0 e4 40 |............>..@|
|
||||
00000310 0d 7b 50 36 8f 88 cb 88 59 7c 20 63 d1 7f 36 9e |.{P6....Y| c..6.|
|
||||
00000320 de a7 cb 6a 49 fd 65 32 36 0b 10 6a df 58 ef fd |...jI.e26..j.X..|
|
||||
00000330 f6 fc e6 65 e7 81 0e 73 25 87 c7 89 dc ec ae 7c |...e...s%......||
|
||||
00000340 e4 81 79 79 a2 b9 12 28 ab 3b d0 2e 5e 81 47 2a |..yy...(.;..^.G*|
|
||||
00000350 79 1e 16 21 fa 64 78 24 33 24 f7 ac f1 11 a7 15 |y..!.dx$3$......|
|
||||
00000360 98 f6 24 52 14 7c 1f 28 0c 24 b1 a9 8a 16 03 03 |..$R.|.(.$......|
|
||||
000002c0 ac 0c 00 00 a8 03 00 1d 20 94 54 54 4c 52 a7 a5 |........ .TTLR..|
|
||||
000002d0 c0 01 ed 59 bf 46 03 59 25 3b 57 f8 24 99 1b dc |...Y.F.Y%;W.$...|
|
||||
000002e0 f6 f4 1d 42 0e 2e c3 7c 02 08 04 00 80 5a 42 35 |...B...|.....ZB5|
|
||||
000002f0 78 c8 a9 37 6f 61 a4 ef 3a a3 12 03 f7 ee 44 be |x..7oa..:.....D.|
|
||||
00000300 8b c9 52 4f de db f5 1e 9c c8 33 32 3c 0a 9e d6 |..RO......32<...|
|
||||
00000310 32 bf 2e 12 f7 b0 9b 15 dc eb 24 6e d6 f2 ad 5d |2.........$n...]|
|
||||
00000320 9e 77 c4 a7 7a a1 a0 13 0b 90 b4 aa 3e 51 a1 3d |.w..z.......>Q.=|
|
||||
00000330 71 09 15 84 1c c5 98 bb 12 db 11 e2 4c 2c d1 a9 |q...........L,..|
|
||||
00000340 5a ed 8e fb c6 ae ec d5 6d ec d8 d8 2a a7 23 ae |Z.......m...*.#.|
|
||||
00000350 d7 d2 03 d0 23 8a 21 ac 7e 56 b4 23 7f c6 2a 72 |....#.!.~V.#..*r|
|
||||
00000360 85 0b 6d 6c 9d 6f ad ee 15 20 d9 2b b9 16 03 03 |..ml.o... .+....|
|
||||
00000370 00 3a 0d 00 00 36 03 01 02 40 00 2e 04 03 05 03 |.:...6...@......|
|
||||
00000380 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
|
||||
00000390 08 06 04 01 05 01 06 01 03 03 02 03 03 01 02 01 |................|
|
||||
@@ -112,26 +112,26 @@
|
||||
00000200 e5 35 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 |.5....%...! /.}.|
|
||||
00000210 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 |G.bC.(.._.).0...|
|
||||
00000220 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 16 03 03 00 |......._X.;t....|
|
||||
00000230 88 0f 00 00 84 08 04 00 80 8b ad 4b 9a 7a 53 b8 |...........K.zS.|
|
||||
00000240 6a 0a e7 71 6a 9b 8b 89 7d 3a 49 c9 af ce 3f e2 |j..qj...}:I...?.|
|
||||
00000250 3e cc 0b da 57 9b 8c 2f 58 0f a9 05 4d e9 de 83 |>...W../X...M...|
|
||||
00000260 60 e8 1c 77 ef 23 e4 aa 6b c3 15 64 98 f8 b1 72 |`..w.#..k..d...r|
|
||||
00000270 b2 8a 9e a3 19 3d 73 84 05 53 59 e1 bb e1 db 51 |.....=s..SY....Q|
|
||||
00000280 49 38 cf 8b ee 3c b6 05 0d ba 62 02 b3 36 dc c1 |I8...<....b..6..|
|
||||
00000290 e1 52 4d bd 6a c1 3e 55 ff 82 5f e3 7c 84 1c 65 |.RM.j.>U.._.|..e|
|
||||
000002a0 45 53 b9 c0 56 99 ac 56 d7 4a fa 72 3e 63 36 06 |ES..V..V.J.r>c6.|
|
||||
000002b0 d3 60 ef 34 05 3f 57 20 79 14 03 03 00 01 01 16 |.`.4.?W y.......|
|
||||
000002c0 03 03 00 28 00 00 00 00 00 00 00 00 00 26 b7 73 |...(.........&.s|
|
||||
000002d0 b5 e9 b3 8a 63 00 9b 36 a0 cf 2a 60 0f 8a 59 75 |....c..6..*`..Yu|
|
||||
000002e0 08 71 97 dc 66 73 15 04 08 b4 d3 91 |.q..fs......|
|
||||
00000230 88 0f 00 00 84 04 01 00 80 61 11 ba 1a fe 08 7c |.........a.....||
|
||||
00000240 40 68 88 01 a4 3a 46 bf f6 e9 bb b6 08 92 20 f0 |@h...:F....... .|
|
||||
00000250 13 90 c2 4b 53 83 a1 12 c2 d5 8d e6 67 82 df 80 |...KS.......g...|
|
||||
00000260 85 a5 b4 e0 cf 1b d6 3a 46 1e 62 e5 7f 21 bc 91 |.......:F.b..!..|
|
||||
00000270 4a 8c c0 79 16 64 5f 7e 40 c5 fb 7a 52 5b bf db |J..y.d_~@..zR[..|
|
||||
00000280 cc 31 f8 b8 37 ef df dc 5f 96 30 ad dd 0b 8a 87 |.1..7..._.0.....|
|
||||
00000290 af 4d c6 5c a5 5e d7 2e fa c7 72 68 85 71 c3 0e |.M.\.^....rh.q..|
|
||||
000002a0 1b 26 87 ff 46 47 4a 1b ce b7 a5 aa 13 d2 5a e3 |.&..FGJ.......Z.|
|
||||
000002b0 36 02 35 df 68 d9 bf 3f 24 14 03 03 00 01 01 16 |6.5.h..?$.......|
|
||||
000002c0 03 03 00 28 00 00 00 00 00 00 00 00 e3 8e cc e5 |...(............|
|
||||
000002d0 2e ab 40 fa 3d 47 c1 4f 3f de 97 a9 3d 96 73 ba |..@.=G.O?...=.s.|
|
||||
000002e0 eb a0 ce 67 f6 d1 14 b8 7e cd 1f 85 |...g....~...|
|
||||
>>> Flow 4 (server to client)
|
||||
00000000 14 03 03 00 01 01 16 03 03 00 28 d2 b2 3f a8 43 |..........(..?.C|
|
||||
00000010 41 1a 85 20 9f ee 21 6a c5 96 cf 7c 01 8e f6 3a |A.. ..!j...|...:|
|
||||
00000020 e3 29 14 68 ea 74 a3 ef 85 04 78 33 db c7 d4 c9 |.).h.t....x3....|
|
||||
00000030 a2 fd 6a |..j|
|
||||
00000000 14 03 03 00 01 01 16 03 03 00 28 6a 0a 74 70 75 |..........(j.tpu|
|
||||
00000010 0b 39 33 a5 15 0d 7c 7f f8 13 de 0e 0a 8f 13 3b |.93...|........;|
|
||||
00000020 62 4f 8a 0b bd 0a aa 9b 5a 52 d5 e6 9f e5 b9 3f |bO......ZR.....?|
|
||||
00000030 bd d8 3b |..;|
|
||||
>>> Flow 5 (client to server)
|
||||
00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 c3 3b 68 |..............;h|
|
||||
00000010 b5 e9 4d 75 22 92 fb 19 85 88 38 97 12 3f ce ca |..Mu".....8..?..|
|
||||
00000020 36 c0 d6 15 03 03 00 1a 00 00 00 00 00 00 00 02 |6...............|
|
||||
00000030 c1 a9 03 81 61 04 7c 86 24 e9 90 22 59 6f c7 bc |....a.|.$.."Yo..|
|
||||
00000040 c2 a1 |..|
|
||||
00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 0e 4d 62 |..............Mb|
|
||||
00000010 d3 ac cd 11 15 6d 24 c7 00 fa f9 d2 91 ba eb 06 |.....m$.........|
|
||||
00000020 f2 44 f1 15 03 03 00 1a 00 00 00 00 00 00 00 02 |.D..............|
|
||||
00000030 d1 5a 58 ba ae 65 15 67 79 1f 52 f1 1a da 50 99 |.ZX..e.gy.R...P.|
|
||||
00000040 e8 50 |.P|
|
||||
|
||||
125
src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-PSS-Disabled-512
vendored
Normal file
125
src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-PSS-Disabled-512
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
>>> Flow 1 (client to server)
|
||||
00000000 16 03 01 00 f8 01 00 00 f4 03 03 00 00 00 00 00 |................|
|
||||
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
||||
00000020 00 00 00 00 00 00 00 00 00 00 00 20 00 00 00 00 |........... ....|
|
||||
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
||||
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a8 |.............2..|
|
||||
00000050 cc a9 c0 2f c0 2b c0 30 c0 2c c0 27 c0 13 c0 23 |.../.+.0.,.'...#|
|
||||
00000060 c0 09 c0 14 c0 0a 00 9c 00 9d 00 3c 00 2f 00 35 |...........<./.5|
|
||||
00000070 c0 12 00 0a 00 05 c0 11 c0 07 13 01 13 03 13 02 |................|
|
||||
00000080 01 00 00 79 00 05 00 05 01 00 00 00 00 00 0a 00 |...y............|
|
||||
00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
|
||||
000000a0 00 00 0d 00 18 00 16 08 04 08 05 08 06 04 01 04 |................|
|
||||
000000b0 03 05 01 05 03 06 01 06 03 02 01 02 03 ff 01 00 |................|
|
||||
000000c0 01 00 00 12 00 00 00 2b 00 09 08 03 04 03 03 03 |.......+........|
|
||||
000000d0 02 03 01 00 33 00 26 00 24 00 1d 00 20 2f e5 7d |....3.&.$... /.}|
|
||||
000000e0 a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 |.G.bC.(.._.).0..|
|
||||
000000f0 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 |........_X.;t|
|
||||
>>> Flow 2 (server to client)
|
||||
00000000 16 03 03 00 59 02 00 00 55 03 03 68 11 23 f1 8d |....Y...U..h.#..|
|
||||
00000010 2b a0 71 8f 6e ad 9f ae 43 58 c2 93 2e f5 01 3d |+.q.n...CX.....=|
|
||||
00000020 15 b6 d6 0d f5 42 25 ca b7 b4 96 20 00 c7 86 06 |.....B%.... ....|
|
||||
00000030 ed d1 23 99 dd e3 c4 f5 f9 31 42 51 a3 51 5a 40 |..#......1BQ.QZ@|
|
||||
00000040 11 f6 07 90 51 04 f8 a2 f6 66 c1 f7 c0 2f 00 00 |....Q....f.../..|
|
||||
00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
|
||||
00000060 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 |..Y...U..R..O0..|
|
||||
00000070 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d |K0..............|
|
||||
00000080 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 |?.[..0...*.H....|
|
||||
00000090 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 |....0.1.0...U...|
|
||||
000000a0 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f |.Go1.0...U....Go|
|
||||
000000b0 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 | Root0...1601010|
|
||||
000000c0 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 |00000Z..25010100|
|
||||
000000d0 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a |0000Z0.1.0...U..|
|
||||
000000e0 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 |..Go1.0...U....G|
|
||||
000000f0 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 |o0..0...*.H.....|
|
||||
00000100 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 |.......0.......F|
|
||||
00000110 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 |}...'.H..(!.~...|
|
||||
00000120 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 |]..RE.z6G....B[.|
|
||||
00000130 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 |....y.@.Om..+...|
|
||||
00000140 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b |..g....."8.J.ts+|
|
||||
00000150 c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c |.4......t{.X.la<|
|
||||
00000160 c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d |..A..++$#w[.;.u]|
|
||||
00000170 ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b |. T..c...$....P.|
|
||||
00000180 aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 |...C...ub...R...|
|
||||
00000190 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f |......0..0...U..|
|
||||
000001a0 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 |.........0...U.%|
|
||||
000001b0 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 |..0...+.........|
|
||||
000001c0 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 |+.......0...U...|
|
||||
000001d0 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 |....0.0...U.....|
|
||||
000001e0 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f |.....CC>I..m....|
|
||||
000001f0 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 |`0...U.#..0...H.|
|
||||
00000200 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 |IM.~.1......n{0.|
|
||||
00000210 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 |..U....0...examp|
|
||||
00000220 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 |le.golang0...*.H|
|
||||
00000230 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 |.............0.@|
|
||||
00000240 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 |+[P.a...SX...(.X|
|
||||
00000250 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d |..8....1Z..f=C.-|
|
||||
00000260 d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c |...... d8.$:....|
|
||||
00000270 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 |}.@ ._...a..v...|
|
||||
00000280 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 |...\.....l..s..C|
|
||||
00000290 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d |w.......@.a.Lr+.|
|
||||
000002a0 ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db |..F..M...>...B..|
|
||||
000002b0 fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 |.=.`.\!.;.......|
|
||||
000002c0 ac 0c 00 00 a8 03 00 1d 20 fe 68 1c bf 2b d7 75 |........ .h..+.u|
|
||||
000002d0 c2 dd 96 03 5d 77 61 c1 7d dd 6f bc ea 3c aa 27 |....]wa.}.o..<.'|
|
||||
000002e0 ba cf 93 e2 8b d8 66 a1 1c 08 04 00 80 5e 16 b9 |......f......^..|
|
||||
000002f0 53 17 7d 8d bb 46 4b 1f 37 be cd fe e1 45 c3 10 |S.}..FK.7....E..|
|
||||
00000300 68 54 e4 61 20 a5 a5 98 4b df a7 5d 41 4a aa f8 |hT.a ...K..]AJ..|
|
||||
00000310 0e 36 c2 02 a6 56 a9 f1 aa 76 86 fd a7 86 fb 06 |.6...V...v......|
|
||||
00000320 94 55 56 bd eb 57 10 9a d5 ba 70 59 46 75 e3 b3 |.UV..W....pYFu..|
|
||||
00000330 29 14 c2 65 0e 5c a1 47 e6 bf 12 9d 31 8f 65 4d |)..e.\.G....1.eM|
|
||||
00000340 af dc 1b 6e d2 de d7 fb 85 e7 5a 42 4f de bf d8 |...n......ZBO...|
|
||||
00000350 d5 d8 5c 95 71 27 e7 04 af 58 0a d8 77 fb 3d 22 |..\.q'...X..w.="|
|
||||
00000360 84 f6 f6 53 c0 79 7a 72 01 6e 5c e1 a8 16 03 03 |...S.yzr.n\.....|
|
||||
00000370 00 3a 0d 00 00 36 03 01 02 40 00 2e 04 03 05 03 |.:...6...@......|
|
||||
00000380 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
|
||||
00000390 08 06 04 01 05 01 06 01 03 03 02 03 03 01 02 01 |................|
|
||||
000003a0 03 02 02 02 04 02 05 02 06 02 00 00 16 03 03 00 |................|
|
||||
000003b0 04 0e 00 00 00 |.....|
|
||||
>>> Flow 3 (client to server)
|
||||
00000000 16 03 03 01 7f 0b 00 01 7b 00 01 78 00 01 75 30 |........{..x..u0|
|
||||
00000010 82 01 71 30 82 01 1b a0 03 02 01 02 02 10 1a 34 |..q0...........4|
|
||||
00000020 27 90 21 65 52 a6 85 96 de a2 c7 2c ff b4 30 0d |'.!eR......,..0.|
|
||||
00000030 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 12 31 |..*.H........0.1|
|
||||
00000040 10 30 0e 06 03 55 04 0a 13 07 41 63 6d 65 20 43 |.0...U....Acme C|
|
||||
00000050 6f 30 1e 17 0d 31 39 30 31 31 38 32 33 32 33 32 |o0...19011823232|
|
||||
00000060 38 5a 17 0d 32 30 30 31 31 38 32 33 32 33 32 38 |8Z..200118232328|
|
||||
00000070 5a 30 12 31 10 30 0e 06 03 55 04 0a 13 07 41 63 |Z0.1.0...U....Ac|
|
||||
00000080 6d 65 20 43 6f 30 5c 30 0d 06 09 2a 86 48 86 f7 |me Co0\0...*.H..|
|
||||
00000090 0d 01 01 01 05 00 03 4b 00 30 48 02 41 00 dd 7b |.......K.0H.A..{|
|
||||
000000a0 3d 6b 15 40 f0 6b 1d 87 4f 16 dc 9c 55 0f f4 08 |=k.@.k..O...U...|
|
||||
000000b0 5c 80 41 8c 1d 55 76 9e 7e 15 54 45 85 24 1e 88 |\.A..Uv.~.TE.$..|
|
||||
000000c0 f0 2f cd 93 1d 17 cb 24 25 ae 61 58 07 31 10 9c |./.....$%.aX.1..|
|
||||
000000d0 83 e1 2a 5b 38 4f 48 45 a0 bb e3 26 75 e9 02 03 |..*[8OHE...&u...|
|
||||
000000e0 01 00 01 a3 4d 30 4b 30 0e 06 03 55 1d 0f 01 01 |....M0K0...U....|
|
||||
000000f0 ff 04 04 03 02 05 a0 30 13 06 03 55 1d 25 04 0c |.......0...U.%..|
|
||||
00000100 30 0a 06 08 2b 06 01 05 05 07 03 01 30 0c 06 03 |0...+.......0...|
|
||||
00000110 55 1d 13 01 01 ff 04 02 30 00 30 16 06 03 55 1d |U.......0.0...U.|
|
||||
00000120 11 04 0f 30 0d 82 0b 65 78 61 6d 70 6c 65 2e 63 |...0...example.c|
|
||||
00000130 6f 6d 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 |om0...*.H.......|
|
||||
00000140 00 03 41 00 c4 3b 94 4b e0 6b ad 2d dc fa 1f a4 |..A..;.K.k.-....|
|
||||
00000150 f9 f4 0f 3a 63 92 73 2e b2 4d 7f 66 1f 0d 10 29 |...:c.s..M.f...)|
|
||||
00000160 bb 9c 19 a9 97 60 4c b4 51 12 30 39 d3 b4 b5 0d |.....`L.Q.09....|
|
||||
00000170 cb 1c f7 35 60 6b d8 48 fc 24 0e 39 23 a8 40 ac |...5`k.H.$.9#.@.|
|
||||
00000180 d9 59 bf 00 16 03 03 00 25 10 00 00 21 20 2f e5 |.Y......%...! /.|
|
||||
00000190 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff |}.G.bC.(.._.).0.|
|
||||
000001a0 f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 16 03 |........._X.;t..|
|
||||
000001b0 03 00 48 0f 00 00 44 04 01 00 40 15 33 b2 27 d6 |..H...D...@.3.'.|
|
||||
000001c0 ad 7f 45 86 df a0 83 5e 7c fb a7 0e 04 8e 3c a1 |..E....^|.....<.|
|
||||
000001d0 5b 9a 8f 98 04 cf 66 bb cf 6a d4 63 d7 ff b2 a4 |[.....f..j.c....|
|
||||
000001e0 f1 08 27 f7 53 1c ec 76 35 b1 09 93 91 db 63 e3 |..'.S..v5.....c.|
|
||||
000001f0 a6 2b e5 55 da 06 5b 2f c7 8d c3 14 03 03 00 01 |.+.U..[/........|
|
||||
00000200 01 16 03 03 00 28 00 00 00 00 00 00 00 00 98 d8 |.....(..........|
|
||||
00000210 99 fa 5a fb 79 57 1f 02 4e 07 51 d6 c6 32 9c e8 |..Z.yW..N.Q..2..|
|
||||
00000220 54 50 6c f9 63 fb 38 e2 ef 88 4b 7e 8d 7a |TPl.c.8...K~.z|
|
||||
>>> Flow 4 (server to client)
|
||||
00000000 14 03 03 00 01 01 16 03 03 00 28 4c 6b f0 26 84 |..........(Lk.&.|
|
||||
00000010 97 e6 54 cf 1f 25 1c 91 5d 10 63 22 66 73 d2 ce |..T..%..].c"fs..|
|
||||
00000020 0d 7c 0b 3d 7d 31 3c 0b 6c be 30 72 9e 04 c0 fb |.|.=}1<.l.0r....|
|
||||
00000030 73 88 75 |s.u|
|
||||
>>> Flow 5 (client to server)
|
||||
00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 2a b2 2d |.............*.-|
|
||||
00000010 7f 6e 12 2d d7 63 05 e8 c4 fd 81 de b6 65 2f 2b |.n.-.c.......e/+|
|
||||
00000020 00 0e 13 15 03 03 00 1a 00 00 00 00 00 00 00 02 |................|
|
||||
00000030 9c c0 ae 5a b4 5f b5 4f cd 3f 27 78 f9 b3 b5 b5 |...Z._.O.?'x....|
|
||||
00000040 57 f2 |W.|
|
||||
@@ -4,6 +4,15 @@
|
||||
|
||||
// Package tls partially implements TLS 1.2, as specified in RFC 5246,
|
||||
// and TLS 1.3, as specified in RFC 8446.
|
||||
//
|
||||
// TLS 1.3 is available only on an opt-in basis in Go 1.12. To enable
|
||||
// it, set the GODEBUG environment variable (comma-separated key=value
|
||||
// options) such that it includes "tls13=1". To enable it from within
|
||||
// the process, set the environment variable before any use of TLS:
|
||||
//
|
||||
// func init() {
|
||||
// os.Setenv("GODEBUG", os.Getenv("GODEBUG")+",tls13=1")
|
||||
// }
|
||||
package tls
|
||||
|
||||
// BUG(agl): The crypto/tls package only implements some countermeasures
|
||||
|
||||
@@ -137,7 +137,7 @@ type Pinger interface {
|
||||
|
||||
// Execer is an optional interface that may be implemented by a Conn.
|
||||
//
|
||||
// If a Conn implements neither ExecerContext nor Execer Execer,
|
||||
// If a Conn implements neither ExecerContext nor Execer,
|
||||
// the sql package's DB.Exec will first prepare a query, execute the statement,
|
||||
// and then close the statement.
|
||||
//
|
||||
|
||||
@@ -167,7 +167,7 @@ func compare(aVal, bVal reflect.Value) int {
|
||||
if c, ok := nilCompare(aVal, bVal); ok {
|
||||
return c
|
||||
}
|
||||
c := compare(reflect.ValueOf(aType), reflect.ValueOf(bType))
|
||||
c := compare(reflect.ValueOf(aVal.Elem().Type()), reflect.ValueOf(bVal.Elem().Type()))
|
||||
if c != 0 {
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -126,10 +126,6 @@ var sortTests = []sortTest{
|
||||
map[[2]int]string{{7, 2}: "72", {7, 1}: "71", {3, 4}: "34"},
|
||||
"[3 4]:34 [7 1]:71 [7 2]:72",
|
||||
},
|
||||
{
|
||||
map[interface{}]string{7: "7", 4: "4", 3: "3", nil: "nil"},
|
||||
"<nil>:nil 3:3 4:4 7:7",
|
||||
},
|
||||
}
|
||||
|
||||
func sprint(data interface{}) string {
|
||||
@@ -210,3 +206,41 @@ func TestOrder(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterface(t *testing.T) {
|
||||
// A map containing multiple concrete types should be sorted by type,
|
||||
// then value. However, the relative ordering of types is unspecified,
|
||||
// so test this by checking the presence of sorted subgroups.
|
||||
m := map[interface{}]string{
|
||||
[2]int{1, 0}: "",
|
||||
[2]int{0, 1}: "",
|
||||
true: "",
|
||||
false: "",
|
||||
3.1: "",
|
||||
2.1: "",
|
||||
1.1: "",
|
||||
math.NaN(): "",
|
||||
3: "",
|
||||
2: "",
|
||||
1: "",
|
||||
"c": "",
|
||||
"b": "",
|
||||
"a": "",
|
||||
struct{ x, y int }{1, 0}: "",
|
||||
struct{ x, y int }{0, 1}: "",
|
||||
}
|
||||
got := sprint(m)
|
||||
typeGroups := []string{
|
||||
"NaN: 1.1: 2.1: 3.1:", // float64
|
||||
"false: true:", // bool
|
||||
"1: 2: 3:", // int
|
||||
"a: b: c:", // string
|
||||
"[0 1]: [1 0]:", // [2]int
|
||||
"{0 1}: {1 0}:", // struct{ x int; y int }
|
||||
}
|
||||
for _, g := range typeGroups {
|
||||
if !strings.Contains(got, g) {
|
||||
t.Errorf("sorted map should contain %q", g)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -660,6 +660,10 @@ func (fd *FD) Write(buf []byte) (int, error) {
|
||||
return 0, err
|
||||
}
|
||||
defer fd.writeUnlock()
|
||||
if fd.isFile || fd.isDir || fd.isConsole {
|
||||
fd.l.Lock()
|
||||
defer fd.l.Unlock()
|
||||
}
|
||||
|
||||
ntotal := 0
|
||||
for len(buf) > 0 {
|
||||
@@ -670,8 +674,6 @@ func (fd *FD) Write(buf []byte) (int, error) {
|
||||
var n int
|
||||
var err error
|
||||
if fd.isFile || fd.isDir || fd.isConsole {
|
||||
fd.l.Lock()
|
||||
defer fd.l.Unlock()
|
||||
if fd.isConsole {
|
||||
n, err = fd.writeConsole(b)
|
||||
} else {
|
||||
|
||||
@@ -152,7 +152,7 @@ type ClientTrace struct {
|
||||
WroteHeaders func()
|
||||
|
||||
// Wait100Continue is called if the Request specified
|
||||
// "Expected: 100-continue" and the Transport has written the
|
||||
// "Expect: 100-continue" and the Transport has written the
|
||||
// request headers but is waiting for "100 Continue" from the
|
||||
// server before writing the request body.
|
||||
Wait100Continue func()
|
||||
|
||||
@@ -389,6 +389,11 @@ func (p *ReverseProxy) copyResponse(dst io.Writer, src io.Reader, flushInterval
|
||||
latency: flushInterval,
|
||||
}
|
||||
defer mlw.stop()
|
||||
|
||||
// set up initial timer so headers get flushed even if body writes are delayed
|
||||
mlw.flushPending = true
|
||||
mlw.t = time.AfterFunc(flushInterval, mlw.delayedFlush)
|
||||
|
||||
dst = mlw
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ package httputil
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -317,6 +318,47 @@ func TestReverseProxyFlushInterval(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestReverseProxyFlushIntervalHeaders(t *testing.T) {
|
||||
const expected = "hi"
|
||||
stopCh := make(chan struct{})
|
||||
backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Add("MyHeader", expected)
|
||||
w.WriteHeader(200)
|
||||
w.(http.Flusher).Flush()
|
||||
<-stopCh
|
||||
}))
|
||||
defer backend.Close()
|
||||
defer close(stopCh)
|
||||
|
||||
backendURL, err := url.Parse(backend.URL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
proxyHandler := NewSingleHostReverseProxy(backendURL)
|
||||
proxyHandler.FlushInterval = time.Microsecond
|
||||
|
||||
frontend := httptest.NewServer(proxyHandler)
|
||||
defer frontend.Close()
|
||||
|
||||
req, _ := http.NewRequest("GET", frontend.URL, nil)
|
||||
req.Close = true
|
||||
|
||||
ctx, cancel := context.WithTimeout(req.Context(), 10*time.Second)
|
||||
defer cancel()
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
res, err := frontend.Client().Do(req)
|
||||
if err != nil {
|
||||
t.Fatalf("Get: %v", err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
if res.Header.Get("MyHeader") != expected {
|
||||
t.Errorf("got header %q; expected %q", res.Header.Get("MyHeader"), expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReverseProxyCancelation(t *testing.T) {
|
||||
const backendResponse = "I am the backend"
|
||||
|
||||
|
||||
@@ -262,8 +262,9 @@ func (r *Resolver) lookupIPAddr(ctx context.Context, network, host string) ([]IP
|
||||
// only the values in context. See Issue 28600.
|
||||
lookupGroupCtx, lookupGroupCancel := context.WithCancel(withUnexpiredValuesPreserved(ctx))
|
||||
|
||||
lookupKey := network + "\000" + host
|
||||
dnsWaitGroup.Add(1)
|
||||
ch, called := r.getLookupGroup().DoChan(host, func() (interface{}, error) {
|
||||
ch, called := r.getLookupGroup().DoChan(lookupKey, func() (interface{}, error) {
|
||||
defer dnsWaitGroup.Done()
|
||||
return testHookLookupIP(lookupGroupCtx, resolverFunc, network, host)
|
||||
})
|
||||
@@ -280,7 +281,7 @@ func (r *Resolver) lookupIPAddr(ctx context.Context, network, host string) ([]IP
|
||||
// let the lookup continue uncanceled, and let later
|
||||
// lookups with the same key share the result.
|
||||
// See issues 8602, 20703, 22724.
|
||||
if r.getLookupGroup().ForgetUnshared(host) {
|
||||
if r.getLookupGroup().ForgetUnshared(lookupKey) {
|
||||
lookupGroupCancel()
|
||||
} else {
|
||||
go func() {
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -253,14 +254,11 @@ func TestLookupGmailTXT(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
var lookupGooglePublicDNSAddrTests = []struct {
|
||||
addr, name string
|
||||
}{
|
||||
{"8.8.8.8", ".google.com."},
|
||||
{"8.8.4.4", ".google.com."},
|
||||
|
||||
{"2001:4860:4860::8888", ".google.com."},
|
||||
{"2001:4860:4860::8844", ".google.com."},
|
||||
var lookupGooglePublicDNSAddrTests = []string{
|
||||
"8.8.8.8",
|
||||
"8.8.4.4",
|
||||
"2001:4860:4860::8888",
|
||||
"2001:4860:4860::8844",
|
||||
}
|
||||
|
||||
func TestLookupGooglePublicDNSAddr(t *testing.T) {
|
||||
@@ -272,8 +270,8 @@ func TestLookupGooglePublicDNSAddr(t *testing.T) {
|
||||
|
||||
defer dnsWaitGroup.Wait()
|
||||
|
||||
for _, tt := range lookupGooglePublicDNSAddrTests {
|
||||
names, err := LookupAddr(tt.addr)
|
||||
for _, ip := range lookupGooglePublicDNSAddrTests {
|
||||
names, err := LookupAddr(ip)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -281,8 +279,8 @@ func TestLookupGooglePublicDNSAddr(t *testing.T) {
|
||||
t.Error("got no record")
|
||||
}
|
||||
for _, name := range names {
|
||||
if !strings.HasSuffix(name, tt.name) {
|
||||
t.Errorf("got %s; want a record containing %s", name, tt.name)
|
||||
if !strings.HasSuffix(name, ".google.com.") && !strings.HasSuffix(name, ".google.") {
|
||||
t.Errorf("got %q; want a record ending in .google.com. or .google.", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -658,8 +656,8 @@ func testDots(t *testing.T, mode string) {
|
||||
t.Errorf("LookupAddr(8.8.8.8): %v (mode=%v)", err, mode)
|
||||
} else {
|
||||
for _, name := range names {
|
||||
if !strings.HasSuffix(name, ".google.com.") {
|
||||
t.Errorf("LookupAddr(8.8.8.8) = %v, want names ending in .google.com. with trailing dot (mode=%v)", names, mode)
|
||||
if !strings.HasSuffix(name, ".google.com.") && !strings.HasSuffix(name, ".google.") {
|
||||
t.Errorf("LookupAddr(8.8.8.8) = %v, want names ending in .google.com or .google with trailing dot (mode=%v)", names, mode)
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -1096,6 +1094,69 @@ func TestLookupIPAddrPreservesContextValues(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Issue 30521: The lookup group should call the resolver for each network.
|
||||
func TestLookupIPAddrConcurrentCallsForNetworks(t *testing.T) {
|
||||
origTestHookLookupIP := testHookLookupIP
|
||||
defer func() { testHookLookupIP = origTestHookLookupIP }()
|
||||
|
||||
queries := [][]string{
|
||||
{"udp", "golang.org"},
|
||||
{"udp4", "golang.org"},
|
||||
{"udp6", "golang.org"},
|
||||
{"udp", "golang.org"},
|
||||
{"udp", "golang.org"},
|
||||
}
|
||||
results := map[[2]string][]IPAddr{
|
||||
{"udp", "golang.org"}: {
|
||||
{IP: IPv4(127, 0, 0, 1)},
|
||||
{IP: IPv6loopback},
|
||||
},
|
||||
{"udp4", "golang.org"}: {
|
||||
{IP: IPv4(127, 0, 0, 1)},
|
||||
},
|
||||
{"udp6", "golang.org"}: {
|
||||
{IP: IPv6loopback},
|
||||
},
|
||||
}
|
||||
calls := int32(0)
|
||||
waitCh := make(chan struct{})
|
||||
testHookLookupIP = func(ctx context.Context, fn func(context.Context, string, string) ([]IPAddr, error), network, host string) ([]IPAddr, error) {
|
||||
// We'll block until this is called one time for each different
|
||||
// expected result. This will ensure that the lookup group would wait
|
||||
// for the existing call if it was to be reused.
|
||||
if atomic.AddInt32(&calls, 1) == int32(len(results)) {
|
||||
close(waitCh)
|
||||
}
|
||||
select {
|
||||
case <-waitCh:
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
return results[[2]string{network, host}], nil
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
wg := sync.WaitGroup{}
|
||||
for _, q := range queries {
|
||||
network := q[0]
|
||||
host := q[1]
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
gotIPs, err := DefaultResolver.lookupIPAddr(ctx, network, host)
|
||||
if err != nil {
|
||||
t.Errorf("lookupIPAddr(%v, %v): unexpected error: %v", network, host, err)
|
||||
}
|
||||
wantIPs := results[[2]string{network, host}]
|
||||
if !reflect.DeepEqual(gotIPs, wantIPs) {
|
||||
t.Errorf("lookupIPAddr(%v, %v): mismatched IPAddr results\n\tGot: %v\n\tWant: %v", network, host, gotIPs, wantIPs)
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestWithUnexpiredValuesPreserved(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
|
||||
9
src/os/export_unix_test.go
Normal file
9
src/os/export_unix_test.go
Normal file
@@ -0,0 +1,9 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix darwin dragonfly freebsd js,wasm linux nacl netbsd openbsd solaris
|
||||
|
||||
package os
|
||||
|
||||
var SplitPath = splitPath
|
||||
@@ -281,3 +281,28 @@ func TestNewFileNonBlock(t *testing.T) {
|
||||
t.Parallel()
|
||||
newFileTest(t, false)
|
||||
}
|
||||
|
||||
func TestSplitPath(t *testing.T) {
|
||||
t.Parallel()
|
||||
for _, tt := range []struct{ path, wantDir, wantBase string }{
|
||||
{"a", ".", "a"},
|
||||
{"a/", ".", "a"},
|
||||
{"a//", ".", "a"},
|
||||
{"a/b", "a", "b"},
|
||||
{"a/b/", "a", "b"},
|
||||
{"a/b/c", "a/b", "c"},
|
||||
{"/a", "/", "a"},
|
||||
{"/a/", "/", "a"},
|
||||
{"/a/b", "/a", "b"},
|
||||
{"/a/b/", "/a", "b"},
|
||||
{"/a/b/c", "/a/b", "c"},
|
||||
{"//a", "/", "a"},
|
||||
{"//a/", "/", "a"},
|
||||
{"///a", "/", "a"},
|
||||
{"///a/", "/", "a"},
|
||||
} {
|
||||
if dir, base := SplitPath(tt.path); dir != tt.wantDir || base != tt.wantBase {
|
||||
t.Errorf("splitPath(%q) = %q, %q, want %q, %q", tt.path, dir, base, tt.wantDir, tt.wantBase)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ func MkdirAll(path string, perm FileMode) error {
|
||||
// It removes everything it can but returns the first error
|
||||
// it encounters. If the path does not exist, RemoveAll
|
||||
// returns nil (no error).
|
||||
// If there is an error, it will be of type *PathError.
|
||||
func RemoveAll(path string) error {
|
||||
return removeAll(path)
|
||||
}
|
||||
|
||||
@@ -38,20 +38,30 @@ func basename(name string) string {
|
||||
func splitPath(path string) (string, string) {
|
||||
// if no better parent is found, the path is relative from "here"
|
||||
dirname := "."
|
||||
// if no slashes in path, base is path
|
||||
basename := path
|
||||
|
||||
// Remove all but one leading slash.
|
||||
for len(path) > 1 && path[0] == '/' && path[1] == '/' {
|
||||
path = path[1:]
|
||||
}
|
||||
|
||||
i := len(path) - 1
|
||||
|
||||
// Remove trailing slashes
|
||||
// Remove trailing slashes.
|
||||
for ; i > 0 && path[i] == '/'; i-- {
|
||||
path = path[:i]
|
||||
}
|
||||
|
||||
// if no slashes in path, base is path
|
||||
basename := path
|
||||
|
||||
// Remove leading directory path
|
||||
for i--; i >= 0; i-- {
|
||||
if path[i] == '/' {
|
||||
dirname = path[:i+1]
|
||||
if i == 0 {
|
||||
dirname = path[:1]
|
||||
} else {
|
||||
dirname = path[:i]
|
||||
}
|
||||
basename = path[i+1:]
|
||||
break
|
||||
}
|
||||
|
||||
@@ -46,13 +46,20 @@ func removeAll(path string) error {
|
||||
}
|
||||
defer parent.Close()
|
||||
|
||||
return removeAllFrom(parent, base)
|
||||
if err := removeAllFrom(parent, base); err != nil {
|
||||
if pathErr, ok := err.(*PathError); ok {
|
||||
pathErr.Path = parentDir + string(PathSeparator) + pathErr.Path
|
||||
err = pathErr
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func removeAllFrom(parent *File, path string) error {
|
||||
func removeAllFrom(parent *File, base string) error {
|
||||
parentFd := int(parent.Fd())
|
||||
// Simple case: if Unlink (aka remove) works, we're done.
|
||||
err := unix.Unlinkat(parentFd, path, 0)
|
||||
err := unix.Unlinkat(parentFd, base, 0)
|
||||
if err == nil || IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
@@ -64,18 +71,21 @@ func removeAllFrom(parent *File, path string) error {
|
||||
// whose contents need to be removed.
|
||||
// Otherwise just return the error.
|
||||
if err != syscall.EISDIR && err != syscall.EPERM && err != syscall.EACCES {
|
||||
return err
|
||||
return &PathError{"unlinkat", base, err}
|
||||
}
|
||||
|
||||
// Is this a directory we need to recurse into?
|
||||
var statInfo syscall.Stat_t
|
||||
statErr := unix.Fstatat(parentFd, path, &statInfo, unix.AT_SYMLINK_NOFOLLOW)
|
||||
statErr := unix.Fstatat(parentFd, base, &statInfo, unix.AT_SYMLINK_NOFOLLOW)
|
||||
if statErr != nil {
|
||||
return statErr
|
||||
if IsNotExist(statErr) {
|
||||
return nil
|
||||
}
|
||||
return &PathError{"fstatat", base, statErr}
|
||||
}
|
||||
if statInfo.Mode&syscall.S_IFMT != syscall.S_IFDIR {
|
||||
// Not a directory; return the error from the Remove.
|
||||
return err
|
||||
// Not a directory; return the error from the unix.Unlinkat.
|
||||
return &PathError{"unlinkat", base, err}
|
||||
}
|
||||
|
||||
// Remove the directory's entries.
|
||||
@@ -84,12 +94,13 @@ func removeAllFrom(parent *File, path string) error {
|
||||
const request = 1024
|
||||
|
||||
// Open the directory to recurse into
|
||||
file, err := openFdAt(parentFd, path)
|
||||
file, err := openFdAt(parentFd, base)
|
||||
if err != nil {
|
||||
if IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
recurseErr = &PathError{"openfdat", base, err}
|
||||
break
|
||||
}
|
||||
|
||||
names, readErr := file.Readdirnames(request)
|
||||
@@ -99,12 +110,15 @@ func removeAllFrom(parent *File, path string) error {
|
||||
if IsNotExist(readErr) {
|
||||
return nil
|
||||
}
|
||||
return readErr
|
||||
return &PathError{"readdirnames", base, readErr}
|
||||
}
|
||||
|
||||
for _, name := range names {
|
||||
err := removeAllFrom(file, name)
|
||||
if err != nil {
|
||||
if pathErr, ok := err.(*PathError); ok {
|
||||
pathErr.Path = base + string(PathSeparator) + pathErr.Path
|
||||
}
|
||||
recurseErr = err
|
||||
}
|
||||
}
|
||||
@@ -123,7 +137,7 @@ func removeAllFrom(parent *File, path string) error {
|
||||
}
|
||||
|
||||
// Remove the directory itself.
|
||||
unlinkError := unix.Unlinkat(parentFd, path, unix.AT_REMOVEDIR)
|
||||
unlinkError := unix.Unlinkat(parentFd, base, unix.AT_REMOVEDIR)
|
||||
if unlinkError == nil || IsNotExist(unlinkError) {
|
||||
return nil
|
||||
}
|
||||
@@ -131,7 +145,7 @@ func removeAllFrom(parent *File, path string) error {
|
||||
if recurseErr != nil {
|
||||
return recurseErr
|
||||
}
|
||||
return unlinkError
|
||||
return &PathError{"unlinkat", base, unlinkError}
|
||||
}
|
||||
|
||||
// openFdAt opens path relative to the directory in fd.
|
||||
@@ -153,7 +167,7 @@ func openFdAt(dirfd int, name string) (*File, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
return nil, &PathError{"openat", name, e}
|
||||
return nil, e
|
||||
}
|
||||
|
||||
if !supportsCloseOnExec {
|
||||
|
||||
@@ -294,7 +294,7 @@ func TestRemoveReadOnlyDir(t *testing.T) {
|
||||
}
|
||||
|
||||
// Issue #29983.
|
||||
func TestRemoveAllButReadOnly(t *testing.T) {
|
||||
func TestRemoveAllButReadOnlyAndPathError(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "js", "windows":
|
||||
t.Skipf("skipping test on %s", runtime.GOOS)
|
||||
@@ -355,10 +355,21 @@ func TestRemoveAllButReadOnly(t *testing.T) {
|
||||
defer Chmod(d, 0777)
|
||||
}
|
||||
|
||||
if err := RemoveAll(tempDir); err == nil {
|
||||
err = RemoveAll(tempDir)
|
||||
if err == nil {
|
||||
t.Fatal("RemoveAll succeeded unexpectedly")
|
||||
}
|
||||
|
||||
// The error should be of type *PathError.
|
||||
// see issue 30491 for details.
|
||||
if pathErr, ok := err.(*PathError); ok {
|
||||
if g, w := pathErr.Path, filepath.Join(tempDir, "b", "y"); g != w {
|
||||
t.Errorf("got %q, expected pathErr.path %q", g, w)
|
||||
}
|
||||
} else {
|
||||
t.Errorf("got %T, expected *os.PathError", err)
|
||||
}
|
||||
|
||||
for _, dir := range dirs {
|
||||
_, err := Stat(filepath.Join(tempDir, dir))
|
||||
if inReadonly(dir) {
|
||||
@@ -372,3 +383,33 @@ func TestRemoveAllButReadOnly(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveUnreadableDir(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "js", "windows":
|
||||
t.Skipf("skipping test on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
if Getuid() == 0 {
|
||||
t.Skip("skipping test when running as root")
|
||||
}
|
||||
|
||||
t.Parallel()
|
||||
|
||||
tempDir, err := ioutil.TempDir("", "TestRemoveAllButReadOnly-")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer RemoveAll(tempDir)
|
||||
|
||||
target := filepath.Join(tempDir, "d0", "d1", "d2")
|
||||
if err := MkdirAll(target, 0755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := Chmod(target, 0300); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := RemoveAll(filepath.Join(tempDir, "d0")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,19 +96,14 @@ func Clean(path string) string {
|
||||
}
|
||||
return originalPath + "."
|
||||
}
|
||||
|
||||
n := len(path)
|
||||
if volLen > 2 && n == 1 && os.IsPathSeparator(path[0]) {
|
||||
// UNC volume name with trailing slash.
|
||||
return FromSlash(originalPath[:volLen])
|
||||
}
|
||||
rooted := os.IsPathSeparator(path[0])
|
||||
|
||||
// Invariants:
|
||||
// reading from path; r is index of next byte to process.
|
||||
// writing to out; w is index of next byte to write.
|
||||
// dotdot is index in out where .. must stop, either because
|
||||
// writing to buf; w is index of next byte to write.
|
||||
// dotdot is index in buf where .. must stop, either because
|
||||
// it is the leading slash or it is a leading ../../.. prefix.
|
||||
n := len(path)
|
||||
out := lazybuf{path: path, volAndPath: originalPath, volLen: volLen}
|
||||
r, dotdot := 0, 0
|
||||
if rooted {
|
||||
|
||||
@@ -93,9 +93,6 @@ var wincleantests = []PathTest{
|
||||
{`//host/share/foo/../baz`, `\\host\share\baz`},
|
||||
{`\\a\b\..\c`, `\\a\b\c`},
|
||||
{`\\a\b`, `\\a\b`},
|
||||
{`\\a\b\`, `\\a\b`},
|
||||
{`\\folder\share\foo`, `\\folder\share\foo`},
|
||||
{`\\folder\share\foo\`, `\\folder\share\foo`},
|
||||
}
|
||||
|
||||
func TestClean(t *testing.T) {
|
||||
@@ -1413,3 +1410,103 @@ func TestIssue29372(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Issue 30520 part 1.
|
||||
func TestEvalSymlinksAboveRoot(t *testing.T) {
|
||||
testenv.MustHaveSymlink(t)
|
||||
|
||||
t.Parallel()
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", "TestEvalSymlinksAboveRoot")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
evalTmpDir, err := filepath.EvalSymlinks(tmpDir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := os.Mkdir(filepath.Join(evalTmpDir, "a"), 0777); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.Symlink(filepath.Join(evalTmpDir, "a"), filepath.Join(evalTmpDir, "b")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := ioutil.WriteFile(filepath.Join(evalTmpDir, "a", "file"), nil, 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Count the number of ".." elements to get to the root directory.
|
||||
vol := filepath.VolumeName(evalTmpDir)
|
||||
c := strings.Count(evalTmpDir[len(vol):], string(os.PathSeparator))
|
||||
var dd []string
|
||||
for i := 0; i < c+2; i++ {
|
||||
dd = append(dd, "..")
|
||||
}
|
||||
|
||||
wantSuffix := strings.Join([]string{"a", "file"}, string(os.PathSeparator))
|
||||
|
||||
// Try different numbers of "..".
|
||||
for _, i := range []int{c, c + 1, c + 2} {
|
||||
check := strings.Join([]string{evalTmpDir, strings.Join(dd[:i], string(os.PathSeparator)), evalTmpDir[len(vol)+1:], "b", "file"}, string(os.PathSeparator))
|
||||
if resolved, err := filepath.EvalSymlinks(check); err != nil {
|
||||
t.Errorf("EvalSymlinks(%q) failed: %v", check, err)
|
||||
} else if !strings.HasSuffix(resolved, wantSuffix) {
|
||||
t.Errorf("EvalSymlinks(%q) = %q does not end with %q", check, resolved, wantSuffix)
|
||||
} else {
|
||||
t.Logf("EvalSymlinks(%q) = %q", check, resolved)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Issue 30520 part 2.
|
||||
func TestEvalSymlinksAboveRootChdir(t *testing.T) {
|
||||
testenv.MustHaveSymlink(t)
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", "TestEvalSymlinksAboveRootChdir")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.Chdir(wd)
|
||||
|
||||
if err := os.Chdir(tmpDir); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
subdir := filepath.Join("a", "b")
|
||||
if err := os.MkdirAll(subdir, 0777); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.Symlink(subdir, "c"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := ioutil.WriteFile(filepath.Join(subdir, "file"), nil, 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
subdir = filepath.Join("d", "e", "f")
|
||||
if err := os.MkdirAll(subdir, 0777); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.Chdir(subdir); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
check := filepath.Join("..", "..", "..", "c", "file")
|
||||
wantSuffix := filepath.Join("a", "b", "file")
|
||||
if resolved, err := filepath.EvalSymlinks(check); err != nil {
|
||||
t.Errorf("EvalSymlinks(%q) failed: %v", check, err)
|
||||
} else if !strings.HasSuffix(resolved, wantSuffix) {
|
||||
t.Errorf("EvalSymlinks(%q) = %q does not end with %q", check, resolved, wantSuffix)
|
||||
} else {
|
||||
t.Logf("EvalSymlinks(%q) = %q", check, resolved)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,18 +44,26 @@ func walkSymlinks(path string) (string, error) {
|
||||
} else if path[start:end] == ".." {
|
||||
// Back up to previous component if possible.
|
||||
// Note that volLen includes any leading slash.
|
||||
|
||||
// Set r to the index of the last slash in dest,
|
||||
// after the volume.
|
||||
var r int
|
||||
for r = len(dest) - 1; r >= volLen; r-- {
|
||||
if os.IsPathSeparator(dest[r]) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if r < volLen {
|
||||
if r < volLen || dest[r+1:] == ".." {
|
||||
// Either path has no slashes
|
||||
// (it's empty or just "C:")
|
||||
// or it ends in a ".." we had to keep.
|
||||
// Either way, keep this "..".
|
||||
if len(dest) > volLen {
|
||||
dest += pathSeparator
|
||||
}
|
||||
dest += ".."
|
||||
} else {
|
||||
// Discard everything since the last slash.
|
||||
dest = dest[:r]
|
||||
}
|
||||
continue
|
||||
|
||||
@@ -443,7 +443,7 @@ TEXT runtime·gcWriteBarrier(SB), NOSPLIT, $16
|
||||
// Record value
|
||||
MOVD R1, 0(R5)
|
||||
// Record *slot
|
||||
MOVD R0, 8(R5)
|
||||
MOVD (R0), 8(R5)
|
||||
|
||||
// Increment wbBuf.next
|
||||
Get R5
|
||||
|
||||
@@ -728,3 +728,15 @@ func TestG0StackOverflow(t *testing.T) {
|
||||
|
||||
runtime.G0StackOverflow()
|
||||
}
|
||||
|
||||
// Test that panic message is not clobbered.
|
||||
// See issue 30150.
|
||||
func TestDoublePanic(t *testing.T) {
|
||||
output := runTestProg(t, "testprog", "DoublePanic", "GODEBUG=clobberfree=1")
|
||||
wants := []string{"panic: XXX", "panic: YYY"}
|
||||
for _, want := range wants {
|
||||
if !strings.Contains(output, want) {
|
||||
t.Errorf("output:\n%s\n\nwant output containing: %s", output, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -513,3 +513,116 @@ func MapTombstoneCheck(m map[int]int) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Span is a safe wrapper around an mspan, whose memory
|
||||
// is managed manually.
|
||||
type Span struct {
|
||||
*mspan
|
||||
}
|
||||
|
||||
func AllocSpan(base, npages uintptr) Span {
|
||||
lock(&mheap_.lock)
|
||||
s := (*mspan)(mheap_.spanalloc.alloc())
|
||||
unlock(&mheap_.lock)
|
||||
s.init(base, npages)
|
||||
return Span{s}
|
||||
}
|
||||
|
||||
func (s *Span) Free() {
|
||||
lock(&mheap_.lock)
|
||||
mheap_.spanalloc.free(unsafe.Pointer(s.mspan))
|
||||
unlock(&mheap_.lock)
|
||||
s.mspan = nil
|
||||
}
|
||||
|
||||
func (s Span) Base() uintptr {
|
||||
return s.mspan.base()
|
||||
}
|
||||
|
||||
func (s Span) Pages() uintptr {
|
||||
return s.mspan.npages
|
||||
}
|
||||
|
||||
type TreapIter struct {
|
||||
treapIter
|
||||
}
|
||||
|
||||
func (t TreapIter) Span() Span {
|
||||
return Span{t.span()}
|
||||
}
|
||||
|
||||
func (t TreapIter) Valid() bool {
|
||||
return t.valid()
|
||||
}
|
||||
|
||||
func (t TreapIter) Next() TreapIter {
|
||||
return TreapIter{t.next()}
|
||||
}
|
||||
|
||||
func (t TreapIter) Prev() TreapIter {
|
||||
return TreapIter{t.prev()}
|
||||
}
|
||||
|
||||
// Treap is a safe wrapper around mTreap for testing.
|
||||
//
|
||||
// It must never be heap-allocated because mTreap is
|
||||
// notinheap.
|
||||
//
|
||||
//go:notinheap
|
||||
type Treap struct {
|
||||
mTreap
|
||||
}
|
||||
|
||||
func (t *Treap) Start() TreapIter {
|
||||
return TreapIter{t.start()}
|
||||
}
|
||||
|
||||
func (t *Treap) End() TreapIter {
|
||||
return TreapIter{t.end()}
|
||||
}
|
||||
|
||||
func (t *Treap) Insert(s Span) {
|
||||
// mTreap uses a fixalloc in mheap_ for treapNode
|
||||
// allocation which requires the mheap_ lock to manipulate.
|
||||
// Locking here is safe because the treap itself never allocs
|
||||
// or otherwise ends up grabbing this lock.
|
||||
lock(&mheap_.lock)
|
||||
t.insert(s.mspan)
|
||||
unlock(&mheap_.lock)
|
||||
t.CheckInvariants()
|
||||
}
|
||||
|
||||
func (t *Treap) Find(npages uintptr) TreapIter {
|
||||
return TreapIter{treapIter{t.find(npages)}}
|
||||
}
|
||||
|
||||
func (t *Treap) Erase(i TreapIter) {
|
||||
// mTreap uses a fixalloc in mheap_ for treapNode
|
||||
// freeing which requires the mheap_ lock to manipulate.
|
||||
// Locking here is safe because the treap itself never allocs
|
||||
// or otherwise ends up grabbing this lock.
|
||||
lock(&mheap_.lock)
|
||||
t.erase(i.treapIter)
|
||||
unlock(&mheap_.lock)
|
||||
t.CheckInvariants()
|
||||
}
|
||||
|
||||
func (t *Treap) RemoveSpan(s Span) {
|
||||
// See Erase about locking.
|
||||
lock(&mheap_.lock)
|
||||
t.removeSpan(s.mspan)
|
||||
unlock(&mheap_.lock)
|
||||
t.CheckInvariants()
|
||||
}
|
||||
|
||||
func (t *Treap) Size() int {
|
||||
i := 0
|
||||
t.mTreap.treap.walkTreap(func(t *treapNode) {
|
||||
i++
|
||||
})
|
||||
return i
|
||||
}
|
||||
|
||||
func (t *Treap) CheckInvariants() {
|
||||
t.mTreap.treap.walkTreap(checkTreapNode)
|
||||
}
|
||||
|
||||
@@ -27,6 +27,10 @@ It is a comma-separated list of name=val pairs setting these named variables:
|
||||
allocfreetrace: setting allocfreetrace=1 causes every allocation to be
|
||||
profiled and a stack trace printed on each object's allocation and free.
|
||||
|
||||
clobberfree: setting clobberfree=1 causes the garbage collector to
|
||||
clobber the memory content of an object with bad content when it frees
|
||||
the object.
|
||||
|
||||
cgocheck: setting cgocheck=0 disables all checks for packages
|
||||
using cgo to incorrectly pass Go pointers to non-Go code.
|
||||
Setting cgocheck=1 (the default) enables relatively cheap
|
||||
@@ -123,7 +127,7 @@ It is a comma-separated list of name=val pairs setting these named variables:
|
||||
IDs will refer to the ID of the goroutine at the time of creation; it's possible for this
|
||||
ID to be reused for another goroutine. Setting N to 0 will report no ancestry information.
|
||||
|
||||
The net and net/http packages also refer to debugging variables in GODEBUG.
|
||||
The net, net/http, and crypto/tls packages also refer to debugging variables in GODEBUG.
|
||||
See the documentation for those packages for details.
|
||||
|
||||
The GOMAXPROCS variable limits the number of operating system threads that
|
||||
|
||||
@@ -134,16 +134,19 @@ func checkTreapNode(t *treapNode) {
|
||||
return t.npagesKey < npages
|
||||
}
|
||||
// t.npagesKey == npages
|
||||
return uintptr(unsafe.Pointer(t.spanKey)) < uintptr(unsafe.Pointer(s))
|
||||
return t.spanKey.base() < s.base()
|
||||
}
|
||||
|
||||
if t == nil {
|
||||
return
|
||||
}
|
||||
if t.spanKey.npages != t.npagesKey || t.spanKey.next != nil {
|
||||
if t.spanKey.next != nil || t.spanKey.prev != nil || t.spanKey.list != nil {
|
||||
throw("span may be on an mSpanList while simultaneously in the treap")
|
||||
}
|
||||
if t.spanKey.npages != t.npagesKey {
|
||||
println("runtime: checkTreapNode treapNode t=", t, " t.npagesKey=", t.npagesKey,
|
||||
"t.spanKey.npages=", t.spanKey.npages)
|
||||
throw("why does span.npages and treap.ngagesKey do not match?")
|
||||
throw("span.npages and treap.npagesKey do not match")
|
||||
}
|
||||
if t.left != nil && lessThan(t.left.npagesKey, t.left.spanKey) {
|
||||
throw("t.lessThan(t.left.npagesKey, t.left.spanKey) is not false")
|
||||
@@ -298,24 +301,30 @@ func (root *mTreap) removeNode(t *treapNode) {
|
||||
// find searches for, finds, and returns the treap node containing the
|
||||
// smallest span that can hold npages. If no span has at least npages
|
||||
// it returns nil.
|
||||
// This is slightly more complicated than a simple binary tree search
|
||||
// since if an exact match is not found the next larger node is
|
||||
// returned.
|
||||
// This is a simple binary tree search that tracks the best-fit node found
|
||||
// so far. The best-fit node is guaranteed to be on the path to a
|
||||
// (maybe non-existent) lowest-base exact match.
|
||||
func (root *mTreap) find(npages uintptr) *treapNode {
|
||||
var best *treapNode
|
||||
t := root.treap
|
||||
for t != nil {
|
||||
if t.spanKey == nil {
|
||||
throw("treap node with nil spanKey found")
|
||||
}
|
||||
if t.npagesKey < npages {
|
||||
t = t.right
|
||||
} else if t.left != nil && t.left.npagesKey >= npages {
|
||||
// If we found an exact match, try to go left anyway. There could be
|
||||
// a span there with a lower base address.
|
||||
//
|
||||
// Don't bother checking nil-ness of left and right here; even if t
|
||||
// becomes nil, we already know the other path had nothing better for
|
||||
// us anyway.
|
||||
if t.npagesKey >= npages {
|
||||
best = t
|
||||
t = t.left
|
||||
} else {
|
||||
return t
|
||||
t = t.right
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return best
|
||||
}
|
||||
|
||||
// removeSpan searches for, finds, deletes span along with
|
||||
|
||||
@@ -709,7 +709,20 @@ func scanstack(gp *g, gcw *gcWork) {
|
||||
return true
|
||||
}
|
||||
gentraceback(^uintptr(0), ^uintptr(0), 0, gp, 0, nil, 0x7fffffff, scanframe, nil, 0)
|
||||
|
||||
// Find additional pointers that point into the stack from the heap.
|
||||
// Currently this includes defers and panics. See also function copystack.
|
||||
tracebackdefers(gp, scanframe, nil)
|
||||
for d := gp._defer; d != nil; d = d.link {
|
||||
// tracebackdefers above does not scan the func value, which could
|
||||
// be a stack allocated closure. See issue 30453.
|
||||
if d.fn != nil {
|
||||
scanblock(uintptr(unsafe.Pointer(&d.fn)), sys.PtrSize, &oneptrmask[0], gcw, &state)
|
||||
}
|
||||
}
|
||||
if gp._panic != nil {
|
||||
state.putPtr(uintptr(unsafe.Pointer(gp._panic)))
|
||||
}
|
||||
|
||||
// Find and scan all reachable stack objects.
|
||||
state.buildIndex()
|
||||
|
||||
@@ -291,7 +291,7 @@ func (s *mspan) sweep(preserve bool) bool {
|
||||
}
|
||||
}
|
||||
|
||||
if debug.allocfreetrace != 0 || raceenabled || msanenabled {
|
||||
if debug.allocfreetrace != 0 || debug.clobberfree != 0 || raceenabled || msanenabled {
|
||||
// Find all newly freed objects. This doesn't have to
|
||||
// efficient; allocfreetrace has massive overhead.
|
||||
mbits := s.markBitsForBase()
|
||||
@@ -302,6 +302,9 @@ func (s *mspan) sweep(preserve bool) bool {
|
||||
if debug.allocfreetrace != 0 {
|
||||
tracefree(unsafe.Pointer(x), size)
|
||||
}
|
||||
if debug.clobberfree != 0 {
|
||||
clobberfree(unsafe.Pointer(x), size)
|
||||
}
|
||||
if raceenabled {
|
||||
racefree(unsafe.Pointer(x), size)
|
||||
}
|
||||
@@ -446,3 +449,12 @@ retry:
|
||||
traceGCSweepDone()
|
||||
}
|
||||
}
|
||||
|
||||
// clobberfree sets the memory content at x to bad content, for debugging
|
||||
// purposes.
|
||||
func clobberfree(x unsafe.Pointer, size uintptr) {
|
||||
// size (span.elemsize) is always a multiple of 4.
|
||||
for i := uintptr(0); i < size; i += 4 {
|
||||
*(*uint32)(add(x, i)) = 0xdeadbeef
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1198,16 +1198,6 @@ HaveSpan:
|
||||
// heap_released since we already did so earlier.
|
||||
sysUsed(unsafe.Pointer(s.base()), s.npages<<_PageShift)
|
||||
s.scavenged = false
|
||||
|
||||
// Since we allocated out of a scavenged span, we just
|
||||
// grew the RSS. Mitigate this by scavenging enough free
|
||||
// space to make up for it.
|
||||
//
|
||||
// Also, scavengeLargest may cause coalescing, so prevent
|
||||
// coalescing with s by temporarily changing its state.
|
||||
s.state = mSpanManual
|
||||
h.scavengeLargest(s.npages * pageSize)
|
||||
s.state = mSpanFree
|
||||
}
|
||||
s.unusedsince = 0
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ const (
|
||||
//go:cgo_import_dynamic runtime._GetProcessAffinityMask GetProcessAffinityMask%3 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._GetQueuedCompletionStatus GetQueuedCompletionStatus%5 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._GetStdHandle GetStdHandle%1 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._GetSystemDirectoryA GetSystemDirectoryA%2 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo%1 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext%2 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll"
|
||||
@@ -47,12 +48,9 @@ const (
|
||||
//go:cgo_import_dynamic runtime._VirtualAlloc VirtualAlloc%4 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._VirtualFree VirtualFree%3 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._VirtualQuery VirtualQuery%3 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._WSAGetOverlappedResult WSAGetOverlappedResult%5 "ws2_32.dll"
|
||||
//go:cgo_import_dynamic runtime._WaitForSingleObject WaitForSingleObject%2 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._WriteConsoleW WriteConsoleW%5 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._WriteFile WriteFile%5 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._timeBeginPeriod timeBeginPeriod%1 "winmm.dll"
|
||||
//go:cgo_import_dynamic runtime._timeEndPeriod timeEndPeriod%1 "winmm.dll"
|
||||
|
||||
type stdFunction unsafe.Pointer
|
||||
|
||||
@@ -75,6 +73,7 @@ var (
|
||||
_GetProcessAffinityMask,
|
||||
_GetQueuedCompletionStatus,
|
||||
_GetStdHandle,
|
||||
_GetSystemDirectoryA,
|
||||
_GetSystemInfo,
|
||||
_GetSystemTimeAsFileTime,
|
||||
_GetThreadContext,
|
||||
@@ -96,12 +95,9 @@ var (
|
||||
_VirtualAlloc,
|
||||
_VirtualFree,
|
||||
_VirtualQuery,
|
||||
_WSAGetOverlappedResult,
|
||||
_WaitForSingleObject,
|
||||
_WriteConsoleW,
|
||||
_WriteFile,
|
||||
_timeBeginPeriod,
|
||||
_timeEndPeriod,
|
||||
_ stdFunction
|
||||
|
||||
// Following syscalls are only available on some Windows PCs.
|
||||
@@ -109,6 +105,7 @@ var (
|
||||
_AddDllDirectory,
|
||||
_AddVectoredContinueHandler,
|
||||
_GetQueuedCompletionStatusEx,
|
||||
_LoadLibraryExA,
|
||||
_LoadLibraryExW,
|
||||
_ stdFunction
|
||||
|
||||
@@ -126,6 +123,12 @@ var (
|
||||
// links wrong printf function to cgo executable (see issue
|
||||
// 12030 for details).
|
||||
_NtWaitForSingleObject stdFunction
|
||||
|
||||
// These are from non-kernel32.dll, so we prefer to LoadLibraryEx them.
|
||||
_timeBeginPeriod,
|
||||
_timeEndPeriod,
|
||||
_WSAGetOverlappedResult,
|
||||
_ stdFunction
|
||||
)
|
||||
|
||||
// Function to be called by windows CreateThread
|
||||
@@ -173,6 +176,26 @@ func windowsFindfunc(lib uintptr, name []byte) stdFunction {
|
||||
return stdFunction(unsafe.Pointer(f))
|
||||
}
|
||||
|
||||
var sysDirectory [521]byte
|
||||
var sysDirectoryLen uintptr
|
||||
|
||||
func windowsLoadSystemLib(name []byte) uintptr {
|
||||
if useLoadLibraryEx {
|
||||
return stdcall3(_LoadLibraryExA, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32)
|
||||
} else {
|
||||
if sysDirectoryLen == 0 {
|
||||
l := stdcall2(_GetSystemDirectoryA, uintptr(unsafe.Pointer(&sysDirectory[0])), uintptr(len(sysDirectory)-1))
|
||||
if l == 0 || l > uintptr(len(sysDirectory)-1) {
|
||||
throw("Unable to determine system directory")
|
||||
}
|
||||
sysDirectory[l] = '\\'
|
||||
sysDirectoryLen = l + 1
|
||||
}
|
||||
absName := append(sysDirectory[:sysDirectoryLen], name...)
|
||||
return stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&absName[0])))
|
||||
}
|
||||
}
|
||||
|
||||
func loadOptionalSyscalls() {
|
||||
var kernel32dll = []byte("kernel32.dll\000")
|
||||
k32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0])))
|
||||
@@ -182,17 +205,19 @@ func loadOptionalSyscalls() {
|
||||
_AddDllDirectory = windowsFindfunc(k32, []byte("AddDllDirectory\000"))
|
||||
_AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000"))
|
||||
_GetQueuedCompletionStatusEx = windowsFindfunc(k32, []byte("GetQueuedCompletionStatusEx\000"))
|
||||
_LoadLibraryExA = windowsFindfunc(k32, []byte("LoadLibraryExA\000"))
|
||||
_LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000"))
|
||||
useLoadLibraryEx = (_LoadLibraryExW != nil && _LoadLibraryExA != nil && _AddDllDirectory != nil)
|
||||
|
||||
var advapi32dll = []byte("advapi32.dll\000")
|
||||
a32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&advapi32dll[0])))
|
||||
a32 := windowsLoadSystemLib(advapi32dll)
|
||||
if a32 == 0 {
|
||||
throw("advapi32.dll not found")
|
||||
}
|
||||
_RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000"))
|
||||
|
||||
var ntdll = []byte("ntdll.dll\000")
|
||||
n32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&ntdll[0])))
|
||||
n32 := windowsLoadSystemLib(ntdll)
|
||||
if n32 == 0 {
|
||||
throw("ntdll.dll not found")
|
||||
}
|
||||
@@ -205,6 +230,27 @@ func loadOptionalSyscalls() {
|
||||
}
|
||||
}
|
||||
|
||||
var winmmdll = []byte("winmm.dll\000")
|
||||
m32 := windowsLoadSystemLib(winmmdll)
|
||||
if m32 == 0 {
|
||||
throw("winmm.dll not found")
|
||||
}
|
||||
_timeBeginPeriod = windowsFindfunc(m32, []byte("timeBeginPeriod\000"))
|
||||
_timeEndPeriod = windowsFindfunc(m32, []byte("timeEndPeriod\000"))
|
||||
if _timeBeginPeriod == nil || _timeEndPeriod == nil {
|
||||
throw("timeBegin/EndPeriod not found")
|
||||
}
|
||||
|
||||
var ws232dll = []byte("ws2_32.dll\000")
|
||||
ws232 := windowsLoadSystemLib(ws232dll)
|
||||
if ws232 == 0 {
|
||||
throw("ws2_32.dll not found")
|
||||
}
|
||||
_WSAGetOverlappedResult = windowsFindfunc(ws232, []byte("WSAGetOverlappedResult\000"))
|
||||
if _WSAGetOverlappedResult == nil {
|
||||
throw("WSAGetOverlappedResult not found")
|
||||
}
|
||||
|
||||
if windowsFindfunc(n32, []byte("wine_get_version\000")) != nil {
|
||||
// running on Wine
|
||||
initWine(k32)
|
||||
@@ -311,8 +357,6 @@ func osinit() {
|
||||
|
||||
loadOptionalSyscalls()
|
||||
|
||||
useLoadLibraryEx = (_LoadLibraryExW != nil && _AddDllDirectory != nil)
|
||||
|
||||
disableWER()
|
||||
|
||||
initExceptionHandler()
|
||||
|
||||
@@ -139,6 +139,7 @@ func TestLldbPython(t *testing.T) {
|
||||
if final := os.Getenv("GOROOT_FINAL"); final != "" && runtime.GOROOT() != final {
|
||||
t.Skip("gdb test can fail with GOROOT_FINAL pending")
|
||||
}
|
||||
testenv.SkipFlaky(t, 31188)
|
||||
|
||||
checkLldbPython(t)
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user