mirror of
https://github.com/golang/go.git
synced 2026-01-29 23:22:06 +03:00
Compare commits
121 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c15c7cce7 | ||
|
|
ea17f61b1e | ||
|
|
6e6f4aaf70 | ||
|
|
06472b99cd | ||
|
|
8e7eb2f04c | ||
|
|
07d3f571c4 | ||
|
|
306a74284e | ||
|
|
305f6dc30c | ||
|
|
3226f2d492 | ||
|
|
7139b45d14 | ||
|
|
4e15604ada | ||
|
|
2da8ca41a7 | ||
|
|
047a326569 | ||
|
|
3c97797394 | ||
|
|
f194c9f25a | ||
|
|
8759b53147 | ||
|
|
7f416b4f04 | ||
|
|
465d821ecf | ||
|
|
4a6c732a53 | ||
|
|
4dbe72de5f | ||
|
|
c955c54431 | ||
|
|
e050fac971 | ||
|
|
39b533ed66 | ||
|
|
77c14d2973 | ||
|
|
4ce6a8e896 | ||
|
|
06a61ef36a | ||
|
|
b408ab558f | ||
|
|
a6178d8ee3 | ||
|
|
3887549ce4 | ||
|
|
451e6d61b3 | ||
|
|
918368e46c | ||
|
|
3b05c3c2e6 | ||
|
|
afcfe0d3c2 | ||
|
|
ecf7695c7d | ||
|
|
cdb776529e | ||
|
|
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,88 @@ 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>
|
||||
|
||||
<p>
|
||||
go1.12.6 (released 2019/06/11) includes fixes to the compiler, the linker,
|
||||
the go command, and the <code>crypto/x509</code>, <code>net/http</code>, and
|
||||
<code>os</code> packages. See the
|
||||
<a href="https://github.com/golang/go/issues?q=milestone%3AGo1.12.6">Go
|
||||
1.12.6 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.12.7 (released 2019/07/08) includes fixes to cgo, the compiler,
|
||||
and the linker.
|
||||
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.12.7">Go
|
||||
1.12.7 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.12.8 (released 2019/08/13) includes security fixes to the
|
||||
<code>net/http</code> and <code>net/url</code> packages.
|
||||
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.12.8">Go
|
||||
1.12.8 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.12.9 (released 2019/08/15) includes fixes to the linker,
|
||||
and the <code>os</code> and <code>math/big</code> packages.
|
||||
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.12.9+label%3ACherryPickApproved">Go
|
||||
1.12.9 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.12.10 (released 2019/09/25) includes security fixes to the
|
||||
<code>net/http</code> and <code>net/textproto</code> packages.
|
||||
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.12.10">Go
|
||||
1.12.10 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<h2 id="go1.11">go1.11 (released 2018/08/24)</h2>
|
||||
|
||||
<p>
|
||||
@@ -66,6 +148,67 @@ 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>
|
||||
|
||||
<p>
|
||||
go1.11.11 (released 2019/06/11) includes a fix to the <code>crypto/x509</code> package.
|
||||
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.11.11">Go
|
||||
1.11.11 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.11.12 (released 2019/07/08) includes fixes to the compiler and the linker.
|
||||
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.11.12">Go
|
||||
1.11.12 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.11.13 (released 2019/08/13) includes security fixes to the
|
||||
<code>net/http</code> and <code>net/url</code> packages.
|
||||
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.11.13">Go
|
||||
1.11.13 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<h2 id="go1.10">go1.10 (released 2018/02/16)</h2>
|
||||
|
||||
<p>
|
||||
@@ -131,6 +274,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>.
|
||||
@@ -87,6 +80,10 @@ Do not send CLs removing the interior tags from such phrases.
|
||||
checks for private API usage. Since it is considered private,
|
||||
<code>syscall.Getdirentries</code> now always fails with
|
||||
<code>ENOSYS</code> on iOS.
|
||||
Additionally, <a href="/pkg/syscall/#Setrlimit"><code>syscall.Setrlimit</code></a>
|
||||
reports <code>invalid</code> <code>argument</code> in places where it historically
|
||||
succeeded. These consequences are not specific to Go and users should expect
|
||||
behavioral parity with <code>libSystem</code>'s implementation going forward.
|
||||
</p>
|
||||
|
||||
<h2 id="tools">Tools</h2>
|
||||
@@ -109,7 +106,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 +118,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 +189,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 +311,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 +503,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 +615,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 +691,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 +795,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 +928,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>
|
||||
|
||||
@@ -95,6 +95,7 @@ func Test26213(t *testing.T) { test26213(t) }
|
||||
func Test27660(t *testing.T) { test27660(t) }
|
||||
func Test28896(t *testing.T) { test28896(t) }
|
||||
func Test30065(t *testing.T) { test30065(t) }
|
||||
func Test32579(t *testing.T) { test32579(t) }
|
||||
|
||||
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
|
||||
func BenchmarkGoString(b *testing.B) { benchGoString(b) }
|
||||
|
||||
22
misc/cgo/test/issue32579.go
Normal file
22
misc/cgo/test/issue32579.go
Normal file
@@ -0,0 +1,22 @@
|
||||
// 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 cgotest
|
||||
|
||||
// #include <string.h>
|
||||
// typedef struct S32579 { unsigned char data[1]; } S32579;
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func test32579(t *testing.T) {
|
||||
var s [1]C.struct_S32579
|
||||
C.memset(unsafe.Pointer(&s[0].data[0]), 1, 1)
|
||||
if s[0].data[0] != 1 {
|
||||
t.Errorf("&s[0].data[0] failed: got %d, want %d", s[0].data[0], 1)
|
||||
}
|
||||
}
|
||||
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
|
||||
)
|
||||
@@ -917,3 +917,10 @@ func TestTestInstalledShared(t *testing.T) {
|
||||
func TestGeneratedMethod(t *testing.T) {
|
||||
goCmd(t, "install", "-buildmode=shared", "-linkshared", "issue25065")
|
||||
}
|
||||
|
||||
// Test use of shared library struct with generated hash function.
|
||||
// Issue 30768.
|
||||
func TestGeneratedHash(t *testing.T) {
|
||||
goCmd(nil, "install", "-buildmode=shared", "-linkshared", "issue30768/issue30768lib")
|
||||
goCmd(nil, "test", "-linkshared", "issue30768")
|
||||
}
|
||||
|
||||
11
misc/cgo/testshared/src/issue30768/issue30768lib/lib.go
Normal file
11
misc/cgo/testshared/src/issue30768/issue30768lib/lib.go
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 issue30768lib
|
||||
|
||||
// S is a struct that requires a generated hash function.
|
||||
type S struct {
|
||||
A string
|
||||
B int
|
||||
}
|
||||
22
misc/cgo/testshared/src/issue30768/x_test.go
Normal file
22
misc/cgo/testshared/src/issue30768/x_test.go
Normal file
@@ -0,0 +1,22 @@
|
||||
// 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 issue30768_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"issue30768/issue30768lib"
|
||||
)
|
||||
|
||||
type s struct {
|
||||
s issue30768lib.S
|
||||
}
|
||||
|
||||
func Test30768(t *testing.T) {
|
||||
// Calling t.Log will convert S to an empty interface,
|
||||
// which will force a reference to the generated hash function,
|
||||
// defined in the shared library.
|
||||
t.Log(s{})
|
||||
}
|
||||
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) {
|
||||
@@ -1302,6 +1256,8 @@ func (p *Package) isVariable(x ast.Expr) bool {
|
||||
return true
|
||||
case *ast.SelectorExpr:
|
||||
return p.isVariable(x.X)
|
||||
case *ast.IndexExpr:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -2511,13 +2467,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 +2486,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),
|
||||
|
||||
@@ -555,6 +555,13 @@ const (
|
||||
inNonInitFunction
|
||||
)
|
||||
|
||||
func (c initContext) String() string {
|
||||
if c == inInitFunction {
|
||||
return "inInitFunction"
|
||||
}
|
||||
return "inNonInitFunction"
|
||||
}
|
||||
|
||||
// from here down is the walk analysis
|
||||
// of composite literals.
|
||||
// most of the work is to generate
|
||||
@@ -913,7 +920,13 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
|
||||
break
|
||||
|
||||
case OARRAYLIT, OSTRUCTLIT:
|
||||
fixedlit(ctxt, initKindDynamic, value, a, init)
|
||||
k := initKindDynamic
|
||||
if vstat == nil {
|
||||
// Generate both static and dynamic initializations.
|
||||
// See issue #31987.
|
||||
k = initKindLocalCode
|
||||
}
|
||||
fixedlit(ctxt, k, value, a, init)
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1597,13 +1597,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (ORL <v.Type> (SHLLconst <v.Type> [j0] (MOVWload [i0] {s} p mem)) y)
|
||||
-> @mergePoint(b,x0,x1,y) (ORL <v.Type> (SHLLconst <v.Type> [j0] (MOVWload [i0] {s} p mem)) y)
|
||||
|
||||
(ORQ
|
||||
s1:(SHLQconst [j1] x1:(MOVBload [i1] {s} p mem))
|
||||
@@ -1618,13 +1618,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVWload [i0] {s} p mem)) y)
|
||||
-> @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVWload [i0] {s} p mem)) y)
|
||||
|
||||
(ORQ
|
||||
s1:(SHLQconst [j1] x1:(MOVWload [i1] {s} p mem))
|
||||
@@ -1639,13 +1639,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVLload [i0] {s} p mem)) y)
|
||||
-> @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVLload [i0] {s} p mem)) y)
|
||||
|
||||
// Little-endian indexed loads
|
||||
|
||||
@@ -1722,13 +1722,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (ORL <v.Type> (SHLLconst <v.Type> [j0] (MOVWloadidx1 [i0] {s} p idx mem)) y)
|
||||
-> @mergePoint(b,x0,x1,y) (ORL <v.Type> (SHLLconst <v.Type> [j0] (MOVWloadidx1 [i0] {s} p idx mem)) y)
|
||||
|
||||
(ORQ
|
||||
s1:(SHLQconst [j1] x1:(MOVBloadidx1 [i1] {s} p idx mem))
|
||||
@@ -1743,13 +1743,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVWloadidx1 [i0] {s} p idx mem)) y)
|
||||
-> @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVWloadidx1 [i0] {s} p idx mem)) y)
|
||||
|
||||
(ORQ
|
||||
s1:(SHLQconst [j1] x1:(MOVWloadidx1 [i1] {s} p idx mem))
|
||||
@@ -1764,13 +1764,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVLloadidx1 [i0] {s} p idx mem)) y)
|
||||
-> @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVLloadidx1 [i0] {s} p idx mem)) y)
|
||||
|
||||
// Big-endian loads
|
||||
|
||||
@@ -1864,13 +1864,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (ORL <v.Type> (SHLLconst <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i0] {s} p mem))) y)
|
||||
-> @mergePoint(b,x0,x1,y) (ORL <v.Type> (SHLLconst <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i0] {s} p mem))) y)
|
||||
|
||||
(ORQ
|
||||
s0:(SHLQconst [j0] x0:(MOVBload [i0] {s} p mem))
|
||||
@@ -1885,13 +1885,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i0] {s} p mem))) y)
|
||||
-> @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i0] {s} p mem))) y)
|
||||
|
||||
(ORQ
|
||||
s0:(SHLQconst [j0] r0:(ROLWconst [8] x0:(MOVWload [i0] {s} p mem)))
|
||||
@@ -1908,7 +1908,7 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(r0)
|
||||
@@ -1916,7 +1916,7 @@
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (BSWAPL <typ.UInt32> (MOVLload [i0] {s} p mem))) y)
|
||||
-> @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (BSWAPL <typ.UInt32> (MOVLload [i0] {s} p mem))) y)
|
||||
|
||||
// Big-endian indexed loads
|
||||
|
||||
@@ -2010,13 +2010,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (ORL <v.Type> (SHLLconst <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWloadidx1 [i0] {s} p idx mem))) y)
|
||||
-> @mergePoint(b,x0,x1,y) (ORL <v.Type> (SHLLconst <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWloadidx1 [i0] {s} p idx mem))) y)
|
||||
|
||||
(ORQ
|
||||
s0:(SHLQconst [j0] x0:(MOVBloadidx1 [i0] {s} p idx mem))
|
||||
@@ -2031,13 +2031,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWloadidx1 [i0] {s} p idx mem))) y)
|
||||
-> @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWloadidx1 [i0] {s} p idx mem))) y)
|
||||
|
||||
(ORQ
|
||||
s0:(SHLQconst [j0] r0:(ROLWconst [8] x0:(MOVWloadidx1 [i0] {s} p idx mem)))
|
||||
@@ -2054,7 +2054,7 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(r0)
|
||||
@@ -2062,7 +2062,7 @@
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (BSWAPL <typ.UInt32> (MOVLloadidx1 [i0] {s} p idx mem))) y)
|
||||
-> @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (BSWAPL <typ.UInt32> (MOVLloadidx1 [i0] {s} p idx mem))) y)
|
||||
|
||||
// Combine 2 byte stores + shift into rolw 8 + word store
|
||||
(MOVBstore [i] {s} p w
|
||||
|
||||
@@ -1480,13 +1480,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (ORW <v.Type> (SLWconst <v.Type> [j1] (MOVHZload [i0] {s} p mem)) y)
|
||||
-> @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j1] (MOVHZload [i0] {s} p mem)) y)
|
||||
|
||||
(OR
|
||||
s0:(SLDconst [j0] x0:(MOVBZload [i0] {s} p mem))
|
||||
@@ -1501,13 +1501,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVHZload [i0] {s} p mem)) y)
|
||||
-> @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVHZload [i0] {s} p mem)) y)
|
||||
|
||||
(OR
|
||||
s0:(SLDconst [j0] x0:(MOVHZload [i0] {s} p mem))
|
||||
@@ -1522,13 +1522,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVWZload [i0] {s} p mem)) y)
|
||||
-> @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVWZload [i0] {s} p mem)) y)
|
||||
|
||||
// Big-endian indexed loads
|
||||
|
||||
@@ -1610,13 +1610,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (ORW <v.Type> (SLWconst <v.Type> [j1] (MOVHZloadidx [i0] {s} p idx mem)) y)
|
||||
-> @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j1] (MOVHZloadidx [i0] {s} p idx mem)) y)
|
||||
|
||||
(OR
|
||||
s0:(SLDconst [j0] x0:(MOVBZloadidx [i0] {s} p idx mem))
|
||||
@@ -1631,13 +1631,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVHZloadidx [i0] {s} p idx mem)) y)
|
||||
-> @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVHZloadidx [i0] {s} p idx mem)) y)
|
||||
|
||||
(OR
|
||||
s0:(SLDconst [j0] x0:(MOVHZloadidx [i0] {s} p idx mem))
|
||||
@@ -1652,13 +1652,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVWZloadidx [i0] {s} p idx mem)) y)
|
||||
-> @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVWZloadidx [i0] {s} p idx mem)) y)
|
||||
|
||||
// Little-endian loads
|
||||
|
||||
@@ -1750,13 +1750,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (ORW <v.Type> (SLWconst <v.Type> [j0] (MOVHZreg (MOVHBRload [i0] {s} p mem))) y)
|
||||
-> @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j0] (MOVHZreg (MOVHBRload [i0] {s} p mem))) y)
|
||||
|
||||
(OR
|
||||
s1:(SLDconst [j1] x1:(MOVBZload [i1] {s} p mem))
|
||||
@@ -1772,13 +1772,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVHZreg (MOVHBRload [i0] {s} p mem))) y)
|
||||
-> @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVHZreg (MOVHBRload [i0] {s} p mem))) y)
|
||||
|
||||
(OR
|
||||
s1:(SLDconst [j1] r1:(MOVHZreg x1:(MOVHBRload [i1] {s} p mem)))
|
||||
@@ -1795,7 +1795,7 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(r0)
|
||||
@@ -1803,7 +1803,7 @@
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVWZreg (MOVWBRload [i0] {s} p mem))) y)
|
||||
-> @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVWZreg (MOVWBRload [i0] {s} p mem))) y)
|
||||
|
||||
// Little-endian indexed loads
|
||||
|
||||
@@ -1895,13 +1895,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (ORW <v.Type> (SLWconst <v.Type> [j0] (MOVHZreg (MOVHBRloadidx [i0] {s} p idx mem))) y)
|
||||
-> @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j0] (MOVHZreg (MOVHBRloadidx [i0] {s} p idx mem))) y)
|
||||
|
||||
(OR
|
||||
s1:(SLDconst [j1] x1:(MOVBZloadidx [i1] {s} p idx mem))
|
||||
@@ -1917,13 +1917,13 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVHZreg (MOVHBRloadidx [i0] {s} p idx mem))) y)
|
||||
-> @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVHZreg (MOVHBRloadidx [i0] {s} p idx mem))) y)
|
||||
|
||||
(OR
|
||||
s1:(SLDconst [j1] r1:(MOVHZreg x1:(MOVHBRloadidx [i1] {s} p idx mem)))
|
||||
@@ -1940,7 +1940,7 @@
|
||||
&& s0.Uses == 1
|
||||
&& s1.Uses == 1
|
||||
&& or.Uses == 1
|
||||
&& mergePoint(b,x0,x1) != nil
|
||||
&& mergePoint(b,x0,x1,y) != nil
|
||||
&& clobber(x0)
|
||||
&& clobber(x1)
|
||||
&& clobber(r0)
|
||||
@@ -1948,7 +1948,7 @@
|
||||
&& clobber(s0)
|
||||
&& clobber(s1)
|
||||
&& clobber(or)
|
||||
-> @mergePoint(b,x0,x1) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVWZreg (MOVWBRloadidx [i0] {s} p idx mem))) y)
|
||||
-> @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVWZreg (MOVWBRloadidx [i0] {s} p idx mem))) y)
|
||||
|
||||
// Combine stores into store multiples.
|
||||
// 32-bit
|
||||
|
||||
@@ -549,15 +549,29 @@ func (ft *factsTable) isNonNegative(v *Value) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
var max int64
|
||||
switch v.Type.Size() {
|
||||
case 1:
|
||||
max = math.MaxInt8
|
||||
case 2:
|
||||
max = math.MaxInt16
|
||||
case 4:
|
||||
max = math.MaxInt32
|
||||
case 8:
|
||||
max = math.MaxInt64
|
||||
default:
|
||||
panic("unexpected integer size")
|
||||
}
|
||||
|
||||
// Check if the recorded limits can prove that the value is positive
|
||||
if l, has := ft.limits[v.ID]; has && (l.min >= 0 || l.umax <= math.MaxInt64) {
|
||||
if l, has := ft.limits[v.ID]; has && (l.min >= 0 || l.umax <= uint64(max)) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check if v = x+delta, and we can use x's limits to prove that it's positive
|
||||
if x, delta := isConstDelta(v); x != nil {
|
||||
if l, has := ft.limits[x.ID]; has {
|
||||
if delta > 0 && l.min >= -delta && l.max <= math.MaxInt64-delta {
|
||||
if delta > 0 && l.min >= -delta && l.max <= max-delta {
|
||||
return true
|
||||
}
|
||||
if delta < 0 && l.min >= -delta {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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,15 @@ 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 set p.Internal.ForceLibrary and
|
||||
// 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 +354,8 @@ func recompileForTest(pmain, preal, ptest, pxtest *Package) {
|
||||
copy(p1.Imports, p.Imports)
|
||||
p = p1
|
||||
p.Target = ""
|
||||
p.Internal.BuildInfo = ""
|
||||
p.Internal.ForceLibrary = true
|
||||
}
|
||||
|
||||
// Update p.Internal.Imports to use test copies.
|
||||
@@ -361,6 +365,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 {
|
||||
|
||||
@@ -177,6 +177,8 @@ var validLinkerFlags = []*regexp.Regexp{
|
||||
re(`-Wl,-framework,[^,@\-][^,]+`),
|
||||
re(`-Wl,-headerpad_max_install_names`),
|
||||
re(`-Wl,--no-undefined`),
|
||||
re(`-Wl,-R([^@\-][^,@]*$)`),
|
||||
re(`-Wl,--just-symbols[=,]([^,@\-][^,@]+)`),
|
||||
re(`-Wl,-rpath(-link)?[=,]([^,@\-][^,]+)`),
|
||||
re(`-Wl,-s`),
|
||||
re(`-Wl,-search_paths_first`),
|
||||
@@ -206,6 +208,8 @@ var validLinkerFlagsWithNextArg = []string{
|
||||
"-target",
|
||||
"-Wl,-framework",
|
||||
"-Wl,-rpath",
|
||||
"-Wl,-R",
|
||||
"-Wl,--just-symbols",
|
||||
"-Wl,-undefined",
|
||||
}
|
||||
|
||||
|
||||
@@ -125,6 +125,11 @@ var goodLinkerFlags = [][]string{
|
||||
{"-pthread"},
|
||||
{"-Wl,-rpath,foo"},
|
||||
{"-Wl,-rpath,$ORIGIN/foo"},
|
||||
{"-Wl,-R", "/foo"},
|
||||
{"-Wl,-R", "foo"},
|
||||
{"-Wl,-R,foo"},
|
||||
{"-Wl,--just-symbols=foo"},
|
||||
{"-Wl,--just-symbols,foo"},
|
||||
{"-Wl,--warn-error"},
|
||||
{"-Wl,--no-warn-error"},
|
||||
{"foo.so"},
|
||||
@@ -197,6 +202,9 @@ var badLinkerFlags = [][]string{
|
||||
{"-x", "--c"},
|
||||
{"-x", "@obj"},
|
||||
{"-Wl,-rpath,@foo"},
|
||||
{"-Wl,-R,foo,bar"},
|
||||
{"-Wl,-R,@foo"},
|
||||
{"-Wl,--just-symbols,@foo"},
|
||||
{"../x.o"},
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -1802,7 +1802,15 @@ func ldshlibsyms(ctxt *Link, shlib string) {
|
||||
if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
|
||||
continue
|
||||
}
|
||||
lsym := ctxt.Syms.Lookup(elfsym.Name, 0)
|
||||
|
||||
// Symbols whose names start with "type." are compiler
|
||||
// generated, so make functions with that prefix internal.
|
||||
ver := 0
|
||||
if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && strings.HasPrefix(elfsym.Name, "type.") {
|
||||
ver = sym.SymVerABIInternal
|
||||
}
|
||||
|
||||
lsym := ctxt.Syms.Lookup(elfsym.Name, ver)
|
||||
// Because loadlib above loads all .a files before loading any shared
|
||||
// libraries, any non-dynimport symbols we find that duplicate symbols
|
||||
// already loaded should be ignored (the symbols from the .a files
|
||||
@@ -1830,7 +1838,7 @@ func ldshlibsyms(ctxt *Link, shlib string) {
|
||||
// the ABIs are actually different. We might have to
|
||||
// mangle Go function names in the .so to include the
|
||||
// ABI.
|
||||
if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC {
|
||||
if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && ver == 0 {
|
||||
alias := ctxt.Syms.Lookup(elfsym.Name, sym.SymVerABIInternal)
|
||||
if alias.Type != 0 {
|
||||
continue
|
||||
@@ -1958,7 +1966,7 @@ func stkcheck(ctxt *Link, up *chain, depth int) int {
|
||||
s.Attr |= sym.AttrStackCheck
|
||||
}
|
||||
|
||||
if depth > 100 {
|
||||
if depth > 500 {
|
||||
Errorf(s, "nosplit stack check too deep")
|
||||
stkbroke(ctxt, up, 0)
|
||||
return -1
|
||||
|
||||
@@ -662,9 +662,11 @@ func Asmbmacho(ctxt *Link) {
|
||||
// and we can assume OS X.
|
||||
//
|
||||
// See golang.org/issues/12941.
|
||||
//
|
||||
// The version must be at least 10.9; see golang.org/issues/30488.
|
||||
ml := newMachoLoad(ctxt.Arch, LC_VERSION_MIN_MACOSX, 2)
|
||||
ml.data[0] = 10<<16 | 7<<8 | 0<<0 // OS X version 10.7.0
|
||||
ml.data[1] = 10<<16 | 7<<8 | 0<<0 // SDK 10.7.0
|
||||
ml.data[0] = 10<<16 | 9<<8 | 0<<0 // OS X version 10.9.0
|
||||
ml.data[1] = 10<<16 | 9<<8 | 0<<0 // SDK 10.9.0
|
||||
}
|
||||
|
||||
a := machowrite(ctxt.Arch, ctxt.Out, ctxt.LinkMode)
|
||||
|
||||
@@ -265,7 +265,7 @@ func machoCombineDwarf(ctxt *Link, inexe, dsym, outexe string) (bool, error) {
|
||||
}
|
||||
}
|
||||
// Do the final update of the DWARF segment's load command.
|
||||
return false, machoUpdateDwarfHeader(&reader, ctxt.BuildMode, compressedSects)
|
||||
return false, machoUpdateDwarfHeader(&reader, compressedSects, dwarfsize)
|
||||
}
|
||||
|
||||
// machoCompressSections tries to compress the DWARF segments in dwarfm,
|
||||
@@ -410,7 +410,7 @@ func machoUpdateSections(r loadCmdReader, seg, sect reflect.Value, deltaOffset,
|
||||
}
|
||||
|
||||
// machoUpdateDwarfHeader updates the DWARF segment load command.
|
||||
func machoUpdateDwarfHeader(r *loadCmdReader, buildmode BuildMode, compressedSects []*macho.Section) error {
|
||||
func machoUpdateDwarfHeader(r *loadCmdReader, compressedSects []*macho.Section, dwarfsize uint64) error {
|
||||
var seg, sect interface{}
|
||||
cmd, err := r.Next()
|
||||
if err != nil {
|
||||
@@ -428,7 +428,6 @@ func machoUpdateDwarfHeader(r *loadCmdReader, buildmode BuildMode, compressedSec
|
||||
}
|
||||
segv := reflect.ValueOf(seg).Elem()
|
||||
segv.FieldByName("Offset").SetUint(uint64(dwarfstart))
|
||||
segv.FieldByName("Addr").SetUint(uint64(dwarfaddr))
|
||||
|
||||
if compressedSects != nil {
|
||||
var segSize uint64
|
||||
@@ -436,23 +435,27 @@ func machoUpdateDwarfHeader(r *loadCmdReader, buildmode BuildMode, compressedSec
|
||||
segSize += newSect.Size
|
||||
}
|
||||
segv.FieldByName("Filesz").SetUint(segSize)
|
||||
segv.FieldByName("Memsz").SetUint(uint64(Rnd(int64(segSize), 1<<pageAlign)))
|
||||
} else {
|
||||
segv.FieldByName("Filesz").SetUint(dwarfsize)
|
||||
}
|
||||
|
||||
deltaOffset := uint64(dwarfstart) - realdwarf.Offset
|
||||
deltaAddr := uint64(dwarfaddr) - realdwarf.Addr
|
||||
|
||||
// If we set Memsz to 0 (and might as well set Addr too),
|
||||
// then the xnu kernel will bail out halfway through load_segment
|
||||
// and not apply further sanity checks that we might fail in the future.
|
||||
// We don't need the DWARF information actually available in memory.
|
||||
// But if we do this for buildmode=c-shared then the user-space
|
||||
// dynamic loader complains about memsz < filesz. Sigh.
|
||||
if buildmode != BuildModeCShared {
|
||||
segv.FieldByName("Addr").SetUint(0)
|
||||
segv.FieldByName("Memsz").SetUint(0)
|
||||
deltaAddr = 0
|
||||
}
|
||||
// We want the DWARF segment to be considered non-loadable, so
|
||||
// force vmaddr and vmsize to zero. In addition, set the initial
|
||||
// protection to zero so as to make the dynamic loader happy,
|
||||
// since otherwise it may complain that that the vm size and file
|
||||
// size don't match for the segment. See issues 21647 and 32673
|
||||
// for more context. Also useful to refer to the Apple dynamic
|
||||
// loader source, specifically ImageLoaderMachO::sniffLoadCommands
|
||||
// in ImageLoaderMachO.cpp (various versions can be found online, see
|
||||
// https://opensource.apple.com/source/dyld/dyld-519.2.2/src/ImageLoaderMachO.cpp.auto.html
|
||||
// as one example).
|
||||
segv.FieldByName("Addr").SetUint(0)
|
||||
segv.FieldByName("Memsz").SetUint(0)
|
||||
segv.FieldByName("Prot").SetUint(0)
|
||||
deltaAddr = 0
|
||||
|
||||
if err := r.WriteAt(0, seg); err != nil {
|
||||
return err
|
||||
|
||||
@@ -325,7 +325,7 @@ func (ctxt *Link) pclntab() {
|
||||
// set the resumption point to PC_B.
|
||||
lastWasmAddr = uint32(r.Add)
|
||||
}
|
||||
if r.Sym != nil && r.Sym.Name == "runtime.deferreturn" && r.Add == 0 {
|
||||
if r.Type.IsDirectJump() && r.Sym != nil && r.Sym.Name == "runtime.deferreturn" {
|
||||
if ctxt.Arch.Family == sys.Wasm {
|
||||
deferreturn = lastWasmAddr
|
||||
} else {
|
||||
|
||||
@@ -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,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"debug/macho"
|
||||
"internal/testenv"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@@ -171,3 +172,67 @@ main.x: relocation target main.zero not defined
|
||||
t.Fatalf("want:\n%sgot:\n%s", want, got)
|
||||
}
|
||||
}
|
||||
|
||||
var testMacOSVersionSrc = `
|
||||
package main
|
||||
func main() { }
|
||||
`
|
||||
|
||||
func TestMacOSVersion(t *testing.T) {
|
||||
testenv.MustHaveGoBuild(t)
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "TestMacOSVersion")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
src := filepath.Join(tmpdir, "main.go")
|
||||
err = ioutil.WriteFile(src, []byte(testMacOSVersionSrc), 0666)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
exe := filepath.Join(tmpdir, "main")
|
||||
cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-linkmode=internal", "-o", exe, src)
|
||||
cmd.Env = append(os.Environ(),
|
||||
"CGO_ENABLED=0",
|
||||
"GOOS=darwin",
|
||||
"GOARCH=amd64",
|
||||
)
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
t.Fatalf("%v: %v:\n%s", cmd.Args, err, out)
|
||||
}
|
||||
exef, err := os.Open(exe)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
exem, err := macho.NewFile(exef)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
found := false
|
||||
const LC_VERSION_MIN_MACOSX = 0x24
|
||||
checkMin := func(ver uint32) {
|
||||
major, minor := (ver>>16)&0xff, (ver>>8)&0xff
|
||||
if major != 10 || minor < 9 {
|
||||
t.Errorf("LC_VERSION_MIN_MACOSX version %d.%d < 10.9", major, minor)
|
||||
}
|
||||
}
|
||||
for _, cmd := range exem.Loads {
|
||||
raw := cmd.Raw()
|
||||
type_ := exem.ByteOrder.Uint32(raw)
|
||||
if type_ != LC_VERSION_MIN_MACOSX {
|
||||
continue
|
||||
}
|
||||
osVer := exem.ByteOrder.Uint32(raw[8:])
|
||||
checkMin(osVer)
|
||||
sdkVer := exem.ByteOrder.Uint32(raw[12:])
|
||||
checkMin(sdkVer)
|
||||
found = true
|
||||
break
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("no LC_VERSION_MIN_MACOSX load command found")
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -370,47 +370,6 @@ func TestVerifyHostname(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyHostnameResumed(t *testing.T) {
|
||||
t.Run("TLSv12", func(t *testing.T) { testVerifyHostnameResumed(t, VersionTLS12) })
|
||||
t.Run("TLSv13", func(t *testing.T) { testVerifyHostnameResumed(t, VersionTLS13) })
|
||||
}
|
||||
|
||||
func testVerifyHostnameResumed(t *testing.T, version uint16) {
|
||||
testenv.MustHaveExternalNetwork(t)
|
||||
|
||||
config := &Config{
|
||||
MaxVersion: version,
|
||||
ClientSessionCache: NewLRUClientSessionCache(32),
|
||||
}
|
||||
for i := 0; i < 2; i++ {
|
||||
c, err := Dial("tcp", "mail.google.com:https", config)
|
||||
if err != nil {
|
||||
t.Fatalf("Dial #%d: %v", i, err)
|
||||
}
|
||||
cs := c.ConnectionState()
|
||||
if i > 0 && !cs.DidResume {
|
||||
t.Fatalf("Subsequent connection unexpectedly didn't resume")
|
||||
}
|
||||
if cs.Version != version {
|
||||
t.Fatalf("Unexpectedly negotiated version %x", cs.Version)
|
||||
}
|
||||
if cs.VerifiedChains == nil {
|
||||
t.Fatalf("Dial #%d: cs.VerifiedChains == nil", i)
|
||||
}
|
||||
if err := c.VerifyHostname("mail.google.com"); err != nil {
|
||||
t.Fatalf("verify mail.google.com #%d: %v", i, err)
|
||||
}
|
||||
// Give the client a chance to read the server session tickets.
|
||||
c.SetReadDeadline(time.Now().Add(500 * time.Millisecond))
|
||||
if _, err := c.Read(make([]byte, 1)); err != nil {
|
||||
if err, ok := err.(net.Error); !ok || !err.Timeout() {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
c.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func TestConnCloseBreakingWrite(t *testing.T) {
|
||||
ln := newLocalListener(t)
|
||||
defer ln.Close()
|
||||
|
||||
@@ -16,7 +16,7 @@ package x509
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <Security/Security.h>
|
||||
|
||||
static bool isSSLPolicy(SecPolicyRef policyRef) {
|
||||
static Boolean isSSLPolicy(SecPolicyRef policyRef) {
|
||||
if (!policyRef) {
|
||||
return false;
|
||||
}
|
||||
@@ -24,13 +24,13 @@ static bool isSSLPolicy(SecPolicyRef policyRef) {
|
||||
if (properties == NULL) {
|
||||
return false;
|
||||
}
|
||||
Boolean isSSL = false;
|
||||
CFTypeRef value = NULL;
|
||||
if (CFDictionaryGetValueIfPresent(properties, kSecPolicyOid, (const void **)&value)) {
|
||||
CFRelease(properties);
|
||||
return CFEqual(value, kSecPolicyAppleSSL);
|
||||
isSSL = CFEqual(value, kSecPolicyAppleSSL);
|
||||
}
|
||||
CFRelease(properties);
|
||||
return false;
|
||||
return isSSL;
|
||||
}
|
||||
|
||||
// sslTrustSettingsResult obtains the final kSecTrustSettingsResult value
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -305,3 +305,6 @@ const (
|
||||
func LoadGetFinalPathNameByHandle() error {
|
||||
return procGetFinalPathNameByHandleW.Find()
|
||||
}
|
||||
|
||||
//sys CreateEnvironmentBlock(block **uint16, token syscall.Token, inheritExisting bool) (err error) = userenv.CreateEnvironmentBlock
|
||||
//sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock
|
||||
|
||||
@@ -58,6 +58,8 @@ var (
|
||||
procNetShareAdd = modnetapi32.NewProc("NetShareAdd")
|
||||
procNetShareDel = modnetapi32.NewProc("NetShareDel")
|
||||
procGetFinalPathNameByHandleW = modkernel32.NewProc("GetFinalPathNameByHandleW")
|
||||
procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock")
|
||||
procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock")
|
||||
procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf")
|
||||
procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
|
||||
procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
|
||||
@@ -220,6 +222,36 @@ func GetFinalPathNameByHandle(file syscall.Handle, filePath *uint16, filePathSiz
|
||||
return
|
||||
}
|
||||
|
||||
func CreateEnvironmentBlock(block **uint16, token syscall.Token, inheritExisting bool) (err error) {
|
||||
var _p0 uint32
|
||||
if inheritExisting {
|
||||
_p0 = 1
|
||||
} else {
|
||||
_p0 = 0
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall(procCreateEnvironmentBlock.Addr(), 3, uintptr(unsafe.Pointer(block)), uintptr(token), uintptr(_p0))
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func DestroyEnvironmentBlock(block *uint16) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procDestroyEnvironmentBlock.Addr(), 1, uintptr(unsafe.Pointer(block)), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ImpersonateSelf(impersonationlevel uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(impersonationlevel), 0, 0)
|
||||
if r1 == 0 {
|
||||
|
||||
@@ -194,83 +194,97 @@ len0:
|
||||
MOVD R2, c+56(FP)
|
||||
RET
|
||||
|
||||
|
||||
// func shlVU(z, x []Word, s uint) (c Word)
|
||||
// This implementation handles the shift operation from the high word to the low word,
|
||||
// which may be an error for the case where the low word of x overlaps with the high
|
||||
// word of z. When calling this function directly, you need to pay attention to this
|
||||
// situation.
|
||||
TEXT ·shlVU(SB),NOSPLIT,$0
|
||||
MOVD z+0(FP), R0
|
||||
MOVD z_len+8(FP), R1
|
||||
LDP z+0(FP), (R0, R1) // R0 = z.ptr, R1 = len(z)
|
||||
MOVD x+24(FP), R2
|
||||
MOVD s+48(FP), R3
|
||||
MOVD $0, R8 // in order not to affect the first element, R8 is initialized to zero
|
||||
MOVD $64, R4
|
||||
SUB R3, R4
|
||||
ADD R1<<3, R0 // R0 = &z[n]
|
||||
ADD R1<<3, R2 // R2 = &x[n]
|
||||
CBZ R1, len0
|
||||
CBZ R3, copy // if the number of shift is 0, just copy x to z
|
||||
|
||||
TBZ $0, R1, two
|
||||
MOVD.P 8(R2), R6
|
||||
LSR R4, R6, R8
|
||||
LSL R3, R6
|
||||
MOVD.P R6, 8(R0)
|
||||
MOVD $64, R4
|
||||
SUB R3, R4
|
||||
// handling the most significant element x[n-1]
|
||||
MOVD.W -8(R2), R6
|
||||
LSR R4, R6, R5 // return value
|
||||
LSL R3, R6, R8 // x[i] << s
|
||||
SUB $1, R1
|
||||
one: TBZ $0, R1, two
|
||||
MOVD.W -8(R2), R6
|
||||
LSR R4, R6, R7
|
||||
ORR R8, R7
|
||||
LSL R3, R6, R8
|
||||
SUB $1, R1
|
||||
MOVD.W R7, -8(R0)
|
||||
two:
|
||||
TBZ $1, R1, loop
|
||||
LDP.P 16(R2), (R6, R7)
|
||||
LSR R4, R6, R9
|
||||
LSL R3, R6
|
||||
ORR R8, R6
|
||||
LSR R4, R7, R8
|
||||
LDP.W -16(R2), (R6, R7)
|
||||
LSR R4, R7, R10
|
||||
ORR R8, R10
|
||||
LSL R3, R7
|
||||
ORR R9, R7
|
||||
STP.P (R6, R7), 16(R0)
|
||||
LSR R4, R6, R9
|
||||
ORR R7, R9
|
||||
LSL R3, R6, R8
|
||||
SUB $2, R1
|
||||
STP.W (R9, R10), -16(R0)
|
||||
loop:
|
||||
CBZ R1, done
|
||||
LDP.P 32(R2), (R10, R11)
|
||||
LDP -16(R2), (R12, R13)
|
||||
LSR R4, R10, R20
|
||||
LSL R3, R10
|
||||
ORR R8, R10 // z[i] = (x[i] << s) | (x[i-1] >> (64 - s))
|
||||
LSR R4, R11, R21
|
||||
LSL R3, R11
|
||||
ORR R20, R11
|
||||
LSR R4, R12, R22
|
||||
LSL R3, R12
|
||||
ORR R21, R12
|
||||
LSR R4, R13, R8
|
||||
LDP.W -32(R2), (R10, R11)
|
||||
LDP 16(R2), (R12, R13)
|
||||
LSR R4, R13, R23
|
||||
ORR R8, R23 // z[i] = (x[i] << s) | (x[i-1] >> (64 - s))
|
||||
LSL R3, R13
|
||||
ORR R22, R13
|
||||
STP.P (R10, R11), 32(R0)
|
||||
STP (R12, R13), -16(R0)
|
||||
LSR R4, R12, R22
|
||||
ORR R13, R22
|
||||
LSL R3, R12
|
||||
LSR R4, R11, R21
|
||||
ORR R12, R21
|
||||
LSL R3, R11
|
||||
LSR R4, R10, R20
|
||||
ORR R11, R20
|
||||
LSL R3, R10, R8
|
||||
STP.W (R20, R21), -32(R0)
|
||||
STP (R22, R23), 16(R0)
|
||||
SUB $4, R1
|
||||
B loop
|
||||
done:
|
||||
MOVD R8, c+56(FP) // the part moved out from the last element
|
||||
MOVD.W R8, -8(R0) // the first element x[0]
|
||||
MOVD R5, c+56(FP) // the part moved out from x[n-1]
|
||||
RET
|
||||
copy:
|
||||
CMP R0, R2
|
||||
BEQ len0
|
||||
TBZ $0, R1, ctwo
|
||||
MOVD.P 8(R2), R3
|
||||
MOVD.P R3, 8(R0)
|
||||
MOVD.W -8(R2), R4
|
||||
MOVD.W R4, -8(R0)
|
||||
SUB $1, R1
|
||||
ctwo:
|
||||
TBZ $1, R1, cloop
|
||||
LDP.P 16(R2), (R4, R5)
|
||||
STP.P (R4, R5), 16(R0)
|
||||
LDP.W -16(R2), (R4, R5)
|
||||
STP.W (R4, R5), -16(R0)
|
||||
SUB $2, R1
|
||||
cloop:
|
||||
CBZ R1, len0
|
||||
LDP.P 32(R2), (R4, R5)
|
||||
LDP -16(R2), (R6, R7)
|
||||
STP.P (R4, R5), 32(R0)
|
||||
STP (R6, R7), -16(R0)
|
||||
LDP.W -32(R2), (R4, R5)
|
||||
LDP 16(R2), (R6, R7)
|
||||
STP.W (R4, R5), -32(R0)
|
||||
STP (R6, R7), 16(R0)
|
||||
SUB $4, R1
|
||||
B cloop
|
||||
len0:
|
||||
MOVD $0, c+56(FP)
|
||||
RET
|
||||
|
||||
|
||||
// func shrVU(z, x []Word, s uint) (c Word)
|
||||
// This implementation handles the shift operation from the low word to the high word,
|
||||
// which may be an error for the case where the high word of x overlaps with the low
|
||||
// word of z. When calling this function directly, you need to pay attention to this
|
||||
// situation.
|
||||
TEXT ·shrVU(SB),NOSPLIT,$0
|
||||
MOVD z+0(FP), R0
|
||||
MOVD z_len+8(FP), R1
|
||||
@@ -330,6 +344,8 @@ done:
|
||||
MOVD R8, (R0) // deal with the last element
|
||||
RET
|
||||
copy:
|
||||
CMP R0, R2
|
||||
BEQ len0
|
||||
TBZ $0, R1, ctwo
|
||||
MOVD.P 8(R2), R3
|
||||
MOVD.P R3, 8(R0)
|
||||
|
||||
@@ -255,6 +255,75 @@ func TestFunVW(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
type argVU struct {
|
||||
d []Word // d is a Word slice, the input parameters x and z come from this array.
|
||||
l uint // l is the length of the input parameters x and z.
|
||||
xp uint // xp is the starting position of the input parameter x, x := d[xp:xp+l].
|
||||
zp uint // zp is the starting position of the input parameter z, z := d[zp:zp+l].
|
||||
s uint // s is the shift number.
|
||||
r []Word // r is the expected output result z.
|
||||
c Word // c is the expected return value.
|
||||
m string // message.
|
||||
}
|
||||
|
||||
var argshlVU = []argVU{
|
||||
// test cases for shlVU
|
||||
{[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0}, 7, 0, 0, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "complete overlap of shlVU"},
|
||||
{[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0, 0, 0, 0}, 7, 0, 3, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "partial overlap by half of shlVU"},
|
||||
{[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0, 0, 0, 0, 0, 0, 0}, 7, 0, 6, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "partial overlap by 1 Word of shlVU"},
|
||||
{[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0, 0, 0, 0, 0, 0, 0, 0}, 7, 0, 7, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "no overlap of shlVU"},
|
||||
}
|
||||
|
||||
var argshrVU = []argVU{
|
||||
// test cases for shrVU
|
||||
{[]Word{0, 3, _M, _M, _M, _M, _M, 1 << (_W - 1)}, 7, 1, 1, 1, []Word{1<<(_W-1) + 1, _M, _M, _M, _M, _M >> 1, 1 << (_W - 2)}, 1 << (_W - 1), "complete overlap of shrVU"},
|
||||
{[]Word{0, 0, 0, 0, 3, _M, _M, _M, _M, _M, 1 << (_W - 1)}, 7, 4, 1, 1, []Word{1<<(_W-1) + 1, _M, _M, _M, _M, _M >> 1, 1 << (_W - 2)}, 1 << (_W - 1), "partial overlap by half of shrVU"},
|
||||
{[]Word{0, 0, 0, 0, 0, 0, 0, 3, _M, _M, _M, _M, _M, 1 << (_W - 1)}, 7, 7, 1, 1, []Word{1<<(_W-1) + 1, _M, _M, _M, _M, _M >> 1, 1 << (_W - 2)}, 1 << (_W - 1), "partial overlap by 1 Word of shrVU"},
|
||||
{[]Word{0, 0, 0, 0, 0, 0, 0, 0, 3, _M, _M, _M, _M, _M, 1 << (_W - 1)}, 7, 8, 1, 1, []Word{1<<(_W-1) + 1, _M, _M, _M, _M, _M >> 1, 1 << (_W - 2)}, 1 << (_W - 1), "no overlap of shrVU"},
|
||||
}
|
||||
|
||||
func testShiftFunc(t *testing.T, f func(z, x []Word, s uint) Word, a argVU) {
|
||||
// save a.d for error message, or it will be overwritten.
|
||||
b := make([]Word, len(a.d))
|
||||
copy(b, a.d)
|
||||
z := a.d[a.zp : a.zp+a.l]
|
||||
x := a.d[a.xp : a.xp+a.l]
|
||||
c := f(z, x, a.s)
|
||||
for i, zi := range z {
|
||||
if zi != a.r[i] {
|
||||
t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot z[%d] = %#x; want %#x", b, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, i, zi, a.r[i])
|
||||
break
|
||||
}
|
||||
}
|
||||
if c != a.c {
|
||||
t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot c = %#x; want %#x", b, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, c, a.c)
|
||||
}
|
||||
}
|
||||
|
||||
func TestShiftOverlap(t *testing.T) {
|
||||
for _, a := range argshlVU {
|
||||
arg := a
|
||||
testShiftFunc(t, shlVU, arg)
|
||||
}
|
||||
|
||||
for _, a := range argshrVU {
|
||||
arg := a
|
||||
testShiftFunc(t, shrVU, arg)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssue31084(t *testing.T) {
|
||||
// compute 10^n via 5^n << n.
|
||||
const n = 165
|
||||
p := nat(nil).expNN(nat{5}, nat{n}, nil)
|
||||
p = p.shl(p, uint(n))
|
||||
got := string(p.utoa(10))
|
||||
want := "1" + strings.Repeat("0", n)
|
||||
if got != want {
|
||||
t.Errorf("shl(%v, %v)\n\tgot %s; want %s\n", p, uint(n), got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAddVW(b *testing.B) {
|
||||
for _, n := range benchSizes {
|
||||
if isRaceBuilder && n > 1e3 {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user