Most platforms only use a single MOV const operand - remove the MOV{B,H,W}const
operands from riscv64 and consistently use MOVDconst instead. The implementation
of all four is the same and there is no benefit gained from having multiple const
operands (in fact it requires a lot more rewrite rules).
Change-Id: I0ba7d7554e371a1de762ef5f3745e9c0c30d41ac
Reviewed-on: https://go-review.googlesource.com/c/go/+/302610
Trust: Joel Sing <joel@sing.id.au>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Michael Munday <mike.munday@lowrisc.org>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
This CL adds rewrite rules for CSETM, CSINC, CSINV, and CSNEG. By adding
these rules, we can save one instruction.
For example,
func test(cond bool, a int) int {
if cond {
a++
}
return a
}
Before:
MOVD "".a+8(RSP), R0
ADD $1, R0, R1
MOVBU "".cond(RSP), R2
CMPW $0, R2
CSEL NE, R1, R0, R0
After:
MOVBU "".cond(RSP), R0
CMPW $0, R0
MOVD "".a+8(RSP), R0
CSINC EQ, R0, R0, R0
This patch is a copy of CL 285694. Co-authored-by: JunchenLi
<junchen.li@arm.com>
Change-Id: Ic1a79e8b8ece409b533becfcb7950f11e7b76f24
Reviewed-on: https://go-review.googlesource.com/c/go/+/302231
Trust: fannie zhang <Fannie.Zhang@arm.com>
Run-TryBot: fannie zhang <Fannie.Zhang@arm.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Don't eagerly record the target type for an untyped operand if the
target type is just one of possibly many types in the type list of
a type parameter. Instead, record expression type only after we
checked that all types in the type list are ok.
Also, update assertion in Checker.recordTypeAndValue since (currently),
a type parameter is not considered a const type. We may change that,
eventually.
This is a temporary (but working) solution. Eventually we should
copy the approach taken in go/types.
Fixes#45096.
Change-Id: Icf61ee893aca6ead32bfc45ee5831572e672357b
Reviewed-on: https://go-review.googlesource.com/c/go/+/302755
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
This verifies that issue #45096 is not an issue for go/types.
Updates #45096.
Change-Id: I4e987b5d4928f0c864d0d2c0379149443beb4d5c
Reviewed-on: https://go-review.googlesource.com/c/go/+/302754
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
The getentropy syscall is available on macOS since version 10.12, which
is the minimum required version since Go 1.15.
Change-Id: I294259af0b11df9669e4dc5fa891d2f2f039d91a
Reviewed-on: https://go-review.googlesource.com/c/go/+/302489
Trust: Tobias Klauser <tobias.klauser@gmail.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Change-Id: I207541efa6a34bc21e7a00584376622b59e2bf6d
Reviewed-on: https://go-review.googlesource.com/c/go/+/302749
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Then, write the 'go.mod' file with that version before further
processing. That way, if the command errors out due to a change in
behavior, the reason for the change in behavior will be visible in the
file diffs.
If the 'go.mod' file cannot be written (due to -mod=readonly or
-mod=vendor), assume Go 1.11 instead of the current Go release.
(cmd/go has added 'go' directives automatically, including in 'go mod
init', since Go 1.12.)
For #44976
Change-Id: If9d4af557366f134f40ce4c5638688ba3bab8380
Reviewed-on: https://go-review.googlesource.com/c/go/+/302051
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
Currently we print a cryptic message if a C compiler doesn't exist.
This patch adds more graceful handling.
Fixes#44271
Change-Id: I44f16ef6eb2853fee22fa1d996e41ec6c9ee82f1
Reviewed-on: https://go-review.googlesource.com/c/go/+/301249
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Change-Id: Ibbed54239228e7ea31ef5978d427425899c3b943
Reviewed-on: https://go-review.googlesource.com/c/go/+/300890
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Trust: Baokun Lee <bk@golangcn.org>
Change-Id: Ie52d70d2ae8a21acacf0745a4093650b03ac43f9
Reviewed-on: https://go-review.googlesource.com/c/go/+/302371
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This CL resurrects the clobberdead debugging mode (CL 23924).
When -clobberdead flag is set (TODO: make it GOEXPERIMENT?), the
compiler inserts code that clobbers all dead stack slots that
contains pointers.
Mark windows syscall functions cgo_unsafe_args, as the code
actually does that, by taking the address of one argument and
passing it to cgocall.
Change-Id: Ie09a015f4bd14ae6053cc707866e30ae509b9d6f
Reviewed-on: https://go-review.googlesource.com/c/go/+/301791
Trust: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
tryResolve is an extremely hot method on the parser. Eliminating this
formatting led to a 20% performance improvement in BenchmarkParse.
Change-Id: Idf8850404bd72d45d1351356427a85086422ea68
Reviewed-on: https://go-review.googlesource.com/c/go/+/302629
Trust: Robert Findley <rfindley@google.com>
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
For Builtin ops, we currently stay with using the old
typechecker to transform the call to a more specific expression
and possibly use more specific ops. However, for a bunch of the
ops, we delay calling the old typechecker if any of the args have
type params, for a variety of reasons.
In the near future, we will start creating separate functions that do
the same transformations as the old typechecker for calls, builtins,
indexing, comparisons, etc. These functions can then be called at noder
time for nodes with no type params, and at stenciling time for nodes
with type params.
Remove unnecessary calls to types1 typechecker for most kinds of
statements (still need it for SendStmt, AssignStmt, ReturnStmt, and
SelectStmt). In particular, we don't need it for RangeStmt, and this
avoids some complaints by the types1 typechecker on generic code.
Other small changes:
- Fix check on whether to delay calling types1-typechecker on type
conversions. Should check if HasTParam is true, rather than if the
type is directly a TYPEPARAM.
- Don't call types1-typechecker on an indexing operation if the left
operand has a typeparam in its type and is not obviously a TMAP,
TSLICE, or TARRAY. As above, we will eventually have to create a new
function that can do the required transformations (for complicated
cases) at noder time or stenciling time.
- Copy n.BuiltinOp in subster.node()
- The complex arithmetic example in absdiff.go now works.
- Added new tests double.go and append.go
- Added new example with a new() call in settable.go
Change-Id: I8f377afb6126cab1826bd3c2732aa8cdf1f7e0b4
Reviewed-on: https://go-review.googlesource.com/c/go/+/301951
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
This will be reintroduced again once the source of the
flakiness has been determined and fixed.
Fixes#45084
Change-Id: I6677b27fcd71e8c9bb8edbe8e3be70e5a271ebd3
Reviewed-on: https://go-review.googlesource.com/c/go/+/302569
Trust: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Trust: Katie Hockman <katie@golang.org>
Run-TryBot: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Run-TryBot: Katie Hockman <katie@golang.org>
Reviewed-by: Katie Hockman <katie@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
The existing implementation of user.LookupGroupId function works
incorrectly with very large (>64K symbols) entries in /etc/group file.
This patch fixes this.
Fixes#43636
Change-Id: I453321f1ab15fd4d0002f97fcec7d0789e1e0da5
Reviewed-on: https://go-review.googlesource.com/c/go/+/283601
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Trust: Emmanuel Odeke <emmanuel@orijtech.com>
Change-Id: I7df915978af3488f46a27595a1b04d0d33f81f7b
Reviewed-on: https://go-review.googlesource.com/c/go/+/302369
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
The changes between (equivalent, and reviewed) go/types/call.go
and call.go can be seen by comparing patchset 1 and 2. The actual
changes are removing the "// UNREVIEWED" marker, renaming of
sig_params to sigParams, and a couple of comment adjustments.
These additional changes reduce the difference between this
file and the go/types version.
Note that the verification pass using a MethodSet doesn't
exist because there's no MethodSet in types2.
Change-Id: I4d49460e0457401ed705dff5cfd17c9ff259d89f
Reviewed-on: https://go-review.googlesource.com/c/go/+/300998
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Static tmps are private to a package, but with plugins a package
can be shared among multiple DSOs. They need to have a consistent
view of the static tmps, especially for writable ones. So export
them. (Read-only static tmps have the same values anyway, so it
doesn't matter. Also Mach-O doesn't support dynamically exporting
read-only symbols anyway.)
Fixes#44956.
Change-Id: I921e25b7ab73cd5d5347800eccdb7931e3448779
Reviewed-on: https://go-review.googlesource.com/c/go/+/301793
Trust: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Update some symbol references after refactoring.
Change-Id: I134eec453b69efae97eb8a13e52ff8c14d38442a
Reviewed-on: https://go-review.googlesource.com/c/go/+/301790
Trust: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
The assember uses R15 as scratch space when assembling global variable
references in dynamically linked code. If the assembly code uses the
clobbered value of R15, report an error. The user is probably expecting
some other value in that register.
Getting rid of the R15 use isn't very practical (we could save a
register to a field in the G maybe, but that gets cumbersome).
Fixes#43661
Change-Id: I43f848a3d8b8a28931ec733386b85e6e9a42d8ff
Reviewed-on: https://go-review.googlesource.com/c/go/+/283474
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
(I needed this to debug an accidental infinite-recursion I introduced
while revising CL 293689.)
Fixes#38768
Change-Id: I306122f15b5bbd2fc5e836b32fd4dd5992ea891e
Reviewed-on: https://go-review.googlesource.com/c/go/+/302052
Trust: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
In Go1.13 and above, signed integers are permitted as shift counts as long as they are >=0.
However, the comments in the "Arithmetic operators" section says shift operators accept "unsigned integer" as of right operands. Replacing this with "integer>=0" resolves the misunderstanding that shift
operators permit only unsigned integers.
Reference: Go1.13 Release Notes: https://golang.org/doc/go1.13
Change-Id: Icd3c7734d539ab702590e992a618c9251c653c37
GitHub-Last-Rev: 4f263a48d3
GitHub-Pull-Request: golang/go#44664
Reviewed-on: https://go-review.googlesource.com/c/go/+/297249
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
Trust: Emmanuel Odeke <emmanuel@orijtech.com>
Trust: Robert Griesemer <gri@golang.org>
Code generation for open defers failed to account for
presence of method receiver and thus was OFF BY ONE.
Fixes#45062.
Updates #44816.
Updates #40724.
Change-Id: Ia90ea8fd0f7d823e1f757c406f9127136c2ffdd2
Reviewed-on: https://go-review.googlesource.com/c/go/+/302249
Trust: David Chase <drchase@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Repair of CL 300749.
ALSO:
found evidence that stack maps for bodyless methods are wrong.
gofmt in test/abi
removed never-executed code in types/size.go
Updates #44816.
Updates #40724.
Change-Id: Ifeb5fee60f60e7c7b58ee0457f58a3265d6cf3f6
Reviewed-on: https://go-review.googlesource.com/c/go/+/302071
Trust: David Chase <drchase@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Ignore an embedded type in an interface which is the predeclared
interface "comparable" (which currently can only be in a type
constraint), since the name doesn't resolve and the "comparable" type
doesn't have any relevant methods (for the purposes of the compiler).
Added new test case graph.go that needs this fix.
Change-Id: I2443d2c3dfeb9d0a78aaaaf91a2808ae2759d247
Reviewed-on: https://go-review.googlesource.com/c/go/+/301831
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Preserve program header flags when passing them through loadelf.Load.
They shouldn't be coerced to 0 on non-ARM platforms which set them
such as ppc64le.
Change-Id: I022613356f910d812de2fc22eac949960eeb53b3
Reviewed-on: https://go-review.googlesource.com/c/go/+/300950
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Emmanuel Odeke <emmanuel@orijtech.com>
Adds the (*tls.Conn).HandshakeContext method. This allows
us to pass the context provided down the call stack to
eventually reach the tls.ClientHelloInfo and
tls.CertificateRequestInfo structs.
These contexts are exposed to the user as read-only via Context()
methods.
This allows users of (*tls.Config).GetCertificate and
(*tls.Config).GetClientCertificate to use the context for
request scoped parameters and cancellation.
Replace uses of (*tls.Conn).Handshake with (*tls.Conn).HandshakeContext
where appropriate, to propagate existing contexts.
Fixes#32406
Change-Id: I259939c744bdc9b805bf51a845a8bc462c042483
Reviewed-on: https://go-review.googlesource.com/c/go/+/295370
Run-TryBot: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Katie Hockman <katie@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
For #36460
Change-Id: I63596e1c95d0c702073cdb016579598d79cc95ef
Reviewed-on: https://go-review.googlesource.com/c/go/+/300158
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
This was causing test failures while revising CL 293689: splitting the
roots out from the rest of the module graph may allow 'go list -e' to
proceed even when the rest of the module graph can't be loaded (e.g.
due to missing go.mod checksums). If that occurs, it becomes more
important that the moduleInfo helper function itself avoid fetching
unchecked files.
For #36460
Change-Id: I088509eeb3008cc6e8bfe85a00ec2bf500bf9423
Reviewed-on: https://go-review.googlesource.com/c/go/+/301371
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
For #36460
Change-Id: Ia8633f37aec8c7ed532bf7278867251e5e2a4285
Reviewed-on: https://go-review.googlesource.com/c/go/+/301370
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
Accepts comma "," as a separator for fractional seconds
hence we now accept:
* 2006-01-02 15:04:05,999999999 -0700 MST
* Mon Jan _2 15:04:05,120007 2006
* Mon Jan 2 15:04:05,120007 2006
This change follows the recommendations of ISO 8601 per
https://en.wikipedia.org/wiki/ISO_8601#cite_note-26
which states
ISO 8601:2004(E), ISO, 2004-12-01, "4.2.2.4 ...
the decimal fraction shall be divided from the integer
part by the decimal sign specified in ISO 31-0, i.e.
the comma [,] or full stop [.]. Of these, the comma
is the preferred sign."
Unfortunately, I couldn't directly access the ISO 8601 document
because suddenly it is behind a paywall on the ISO website,
charging CHF 158 (USD 179) for 38 pages :-(
However, this follows publicly available cited literature, as well
as the recommendations from the proposal approval.
Fixes#6189
Updates #27746
Updates #26002
Updates #36145
Updates #43813Fixes#43823
Change-Id: Ibe96064e8ee27c239be78c880fa561a1a41e190c
Reviewed-on: https://go-review.googlesource.com/c/go/+/300996
Trust: Emmanuel Odeke <emmanuel@orijtech.com>
Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com>
Reviewed-by: Rob Pike <r@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Since we cannot change the signature of reflect.ArrayOf to return an
error, we panic instead of producing a wrong result.
Fixes#43603
Change-Id: I23915df8d190f35af4d00ab86768868cd621e839
Reviewed-on: https://go-review.googlesource.com/c/go/+/284136
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com>
TryBot-Result: Go Bot <gobot@golang.org>
Using 0.0.0.0 for ListenUDP listens on all addresses. Calling LocalAddr
on that Conn returns 0.0.0.0. Sending to 0.0.0.0 doesn't seem to work on
Windows. See #22827.
Change-Id: I4a48fbabe65a63e07600a65309977cec08a9c1e5
Reviewed-on: https://go-review.googlesource.com/c/go/+/301850
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Trust: Filippo Valsorda <filippo@golang.org>
This reverts commit 8ed438c077, CL 300749.
Reason for revert: Looks like it crashes on link-register architectures
Change-Id: I0c261df58900008cada3359889d2a87508158447
Reviewed-on: https://go-review.googlesource.com/c/go/+/302053
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
ALSO:
found evidence that stack maps for bodyless methods are wrong.
gofmt in test/abi
removed never-executed code in types/size.go
Updates #44816.
Change-Id: I658c33f049337fb6f1e625f0c55430d25bfa877e
Reviewed-on: https://go-review.googlesource.com/c/go/+/300749
Trust: David Chase <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Added test example orderedmap.go (binary search tree) that requires this
fix (calling function compare in _Map).
Also added new tests slices.go and metrics.go that just work.
Change-Id: Ifa5f42ab6eee9aa54c40f0eca19e00a87f8f608a
Reviewed-on: https://go-review.googlesource.com/c/go/+/301829
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Add support for maps in subster.typ(). Add new test cases maps.go and set.go.
Change substitution of a TFUNC in subster.typ() to always create new
param and result structs if any of the receiver, param, or result
structs get substituted. All these func structs must be copied, because
they have offset fields that are dependent, and so must have an
independent copy for each new signature (else there will be an error
later when frame offsets are calculated).
Change-Id: I576942a62f06b46b6f005abc98f65533008de8dc
Reviewed-on: https://go-review.googlesource.com/c/go/+/301670
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Add support for channels in subster.typ(). Add new test file chans.go.
To support assignability of bidirectional channel args to directional
channel params, I needed to type check generic calls after they are
instantiated. (Eventually, we will create separate functions to just do
the assignability logic, so we don't need to call the old typechecker in
this case.) So, for generic calls, we now leave the call as OCALL (as a
signal that the call still needs typechecking), and do typecheck.Call()
during stenciling.
Smaller changes:
- Set the type of an instantiated OCLOSURE node (and not just the associated
OFUNC node)
- In instTypeName2, filter out the space that types2.TypeString inserts
after a common in a typelist. Our standard naming requires no space
after the comma.
- With the assignability fix above, I no longer need the explicit
conversions in cons.go.
Change-Id: I148858bfc6708c0aa3f50bad7debce2b8c8c091f
Reviewed-on: https://go-review.googlesource.com/c/go/+/301669
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>