1
0
mirror of https://github.com/golang/go synced 2024-11-05 17:36:15 -07:00
Commit Graph

189 Commits

Author SHA1 Message Date
Rob Pike
e239f1b3f2 go.tools/cmd/vet: don't check for shadowing of blank identifier
It's pointless.
Also this fixes a crash, because the blank identifier no longer appears as a
defined object after CL 74190043 so we were getting nil pointer violations.
Even better, we get to re-enable a disabled test.

LGTM=gri
R=gri
CC=golang-codereviews
https://golang.org/cl/75140043
2014-03-13 10:27:55 +11:00
Robert Griesemer
ea79d922e6 go.tools/go/vet: temporarily disable some tests to fix build
Revert this CL once a proper fix is in place.

LGTM=adonovan
R=r, adonovan
CC=golang-codereviews
https://golang.org/cl/74930043
2014-03-12 11:56:25 -07:00
Rob Pike
6bd3206b1f go.tools/cmd/vet: allow checks to be disabled explicitly as well as set explicitly
Now we can say
        vet -printf=false
to disable the printf test but run all others.
Implemented by creating a tri-state boolean flag that records whether it has been
set explicitly; before this, -printf=false was not distinguishable from not having
mentioned the printf flag at all.

Fixes golang/go#7422.

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/72330043
2014-03-07 16:02:49 +11:00
Rob Pike
95c9b7bad1 go.tools/cmd/vet: replace warnings by errors
Over time, a number of modules were added that used Warn instead of Bad
to report problems with the code, but the documentation states that
if there is a problem, the exit code must be 1, not 0. Warn does not set the
exit code and should be used only for internal errors and messages
triggered by the -v flag.

There's nothing substantive here except calling the other function in a few
places.

Fixes golang/go#7017.

LGTM=crawshaw
R=golang-codereviews, crawshaw
CC=golang-codereviews
https://golang.org/cl/71860044
2014-03-07 15:31:28 +11:00
Rob Pike
31c219bef7 go.tools/cmd/vet: change reporting of incorrect error count in Printf
The old code was misleading in saying how many args were present.
Change the wording of the message to be unambiguous and change
the presentation of the format to include the full directive, making
it easier to correlate with the input (and fixing a silent bug).
Fixes golang/go#6248.

LGTM=dsymonds
R=golang-codereviews, dsymonds
CC=golang-codereviews
https://golang.org/cl/69120044
2014-03-04 15:41:49 +11:00
David du Colombier
ec0de5a8bc go.tools/cmd/godoc: fix test on Plan 9
LGTM=bradfitz
R=minux.ma, bradfitz
CC=golang-codereviews
https://golang.org/cl/70610044
2014-03-02 19:34:05 +01:00
Alan Donovan
ced954c167 go.tools/go/types: split Info.Objects map into Defs and Uses.
An identifier X in anonymous struct field struct{X} is both a
definition of a field (*Var) and reference to a type
(*TypeName).  Now that we have split the map, we can capture
both of these aspects.

Interestingly, every client but one was going to extra effort
to iterate over just the uses or just the defs; this
simplifies them.

Also, fix two bug related to tagless switches:
- An entry was being recorded in the Object map for a piece of
  synthetic syntax.
- The "true" identifier was being looked up in the current scope,
  which allowed perverse users to locally redefine it.  Now
  we use the bool (not untyped boolean) constant true, per the
  consequent clarification of the spec (issue 7404).

+ tests.

Fixes golang/go#7276

LGTM=gri
R=gri
CC=golang-codereviews
https://golang.org/cl/68270044
2014-02-27 13:21:59 -05:00
Brad Garcia
aaca3a4f95 godoc: Remove bogus messages referring to "/target".
Fix package text display spacing.
Fixes golang/go#7395.

R=bradfitz, sameer
CC=golang-codereviews
https://golang.org/cl/68210043
2014-02-26 13:21:44 -05:00
Rob Pike
ee3eeefaa3 cmd/vet: check for nil result set in isStringer
Fixes golang/go#7149.

LGTM=gri
R=golang-codereviews, gri
CC=golang-codereviews
https://golang.org/cl/68260044
2014-02-24 11:39:42 -08:00
Rob Pike
cde4d316d2 go.tools/cmd/vet: docs: explain the command line interface better
How it handles packages vs. directories vs. files was not explained.

LGTM=rsc
R=golang-codereviews, gobot, rsc
CC=golang-codereviews
https://golang.org/cl/67150043
2014-02-24 10:44:02 -08:00
David du Colombier
374c600cae go.tools/cmd/vet: disable TestVet on Plan 9
LGTM=minux.ma
R=golang-codereviews, minux.ma
CC=golang-codereviews
https://golang.org/cl/64410043
2014-02-20 21:43:24 +01:00
Josh Bleecher Snyder
e8c291b808 go.tools/cmd/benchcmp: sort by original benchmark order by default
benchcmp now preserves benchmark order. This restores the original
misc/benchcmp behavior. This also makes the output of benchcmp stable,
and groups together multiple -cpu results.

Magnitude-based sorting is still available via the -mag flag.
It is useful for surfacing items of note (particularly changes
in allocs) when making compiler changes and running broad
benchmarks.

Fixes golang/go#7259.

LGTM=dave
R=dave, mtj
CC=bradfitz, dvyukov, golang-codereviews
https://golang.org/cl/60840045
2014-02-19 07:44:49 -08:00
Andrew Gerrand
47596b4b81 go.tools/cmd/vet: add stable checks to doc.go
These are the simplest possible descriptions of each command.
They may be fleshed out later.

Fixes golang/go#7298.

LGTM=r
R=r
CC=golang-codereviews
https://golang.org/cl/61480044
2014-02-13 11:05:01 +11:00
Brad Fitzpatrick
05bc285da4 cmd/goimports: update doc, remove old gofmt flags
Don't say the word "fork" (not accurate), and remove the
tab/comment flags that were removed from gofmt.

LGTM=adg
R=golang-codereviews, adg
CC=golang-codereviews
https://golang.org/cl/61410052
2014-02-12 08:35:02 -08:00
Alan Donovan
08fadac071 go.tools/go/loader: simplify command-line syntax.
Previously, each word could be a package import path or a
comma-separated list of *.go file names.  Now, if the
first word ends with ".go", all words are assumed to be
Go source files.  This makes it impossible to specify
two ad-hoc packages from source files, but no-one needs that.

FromArgs also takes a boolean indicating whether tests
are wanted or not.

Also: ssadump: add -test flag to set that boolean.
For the oracle it's always true.

LGTM=gri
R=gri
CC=golang-codereviews
https://golang.org/cl/61470047
2014-02-11 16:52:16 -05:00
Alan Donovan
1f29e74bfa go.tools/go/types: remove Type.MethodSet() method.
Method-set caching is now performed externally using a MethodSetCache (if desired), not by the Types themselves.

This a minor deoptimization due to the extra maps, but avoids a situation in which method-sets are computed and frozen prematurely. (See b/7114)

LGTM=gri
R=gri
CC=golang-codereviews
https://golang.org/cl/61430045
2014-02-11 16:49:27 -05:00
Robert Griesemer
20efc5ba73 go.tools/go/types: use init cycle tracking for all const and var cycles
Also rename types.Assertable -> types.AssertableTo per adonovan.

LGTM=adonovan
R=adonovan
CC=golang-codereviews
https://golang.org/cl/59680044
2014-02-03 16:02:56 -08:00
Robert Griesemer
4dcaee97b2 go.tools/cmd/vet: use new Assertable predicate (fix build)
LGTM=r
R=r
CC=golang-codereviews
https://golang.org/cl/59210045
2014-02-03 11:39:10 -08:00
Josh Bleecher Snyder
285f6fe2f6 go.tools/cmd/benchcmp: add benchcmp
This is intended to replace the awk-based misc/benchcmp.
It mostly matches the existing misc/benchcmp.
Notable changes:

* Written in Go.
* Minor whitespace changes in the output; the tabular nature of the
  output is preserved, as is most number formatting and verbiage.
* Comparisons within each section are sorted from highest change to lowest.
* Proper handling of multiple benchmarks with the same name (issue 7016).
* Does not omit benchmark comparisons for which the new value is zero.
* Adds -changed flag to only show benchmarks whose value have changed.
  Useful for memory-oriented, large-scale benchmark comparisons.
* Has tests.
* Formats small ns measurements with extra precision.

Updates golang/go#7016.

LGTM=r
R=golang-codereviews, dave, dvyukov, oleku.konko, bradfitz, gobot, r
CC=golang-codereviews
https://golang.org/cl/47980043
2014-01-31 15:39:59 -08:00
Brad Garcia
d682175c6e godoc: test fixes for recent cmdline changes.
Tests broken by:
https://code.google.com/p/go/source/detail?r=1666da2583f4&repo=tools

R=gri, adonovan
CC=golang-codereviews
https://golang.org/cl/58780043
2014-01-30 15:32:23 -05:00
Brad Garcia
f97ec06d2c godoc: forward /pkg/C links to /cmd/cgo.
Fixes golang/go#5651.

R=bradfitz
CC=golang-codereviews
https://golang.org/cl/58660043
2014-01-30 07:07:12 -05:00
Alan Donovan
64ec206bfd go.tools/go/types: combine Info.{Types,Values} maps.
This results in significant improvement to type-checking time:
it reduces by 4% the entire running time of ssa/stdlib_test
(GOMAXPROCS=8, n=7).

LGTM=gri
R=gri
CC=golang-codereviews
https://golang.org/cl/57770043
2014-01-28 16:46:24 -05:00
Robert Griesemer
ebfa4efbc4 go.tools/go/types: cleanup: more consistent exported predicate names
Renamed predicates:
IsIdentical -> Identical
IsAssignableTo -> AssignableTo
Signature.IsVariadic -> Signature.Variadic
Object.IsExported -> Object.Exported

LGTM=adonovan
R=adonovan
CC=golang-codereviews
https://golang.org/cl/53370043
2014-01-28 10:57:56 -08:00
Alan Donovan
3fc0fc1310 go.tools: rename packages.
Was:		Now:
ssa		go/ssa
importer	go/loader
pointer		go/pointer

Next CL: call -> go/callgraph (requires more care)

R=gri, crawshaw
CC=golang-codereviews
https://golang.org/cl/52960043
2014-01-16 09:33:58 -05:00
Alan Donovan
e8afbfad8c go.tools/importer: API rethink.
The Importer type has been replaced with Config and Program.

Clients populate a Config, directly or more usually via
convenience functions.  They then call its Load() method to do
all of the typechecking and transitive-closure computation.

ssa.NewProgram and ssa.CreatePackages have been fused into
ssa.Create, which now cannot fail, since (*Config).Load()
reports all type errors.

Also:
- The addition of an ssa.GlobalDebug builder mode flag
  eliminates a loop-over-packages repeated in many clients.
- PackageInfo.Err flag unexported.  Clients never see bad infos now.
- cmd/ssadump: now only looks for func "main" in package "main".
- importsOf deleted, was dead code.

STILL TODO:
- ParseFile seems like API creep (though it's convenient)
  and CreateFromFiles is dangerous (w.r.t. FileSet identity).
  Need to think more...
- the need for clients to rely on elementwise correspondence
  of Config.CreatePkgs and Program.Created is a little sad.
- The command-line interface has not changed.
  That will happen in a follow-up.
  r recommends using a repeated flag: -package p -package q ...

R=gri
CC=axwalk, frederik.zipp, golang-codereviews
https://golang.org/cl/49530047
2014-01-15 21:37:55 -05:00
Alan Donovan
3d82e7e94a go.tools/ssa: fix crash in SSA builder when using GCImporter to satisfy imports (ssadump -build=G).
Packages were not being created for all types.Packages,
specifically, indirectly imported packages were missing.
(*Program).CreatePackages now iterates over the type-checker's
package map too.

Also: removed all concurrency from importer.  I think it was
incorrect (and hard to fix).

Also: change LoadInitialPackages so that all named packages
are loaded from source.  This happens regardless of whether
GCImporter is used to satisfy imports.

Details:
- importer.Config.SourceImports flag determines whether to
  load all packages from *.go source.
  (Before, this was indicated by Config.Build != nil.)
- importer.Config.Build field effectively defaults to
  &go/build.Default.  A zero importer.Config is now usable.
- importer.Importer.Config field is now exported.
- LoadPackage renamed to ImportPackage since the resulting
  packages may come from GCImporter (and be incomplete).
- doImport and ImportPackage fused.

Fixes golang/go#7028

R=gri, axwalk
CC=golang-codereviews
https://golang.org/cl/48770043
2014-01-09 14:11:54 -05:00
Peter Collingbourne
d0b88d2206 cmd/gotype: add -gccgo flag
R=gri
CC=golang-codereviews, golang-dev
https://golang.org/cl/39050043
2014-01-08 15:25:17 -08:00
Alan Donovan
5612f0615f go.tools/ssa: use correct word size for GOARCH during type checking, interpretation.
Also report an error for "cross-interpretation": not supported
due to the interpreter's assumption that host and target
{int,uint,uintptr} are the same.  (Too tedious and messy to fix.)

Tested manually:

% cat d.go
package main
const m = ^uintptr(0)
const w = m>>8&1 + m>>16&1 + m>>32&1
func main() { println(m, w) }

% ./ssadump -build=P -run d.go
package main:
  const m          m = 18446744073709551615:uintptr
  const w          w = 3:uintptr
18446744073709551615 3

% GOARCH=386 ./ssadump -build=P -run d.go
package main:
  const m          m = 4294967295:uintptr
  const w          w = 2:uintptr
Error: Cross-interpretation is not yet supported (target has GOARCH 386, interpreter has amd64).

Fixes golang/go#7080

R=gri
CC=golang-codereviews
https://golang.org/cl/49070043
2014-01-08 14:46:17 -05:00
Brad Garcia
a28efa5d8c godoc: add ability to change or disable the display of search results.
The display of search results can now be changed. A slice of functions for displaying the results can now be provided.  By default, three functions are provided to display documentation, source code, and textual results.
This makes it possible to replace them with equivalents that, say,
obtain search results from alternative source code search engines.

R=bradfitz, adg
CC=golang-codereviews
https://golang.org/cl/43470043
2014-01-06 09:51:01 -05:00
Pavel Zinovkin
3658622d3e go.tools/cmd/goimports: Fixed url
R=golang-codereviews, bradfitz
CC=golang-codereviews
https://golang.org/cl/40610046
2014-01-02 11:02:13 -08:00
Andrew Gerrand
efcc5ffb58 go.tools/cmd/goimports: rename README to doc.go
README is a GitHub thing. Let's do the godoc thing.

R=golang-dev, crawshaw
CC=golang-dev
https://golang.org/cl/44030046
2013-12-20 09:26:26 +11:00
Rob Pike
bae6bf6180 go.tools/cmd/vet: improve error message for build tag problems
Fixes golang/go#6979.

R=golang-dev, dave, iant
CC=golang-dev
https://golang.org/cl/37720048
2013-12-18 16:06:56 -08:00
David Crawshaw
c87866116c go.tools/imports: move goimports from github to go.tools.
From revision d0880223588919729793727c9d65f202a73cda77.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/35850048
2013-12-17 21:21:03 -05:00
Brad Fitzpatrick
59db975409 godoc: limit concurrency to local disk filesystem
Not for Go 1.2.  Still needs a flag.

Linux at least (and likely other OSes) don't like you doing
a few hundred readdirs at once and spawing as many threads.

R=golang-dev, adg, jeremyjackins
CC=golang-dev
https://golang.org/cl/30620043
2013-12-16 11:25:50 -08:00
Alan Donovan
8b9d1fd507 go.tools/oracle: implements: now shows whole-program implements relation for selected type.
(Previously it showed the implements relation for all types within the query package.)

R=crawshaw
CC=golang-dev
https://golang.org/cl/42000043
2013-12-13 18:00:55 -05:00
Alan Donovan
f119874203 go.tools/oracle: improvements to command set and performance.
Command set:
- what: an extremely fast query that parses a single
  file and returns the AST stack, package name and the
  set of query modes that apply to the current selection.
  Intended for GUI tools that need to grey out UI elements.
- definition: shows the definition of an identifier.
- pointsto: the PTA features of 'describe' have been split
  out into their own command.
- describe: with PTA stripped out, the cost is now bounded by
  type checking.

Performance:
- The importer.Config.TypeCheckFuncBodies predicate supports
  setting the 'IgnoreFuncBodies' typechecker flag on a
  per-package basis.  This means we can load dependencies from
  source more quickly if we only need exported types.
  (We avoid gcimport data because it may be absent or stale.)
  This also means we can run type-based queries on packages
  that aren't part of the pointer analysis scope. (Yay.)
- Modes that require only type analysis of the query package
  run a "what" query first, and restrict their analysis scope
  to just that package and its dependencies (sans func
  bodies), making them much faster.
- We call newOracle not oracle.New in Query, so that the
  'needs' bitset isn't ignored (oops!).  This makes the
  non-PTA queries faster.

Also:
- removed vestigial timers junk.
- pos.go: existing position utilties split out into own file.
  Added parsePosFlag utility.
- numerous cosmetic tweaks.

+ very basic tests.

To do in follow-ups:
- sophisticated editor integration of "what".
- better tests.
- refactoring of control flow as described in comment.
- changes to "implements", "describe" commands.
- update design doc + user manual.

R=crawshaw, dominik.honnef
CC=golang-dev, gri
https://golang.org/cl/40630043
2013-12-13 10:04:55 -05:00
Josh Bleecher Snyder
866b24e166 cmd/vet: check for sync types being copied during function calls
Using a type containing a sync type directly
in a function call (whether as a receiver,
a param, or a return value) is an easy way
to accidentally copy a lock or other sync primitive.
Check for it.

The test as implemented does not provide 100%
coverage; see the discussion near the bottom of
testdata/copylock.go for shortcomings.

Fixes golang/go#6729.

R=adg, r, dsymonds
CC=golang-dev
https://golang.org/cl/23420043
2013-12-09 20:14:28 -08:00
Andrew Wilkins
df34f98521 go.tools/cover: split parsing code out from cmd/cover
Split the profile parsing code out of cmd/cover into
a reusable package, to support third-party coverage
tools.

R=golang-dev, r, adg
CC=golang-dev
https://golang.org/cl/36050045
2013-12-03 20:55:21 -08:00
Shenghou Ma
5d386107a0 go.tools/cmd/oracle: output help messages to stderr for consistency
Fixes golang/go#6838.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/36820043
2013-12-03 17:37:59 -05:00
Brad Garcia
f3faf8b6e0 godoc: add search results that point to documentation instead of source.
Add explicit options to Corpus to control search indexing of documentation, Go source code, and full-text.

R=bradfitz, r
CC=golang-dev
https://golang.org/cl/24190043
2013-11-21 11:55:42 -05:00
Brad Garcia
b844907f9f godoc: refactor command-line mode handling.
R=bradfitz
CC=golang-dev
https://golang.org/cl/29230044
2013-11-20 09:56:10 -05:00
Robert Griesemer
27563ff576 go.tools/go/types: move gcimporter to its own package
- fixed a couple of TODOs
- various cleanups along the way
- adjusted clients

Once submitted, clients of go/types that don't explicitly
specify Config.Import will need to add the extra import:

import _ "code.google.com/p/go.tools/go/gcimporter"

to install the default (gc) importer in go/types.

R=adonovan, gri
CC=golang-dev
https://golang.org/cl/26390043
2013-11-14 14:11:43 -08:00
Brad Fitzpatrick
626e9341d5 godoc: add forgotten file from last CL to fix build
R=adg, franciscossouza, dave
CC=golang-dev
https://golang.org/cl/25650043
2013-11-12 15:46:25 -08:00
Robert Griesemer
7b183d1766 go.tools/go/types, cmd/gotype: fix early bailout
Clients must have chance to look at panics they
are raising.

R=adonovan
CC=golang-dev
https://golang.org/cl/23820043
2013-11-08 12:52:57 -08:00
Robert Griesemer
0c141425f6 go.tools/cmd/gotype: parse in parallel
Performance increase is much smaller than expected;
need to investigate. Possibly, repeatedly (for each
line) accessing file sets from multiple goroutines
(in the scanner) is a bottle neck; or perhaps i/o.

R=adonovan
CC=golang-dev
https://golang.org/cl/23090043
2013-11-07 13:32:02 -08:00
Rob Pike
2afbb1cd5f go.tools/cmd/vet: handle symbolic TEXT annotations
The symbolic names such as NOSPLIT for annotations on the TEXT
directive appeared after vet started checking .s files. This CL tweaks
the regular expression to allow CAPITALS and the symbols | and +
as well as digits in that field, and interprets NOSPLIT as equivalent
to 7 in that field. All magic.

Fixes golang/go#6695

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/18700044
2013-11-01 11:49:11 -07:00
Robert Griesemer
03e3f0cf81 go.tools/cmd/gotype: make gotype use go/build
This CL makes gotype usable again. Removed -r
(recursive) mode; use go/build to determine
the correct set of Go files when processing
a directory. The -v (verbose) mode now prints
some basic stats (duration, number of files,
lines, and lines/s).

Thoroughly restructured the code.

Applying gotype -v -a . to the go/types directory:
128.94141ms (40 files, 12008 lines, 93127 lines/s)

On a 2.8 GHz Quad-Core Intel Xeon, 800 MHz DDR2 FB-DIMM,
with go/types built with the (interal) debug flag set to
false. There's still quite a bit of room for performance
improvement in all parts of the code since no tuning has
been done.

R=golang-dev, adonovan
CC=golang-dev
https://golang.org/cl/19930043
2013-10-31 10:01:58 -07:00
Alan Donovan
8636f40baf go.tools/ssa: CreateTestMainPackage: synthesize test driver as a package ("testmain") not 'main' function.
This allows us to run/analyze multiple tests.
Also it causes the production code packages to be properly initialized.

Also:
- cmd/ssadump: improved usage message (add example;
  incorporate LoadInitialPackages usage; explain how -run
  finds main).
- pointer, oracle, ssa/interp: use CreateTestMainPackage.
- ssa/builder.go: remove 'rundefers' instruction from package init,
  which no longer uses 'defer'.

R=gri
CC=golang-dev
https://golang.org/cl/15920047
2013-10-23 18:07:53 -04:00
Andrew Gerrand
36c288d6d7 go.tools/cmd/godoc: search go.tools/cmd before $GOROOT/cmd
Fixes golang/go#6527.

R=rsc
CC=golang-dev
https://golang.org/cl/14725043
2013-10-18 10:42:41 +09:00
Alan Donovan
2accef29d7 go.tools/ssa: implement correct control flow for recovered panic.
A function such as this:
        func one() (x int) {
                defer func() { recover() }()
                x = 1
                panic("return")
        }
that combines named return parameters (NRPs) with deferred calls
that call recover, may return non-zero values despite the
fact it doesn't even contain a return statement. (!)

This requires a change to the SSA API: all functions'
control-flow graphs now have a second entry point, called
Recover, which is the block at which control flow resumes
after a recovered panic.  The Recover block simply loads the
NRPs and returns them.

As an optimization, most functions don't need a Recover block,
so it is omitted.  In fact it is only needed for functions that
have NRPs and defer a call to another function that _may_ call
recover.

Dataflow analysis of SSA now requires extra work, since every
may-panic instruction has an implicit control-flow edge to
the Recover block.  The only dataflow analysis so far implemented
is SSA renaming, for which we make the following simplifying
assumption: the Recover block only loads the NRPs and returns.
This means we don't really need to analyze it, we can just
skip the "lifting" of such NRPs.  We also special-case the Recover
block in the dominance computation.

Rejected alternative approaches:
- Specifying a Recover block for every defer instruction (like a
   traditional exception handler).
   This seemed like excessive generality, since Go programs
   only need the same degenerate form of Recover block.
- Adding an instruction to set the Recover block immediately
   after the named return values are set up, so that dominance
   can be computed without special-casing.
   This didn't seem worth the effort.

Interpreter:
- This CL completely reimplements the panic/recover/
  defer logic in the interpreter.  It's clearer and simpler
  and closer to the model in the spec.
- Some runtime panic messages have been changed to be closer
  to gc's, since tests depend on it.
- The interpreter now requires that the runtime.runtimeError
  type be part of the SSA program.  This requires that clients
  import this package prior to invoking the interpreter.
  This in turn requires (Importer).ImportPackage(path string),
  which this CL adds.
- All $GOROOT/test/recover{,1,2,3}.go tests are now passing.

NB, the bug described in coverage.go (defer/recover in a concatenated
init function) remains.  Will be fixed in a follow-up.

Fixes golang/go#6381

R=gri
CC=crawshaw, golang-dev
https://golang.org/cl/13844043
2013-10-14 15:38:56 -04:00