Switch the default to new object files.
Internal linking cgo is disabled for now, as it does not work yet
in newobj mode.
Shared libraries are also broken.
Disable some tests that are known broken for now.
Change-Id: I8ca74793423861d607a2aa7b0d89a4f4d4ca7671
Reviewed-on: https://go-review.googlesource.com/c/go/+/200161
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Third change of several to update the loader API to reflect the final
consensus version of the loader API as described in Cherry's doc.
This piece:
- move objfile.Loader into its own separate package, and update
clients accordingly.
This includes a few minor cleanups, including converting a couple
of loader-related functions to methods, and privatizing some of the
loader methods such as ToGlobal/ToLocal.
Change-Id: Iae20585751a45491d8b19dcffc096aadae6bbfc6
Reviewed-on: https://go-review.googlesource.com/c/go/+/200998
Run-TryBot: Than McIntosh <thanm@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Per Jeremy's comment in CL 199643. This makes the code read
better.
Change-Id: If270aecd712a27fb52e3faf5a4339200327d9ffe
Reviewed-on: https://go-review.googlesource.com/c/go/+/201023
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
A contentless data symbol may be a declaration of a cgo-imported
variable, e.g.
//go:cgo_import_dynamic xxx
var xxx uintptr
In this case, we want to mark the symbol imported, instead of
defined with zero value.
We used to load cgo directives before loading the object file, so
we'll mark the symbol SDYNIMPORT first. But in newobj mode,
currently we load cgo directives later. Letting SDYNIMPORT
overwrite contentless data symbol makes it work in both ordering.
Change-Id: I878f52086d6cdb5a347669bf8f848a49bce87b52
Reviewed-on: https://go-review.googlesource.com/c/go/+/201020
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
When a dupok symbol is resolved to another package, we still need
to record its presence in the current package, as the trampoline
pass expects packages are laid out in dependency order. At the
point after deadcode where we populate symbol contents for
reachable symbols (add relocations and read symbol data), make a
note of the dupok text symbols for each package. Later in
addToTextp we will visit packages in dependency order, process
the dup text symbol list for each package and select a final lib
for each dup text symbol.
Change-Id: Ib885e0a7e2343229d853aa629e3e337111df6011
Reviewed-on: https://go-review.googlesource.com/c/go/+/200797
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Add InlTree to the FuncInfo aux symbol in new object files.
In the linker, change InlinedCall.Func from a Symbol to a string,
as we only use its Name. (There was a use of Func.File, but that
use is not correct anyway.) So we don't need to create a Symbol
if not necessary.
Change-Id: I38ce568ae0934cd9cb6d0b30599f1c8d75444fc9
Reviewed-on: https://go-review.googlesource.com/c/go/+/200098
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
If two defined symbols have the same name, one contentless and
one with content, the one with content "wins". This is mainly for
go:linkname on data symbols. Support this logic in newobj mode.
Introduce an "overwrite" mechanism, letting one symbol overwrite
another. This machanism could later be used for the linker
overwriting symbol contents (e.g. -X flag).
Change-Id: I32ee7d4b82df275f11b38c3abefc99b878ff12d7
Reviewed-on: https://go-review.googlesource.com/c/go/+/200097
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Use the auxiliary symbol mechanism to connect the text symbol and
its associated DWARF symbols. This way, the linker can track the
DWARF symbols from the text symbol, without looking up special
names.
Currently, in the linker this is only used in the deadcode pass
to track which DWARF symbols are used and need to load. Later
passes still use name lookup for now.
Change-Id: I2fe49f3b1f0ecc1472ae8aa93907cff740022d8d
Reviewed-on: https://go-review.googlesource.com/c/go/+/199801
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
With the new object files, now we can run the deadcode pass on
indices instead of Symbol structs, so we can delay creating
Symbols after the deadcode pass. Then we only need to create
reachable symbols.
Not create Symbols in LoadNew and LoadRefs, and recombine
LoadReloc into LoadFull.
Split loadcgo into two parts: the first finds root symbols, the
second create Symbols and sets attributes. The first runs before
the deadcode pass, while the second runs after.
TODO: currently there are still symbols that are not marked
reachable but still used. This includes DWARF symbols, file
symbols, and type symbols that are referenced by DWARF symbols.
We still need to create them (conservatively).
Change-Id: I695779c9312be9d49ab1683957ac3e72e1f65a1e
Reviewed-on: https://go-review.googlesource.com/c/go/+/199643
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
The old code does this. Do the same.
Change-Id: Ibf32ac347d6425e19ad0bc664c6b43ab5eba9c5e
Reviewed-on: https://go-review.googlesource.com/c/go/+/201022
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
In CL 196030 we decided to combine the imported package list
(Autolib) and referenced package list (PkgIdx, or Pkglist).
However, in some cases the Autolib list may contain file name,
instead of package path, e.g.
https://go.googlesource.com/go/+/refs/heads/dev.link/src/cmd/compile/internal/gc/main.go#1181
And the linker needs that to locate the file. This mostly happens
with direct invocation of the compiler and linker (i.e., not
through "go build").
Instead of letting the linker make guess of the file name based
on the package path, make Autolib a separate list.
Change-Id: If195a69462d04db515346ee67cdec925f5a69e2e
Reviewed-on: https://go-review.googlesource.com/c/go/+/200157
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
On AIX, a TOC symbol always has a relocation to its target symbol.
Instead of using name lookup to locate the target symbol, we can
just use the relocation.
Using name lookup, besides being less efficient, needs to provide
the right symbol version. In this particular case, we are looking
for a data symbol so it is almost always version 0. But in case
that it is a text symbol, we may get an ABIALIAS symbol, which
does not have its Sect set.
Change-Id: I1ecfd284b04a86bbbc450059ee89d99d40493e51
Reviewed-on: https://go-review.googlesource.com/c/go/+/201019
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
On AIX, TOC symbols may be created and added to ctxt.Data
concurrently. To ensure reproducible builds, sort ctxt.Data.
This implements the same logic as WriteObjFile does for old
object files.
Change-Id: I2e6e2d7755352848981544a4fb68b828a188c2ca
Reviewed-on: https://go-review.googlesource.com/c/go/+/201021
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
When reflect.Type.Method is called, all exported methods from a
reachable type need to be conservatively live. When such a
function is called, the compiler sets an attribute to the
function, and the linker needs to check that attribute. Implement
this in the index-based deadcode pass.
Unify symbol flags and FuncInfo flags to make things simpler. In
particular, the deadcode pass can check the reflectMethod
attribute without reading in and decoding FuncInfo.
Change-Id: Ibb21e172f2996e899c6efa5551a29d0eca62df67
Reviewed-on: https://go-review.googlesource.com/c/go/+/200099
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
This essentially replicates the logic of live method tracking and
type symbol decoding, rewritten to operate on indices instead of
Symbols.
TODO: the special handling of reflect.Type.Method has not been
implemented.
TODO: the symbol name is used too much. It ought to be a better
way to do it.
Change-Id: I860ee7a506c00833902e4870d15aea698a705dd9
Reviewed-on: https://go-review.googlesource.com/c/go/+/199078
Reviewed-by: Than McIntosh <thanm@google.com>
We couldn't do this before because sighandler was compiled for nacl.
Updates #30439
Change-Id: Ieec9938b6a1796c48d251cd8b1db1a42c25f3943
Reviewed-on: https://go-review.googlesource.com/c/go/+/200739
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
NextPart has automatic handling of quoted-printable encoding,
which is sometimes undesirable. NextRawPart adds a method
for reading a part while bypassing such automatic handling.
Fixes#29090
Change-Id: I6a042a4077c64091efa3f5dbecce0d9a34ac7065
Reviewed-on: https://go-review.googlesource.com/c/go/+/152877
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
RFC 5322 date format allows CFWS after the timezone.
If CFWS is valid, it is discarded and parsing is done as before
using time.Parse().
Existing test is extended with limit cases and invalid strings.
Fixes#22661
Change-Id: I54b96d7bc384b751962a76690e7e4786217a7941
Reviewed-on: https://go-review.googlesource.com/c/go/+/117596
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This makes Decoder.offset public while renaming it to
Decoder.InputOffset to match encoding/xml Decoder API
Code changes made by Adam Stankiewicz [sheerun@sher.pl]
Fixes#29688
Change-Id: I86dbfd2b2da80160846e92bfa580c53d8d45e2db
Reviewed-on: https://go-review.googlesource.com/c/go/+/200677
Run-TryBot: Johan Brandhorst <johan.brandhorst@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Avoid an out-of-range error when calling LongString on a generic
block.
Change-Id: I33ca88940d899bc71e3155bc63d2aa925cf83230
Reviewed-on: https://go-review.googlesource.com/c/go/+/200737
Run-TryBot: Michael Munday <mike.munday@ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Update the new deadcode pass to use the revised loader interface
for querying relocations. Remove some of the previous loader relocation
methods, since they are no longer used.
Change-Id: I08cec4c05793a17698b2674068f64837a5bf4477
Reviewed-on: https://go-review.googlesource.com/c/go/+/200718
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Second change of several to update the loader API to reflect the final
consensus version of the loader API as described in Cherry's doc.
This piece:
- define new loader.Relocs() method that returns a struct
encapsulating a set of relocations on a global symbol
Old way of examining relocations:
nreloc := loader.NReloc(someGlobalSymbolIndex)
for i := 0; i < nreloc; i++ {
tgtIdx := loader.RelocSym(someGlobalSymbolIndex, i))
... <do something with tgtIdx>
}
New way of examining relocations:
relocs := d.loader.Relocs(someGlobalSymbolIndex)
for i := 0; i < relocs.Count; i++ {
r := relocs.At(i).Sym
... <do something with r.Sym>
}
Change-Id: I5bead1d729655ea13b3396647e53aafcd3e60f97
Reviewed-on: https://go-review.googlesource.com/c/go/+/200717
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Increases the exec timeout from 5sec to 1min, but
also print out the error value on any test failure.
Fixes#34836
Change-Id: Ida2b8bd460243491ef0f90dfe0f978dfe02a0703
Reviewed-on: https://go-review.googlesource.com/c/go/+/200519
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
We should keep a consistent way of formatting errors
in this file.
Fixes#34848
Change-Id: Ibb75908504f381fccab0281a42e788ef8c716b6f
Reviewed-on: https://go-review.googlesource.com/c/go/+/200679
Run-TryBot: Johan Brandhorst <johan.brandhorst@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Part 1: CL 199499 (GOOS nacl)
Part 2: CL 200077 (amd64p32 files, toolchain)
Part 3: stuff that arguably should've been part of Part 2, but I forgot
one of my grep patterns when splitting the original CL up into
two parts.
This one might also have interesting stuff to resurrect for any future
x32 ABI support.
Updates #30439
Change-Id: I2b4143374a253a003666f3c69e776b7e456bdb9c
Reviewed-on: https://go-review.googlesource.com/c/go/+/200318
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
The package references recorded in the object file, which are
obtained from the compiler, are escaped. We should also use the
escaped package paths in the linker for resolving package
references.
Change-Id: I42eb12df6ff24330e6dc7bed1dc8224bb3b8a106
Reviewed-on: https://go-review.googlesource.com/c/go/+/200158
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
This is the behavior of the old code. Do the same.
Change-Id: I3d393d754dcbdb7e76a577252a94214d2e316651
Reviewed-on: https://go-review.googlesource.com/c/go/+/200159
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
When the compiler's -S flag is specified, it dumps the
disassembly. Add this when writing the new style object file.
Change-Id: I4cf85e57d22d0ceea1fda6d3b59fe363573659e7
Reviewed-on: https://go-review.googlesource.com/c/go/+/200100
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Switch the deadcode pass to use indices instead of Symbol
structures when using new object file format. Delay loading
symbol relocations and contents fully after the deadcode pass.
The next step is not to create Symbol structures until deadcode
is done.
Method tracking logic hasn't been implemented. Currently, all
methods of a reachable type are live.
Change-Id: Iffcd06ff84e6e52bd9eb24d1220d94234d18ab6b
Reviewed-on: https://go-review.googlesource.com/c/go/+/198199
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
First change of several to update the loader API to reflect the final
consensus version of the loader API as described in Cherry's doc.
This piece:
- define new loader.Sym type to encapsulate a global symbol
index (as opposed to just using 'int')
Change-Id: I6f6483e269f80abfc7d373b2856b2c0d61b9ac24
Reviewed-on: https://go-review.googlesource.com/c/go/+/200417
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Also, in cmd/doc, avoid calling 'go list -m all' when in module mode
outside a module since it's now an error.
Fixes#32027
Change-Id: I7224c7fdf7e950bce6c058ab2a5837c27ba3b899
Reviewed-on: https://go-review.googlesource.com/c/go/+/200297
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
When unmarshaling to a map, the map's key type must either be a string,
an integer, or implement encoding.TextUnmarshaler. But for a user
defined type, reflect.Kind will not distinguish between the static type
and the underlying type. In:
var x MyString = "x"
t := reflect.TypeOf(x)
println(t.Kind() == reflect.String)
the Kind of x is still reflect.String, even though the static type of x
is MyString.
Moreover, checking for the map's key type is a string occurs first, so
even if the map key type MyString implements encoding.TextUnmarshaler,
it will be ignored.
To fix the bug, check for encoding.TextUnmarshaler first.
Fixes#34437
Change-Id: I780e0b084575e1dddfbb433fe03857adf71d05fb
Reviewed-on: https://go-review.googlesource.com/c/go/+/200237
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Compact has been inconsistently escaping only some problematic characters
(U+2028 and U+2029), but not others (<, > and &). This change addresses
this inconsistency by removing the escaping of U+2028 and U+2029.
Callers who need to escape the output of Compact should use HTMLEscape
which escapes <, >, &, U+2028 and U+2029.
Fixes#34070Fixes#30357
Updates #5836
Change-Id: Icfce7691d2b8b1d9b05ba7b64d2d1e4f3b67871b
GitHub-Last-Rev: 38859fe3e2
GitHub-Pull-Request: golang/go#34804
Reviewed-on: https://go-review.googlesource.com/c/go/+/200217
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
When in module mode outside of any module, 'go build' and most other
commands will now report an error instead of resolving a package path
to a module.
Previously, most commands would attempt to find the latest version of
a module providing the package. This could be very slow if many
packages needed to be resolved this way. Since there is no go.mod file
where module requirements can be saved, it's a repeatedly slow and
confusing experience.
After this change, 'go build' and other commands may still be used
outside of a module on packages in std and source files (.go
arguments) that only import packages in std. Listing any other package
on the command line or importing a package outside std will cause an
error.
'go get' is exempted from the new behavior, since it's expected that
'go get' resolves paths to modules at new versions.
Updates #32027
Change-Id: Ia9d3a3b4ad738ca5423472e17818d62b96a2c959
Reviewed-on: https://go-review.googlesource.com/c/go/+/198778
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
go/build.Import locates package dirctories using 'go list' when in
module mode (finding, downloading, and extracting modules is
complicated, so go/build does not handle it).
Previously, Import used 'go list' if GO111MODULE was not explicitly
off and a go.mod file was present (plus some other conditions). With
this change, if GO111MODULE is "on", a go.mod file does not need to be
present.
Fixes#34669
Change-Id: I9e56871054d4b07c3fc04b6f14a5c8c8e9f3c333
Reviewed-on: https://go-review.googlesource.com/c/go/+/199818
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
This is part two if the nacl removal. Part 1 was CL 199499.
This CL removes amd64p32 support, which might be useful in the future
if we implement the x32 ABI. It also removes the nacl bits in the
toolchain, and some remaining nacl bits.
Updates #30439
Change-Id: I2475d5bb066d1b474e00e40d95b520e7c2e286e1
Reviewed-on: https://go-review.googlesource.com/c/go/+/200077
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Some code tags in the HTML were not properly closed. Close them so that
the text is rendered correctly.
Change-Id: I5c2170ffced313417f65004d53518128c34f7979
Reviewed-on: https://go-review.googlesource.com/c/go/+/200117
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Change some decodetype functions to operate on bytes nstead of
Symbol. This is in preparation of implementing live method
tracking in index-based deadcode pass, and reducing/eliminating
sym.Symbol in general.
Change-Id: Ia9809ad7b182884225e1bda577e8dbec0cd216c5
Reviewed-on: https://go-review.googlesource.com/c/go/+/199077
Reviewed-by: Austin Clements <austin@google.com>
The dev.link branch was not sync'd with the new DWARF compilation
unit logic change on the master branch, and the new object file
format didn't support this.
This CL adds the new DWARF CU and file table support to the new
object file format. In the old object file, the DWARF file table
is a separate section. For now, we do the same with the new
object file, keeping it as a separate block.
While here, also refactor the loader code so it is easier for the
loader to carry per-object informations.
Change-Id: I4c317941fc0a5831acbc11ce8c2a8b7421471372
Reviewed-on: https://go-review.googlesource.com/c/go/+/198198
Reviewed-by: Austin Clements <austin@google.com>
With the old object file format, we use mmap (if supported) to
read object files and back symbol data with mapped read-only
memory.
Do the same with the new object file format. This also
significantly reduces number of syscalls made to read object
files.
Currently we still do mmap in object file level, not archive
level. This is probably ok, as there shouldn't be many archives
that contain more than one object. If this is a problem we can
change that later.
Change-Id: Icae3ef14d8ed6adbee1b5b48d420e2af22fd9604
Reviewed-on: https://go-review.googlesource.com/c/go/+/197797
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
This change introduces a new interface, load.ImportPathError. An error
may satisfy this by providing an ImportPath method and including the
import path in its error text. modload.ImportMissingError satisfies
this interface. load.ImportErrorf also provides a convenient way to
create an error satisfying this interface with an arbitrary message.
When load.PackageError formats its error text, it may omit the last
path on the import stack if the wrapped error satisfies
ImportPathError and has a matching path.
To make this work, PackageError.Err is now an error instead of a
string. PackageError.MarshalJSON will write Err as a string for
'go list -json' output.
When go/build.Import invokes 'go list' in module mode, it now runs
with '-e' and includes '.Error' in the output format instead of
expecting the error to be in the raw stderr text. If a package error
is printed and a directory was not found, the error will be returned
without extra decoration.
Fixes#34752
Change-Id: I2d81dab7dec19e0ae9f51f6412bc9f30433a8596
Reviewed-on: https://go-review.googlesource.com/c/go/+/199840
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>