Compare commits

...

59 Commits

Author SHA1 Message Date
Chris Broadfoot
2a5f65a98c [release-branch.go1.8] go1.8rc3
Change-Id: Ie306bb5355f56113356fc141f3c1a56872b39f9e
Reviewed-on: https://go-review.googlesource.com/35836
Reviewed-by: Chris Broadfoot <cbro@golang.org>
2017-01-26 17:42:08 +00:00
Chris Broadfoot
2f6c20b46c [release-branch.go1.8] all: merge master into release-branch.go1.8
78860b2ad2 cmd/go: don't reject ./... matching top-level file outside GOPATH
2b283cedef database/sql: fix race when canceling queries immediately
1cf08182f9 go/printer: fix format with leading comments in composite literal
b531eb3062 runtime: reorder modules so main.main comes first
165cfbc409 database/sql: let tests wait for db pool to come to expected state
ea73649343 doc: update gccgo docs
1db16711f5 doc: clarify what to do with Go 1.4 when installing from source
3717b429f2 doc: note that plugins are not fully baked
98842cabb6 net/http: don't send body on redirects for 301, 302, 303 when GetBody is set
314180e7f6 net/http: fix a nit
aad06da2b9 cmd/link: mark DWARF function symbols as reachable
be9dcfec29 doc: mention testing.MainStart signature change
a96e117a58 runtime: amd64, use 4-byte ops for memmove of 4 bytes
4cce27a3fa cmd/compile: fix constant propagation through s390x MOVDNE instructions
1be957d703 misc/cgo/test: pass current environment to syscall.Exec
ec654e2251 misc/cgo/test: fix test when using GCC 7
256a605faa cmd/compile: don't use nilcheck information until the next block
e8d5989ed1 cmd/compile: fix compilebench -alloc
ea7d9e6a52 runtime: check for nil g and m in msanread

Change-Id: I61d508d4f0efe4b72e7396645c8ad6088d2bfa6e
2017-01-26 09:24:31 -08:00
Ian Lance Taylor
78860b2ad2 cmd/go: don't reject ./... matching top-level file outside GOPATH
This unwinds a small part of CL 31668: we now accept "./." in cleanImport.

Fixes #18778.

Change-Id: Ia7f1fde1cafcea3cc9e0b597a95a0e0bb410a3ed
Reviewed-on: https://go-review.googlesource.com/35646
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
2017-01-26 14:41:37 +00:00
Daniel Theophanes
2b283cedef database/sql: fix race when canceling queries immediately
Previously the following could happen, though in practice it would
be rare.

Goroutine 1:
	(*Tx).QueryContext begins a query, passing in userContext

Goroutine 2:
	(*Tx).awaitDone starts to wait on the context derived from the passed in context

Goroutine 1:
	(*Tx).grabConn returns a valid (*driverConn)
	The (*driverConn) passes to (*DB).queryConn

Goroutine 3:
	userContext is canceled

Goroutine 2:
	(*Tx).awaitDone unblocks and calls (*Tx).rollback
	(*driverConn).finalClose obtains dc.Mutex
	(*driverConn).finalClose sets dc.ci = nil

Goroutine 1:
	(*DB).queryConn obtains dc.Mutex in withLock
	ctxDriverPrepare accepts dc.ci which is now nil
	ctxCriverPrepare panics on the nil ci

The fix for this is to guard the Tx methods with a RWLock
holding it exclusivly when closing the Tx and holding a read lock
when executing a query.

Fixes #18719

Change-Id: I37aa02c37083c9793dabd28f7f934a1c5cbc05ea
Reviewed-on: https://go-review.googlesource.com/35550
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-01-26 06:25:37 +00:00
Robert Griesemer
1cf08182f9 go/printer: fix format with leading comments in composite literal
This fix is less pervasive than it seems. The only change affecting
formatting is on printer.go:760. The remaining changes have no effect
on formatting since the value of p.level is ignored except on this
specific line.

The remaining changes are:
- renamed adjBlock to funcBody since that's how it is used
- introduced new printer field 'level' tracking the composite
  literal nesting level
- update/restore the composite literal nesting level as needed

Fixes #18782.

Change-Id: Ie833a9b5a559c4ec0f2eef2c5dc97aa263dca53a
Reviewed-on: https://go-review.googlesource.com/35811
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-01-26 00:06:54 +00:00
David Crawshaw
b531eb3062 runtime: reorder modules so main.main comes first
Modules appear in the moduledata linked list in the order they are
loaded by the dynamic loader, with one exception: the
firstmoduledata itself the module that contains the runtime.
This is not always the first module (when using -buildmode=shared,
it is typically libstd.so, the second module).

The order matters for typelinksinit, so we swap the first module
with whatever module contains the main function.

Updates #18729

This fixes the test case extracted with -linkshared, and now

	go test -linkshared encoding/...

passes. However the original issue about a plugin failure is not
yet fixed.

Change-Id: I9f399ecc3518e22e6b0a350358e90b0baa44ac96
Reviewed-on: https://go-review.googlesource.com/35644
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Michael Hudson-Doyle <michael.hudson@canonical.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-01-25 22:33:57 +00:00
Daniel Theophanes
165cfbc409 database/sql: let tests wait for db pool to come to expected state
Slower builders were failing TestQueryContext because the cancel
and return to conn pool happens async. TestQueryContext already
uses a wait method for this reason. Use the same method for
other context tests.

Fixes #18759

Change-Id: I84cce697392b867e4ebdfadd38027a06ca14655f
Reviewed-on: https://go-review.googlesource.com/35750
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-01-25 21:57:28 +00:00
Ian Lance Taylor
ea73649343 doc: update gccgo docs
Update docs on correspondence between Go releases and GCC releases.

Update C type that corresponds to Go type `int`.

Drop out of date comments about Ubuntu and RTEMS.

Change-Id: Ic1b5ce9f242789af23ec3b7e7a64c9d257d6913e
Reviewed-on: https://go-review.googlesource.com/35631
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-01-24 21:21:59 +00:00
Ian Lance Taylor
1db16711f5 doc: clarify what to do with Go 1.4 when installing from source
You have to actually run make.bash (or make.bat).

Update #18771.

Change-Id: Ie6672a4e4abde0150c1ae57cabb1222de2c78716
Reviewed-on: https://go-review.googlesource.com/35632
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-01-24 21:03:41 +00:00
Brad Fitzpatrick
3717b429f2 doc: note that plugins are not fully baked
Change-Id: I6341b8cce0b4a9922928f73f8b459cbb9ec25e79
Reviewed-on: https://go-review.googlesource.com/35571
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
2017-01-24 20:10:28 +00:00
Brad Fitzpatrick
98842cabb6 net/http: don't send body on redirects for 301, 302, 303 when GetBody is set
The presence of Request.GetBody being set on a request was causing all
redirected requests to have a body, even if the redirect status didn't
warrant one.

This bug came from 307/308 support (https://golang.org/cl/29852) which
removed the line that set req.Body to nil after POST/PUT redirects.

Change-Id: I2a4dd5320f810ae25cfd8ea8ca7c9700e5dbd369
Reviewed-on: https://go-review.googlesource.com/35633
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
2017-01-24 19:56:23 +00:00
Mikio Hara
314180e7f6 net/http: fix a nit
Change-Id: I31fa5f906ad2e8dc475dbbeb91f568f91e16861b
Reviewed-on: https://go-review.googlesource.com/35514
Run-TryBot: Mikio Hara <mikioh.mikioh@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-01-24 16:48:33 +00:00
Ian Lance Taylor
aad06da2b9 cmd/link: mark DWARF function symbols as reachable
Otherwise we don't emit any required ELF relocations when doing an
external link, because elfrelocsect skips unreachable symbols.

Fixes #18745.

Change-Id: Ia3583c41bb6c5ebb7579abd26ed8689370311cd6
Reviewed-on: https://go-review.googlesource.com/35590
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2017-01-24 03:37:56 +00:00
Brad Fitzpatrick
be9dcfec29 doc: mention testing.MainStart signature change
Fixes #18766

Change-Id: Ic0f72f3b7bbccd0546692993c4ed414f8c88c1c6
Reviewed-on: https://go-review.googlesource.com/35573
Reviewed-by: Russ Cox <rsc@golang.org>
2017-01-24 00:28:27 +00:00
Keith Randall
a96e117a58 runtime: amd64, use 4-byte ops for memmove of 4 bytes
memmove used to use 2 2-byte load/store pairs to move 4 bytes.
When the result is loaded with a single 4-byte load, it caused
a store to load fowarding stall.  To avoid the stall,
special case memmove to use 4 byte ops for the 4 byte copy case.

We already have a special case for 8-byte copies.
386 already specializes 4-byte copies.
I'll do 2-byte copies also, but not for 1.8.

benchmark                 old ns/op     new ns/op     delta
BenchmarkIssue18740-8     7567          4799          -36.58%

3-byte copies get a bit slower.  Other copies are unchanged.
name         old time/op   new time/op   delta
Memmove/3-8   4.76ns ± 5%   5.26ns ± 3%  +10.50%  (p=0.000 n=10+10)

Fixes #18740

Change-Id: Iec82cbac0ecfee80fa3c8fc83828f9a1819c3c74
Reviewed-on: https://go-review.googlesource.com/35567
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2017-01-23 19:39:22 +00:00
Michael Munday
4cce27a3fa cmd/compile: fix constant propagation through s390x MOVDNE instructions
The constant propagation rules selected the wrong operand to
propagate. So MOVDNE (move if not equal) propagated operands as if
it were a MOVDEQ (move if equal).

Fixes #18735.

Change-Id: I87ac469172f9df7d5aabaf7106e2936ce54ae202
Reviewed-on: https://go-review.googlesource.com/35498
Run-TryBot: Michael Munday <munday@ca.ibm.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-01-21 03:20:55 +00:00
Ian Lance Taylor
1be957d703 misc/cgo/test: pass current environment to syscall.Exec
This is needed for typical tests with gccgo, as it passes the
LD_LIBRARY_PATH environment variable to the new program.

Change-Id: I9bf4b0dbdff63f5449c7fcb8124eaeab10ed7f34
Reviewed-on: https://go-review.googlesource.com/35481
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-01-20 21:12:54 +00:00
Ian Lance Taylor
ec654e2251 misc/cgo/test: fix test when using GCC 7
With GCC 7 (not yet released), cgo fails with errors like

./sigaltstack.go:65:8: call of non-function C.restoreSignalStack

I do not know precisely why. Explicitly declaring that there are no
arguments to the static function is a simple fix for the debug info.

Change-Id: Id96e1cb1e55ee37a9f1f5ad243d7ee33e71584ac
Reviewed-on: https://go-review.googlesource.com/35480
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-01-20 21:12:19 +00:00
Keith Randall
256a605faa cmd/compile: don't use nilcheck information until the next block
When nilcheck runs, the values in a block are not in any particular
order.  So any facts derived from examining the blocks shouldn't be
used until we reach the next block.

This is suboptimal as it won't eliminate nil checks within a block.
But it's probably a better fix for now as it is a much smaller change
than other strategies for fixing this bug.

nilptr3.go changes are mostly because for this pattern:
  _ = *p
  _ = *p
either nil check is fine to keep, and this CL changes which one
the compiler tends to keep.
There are a few regressions from code like this:
  _ = *p
  f()
  _ = *p
For this pattern, after this CL we issue 2 nil checks instead of one.
(For the curious, this happens because intra-block nil check
 elimination now falls to CSE, not nilcheck proper.  The former
 pattern has two nil checks with the same store argument.  The latter
 pattern has two nil checks with different store arguments.)

Fixes #18725

Change-Id: I3721b494c8bc9ba1142dc5c4361ea55c66920ac8
Reviewed-on: https://go-review.googlesource.com/35485
Reviewed-by: Cherry Zhang <cherryyz@google.com>
2017-01-20 20:21:55 +00:00
Josh Bleecher Snyder
e8d5989ed1 cmd/compile: fix compilebench -alloc
pprof.WriteHeapProfile is shorthand for
pprof.Lookup("heap").WriteTo(f, 0).
The second parameter is debug.
If it is non-zero, pprof writes legacy-format
pprof output, which compilebench can parse.

Fixes #18641

Change-Id: Ica69adeb9809e9b5933aed943dcf4a07910e43fc
Reviewed-on: https://go-review.googlesource.com/35484
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-01-20 18:57:23 +00:00
Bryan C. Mills
ea7d9e6a52 runtime: check for nil g and m in msanread
fixes #18707.

Change-Id: Ibc4efef01197799f66d10bfead22faf8ac00473c
Reviewed-on: https://go-review.googlesource.com/35452
Run-TryBot: Bryan Mills <bcmills@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-01-19 23:06:54 +00:00
Chris Broadfoot
59f181b6fd [release-branch.go1.8] go1.8rc2
Change-Id: Ifcf2e13b962aa10280df8ca76cb21b37e3533f8f
Reviewed-on: https://go-review.googlesource.com/35475
Run-TryBot: Chris Broadfoot <cbro@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-01-19 20:58:37 +00:00
Chris Broadfoot
d18087cb25 [release-branch.go1.8] all: merge master into release-branch.go1.8
6593d8650d go/ast: fix Object's doc comment about Data
c1730ae424 runtime: force workers out before checking mark roots
d10eddcba3 testing: make parallel t.Run safe again
2c8b70eacf crypto/x509: revert SystemCertPool implementation for Windows
fcfd91858b doc/go1.8: document Plan 9 requirements
81a61a96c9 runtime: for plugins, don't add duplicate itabs
f674537cc9 README.md: update and simplify
d8711919db cmd/go: fix bug help message
48d8edb5b2 crypto/tls: disable CBC cipher suites with SHA-256 by default
92ecd78933 cmd/compile: add ZeroWB case in writebarrier
787125abab doc: 2017 is the Year of the Gopher
5b708a6b6a cmd/compile: lvalues are only required for == when calling runtime fns
e83d506714 vendor/golang_org/x/crypto/poly1305: revendor to pick up fix for #18673
76f981c8d8 net/http: skip TestServerHijackGetsBackgroundByte on Plan 9
e395e3246a net/http: skip TestServerHijackGetsBackgroundByte_big on Plan 9
6a3c6c0de8 net/http: add another hijack-after-background-read test
467109bf56 all: test adjustments for the iOS builder
b2a3b54b95 net/http: make sure Hijack's bufio.Reader includes pre-read background byte
593ea3b360 cmd/go, misc: rework cwd handling for iOS tests
0642b8a2f1 syscall: export Fsid.X__val on s390x
4601eae6ba doc/gdb: mention GOTRACEBACK=crash
4c4c5fc7a3 misc/cgo/testplugin: test that types and itabs are unique
22689c4450 reflect: keep makeFuncImpl live across makeFuncStub
9cf06ed6cd cmd/link: only exclude C-only symbols on darwin
9c3630f578 compress/flate: avoid large stack growth in fillDeflate
4f0aac52d9 cmd/go: add comment about SIGUSR2 on iOS
333f764df3 cmd/go, misc: switch from breakpoint to SIGUSR2
39e31d5ec0 doc/go1.8: update timezone database version
08da8201ca misc/cgo/testshared: test that types and itabs are unique
fdde7ba2a2 runtime: avoid clobbering C callee-save register in cgoSigtramp
f65abf6ddc cmd/compile: hide testdclstack behind debug flag
641ef2a733 compress/gzip: skip TestGZIPFilesHaveZeroMTimes on non-builders
0724aa813f crypto/dsa: gofmt
ac05542985 net/http: deflake TestRetryIdempotentRequestsOnError
b842c9aac7 doc: remove inline styles

Change-Id: I642c056732fe1e8081e9d73e086e38ea0b2568cc
2017-01-19 12:36:53 -08:00
Hironao OTSUBO
6593d8650d go/ast: fix Object's doc comment about Data
The doc comment about the Data field of go/ast.Object reflects its old
behavior, from when the go/types typechecker depended on ast.Objects.

Since when the doc was written, the behavior has changed in
https://golang.org/cl/7058060 and https://golang.org/cl/7096048 .

Fixes #18631

Change-Id: I10fc3e31cfbf7b303eec44150df917f6eb285f90
Reviewed-on: https://go-review.googlesource.com/35075
Reviewed-by: Robert Griesemer <gri@golang.org>
2017-01-19 04:55:19 +00:00
Austin Clements
c1730ae424 runtime: force workers out before checking mark roots
Currently we check that all roots are marked as soon as gcMarkDone
decides to transition from mark 1 to mark 2. However, issue #16083
indicates that there may be a race where we try to complete mark 1
while a worker is still scanning a stack, causing the root mark check
to fail.

We don't yet understand this race, but as a simple mitigation, move
the root check to after gcMarkDone performs a ragged barrier, which
will force any remaining workers to finish their current job.

Updates #16083. This may "fix" it, but it would be better to
understand and fix the underlying race.

Change-Id: I1af9ce67bd87ade7bc2a067295d79c28cd11abd2
Reviewed-on: https://go-review.googlesource.com/35353
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
Reviewed-by: Rick Hudson <rlh@golang.org>
2017-01-18 15:40:33 +00:00
Russ Cox
d10eddcba3 testing: make parallel t.Run safe again
Fixes #18603.

Change-Id: I5760c0a9f862200b7e943058a672eb559ac1b9d9
Reviewed-on: https://go-review.googlesource.com/35354
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-01-18 07:44:24 +00:00
Brad Fitzpatrick
2c8b70eacf crypto/x509: revert SystemCertPool implementation for Windows
Updates #18609

Change-Id: I8306135660f52cf625bed4c7f53f632e527617de
Reviewed-on: https://go-review.googlesource.com/35265
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
Reviewed-by: Quentin Smith <quentin@golang.org>
2017-01-18 05:41:15 +00:00
David du Colombier
fcfd91858b doc/go1.8: document Plan 9 requirements
Fixes #18610.

Change-Id: I19da4d59a1b6293c9a4722aa696e2cb58d982a15
Reviewed-on: https://go-review.googlesource.com/35333
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-01-18 00:13:55 +00:00
Keith Randall
81a61a96c9 runtime: for plugins, don't add duplicate itabs
We already do this for shared libraries. Do it for plugins also.
Suggestions on how to test this would be welcome.

I'd like to get this in for 1.8.  It could lead to mysterious
hangs when using plugins.

Fixes #18676

Change-Id: I03209b096149090b9ba171c834c5e59087ed0f92
Reviewed-on: https://go-review.googlesource.com/35117
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Michael Hudson-Doyle <michael.hudson@canonical.com>
2017-01-17 22:37:19 +00:00
Alberto Donizetti
f674537cc9 README.md: update and simplify
Fixes #18675

Change-Id: I82e63e8ee3fe4a998b01d9397c3045912588e2f5
Reviewed-on: https://go-review.googlesource.com/35183
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-01-17 21:26:43 +00:00
gulyasm
d8711919db cmd/go: fix bug help message
The bug subcommand opens up the browser instead of printing information.
Fixes help message to reflect that.

Fixes #18630.

Change-Id: I660c94bc65ef1994292cfd72d08a544699545701
Reviewed-on: https://go-review.googlesource.com/35150
Reviewed-by: Russ Cox <rsc@golang.org>
2017-01-17 20:48:27 +00:00
Filippo Valsorda
48d8edb5b2 crypto/tls: disable CBC cipher suites with SHA-256 by default
As is, they were fully vulnerable to the Lucky13 attack. The SHA1
variants implement limited countermeasures (see f28cf8346c) but the
SHA256 ones are apparently used rarely enough (see 8741504888) that
it's not worth the extra code.

Instead, disable them by default and update the warning.

Updates #13385
Updates #15487

Change-Id: I45b8b716001e2fa0811b17e25be76e2512e5abb2
Reviewed-on: https://go-review.googlesource.com/35290
Reviewed-by: Adam Langley <alangley@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Matt Layher <mdlayher@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-01-17 16:41:09 +00:00
Cherry Zhang
92ecd78933 cmd/compile: add ZeroWB case in writebarrier
It looks like it should be there, although I couldn't find a test
case that fails without it. ZeroWB is probably never generated now:
zeroing an initialized heap object is done by making an autotmp on
stack, zeroing it, and copying (typedmemmove) to heap.

Passes "toolstash -cmp" on std.

Change-Id: I702a59759e33fb8cc2a34a3b3029e7540aca080a
Reviewed-on: https://go-review.googlesource.com/35250
Reviewed-by: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-01-16 18:27:48 +00:00
Brad Fitzpatrick
787125abab doc: 2017 is the Year of the Gopher
Change-Id: Iac713ae1f322f893c92b3fc47fe9b5719052f9eb
Reviewed-on: https://go-review.googlesource.com/35240
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: David Symonds <dsymonds@golang.org>
Reviewed-by: Minux Ma <minux@golang.org>
2017-01-16 17:11:57 +00:00
Josh Bleecher Snyder
5b708a6b6a cmd/compile: lvalues are only required for == when calling runtime fns
Fixes #18661.

Change-Id: I865802a9b88ab22560c9914a70901d1924242bdc
Reviewed-on: https://go-review.googlesource.com/35236
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-01-16 05:40:45 +00:00
Shenghou Ma
e83d506714 vendor/golang_org/x/crypto/poly1305: revendor to pick up fix for #18673
Fixes #18673.

Change-Id: Ic827c16ad414733392c348da1c9ed9b308879fef
Reviewed-on: https://go-review.googlesource.com/35260
Run-TryBot: Minux Ma <minux@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-01-16 01:50:58 +00:00
David du Colombier
76f981c8d8 net/http: skip TestServerHijackGetsBackgroundByte on Plan 9
CL 5232 added TestServerHijackGetsBackgroundByte, which is failing
on Plan 9, because CloseWrite is not implemented on Plan 9 yet.

Updates #17906.
Updates #18657.

Change-Id: I3c2f73760b0f767f3f9ed2698c855372170e0481
Reviewed-on: https://go-review.googlesource.com/35178
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-01-14 17:11:31 +00:00
David du Colombier
e395e3246a net/http: skip TestServerHijackGetsBackgroundByte_big on Plan 9
CL 35234 added TestServerHijackGetsBackgroundByte_big, which is failing
on Plan 9, because CloseWrite is not implemented on Plan 9 yet.

Updates #17906.
Updates #18658.

Change-Id: Icaf3fe3600d586515ecd92aca874104ea81ce6b9
Reviewed-on: https://go-review.googlesource.com/35179
Run-TryBot: David du Colombier <0intro@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-01-14 17:11:06 +00:00
Brad Fitzpatrick
6a3c6c0de8 net/http: add another hijack-after-background-read test
Follow-up test from Ian's comments in https://golang.org/cl/35232
after submit.

Change-Id: Ifa504bd8d09e555c3c7738376199dfc9b99130cf
Reviewed-on: https://go-review.googlesource.com/35234
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
2017-01-14 05:57:07 +00:00
David Crawshaw
467109bf56 all: test adjustments for the iOS builder
The working directory is now adjusted to match the typical Go test
working directory in main, as the old trick for adjusting earlier
stopped working with the latest version of LLDB bugs.

That means the small number of places where testdata files are
read before main is called no longer work. This CL adjusts those
reads to happen after main is called. (This has the bonus effect of
not reading some benchmark testdata files in all.bash.)

Fixes compress/bzip2, go/doc, go/parser, os, and time package
tests on the iOS builder.

Change-Id: If60f026aa7848b37511c36ac5e3985469ec25209
Reviewed-on: https://go-review.googlesource.com/35255
Run-TryBot: David Crawshaw <crawshaw@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-01-14 03:27:53 +00:00
Brad Fitzpatrick
b2a3b54b95 net/http: make sure Hijack's bufio.Reader includes pre-read background byte
Previously, if the Hijack called stopped the background read call
which read a byte, that byte was sitting in memory, buffered, ready to
be Read by Hijack's returned bufio.Reader, but it wasn't yet in the
bufio.Reader's buffer itself, so bufio.Reader.Buffered() reported 1
byte fewer.

This matters for callers who wanted to stitch together any buffered
data (with bufio.Reader.Peek(bufio.Reader.Buffered())) with Hijack's
returned net.Conn. Otherwise there was no way for callers to know a
byte was read.

Change-Id: Id7cb0a0a33fe2f33d79250e13dbaa9c0f7abba13
Reviewed-on: https://go-review.googlesource.com/35232
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
2017-01-13 23:13:54 +00:00
David Crawshaw
593ea3b360 cmd/go, misc: rework cwd handling for iOS tests
Another change in behvaior (bug) in LLDB. Despite the fact that
LLDB can dump the symtab of our test binaries and show the function
addresses, it can no longer call the functions. This means the chdir
trick on signal is failing.

This CL uses a new trick. For iOS, the exec script passes the change
in directory as an argument, and it is processed early by the test
harness generated by cmd/go.

For the iOS builders.

Change-Id: I8f5d0f831fe18de99f097761f89c5184d5bf2afb
Reviewed-on: https://go-review.googlesource.com/35152
Reviewed-by: Elias Naur <elias.naur@gmail.com>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-01-13 20:08:06 +00:00
Michael Munday
0642b8a2f1 syscall: export Fsid.X__val on s390x
mkpost.go replaces all variables prefixed with 'X_' with '_' on s390x
because most of them do not need to be exposed. X__val is being used
by a third party library so it turns out we do need to expose it on
s390x (it is already exposed on all other Linux architectures).

Fixes #17298 and updates #18632.

Change-Id: Ic03463229a5f75ca41a4a4b50300da4b4d892d45
Reviewed-on: https://go-review.googlesource.com/30130
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-01-13 19:31:47 +00:00
Alberto Donizetti
4601eae6ba doc/gdb: mention GOTRACEBACK=crash
Also fix a couple of other errors.

Fixes #6877

Change-Id: I94c81c5847cc7b0adab19418e71687bc2ee7fe94
Reviewed-on: https://go-review.googlesource.com/34960
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-01-13 18:05:46 +00:00
Keith Randall
4c4c5fc7a3 misc/cgo/testplugin: test that types and itabs are unique
Make sure that the same type and itab generated in two
different plugins are actually the same thing.

See also CL 35115

Change-Id: I0c1ecb039d7e2bf5a601d58dfa162a435ae4ef76
Reviewed-on: https://go-review.googlesource.com/35116
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2017-01-13 17:31:33 +00:00
Austin Clements
22689c4450 reflect: keep makeFuncImpl live across makeFuncStub
When traceback sees reflect.makeFuncStub (or reflect.methodValueCall)
on the stack, it expects to be able to get the *reflect.makeFuncImpl
(or *reflect.methodValue) for that call from the first outgoing
argument slot of makeFuncStub/methodValueCall.

However, currently this object isn't necessarily kept live across
makeFuncStub. This means it may get garbage collected while in a
reflect call and reused for something else. If we then try to
traceback, the runtime will see a corrupted makeFuncImpl object and
panic. This was not a problem in previous releases because we always
kept arguments live across the whole function. This became a problem
when we stopped doing this.

Fix this by using reflect.KeepAlive to keep the
makeFuncImpl/methodValue live across all of callReflect/callMethod,
which in turn keeps it live as long as makeFuncStub/methodValueCall
are on the stack.

Fixes #18635.

Change-Id: I91853efcf17912390fddedfb0230648391c33936
Reviewed-on: https://go-review.googlesource.com/35151
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-01-13 03:45:28 +00:00
David Crawshaw
9cf06ed6cd cmd/link: only exclude C-only symbols on darwin
C-only symbols are excluded from pclntab because of a quirk of darwin,
where functions are referred to by an exported symbol so dynamic
relocations de-duplicate to the host binary module and break unwinding.

This doesn't happen on ELF systems because the linker always refers to
unexported module-local symbols, so we don't need this condition.
And the current logic for excluding some functions breaks the module
verification code in moduledataverify1. So disable this for plugins
on linux.

(In 1.9, it will probably be necessary to introduce a module-local
symbol reference system on darwin to fix a different bug, so all of
this onlycsymbol code made be short-lived.)

With this CL, the tests in CL 35116 pass.

Change-Id: I517d7ca4427241fa0a91276c462827efb9383be9
Reviewed-on: https://go-review.googlesource.com/35190
Reviewed-by: Michael Hudson-Doyle <michael.hudson@canonical.com>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-01-12 23:48:11 +00:00
Joe Tsai
9c3630f578 compress/flate: avoid large stack growth in fillDeflate
Ranging over an array causes the array to be copied over to the
stack, which cause large re-growths. Instead, we should iterate
over slices of the array.

Also, assigning a large struct literal uses the stack even
though the actual fields being populated are small in comparison
to the entirety of the struct (see #18636).

Fixing the stack growth does not alter CPU-time performance much
since the stack-growth and copying was such a tiny portion of the
compression work:

name                         old time/op    new time/op    delta
Encode/Digits/Default/1e4-8     332µs ± 1%     332µs ± 1%   ~     (p=0.796 n=10+10)
Encode/Digits/Default/1e5-8    5.07ms ± 2%    5.05ms ± 1%   ~       (p=0.815 n=9+8)
Encode/Digits/Default/1e6-8    53.7ms ± 1%    53.9ms ± 1%   ~     (p=0.075 n=10+10)
Encode/Twain/Default/1e4-8      380µs ± 1%     380µs ± 1%   ~     (p=0.684 n=10+10)
Encode/Twain/Default/1e5-8     5.79ms ± 2%    5.79ms ± 1%   ~      (p=0.497 n=9+10)
Encode/Twain/Default/1e6-8     61.5ms ± 1%    61.8ms ± 1%   ~     (p=0.247 n=10+10)

name                         old speed      new speed      delta
Encode/Digits/Default/1e4-8  30.1MB/s ± 1%  30.1MB/s ± 1%   ~     (p=0.753 n=10+10)
Encode/Digits/Default/1e5-8  19.7MB/s ± 2%  19.8MB/s ± 1%   ~       (p=0.795 n=9+8)
Encode/Digits/Default/1e6-8  18.6MB/s ± 1%  18.5MB/s ± 1%   ~     (p=0.072 n=10+10)
Encode/Twain/Default/1e4-8   26.3MB/s ± 1%  26.3MB/s ± 1%   ~     (p=0.616 n=10+10)
Encode/Twain/Default/1e5-8   17.3MB/s ± 2%  17.3MB/s ± 1%   ~      (p=0.484 n=9+10)
Encode/Twain/Default/1e6-8   16.3MB/s ± 1%  16.2MB/s ± 1%   ~     (p=0.238 n=10+10)

Updates #18636
Fixes #18625

Change-Id: I471b20339bf675f63dc56d38b3acdd824fe23328
Reviewed-on: https://go-review.googlesource.com/35122
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-01-12 19:15:57 +00:00
David Crawshaw
4f0aac52d9 cmd/go: add comment about SIGUSR2 on iOS
Missing from CL 34926.

Change-Id: I4a046440c30811f26da53bee0e853dae3b0ac57a
Reviewed-on: https://go-review.googlesource.com/35123
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-01-12 16:47:42 +00:00
David Crawshaw
333f764df3 cmd/go, misc: switch from breakpoint to SIGUSR2
The iOS test harness has set a breakpoint early in the life of Go
programs so that it can change the current working directory using
information only available from the host debugger. Somewhere in the
upgrade to iOS 10 / XCode 8.2, breakpoints stopped working. This
may be an LLDB bug, or a bug in the ios-deploy LLDB scripts, it's
not clear.

Work around the problem by giving up on breakpoints. Instead, early
in the life of every test binary built for iOS, send (and ignore) a
SIGUSR2 signal. The debugger will catch this, giving the script
go_darwin_arm_exec a chance to change the working directory.

For the iOS builders.

Change-Id: I7476531985217d0c76bc176904c48379210576c2
Reviewed-on: https://go-review.googlesource.com/34926
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-01-12 15:46:46 +00:00
Shenghou Ma
39e31d5ec0 doc/go1.8: update timezone database version
Fixes #18623.

Change-Id: Ic965f5f7088c3270adbca7162226be486d1b9b4e
Reviewed-on: https://go-review.googlesource.com/35130
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-01-12 04:50:46 +00:00
Keith Randall
08da8201ca misc/cgo/testshared: test that types and itabs are unique
Make sure that the same type and itab generated in two
different shared library are actually the same thing.

Change-Id: Ica45862d65ff8bc7ad04d59a41f57223f71224cd
Reviewed-on: https://go-review.googlesource.com/35115
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-01-12 00:20:55 +00:00
Bryan C. Mills
fdde7ba2a2 runtime: avoid clobbering C callee-save register in cgoSigtramp
Use R11 (a caller-saved temp register) instead of RBX (a callee-saved
register).

I believe this only affects linux/amd64, since it is the only platform
with a non-trivial cgoSigtramp implementation.

Updates #18328.

Change-Id: I3d35c4512624184d5a8ece653fa09ddf50e079a2
Reviewed-on: https://go-review.googlesource.com/35068
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-01-12 00:06:32 +00:00
Josh Bleecher Snyder
f65abf6ddc cmd/compile: hide testdclstack behind debug flag
This reduces compilation time for the program
in #18602 from 7 hours to 30 min.

Updates #14781
Updates #18602

Change-Id: I3c4af878a08920e6373d3b3b0c4453ee002e32eb
Reviewed-on: https://go-review.googlesource.com/35113
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-01-11 23:39:50 +00:00
Joe Tsai
641ef2a733 compress/gzip: skip TestGZIPFilesHaveZeroMTimes on non-builders
Fixes #18604

Change-Id: I89221d5e632042167dfced068e1dc14e932cd618
Reviewed-on: https://go-review.googlesource.com/35111
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-01-11 17:48:09 +00:00
Austin Clements
0724aa813f crypto/dsa: gofmt
Somehow this file didn't get gofmted after the last change, which
interferes with merges.

Change-Id: I965cfdbf27a01124a6ed300be9687ff84f68f9a1
Reviewed-on: https://go-review.googlesource.com/35064
Reviewed-by: Matt Layher <mdlayher@gmail.com>
Reviewed-by: Adam Langley <agl@chromium.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Matt Layher <mdlayher@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-01-11 17:10:59 +00:00
Brad Fitzpatrick
ac05542985 net/http: deflake TestRetryIdempotentRequestsOnError
The test was previously an integration test, relying on luck and many
goroutines and lots of time to hit the path to be tested.

Instead, rewrite the test to exactly hit the path to be tested, in one
try, in one goroutine.

Fixes #18205

Change-Id: I63cd513316344bfd7375dcc452c1c396dec0e49f
Reviewed-on: https://go-review.googlesource.com/35107
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-01-11 01:39:54 +00:00
Jaana Burcu Dogan
b842c9aac7 doc: remove inline styles
Change-Id: I7ca7e9a2d4cf97cf33c60a9a4d0ba5fb0ca6e44c
Reviewed-on: https://go-review.googlesource.com/35098
Reviewed-by: Chris Broadfoot <cbro@golang.org>
2017-01-10 22:54:19 +00:00
Chris Broadfoot
3de6e96e4b [release-branch.go1.8] go1.8rc1
Change-Id: I68a99a4d750357dd59eb48f7c05b4dc08c64c92d
Reviewed-on: https://go-review.googlesource.com/35097
Run-TryBot: Chris Broadfoot <cbro@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-01-10 19:35:03 +00:00
91 changed files with 1482 additions and 372 deletions

View File

@@ -5,39 +5,37 @@ reliable, and efficient software.
![Gopher image](doc/gopher/fiveyears.jpg)
For documentation about how to install and use Go,
visit https://golang.org/ or load doc/install-source.html
in your web browser.
Our canonical Git repository is located at https://go.googlesource.com/go.
There is a mirror of the repository at https://github.com/golang/go.
Unless otherwise noted, the Go source files are distributed under the
BSD-style license found in the LICENSE file.
### Download and Install
#### Binary Distributions
Official binary distributions are available at https://golang.org/dl/.
After downloading a binary release, visit https://golang.org/doc/install
or load doc/install.html in your web browser for installation
instructions.
#### Install From Source
If a binary distribution is not available for your combination of
operating system and architecture, visit
https://golang.org/doc/install/source or load doc/install-source.html
in your web browser for source installation instructions.
### Contributing
Go is the work of hundreds of contributors. We appreciate your help!
To contribute, please read the contribution guidelines:
https://golang.org/doc/contribute.html
##### Note that we do not accept pull requests and that we use the issue tracker for bug reports and proposals only. Please ask questions on https://forum.golangbridge.org or https://groups.google.com/forum/#!forum/golang-nuts.
Unless otherwise noted, the Go source files are distributed
under the BSD-style license found in the LICENSE file.
--
## Binary Distribution Notes
If you have just untarred a binary Go distribution, you need to set
the environment variable $GOROOT to the full path of the go
directory (the one containing this file). You can omit the
variable if you unpack it into /usr/local/go, or if you rebuild
from sources by running all.bash (see doc/install-source.html).
You should also add the Go binary directory $GOROOT/bin
to your shell's path.
For example, if you extracted the tar file into $HOME/go, you might
put the following in your .profile:
export GOROOT=$HOME/go
export PATH=$PATH:$GOROOT/bin
See https://golang.org/doc/install or doc/install.html for more details.
Note that the Go project does not use GitHub pull requests, and that
we use the issue tracker for bug reports and proposals only. See
https://golang.org/wiki/Questions for a list of places to ask
questions about the Go language.

1
VERSION Normal file
View File

@@ -0,0 +1 @@
go1.8rc3

View File

@@ -698,7 +698,7 @@ These files will be periodically updated based on the commit logs.
<p>Code that you contribute should use the standard copyright header:</p>
<pre>
// Copyright 2016 The Go Authors. All rights reserved.
// Copyright 2017 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.
</pre>

View File

@@ -4,7 +4,8 @@
}-->
<p><i>
This applies to the <code>gc</code> toolchain. Gccgo has native gdb support.
This applies to the standard toolchain (the <code>gc</code> Go
compiler and tools). Gccgo has native gdb support.
Besides this overview you might want to consult the
<a href="http://sourceware.org/gdb/current/onlinedocs/gdb/">GDB manual</a>.
</i></p>
@@ -49,6 +50,14 @@ when debugging, pass the flags <code>-gcflags "-N -l"</code> to the
debugged.
</p>
<p>
If you want to use gdb to inspect a core dump, you can trigger a dump
on a program crash, on systems that permit it, by setting
<code>GOTRACEBACK=crash</code> in the environment (see the
<a href="/pkg/runtime/#hdr-Environment_Variables"> runtime package
documentation</a> for more info).
</p>
<h3 id="Common_Operations">Common Operations</h3>
<ul>
@@ -130,7 +139,7 @@ the DWARF code.
<p>
If you're interested in what the debugging information looks like, run
'<code>objdump -W 6.out</code>' and browse through the <code>.debug_*</code>
'<code>objdump -W a.out</code>' and browse through the <code>.debug_*</code>
sections.
</p>
@@ -377,7 +386,9 @@ $3 = struct hchan&lt;*testing.T&gt;
</pre>
<p>
That <code>struct hchan&lt;*testing.T&gt;</code> is the runtime-internal representation of a channel. It is currently empty, or gdb would have pretty-printed it's contents.
That <code>struct hchan&lt;*testing.T&gt;</code> is the
runtime-internal representation of a channel. It is currently empty,
or gdb would have pretty-printed its contents.
</p>
<p>

View File

@@ -52,6 +52,19 @@ user libraries. The Go 1.4 runtime is not fully merged, but that
should not be visible to Go programs.
</p>
<p>
The GCC 6 releases include a complete implementation of the Go 1.6.1
user libraries. The Go 1.6 runtime is not fully merged, but that
should not be visible to Go programs.
</p>
<p>
The GCC 7 releases are expected to include a complete implementation
of the Go 1.8 user libraries. As with earlier releases, the Go 1.8
runtime is not fully merged, but that should not be visible to Go
programs.
</p>
<h2 id="Source_code">Source code</h2>
<p>
@@ -160,23 +173,6 @@ make
make install
</pre>
<h3 id="Ubuntu">A note on Ubuntu</h3>
<p>
Current versions of Ubuntu and versions of GCC before 4.8 disagree on
where system libraries and header files are found. This is not a
gccgo issue. When building older versions of GCC, setting these
environment variables while configuring and building gccgo may fix the
problem.
</p>
<pre>
LIBRARY_PATH=/usr/lib/x86_64-linux-gnu
C_INCLUDE_PATH=/usr/include/x86_64-linux-gnu
CPLUS_INCLUDE_PATH=/usr/include/x86_64-linux-gnu
export LIBRARY_PATH C_INCLUDE_PATH CPLUS_INCLUDE_PATH
</pre>
<h2 id="Using_gccgo">Using gccgo</h2>
<p>
@@ -364,12 +360,15 @@ or with C++ code compiled using <code>extern "C"</code>.
<h3 id="Types">Types</h3>
<p>
Basic types map directly: an <code>int</code> in Go is an <code>int</code>
in C, an <code>int32</code> is an <code>int32_t</code>,
etc. Go <code>byte</code> is equivalent to C <code>unsigned
char</code>.
Pointers in Go are pointers in C. A Go <code>struct</code> is the same as C
<code>struct</code> with the same fields and types.
Basic types map directly: an <code>int32</code> in Go is
an <code>int32_t</code> in C, an <code>int64</code> is
an <code>int64_t</code>, etc.
The Go type <code>int</code> is an integer that is the same size as a
pointer, and as such corresponds to the C type <code>intptr_t</code>.
Go <code>byte</code> is equivalent to C <code>unsigned char</code>.
Pointers in Go are pointers in C.
A Go <code>struct</code> is the same as C <code>struct</code> with the
same fields and types.
</p>
<p>
@@ -380,7 +379,7 @@ structure (this is <b style="color: red;">subject to change</b>):
<pre>
struct __go_string {
const unsigned char *__data;
int __length;
intptr_t __length;
};
</pre>
@@ -400,8 +399,8 @@ A slice in Go is a structure. The current definition is
<pre>
struct __go_slice {
void *__values;
int __count;
int __capacity;
intptr_t __count;
intptr_t __capacity;
};
</pre>
@@ -526,15 +525,3 @@ This procedure is full of unstated caveats and restrictions and we make no
guarantee that it will not change in the future. It is more useful as a
starting point for real Go code than as a regular procedure.
</p>
<h2 id="RTEMS_Port">RTEMS Port</h2>
<p>
The gccgo compiler has been ported to <a href="http://www.rtems.com/">
<code>RTEMS</code></a>. <code>RTEMS</code> is a real-time executive
that provides a high performance environment for embedded applications
on a range of processors and embedded hardware. The current gccgo
port is for x86. The goal is to extend the port to most of the
<a href="http://www.rtems.org/wiki/index.php/SupportedCPUs">
architectures supported by <code>RTEMS</code></a>. For more information on the port,
as well as instructions on how to install it, please see this
<a href="http://www.rtems.org/wiki/index.php/GCCGoRTEMS"><code>RTEMS</code> Wiki page</a>.

View File

@@ -93,7 +93,8 @@ On OpenBSD, Go now requires OpenBSD 5.9 or later. <!-- CL 34093 -->
<p>
The Plan 9 port's networking support is now much more complete
and matches the behavior of Unix and Windows with respect to deadlines
and cancelation.
and cancelation. For Plan 9 kernel requirements, see the
<a href="https://golang.org/wiki/Plan9">Plan 9 wiki page</a>.
</p>
<p>
@@ -434,11 +435,11 @@ version of gccgo.
<h3 id="plugin">Plugins</h3>
<p>
Go now supports a “<code>plugin</code> build mode for generating
plugins written in Go, and a
Go now provides early support for plugins with a “<code>plugin</code>
build mode for generating plugins written in Go, and a
new <a href="/pkg/plugin/"><code>plugin</code></a> package for
loading such plugins at run time. Plugin support is only currently
available on Linux.
loading such plugins at run time. Plugin support is currently only
available on Linux. Please report any issues.
</p>
<h2 id="runtime">Runtime</h2>
@@ -808,11 +809,6 @@ Optimizations and minor bug fixes are not listed.
<dl id="crypto_x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt>
<dd>
<p> <!-- CL 30578 -->
<a href="/pkg/crypto/x509/#SystemCertPool"><code>SystemCertPool</code></a>
is now implemented on Windows.
</p>
<p> <!-- CL 24743 -->
PSS signatures are now supported.
</p>
@@ -1617,9 +1613,9 @@ crypto/x509: return error for missing SerialNumber (CL 27238)
June 31 and July 32.
</p>
<p> <!-- CL 33029 -->
<p> <!-- CL 33029 --> <!-- CL 34816 -->
The <code>tzdata</code> database has been updated to version
2016i for systems that don't already have a local time zone
2016j for systems that don't already have a local time zone
database.
</p>
@@ -1649,6 +1645,17 @@ crypto/x509: return error for missing SerialNumber (CL 27238)
and only the overall execution of the test binary would fail.
</p>
<p><!-- CL 32455 -->
The signature of the
<a href="/pkg/testing/#MainStart"><code>MainStart</code></a>
function has changed, as allowed by the documentation. It is an
internal detail and not part of the Go 1 compatibility promise.
If you're not calling <code>MainStart</code> directly but see
errors, that likely means you set the
normally-empty <code>GOROOT</code> environment variable and it
doesn't match the version of your <code>go</code> command's binary.
</p>
</dd>
</dl>

View File

@@ -147,6 +147,9 @@ either the git branch <code>release-branch.go1.4</code> or
which contains the Go 1.4 source code plus accumulated fixes
to keep the tools running on newer operating systems.
(Go 1.4 was the last distribution in which the tool chain was written in C.)
After unpacking the Go 1.4 source, <code>cd</code> to
the <code>src</code> subdirectory and run <code>make.bash</code> (or,
on Windows, <code>make.bat</code>).
</p>
<p>

View File

@@ -250,7 +250,7 @@ $ <b>cd $HOME/go/src/hello</b>
$ <b>go build</b>
</pre>
<pre class="testWindows" style="display: none">
<pre class="testWindows">
C:\&gt; <b>cd %USERPROFILE%\go\src\hello</b>
C:\Users\Gopher\go\src\hello&gt; <b>go build</b>
</pre>
@@ -267,7 +267,7 @@ $ <b>./hello</b>
hello, world
</pre>
<pre class="testWindows" style="display: none">
<pre class="testWindows">
C:\Users\Gopher\go\src\hello&gt; <b>hello</b>
hello, world
</pre>

View File

@@ -73,7 +73,7 @@ func test18146(t *testing.T) {
}
runtime.GOMAXPROCS(threads)
argv := append(os.Args, "-test.run=NoSuchTestExists")
if err := syscall.Exec(os.Args[0], argv, nil); err != nil {
if err := syscall.Exec(os.Args[0], argv, os.Environ()); err != nil {
t.Fatal(err)
}
}

View File

@@ -17,7 +17,7 @@ package cgotest
static stack_t oss;
static char signalStack[SIGSTKSZ];
static void changeSignalStack() {
static void changeSignalStack(void) {
stack_t ss;
memset(&ss, 0, sizeof ss);
ss.ss_sp = signalStack;
@@ -29,7 +29,7 @@ static void changeSignalStack() {
}
}
static void restoreSignalStack() {
static void restoreSignalStack(void) {
#if (defined(__x86_64__) || defined(__i386__)) && defined(__APPLE__)
// The Darwin C library enforces a minimum that the kernel does not.
// This is OK since we allocated this much space in mpreinit,
@@ -42,7 +42,7 @@ static void restoreSignalStack() {
}
}
static int zero() {
static int zero(void) {
return 0;
}
*/

View File

@@ -0,0 +1,46 @@
// Copyright 2017 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 main
import (
"iface_i"
"log"
"plugin"
)
func main() {
a, err := plugin.Open("iface_a.so")
if err != nil {
log.Fatalf(`plugin.Open("iface_a.so"): %v`, err)
}
b, err := plugin.Open("iface_b.so")
if err != nil {
log.Fatalf(`plugin.Open("iface_b.so"): %v`, err)
}
af, err := a.Lookup("F")
if err != nil {
log.Fatalf(`a.Lookup("F") failed: %v`, err)
}
bf, err := b.Lookup("F")
if err != nil {
log.Fatalf(`b.Lookup("F") failed: %v`, err)
}
if af.(func() interface{})() != bf.(func() interface{})() {
panic("empty interfaces not equal")
}
ag, err := a.Lookup("G")
if err != nil {
log.Fatalf(`a.Lookup("G") failed: %v`, err)
}
bg, err := b.Lookup("G")
if err != nil {
log.Fatalf(`b.Lookup("G") failed: %v`, err)
}
if ag.(func() iface_i.I)() != bg.(func() iface_i.I)() {
panic("nonempty interfaces not equal")
}
}

View File

@@ -0,0 +1,17 @@
// Copyright 2017 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 main
import "iface_i"
//go:noinline
func F() interface{} {
return (*iface_i.T)(nil)
}
//go:noinline
func G() iface_i.I {
return (*iface_i.T)(nil)
}

View File

@@ -0,0 +1,17 @@
// Copyright 2017 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 main
import "iface_i"
//go:noinline
func F() interface{} {
return (*iface_i.T)(nil)
}
//go:noinline
func G() iface_i.I {
return (*iface_i.T)(nil)
}

View File

@@ -0,0 +1,17 @@
// Copyright 2017 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 iface_i
type I interface {
M()
}
type T struct {
}
func (t *T) M() {
}
// *T implements I

View File

@@ -0,0 +1,13 @@
// Copyright 2017 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 dynamodbstreamsevt
import "encoding/json"
var foo json.RawMessage
type Event struct{}
func (e *Event) Dummy() {}

View File

@@ -0,0 +1,31 @@
// Copyright 2017 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.
// The bug happened like this:
// 1) The main binary adds an itab for *json.UnsupportedValueError / error
// (concrete type / interface type). This itab goes in hash bucket 0x111.
// 2) The plugin adds that same itab again. That makes a cycle in the itab
// chain rooted at hash bucket 0x111.
// 3) The main binary then asks for the itab for *dynamodbstreamsevt.Event /
// json.Unmarshaler. This itab happens to also live in bucket 0x111.
// The lookup code goes into an infinite loop searching for this itab.
// The code is carefully crafted so that the two itabs are both from the
// same bucket, and so that the second itab doesn't exist in
// the itab hashmap yet (so the entire linked list must be searched).
package main
import (
"encoding/json"
"issue18676/dynamodbstreamsevt"
"plugin"
)
func main() {
plugin.Open("plugin.so")
var x interface{} = (*dynamodbstreamsevt.Event)(nil)
if _, ok := x.(json.Unmarshaler); !ok {
println("something")
}
}

View File

@@ -0,0 +1,11 @@
// Copyright 2017 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 main
import "C"
import "issue18676/dynamodbstreamsevt"
func F(evt *dynamodbstreamsevt.Event) {}

View File

@@ -15,8 +15,8 @@ goos=$(go env GOOS)
goarch=$(go env GOARCH)
function cleanup() {
rm -f plugin*.so unnamed*.so
rm -rf host pkg sub
rm -f plugin*.so unnamed*.so iface*.so
rm -rf host pkg sub iface issue18676
}
trap cleanup EXIT
@@ -32,3 +32,15 @@ GOPATH=$(pwd) go build -buildmode=plugin unnamed2.go
GOPATH=$(pwd) go build host
LD_LIBRARY_PATH=$(pwd) ./host
# Test that types and itabs get properly uniqified.
GOPATH=$(pwd) go build -buildmode=plugin iface_a
GOPATH=$(pwd) go build -buildmode=plugin iface_b
GOPATH=$(pwd) go build iface
LD_LIBRARY_PATH=$(pwd) ./iface
# Test for issue 18676 - make sure we don't add the same itab twice.
# The buggy code hangs forever, so use a timeout to check for that.
GOPATH=$(pwd) go build -buildmode=plugin -o plugin.so src/issue18676/plugin.go
GOPATH=$(pwd) go build -o issue18676 src/issue18676/main.go
timeout 10s ./issue18676

View File

@@ -0,0 +1,12 @@
// Copyright 2017 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.
// This program segfaulted during libpreinit when built with -msan:
// http://golang.org/issue/18707
package main
import "C"
func main() {}

View File

@@ -68,6 +68,25 @@ fi
status=0
testmsanshared() {
goos=$(go env GOOS)
suffix="-installsuffix testsanitizers"
libext="so"
if [ "$goos" == "darwin" ]; then
libext="dylib"
fi
go build -msan -buildmode=c-shared $suffix -o ${TMPDIR}/libmsanshared.$libext msan_shared.go
echo 'int main() { return 0; }' > ${TMPDIR}/testmsanshared.c
$CC $(go env GOGCCFLAGS) -fsanitize=memory -o ${TMPDIR}/testmsanshared ${TMPDIR}/testmsanshared.c ${TMPDIR}/libmsanshared.$libext
if ! LD_LIBRARY_PATH=. ${TMPDIR}/testmsanshared; then
echo "FAIL: msan_shared"
status=1
fi
rm -f ${TMPDIR}/{testmsanshared,testmsanshared.c,libmsanshared.$libext}
}
if test "$msan" = "yes"; then
if ! go build -msan std; then
echo "FAIL: build -msan std"
@@ -108,6 +127,8 @@ if test "$msan" = "yes"; then
echo "FAIL: msan_fail"
status=1
fi
testmsanshared
fi
if test "$tsan" = "yes"; then

View File

@@ -815,3 +815,14 @@ func TestImplicitInclusion(t *testing.T) {
goCmd(t, "install", "-linkshared", "implicitcmd")
run(t, "running executable linked against library that contains same package as it", "./bin/implicitcmd")
}
// Tests to make sure that the type fields of empty interfaces and itab
// fields of nonempty interfaces are unique even across modules,
// so that interface equality works correctly.
func TestInterface(t *testing.T) {
goCmd(t, "install", "-buildmode=shared", "-linkshared", "iface_a")
// Note: iface_i gets installed implicitly as a dependency of iface_a.
goCmd(t, "install", "-buildmode=shared", "-linkshared", "iface_b")
goCmd(t, "install", "-linkshared", "iface")
run(t, "running type/itab uniqueness tester", "./bin/iface")
}

View File

@@ -5,6 +5,8 @@ import (
"reflect"
)
var SlicePtr interface{} = &[]int{}
var V int = 1
var HasMask []string = []string{"hi"}

View File

@@ -19,6 +19,8 @@ func F() *C {
return nil
}
var slicePtr interface{} = &[]int{}
func main() {
defer depBase.ImplementedInAsm()
// This code below causes various go.itab.* symbols to be generated in
@@ -32,4 +34,11 @@ func main() {
if reflect.TypeOf(F).Out(0) != reflect.TypeOf(c) {
panic("bad reflection results, see golang.org/issue/18252")
}
sp := reflect.New(reflect.TypeOf(slicePtr).Elem())
s := sp.Interface()
if reflect.TypeOf(s) != reflect.TypeOf(slicePtr) {
panic("bad reflection results, see golang.org/issue/18729")
}
}

View File

@@ -0,0 +1,17 @@
// Copyright 2017 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 main
import "iface_a"
import "iface_b"
func main() {
if iface_a.F() != iface_b.F() {
panic("empty interfaces not equal")
}
if iface_a.G() != iface_b.G() {
panic("non-empty interfaces not equal")
}
}

View File

@@ -0,0 +1,17 @@
// Copyright 2017 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 iface_a
import "iface_i"
//go:noinline
func F() interface{} {
return (*iface_i.T)(nil)
}
//go:noinline
func G() iface_i.I {
return (*iface_i.T)(nil)
}

View File

@@ -0,0 +1,17 @@
// Copyright 2017 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 iface_b
import "iface_i"
//go:noinline
func F() interface{} {
return (*iface_i.T)(nil)
}
//go:noinline
func G() iface_i.I {
return (*iface_i.T)(nil)
}

View File

@@ -0,0 +1,17 @@
// Copyright 2017 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 iface_i
type I interface {
M()
}
type T struct {
}
func (t *T) M() {
}
// *T implements I

View File

@@ -99,7 +99,7 @@ func main() {
// Approximately 1 in a 100 binaries fail to start. If it happens,
// try again. These failures happen for several reasons beyond
// our control, but all of them are safe to retry as they happen
// before lldb encounters the initial getwd breakpoint. As we
// before lldb encounters the initial SIGUSR2 stop. As we
// know the tests haven't started, we are not hiding flaky tests
// with this retry.
for i := 0; i < 5; i++ {
@@ -204,6 +204,11 @@ func run(bin string, args []string) (err error) {
var opts options
opts, args = parseArgs(args)
// Pass the suffix for the current working directory as the
// first argument to the test. For iOS, cmd/go generates
// special handling of this argument.
args = append([]string{"cwdSuffix=" + pkgpath}, args...)
// ios-deploy invokes lldb to give us a shell session with the app.
s, err := newSession(appdir, args, opts)
if err != nil {
@@ -224,6 +229,7 @@ func run(bin string, args []string) (err error) {
s.do(`process handle SIGHUP --stop false --pass true --notify false`)
s.do(`process handle SIGPIPE --stop false --pass true --notify false`)
s.do(`process handle SIGUSR1 --stop false --pass true --notify false`)
s.do(`process handle SIGUSR2 --stop true --pass false --notify true`) // sent by test harness
s.do(`process handle SIGCONT --stop false --pass true --notify false`)
s.do(`process handle SIGSEGV --stop false --pass true --notify false`) // does not work
s.do(`process handle SIGBUS --stop false --pass true --notify false`) // does not work
@@ -236,20 +242,9 @@ func run(bin string, args []string) (err error) {
return nil
}
s.do(`breakpoint set -n getwd`) // in runtime/cgo/gcc_darwin_arm.go
started = true
s.doCmd("run", "stop reason = breakpoint", 20*time.Second)
// Move the current working directory into the faux gopath.
if pkgpath != "src" {
s.do(`breakpoint delete 1`)
s.do(`expr char* $mem = (char*)malloc(512)`)
s.do(`expr $mem = (char*)getwd($mem, 512)`)
s.do(`expr $mem = (char*)strcat($mem, "/` + pkgpath + `")`)
s.do(`call (void)chdir($mem)`)
}
s.doCmd("run", "stop reason = signal SIGUSR2", 20*time.Second)
startTestsLen := s.out.Len()
fmt.Fprintln(s.in, `process continue`)
@@ -520,13 +515,11 @@ func copyLocalData(dstbase string) (pkgpath string, err error) {
// Copy timezone file.
//
// Typical apps have the zoneinfo.zip in the root of their app bundle,
// Apps have the zoneinfo.zip in the root of their app bundle,
// read by the time package as the working directory at initialization.
// As we move the working directory to the GOROOT pkg directory, we
// install the zoneinfo.zip file in the pkgpath.
if underGoRoot {
err := cp(
filepath.Join(dstbase, pkgpath),
dstbase,
filepath.Join(cwd, "lib", "time", "zoneinfo.zip"),
)
if err != nil {

View File

@@ -303,7 +303,9 @@ func genhash(sym *Sym, t *Type) {
typecheckslice(fn.Nbody.Slice(), Etop)
Curfn = nil
popdcl()
testdclstack()
if debug_dclstack != 0 {
testdclstack()
}
// Disable safemode while compiling this code: the code we
// generate internally can refer to unsafe.Pointer.
@@ -493,7 +495,9 @@ func geneq(sym *Sym, t *Type) {
typecheckslice(fn.Nbody.Slice(), Etop)
Curfn = nil
popdcl()
testdclstack()
if debug_dclstack != 0 {
testdclstack()
}
// Disable safemode while compiling this code: the code we
// generate internally can refer to unsafe.Pointer.

View File

@@ -217,7 +217,9 @@ func Import(in *bufio.Reader) {
typecheckok = tcok
resumecheckwidth()
testdclstack() // debugging only
if debug_dclstack != 0 {
testdclstack()
}
}
func formatErrorf(format string, args ...interface{}) {

View File

@@ -30,11 +30,12 @@ var (
)
var (
Debug_append int
Debug_closure int
Debug_panic int
Debug_slice int
Debug_wb int
Debug_append int
Debug_closure int
debug_dclstack int
Debug_panic int
Debug_slice int
Debug_wb int
)
// Debug arguments.
@@ -48,6 +49,7 @@ var debugtab = []struct {
{"append", &Debug_append}, // print information about append compilation
{"closure", &Debug_closure}, // print information about closure compilation
{"disablenil", &disable_checknil}, // disable nil checks
{"dclstack", &debug_dclstack}, // run internal dclstack checks
{"gcprog", &Debug_gcprog}, // print dump of GC programs
{"nil", &Debug_checknil}, // print information about nil checks
{"panic", &Debug_panic}, // do not hide any compiler panic
@@ -325,7 +327,6 @@ func Main() {
timings.Stop()
timings.AddEvent(int64(lexlineno-lexlineno0), "lines")
testdclstack()
mkpackage(localpkg.Name) // final import not used checks
finishUniverse()

View File

@@ -34,6 +34,7 @@ func parseFile(filename string) {
}
if nsyntaxerrors == 0 {
// Always run testdclstack here, even when debug_dclstack is not set, as a sanity measure.
testdclstack()
}
}

View File

@@ -1833,7 +1833,9 @@ func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) {
funcbody(fn)
Curfn = fn
popdcl()
testdclstack()
if debug_dclstack != 0 {
testdclstack()
}
// wrappers where T is anonymous (struct or interface) can be duplicated.
if rcvr.IsStruct() || rcvr.IsInterface() || rcvr.IsPtr() && rcvr.Elem().IsStruct() {

View File

@@ -57,8 +57,13 @@ func startProfile() {
Fatalf("%v", err)
}
atExit(func() {
runtime.GC() // profile all outstanding allocations
if err := pprof.WriteHeapProfile(f); err != nil {
// Profile all outstanding allocations.
runtime.GC()
// compilebench parses the memory profile to extract memstats,
// which are only written in the legacy pprof format.
// See golang.org/issue/18641 and runtime/pprof/pprof.go:writeHeap.
const writeLegacyFormat = 1
if err := pprof.Lookup("heap").WriteTo(f, writeLegacyFormat); err != nil {
Fatalf("%v", err)
}
})

View File

@@ -3117,12 +3117,12 @@ func walkcompare(n *Node, init *Nodes) *Node {
cmpr = cmpr.Left
}
if !islvalue(cmpl) || !islvalue(cmpr) {
Fatalf("arguments of comparison must be lvalues - %v %v", cmpl, cmpr)
}
// Chose not to inline. Call equality function directly.
if !inline {
if !islvalue(cmpl) || !islvalue(cmpr) {
Fatalf("arguments of comparison must be lvalues - %v %v", cmpl, cmpr)
}
// eq algs take pointers
pl := temp(ptrto(t))
al := nod(OAS, pl, nod(OADDR, cmpl, nil))

View File

@@ -885,9 +885,9 @@
(MOVDEQ y _ (FlagLT)) -> y
(MOVDEQ y _ (FlagGT)) -> y
(MOVDNE _ y (FlagEQ)) -> y
(MOVDNE x _ (FlagLT)) -> x
(MOVDNE x _ (FlagGT)) -> x
(MOVDNE y _ (FlagEQ)) -> y
(MOVDNE _ x (FlagLT)) -> x
(MOVDNE _ x (FlagGT)) -> x
(MOVDLT y _ (FlagEQ)) -> y
(MOVDLT _ x (FlagLT)) -> x

View File

@@ -82,7 +82,7 @@ func nilcheckelim(f *Func) {
}
}
// Next, process values in the block.
// Next, eliminate any redundant nil checks in this block.
i := 0
for _, v := range b.Values {
b.Values[i] = v
@@ -105,13 +105,10 @@ func nilcheckelim(f *Func) {
f.Config.Warnl(v.Line, "removed nil check")
}
v.reset(OpUnknown)
// TODO: f.freeValue(v)
i--
continue
}
// Record the fact that we know ptr is non nil, and remember to
// undo that information when this dominator subtree is done.
nonNilValues[ptr.ID] = true
work = append(work, bp{op: ClearPtr, ptr: ptr})
}
}
for j := i; j < len(b.Values); j++ {
@@ -119,6 +116,21 @@ func nilcheckelim(f *Func) {
}
b.Values = b.Values[:i]
// Finally, find redundant nil checks for subsequent blocks.
// Note that we can't add these until the loop above is done, as the
// values in the block are not ordered in any way when this pass runs.
// This was the cause of issue #18725.
for _, v := range b.Values {
if v.Op != OpNilCheck {
continue
}
ptr := v.Args[0]
// Record the fact that we know ptr is non nil, and remember to
// undo that information when this dominator subtree is done.
nonNilValues[ptr.ID] = true
work = append(work, bp{op: ClearPtr, ptr: ptr})
}
// Add all dominated blocks to the work list.
for w := sdom[node.block.ID].child; w != nil; w = sdom[w.ID].sibling {
work = append(work, bp{op: Work, block: w})

View File

@@ -9847,11 +9847,11 @@ func rewriteValueS390X_OpS390XMOVDNE(v *Value, config *Config) bool {
v.AddArg(cmp)
return true
}
// match: (MOVDNE _ y (FlagEQ))
// match: (MOVDNE y _ (FlagEQ))
// cond:
// result: y
for {
y := v.Args[1]
y := v.Args[0]
v_2 := v.Args[2]
if v_2.Op != OpS390XFlagEQ {
break
@@ -9861,11 +9861,11 @@ func rewriteValueS390X_OpS390XMOVDNE(v *Value, config *Config) bool {
v.AddArg(y)
return true
}
// match: (MOVDNE x _ (FlagLT))
// match: (MOVDNE _ x (FlagLT))
// cond:
// result: x
for {
x := v.Args[0]
x := v.Args[1]
v_2 := v.Args[2]
if v_2.Op != OpS390XFlagLT {
break
@@ -9875,11 +9875,11 @@ func rewriteValueS390X_OpS390XMOVDNE(v *Value, config *Config) bool {
v.AddArg(x)
return true
}
// match: (MOVDNE x _ (FlagGT))
// match: (MOVDNE _ x (FlagGT))
// cond:
// result: x
for {
x := v.Args[0]
x := v.Args[1]
v_2 := v.Args[2]
if v_2.Op != OpS390XFlagGT {
break

View File

@@ -35,7 +35,7 @@ func writebarrier(f *Func) {
valueLoop:
for i, v := range b.Values {
switch v.Op {
case OpStoreWB, OpMoveWB, OpMoveWBVolatile:
case OpStoreWB, OpMoveWB, OpMoveWBVolatile, OpZeroWB:
if IsStackAddr(v.Args[0]) {
switch v.Op {
case OpStoreWB:

View File

@@ -20,11 +20,10 @@ import (
var cmdBug = &Command{
Run: runBug,
UsageLine: "bug",
Short: "print information for bug reports",
Short: "start a bug report",
Long: `
Bug prints information that helps file effective bug reports.
Bugs may be reported at https://golang.org/issue/new.
Bug opens the default browser and starts a new bug report.
The report includes useful system information.
`,
}

View File

@@ -3787,3 +3787,26 @@ GLOBL ·constants<>(SB),8,$8
tg.setenv("GOPATH", tg.path("go"))
tg.run("build", "p")
}
// Issue 18778.
func TestDotDotDotOutsideGOPATH(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
tg.tempFile("pkgs/a.go", `package x`)
tg.tempFile("pkgs/a_test.go", `package x_test
import "testing"
func TestX(t *testing.T) {}`)
tg.tempFile("pkgs/a/a.go", `package a`)
tg.tempFile("pkgs/a/a_test.go", `package a_test
import "testing"
func TestA(t *testing.T) {}`)
tg.cd(tg.path("pkgs"))
tg.run("build", "./...")
tg.run("test", "./...")
tg.run("list", "./...")
tg.grepStdout("pkgs$", "expected package not listed")
tg.grepStdout("pkgs/a", "expected package not listed")
}

View File

@@ -429,7 +429,7 @@ func setErrorPos(p *Package, importPos []token.Position) *Package {
func cleanImport(path string) string {
orig := path
path = pathpkg.Clean(path)
if strings.HasPrefix(orig, "./") && path != ".." && path != "." && !strings.HasPrefix(path, "../") {
if strings.HasPrefix(orig, "./") && path != ".." && !strings.HasPrefix(path, "../") {
path = "./" + path
}
return path

View File

@@ -894,9 +894,13 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
if buildContext.GOOS == "darwin" {
if buildContext.GOARCH == "arm" || buildContext.GOARCH == "arm64" {
t.NeedCgo = true
t.IsIOS = true
t.NeedOS = true
}
}
if t.TestMain == nil {
t.NeedOS = true
}
for _, cp := range pmain.imports {
if len(cp.coverVars) > 0 {
@@ -1343,7 +1347,8 @@ type testFuncs struct {
NeedTest bool
ImportXtest bool
NeedXtest bool
NeedCgo bool
NeedOS bool
IsIOS bool
Cover []coverInfo
}
@@ -1444,7 +1449,7 @@ var testmainTmpl = template.Must(template.New("main").Parse(`
package main
import (
{{if not .TestMain}}
{{if .NeedOS}}
"os"
{{end}}
"testing"
@@ -1460,8 +1465,10 @@ import (
_cover{{$i}} {{$p.Package.ImportPath | printf "%q"}}
{{end}}
{{if .NeedCgo}}
{{if .IsIOS}}
"os/signal"
_ "runtime/cgo"
"syscall"
{{end}}
)
@@ -1523,6 +1530,32 @@ func coverRegisterFile(fileName string, counter []uint32, pos []uint32, numStmts
{{end}}
func main() {
{{if .IsIOS}}
// Send a SIGUSR2, which will be intercepted by LLDB to
// tell the test harness that installation was successful.
// See misc/ios/go_darwin_arm_exec.go.
signal.Notify(make(chan os.Signal), syscall.SIGUSR2)
syscall.Kill(0, syscall.SIGUSR2)
signal.Reset(syscall.SIGUSR2)
// The first argument supplied to an iOS test is an offset
// suffix for the current working directory.
// Process it here, and remove it from os.Args.
const hdr = "cwdSuffix="
if len(os.Args) < 2 || len(os.Args[1]) <= len(hdr) || os.Args[1][:len(hdr)] != hdr {
panic("iOS test not passed a working directory suffix")
}
suffix := os.Args[1][len(hdr):]
dir, err := os.Getwd()
if err != nil {
panic(err)
}
if err := os.Chdir(dir + "/" + suffix); err != nil {
panic(err)
}
os.Args = append([]string{os.Args[0]}, os.Args[2:]...)
{{end}}
{{if .CoverEnabled}}
testing.RegisterCover(testing.Cover{
Mode: {{printf "%q" .CoverMode}},

View File

@@ -1080,7 +1080,7 @@ func writelines(ctxt *Link, syms []*Symbol) ([]*Symbol, []*Symbol) {
epcs = s
dsym := ctxt.Syms.Lookup(dwarf.InfoPrefix+s.Name, int(s.Version))
dsym.Attr |= AttrHidden
dsym.Attr |= AttrHidden | AttrReachable
dsym.Type = obj.SDWARFINFO
for _, r := range dsym.R {
if r.Type == obj.R_DWARFREF && r.Sym.Size == 0 {

View File

@@ -168,7 +168,7 @@ func container(s *Symbol) int {
if s == nil {
return 0
}
if Buildmode == BuildmodePlugin && onlycsymbol(s) {
if Buildmode == BuildmodePlugin && Headtype == obj.Hdarwin && onlycsymbol(s) {
return 1
}
// We want to generate func table entries only for the "lowest level" symbols,

View File

@@ -204,12 +204,6 @@ func TestMTF(t *testing.T) {
}
}
var (
digits = mustLoadFile("testdata/e.txt.bz2")
twain = mustLoadFile("testdata/Mark.Twain-Tom.Sawyer.txt.bz2")
random = mustLoadFile("testdata/random.data.bz2")
)
func benchmarkDecode(b *testing.B, compressed []byte) {
// Determine the uncompressed size of testfile.
uncompressedSize, err := io.Copy(ioutil.Discard, NewReader(bytes.NewReader(compressed)))
@@ -227,6 +221,18 @@ func benchmarkDecode(b *testing.B, compressed []byte) {
}
}
func BenchmarkDecodeDigits(b *testing.B) { benchmarkDecode(b, digits) }
func BenchmarkDecodeTwain(b *testing.B) { benchmarkDecode(b, twain) }
func BenchmarkDecodeRand(b *testing.B) { benchmarkDecode(b, random) }
func BenchmarkDecodeDigits(b *testing.B) {
digits := mustLoadFile("testdata/e.txt.bz2")
b.ResetTimer()
benchmarkDecode(b, digits)
}
func BenchmarkDecodeTwain(b *testing.B) {
twain := mustLoadFile("testdata/Mark.Twain-Tom.Sawyer.txt.bz2")
b.ResetTimer()
benchmarkDecode(b, twain)
}
func BenchmarkDecodeRand(b *testing.B) {
random := mustLoadFile("testdata/random.data.bz2")
b.ResetTimer()
benchmarkDecode(b, random)
}

View File

@@ -136,14 +136,17 @@ func (d *compressor) fillDeflate(b []byte) int {
delta := d.hashOffset - 1
d.hashOffset -= delta
d.chainHead -= delta
for i, v := range d.hashPrev {
// Iterate over slices instead of arrays to avoid copying
// the entire table onto the stack (Issue #18625).
for i, v := range d.hashPrev[:] {
if int(v) > delta {
d.hashPrev[i] = uint32(int(v) - delta)
} else {
d.hashPrev[i] = 0
}
}
for i, v := range d.hashHead {
for i, v := range d.hashHead[:] {
if int(v) > delta {
d.hashHead[i] = uint32(int(v) - delta)
} else {

View File

@@ -12,6 +12,7 @@ import (
"io"
"io/ioutil"
"reflect"
"runtime/debug"
"sync"
"testing"
)
@@ -864,3 +865,33 @@ func TestBestSpeedMaxMatchOffset(t *testing.T) {
}
}
}
func TestMaxStackSize(t *testing.T) {
// This test must not run in parallel with other tests as debug.SetMaxStack
// affects all goroutines.
n := debug.SetMaxStack(1 << 16)
defer debug.SetMaxStack(n)
var wg sync.WaitGroup
defer wg.Wait()
b := make([]byte, 1<<20)
for level := HuffmanOnly; level <= BestCompression; level++ {
// Run in separate goroutine to increase probability of stack regrowth.
wg.Add(1)
go func(level int) {
defer wg.Done()
zw, err := NewWriter(ioutil.Discard, level)
if err != nil {
t.Errorf("level %d, NewWriter() = %v, want nil", level, err)
}
if n, err := zw.Write(b); n != len(b) || err != nil {
t.Errorf("level %d, Write() = (%d, %v), want (%d, nil)", level, n, err, len(b))
}
if err := zw.Close(); err != nil {
t.Errorf("level %d, Close() = %v, want nil", level, err)
}
zw.Reset(ioutil.Discard)
}(level)
}
}

View File

@@ -60,7 +60,7 @@ func newDeflateFast() *deflateFast {
func (e *deflateFast) encode(dst []token, src []byte) []token {
// Ensure that e.cur doesn't wrap.
if e.cur > 1<<30 {
*e = deflateFast{cur: maxStoreBlockSize, prev: e.prev[:0]}
e.resetAll()
}
// This check isn't in the Snappy implementation, but there, the caller
@@ -265,6 +265,21 @@ func (e *deflateFast) reset() {
// Protect against e.cur wraparound.
if e.cur > 1<<30 {
*e = deflateFast{cur: maxStoreBlockSize, prev: e.prev[:0]}
e.resetAll()
}
}
// resetAll resets the deflateFast struct and is only called in rare
// situations to prevent integer overflow. It manually resets each field
// to avoid causing large stack growth.
//
// See https://golang.org/issue/18636.
func (e *deflateFast) resetAll() {
// This is equivalent to:
// *e = deflateFast{cur: maxStoreBlockSize, prev: e.prev[:0]}
e.cur = maxStoreBlockSize
e.prev = e.prev[:0]
for i := range e.table {
e.table[i] = tableEntry{}
}
}

View File

@@ -9,11 +9,17 @@ import (
"testing"
)
// Per golang.org/issue/14937, check that every .gz file
// in the tree has a zero mtime.
// TestGZIPFilesHaveZeroMTimes checks that every .gz file in the tree
// has a zero MTIME. This is a requirement for the Debian maintainers
// to be able to have deterministic packages.
//
// See https://golang.org/issue/14937.
func TestGZIPFilesHaveZeroMTimes(t *testing.T) {
if testing.Short() && testenv.Builder() == "" {
t.Skip("skipping in short mode")
// To avoid spurious false positives due to untracked GZIP files that
// may be in the user's GOROOT (Issue 18604), we only run this test on
// the builders, which should have a clean checkout of the tree.
if testenv.Builder() == "" {
t.Skip("skipping test on non-builder")
}
goroot, err := filepath.EvalSymlinks(runtime.GOROOT())
if err != nil {

View File

@@ -95,7 +95,7 @@ func TestSignAndVerify(t *testing.T) {
func TestSigningWithDegenerateKeys(t *testing.T) {
// Signing with degenerate private keys should not cause an infinite
// loop.
badKeys := []struct{
badKeys := []struct {
p, q, g, y, x string
}{
{"00", "01", "00", "00", "00"},
@@ -105,7 +105,7 @@ func TestSigningWithDegenerateKeys(t *testing.T) {
for i, test := range badKeys {
priv := PrivateKey{
PublicKey: PublicKey{
Parameters: Parameters {
Parameters: Parameters{
P: fromHex(test.p),
Q: fromHex(test.q),
G: fromHex(test.g),

View File

@@ -84,15 +84,15 @@ var cipherSuites = []*cipherSuite{
{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM},
{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12, cipherAES, macSHA256, nil},
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, cipherAES, macSHA256, nil},
{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
{TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, rsaKA, suiteTLS12, nil, nil, aeadAESGCM},
{TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
{TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12, cipherAES, macSHA256, nil},
{TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},

View File

@@ -6,8 +6,8 @@
package tls
// BUG(agl): The crypto/tls package only implements some countermeasures
// against Lucky13 attacks on CBC-mode encryption. See
// http://www.isg.rhul.ac.uk/tls/TLStiming.pdf and
// against Lucky13 attacks on CBC-mode encryption, and only on SHA1
// variants. See http://www.isg.rhul.ac.uk/tls/TLStiming.pdf and
// https://www.imperialviolet.org/2013/02/04/luckythirteen.html.
import (

View File

@@ -4,7 +4,11 @@
package x509
import "encoding/pem"
import (
"encoding/pem"
"errors"
"runtime"
)
// CertPool is a set of certificates.
type CertPool struct {
@@ -26,6 +30,11 @@ func NewCertPool() *CertPool {
// Any mutations to the returned pool are not written to disk and do
// not affect any other pool.
func SystemCertPool() (*CertPool, error) {
if runtime.GOOS == "windows" {
// Issue 16736, 18609:
return nil, errors.New("crypto/x509: system root pool is not available on Windows")
}
return loadSystemRoots()
}

View File

@@ -226,6 +226,11 @@ func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate
}
func loadSystemRoots() (*CertPool, error) {
// TODO: restore this functionality on Windows. We tried to do
// it in Go 1.8 but had to revert it. See Issue 18609.
// Returning (nil, nil) was the old behavior, prior to CL 30578.
return nil, nil
const CRYPT_E_NOT_FOUND = 0x80092004
store, err := syscall.CertOpenSystemStore(0, syscall.StringToUTF16Ptr("ROOT"))

View File

@@ -24,6 +24,7 @@ import (
"net"
"os/exec"
"reflect"
"runtime"
"strings"
"testing"
"time"
@@ -1477,6 +1478,9 @@ func TestMultipleRDN(t *testing.T) {
}
func TestSystemCertPool(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("not implemented on Windows; Issue 16736, 18609")
}
_, err := SystemCertPool()
if err != nil {
t.Fatal(err)

View File

@@ -1357,16 +1357,7 @@ func (db *DB) begin(ctx context.Context, opts *TxOptions, strategy connReuseStra
cancel: cancel,
ctx: ctx,
}
go func(tx *Tx) {
select {
case <-tx.ctx.Done():
if !tx.isDone() {
// Discard and close the connection used to ensure the transaction
// is closed and the resources are released.
tx.rollback(true)
}
}
}(tx)
go tx.awaitDone()
return tx, nil
}
@@ -1388,6 +1379,11 @@ func (db *DB) Driver() driver.Driver {
type Tx struct {
db *DB
// closemu prevents the transaction from closing while there
// is an active query. It is held for read during queries
// and exclusively during close.
closemu sync.RWMutex
// dc is owned exclusively until Commit or Rollback, at which point
// it's returned with putConn.
dc *driverConn
@@ -1413,6 +1409,20 @@ type Tx struct {
ctx context.Context
}
// awaitDone blocks until the context in Tx is canceled and rolls back
// the transaction if it's not already done.
func (tx *Tx) awaitDone() {
// Wait for either the transaction to be committed or rolled
// back, or for the associated context to be closed.
<-tx.ctx.Done()
// Discard and close the connection used to ensure the
// transaction is closed and the resources are released. This
// rollback does nothing if the transaction has already been
// committed or rolled back.
tx.rollback(true)
}
func (tx *Tx) isDone() bool {
return atomic.LoadInt32(&tx.done) != 0
}
@@ -1424,16 +1434,31 @@ var ErrTxDone = errors.New("sql: Transaction has already been committed or rolle
// close returns the connection to the pool and
// must only be called by Tx.rollback or Tx.Commit.
func (tx *Tx) close(err error) {
tx.closemu.Lock()
defer tx.closemu.Unlock()
tx.db.putConn(tx.dc, err)
tx.cancel()
tx.dc = nil
tx.txi = nil
}
// hookTxGrabConn specifies an optional hook to be called on
// a successful call to (*Tx).grabConn. For tests.
var hookTxGrabConn func()
func (tx *Tx) grabConn(ctx context.Context) (*driverConn, error) {
select {
default:
case <-ctx.Done():
return nil, ctx.Err()
}
if tx.isDone() {
return nil, ErrTxDone
}
if hookTxGrabConn != nil { // test hook
hookTxGrabConn()
}
return tx.dc, nil
}
@@ -1503,6 +1528,9 @@ func (tx *Tx) Rollback() error {
// for the execution of the returned statement. The returned statement
// will run in the transaction context.
func (tx *Tx) PrepareContext(ctx context.Context, query string) (*Stmt, error) {
tx.closemu.RLock()
defer tx.closemu.RUnlock()
// TODO(bradfitz): We could be more efficient here and either
// provide a method to take an existing Stmt (created on
// perhaps a different Conn), and re-create it on this Conn if
@@ -1567,6 +1595,9 @@ func (tx *Tx) Prepare(query string) (*Stmt, error) {
// The returned statement operates within the transaction and will be closed
// when the transaction has been committed or rolled back.
func (tx *Tx) StmtContext(ctx context.Context, stmt *Stmt) *Stmt {
tx.closemu.RLock()
defer tx.closemu.RUnlock()
// TODO(bradfitz): optimize this. Currently this re-prepares
// each time. This is fine for now to illustrate the API but
// we should really cache already-prepared statements
@@ -1618,6 +1649,9 @@ func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
// ExecContext executes a query that doesn't return rows.
// For example: an INSERT and UPDATE.
func (tx *Tx) ExecContext(ctx context.Context, query string, args ...interface{}) (Result, error) {
tx.closemu.RLock()
defer tx.closemu.RUnlock()
dc, err := tx.grabConn(ctx)
if err != nil {
return nil, err
@@ -1661,6 +1695,9 @@ func (tx *Tx) Exec(query string, args ...interface{}) (Result, error) {
// QueryContext executes a query that returns rows, typically a SELECT.
func (tx *Tx) QueryContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {
tx.closemu.RLock()
defer tx.closemu.RUnlock()
dc, err := tx.grabConn(ctx)
if err != nil {
return nil, err
@@ -2038,25 +2075,21 @@ type Rows struct {
// closed value is 1 when the Rows is closed.
// Use atomic operations on value when checking value.
closed int32
ctxClose chan struct{} // closed when Rows is closed, may be null.
cancel func() // called when Rows is closed, may be nil.
lastcols []driver.Value
lasterr error // non-nil only if closed is true
closeStmt *driverStmt // if non-nil, statement to Close on close
}
func (rs *Rows) initContextClose(ctx context.Context) {
if ctx.Done() == context.Background().Done() {
return
}
ctx, rs.cancel = context.WithCancel(ctx)
go rs.awaitDone(ctx)
}
rs.ctxClose = make(chan struct{})
go func() {
select {
case <-ctx.Done():
rs.Close()
case <-rs.ctxClose:
}
}()
// awaitDone blocks until the rows are closed or the context canceled.
func (rs *Rows) awaitDone(ctx context.Context) {
<-ctx.Done()
rs.Close()
}
// Next prepares the next result row for reading with the Scan method. It
@@ -2314,7 +2347,9 @@ func (rs *Rows) Scan(dest ...interface{}) error {
return nil
}
var rowsCloseHook func(*Rows, *error)
// rowsCloseHook returns a function so tests may install the
// hook throug a test only mutex.
var rowsCloseHook = func() func(*Rows, *error) { return nil }
func (rs *Rows) isClosed() bool {
return atomic.LoadInt32(&rs.closed) != 0
@@ -2328,13 +2363,15 @@ func (rs *Rows) Close() error {
if !atomic.CompareAndSwapInt32(&rs.closed, 0, 1) {
return nil
}
if rs.ctxClose != nil {
close(rs.ctxClose)
}
err := rs.rowsi.Close()
if fn := rowsCloseHook; fn != nil {
if fn := rowsCloseHook(); fn != nil {
fn(rs, &err)
}
if rs.cancel != nil {
rs.cancel()
}
if rs.closeStmt != nil {
rs.closeStmt.Close()
}

View File

@@ -14,6 +14,7 @@ import (
"runtime"
"strings"
"sync"
"sync/atomic"
"testing"
"time"
)
@@ -326,9 +327,7 @@ func TestQueryContext(t *testing.T) {
// And verify that the final rows.Next() call, which hit EOF,
// also closed the rows connection.
if n := db.numFreeConns(); n != 1 {
t.Fatalf("free conns after query hitting EOF = %d; want 1", n)
}
waitForFree(t, db, 5*time.Second, 1)
if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
t.Errorf("executed %d Prepare statements; want 1", prepares)
}
@@ -345,6 +344,18 @@ func waitCondition(waitFor, checkEvery time.Duration, fn func() bool) bool {
return false
}
// waitForFree checks db.numFreeConns until either it equals want or
// the maxWait time elapses.
func waitForFree(t *testing.T, db *DB, maxWait time.Duration, want int) {
var numFree int
if !waitCondition(maxWait, 5*time.Millisecond, func() bool {
numFree = db.numFreeConns()
return numFree == want
}) {
t.Fatalf("free conns after hitting EOF = %d; want %d", numFree, want)
}
}
func TestQueryContextWait(t *testing.T) {
db := newTestDB(t, "people")
defer closeDB(t, db)
@@ -361,9 +372,7 @@ func TestQueryContextWait(t *testing.T) {
}
// Verify closed rows connection after error condition.
if n := db.numFreeConns(); n != 1 {
t.Fatalf("free conns after query hitting EOF = %d; want 1", n)
}
waitForFree(t, db, 5*time.Second, 1)
if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
t.Errorf("executed %d Prepare statements; want 1", prepares)
}
@@ -388,13 +397,7 @@ func TestTxContextWait(t *testing.T) {
t.Fatalf("expected QueryContext to error with context deadline exceeded but returned %v", err)
}
var numFree int
if !waitCondition(5*time.Second, 5*time.Millisecond, func() bool {
numFree = db.numFreeConns()
return numFree == 0
}) {
t.Fatalf("free conns after hitting EOF = %d; want 0", numFree)
}
waitForFree(t, db, 5*time.Second, 0)
// Ensure the dropped connection allows more connections to be made.
// Checked on DB Close.
@@ -471,9 +474,7 @@ func TestMultiResultSetQuery(t *testing.T) {
// And verify that the final rows.Next() call, which hit EOF,
// also closed the rows connection.
if n := db.numFreeConns(); n != 1 {
t.Fatalf("free conns after query hitting EOF = %d; want 1", n)
}
waitForFree(t, db, 5*time.Second, 1)
if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
t.Errorf("executed %d Prepare statements; want 1", prepares)
}
@@ -1135,6 +1136,24 @@ func TestQueryRowClosingStmt(t *testing.T) {
}
}
var atomicRowsCloseHook atomic.Value // of func(*Rows, *error)
func init() {
rowsCloseHook = func() func(*Rows, *error) {
fn, _ := atomicRowsCloseHook.Load().(func(*Rows, *error))
return fn
}
}
func setRowsCloseHook(fn func(*Rows, *error)) {
if fn == nil {
// Can't change an atomic.Value back to nil, so set it to this
// no-op func instead.
fn = func(*Rows, *error) {}
}
atomicRowsCloseHook.Store(fn)
}
// Test issue 6651
func TestIssue6651(t *testing.T) {
db := newTestDB(t, "people")
@@ -1147,6 +1166,7 @@ func TestIssue6651(t *testing.T) {
return fmt.Errorf(want)
}
defer func() { rowsCursorNextHook = nil }()
err := db.QueryRow("SELECT|people|name|").Scan(&v)
if err == nil || err.Error() != want {
t.Errorf("error = %q; want %q", err, want)
@@ -1154,10 +1174,10 @@ func TestIssue6651(t *testing.T) {
rowsCursorNextHook = nil
want = "error in rows.Close"
rowsCloseHook = func(rows *Rows, err *error) {
setRowsCloseHook(func(rows *Rows, err *error) {
*err = fmt.Errorf(want)
}
defer func() { rowsCloseHook = nil }()
})
defer setRowsCloseHook(nil)
err = db.QueryRow("SELECT|people|name|").Scan(&v)
if err == nil || err.Error() != want {
t.Errorf("error = %q; want %q", err, want)
@@ -1830,7 +1850,9 @@ func TestStmtCloseDeps(t *testing.T) {
db.dumpDeps(t)
}
if len(stmt.css) > nquery {
if !waitCondition(5*time.Second, 5*time.Millisecond, func() bool {
return len(stmt.css) <= nquery
}) {
t.Errorf("len(stmt.css) = %d; want <= %d", len(stmt.css), nquery)
}
@@ -2576,10 +2598,10 @@ func TestIssue6081(t *testing.T) {
if err != nil {
t.Fatal(err)
}
rowsCloseHook = func(rows *Rows, err *error) {
setRowsCloseHook(func(rows *Rows, err *error) {
*err = driver.ErrBadConn
}
defer func() { rowsCloseHook = nil }()
})
defer setRowsCloseHook(nil)
for i := 0; i < 10; i++ {
rows, err := stmt.Query()
if err != nil {
@@ -2642,7 +2664,10 @@ func TestIssue18429(t *testing.T) {
if err != nil {
return
}
rows, err := tx.QueryContext(ctx, "WAIT|"+qwait+"|SELECT|people|name|")
// This is expected to give a cancel error many, but not all the time.
// Test failure will happen with a panic or other race condition being
// reported.
rows, _ := tx.QueryContext(ctx, "WAIT|"+qwait+"|SELECT|people|name|")
if rows != nil {
rows.Close()
}
@@ -2655,6 +2680,56 @@ func TestIssue18429(t *testing.T) {
time.Sleep(milliWait * 3 * time.Millisecond)
}
// TestIssue18719 closes the context right before use. The sql.driverConn
// will nil out the ci on close in a lock, but if another process uses it right after
// it will panic with on the nil ref.
//
// See https://golang.org/cl/35550 .
func TestIssue18719(t *testing.T) {
db := newTestDB(t, "people")
defer closeDB(t, db)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
tx, err := db.BeginTx(ctx, nil)
if err != nil {
t.Fatal(err)
}
hookTxGrabConn = func() {
cancel()
// Wait for the context to cancel and tx to rollback.
for tx.isDone() == false {
time.Sleep(time.Millisecond * 3)
}
}
defer func() { hookTxGrabConn = nil }()
// This call will grab the connection and cancel the context
// after it has done so. Code after must deal with the canceled state.
rows, err := tx.QueryContext(ctx, "SELECT|people|name|")
if err != nil {
rows.Close()
t.Fatalf("expected error %v but got %v", nil, err)
}
// Rows may be ignored because it will be closed when the context is canceled.
// Do not explicitly rollback. The rollback will happen from the
// canceled context.
// Wait for connections to return to pool.
var numOpen int
if !waitCondition(5*time.Second, 5*time.Millisecond, func() bool {
numOpen = db.numOpenConns()
return numOpen == 0
}) {
t.Fatalf("open conns after hitting EOF = %d; want 0", numOpen)
}
}
func TestConcurrency(t *testing.T) {
doConcurrentTest(t, new(concurrentDBQueryTest))
doConcurrentTest(t, new(concurrentDBExecTest))

View File

@@ -70,10 +70,8 @@ func (s *Scope) String() string {
// The Data fields contains object-specific data:
//
// Kind Data type Data value
// Pkg *types.Package package scope
// Pkg *Scope package scope
// Con int iota for the respective declaration
// Con != nil constant value
// Typ *Scope (used as method scope during type checking - transient)
//
type Object struct {
Kind ObjKind

View File

@@ -25,7 +25,7 @@ var files = flag.String("files", "", "consider only Go test files matching this
const dataDir = "testdata"
var templateTxt = readTemplate("template.txt")
var templateTxt *template.Template
func readTemplate(filename string) *template.Template {
t := template.New(filename)
@@ -96,6 +96,9 @@ func test(t *testing.T, mode Mode) {
if err != nil {
t.Fatal(err)
}
if templateTxt == nil {
templateTxt = readTemplate("template.txt")
}
// test packages
for _, pkg := range pkgs {

View File

@@ -10,17 +10,12 @@ import (
"testing"
)
var src = readFile("parser.go")
func readFile(filename string) []byte {
data, err := ioutil.ReadFile(filename)
if err != nil {
panic(err)
}
return data
}
func BenchmarkParse(b *testing.B) {
src, err := ioutil.ReadFile("parser.go")
if err != nil {
b.Fatal(err)
}
b.ResetTimer()
b.SetBytes(int64(len(src)))
for i := 0; i < b.N; i++ {
if _, err := ParseFile(token.NewFileSet(), "", src, ParseComments); err != nil {

View File

@@ -733,7 +733,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
case *ast.FuncLit:
p.expr(x.Type)
p.adjBlock(p.distanceFrom(x.Type.Pos()), blank, x.Body)
p.funcBody(p.distanceFrom(x.Type.Pos()), blank, x.Body)
case *ast.ParenExpr:
if _, hasParens := x.X.(*ast.ParenExpr); hasParens {
@@ -825,6 +825,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
if x.Type != nil {
p.expr1(x.Type, token.HighestPrec, depth)
}
p.level++
p.print(x.Lbrace, token.LBRACE)
p.exprList(x.Lbrace, x.Elts, 1, commaTerm, x.Rbrace)
// do not insert extra line break following a /*-style comment
@@ -837,6 +838,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
mode |= noExtraBlank
}
p.print(mode, x.Rbrace, token.RBRACE, mode)
p.level--
case *ast.Ellipsis:
p.print(token.ELLIPSIS)
@@ -1557,18 +1559,23 @@ func (p *printer) bodySize(b *ast.BlockStmt, maxSize int) int {
return bodySize
}
// adjBlock prints an "adjacent" block (e.g., a for-loop or function body) following
// a header (e.g., a for-loop control clause or function signature) of given headerSize.
// funcBody prints a function body following a function header of given headerSize.
// If the header's and block's size are "small enough" and the block is "simple enough",
// the block is printed on the current line, without line breaks, spaced from the header
// by sep. Otherwise the block's opening "{" is printed on the current line, followed by
// lines for the block's statements and its closing "}".
//
func (p *printer) adjBlock(headerSize int, sep whiteSpace, b *ast.BlockStmt) {
func (p *printer) funcBody(headerSize int, sep whiteSpace, b *ast.BlockStmt) {
if b == nil {
return
}
// save/restore composite literal nesting level
defer func(level int) {
p.level = level
}(p.level)
p.level = 0
const maxSize = 100
if headerSize+p.bodySize(b, maxSize) <= maxSize {
p.print(sep, b.Lbrace, token.LBRACE)
@@ -1613,7 +1620,7 @@ func (p *printer) funcDecl(d *ast.FuncDecl) {
}
p.expr(d.Name)
p.signature(d.Type.Params, d.Type.Results)
p.adjBlock(p.distanceFrom(d.Pos()), vtab, d.Body)
p.funcBody(p.distanceFrom(d.Pos()), vtab, d.Body)
}
func (p *printer) decl(decl ast.Decl) {

View File

@@ -58,6 +58,7 @@ type printer struct {
// Current state
output []byte // raw printer result
indent int // current indentation
level int // level == 0: outside composite literal; level > 0: inside composite literal
mode pmode // current printer mode
impliedSemi bool // if set, a linebreak implies a semicolon
lastTok token.Token // last token printed (token.ILLEGAL if it's whitespace)
@@ -744,15 +745,19 @@ func (p *printer) intersperseComments(next token.Position, tok token.Token) (wro
// follows on the same line but is not a comma, and not a "closing"
// token immediately following its corresponding "opening" token,
// add an extra separator unless explicitly disabled. Use a blank
// as separator unless we have pending linebreaks and they are not
// disabled, in which case we want a linebreak (issue 15137).
// as separator unless we have pending linebreaks, they are not
// disabled, and we are outside a composite literal, in which case
// we want a linebreak (issue 15137).
// TODO(gri) This has become overly complicated. We should be able
// to track whether we're inside an expression or statement and
// use that information to decide more directly.
needsLinebreak := false
if p.mode&noExtraBlank == 0 &&
last.Text[1] == '*' && p.lineFor(last.Pos()) == next.Line &&
tok != token.COMMA &&
(tok != token.RPAREN || p.prevOpen == token.LPAREN) &&
(tok != token.RBRACK || p.prevOpen == token.LBRACK) {
if p.containsLinebreak() && p.mode&noExtraLinebreak == 0 {
if p.containsLinebreak() && p.mode&noExtraLinebreak == 0 && p.level == 0 {
needsLinebreak = true
} else {
p.writeByte(' ', 1)

View File

@@ -103,3 +103,62 @@ label:
mask := uint64(1)<<c - 1 // Allocation mask
used := atomic.LoadUint64(&h.used) // Current allocations
}
// Test cases for issue 18782
var _ = [][]int{
/* a, b, c, d, e */
/* a */ {0, 0, 0, 0, 0},
/* b */ {0, 5, 4, 4, 4},
/* c */ {0, 4, 5, 4, 4},
/* d */ {0, 4, 4, 5, 4},
/* e */ {0, 4, 4, 4, 5},
}
var _ = T{ /* a */ 0}
var _ = T{ /* a */ /* b */ 0}
var _ = T{ /* a */ /* b */
/* c */ 0,
}
var _ = T{ /* a */ /* b */
/* c */
/* d */ 0,
}
var _ = T{
/* a */
/* b */ 0,
}
var _ = T{ /* a */ {}}
var _ = T{ /* a */ /* b */ {}}
var _ = T{ /* a */ /* b */
/* c */ {},
}
var _ = T{ /* a */ /* b */
/* c */
/* d */ {},
}
var _ = T{
/* a */
/* b */ {},
}
var _ = []T{
func() {
var _ = [][]int{
/* a, b, c, d, e */
/* a */ {0, 0, 0, 0, 0},
/* b */ {0, 5, 4, 4, 4},
/* c */ {0, 4, 5, 4, 4},
/* d */ {0, 4, 4, 5, 4},
/* e */ {0, 4, 4, 4, 5},
}
},
}

View File

@@ -103,3 +103,66 @@ label:
mask := uint64(1)<<c - 1 // Allocation mask
used := atomic.LoadUint64(&h.used) // Current allocations
}
// Test cases for issue 18782
var _ = [][]int{
/* a, b, c, d, e */
/* a */ {0, 0, 0, 0, 0},
/* b */ {0, 5, 4, 4, 4},
/* c */ {0, 4, 5, 4, 4},
/* d */ {0, 4, 4, 5, 4},
/* e */ {0, 4, 4, 4, 5},
}
var _ = T{ /* a */ 0,
}
var _ = T{ /* a */ /* b */ 0,
}
var _ = T{ /* a */ /* b */
/* c */ 0,
}
var _ = T{ /* a */ /* b */
/* c */
/* d */ 0,
}
var _ = T{
/* a */
/* b */ 0,
}
var _ = T{ /* a */ {},
}
var _ = T{ /* a */ /* b */ {},
}
var _ = T{ /* a */ /* b */
/* c */ {},
}
var _ = T{ /* a */ /* b */
/* c */
/* d */ {},
}
var _ = T{
/* a */
/* b */ {},
}
var _ = []T{
func() {
var _ = [][]int{
/* a, b, c, d, e */
/* a */ {0, 0, 0, 0, 0},
/* b */ {0, 5, 4, 4, 4},
/* c */ {0, 4, 5, 4, 4},
/* d */ {0, 4, 4, 5, 4},
/* e */ {0, 4, 4, 4, 5},
}
},
}

View File

@@ -413,11 +413,12 @@ func (c *Client) checkRedirect(req *Request, via []*Request) error {
// redirectBehavior describes what should happen when the
// client encounters a 3xx status code from the server
func redirectBehavior(reqMethod string, resp *Response, ireq *Request) (redirectMethod string, shouldRedirect bool) {
func redirectBehavior(reqMethod string, resp *Response, ireq *Request) (redirectMethod string, shouldRedirect, includeBody bool) {
switch resp.StatusCode {
case 301, 302, 303:
redirectMethod = reqMethod
shouldRedirect = true
includeBody = false
// RFC 2616 allowed automatic redirection only with GET and
// HEAD requests. RFC 7231 lifts this restriction, but we still
@@ -429,6 +430,7 @@ func redirectBehavior(reqMethod string, resp *Response, ireq *Request) (redirect
case 307, 308:
redirectMethod = reqMethod
shouldRedirect = true
includeBody = true
// Treat 307 and 308 specially, since they're new in
// Go 1.8, and they also require re-sending the request body.
@@ -449,7 +451,7 @@ func redirectBehavior(reqMethod string, resp *Response, ireq *Request) (redirect
shouldRedirect = false
}
}
return redirectMethod, shouldRedirect
return redirectMethod, shouldRedirect, includeBody
}
// Do sends an HTTP request and returns an HTTP response, following
@@ -492,11 +494,14 @@ func (c *Client) Do(req *Request) (*Response, error) {
}
var (
deadline = c.deadline()
reqs []*Request
resp *Response
copyHeaders = c.makeHeadersCopier(req)
deadline = c.deadline()
reqs []*Request
resp *Response
copyHeaders = c.makeHeadersCopier(req)
// Redirect behavior:
redirectMethod string
includeBody bool
)
uerr := func(err error) error {
req.closeBody()
@@ -534,7 +539,7 @@ func (c *Client) Do(req *Request) (*Response, error) {
Cancel: ireq.Cancel,
ctx: ireq.ctx,
}
if ireq.GetBody != nil {
if includeBody && ireq.GetBody != nil {
req.Body, err = ireq.GetBody()
if err != nil {
return nil, uerr(err)
@@ -598,7 +603,7 @@ func (c *Client) Do(req *Request) (*Response, error) {
}
var shouldRedirect bool
redirectMethod, shouldRedirect = redirectBehavior(req.Method, resp, reqs[0])
redirectMethod, shouldRedirect, includeBody = redirectBehavior(req.Method, resp, reqs[0])
if !shouldRedirect {
return resp, nil
}

View File

@@ -360,25 +360,25 @@ func TestPostRedirects(t *testing.T) {
wantSegments := []string{
`POST / "first"`,
`POST /?code=301&next=302 "c301"`,
`GET /?code=302 "c301"`,
`GET / "c301"`,
`GET /?code=302 ""`,
`GET / ""`,
`POST /?code=302&next=302 "c302"`,
`GET /?code=302 "c302"`,
`GET / "c302"`,
`GET /?code=302 ""`,
`GET / ""`,
`POST /?code=303&next=301 "c303wc301"`,
`GET /?code=301 "c303wc301"`,
`GET / "c303wc301"`,
`GET /?code=301 ""`,
`GET / ""`,
`POST /?code=304 "c304"`,
`POST /?code=305 "c305"`,
`POST /?code=307&next=303,308,302 "c307"`,
`POST /?code=303&next=308,302 "c307"`,
`GET /?code=308&next=302 "c307"`,
`GET /?code=308&next=302 ""`,
`GET /?code=302 "c307"`,
`GET / "c307"`,
`GET / ""`,
`POST /?code=308&next=302,301 "c308"`,
`POST /?code=302&next=301 "c308"`,
`GET /?code=301 "c308"`,
`GET / "c308"`,
`GET /?code=301 ""`,
`GET / ""`,
`POST /?code=404 "c404"`,
}
want := strings.Join(wantSegments, "\n")
@@ -399,20 +399,20 @@ func TestDeleteRedirects(t *testing.T) {
wantSegments := []string{
`DELETE / "first"`,
`DELETE /?code=301&next=302,308 "c301"`,
`GET /?code=302&next=308 "c301"`,
`GET /?code=308 "c301"`,
`GET /?code=302&next=308 ""`,
`GET /?code=308 ""`,
`GET / "c301"`,
`DELETE /?code=302&next=302 "c302"`,
`GET /?code=302 "c302"`,
`GET / "c302"`,
`GET /?code=302 ""`,
`GET / ""`,
`DELETE /?code=303 "c303"`,
`GET / "c303"`,
`GET / ""`,
`DELETE /?code=307&next=301,308,303,302,304 "c307"`,
`DELETE /?code=301&next=308,303,302,304 "c307"`,
`GET /?code=308&next=303,302,304 "c307"`,
`GET /?code=308&next=303,302,304 ""`,
`GET /?code=303&next=302,304 "c307"`,
`GET /?code=302&next=304 "c307"`,
`GET /?code=304 "c307"`,
`GET /?code=302&next=304 ""`,
`GET /?code=304 ""`,
`DELETE /?code=308&next=307 "c308"`,
`DELETE /?code=307 "c308"`,
`DELETE / "c308"`,
@@ -432,7 +432,11 @@ func testRedirectsByMethod(t *testing.T, method string, table []redirectTest, wa
ts = httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
log.Lock()
slurp, _ := ioutil.ReadAll(r.Body)
fmt.Fprintf(&log.Buffer, "%s %s %q\n", r.Method, r.RequestURI, slurp)
fmt.Fprintf(&log.Buffer, "%s %s %q", r.Method, r.RequestURI, slurp)
if cl := r.Header.Get("Content-Length"); r.Method == "GET" && len(slurp) == 0 && (r.ContentLength != 0 || cl != "") {
fmt.Fprintf(&log.Buffer, " (but with body=%T, content-length = %v, %q)", r.Body, r.ContentLength, cl)
}
log.WriteByte('\n')
log.Unlock()
urlQuery := r.URL.Query()
if v := urlQuery.Get("code"); v != "" {
@@ -475,7 +479,24 @@ func testRedirectsByMethod(t *testing.T, method string, table []redirectTest, wa
want = strings.TrimSpace(want)
if got != want {
t.Errorf("Log differs.\n Got:\n%s\nWant:\n%s\n", got, want)
got, want, lines := removeCommonLines(got, want)
t.Errorf("Log differs after %d common lines.\n\nGot:\n%s\n\nWant:\n%s\n", lines, got, want)
}
}
func removeCommonLines(a, b string) (asuffix, bsuffix string, commonLines int) {
for {
nl := strings.IndexByte(a, '\n')
if nl < 0 {
return a, b, commonLines
}
line := a[:nl+1]
if !strings.HasPrefix(b, line) {
return a, b, commonLines
}
commonLines++
a = a[len(line):]
b = b[len(line):]
}
}

View File

@@ -5173,3 +5173,142 @@ func TestServerDuplicateBackgroundRead(t *testing.T) {
}
wg.Wait()
}
// Test that the bufio.Reader returned by Hijack includes any buffered
// byte (from the Server's backgroundRead) in its buffer. We want the
// Handler code to be able to tell that a byte is available via
// bufio.Reader.Buffered(), without resorting to Reading it
// (potentially blocking) to get at it.
func TestServerHijackGetsBackgroundByte(t *testing.T) {
if runtime.GOOS == "plan9" {
t.Skip("skipping test; see https://golang.org/issue/18657")
}
setParallel(t)
defer afterTest(t)
done := make(chan struct{})
inHandler := make(chan bool, 1)
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
defer close(done)
// Tell the client to send more data after the GET request.
inHandler <- true
// Wait until the HTTP server sees the extra data
// after the GET request. The HTTP server fires the
// close notifier here, assuming it's a pipelined
// request, as documented.
select {
case <-w.(CloseNotifier).CloseNotify():
case <-time.After(5 * time.Second):
t.Error("timeout")
return
}
conn, buf, err := w.(Hijacker).Hijack()
if err != nil {
t.Error(err)
return
}
defer conn.Close()
n := buf.Reader.Buffered()
if n != 1 {
t.Errorf("buffered data = %d; want 1", n)
}
peek, err := buf.Reader.Peek(3)
if string(peek) != "foo" || err != nil {
t.Errorf("Peek = %q, %v; want foo, nil", peek, err)
}
}))
defer ts.Close()
cn, err := net.Dial("tcp", ts.Listener.Addr().String())
if err != nil {
t.Fatal(err)
}
defer cn.Close()
if _, err := cn.Write([]byte("GET / HTTP/1.1\r\nHost: e.com\r\n\r\n")); err != nil {
t.Fatal(err)
}
<-inHandler
if _, err := cn.Write([]byte("foo")); err != nil {
t.Fatal(err)
}
if err := cn.(*net.TCPConn).CloseWrite(); err != nil {
t.Fatal(err)
}
select {
case <-done:
case <-time.After(2 * time.Second):
t.Error("timeout")
}
}
// Like TestServerHijackGetsBackgroundByte above but sending a
// immediate 1MB of data to the server to fill up the server's 4KB
// buffer.
func TestServerHijackGetsBackgroundByte_big(t *testing.T) {
if runtime.GOOS == "plan9" {
t.Skip("skipping test; see https://golang.org/issue/18657")
}
setParallel(t)
defer afterTest(t)
done := make(chan struct{})
const size = 8 << 10
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
defer close(done)
// Wait until the HTTP server sees the extra data
// after the GET request. The HTTP server fires the
// close notifier here, assuming it's a pipelined
// request, as documented.
select {
case <-w.(CloseNotifier).CloseNotify():
case <-time.After(5 * time.Second):
t.Error("timeout")
return
}
conn, buf, err := w.(Hijacker).Hijack()
if err != nil {
t.Error(err)
return
}
defer conn.Close()
slurp, err := ioutil.ReadAll(buf.Reader)
if err != nil {
t.Errorf("Copy: %v", err)
}
allX := true
for _, v := range slurp {
if v != 'x' {
allX = false
}
}
if len(slurp) != size {
t.Errorf("read %d; want %d", len(slurp), size)
} else if !allX {
t.Errorf("read %q; want %d 'x'", slurp, size)
}
}))
defer ts.Close()
cn, err := net.Dial("tcp", ts.Listener.Addr().String())
if err != nil {
t.Fatal(err)
}
defer cn.Close()
if _, err := fmt.Fprintf(cn, "GET / HTTP/1.1\r\nHost: e.com\r\n\r\n%s",
strings.Repeat("x", size)); err != nil {
t.Fatal(err)
}
if err := cn.(*net.TCPConn).CloseWrite(); err != nil {
t.Fatal(err)
}
select {
case <-done:
case <-time.After(2 * time.Second):
t.Error("timeout")
}
}

View File

@@ -164,7 +164,7 @@ type Flusher interface {
// should always test for this ability at runtime.
type Hijacker interface {
// Hijack lets the caller take over the connection.
// After a call to Hijack(), the HTTP server library
// After a call to Hijack the HTTP server library
// will not do anything else with the connection.
//
// It becomes the caller's responsibility to manage
@@ -174,6 +174,9 @@ type Hijacker interface {
// already set, depending on the configuration of the
// Server. It is the caller's responsibility to set
// or clear those deadlines as needed.
//
// The returned bufio.Reader may contain unprocessed buffered
// data from the client.
Hijack() (net.Conn, *bufio.ReadWriter, error)
}
@@ -293,6 +296,11 @@ func (c *conn) hijackLocked() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
rwc.SetDeadline(time.Time{})
buf = bufio.NewReadWriter(c.bufr, bufio.NewWriter(rwc))
if c.r.hasByte {
if _, err := c.bufr.Peek(c.bufr.Buffered() + 1); err != nil {
return nil, nil, fmt.Errorf("unexpected Peek failure reading buffered byte: %v", err)
}
}
c.setState(rwc, StateHijacked)
return
}

View File

@@ -36,6 +36,7 @@ import (
"strconv"
"strings"
"sync"
"sync/atomic"
"testing"
"time"
)
@@ -2545,6 +2546,13 @@ type closerFunc func() error
func (f closerFunc) Close() error { return f() }
type writerFuncConn struct {
net.Conn
write func(p []byte) (n int, err error)
}
func (c writerFuncConn) Write(p []byte) (n int, err error) { return c.write(p) }
// Issue 4677. If we try to reuse a connection that the server is in the
// process of closing, we may end up successfully writing out our request (or a
// portion of our request) only to find a connection error when we try to read
@@ -2557,66 +2565,78 @@ func (f closerFunc) Close() error { return f() }
func TestRetryIdempotentRequestsOnError(t *testing.T) {
defer afterTest(t)
var (
mu sync.Mutex
logbuf bytes.Buffer
)
logf := func(format string, args ...interface{}) {
mu.Lock()
defer mu.Unlock()
fmt.Fprintf(&logbuf, format, args...)
logbuf.WriteByte('\n')
}
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
logf("Handler")
w.Header().Set("X-Status", "ok")
}))
defer ts.Close()
tr := &Transport{}
var writeNumAtomic int32
tr := &Transport{
Dial: func(network, addr string) (net.Conn, error) {
logf("Dial")
c, err := net.Dial(network, ts.Listener.Addr().String())
if err != nil {
logf("Dial error: %v", err)
return nil, err
}
return &writerFuncConn{
Conn: c,
write: func(p []byte) (n int, err error) {
if atomic.AddInt32(&writeNumAtomic, 1) == 2 {
logf("intentional write failure")
return 0, errors.New("second write fails")
}
logf("Write(%q)", p)
return c.Write(p)
},
}, nil
},
}
defer tr.CloseIdleConnections()
c := &Client{Transport: tr}
const N = 2
retryc := make(chan struct{}, N)
SetRoundTripRetried(func() {
retryc <- struct{}{}
logf("Retried.")
})
defer SetRoundTripRetried(nil)
for n := 0; n < 100; n++ {
// open 2 conns
errc := make(chan error, N)
for i := 0; i < N; i++ {
// start goroutines, send on errc
go func() {
res, err := c.Get(ts.URL)
if err == nil {
res.Body.Close()
}
errc <- err
}()
}
for i := 0; i < N; i++ {
if err := <-errc; err != nil {
t.Fatal(err)
}
}
ts.CloseClientConnections()
for i := 0; i < N; i++ {
go func() {
res, err := c.Get(ts.URL)
if err == nil {
res.Body.Close()
}
errc <- err
}()
}
for i := 0; i < N; i++ {
if err := <-errc; err != nil {
t.Fatal(err)
}
}
for i := 0; i < N; i++ {
select {
case <-retryc:
// we triggered a retry, test was successful
t.Logf("finished after %d runs\n", n)
return
default:
}
for i := 0; i < 3; i++ {
res, err := c.Get("http://fake.golang/")
if err != nil {
t.Fatalf("i=%d: Get = %v", i, err)
}
res.Body.Close()
}
mu.Lock()
got := logbuf.String()
mu.Unlock()
const want = `Dial
Write("GET / HTTP/1.1\r\nHost: fake.golang\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n")
Handler
intentional write failure
Retried.
Dial
Write("GET / HTTP/1.1\r\nHost: fake.golang\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n")
Handler
Write("GET / HTTP/1.1\r\nHost: fake.golang\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n")
Handler
`
if got != want {
t.Errorf("Log of events differs. Got:\n%s\nWant:\n%s", got, want)
}
t.Fatal("did not trigger any retries")
}
// Issue 6981

View File

@@ -54,12 +54,15 @@ var sysdir = func() *sysDir {
case "darwin":
switch runtime.GOARCH {
case "arm", "arm64":
/// At this point the test harness has not had a chance
// to move us into the ./src/os directory, so the
// current working directory is the root of the app.
wd, err := syscall.Getwd()
if err != nil {
wd = err.Error()
}
return &sysDir{
filepath.Join(wd, "..", ".."),
wd,
[]string{
"ResourceRules.plist",
"Info.plist",

View File

@@ -26,6 +26,8 @@ import (
"unsafe"
)
var sink interface{}
func TestBool(t *testing.T) {
v := ValueOf(true)
if v.Bool() != true {
@@ -5331,6 +5333,72 @@ func TestCallGC(t *testing.T) {
f2("four", "five5", "six666", "seven77", "eight888")
}
// Issue 18635 (function version).
func TestKeepFuncLive(t *testing.T) {
// Test that we keep makeFuncImpl live as long as it is
// referenced on the stack.
typ := TypeOf(func(i int) {})
var f, g func(in []Value) []Value
f = func(in []Value) []Value {
clobber()
i := int(in[0].Int())
if i > 0 {
// We can't use Value.Call here because
// runtime.call* will keep the makeFuncImpl
// alive. However, by converting it to an
// interface value and calling that,
// reflect.callReflect is the only thing that
// can keep the makeFuncImpl live.
//
// Alternate between f and g so that if we do
// reuse the memory prematurely it's more
// likely to get obviously corrupted.
MakeFunc(typ, g).Interface().(func(i int))(i - 1)
}
return nil
}
g = func(in []Value) []Value {
clobber()
i := int(in[0].Int())
MakeFunc(typ, f).Interface().(func(i int))(i)
return nil
}
MakeFunc(typ, f).Call([]Value{ValueOf(10)})
}
// Issue 18635 (method version).
type KeepMethodLive struct{}
func (k KeepMethodLive) Method1(i int) {
clobber()
if i > 0 {
ValueOf(k).MethodByName("Method2").Interface().(func(i int))(i - 1)
}
}
func (k KeepMethodLive) Method2(i int) {
clobber()
ValueOf(k).MethodByName("Method1").Interface().(func(i int))(i)
}
func TestKeepMethodLive(t *testing.T) {
// Test that we keep methodValue live as long as it is
// referenced on the stack.
KeepMethodLive{}.Method1(10)
}
// clobber tries to clobber unreachable memory.
func clobber() {
runtime.GC()
for i := 1; i < 32; i++ {
for j := 0; j < 10; j++ {
obj := make([]*byte, i)
sink = obj
}
}
runtime.GC()
}
type funcLayoutTest struct {
rcvr, t Type
size, argsize, retOffset uintptr

View File

@@ -538,6 +538,11 @@ func callReflect(ctxt *makeFuncImpl, frame unsafe.Pointer) {
off += typ.size
}
}
// runtime.getArgInfo expects to be able to find ctxt on the
// stack when it finds our caller, makeFuncStub. Make sure it
// doesn't get garbage collected.
runtime.KeepAlive(ctxt)
}
// methodReceiver returns information about the receiver
@@ -650,6 +655,9 @@ func callMethod(ctxt *methodValue, frame unsafe.Pointer) {
// though it's a heap object.
memclrNoHeapPointers(args, frametype.size)
framePool.Put(args)
// See the comment in callReflect.
runtime.KeepAlive(ctxt)
}
// funcName returns the name of f, for use in error messages.

View File

@@ -146,10 +146,16 @@ move_1or2:
move_0:
RET
move_3or4:
CMPQ BX, $4
JB move_3
MOVL (SI), AX
MOVL AX, (DI)
RET
move_3:
MOVW (SI), AX
MOVW -2(SI)(BX*1), CX
MOVB 2(SI), CX
MOVW AX, (DI)
MOVW CX, -2(DI)(BX*1)
MOVB CX, 2(DI)
RET
move_5through7:
MOVL (SI), AX

View File

@@ -6,6 +6,7 @@ package runtime_test
import (
"crypto/rand"
"encoding/binary"
"fmt"
"internal/race"
. "runtime"
@@ -447,3 +448,22 @@ func BenchmarkCopyFat1024(b *testing.B) {
_ = y
}
}
func BenchmarkIssue18740(b *testing.B) {
// This tests that memmove uses one 4-byte load/store to move 4 bytes.
// It used to do 2 2-byte load/stores, which leads to a pipeline stall
// when we try to read the result with one 4-byte load.
var buf [4]byte
for j := 0; j < b.N; j++ {
s := uint32(0)
for i := 0; i < 4096; i += 4 {
copy(buf[:], g[i:])
s += binary.LittleEndian.Uint32(buf[:])
}
sink = uint64(s)
}
}
// TODO: 2 byte and 8 byte benchmarks also.
var g [4096]byte

View File

@@ -1129,8 +1129,6 @@ top:
// sitting in the per-P work caches.
// Flush and disable work caches.
gcMarkRootCheck()
// Disallow caching workbufs and indicate that we're in mark 2.
gcBlackenPromptly = true
@@ -1153,6 +1151,16 @@ top:
})
})
// Check that roots are marked. We should be able to
// do this before the forEachP, but based on issue
// #16083 there may be a (harmless) race where we can
// enter mark 2 while some workers are still scanning
// stacks. The forEachP ensures these scans are done.
//
// TODO(austin): Figure out the race and fix this
// properly.
gcMarkRootCheck()
// Now we can start up mark 2 workers.
atomic.Xaddint64(&gcController.dedicatedMarkWorkersNeeded, 0xffffffff)
atomic.Xaddint64(&gcController.fractionalMarkWorkersNeeded, 0xffffffff)

View File

@@ -28,9 +28,11 @@ const msanenabled = true
// the runtime, but operations like a slice copy can call msanread
// anyhow for values on the stack. Just ignore msanread when running
// on the system stack. The other msan functions are fine.
//
//go:nosplit
func msanread(addr unsafe.Pointer, sz uintptr) {
g := getg()
if g == g.m.g0 || g == g.m.gsignal {
if g == nil || g.m == nil || g == g.m.g0 || g == g.m.gsignal {
return
}
domsanread(addr, sz)

View File

@@ -56,7 +56,9 @@ func plugin_lastmoduleinit() (path string, syms map[string]interface{}, mismatch
lock(&ifaceLock)
for _, i := range md.itablinks {
additab(i, true, false)
if i.inhash == 0 {
additab(i, true, false)
}
}
unlock(&ifaceLock)

View File

@@ -7,6 +7,7 @@ package runtime_test
import (
"bytes"
"fmt"
"go/build"
"internal/testenv"
"io/ioutil"
"os"
@@ -67,7 +68,6 @@ func checkGdbPython(t *testing.T) {
}
const helloSource = `
package main
import "fmt"
var gslice []string
func main() {
@@ -85,9 +85,20 @@ func main() {
`
func TestGdbPython(t *testing.T) {
testGdbPython(t, false)
}
func TestGdbPythonCgo(t *testing.T) {
testGdbPython(t, true)
}
func testGdbPython(t *testing.T, cgo bool) {
if runtime.GOARCH == "mips64" {
testenv.SkipFlaky(t, 18173)
}
if cgo && !build.Default.CgoEnabled {
t.Skip("skipping because cgo is not enabled")
}
t.Parallel()
checkGdbEnvironment(t)
@@ -100,8 +111,15 @@ func TestGdbPython(t *testing.T) {
}
defer os.RemoveAll(dir)
var buf bytes.Buffer
buf.WriteString("package main\n")
if cgo {
buf.WriteString(`import "C"` + "\n")
}
buf.WriteString(helloSource)
src := filepath.Join(dir, "main.go")
err = ioutil.WriteFile(src, []byte(helloSource), 0644)
err = ioutil.WriteFile(src, buf.Bytes(), 0644)
if err != nil {
t.Fatalf("failed to create file: %v", err)
}

View File

@@ -285,6 +285,25 @@ func modulesinit() {
md.gcbssmask = progToPointerMask((*byte)(unsafe.Pointer(md.gcbss)), md.ebss-md.bss)
}
}
// Modules appear in the moduledata linked list in the order they are
// loaded by the dynamic loader, with one exception: the
// firstmoduledata itself the module that contains the runtime. This
// is not always the first module (when using -buildmode=shared, it
// is typically libstd.so, the second module). The order matters for
// typelinksinit, so we swap the first module with whatever module
// contains the main function.
//
// See Issue #18729.
mainText := funcPC(main_main)
for i, md := range *modules {
if md.text <= mainText && mainText <= md.etext {
(*modules)[0] = md
(*modules)[i] = &firstmoduledata
break
}
}
atomicstorep(unsafe.Pointer(&modulesSlice), unsafe.Pointer(modules))
}

View File

@@ -330,9 +330,9 @@ sigtrampnog:
// Lock sigprofCallersUse.
MOVL $0, AX
MOVL $1, CX
MOVQ $runtime·sigprofCallersUse(SB), BX
MOVQ $runtime·sigprofCallersUse(SB), R11
LOCK
CMPXCHGL CX, 0(BX)
CMPXCHGL CX, 0(R11)
JNZ sigtramp // Skip stack trace if already locked.
// Jump to the traceback function in runtime/cgo.

View File

@@ -18,6 +18,7 @@ import (
"log"
"os"
"regexp"
"strings"
)
func main() {
@@ -38,10 +39,16 @@ func main() {
re = regexp.MustCompile("Pad_cgo[A-Za-z0-9_]*")
s = re.ReplaceAllString(s, "_")
// We want to keep X__val in Fsid. Hide it and restore it later.
s = strings.Replace(s, "X__val", "MKPOSTFSIDVAL", 1)
// Replace other unwanted fields with blank identifiers.
re = regexp.MustCompile("X_[A-Za-z0-9_]*")
s = re.ReplaceAllString(s, "_")
// Restore X__val in Fsid.
s = strings.Replace(s, "MKPOSTFSIDVAL", "X__val", 1)
// Force the type of RawSockaddr.Data to [14]int8 to match
// the existing gccgo API.
re = regexp.MustCompile("(Data\\s+\\[14\\])uint8")

View File

@@ -140,7 +140,7 @@ type Dirent struct {
}
type Fsid struct {
_ [2]int32
X__val [2]int32
}
type Flock_t struct {

View File

@@ -219,7 +219,7 @@ func (b *B) run1() bool {
}
// Only print the output if we know we are not going to proceed.
// Otherwise it is printed in processBench.
if b.hasSub || b.finished {
if atomic.LoadInt32(&b.hasSub) != 0 || b.finished {
tag := "BENCH"
if b.skipped {
tag = "SKIP"
@@ -460,10 +460,13 @@ func (ctx *benchContext) processBench(b *B) {
//
// A subbenchmark is like any other benchmark. A benchmark that calls Run at
// least once will not be measured itself and will be called once with N=1.
//
// Run may be called simultaneously from multiple goroutines, but all such
// calls must happen before the outer benchmark function for b returns.
func (b *B) Run(name string, f func(b *B)) bool {
// Since b has subbenchmarks, we will no longer run it as a benchmark itself.
// Release the lock and acquire it on exit to ensure locks stay paired.
b.hasSub = true
atomic.StoreInt32(&b.hasSub, 1)
benchmarkLock.Unlock()
defer benchmarkLock.Lock()

View File

@@ -6,6 +6,7 @@ package testing
import (
"bytes"
"fmt"
"regexp"
"strings"
"sync/atomic"
@@ -515,3 +516,19 @@ func TestBenchmarkOutput(t *T) {
Benchmark(func(b *B) { b.Error("do not print this output") })
Benchmark(func(b *B) {})
}
func TestParallelSub(t *T) {
c := make(chan int)
block := make(chan int)
for i := 0; i < 10; i++ {
go func(i int) {
<-block
t.Run(fmt.Sprint(i), func(t *T) {})
c <- 1
}(i)
}
close(block)
for i := 0; i < 10; i++ {
<-c
}
}

View File

@@ -216,6 +216,7 @@ import (
"strconv"
"strings"
"sync"
"sync/atomic"
"time"
)
@@ -267,8 +268,8 @@ type common struct {
skipped bool // Test of benchmark has been skipped.
finished bool // Test function has completed.
done bool // Test is finished and all subtests have completed.
hasSub bool
raceErrors int // number of races detected during test
hasSub int32 // written atomically
raceErrors int // number of races detected during test
parent *common
level int // Nesting depth of test or benchmark.
@@ -645,7 +646,7 @@ func tRunner(t *T, fn func(t *T)) {
// Do not lock t.done to allow race detector to detect race in case
// the user does not appropriately synchronizes a goroutine.
t.done = true
if t.parent != nil && !t.hasSub {
if t.parent != nil && atomic.LoadInt32(&t.hasSub) == 0 {
t.setRan()
}
t.signal <- true
@@ -659,8 +660,11 @@ func tRunner(t *T, fn func(t *T)) {
// Run runs f as a subtest of t called name. It reports whether f succeeded.
// Run will block until all its parallel subtests have completed.
//
// Run may be called simultaneously from multiple goroutines, but all such
// calls must happen before the outer test function for t returns.
func (t *T) Run(name string, f func(t *T)) bool {
t.hasSub = true
atomic.StoreInt32(&t.hasSub, 1)
testName, ok := t.context.match.fullName(&t.common, name)
if !ok {
return true

View File

@@ -54,9 +54,9 @@
ADCQ t3, h1; \
ADCQ $0, h2
DATA poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
DATA poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
GLOBL poly1305Mask<>(SB), RODATA, $16
DATA ·poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
GLOBL ·poly1305Mask<>(SB), RODATA, $16
// func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]key)
TEXT ·poly1305(SB), $0-32
@@ -67,8 +67,8 @@ TEXT ·poly1305(SB), $0-32
MOVQ 0(AX), R11
MOVQ 8(AX), R12
ANDQ poly1305Mask<>(SB), R11 // r0
ANDQ poly1305Mask<>+8(SB), R12 // r1
ANDQ ·poly1305Mask<>(SB), R11 // r0
ANDQ ·poly1305Mask<>+8(SB), R12 // r1
XORQ R8, R8 // h0
XORQ R9, R9 // h1
XORQ R10, R10 // h2

View File

@@ -9,12 +9,12 @@
// This code was translated into a form compatible with 5a from the public
// domain source by Andrew Moon: github.com/floodyberry/poly1305-opt/blob/master/app/extensions/poly1305.
DATA poly1305_init_constants_armv6<>+0x00(SB)/4, $0x3ffffff
DATA poly1305_init_constants_armv6<>+0x04(SB)/4, $0x3ffff03
DATA poly1305_init_constants_armv6<>+0x08(SB)/4, $0x3ffc0ff
DATA poly1305_init_constants_armv6<>+0x0c(SB)/4, $0x3f03fff
DATA poly1305_init_constants_armv6<>+0x10(SB)/4, $0x00fffff
GLOBL poly1305_init_constants_armv6<>(SB), 8, $20
DATA ·poly1305_init_constants_armv6<>+0x00(SB)/4, $0x3ffffff
DATA ·poly1305_init_constants_armv6<>+0x04(SB)/4, $0x3ffff03
DATA ·poly1305_init_constants_armv6<>+0x08(SB)/4, $0x3ffc0ff
DATA ·poly1305_init_constants_armv6<>+0x0c(SB)/4, $0x3f03fff
DATA ·poly1305_init_constants_armv6<>+0x10(SB)/4, $0x00fffff
GLOBL ·poly1305_init_constants_armv6<>(SB), 8, $20
// Warning: the linker may use R11 to synthesize certain instructions. Please
// take care and verify that no synthetic instructions use it.
@@ -27,7 +27,7 @@ TEXT poly1305_init_ext_armv6<>(SB), NOSPLIT, $0
ADD $4, R13, R8
MOVM.IB [R4-R7], (R8)
MOVM.IA.W (R1), [R2-R5]
MOVW $poly1305_init_constants_armv6<>(SB), R7
MOVW $·poly1305_init_constants_armv6<>(SB), R7
MOVW R2, R8
MOVW R2>>26, R9
MOVW R3>>20, g

View File

@@ -0,0 +1,18 @@
// compile
// Copyright 2017 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 p
var (
e interface{}
s = struct{ a *int }{}
b = e == s
)
func test(obj interface{}) {
if obj != struct{ a *string }{} {
}
}

View File

@@ -0,0 +1,24 @@
// run
// Copyright 2017 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 main
import "os"
func panicWhenNot(cond bool) {
if cond {
os.Exit(0)
} else {
panic("nilcheck elim failed")
}
}
func main() {
e := (*string)(nil)
panicWhenNot(e == e)
// Should never reach this line.
panicWhenNot(*e == *e)
}

View File

@@ -40,23 +40,23 @@ var (
)
func f1() {
_ = *intp // ERROR "generated nil check"
_ = *intp // ERROR "removed nil check"
// This one should be removed but the block copy needs
// to be turned into its own pseudo-op in order to see
// the indirect.
_ = *arrayp // ERROR "generated nil check"
_ = *arrayp // ERROR "removed nil check"
// 0-byte indirect doesn't suffice.
// we don't registerize globals, so there are no removed.* nil checks.
_ = *array0p // ERROR "generated nil check"
_ = *array0p // ERROR "removed nil check"
_ = *array0p // ERROR "generated nil check"
_ = *intp // ERROR "removed nil check"
_ = *intp // ERROR "generated nil check"
_ = *arrayp // ERROR "removed nil check"
_ = *structp // ERROR "generated nil check"
_ = *emptyp // ERROR "generated nil check"
_ = *arrayp // ERROR "removed nil check"
_ = *arrayp // ERROR "generated nil check"
}
func f2() {
@@ -71,15 +71,15 @@ func f2() {
empty1p *Empty1
)
_ = *intp // ERROR "generated nil check"
_ = *arrayp // ERROR "generated nil check"
_ = *array0p // ERROR "generated nil check"
_ = *array0p // ERROR "removed.* nil check"
_ = *intp // ERROR "removed.* nil check"
_ = *arrayp // ERROR "removed.* nil check"
_ = *array0p // ERROR "removed.* nil check"
_ = *array0p // ERROR "generated nil check"
_ = *intp // ERROR "generated nil check"
_ = *arrayp // ERROR "removed.* nil check"
_ = *structp // ERROR "generated nil check"
_ = *emptyp // ERROR "generated nil check"
_ = *arrayp // ERROR "removed.* nil check"
_ = *arrayp // ERROR "generated nil check"
_ = *bigarrayp // ERROR "generated nil check" ARM removed nil check before indirect!!
_ = *bigstructp // ERROR "generated nil check"
_ = *empty1p // ERROR "generated nil check"
@@ -122,16 +122,16 @@ func f3(x *[10000]int) {
// x wasn't going to change across the function call.
// But it's a little complex to do and in practice doesn't
// matter enough.
_ = x[9999] // ERROR "removed nil check"
_ = x[9999] // ERROR "generated nil check" // TODO: fix
}
func f3a() {
x := fx10k()
y := fx10k()
z := fx10k()
_ = &x[9] // ERROR "generated nil check"
y = z
_ = &x[9] // ERROR "removed.* nil check"
y = z
_ = &x[9] // ERROR "generated nil check"
x = y
_ = &x[9] // ERROR "generated nil check"
}
@@ -139,11 +139,11 @@ func f3a() {
func f3b() {
x := fx10k()
y := fx10k()
_ = &x[9] // ERROR "generated nil check"
_ = &x[9] // ERROR "removed.* nil check"
y = x
_ = &x[9] // ERROR "removed.* nil check"
x = y
_ = &x[9] // ERROR "removed.* nil check"
_ = &x[9] // ERROR "generated nil check"
}
func fx10() *[10]int
@@ -179,15 +179,15 @@ func f4(x *[10]int) {
_ = x[9] // ERROR "generated nil check" // bug would like to remove before indirect
fx10()
_ = x[9] // ERROR "removed nil check"
_ = x[9] // ERROR "generated nil check" // TODO: fix
x = fx10()
y := fx10()
_ = &x[9] // ERROR "generated nil check"
_ = &x[9] // ERROR "removed[a-z ]* nil check"
y = x
_ = &x[9] // ERROR "removed[a-z ]* nil check"
x = y
_ = &x[9] // ERROR "removed[a-z ]* nil check"
_ = &x[9] // ERROR "generated nil check"
}
func f5(p *float32, q *float64, r *float32, s *float64) float64 {