aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2016-02-17 13:45:03 -0500
committerRuss Cox <rsc@golang.org>2016-02-17 13:45:03 -0500
commit6e3041b92767ff38a993a265ef2daec64b3f7f11 (patch)
tree656b19140efdf0caba7bcefd38b1fc7f3f8b61c6
parent5d343bdfb140970cc37f099064226d104ca6d817 (diff)
parent939a9424de5c3d0a0d2e1769778b5b0aa9c61954 (diff)
downloadgo-6e3041b92767ff38a993a265ef2daec64b3f7f11.tar.gz
go-6e3041b92767ff38a993a265ef2daec64b3f7f11.zip
all: merge master into release-branch.go1.6
Change-Id: Ie2a999e36ee654c1217bd03f720791360f66718d
-rw-r--r--doc/asm.html13
-rw-r--r--doc/codewalk/codewalk.xml2
-rw-r--r--doc/contribute.html14
-rw-r--r--doc/go1.6.html34
-rw-r--r--doc/go_faq.html2
-rw-r--r--misc/nacl/testzip.proto24
-rw-r--r--src/cmd/compile/internal/gc/fmt.go8
-rw-r--r--src/cmd/compile/internal/gc/gen.go2
-rw-r--r--src/cmd/dist/test.go5
-rw-r--r--src/cmd/go/build.go18
-rw-r--r--src/cmd/go/go_test.go79
-rw-r--r--src/cmd/go/main.go2
-rw-r--r--src/cmd/go/pkg.go2
-rw-r--r--src/cmd/internal/objfile/disasm.go4
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/Makefile (renamed from src/cmd/vendor/golang.org/x/arch/arm/armasm/Makefile)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/decode.go (renamed from src/cmd/vendor/golang.org/x/arch/arm/armasm/decode.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/decode_test.go (renamed from src/cmd/vendor/golang.org/x/arch/arm/armasm/decode_test.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/ext_test.go (renamed from src/cmd/vendor/golang.org/x/arch/arm/armasm/ext_test.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/gnu.go (renamed from src/cmd/vendor/golang.org/x/arch/arm/armasm/gnu.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/inst.go (renamed from src/cmd/vendor/golang.org/x/arch/arm/armasm/inst.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/objdump_test.go (renamed from src/cmd/vendor/golang.org/x/arch/arm/armasm/objdump_test.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/objdumpext_test.go (renamed from src/cmd/vendor/golang.org/x/arch/arm/armasm/objdumpext_test.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/plan9x.go (renamed from src/cmd/vendor/golang.org/x/arch/arm/armasm/plan9x.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/tables.go (renamed from src/cmd/vendor/golang.org/x/arch/arm/armasm/tables.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/testdata/Makefile (renamed from src/cmd/vendor/golang.org/x/arch/arm/armasm/testdata/Makefile)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/testdata/decode.txt (renamed from src/cmd/vendor/golang.org/x/arch/arm/armasm/testdata/decode.txt)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/Makefile (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/Makefile)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/decode.go (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/decode.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/decode_test.go (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/decode_test.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/ext_test.go (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/ext_test.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/gnu.go (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/gnu.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/inst.go (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/inst.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/inst_test.go (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/inst_test.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/intel.go (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/intel.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/objdump_test.go (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/objdump_test.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/objdumpext_test.go (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/objdumpext_test.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/plan9ext_test.go (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/plan9ext_test.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/plan9x.go (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/plan9x.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/plan9x_test.go (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/plan9x_test.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/tables.go (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/tables.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/testdata/Makefile (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/testdata/Makefile)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/testdata/decode.txt (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/testdata/decode.txt)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/testdata/libmach8db.c (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/testdata/libmach8db.c)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/xed_test.go (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/xed_test.go)0
-rw-r--r--src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/xedext_test.go (renamed from src/cmd/vendor/golang.org/x/arch/x86/x86asm/xedext_test.go)0
-rw-r--r--src/cmd/internal/unvendor/vendor.json (renamed from src/cmd/vendor/vendor.json)0
-rw-r--r--src/cmd/link/internal/ld/dwarf.go4
-rw-r--r--src/go/constant/value.go2
-rw-r--r--src/go/constant/value_test.go2
-rw-r--r--src/go/internal/gcimporter/gcimporter.go6
-rw-r--r--src/go/types/expr.go8
-rw-r--r--src/go/types/resolver.go10
-rw-r--r--src/go/types/testdata/issues.src17
-rw-r--r--src/net/http/h2_bundle.go128
-rw-r--r--src/net/http/httptest/server.go49
-rw-r--r--src/net/http/httptest/server_test.go14
-rw-r--r--src/net/http/request.go40
-rw-r--r--src/net/http/serve_test.go44
-rw-r--r--src/net/http/server.go12
-rw-r--r--src/net/http/transport.go16
-rw-r--r--src/net/http/transport_test.go37
-rw-r--r--src/net/net_windows_test.go117
-rw-r--r--src/runtime/cgocheck.go3
-rw-r--r--src/runtime/crash_test.go19
-rw-r--r--src/runtime/crash_unix_test.go17
-rw-r--r--src/runtime/export_linux_test.go1
-rw-r--r--src/runtime/export_mmap_test.go15
-rw-r--r--src/runtime/mem_bsd.go4
-rw-r--r--src/runtime/os2_nacl.go25
-rw-r--r--src/runtime/os3_solaris.go16
-rw-r--r--src/runtime/pprof/pprof.go2
-rw-r--r--src/runtime/runtime-lldb_test.go262
-rw-r--r--src/runtime/runtime_linux_test.go13
-rw-r--r--src/runtime/runtime_mmap_test.go30
-rw-r--r--src/runtime/stack_test.go4
-rw-r--r--src/runtime/string.go4
-rw-r--r--src/runtime/string_test.go15
-rw-r--r--src/runtime/sys_linux_arm64.s3
-rw-r--r--src/runtime/sys_linux_mips64x.s1
-rw-r--r--src/runtime/sys_linux_ppc64x.s1
-rw-r--r--src/runtime/sys_nacl_386.s3
-rw-r--r--src/runtime/testdata/testprog/deadlock.go20
-rw-r--r--src/runtime/time.go2
-rw-r--r--src/runtime/traceback.go10
-rw-r--r--test/fixedbugs/issue14331.dir/a.go14
-rw-r--r--test/fixedbugs/issue14331.dir/b.go11
-rw-r--r--test/fixedbugs/issue14331.go9
-rw-r--r--test/writebarrier.go14
88 files changed, 1054 insertions, 179 deletions
diff --git a/doc/asm.html b/doc/asm.html
index 2af2005143..392af174c2 100644
--- a/doc/asm.html
+++ b/doc/asm.html
@@ -12,7 +12,7 @@ The document is not comprehensive.
<p>
The assembler is based on the input style of the Plan 9 assemblers, which is documented in detail
-<a href="http://plan9.bell-labs.com/sys/doc/asm.html">elsewhere</a>.
+<a href="https://9p.io/sys/doc/asm.html">elsewhere</a>.
If you plan to write assembly language, you should read that document although much of it is Plan 9-specific.
The current document provides a summary of the syntax and the differences with
what is explained in that document, and
@@ -23,7 +23,7 @@ describes the peculiarities that apply when writing assembly code to interact wi
The most important thing to know about Go's assembler is that it is not a direct representation of the underlying machine.
Some of the details map precisely to the machine, but some do not.
This is because the compiler suite (see
-<a href="http://plan9.bell-labs.com/sys/doc/compiler.html">this description</a>)
+<a href="https://9p.io/sys/doc/compiler.html">this description</a>)
needs no assembler pass in the usual pipeline.
Instead, the compiler operates on a kind of semi-abstract instruction set,
and instruction selection occurs partly after code generation.
@@ -621,6 +621,15 @@ These modes accept only 1, 2, 4, and 8 as scale factors.
</ul>
+<p>
+When using the compiler and assembler's
+<code>-dynlink</code> or <code>-shared</code> modes,
+any load or store of a fixed memory location such as a global variable
+must be assumed to overwrite <code>CX</code>.
+Therefore, to be safe for use with these modes,
+assembly sources should typically avoid CX except between memory references.
+</p>
+
<h3 id="amd64">64-bit Intel 386 (a.k.a. amd64)</h3>
<p>
diff --git a/doc/codewalk/codewalk.xml b/doc/codewalk/codewalk.xml
index 3496db71d7..34e6e91938 100644
--- a/doc/codewalk/codewalk.xml
+++ b/doc/codewalk/codewalk.xml
@@ -91,7 +91,7 @@
The full address syntax is summarized in this table
(an excerpt of Table II from
- <a href="http://plan9.bell-labs.com/sys/doc/sam/sam.html">The text editor <code>sam</code></a>):
+ <a href="https://9p.io/sys/doc/sam/sam.html">The text editor <code>sam</code></a>):
<br/><br/>
<table>
diff --git a/doc/contribute.html b/doc/contribute.html
index a321a8646f..4619c81124 100644
--- a/doc/contribute.html
+++ b/doc/contribute.html
@@ -198,9 +198,13 @@ prints help text, not an error.
</p>
<p>
-Note to Git aficionados: The <code>git-codereview</code> command is not required to
+<b>Note to Git aficionados:</b>
+The <code>git-codereview</code> command is not required to
upload and manage Gerrit code reviews. For those who prefer plain Git, the text
-below gives the Git equivalent of each git-codereview command. If you do use plain
+below gives the Git equivalent of each git-codereview command.
+</p>
+
+<p>If you do use plain
Git, note that you still need the commit hooks that the git-codereview command
configures; those hooks add a Gerrit <code>Change-Id</code> line to the commit
message and check that all Go source files have been formatted with gofmt. Even
@@ -208,6 +212,12 @@ if you intend to use plain Git for daily work, install the hooks in a new Git
checkout by running <code>git-codereview</code> <code>hooks</code>.
</p>
+<p>
+The workflow described below assumes a single change per branch.
+It is also possible to prepare a sequence of (usually related) changes in a single branch.
+See the <a href="https://golang.org/x/review/git-codereview">git-codereview documentation</a> for details.
+</p>
+
<h3 id="git-config">Set up git aliases</h3>
<p>
diff --git a/doc/go1.6.html b/doc/go1.6.html
index b4a3900aa0..17c3536aeb 100644
--- a/doc/go1.6.html
+++ b/doc/go1.6.html
@@ -1,5 +1,5 @@
<!--{
- "Title": "Go 1.6 Release Notes DRAFT",
+ "Title": "Go 1.6 Release Notes",
"Path": "/doc/go1.6",
"Template": true
}-->
@@ -13,13 +13,6 @@ Edit .,s;^([a-z][A-Za-z0-9_/]+)\.([A-Z][A-Za-z0-9_]+\.)?([A-Z][A-Za-z0-9_]+)([ .
ul li { margin: 0.5em 0; }
</style>
-<p>
-<i>NOTE: This is a DRAFT of the Go 1.6 release notes, prepared for the Go 1.6 beta.
-Go 1.6 has NOT yet been released.
-By our regular schedule, it is expected some time in February 2016.
-</i>
-</p>
-
<h2 id="introduction">Introduction to Go 1.6</h2>
<p>
@@ -70,9 +63,12 @@ On NaCl, Go 1.5 required SDK version pepper-41.
Go 1.6 adds support for later SDK versions.
</p>
-<pre>
-TODO: CX no longer available on 386 assembly? (https://golang.org/cl/16386)
-</pre>
+<p>
+On 32-bit x86 systems using the <code>-dynlink</code> or <code>-shared</code> compilation modes,
+the register CX is now overwritten by certain memory references and should
+be avoided in hand-written assembly.
+See the <a href="/doc/asm#x86">assembly documentation</a> for details.
+</p>
<h2 id="tools">Tools</h2>
@@ -248,7 +244,7 @@ Some programs may run faster, some slower.
On average the programs in the Go 1 benchmark suite run a few percent faster in Go 1.6
than they did in Go 1.5.
The garbage collector's pauses are even lower than in Go 1.5,
-although the effect is likely only noticeable for programs using
+especially for programs using
a large amount of memory.
</p>
@@ -569,7 +565,7 @@ The <a href="/pkg/debug/elf/"><code>debug/elf</code></a> package
adds support for general compressed ELF sections.
User code needs no updating: the sections are decompressed automatically when read.
However, compressed
-<a href="/pkg/debug/elf/#Section"><code>Section</code></a>'s do not support random access:
+<a href="/pkg/debug/elf/#Section"><code>Sections</code></a> do not support random access:
they have a nil <code>ReaderAt</code> field.
</li>
@@ -632,7 +628,6 @@ In previous releases, the argument to <code>*</code> was required to have type <
Also in the <a href="/pkg/fmt/"><code>fmt</code></a> package,
<a href="/pkg/fmt/#Scanf"><code>Scanf</code></a> can now scan hexadecimal strings using %X, as an alias for %x.
Both formats accept any mix of upper- and lower-case hexadecimal.
-<a href="https://golang.org/issues/13585">TODO: Keep?</a>
</li>
<li>
@@ -717,9 +712,6 @@ Second, DNS lookup functions such as
<a href="/pkg/net/#LookupAddr"><code>LookupAddr</code></a>
now return rooted domain names (with a trailing dot)
on Plan 9 and Windows, to match the behavior of Go on Unix systems.
-TODO: Third, lookups satisfied from /etc/hosts now add a trailing dot as well,
-so that looking up 127.0.0.1 typically now returns &ldquo;localhost.&rdquo; not &ldquo;localhost&rdquo;.
-This is arguably a mistake but is not yet fixed. See https://golang.org/issue/13564.
</li>
<li>
@@ -875,16 +867,18 @@ should only be used when contention has been observed.
<li>
The <a href="/pkg/strconv/"><code>strconv</code></a> package adds
<a href="/pkg/strconv/#IsGraphic"><code>IsGraphic</code></a>,
+similar to <a href="/pkg/strconv/#IsPrint"><code>IsPrint</code></a>.
+It also adds
<a href="/pkg/strconv/#QuoteToGraphic"><code>QuoteToGraphic</code></a>,
<a href="/pkg/strconv/#QuoteRuneToGraphic"><code>QuoteRuneToGraphic</code></a>,
<a href="/pkg/strconv/#AppendQuoteToGraphic"><code>AppendQuoteToGraphic</code></a>,
and
<a href="/pkg/strconv/#AppendQuoteRuneToGraphic"><code>AppendQuoteRuneToGraphic</code></a>,
analogous to
-<a href="/pkg/strconv/#IsPrint"><code>IsPrint</code></a>,
-<a href="/pkg/strconv/#QuoteToPrint"><code>QuoteToPrint</code></a>,
+<a href="/pkg/strconv/#QuoteToASCII"><code>QuoteToASCII</code></a>,
+<a href="/pkg/strconv/#QuoteRuneToASCII"><code>QuoteRuneToASCII</code></a>,
and so on.
-The <code>Print</code> family escapes all space characters except ASCII space (U+0020).
+The <code>ASCII</code> family escapes all space characters except ASCII space (U+0020).
In contrast, the <code>Graphic</code> family does not escape any Unicode space characters (category Zs).
</li>
diff --git a/doc/go_faq.html b/doc/go_faq.html
index bcd12075b6..b5f9772787 100644
--- a/doc/go_faq.html
+++ b/doc/go_faq.html
@@ -98,7 +98,7 @@ What's the origin of the mascot?</h3>
<p>
The mascot and logo were designed by
<a href="http://reneefrench.blogspot.com">Renée French</a>, who also designed
-<a href="http://plan9.bell-labs.com/plan9/glenda.html">Glenda</a>,
+<a href="https://9p.io/plan9/glenda.html">Glenda</a>,
the Plan 9 bunny.
The <a href="https://blog.golang.org/gopher">gopher</a>
is derived from one she used for an <a href="http://wfmu.org/">WFMU</a>
diff --git a/misc/nacl/testzip.proto b/misc/nacl/testzip.proto
index c8ab18ea20..4e82ac9b4b 100644
--- a/misc/nacl/testzip.proto
+++ b/misc/nacl/testzip.proto
@@ -27,23 +27,23 @@ go src=..
internal
objfile
objfile.go
+ unvendor
+ golang.org
+ x
+ arch
+ arm
+ armasm
+ testdata
+ +
+ x86
+ x86asm
+ testdata
+ +
gofmt
gofmt.go
gofmt_test.go
testdata
+
- vendor
- golang.org
- x
- arch
- arm
- armasm
- testdata
- +
- x86
- x86asm
- testdata
- +
archive
tar
testdata
diff --git a/src/cmd/compile/internal/gc/fmt.go b/src/cmd/compile/internal/gc/fmt.go
index 64b6e36758..d00e5a6c46 100644
--- a/src/cmd/compile/internal/gc/fmt.go
+++ b/src/cmd/compile/internal/gc/fmt.go
@@ -748,7 +748,13 @@ func typefmt(t *Type, flag int) string {
if name != "" {
str = name + " " + typ
}
- if flag&obj.FmtShort == 0 && !fmtbody && t.Note != nil {
+
+ // The fmtbody flag is intended to suppress escape analysis annotations
+ // when printing a function type used in a function body.
+ // (The escape analysis tags do not apply to func vars.)
+ // But it must not suppress struct field tags.
+ // See golang.org/issue/13777 and golang.org/issue/14331.
+ if flag&obj.FmtShort == 0 && (!fmtbody || !t.Funarg) && t.Note != nil {
str += " " + strconv.Quote(*t.Note)
}
return str
diff --git a/src/cmd/compile/internal/gc/gen.go b/src/cmd/compile/internal/gc/gen.go
index 836834f8bd..b756055668 100644
--- a/src/cmd/compile/internal/gc/gen.go
+++ b/src/cmd/compile/internal/gc/gen.go
@@ -836,7 +836,7 @@ func gen(n *Node) {
Cgen_as_wb(n.Left, n.Right, true)
case OAS2DOTTYPE:
- cgen_dottype(n.Rlist.N, n.List.N, n.List.Next.N, false)
+ cgen_dottype(n.Rlist.N, n.List.N, n.List.Next.N, needwritebarrier(n.List.N, n.Rlist.N))
case OCALLMETH:
cgen_callmeth(n, 0)
diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go
index 156b868109..36c829d1b9 100644
--- a/src/cmd/dist/test.go
+++ b/src/cmd/dist/test.go
@@ -947,6 +947,11 @@ func (t *tester) raceTest(dt *distTest) error {
t.addCmd(dt, "src", "go", "test", "-race", "-i", "runtime/race", "flag", "os/exec")
t.addCmd(dt, "src", "go", "test", "-race", "-run=Output", "runtime/race")
t.addCmd(dt, "src", "go", "test", "-race", "-short", "-run=TestParse|TestEcho", "flag", "os/exec")
+ // We don't want the following line, because it
+ // slows down all.bash (by 10 seconds on my laptop).
+ // The race builder should catch any error here, but doesn't.
+ // TODO(iant): Figure out how to catch this.
+ // t.addCmd(dt, "src", "go", "test", "-race", "-run=TestParallelTest", "cmd/go")
if t.cgoEnabled {
env := mergeEnvLists([]string{"GOTRACEBACK=2"}, os.Environ())
cmd := t.addCmd(dt, "misc/cgo/test", "go", "test", "-race", "-short")
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
index a1f925ed0b..f2a2a6014f 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -667,6 +667,7 @@ var (
goarch string
goos string
exeSuffix string
+ gopath []string
)
func init() {
@@ -675,6 +676,7 @@ func init() {
if goos == "windows" {
exeSuffix = ".exe"
}
+ gopath = filepath.SplitList(buildContext.GOPATH)
}
// A builder holds global state about a build.
@@ -1684,6 +1686,22 @@ func (b *builder) includeArgs(flag string, all []*action) []string {
inc = append(inc, flag, b.work)
// Finally, look in the installed package directories for each action.
+ // First add the package dirs corresponding to GOPATH entries
+ // in the original GOPATH order.
+ need := map[string]*build.Package{}
+ for _, a1 := range all {
+ if a1.p != nil && a1.pkgdir == a1.p.build.PkgRoot {
+ need[a1.p.build.Root] = a1.p.build
+ }
+ }
+ for _, root := range gopath {
+ if p := need[root]; p != nil && !incMap[p.PkgRoot] {
+ incMap[p.PkgRoot] = true
+ inc = append(inc, flag, p.PkgTargetRoot)
+ }
+ }
+
+ // Then add anything that's left.
for _, a1 := range all {
if a1.p == nil {
continue
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index 6d12f75073..39e0f3e56d 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -10,6 +10,7 @@ import (
"fmt"
"go/build"
"go/format"
+ "internal/race"
"internal/testenv"
"io"
"io/ioutil"
@@ -69,7 +70,11 @@ func TestMain(m *testing.M) {
flag.Parse()
if canRun {
- out, err := exec.Command("go", "build", "-tags", "testgo", "-o", "testgo"+exeSuffix).CombinedOutput()
+ args := []string{"build", "-tags", "testgo", "-o", "testgo" + exeSuffix}
+ if race.Enabled {
+ args = append(args, "-race")
+ }
+ out, err := exec.Command("go", args...).CombinedOutput()
if err != nil {
fmt.Fprintf(os.Stderr, "building testgo failed: %v\n%s", err, out)
os.Exit(2)
@@ -2565,6 +2570,59 @@ func TestGoInstallShadowedGOPATH(t *testing.T) {
tg.grepStderr("no install location for.*gopath2.src.test: hidden by .*gopath1.src.test", "missing error")
}
+func TestGoBuildGOPATHOrder(t *testing.T) {
+ // golang.org/issue/14176#issuecomment-179895769
+ // golang.org/issue/14192
+ // -I arguments to compiler could end up not in GOPATH order,
+ // leading to unexpected import resolution in the compiler.
+ // This is still not a complete fix (see golang.org/issue/14271 and next test)
+ // but it is clearly OK and enough to fix both of the two reported
+ // instances of the underlying problem. It will have to do for now.
+
+ tg := testgo(t)
+ defer tg.cleanup()
+ tg.makeTempdir()
+ tg.setenv("GOPATH", tg.path("p1")+string(filepath.ListSeparator)+tg.path("p2"))
+
+ tg.tempFile("p1/src/foo/foo.go", "package foo\n")
+ tg.tempFile("p2/src/baz/baz.go", "package baz\n")
+ tg.tempFile("p2/pkg/"+runtime.GOOS+"_"+runtime.GOARCH+"/foo.a", "bad\n")
+ tg.tempFile("p1/src/bar/bar.go", `
+ package bar
+ import _ "baz"
+ import _ "foo"
+ `)
+
+ tg.run("install", "-x", "bar")
+}
+
+func TestGoBuildGOPATHOrderBroken(t *testing.T) {
+ // This test is known not to work.
+ // See golang.org/issue/14271.
+ t.Skip("golang.org/issue/14271")
+
+ tg := testgo(t)
+ defer tg.cleanup()
+ tg.makeTempdir()
+
+ tg.tempFile("p1/src/foo/foo.go", "package foo\n")
+ tg.tempFile("p2/src/baz/baz.go", "package baz\n")
+ tg.tempFile("p1/pkg/"+runtime.GOOS+"_"+runtime.GOARCH+"/baz.a", "bad\n")
+ tg.tempFile("p2/pkg/"+runtime.GOOS+"_"+runtime.GOARCH+"/foo.a", "bad\n")
+ tg.tempFile("p1/src/bar/bar.go", `
+ package bar
+ import _ "baz"
+ import _ "foo"
+ `)
+
+ colon := string(filepath.ListSeparator)
+ tg.setenv("GOPATH", tg.path("p1")+colon+tg.path("p2"))
+ tg.run("install", "-x", "bar")
+
+ tg.setenv("GOPATH", tg.path("p2")+colon+tg.path("p1"))
+ tg.run("install", "-x", "bar")
+}
+
func TestIssue11709(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
@@ -2682,3 +2740,22 @@ func TestIssue13655(t *testing.T) {
tg.grepStdout("runtime/internal/sys", "did not find required dependency of "+pkg+" on runtime/internal/sys")
}
}
+
+// For issue 14337.
+func TestParallelTest(t *testing.T) {
+ tg := testgo(t)
+ defer tg.cleanup()
+ tg.makeTempdir()
+ const testSrc = `package package_test
+ import (
+ "testing"
+ )
+ func TestTest(t *testing.T) {
+ }`
+ tg.tempFile("src/p1/p1_test.go", strings.Replace(testSrc, "package_test", "p1_test", 1))
+ tg.tempFile("src/p2/p2_test.go", strings.Replace(testSrc, "package_test", "p2_test", 1))
+ tg.tempFile("src/p3/p3_test.go", strings.Replace(testSrc, "package_test", "p3_test", 1))
+ tg.tempFile("src/p4/p4_test.go", strings.Replace(testSrc, "package_test", "p4_test", 1))
+ tg.setenv("GOPATH", tg.path("."))
+ tg.run("test", "-p=4", "p1", "p2", "p3", "p4")
+}
diff --git a/src/cmd/go/main.go b/src/cmd/go/main.go
index d384594722..f9b979da7f 100644
--- a/src/cmd/go/main.go
+++ b/src/cmd/go/main.go
@@ -454,7 +454,9 @@ func envForDir(dir string, base []string) []string {
// mergeEnvLists merges the two environment lists such that
// variables with the same name in "in" replace those in "out".
+// This always returns a newly allocated slice.
func mergeEnvLists(in, out []string) []string {
+ out = append([]string(nil), out...)
NextVar:
for _, inkv := range in {
k := strings.SplitAfterN(inkv, "=", 2)[0]
diff --git a/src/cmd/go/pkg.go b/src/cmd/go/pkg.go
index a804ccd277..0c0cf07e71 100644
--- a/src/cmd/go/pkg.go
+++ b/src/cmd/go/pkg.go
@@ -967,7 +967,7 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
}
}
}
- if p.Standard && !p1.Standard && p.Error == nil {
+ if p.Standard && p.Error == nil && !p1.Standard && p1.Error == nil {
p.Error = &PackageError{
ImportStack: stk.copy(),
Err: fmt.Sprintf("non-standard import %q in standard package %q", path, p.ImportPath),
diff --git a/src/cmd/internal/objfile/disasm.go b/src/cmd/internal/objfile/disasm.go
index 6495dfb356..f038883dc0 100644
--- a/src/cmd/internal/objfile/disasm.go
+++ b/src/cmd/internal/objfile/disasm.go
@@ -15,8 +15,8 @@ import (
"strings"
"text/tabwriter"
- "golang.org/x/arch/arm/armasm"
- "golang.org/x/arch/x86/x86asm"
+ "cmd/internal/unvendor/golang.org/x/arch/arm/armasm"
+ "cmd/internal/unvendor/golang.org/x/arch/x86/x86asm"
)
// Disasm is a disassembler for a given File.
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/Makefile b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/Makefile
index a3f57001f6..a3f57001f6 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/Makefile
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/Makefile
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/decode.go b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/decode.go
index 6b4d73841b..6b4d73841b 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/decode.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/decode.go
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/decode_test.go b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/decode_test.go
index e2d9127348..e2d9127348 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/decode_test.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/decode_test.go
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/ext_test.go b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/ext_test.go
index 98192b324e..98192b324e 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/ext_test.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/ext_test.go
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/gnu.go b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/gnu.go
index 1a97a5a844..1a97a5a844 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/gnu.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/gnu.go
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/inst.go b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/inst.go
index 60d633bdb6..60d633bdb6 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/inst.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/inst.go
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/objdump_test.go b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/objdump_test.go
index db51902cc7..db51902cc7 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/objdump_test.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/objdump_test.go
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/objdumpext_test.go b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/objdumpext_test.go
index 74fb47d2db..74fb47d2db 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/objdumpext_test.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/objdumpext_test.go
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/plan9x.go b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/plan9x.go
index fae0ca62a5..fae0ca62a5 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/plan9x.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/plan9x.go
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/tables.go b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/tables.go
index 58f51fe1f5..58f51fe1f5 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/tables.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/tables.go
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/testdata/Makefile b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/testdata/Makefile
index 1adab68517..1adab68517 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/testdata/Makefile
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/testdata/Makefile
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/testdata/decode.txt b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/testdata/decode.txt
index cc1ea0abe5..cc1ea0abe5 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/testdata/decode.txt
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/arm/armasm/testdata/decode.txt
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/Makefile b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/Makefile
index 9eb4557c11..9eb4557c11 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/Makefile
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/Makefile
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/decode.go b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/decode.go
index e4122c1e6d..e4122c1e6d 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/decode.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/decode.go
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/decode_test.go b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/decode_test.go
index b6098b898e..b6098b898e 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/decode_test.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/decode_test.go
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/ext_test.go b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/ext_test.go
index eadfd71bf5..eadfd71bf5 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/ext_test.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/ext_test.go
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/gnu.go b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/gnu.go
index e2ff801183..e2ff801183 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/gnu.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/gnu.go
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/inst.go b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/inst.go
index ef74025e08..ef74025e08 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/inst.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/inst.go
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/inst_test.go b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/inst_test.go
index 23ac523207..23ac523207 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/inst_test.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/inst_test.go
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/intel.go b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/intel.go
index 90af9dd638..90af9dd638 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/intel.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/intel.go
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/objdump_test.go b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/objdump_test.go
index 3d4e1460f8..3d4e1460f8 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/objdump_test.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/objdump_test.go
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/objdumpext_test.go b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/objdumpext_test.go
index f720dc6cb7..f720dc6cb7 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/objdumpext_test.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/objdumpext_test.go
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/plan9ext_test.go b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/plan9ext_test.go
index 9bd296cf75..9bd296cf75 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/plan9ext_test.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/plan9ext_test.go
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/plan9x.go b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/plan9x.go
index afe6a92e90..afe6a92e90 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/plan9x.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/plan9x.go
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/plan9x_test.go b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/plan9x_test.go
index f2ea28cd90..f2ea28cd90 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/plan9x_test.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/plan9x_test.go
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/tables.go b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/tables.go
index 3d08d5ebe3..3d08d5ebe3 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/tables.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/tables.go
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/testdata/Makefile b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/testdata/Makefile
index 9cb44127a4..9cb44127a4 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/testdata/Makefile
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/testdata/Makefile
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/testdata/decode.txt b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/testdata/decode.txt
index a899d75fdb..a899d75fdb 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/testdata/decode.txt
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/testdata/decode.txt
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/testdata/libmach8db.c b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/testdata/libmach8db.c
index 90ace5241d..90ace5241d 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/testdata/libmach8db.c
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/testdata/libmach8db.c
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/xed_test.go b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/xed_test.go
index 91cf822727..91cf822727 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/xed_test.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/xed_test.go
diff --git a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/xedext_test.go b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/xedext_test.go
index e27cdc07c4..e27cdc07c4 100644
--- a/src/cmd/vendor/golang.org/x/arch/x86/x86asm/xedext_test.go
+++ b/src/cmd/internal/unvendor/golang.org/x/arch/x86/x86asm/xedext_test.go
diff --git a/src/cmd/vendor/vendor.json b/src/cmd/internal/unvendor/vendor.json
index 565498ff8a..565498ff8a 100644
--- a/src/cmd/vendor/vendor.json
+++ b/src/cmd/internal/unvendor/vendor.json
diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go
index 563600d9a2..a96b37a4be 100644
--- a/src/cmd/link/internal/ld/dwarf.go
+++ b/src/cmd/link/internal/ld/dwarf.go
@@ -1946,7 +1946,9 @@ func writepub(ispub func(*DWDie) bool) int64 {
*/
func writearanges() int64 {
sectionstart := Cpos()
- headersize := int(Rnd(4+2+4+1+1, int64(Thearch.Ptrsize))) // don't count unit_length field itself
+ // The first tuple is aligned to a multiple of the size of a single tuple
+ // (twice the size of an address)
+ headersize := int(Rnd(4+2+4+1+1, int64(Thearch.Ptrsize*2))) // don't count unit_length field itself
for compunit := dwroot.child; compunit != nil; compunit = compunit.link {
b := getattr(compunit, DW_AT_low_pc)
diff --git a/src/go/constant/value.go b/src/go/constant/value.go
index 630581047a..310814df71 100644
--- a/src/go/constant/value.go
+++ b/src/go/constant/value.go
@@ -96,7 +96,7 @@ func (x stringVal) String() string {
// only the first maxLen-3 runes; then add "...".
i := 0
for n := 0; n < maxLen-3; n++ {
- _, size := utf8.DecodeRuneInString(s)
+ _, size := utf8.DecodeRuneInString(s[i:])
i += size
}
s = s[:i] + "..."
diff --git a/src/go/constant/value_test.go b/src/go/constant/value_test.go
index de1ab0267a..dbd96c07a3 100644
--- a/src/go/constant/value_test.go
+++ b/src/go/constant/value_test.go
@@ -204,6 +204,7 @@ func eql(x, y Value) bool {
// String tests
var xxx = strings.Repeat("x", 68)
+var issue14262 = `"بموجب الشروط التالية نسب المصنف — يجب عليك أن تنسب العمل بالطريقة التي تحددها المؤلف أو المرخص (ولكن ليس بأي حال من الأحوال أن توحي وتقترح بتحول أو استخدامك للعمل). المشاركة على قدم المساواة — إذا كنت يعدل ، والتغيير ، أو الاستفادة من هذا العمل ، قد ينتج عن توزيع العمل إلا في ظل تشابه او تطابق فى واحد لهذا الترخيص."`
var stringTests = []struct {
input, short, exact string
@@ -225,6 +226,7 @@ var stringTests = []struct {
{`"` + xxx + `xx"`, `"` + xxx + `xx"`, `"` + xxx + `xx"`},
{`"` + xxx + `xxx"`, `"` + xxx + `...`, `"` + xxx + `xxx"`},
{`"` + xxx + xxx + `xxx"`, `"` + xxx + `...`, `"` + xxx + xxx + `xxx"`},
+ {issue14262, `"بموجب الشروط التالية نسب المصنف — يجب عليك أن تنسب العمل بالطريقة ال...`, issue14262},
// Int
{"0", "0", "0"},
diff --git a/src/go/internal/gcimporter/gcimporter.go b/src/go/internal/gcimporter/gcimporter.go
index 0ef8eb4fc6..d70ec083c3 100644
--- a/src/go/internal/gcimporter/gcimporter.go
+++ b/src/go/internal/gcimporter/gcimporter.go
@@ -31,7 +31,8 @@ var pkgExts = [...]string{".a", ".o"}
// FindPkg returns the filename and unique package id for an import
// path based on package information provided by build.Import (using
-// the build.Default build.Context).
+// the build.Default build.Context). A relative srcDir is interpreted
+// relative to the current working directory.
// If no file was found, an empty filename is returned.
//
func FindPkg(path, srcDir string) (filename, id string) {
@@ -44,6 +45,9 @@ func FindPkg(path, srcDir string) (filename, id string) {
default:
// "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
// Don't require the source files to be present.
+ if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282
+ srcDir = abs
+ }
bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
if bp.PkgObj == "" {
return
diff --git a/src/go/types/expr.go b/src/go/types/expr.go
index 942d3fd5f7..f7c4a17378 100644
--- a/src/go/types/expr.go
+++ b/src/go/types/expr.go
@@ -184,7 +184,8 @@ func roundFloat64(x constant.Value) constant.Value {
// provided (only needed for int/uint sizes).
//
// If rounded != nil, *rounded is set to the rounded value of x for
-// representable floating-point values; it is left alone otherwise.
+// representable floating-point and complex values, and to an Int
+// value for integer values; it is left alone otherwise.
// It is ok to provide the addressof the first argument for rounded.
func representableConst(x constant.Value, conf *Config, typ *Basic, rounded *constant.Value) bool {
if x.Kind() == constant.Unknown {
@@ -197,6 +198,9 @@ func representableConst(x constant.Value, conf *Config, typ *Basic, rounded *con
if x.Kind() != constant.Int {
return false
}
+ if rounded != nil {
+ *rounded = x
+ }
if x, ok := constant.Int64Val(x); ok {
switch typ.kind {
case Int:
@@ -808,8 +812,6 @@ func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, o
typ := x.typ.Underlying().(*Basic)
// force integer division of integer operands
if op == token.QUO && isInteger(typ) {
- xval = constant.ToInt(xval)
- yval = constant.ToInt(yval)
op = token.QUO_ASSIGN
}
x.val = constant.BinaryOp(xval, op, yval)
diff --git a/src/go/types/resolver.go b/src/go/types/resolver.go
index 14148a585b..1536df5bf1 100644
--- a/src/go/types/resolver.go
+++ b/src/go/types/resolver.go
@@ -483,11 +483,9 @@ func pkgName(path string) string {
// (Per the go/build package dependency tests, we cannot import
// path/filepath and simply use filepath.Dir.)
func dir(path string) string {
- if i := strings.LastIndexAny(path, "/\\"); i >= 0 {
- path = path[:i]
+ if i := strings.LastIndexAny(path, `/\`); i > 0 {
+ return path[:i]
}
- if path == "" {
- path = "."
- }
- return path
+ // i <= 0
+ return "."
}
diff --git a/src/go/types/testdata/issues.src b/src/go/types/testdata/issues.src
index 564d0649b2..4fe0c62938 100644
--- a/src/go/types/testdata/issues.src
+++ b/src/go/types/testdata/issues.src
@@ -153,3 +153,20 @@ func issue10260() {
make(chan I1) <- i0 /* ERROR cannot use .* in send: missing method foo */
make(chan I1) <- i2 /* ERROR cannot use .* in send: wrong type for method foo */
}
+
+// Check that constants representable as integers are in integer form
+// before being used in operations that are only defined on integers.
+func issue14229() {
+ // from the issue
+ const _ = int64(-1<<63) % 1e6
+
+ // related
+ const (
+ a int = 3
+ b = 4.0
+ _ = a / b
+ _ = a % b
+ _ = b / a
+ _ = b % a
+ )
+}
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
index 11f33cf3b1..4e19b3e71f 100644
--- a/src/net/http/h2_bundle.go
+++ b/src/net/http/h2_bundle.go
@@ -1,5 +1,5 @@
-// Code generated by golang.org/x/tools/cmd/bundle command:
-// $ bundle golang.org/x/net/http2 net/http http2
+// Code generated by golang.org/x/tools/cmd/bundle.
+//go:generate bundle -o h2_bundle.go -prefix http2 -import golang.org/x/net/http2/hpack=internal/golang.org/x/net/http2/hpack golang.org/x/net/http2
// Package http2 implements the HTTP/2 protocol.
//
@@ -2331,6 +2331,10 @@ var http2isTokenTable = [127]bool{
'~': true,
}
+type http2connectionStater interface {
+ ConnectionState() tls.ConnectionState
+}
+
// pipe is a goroutine-safe io.Reader/io.Writer pair. It's like
// io.Pipe except there are no PipeReader/PipeWriter halves, and the
// underlying buffer is an interface. (io.Pipe is always unbuffered)
@@ -2593,28 +2597,76 @@ func http2ConfigureServer(s *Server, conf *http2Server) error {
if http2testHookOnConn != nil {
http2testHookOnConn()
}
- conf.handleConn(hs, c, h)
+ conf.ServeConn(c, &http2ServeConnOpts{
+ Handler: h,
+ BaseConfig: hs,
+ })
}
s.TLSNextProto[http2NextProtoTLS] = protoHandler
s.TLSNextProto["h2-14"] = protoHandler
return nil
}
-func (srv *http2Server) handleConn(hs *Server, c net.Conn, h Handler) {
+// ServeConnOpts are options for the Server.ServeConn method.
+type http2ServeConnOpts struct {
+ // BaseConfig optionally sets the base configuration
+ // for values. If nil, defaults are used.
+ BaseConfig *Server
+
+ // Handler specifies which handler to use for processing
+ // requests. If nil, BaseConfig.Handler is used. If BaseConfig
+ // or BaseConfig.Handler is nil, http.DefaultServeMux is used.
+ Handler Handler
+}
+
+func (o *http2ServeConnOpts) baseConfig() *Server {
+ if o != nil && o.BaseConfig != nil {
+ return o.BaseConfig
+ }
+ return new(Server)
+}
+
+func (o *http2ServeConnOpts) handler() Handler {
+ if o != nil {
+ if o.Handler != nil {
+ return o.Handler
+ }
+ if o.BaseConfig != nil && o.BaseConfig.Handler != nil {
+ return o.BaseConfig.Handler
+ }
+ }
+ return DefaultServeMux
+}
+
+// ServeConn serves HTTP/2 requests on the provided connection and
+// blocks until the connection is no longer readable.
+//
+// ServeConn starts speaking HTTP/2 assuming that c has not had any
+// reads or writes. It writes its initial settings frame and expects
+// to be able to read the preface and settings frame from the
+// client. If c has a ConnectionState method like a *tls.Conn, the
+// ConnectionState is used to verify the TLS ciphersuite and to set
+// the Request.TLS field in Handlers.
+//
+// ServeConn does not support h2c by itself. Any h2c support must be
+// implemented in terms of providing a suitably-behaving net.Conn.
+//
+// The opts parameter is optional. If nil, default values are used.
+func (s *http2Server) ServeConn(c net.Conn, opts *http2ServeConnOpts) {
sc := &http2serverConn{
- srv: srv,
- hs: hs,
+ srv: s,
+ hs: opts.baseConfig(),
conn: c,
remoteAddrStr: c.RemoteAddr().String(),
bw: http2newBufferedWriter(c),
- handler: h,
+ handler: opts.handler(),
streams: make(map[uint32]*http2stream),
readFrameCh: make(chan http2readFrameResult),
wantWriteFrameCh: make(chan http2frameWriteMsg, 8),
wroteFrameCh: make(chan http2frameWriteResult, 1),
bodyReadCh: make(chan http2bodyReadMsg),
doneServing: make(chan struct{}),
- advMaxStreams: srv.maxConcurrentStreams(),
+ advMaxStreams: s.maxConcurrentStreams(),
writeSched: http2writeScheduler{
maxFrameSize: http2initialMaxFrameSize,
},
@@ -2630,10 +2682,10 @@ func (srv *http2Server) handleConn(hs *Server, c net.Conn, h Handler) {
sc.hpackDecoder.SetMaxStringLength(sc.maxHeaderStringLen())
fr := http2NewFramer(sc.bw, c)
- fr.SetMaxReadFrameSize(srv.maxReadFrameSize())
+ fr.SetMaxReadFrameSize(s.maxReadFrameSize())
sc.framer = fr
- if tc, ok := c.(*tls.Conn); ok {
+ if tc, ok := c.(http2connectionStater); ok {
sc.tlsState = new(tls.ConnectionState)
*sc.tlsState = tc.ConnectionState()
@@ -2646,7 +2698,7 @@ func (srv *http2Server) handleConn(hs *Server, c net.Conn, h Handler) {
}
- if !srv.PermitProhibitedCipherSuites && http2isBadCipher(sc.tlsState.CipherSuite) {
+ if !s.PermitProhibitedCipherSuites && http2isBadCipher(sc.tlsState.CipherSuite) {
sc.rejectConn(http2ErrCodeInadequateSecurity, fmt.Sprintf("Prohibited TLS 1.2 Cipher Suite: %x", sc.tlsState.CipherSuite))
return
@@ -4874,10 +4926,7 @@ func (t *http2Transport) NewClientConn(c net.Conn) (*http2ClientConn, error) {
cc.henc = hpack.NewEncoder(&cc.hbuf)
- type connectionStater interface {
- ConnectionState() tls.ConnectionState
- }
- if cs, ok := c.(connectionStater); ok {
+ if cs, ok := c.(http2connectionStater); ok {
state := cs.ConnectionState()
cc.tlsState = &state
}
@@ -5028,7 +5077,27 @@ func (cc *http2ClientConn) responseHeaderTimeout() time.Duration {
return 0
}
+// checkConnHeaders checks whether req has any invalid connection-level headers.
+// per RFC 7540 section 8.1.2.2: Connection-Specific Header Fields.
+// Certain headers are special-cased as okay but not transmitted later.
+func http2checkConnHeaders(req *Request) error {
+ if v := req.Header.Get("Upgrade"); v != "" {
+ return errors.New("http2: invalid Upgrade request header")
+ }
+ if v := req.Header.Get("Transfer-Encoding"); (v != "" && v != "chunked") || len(req.Header["Transfer-Encoding"]) > 1 {
+ return errors.New("http2: invalid Transfer-Encoding request header")
+ }
+ if v := req.Header.Get("Connection"); (v != "" && v != "close" && v != "keep-alive") || len(req.Header["Connection"]) > 1 {
+ return errors.New("http2: invalid Connection request header")
+ }
+ return nil
+}
+
func (cc *http2ClientConn) RoundTrip(req *Request) (*Response, error) {
+ if err := http2checkConnHeaders(req); err != nil {
+ return nil, err
+ }
+
trailers, err := http2commaSeparatedTrailers(req)
if err != nil {
return nil, err
@@ -5334,10 +5403,14 @@ func (cc *http2ClientConn) encodeHeaders(req *Request, addGzipHeader bool, trail
var didUA bool
for k, vv := range req.Header {
lowKey := strings.ToLower(k)
- if lowKey == "host" || lowKey == "content-length" {
+ switch lowKey {
+ case "host", "content-length":
+
continue
- }
- if lowKey == "user-agent" {
+ case "connection", "proxy-connection", "transfer-encoding", "upgrade":
+
+ continue
+ case "user-agent":
didUA = true
if len(vv) < 1 {
@@ -5445,8 +5518,9 @@ func (cc *http2ClientConn) streamByID(id uint32, andRemove bool) *http2clientStr
// clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop.
type http2clientConnReadLoop struct {
- cc *http2ClientConn
- activeRes map[uint32]*http2clientStream // keyed by streamID
+ cc *http2ClientConn
+ activeRes map[uint32]*http2clientStream // keyed by streamID
+ closeWhenIdle bool
hdec *hpack.Decoder
@@ -5503,7 +5577,7 @@ func (rl *http2clientConnReadLoop) cleanup() {
func (rl *http2clientConnReadLoop) run() error {
cc := rl.cc
- closeWhenIdle := cc.t.disableKeepAlives()
+ rl.closeWhenIdle = cc.t.disableKeepAlives()
gotReply := false
for {
f, err := cc.fr.ReadFrame()
@@ -5552,7 +5626,7 @@ func (rl *http2clientConnReadLoop) run() error {
if err != nil {
return err
}
- if closeWhenIdle && gotReply && maybeIdle && len(rl.activeRes) == 0 {
+ if rl.closeWhenIdle && gotReply && maybeIdle && len(rl.activeRes) == 0 {
cc.closeIfIdle()
}
}
@@ -5803,6 +5877,9 @@ func (rl *http2clientConnReadLoop) endStream(cs *http2clientStream) {
}
cs.bufPipe.closeWithErrorAndCode(err, code)
delete(rl.activeRes, cs.ID)
+ if cs.req.Close || cs.req.Header.Get("Connection") == "close" {
+ rl.closeWhenIdle = true
+ }
}
func (cs *http2clientStream) copyTrailers() {
@@ -6064,13 +6141,18 @@ func (rt http2erringRoundTripper) RoundTrip(*Request) (*Response, error) { retur
// call gzip.NewReader on the first call to Read
type http2gzipReader struct {
body io.ReadCloser // underlying Response.Body
- zr io.Reader // lazily-initialized gzip reader
+ zr *gzip.Reader // lazily-initialized gzip reader
+ zerr error // sticky error
}
func (gz *http2gzipReader) Read(p []byte) (n int, err error) {
+ if gz.zerr != nil {
+ return 0, gz.zerr
+ }
if gz.zr == nil {
gz.zr, err = gzip.NewReader(gz.body)
if err != nil {
+ gz.zerr = err
return 0, err
}
}
diff --git a/src/net/http/httptest/server.go b/src/net/http/httptest/server.go
index fabfeca943..a2573df251 100644
--- a/src/net/http/httptest/server.go
+++ b/src/net/http/httptest/server.go
@@ -202,10 +202,31 @@ func (s *Server) logCloseHangDebugInfo() {
// CloseClientConnections closes any open HTTP connections to the test Server.
func (s *Server) CloseClientConnections() {
+ var conns int
+ ch := make(chan bool)
+
s.mu.Lock()
- defer s.mu.Unlock()
for c := range s.conns {
- s.closeConn(c)
+ conns++
+ s.closeConnChan(c, ch)
+ }
+ s.mu.Unlock()
+
+ // Wait for outstanding closes to finish.
+ //
+ // Out of paranoia for making a late change in Go 1.6, we
+ // bound how long this can wait, since golang.org/issue/14291
+ // isn't fully understood yet. At least this should only be used
+ // in tests.
+ timer := time.NewTimer(5 * time.Second)
+ defer timer.Stop()
+ for i := 0; i < conns; i++ {
+ select {
+ case <-ch:
+ case <-timer.C:
+ // Too slow. Give up.
+ return
+ }
}
}
@@ -267,9 +288,13 @@ func (s *Server) wrap() {
}
}
-// closeConn closes c. Except on plan9, which is special. See comment below.
+// closeConn closes c.
// s.mu must be held.
-func (s *Server) closeConn(c net.Conn) {
+func (s *Server) closeConn(c net.Conn) { s.closeConnChan(c, nil) }
+
+// closeConnChan is like closeConn, but takes an optional channel to receive a value
+// when the goroutine closing c is done.
+func (s *Server) closeConnChan(c net.Conn, done chan<- bool) {
if runtime.GOOS == "plan9" {
// Go's Plan 9 net package isn't great at unblocking reads when
// their underlying TCP connections are closed. Don't trust
@@ -278,7 +303,21 @@ func (s *Server) closeConn(c net.Conn) {
// resources if the syscall doesn't end up returning. Oh well.
s.forgetConn(c)
}
- go c.Close()
+
+ // Somewhere in the chaos of https://golang.org/cl/15151 we found that
+ // some types of conns were blocking in Close too long (or deadlocking?)
+ // and we had to call Close in a goroutine. I (bradfitz) forget what
+ // that was at this point, but I suspect it was *tls.Conns, which
+ // were later fixed in https://golang.org/cl/18572, so this goroutine
+ // is _probably_ unnecessary now. But it's too late in Go 1.6 too remove
+ // it with confidence.
+ // TODO(bradfitz): try to remove it for Go 1.7. (golang.org/issue/14291)
+ go func() {
+ c.Close()
+ if done != nil {
+ done <- true
+ }
+ }()
}
// forgetConn removes c from the set of tracked conns and decrements it from the
diff --git a/src/net/http/httptest/server_test.go b/src/net/http/httptest/server_test.go
index 6ffc671e57..c9606f2419 100644
--- a/src/net/http/httptest/server_test.go
+++ b/src/net/http/httptest/server_test.go
@@ -84,3 +84,17 @@ func TestServerCloseBlocking(t *testing.T) {
ts.Close() // test we don't hang here forever.
}
+
+// Issue 14290
+func TestServerCloseClientConnections(t *testing.T) {
+ var s *Server
+ s = NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ s.CloseClientConnections()
+ }))
+ defer s.Close()
+ res, err := http.Get(s.URL)
+ if err == nil {
+ res.Body.Close()
+ t.Fatal("Unexpected response: %#v", res)
+ }
+}
diff --git a/src/net/http/request.go b/src/net/http/request.go
index 16c5bb43ac..8cdab02af5 100644
--- a/src/net/http/request.go
+++ b/src/net/http/request.go
@@ -99,30 +99,37 @@ type Request struct {
ProtoMajor int // 1
ProtoMinor int // 0
- // A header maps request lines to their values.
- // If the header says
+ // Header contains the request header fields either received
+ // by the server or to be sent by the client.
//
+ // If a server received a request with header lines,
+ //
+ // Host: example.com
// accept-encoding: gzip, deflate
// Accept-Language: en-us
- // Connection: keep-alive
+ // fOO: Bar
+ // foo: two
//
// then
//
// Header = map[string][]string{
// "Accept-Encoding": {"gzip, deflate"},
// "Accept-Language": {"en-us"},
- // "Connection": {"keep-alive"},
+ // "Foo": {"Bar", "two"},
// }
//
- // HTTP defines that header names are case-insensitive.
- // The request parser implements this by canonicalizing the
- // name, making the first character and any characters
- // following a hyphen uppercase and the rest lowercase.
+ // For incoming requests, the Host header is promoted to the
+ // Request.Host field and removed from the Header map.
//
- // For client requests certain headers are automatically
- // added and may override values in Header.
+ // HTTP defines that header names are case-insensitive. The
+ // request parser implements this by using CanonicalHeaderKey,
+ // making the first character and any characters following a
+ // hyphen uppercase and the rest lowercase.
//
- // See the documentation for the Request.Write method.
+ // For client requests, certain headers such as Content-Length
+ // and Connection are automatically written when needed and
+ // values in Header may be ignored. See the documentation
+ // for the Request.Write method.
Header Header
// Body is the request's body.
@@ -152,8 +159,15 @@ type Request struct {
TransferEncoding []string
// Close indicates whether to close the connection after
- // replying to this request (for servers) or after sending
- // the request (for clients).
+ // replying to this request (for servers) or after sending this
+ // request and reading its response (for clients).
+ //
+ // For server requests, the HTTP server handles this automatically
+ // and this field is not needed by Handlers.
+ //
+ // For client requests, setting this field prevents re-use of
+ // TCP connections between requests to the same hosts, as if
+ // Transport.DisableKeepAlives were set.
Close bool
// For server requests Host specifies the host on which the
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
index f8cad802d4..384b453ce0 100644
--- a/src/net/http/serve_test.go
+++ b/src/net/http/serve_test.go
@@ -1039,12 +1039,30 @@ func TestAutomaticHTTP2_Serve(t *testing.T) {
}
func TestAutomaticHTTP2_ListenAndServe(t *testing.T) {
- defer afterTest(t)
- defer SetTestHookServerServe(nil)
cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
if err != nil {
t.Fatal(err)
}
+ testAutomaticHTTP2_ListenAndServe(t, &tls.Config{
+ Certificates: []tls.Certificate{cert},
+ })
+}
+
+func TestAutomaticHTTP2_ListenAndServe_GetCertificate(t *testing.T) {
+ cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
+ if err != nil {
+ t.Fatal(err)
+ }
+ testAutomaticHTTP2_ListenAndServe(t, &tls.Config{
+ GetCertificate: func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
+ return &cert, nil
+ },
+ })
+}
+
+func testAutomaticHTTP2_ListenAndServe(t *testing.T, tlsConf *tls.Config) {
+ defer afterTest(t)
+ defer SetTestHookServerServe(nil)
var ok bool
var s *Server
const maxTries = 5
@@ -1060,10 +1078,8 @@ Try:
lnc <- ln
})
s = &Server{
- Addr: addr,
- TLSConfig: &tls.Config{
- Certificates: []tls.Certificate{cert},
- },
+ Addr: addr,
+ TLSConfig: tlsConf,
}
errc := make(chan error, 1)
go func() { errc <- s.ListenAndServeTLS("", "") }()
@@ -2416,7 +2432,7 @@ func TestCloseNotifierPipelined(t *testing.T) {
if err != nil {
t.Fatalf("error dialing: %v", err)
}
- diec := make(chan bool, 2)
+ diec := make(chan bool, 1)
go func() {
const req = "GET / HTTP/1.1\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n"
_, err = io.WriteString(conn, req+req) // two requests
@@ -2426,13 +2442,23 @@ func TestCloseNotifierPipelined(t *testing.T) {
<-diec
conn.Close()
}()
+ reqs := 0
+ closes := 0
For:
for {
select {
case <-gotReq:
- diec <- true
+ reqs++
+ if reqs > 2 {
+ t.Fatal("too many requests")
+ } else if reqs > 1 {
+ diec <- true
+ }
case <-sawClose:
- break For
+ closes++
+ if closes > 1 {
+ break For
+ }
case <-time.After(5 * time.Second):
ts.CloseClientConnections()
t.Fatal("timeout")
diff --git a/src/net/http/server.go b/src/net/http/server.go
index 004a1f92fc..5e3b6084ae 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -2233,10 +2233,11 @@ func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error {
// Accepted connections are configured to enable TCP keep-alives.
//
// Filenames containing a certificate and matching private key for the
-// server must be provided if the Server's TLSConfig.Certificates is
-// not populated. If the certificate is signed by a certificate
-// authority, the certFile should be the concatenation of the server's
-// certificate, any intermediates, and the CA's certificate.
+// server must be provided if neither the Server's TLSConfig.Certificates
+// nor TLSConfig.GetCertificate are populated. If the certificate is
+// signed by a certificate authority, the certFile should be the
+// concatenation of the server's certificate, any intermediates, and
+// the CA's certificate.
//
// If srv.Addr is blank, ":https" is used.
//
@@ -2258,7 +2259,8 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
config.NextProtos = append(config.NextProtos, "http/1.1")
}
- if len(config.Certificates) == 0 || certFile != "" || keyFile != "" {
+ configHasCert := len(config.Certificates) > 0 || config.GetCertificate != nil
+ if !configHasCert || certFile != "" || keyFile != "" {
var err error
config.Certificates = make([]tls.Certificate, 1)
config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
index 41df906cf2..baf71d5e85 100644
--- a/src/net/http/transport.go
+++ b/src/net/http/transport.go
@@ -163,6 +163,22 @@ func (t *Transport) onceSetNextProtoDefaults() {
return
}
if t.TLSNextProto != nil {
+ // This is the documented way to disable http2 on a
+ // Transport.
+ return
+ }
+ if t.TLSClientConfig != nil {
+ // Be conservative for now (for Go 1.6) at least and
+ // don't automatically enable http2 if they've
+ // specified a custom TLS config. Let them opt-in
+ // themselves via http2.ConfigureTransport so we don't
+ // surprise them by modifying their tls.Config.
+ // Issue 14275.
+ return
+ }
+ if t.ExpectContinueTimeout != 0 {
+ // Unsupported in http2, so disable http2 for now.
+ // Issue 13851.
return
}
t2, err := http2configureTransport(t)
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index 8cb89a4220..0c901b30a4 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -2885,23 +2885,34 @@ func TestTransportPrefersResponseOverWriteError(t *testing.T) {
}
func TestTransportAutomaticHTTP2(t *testing.T) {
- tr := &Transport{}
- _, err := tr.RoundTrip(new(Request))
- if err == nil {
- t.Error("expected error from RoundTrip")
- }
- if tr.TLSNextProto["h2"] == nil {
- t.Errorf("HTTP/2 not registered.")
- }
+ testTransportAutoHTTP(t, &Transport{}, true)
+}
- // Now with TLSNextProto set:
- tr = &Transport{TLSNextProto: make(map[string]func(string, *tls.Conn) RoundTripper)}
- _, err = tr.RoundTrip(new(Request))
+func TestTransportAutomaticHTTP2_TLSNextProto(t *testing.T) {
+ testTransportAutoHTTP(t, &Transport{
+ TLSNextProto: make(map[string]func(string, *tls.Conn) RoundTripper),
+ }, false)
+}
+
+func TestTransportAutomaticHTTP2_TLSConfig(t *testing.T) {
+ testTransportAutoHTTP(t, &Transport{
+ TLSClientConfig: new(tls.Config),
+ }, false)
+}
+
+func TestTransportAutomaticHTTP2_ExpectContinueTimeout(t *testing.T) {
+ testTransportAutoHTTP(t, &Transport{
+ ExpectContinueTimeout: 1 * time.Second,
+ }, false)
+}
+
+func testTransportAutoHTTP(t *testing.T, tr *Transport, wantH2 bool) {
+ _, err := tr.RoundTrip(new(Request))
if err == nil {
t.Error("expected error from RoundTrip")
}
- if tr.TLSNextProto["h2"] != nil {
- t.Errorf("HTTP/2 registered, despite non-nil TLSNextProto field")
+ if reg := tr.TLSNextProto["h2"] != nil; reg != wantH2 {
+ t.Errorf("HTTP/2 registered = %v; want %v", reg, wantH2)
}
}
diff --git a/src/net/net_windows_test.go b/src/net/net_windows_test.go
index 095a339e02..df39032721 100644
--- a/src/net/net_windows_test.go
+++ b/src/net/net_windows_test.go
@@ -314,20 +314,43 @@ func TestInterfacesWithNetsh(t *testing.T) {
}
}
-func netshInterfaceIPv4ShowAddress(name string) ([]string, error) {
- out, err := runCmd("netsh", "interface", "ipv4", "show", "address", "name=\""+name+"\"")
- if err != nil {
- return nil, err
- }
+func netshInterfaceIPv4ShowAddress(name string, netshOutput []byte) []string {
// adress information is listed like:
+ //
+ //Configuration for interface "Local Area Connection"
+ // DHCP enabled: Yes
// IP Address: 10.0.0.2
// Subnet Prefix: 10.0.0.0/24 (mask 255.255.255.0)
// IP Address: 10.0.0.3
// Subnet Prefix: 10.0.0.0/24 (mask 255.255.255.0)
+ // Default Gateway: 10.0.0.254
+ // Gateway Metric: 0
+ // InterfaceMetric: 10
+ //
+ //Configuration for interface "Loopback Pseudo-Interface 1"
+ // DHCP enabled: No
+ // IP Address: 127.0.0.1
+ // Subnet Prefix: 127.0.0.0/8 (mask 255.0.0.0)
+ // InterfaceMetric: 50
+ //
addrs := make([]string, 0)
var addr, subnetprefix string
- lines := bytes.Split(out, []byte{'\r', '\n'})
+ var processingOurInterface bool
+ lines := bytes.Split(netshOutput, []byte{'\r', '\n'})
for _, line := range lines {
+ if !processingOurInterface {
+ if !bytes.HasPrefix(line, []byte("Configuration for interface")) {
+ continue
+ }
+ if !bytes.Contains(line, []byte(`"`+name+`"`)) {
+ continue
+ }
+ processingOurInterface = true
+ continue
+ }
+ if len(line) == 0 {
+ break
+ }
if bytes.Contains(line, []byte("Subnet Prefix:")) {
f := bytes.Split(line, []byte{':'})
if len(f) == 2 {
@@ -351,18 +374,50 @@ func netshInterfaceIPv4ShowAddress(name string) ([]string, error) {
}
}
}
- return addrs, nil
+ return addrs
}
-func netshInterfaceIPv6ShowAddress(name string) ([]string, error) {
+func netshInterfaceIPv6ShowAddress(name string, netshOutput []byte) []string {
+ // adress information is listed like:
+ //
+ //Address ::1 Parameters
+ //---------------------------------------------------------
+ //Interface Luid : Loopback Pseudo-Interface 1
+ //Scope Id : 0.0
+ //Valid Lifetime : infinite
+ //Preferred Lifetime : infinite
+ //DAD State : Preferred
+ //Address Type : Other
+ //Skip as Source : false
+ //
+ //Address XXXX::XXXX:XXXX:XXXX:XXXX%11 Parameters
+ //---------------------------------------------------------
+ //Interface Luid : Local Area Connection
+ //Scope Id : 0.11
+ //Valid Lifetime : infinite
+ //Preferred Lifetime : infinite
+ //DAD State : Preferred
+ //Address Type : Other
+ //Skip as Source : false
+ //
+
// TODO: need to test ipv6 netmask too, but netsh does not outputs it
- out, err := runCmd("netsh", "interface", "ipv6", "show", "address", "interface=\""+name+"\"")
- if err != nil {
- return nil, err
- }
+ var addr string
addrs := make([]string, 0)
- lines := bytes.Split(out, []byte{'\r', '\n'})
+ lines := bytes.Split(netshOutput, []byte{'\r', '\n'})
for _, line := range lines {
+ if addr != "" {
+ if len(line) == 0 {
+ addr = ""
+ continue
+ }
+ if string(line) != "Interface Luid : "+name {
+ continue
+ }
+ addrs = append(addrs, addr)
+ addr = ""
+ continue
+ }
if !bytes.HasPrefix(line, []byte("Address")) {
continue
}
@@ -383,9 +438,9 @@ func netshInterfaceIPv6ShowAddress(name string) ([]string, error) {
f[0] = []byte(ParseIP(string(f[0])).String())
}
- addrs = append(addrs, string(bytes.ToLower(bytes.TrimSpace(f[0]))))
+ addr = string(bytes.ToLower(bytes.TrimSpace(f[0])))
}
- return addrs, nil
+ return addrs
}
func TestInterfaceAddrsWithNetsh(t *testing.T) {
@@ -395,6 +450,16 @@ func TestInterfaceAddrsWithNetsh(t *testing.T) {
if !isEnglishOS(t) {
t.Skip("English version of OS required for this test")
}
+
+ outIPV4, err := runCmd("netsh", "interface", "ipv4", "show", "address")
+ if err != nil {
+ t.Fatal(err)
+ }
+ outIPV6, err := runCmd("netsh", "interface", "ipv6", "show", "address", "level=verbose")
+ if err != nil {
+ t.Fatal(err)
+ }
+
ift, err := Interfaces()
if err != nil {
t.Fatal(err)
@@ -431,14 +496,8 @@ func TestInterfaceAddrsWithNetsh(t *testing.T) {
}
sort.Strings(have)
- want, err := netshInterfaceIPv4ShowAddress(ifi.Name)
- if err != nil {
- t.Fatal(err)
- }
- wantIPv6, err := netshInterfaceIPv6ShowAddress(ifi.Name)
- if err != nil {
- t.Fatal(err)
- }
+ want := netshInterfaceIPv4ShowAddress(ifi.Name, outIPV4)
+ wantIPv6 := netshInterfaceIPv6ShowAddress(ifi.Name, outIPV6)
want = append(want, wantIPv6...)
sort.Strings(want)
@@ -487,8 +546,13 @@ func TestInterfaceHardwareAddrWithGetmac(t *testing.T) {
//
//Connection Name: Bluetooth Network Connection
//Network Adapter: Bluetooth Device (Personal Area Network)
- //Physical Address: XX-XX-XX-XX-XX-XX
- //Transport Name: Media disconnected
+ //Physical Address: N/A
+ //Transport Name: Hardware not present
+ //
+ //Connection Name: VMware Network Adapter VMnet8
+ //Network Adapter: VMware Virtual Ethernet Adapter for VMnet8
+ //Physical Address: Disabled
+ //Transport Name: Disconnected
//
want := make(map[string]string)
var name string
@@ -516,6 +580,9 @@ func TestInterfaceHardwareAddrWithGetmac(t *testing.T) {
if addr == "" {
t.Fatal("empty address on \"Physical Address\" line: %q", line)
}
+ if addr == "disabled" || addr == "n/a" {
+ continue
+ }
addr = strings.Replace(addr, "-", ":", -1)
want[name] = addr
name = ""
diff --git a/src/runtime/cgocheck.go b/src/runtime/cgocheck.go
index 0077e22332..aebce1506d 100644
--- a/src/runtime/cgocheck.go
+++ b/src/runtime/cgocheck.go
@@ -135,9 +135,6 @@ func cgoCheckTypedBlock(typ *_type, src unsafe.Pointer, off, size uintptr) {
hbits := heapBitsForAddr(uintptr(src))
for i := uintptr(0); i < off+size; i += sys.PtrSize {
bits := hbits.bits()
- if bits != 0 {
- println(i, bits)
- }
if i >= off && bits&bitPointer != 0 {
v := *(*unsafe.Pointer)(add(src, i))
if cgoIsGoPointer(v) {
diff --git a/src/runtime/crash_test.go b/src/runtime/crash_test.go
index b622eb4526..5f0e77b0dc 100644
--- a/src/runtime/crash_test.go
+++ b/src/runtime/crash_test.go
@@ -317,3 +317,22 @@ func TestNetpollDeadlock(t *testing.T) {
t.Fatalf("output does not start with %q:\n%s", want, output)
}
}
+
+func TestPanicTraceback(t *testing.T) {
+ output := runTestProg(t, "testprog", "PanicTraceback")
+ want := "panic: hello"
+ if !strings.HasPrefix(output, want) {
+ t.Fatalf("output does not start with %q:\n%s", want, output)
+ }
+
+ // Check functions in the traceback.
+ fns := []string{"panic", "main.pt1.func1", "panic", "main.pt2.func1", "panic", "main.pt2", "main.pt1"}
+ for _, fn := range fns {
+ re := regexp.MustCompile(`(?m)^` + regexp.QuoteMeta(fn) + `\(.*\n`)
+ idx := re.FindStringIndex(output)
+ if idx == nil {
+ t.Fatalf("expected %q function in traceback:\n%s", fn, output)
+ }
+ output = output[idx[1]:]
+ }
+}
diff --git a/src/runtime/crash_unix_test.go b/src/runtime/crash_unix_test.go
index 5284a37b0f..771b303f6e 100644
--- a/src/runtime/crash_unix_test.go
+++ b/src/runtime/crash_unix_test.go
@@ -14,6 +14,7 @@ import (
"os/exec"
"path/filepath"
"runtime"
+ "strings"
"syscall"
"testing"
)
@@ -52,6 +53,18 @@ func TestCrashDumpsAllThreads(t *testing.T) {
cmd = exec.Command(filepath.Join(dir, "a.exe"))
cmd = testEnv(cmd)
cmd.Env = append(cmd.Env, "GOTRACEBACK=crash")
+
+ // Set GOGC=off. Because of golang.org/issue/10958, the tight
+ // loops in the test program are not preemptible. If GC kicks
+ // in, it may lock up and prevent main from saying it's ready.
+ newEnv := []string{}
+ for _, s := range cmd.Env {
+ if !strings.HasPrefix(s, "GOGC=") {
+ newEnv = append(newEnv, s)
+ }
+ }
+ cmd.Env = append(newEnv, "GOGC=off")
+
var outbuf bytes.Buffer
cmd.Stdout = &outbuf
cmd.Stderr = &outbuf
@@ -137,8 +150,8 @@ func loop(i int, c chan bool) {
func TestSignalExitStatus(t *testing.T) {
testenv.MustHaveGoBuild(t)
switch runtime.GOOS {
- case "netbsd":
- t.Skip("skipping on NetBSD; see https://golang.org/issue/14063")
+ case "netbsd", "solaris":
+ t.Skipf("skipping on %s; see https://golang.org/issue/14063", runtime.GOOS)
}
exe, err := buildTestProg(t, "testprog")
if err != nil {
diff --git a/src/runtime/export_linux_test.go b/src/runtime/export_linux_test.go
index c8b9746676..61d6ae4bf2 100644
--- a/src/runtime/export_linux_test.go
+++ b/src/runtime/export_linux_test.go
@@ -7,3 +7,4 @@
package runtime
var NewOSProc0 = newosproc0
+var Mincore = mincore
diff --git a/src/runtime/export_mmap_test.go b/src/runtime/export_mmap_test.go
new file mode 100644
index 0000000000..11ea076f0b
--- /dev/null
+++ b/src/runtime/export_mmap_test.go
@@ -0,0 +1,15 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+// Export guts for testing.
+
+package runtime
+
+var Mmap = mmap
+
+const ENOMEM = _ENOMEM
+const MAP_ANON = _MAP_ANON
+const MAP_PRIVATE = _MAP_PRIVATE
diff --git a/src/runtime/mem_bsd.go b/src/runtime/mem_bsd.go
index 1e388ec728..c3fe6106d7 100644
--- a/src/runtime/mem_bsd.go
+++ b/src/runtime/mem_bsd.go
@@ -59,9 +59,9 @@ func sysReserve(v unsafe.Pointer, n uintptr, reserved *bool) unsafe.Pointer {
return p
}
-func sysMap(v unsafe.Pointer, n uintptr, reserved bool, sysStat *uint64) {
- const _ENOMEM = 12
+const _ENOMEM = 12
+func sysMap(v unsafe.Pointer, n uintptr, reserved bool, sysStat *uint64) {
mSysStatInc(sysStat, n)
// On 64-bit, we don't actually have v reserved, so tread carefully.
diff --git a/src/runtime/os2_nacl.go b/src/runtime/os2_nacl.go
index 0c91e0f737..d8c88db0ad 100644
--- a/src/runtime/os2_nacl.go
+++ b/src/runtime/os2_nacl.go
@@ -10,18 +10,19 @@ const (
// native_client/src/trusted/service_runtime/include/sys/errno.h
// The errors are mainly copied from Linux.
- _EPERM = 1 /* Operation not permitted */
- _ENOENT = 2 /* No such file or directory */
- _ESRCH = 3 /* No such process */
- _EINTR = 4 /* Interrupted system call */
- _EIO = 5 /* I/O error */
- _ENXIO = 6 /* No such device or address */
- _E2BIG = 7 /* Argument list too long */
- _ENOEXEC = 8 /* Exec format error */
- _EBADF = 9 /* Bad file number */
- _ECHILD = 10 /* No child processes */
- _EAGAIN = 11 /* Try again */
- _ENOMEM = 12 /* Out of memory */
+ _EPERM = 1 /* Operation not permitted */
+ _ENOENT = 2 /* No such file or directory */
+ _ESRCH = 3 /* No such process */
+ _EINTR = 4 /* Interrupted system call */
+ _EIO = 5 /* I/O error */
+ _ENXIO = 6 /* No such device or address */
+ _E2BIG = 7 /* Argument list too long */
+ _ENOEXEC = 8 /* Exec format error */
+ _EBADF = 9 /* Bad file number */
+ _ECHILD = 10 /* No child processes */
+ _EAGAIN = 11 /* Try again */
+ // _ENOMEM is defined in mem_bsd.go for nacl.
+ // _ENOMEM = 12 /* Out of memory */
_EACCES = 13 /* Permission denied */
_EFAULT = 14 /* Bad address */
_EBUSY = 16 /* Device or resource busy */
diff --git a/src/runtime/os3_solaris.go b/src/runtime/os3_solaris.go
index 7bda07bd4a..7ebb35c8e9 100644
--- a/src/runtime/os3_solaris.go
+++ b/src/runtime/os3_solaris.go
@@ -442,7 +442,21 @@ func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
//go:nosplit
func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer {
- return unsafe.Pointer(sysvicall6(&libc_mmap, uintptr(addr), uintptr(n), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(off)))
+ p, err := doMmap(uintptr(addr), n, uintptr(prot), uintptr(flags), uintptr(fd), uintptr(off))
+ if p == ^uintptr(0) {
+ return unsafe.Pointer(err)
+ }
+ return unsafe.Pointer(p)
+}
+
+//go:nosplit
+func doMmap(addr, n, prot, flags, fd, off uintptr) (uintptr, uintptr) {
+ var libcall libcall
+ libcall.fn = uintptr(unsafe.Pointer(&libc_mmap))
+ libcall.n = 6
+ libcall.args = uintptr(noescape(unsafe.Pointer(&addr)))
+ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&libcall))
+ return libcall.r1, libcall.err
}
//go:nosplit
diff --git a/src/runtime/pprof/pprof.go b/src/runtime/pprof/pprof.go
index 7d677cb64e..e09a33d5d9 100644
--- a/src/runtime/pprof/pprof.go
+++ b/src/runtime/pprof/pprof.go
@@ -346,7 +346,7 @@ func printStackRecord(w io.Writer, stk []uintptr, allFrames bool) {
name := f.Name()
// Hide runtime.goexit and any runtime functions at the beginning.
// This is useful mainly for allocation traces.
- wasPanic = name == "runtime.panic"
+ wasPanic = name == "runtime.gopanic"
if name == "runtime.goexit" || !show && strings.HasPrefix(name, "runtime.") {
continue
}
diff --git a/src/runtime/runtime-lldb_test.go b/src/runtime/runtime-lldb_test.go
new file mode 100644
index 0000000000..2bd91c1ec0
--- /dev/null
+++ b/src/runtime/runtime-lldb_test.go
@@ -0,0 +1,262 @@
+// Copyright 2016 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 runtime_test
+
+import (
+ "debug/elf"
+ "debug/macho"
+ "encoding/binary"
+ "internal/testenv"
+ "io"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "runtime"
+ "strings"
+ "testing"
+)
+
+var lldbPath string
+
+func checkLldbPython(t *testing.T) {
+ cmd := exec.Command("lldb", "-P")
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Skipf("skipping due to issue running lldb: %v\n%s", err, out)
+ }
+ lldbPath = strings.TrimSpace(string(out))
+
+ cmd = exec.Command("/usr/bin/python2.7", "-c", "import sys;sys.path.append(sys.argv[1]);import lldb; print('go lldb python support')", lldbPath)
+ out, err = cmd.CombinedOutput()
+
+ if err != nil {
+ t.Skipf("skipping due to issue running python: %v\n%s", err, out)
+ }
+ if string(out) != "go lldb python support\n" {
+ t.Skipf("skipping due to lack of python lldb support: %s", out)
+ }
+
+ if runtime.GOOS == "darwin" {
+ // Try to see if we have debugging permissions.
+ cmd = exec.Command("/usr/sbin/DevToolsSecurity", "-status")
+ out, err = cmd.CombinedOutput()
+ if err != nil {
+ t.Skipf("DevToolsSecurity failed: %v", err)
+ } else if !strings.Contains(string(out), "enabled") {
+ t.Skip(string(out))
+ }
+ cmd = exec.Command("/usr/bin/groups")
+ out, err = cmd.CombinedOutput()
+ if err != nil {
+ t.Skipf("groups failed: %v", err)
+ } else if !strings.Contains(string(out), "_developer") {
+ t.Skip("Not in _developer group")
+ }
+ }
+}
+
+const lldbHelloSource = `
+package main
+import "fmt"
+func main() {
+ mapvar := make(map[string]string,5)
+ mapvar["abc"] = "def"
+ mapvar["ghi"] = "jkl"
+ intvar := 42
+ ptrvar := &intvar
+ fmt.Println("hi") // line 10
+ _ = ptrvar
+}
+`
+
+const lldbScriptSource = `
+import sys
+sys.path.append(sys.argv[1])
+import lldb
+import os
+
+TIMEOUT_SECS = 5
+
+debugger = lldb.SBDebugger.Create()
+debugger.SetAsync(True)
+target = debugger.CreateTargetWithFileAndArch("a.exe", None)
+if target:
+ print "Created target"
+ main_bp = target.BreakpointCreateByLocation("main.go", 10)
+ if main_bp:
+ print "Created breakpoint"
+ process = target.LaunchSimple(None, None, os.getcwd())
+ if process:
+ print "Process launched"
+ listener = debugger.GetListener()
+ process.broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged)
+ while True:
+ event = lldb.SBEvent()
+ if listener.WaitForEvent(TIMEOUT_SECS, event):
+ if lldb.SBProcess.GetRestartedFromEvent(event):
+ continue
+ state = process.GetState()
+ if state in [lldb.eStateUnloaded, lldb.eStateLaunching, lldb.eStateRunning]:
+ continue
+ else:
+ print "Timeout launching"
+ break
+ if state == lldb.eStateStopped:
+ for t in process.threads:
+ if t.GetStopReason() == lldb.eStopReasonBreakpoint:
+ print "Hit breakpoint"
+ frame = t.GetFrameAtIndex(0)
+ if frame:
+ if frame.line_entry:
+ print "Stopped at %s:%d" % (frame.line_entry.file.basename, frame.line_entry.line)
+ if frame.function:
+ print "Stopped in %s" % (frame.function.name,)
+ var = frame.FindVariable('intvar')
+ if var:
+ print "intvar = %s" % (var.GetValue(),)
+ else:
+ print "no intvar"
+ else:
+ print "Process state", state
+ process.Destroy()
+else:
+ print "Failed to create target a.exe"
+
+lldb.SBDebugger.Destroy(debugger)
+sys.exit()
+`
+
+const expectedLldbOutput = `Created target
+Created breakpoint
+Process launched
+Hit breakpoint
+Stopped at main.go:10
+Stopped in main.main
+intvar = 42
+`
+
+func TestLldbPython(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+ if final := os.Getenv("GOROOT_FINAL"); final != "" && runtime.GOROOT() != final {
+ t.Skip("gdb test can fail with GOROOT_FINAL pending")
+ }
+
+ checkLldbPython(t)
+
+ dir, err := ioutil.TempDir("", "go-build")
+ if err != nil {
+ t.Fatalf("failed to create temp directory: %v", err)
+ }
+ defer os.RemoveAll(dir)
+
+ src := filepath.Join(dir, "main.go")
+ err = ioutil.WriteFile(src, []byte(lldbHelloSource), 0644)
+ if err != nil {
+ t.Fatalf("failed to create file: %v", err)
+ }
+
+ cmd := exec.Command("go", "build", "-gcflags", "-N -l", "-o", "a.exe")
+ cmd.Dir = dir
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("building source %v\n%s", err, out)
+ }
+
+ src = filepath.Join(dir, "script.py")
+ err = ioutil.WriteFile(src, []byte(lldbScriptSource), 0755)
+ if err != nil {
+ t.Fatalf("failed to create script: %v", err)
+ }
+
+ cmd = exec.Command("/usr/bin/python2.7", "script.py", lldbPath)
+ cmd.Dir = dir
+ got, _ := cmd.CombinedOutput()
+
+ if string(got) != expectedLldbOutput {
+ if strings.Contains(string(got), "Timeout launching") {
+ t.Skip("Timeout launching")
+ }
+ t.Fatalf("Unexpected lldb output:\n%s", got)
+ }
+}
+
+// Check that aranges are valid even when lldb isn't installed.
+func TestDwarfAranges(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+ dir, err := ioutil.TempDir("", "go-build")
+ if err != nil {
+ t.Fatalf("failed to create temp directory: %v", err)
+ }
+ defer os.RemoveAll(dir)
+
+ src := filepath.Join(dir, "main.go")
+ err = ioutil.WriteFile(src, []byte(lldbHelloSource), 0644)
+ if err != nil {
+ t.Fatalf("failed to create file: %v", err)
+ }
+
+ cmd := exec.Command("go", "build", "-o", "a.exe")
+ cmd.Dir = dir
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("building source %v\n%s", err, out)
+ }
+
+ filename := filepath.Join(dir, "a.exe")
+ if f, err := elf.Open(filename); err == nil {
+ sect := f.Section(".debug_aranges")
+ if sect == nil {
+ t.Fatal("Missing aranges section")
+ }
+ verifyAranges(t, f.ByteOrder, sect.Open())
+ } else if f, err := macho.Open(filename); err == nil {
+ sect := f.Section("__debug_aranges")
+ if sect == nil {
+ t.Fatal("Missing aranges section")
+ }
+ verifyAranges(t, f.ByteOrder, sect.Open())
+ } else {
+ t.Skip("Not an elf or macho binary.")
+ }
+}
+
+func verifyAranges(t *testing.T, byteorder binary.ByteOrder, data io.ReadSeeker) {
+ var header struct {
+ UnitLength uint32 // does not include the UnitLength field
+ Version uint16
+ Offset uint32
+ AddressSize uint8
+ SegmentSize uint8
+ }
+ for {
+ offset, err := data.Seek(0, 1)
+ if err != nil {
+ t.Fatalf("Seek error: %v", err)
+ }
+ if err = binary.Read(data, byteorder, &header); err == io.EOF {
+ return
+ } else if err != nil {
+ t.Fatalf("Error reading arange header: %v", err)
+ }
+ tupleSize := int64(header.SegmentSize) + 2*int64(header.AddressSize)
+ lastTupleOffset := offset + int64(header.UnitLength) + 4 - tupleSize
+ if lastTupleOffset%tupleSize != 0 {
+ t.Fatalf("Invalid arange length %d, (addr %d, seg %d)", header.UnitLength, header.AddressSize, header.SegmentSize)
+ }
+ if _, err = data.Seek(lastTupleOffset, 0); err != nil {
+ t.Fatalf("Seek error: %v", err)
+ }
+ buf := make([]byte, tupleSize)
+ if n, err := data.Read(buf); err != nil || int64(n) < tupleSize {
+ t.Fatalf("Read error: %v", err)
+ }
+ for _, val := range buf {
+ if val != 0 {
+ t.Fatalf("Invalid terminator")
+ }
+ }
+ }
+}
diff --git a/src/runtime/runtime_linux_test.go b/src/runtime/runtime_linux_test.go
index 5344ed2051..58c797f1dd 100644
--- a/src/runtime/runtime_linux_test.go
+++ b/src/runtime/runtime_linux_test.go
@@ -8,6 +8,7 @@ import (
. "runtime"
"syscall"
"testing"
+ "unsafe"
)
var pid, tid int
@@ -27,3 +28,15 @@ func TestLockOSThread(t *testing.T) {
t.Fatalf("pid=%d but tid=%d", pid, tid)
}
}
+
+// Test that error values are negative. Use address 1 (a misaligned
+// pointer) to get -EINVAL.
+func TestMincoreErrorSign(t *testing.T) {
+ var dst byte
+ v := Mincore(unsafe.Pointer(uintptr(1)), 1, &dst)
+
+ const EINVAL = 0x16
+ if v != -EINVAL {
+ t.Errorf("mincore = %v, want %v", v, -EINVAL)
+ }
+}
diff --git a/src/runtime/runtime_mmap_test.go b/src/runtime/runtime_mmap_test.go
new file mode 100644
index 0000000000..ff5e733cb0
--- /dev/null
+++ b/src/runtime/runtime_mmap_test.go
@@ -0,0 +1,30 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+package runtime_test
+
+import (
+ "runtime"
+ "runtime/internal/sys"
+ "testing"
+)
+
+// Test that the error value returned by mmap is positive, as that is
+// what the code in mem_bsd.go, mem_darwin.go, and mem_linux.go expects.
+// See the uses of ENOMEM in sysMap in those files.
+func TestMmapErrorSign(t *testing.T) {
+ p := runtime.Mmap(nil, ^uintptr(0)&^(sys.PhysPageSize-1), 0, runtime.MAP_ANON|runtime.MAP_PRIVATE, -1, 0)
+
+ // The runtime.mmap function is nosplit, but t.Errorf is not.
+ // Reset the pointer so that we don't get an "invalid stack
+ // pointer" error from t.Errorf if we call it.
+ v := uintptr(p)
+ p = nil
+
+ if v != runtime.ENOMEM {
+ t.Errorf("mmap = %v, want %v", v, runtime.ENOMEM)
+ }
+}
diff --git a/src/runtime/stack_test.go b/src/runtime/stack_test.go
index fa073f19ad..928d1eca20 100644
--- a/src/runtime/stack_test.go
+++ b/src/runtime/stack_test.go
@@ -111,7 +111,8 @@ func TestStackGrowth(t *testing.T) {
select {
case <-done:
case <-time.After(20 * time.Second):
- t.Fatal("finalizer did not run")
+ t.Error("finalizer did not run")
+ return
}
}()
wg.Wait()
@@ -191,7 +192,6 @@ func TestStackGrowthCallback(t *testing.T) {
<-done
})
}()
-
wg.Wait()
}
diff --git a/src/runtime/string.go b/src/runtime/string.go
index f8ccd41b1d..dd04bda04b 100644
--- a/src/runtime/string.go
+++ b/src/runtime/string.go
@@ -139,7 +139,7 @@ func slicebytetostringtmp(b []byte) string {
func stringtoslicebyte(buf *tmpBuf, s string) []byte {
var b []byte
if buf != nil && len(s) <= len(buf) {
- b = buf[:len(s)]
+ b = buf[:len(s):len(s)]
} else {
b = rawbyteslice(len(s))
}
@@ -171,7 +171,7 @@ func stringtoslicerune(buf *[tmpStringBufSize]rune, s string) []rune {
}
var a []rune
if buf != nil && n <= len(buf) {
- a = buf[:n]
+ a = buf[:n:n]
} else {
a = rawruneslice(n)
}
diff --git a/src/runtime/string_test.go b/src/runtime/string_test.go
index 318a5532e5..150a25520a 100644
--- a/src/runtime/string_test.go
+++ b/src/runtime/string_test.go
@@ -222,3 +222,18 @@ func TestRangeStringCast(t *testing.T) {
t.Fatalf("want 0 allocs, got %v", n)
}
}
+
+func TestString2Slice(t *testing.T) {
+ // Make sure we don't return slices that expose
+ // an unzeroed section of stack-allocated temp buf
+ // between len and cap. See issue 14232.
+ s := "foož"
+ b := ([]byte)(s)
+ if cap(b) != 5 {
+ t.Errorf("want cap of 5, got %d", cap(b))
+ }
+ r := ([]rune)(s)
+ if cap(r) != 4 {
+ t.Errorf("want cap of 4, got %d", cap(r))
+ }
+}
diff --git a/src/runtime/sys_linux_arm64.s b/src/runtime/sys_linux_arm64.s
index ca0e07aaa4..94c101a3d4 100644
--- a/src/runtime/sys_linux_arm64.s
+++ b/src/runtime/sys_linux_arm64.s
@@ -269,6 +269,9 @@ TEXT runtime·mmap(SB),NOSPLIT,$-8
MOVD $SYS_mmap, R8
SVC
+ CMN $4095, R0
+ BCC 2(PC)
+ NEG R0,R0
MOVD R0, ret+32(FP)
RET
diff --git a/src/runtime/sys_linux_mips64x.s b/src/runtime/sys_linux_mips64x.s
index 6ccb38f90b..26437ddde4 100644
--- a/src/runtime/sys_linux_mips64x.s
+++ b/src/runtime/sys_linux_mips64x.s
@@ -168,6 +168,7 @@ TEXT runtime·mincore(SB),NOSPLIT,$-8-28
MOVV dst+16(FP), R6
MOVV $SYS_mincore, R2
SYSCALL
+ SUBVU R2, R0, R2 // caller expects negative errno
MOVW R2, ret+24(FP)
RET
diff --git a/src/runtime/sys_linux_ppc64x.s b/src/runtime/sys_linux_ppc64x.s
index ba410c51b6..d063e025a6 100644
--- a/src/runtime/sys_linux_ppc64x.s
+++ b/src/runtime/sys_linux_ppc64x.s
@@ -153,6 +153,7 @@ TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28
MOVD n+8(FP), R4
MOVD dst+16(FP), R5
SYSCALL $SYS_mincore
+ NEG R3 // caller expects negative errno
MOVW R3, ret+24(FP)
RET
diff --git a/src/runtime/sys_nacl_386.s b/src/runtime/sys_nacl_386.s
index bf2d36ec85..e69a0b7bfe 100644
--- a/src/runtime/sys_nacl_386.s
+++ b/src/runtime/sys_nacl_386.s
@@ -227,6 +227,9 @@ TEXT runtime·mmap(SB),NOSPLIT,$32
LEAL 24(SP), AX
MOVL AX, 20(SP)
NACL_SYSCALL(SYS_mmap)
+ CMPL AX, $-4095
+ JNA 2(PC)
+ NEGL AX
MOVL AX, ret+24(FP)
RET
diff --git a/src/runtime/testdata/testprog/deadlock.go b/src/runtime/testdata/testprog/deadlock.go
index 7f0a0cd1e0..73fbf6224d 100644
--- a/src/runtime/testdata/testprog/deadlock.go
+++ b/src/runtime/testdata/testprog/deadlock.go
@@ -29,7 +29,7 @@ func init() {
register("GoexitInPanic", GoexitInPanic)
register("PanicAfterGoexit", PanicAfterGoexit)
register("RecoveredPanicAfterGoexit", RecoveredPanicAfterGoexit)
-
+ register("PanicTraceback", PanicTraceback)
}
func SimpleDeadlock() {
@@ -171,3 +171,21 @@ func RecoveredPanicAfterGoexit() {
}()
runtime.Goexit()
}
+
+func PanicTraceback() {
+ pt1()
+}
+
+func pt1() {
+ defer func() {
+ panic("panic pt1")
+ }()
+ pt2()
+}
+
+func pt2() {
+ defer func() {
+ panic("panic pt2")
+ }()
+ panic("hello")
+}
diff --git a/src/runtime/time.go b/src/runtime/time.go
index ffe7590526..3f8f6968c2 100644
--- a/src/runtime/time.go
+++ b/src/runtime/time.go
@@ -16,7 +16,7 @@ type timer struct {
i int // heap index
// Timer wakes up at when, and then at when+period, ... (period > 0 only)
- // each time calling f(now, arg) in the timer goroutine, so f must be
+ // each time calling f(arg, now) in the timer goroutine, so f must be
// a well-behaved function and not block.
when int64
period int64
diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go
index 6559cd7ba3..b4bfe71627 100644
--- a/src/runtime/traceback.go
+++ b/src/runtime/traceback.go
@@ -380,7 +380,11 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
if (n > 0 || flags&_TraceTrap == 0) && frame.pc > f.entry && !waspanic {
tracepc--
}
- print(funcname(f), "(")
+ name := funcname(f)
+ if name == "runtime.gopanic" {
+ name = "panic"
+ }
+ print(name, "(")
argp := (*[100]uintptr)(unsafe.Pointer(frame.argp))
for i := uintptr(0); i < frame.arglen/sys.PtrSize; i++ {
if i >= 10 {
@@ -617,10 +621,10 @@ func showframe(f *_func, gp *g) bool {
level, _, _ := gotraceback()
name := funcname(f)
- // Special case: always show runtime.panic frame, so that we can
+ // Special case: always show runtime.gopanic frame, so that we can
// see where a panic started in the middle of a stack trace.
// See golang.org/issue/5832.
- if name == "runtime.panic" {
+ if name == "runtime.gopanic" {
return true
}
diff --git a/test/fixedbugs/issue14331.dir/a.go b/test/fixedbugs/issue14331.dir/a.go
new file mode 100644
index 0000000000..1b7f853bc9
--- /dev/null
+++ b/test/fixedbugs/issue14331.dir/a.go
@@ -0,0 +1,14 @@
+// Copyright 2016 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 a
+
+var S struct {
+ Str string `tag`
+}
+
+func F() string {
+ v := S
+ return v.Str
+}
diff --git a/test/fixedbugs/issue14331.dir/b.go b/test/fixedbugs/issue14331.dir/b.go
new file mode 100644
index 0000000000..7a0abb2506
--- /dev/null
+++ b/test/fixedbugs/issue14331.dir/b.go
@@ -0,0 +1,11 @@
+// Copyright 2016 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 b
+
+import "./a"
+
+func G() string {
+ return a.F()
+}
diff --git a/test/fixedbugs/issue14331.go b/test/fixedbugs/issue14331.go
new file mode 100644
index 0000000000..32f3e5156c
--- /dev/null
+++ b/test/fixedbugs/issue14331.go
@@ -0,0 +1,9 @@
+// compiledir
+
+// Copyright 2016 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.
+
+// Inline function misses struct tags.
+
+package ignored
diff --git a/test/writebarrier.go b/test/writebarrier.go
index 9b741a60df..dcd20a0225 100644
--- a/test/writebarrier.go
+++ b/test/writebarrier.go
@@ -144,3 +144,17 @@ type T8 struct {
func f16(x []T8, y T8) []T8 {
return append(x, y) // ERROR "write barrier"
}
+
+func t1(i interface{}) **int {
+ // From issue 14306, make sure we have write barriers in a type switch
+ // where the assigned variable escapes.
+ switch x := i.(type) { // ERROR "write barrier"
+ case *int:
+ return &x
+ }
+ switch y := i.(type) { // no write barrier here
+ case **int:
+ return y
+ }
+ return nil
+}