[Pkg-golang-commits] [golang] 23/27: Imported Upstream version 1.6~rc2

Michael Hudson-Doyle mwhudson-guest at moszumanska.debian.org
Tue Mar 1 02:57:44 UTC 2016


This is an automated email from the git hooks/post-receive script.

mwhudson-guest pushed a commit to branch gbp
in repository golang.

commit 512a669a6098876c407e93d2a2848c96197b65d8
Author: Michael Hudson-Doyle <michael.hudson at canonical.com>
Date:   Fri Feb 12 10:43:25 2016 +1300

    Imported Upstream version 1.6~rc2
---
 VERSION                                    |   2 +-
 doc/go1.6.html                             |  26 +---
 lib/time/update.bash                       |   4 +-
 lib/time/zoneinfo.zip                      | Bin 360617 -> 360703 bytes
 src/archive/zip/reader.go                  |  12 +-
 src/archive/zip/reader_test.go             | 235 +++++++++++++++++++++++++++--
 src/cmd/compile/internal/gc/parser.go      |  18 +++
 src/cmd/go/alldocs.go                      |   3 +-
 src/cmd/go/build.go                        |   3 +-
 src/cmd/go/go_test.go                      | 140 ++++++++++++++++-
 src/cmd/go/main.go                         |   9 ++
 src/cmd/go/pkg.go                          |  30 +++-
 src/cmd/go/vcs.go                          |  11 +-
 src/cmd/vet/cgo.go                         |   3 +
 src/cmd/vet/print.go                       |   8 +-
 src/cmd/vet/testdata/cgo2.go               |   9 ++
 src/cmd/vet/testdata/print.go              |   3 +
 src/net/http/clientserver_test.go          |  12 +-
 src/net/http/h2_bundle.go                  |  67 +++++++-
 src/net/http/httputil/reverseproxy.go      |   5 +-
 src/net/http/httputil/reverseproxy_test.go |   8 +
 src/net/http/transport_test.go             |   5 +-
 src/net/net_test.go                        |  24 ++-
 src/os/doc.go                              |   6 +-
 src/runtime/cgo_mmap.go                    |  13 +-
 src/runtime/pprof/pprof_test.go            |  14 +-
 src/runtime/proc.go                        |  12 ++
 src/runtime/runtime_test.go                |  25 ++-
 src/runtime/sys_darwin_386.s               |  20 ++-
 src/sync/waitgroup_test.go                 |  11 +-
 src/unsafe/unsafe.go                       |   2 +-
 test/fixedbugs/issue14164.dir/a.go         |  47 ++++++
 test/fixedbugs/issue14164.dir/main.go      |  12 ++
 test/fixedbugs/issue14164.go               |   7 +
 34 files changed, 711 insertions(+), 95 deletions(-)

diff --git a/VERSION b/VERSION
index c9b2fc0..ad28dff 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-go1.6rc1
\ No newline at end of file
+go1.6rc2
\ No newline at end of file
diff --git a/doc/go1.6.html b/doc/go1.6.html
index 46a8f65..b4a3900 100644
--- a/doc/go1.6.html
+++ b/doc/go1.6.html
@@ -464,20 +464,8 @@ Second, the new <a href="/pkg/text/template/#hdr-Actions"><code>{{"{{"}}block}}<
 combined with allowing redefinition of named templates,
 provides a simple way to define pieces of a template that
 can be replaced in different instantiations.
-For example, the template
-</p>
-
-<pre>
-<title>{{"{{"}}block "title"}}Page Title{{"{{"}}end}}</title>
-<body>
-<h1>{{"{{"}}template "title"}}</h1>
-{{"{{"}}block "page"}}Main text{{"{{"}}end}}
-</pre>
-
-<p>
-defines the basic formatting of a web page. A program can then
-overlay that template with new definitions for the <code>"title"</code>
-and <code>"page"</code> blocks to reuse the formatting for another page.
+There is <a href="/pkg/text/template/#example_Template_block">an example</a>
+in the <code>text/template</code> package that demonstrates this new feature.
 </p>
 
 <h3 id="minor_library_changes">Minor changes to the library</h3>
@@ -752,13 +740,13 @@ Third, the
 <code>Expect:</code> <code>100-continue</code> header (see
 <a href="/pkg/net/http/#Transport"><code>Transport.ExpectContinueTimeout</code></a>).
 Fourth, there are
-<a href="/pkg/net/http/#pkg-constants">five new error codes</a> from RFC 6585:
+<a href="/pkg/net/http/#pkg-constants">five new error codes</a>:
 <code>StatusPreconditionRequired</code> (428),
 <code>StatusTooManyRequests</code> (429),
-<code>StatusRequestHeaderFieldsTooLarge</code> (431),
-<code>StatusUnavailableForLegalReasons</code> (451)),
-and
-<code>StatusNetworkAuthenticationRequired</code> (511).
+<code>StatusRequestHeaderFieldsTooLarge</code> (431), and
+<code>StatusNetworkAuthenticationRequired</code> (511) from RFC 6585,
+as well as the recently-approved
+<code>StatusUnavailableForLegalReasons</code> (451).
 Fifth, the implementation and documentation of
 <a href="/pkg/net/http/#CloseNotifier"><code>CloseNotifier</code></a>
 has been substantially changed.
diff --git a/lib/time/update.bash b/lib/time/update.bash
index 3ffadc2..86b1f21 100755
--- a/lib/time/update.bash
+++ b/lib/time/update.bash
@@ -8,8 +8,8 @@
 # Consult http://www.iana.org/time-zones for the latest versions.
 
 # Versions to use.
-CODE=2015g
-DATA=2015g
+CODE=2016a
+DATA=2016a
 
 set -e
 rm -rf work
diff --git a/lib/time/zoneinfo.zip b/lib/time/zoneinfo.zip
index 740d819..0207d6b 100644
Binary files a/lib/time/zoneinfo.zip and b/lib/time/zoneinfo.zip differ
diff --git a/src/archive/zip/reader.go b/src/archive/zip/reader.go
index 84a9d41..10e8172 100644
--- a/src/archive/zip/reader.go
+++ b/src/archive/zip/reader.go
@@ -330,7 +330,17 @@ func readDirectoryHeader(f *File, r io.Reader) error {
 		}
 	}
 
-	if needUSize || needCSize || needHeaderOffset {
+	// Assume that uncompressed size 2³²-1 could plausibly happen in
+	// an old zip32 file that was sharding inputs into the largest chunks
+	// possible (or is just malicious; search the web for 42.zip).
+	// If needUSize is true still, it means we didn't see a zip64 extension.
+	// As long as the compressed size is not also 2³²-1 (implausible)
+	// and the header is not also 2³²-1 (equally implausible),
+	// accept the uncompressed size 2³²-1 as valid.
+	// If nothing else, this keeps archive/zip working with 42.zip.
+	_ = needUSize
+
+	if needCSize || needHeaderOffset {
 		return ErrFormat
 	}
 
diff --git a/src/archive/zip/reader_test.go b/src/archive/zip/reader_test.go
index 8f7e8bf..72cf5d9 100644
--- a/src/archive/zip/reader_test.go
+++ b/src/archive/zip/reader_test.go
@@ -27,12 +27,24 @@ type ZipTest struct {
 }
 
 type ZipTestFile struct {
-	Name       string
-	Content    []byte // if blank, will attempt to compare against File
+	Name  string
+	Mode  os.FileMode
+	Mtime string // optional, modified time in format "mm-dd-yy hh:mm:ss"
+
+	// Information describing expected zip file content.
+	// First, reading the entire content should produce the error ContentErr.
+	// Second, if ContentErr==nil, the content should match Content.
+	// If content is large, an alternative to setting Content is to set File,
+	// which names a file in the testdata/ directory containing the
+	// uncompressed expected content.
+	// If content is very large, an alternative to setting Content or File
+	// is to set Size, which will then be checked against the header-reported size
+	// but will bypass the decompressing of the actual data.
+	// This last option is used for testing very large (multi-GB) compressed files.
 	ContentErr error
-	File       string // name of file to compare to (relative to testdata/)
-	Mtime      string // modified time in format "mm-dd-yy hh:mm:ss"
-	Mode       os.FileMode
+	Content    []byte
+	File       string
+	Size       uint64
 }
 
 // Caution: The Mtime values found for the test files should correspond to
@@ -248,6 +260,19 @@ var tests = []ZipTest{
 			},
 		},
 	},
+	// Largest possible non-zip64 file, with no zip64 header.
+	{
+		Name:   "big.zip",
+		Source: returnBigZipBytes,
+		File: []ZipTestFile{
+			{
+				Name:    "big.file",
+				Content: nil,
+				Size:    1<<32 - 1,
+				Mode:    0666,
+			},
+		},
+	},
 }
 
 var crossPlatform = []ZipTestFile{
@@ -356,13 +381,31 @@ func readTestFile(t *testing.T, zt ZipTest, ft ZipTestFile, f *File) {
 
 	testFileMode(t, zt.Name, f, ft.Mode)
 
-	var b bytes.Buffer
+	size := uint64(f.UncompressedSize)
+	if size == uint32max {
+		size = f.UncompressedSize64
+	} else if size != f.UncompressedSize64 {
+		t.Errorf("%v: UncompressedSize=%#x does not match UncompressedSize64=%#x", f.Name, size, f.UncompressedSize64)
+	}
+
 	r, err := f.Open()
 	if err != nil {
 		t.Errorf("%s: %v", zt.Name, err)
 		return
 	}
 
+	// For very large files, just check that the size is correct.
+	// The content is expected to be all zeros.
+	// Don't bother uncompressing: too big.
+	if ft.Content == nil && ft.File == "" && ft.Size > 0 {
+		if size != ft.Size {
+			t.Errorf("%v: uncompressed size %#x, want %#x", size, ft.Size)
+		}
+		r.Close()
+		return
+	}
+
+	var b bytes.Buffer
 	_, err = io.Copy(&b, r)
 	if err != ft.ContentErr {
 		t.Errorf("%s: copying contents: %v (want %v)", zt.Name, err, ft.ContentErr)
@@ -372,10 +415,6 @@ func readTestFile(t *testing.T, zt ZipTest, ft ZipTestFile, f *File) {
 	}
 	r.Close()
 
-	size := uint64(f.UncompressedSize)
-	if size == uint32max {
-		size = f.UncompressedSize64
-	}
 	if g := uint64(b.Len()); g != size {
 		t.Errorf("%v: read %v bytes but f.UncompressedSize == %v", f.Name, g, size)
 	}
@@ -510,6 +549,182 @@ func returnRecursiveZip() (r io.ReaderAt, size int64) {
 	return bytes.NewReader(b), int64(len(b))
 }
 
+// biggestZipBytes returns the bytes of a zip file biggest.zip
+// that contains a zip file bigger.zip that contains a zip file
+// big.zip that contains big.file, which contains 2³²-1 zeros.
+// The big.zip file is interesting because it has no zip64 header,
+// much like the innermost zip files in the well-known 42.zip.
+//
+// biggest.zip was generated by changing isZip64 to use > uint32max
+// instead of >= uint32max and then running this program:
+//
+//	package main
+//
+//	import (
+//		"archive/zip"
+//		"bytes"
+//		"io"
+//		"io/ioutil"
+//		"log"
+//	)
+//
+//	type zeros struct{}
+//
+//	func (zeros) Read(b []byte) (int, error) {
+//		for i := range b {
+//			b[i] = 0
+//		}
+//		return len(b), nil
+//	}
+//
+//	func main() {
+//		bigZip := makeZip("big.file", io.LimitReader(zeros{}, 1<<32-1))
+//		if err := ioutil.WriteFile("/tmp/big.zip", bigZip, 0666); err != nil {
+//			log.Fatal(err)
+//		}
+//
+//		biggerZip := makeZip("big.zip", bytes.NewReader(bigZip))
+//		if err := ioutil.WriteFile("/tmp/bigger.zip", biggerZip, 0666); err != nil {
+//			log.Fatal(err)
+//		}
+//
+//		biggestZip := makeZip("bigger.zip", bytes.NewReader(biggerZip))
+//		if err := ioutil.WriteFile("/tmp/biggest.zip", biggestZip, 0666); err != nil {
+//			log.Fatal(err)
+//		}
+//	}
+//
+//	func makeZip(name string, r io.Reader) []byte {
+//		var buf bytes.Buffer
+//		w := zip.NewWriter(&buf)
+//		wf, err := w.Create(name)
+//		if err != nil {
+//			log.Fatal(err)
+//		}
+//		if _, err = io.Copy(wf, r); err != nil {
+//			log.Fatal(err)
+//		}
+//		if err := w.Close(); err != nil {
+//			log.Fatal(err)
+//		}
+//		return buf.Bytes()
+//	}
+//
+// The 4 GB of zeros compresses to 4 MB, which compresses to 20 kB,
+// which compresses to 1252 bytes (in the hex dump below).
+//
+// It's here in hex for the same reason as rZipBytes above: to avoid
+// problems with on-disk virus scanners or other zip processors.
+//
+func biggestZipBytes() []byte {
+	s := `
+0000000 50 4b 03 04 14 00 08 00 08 00 00 00 00 00 00 00
+0000010 00 00 00 00 00 00 00 00 00 00 0a 00 00 00 62 69
+0000020 67 67 65 72 2e 7a 69 70 ec dc 6b 4c 53 67 18 07
+0000030 f0 16 c5 ca 65 2e cb b8 94 20 61 1f 44 33 c7 cd
+0000040 c0 86 4a b5 c0 62 8a 61 05 c6 cd 91 b2 54 8c 1b
+0000050 63 8b 03 9c 1b 95 52 5a e3 a0 19 6c b2 05 59 44
+0000060 64 9d 73 83 71 11 46 61 14 b9 1d 14 09 4a c3 60
+0000070 2e 4c 6e a5 60 45 02 62 81 95 b6 94 9e 9e 77 e7
+0000080 d0 43 b6 f8 71 df 96 3c e7 a4 69 ce bf cf e9 79
+0000090 ce ef 79 3f bf f1 31 db b6 bb 31 76 92 e7 f3 07
+00000a0 8b fc 9c ca cc 08 cc cb cc 5e d2 1c 88 d9 7e bb
+00000b0 4f bb 3a 3f 75 f1 5d 7f 8f c2 68 67 77 8f 25 ff
+00000c0 84 e2 93 2d ef a4 95 3d 71 4e 2c b9 b0 87 c3 be
+00000d0 3d f8 a7 60 24 61 c5 ef ae 9e c8 6c 6d 4e 69 c8
+00000e0 67 65 34 f8 37 76 2d 76 5c 54 f3 95 65 49 c7 0f
+00000f0 18 71 4b 7e 5b 6a d1 79 47 61 41 b0 4e 2a 74 45
+0000100 43 58 12 b2 5a a5 c6 7d 68 55 88 d4 98 75 18 6d
+0000110 08 d1 1f 8f 5a 9e 96 ee 45 cf a4 84 4e 4b e8 50
+0000120 a7 13 d9 06 de 52 81 97 36 b2 d7 b8 fc 2b 5f 55
+0000130 23 1f 32 59 cf 30 27 fb e2 8a b9 de 45 dd 63 9c
+0000140 4b b5 8b 96 4c 7a 62 62 cc a1 a7 cf fa f1 fe dd
+0000150 54 62 11 bf 36 78 b3 c7 b1 b5 f2 61 4d 4e dd 66
+0000160 32 2e e6 70 34 5f f4 c9 e6 6c 43 6f da 6b c6 c3
+0000170 09 2c ce 09 57 7f d2 7e b4 23 ba 7c 1b 99 bc 22
+0000180 3e f1 de 91 2f e3 9c 1b 82 cc c2 84 39 aa e6 de
+0000190 b4 69 fc cc cb 72 a6 61 45 f0 d3 1d 26 19 7c 8d
+00001a0 29 c8 66 02 be 77 6a f9 3d 34 79 17 19 c8 96 24
+00001b0 a3 ac e4 dd 3b 1a 8e c6 fe 96 38 6b bf 67 5a 23
+00001c0 f4 16 f4 e6 8a b4 fc c2 cd bf 95 66 1d bb 35 aa
+00001d0 92 7d 66 d8 08 8d a5 1f 54 2a af 09 cf 61 ff d2
+00001e0 85 9d 8f b6 d7 88 07 4a 86 03 db 64 f3 d9 92 73
+00001f0 df ec a7 fc 23 4c 8d 83 79 63 2a d9 fd 8d b3 c8
+0000200 8f 7e d4 19 85 e6 8d 1c 76 f0 8b 58 32 fd 9a d6
+0000210 85 e2 48 ad c3 d5 60 6f 7e 22 dd ef 09 49 7c 7f
+0000220 3a 45 c3 71 b7 df f3 4c 63 fb b5 d9 31 5f 6e d6
+0000230 24 1d a4 4a fe 32 a7 5c 16 48 5c 3e 08 6b 8a d3
+0000240 25 1d a2 12 a5 59 24 ea 20 5f 52 6d ad 94 db 6b
+0000250 94 b9 5d eb 4b a7 5c 44 bb 1e f2 3c 6b cf 52 c9
+0000260 e9 e5 ba 06 b9 c4 e5 0a d0 00 0d d0 00 0d d0 00
+0000270 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d
+0000280 d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0
+0000290 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00
+00002a0 0d d0 00 cd ff 9e 46 86 fa a7 7d 3a 43 d7 8e 10
+00002b0 52 e9 be e6 6e cf eb 9e 85 4d 65 ce cc 30 c1 44
+00002c0 c0 4e af bc 9c 6c 4b a0 d7 54 ff 1d d5 5c 89 fb
+00002d0 b5 34 7e c4 c2 9e f5 a0 f6 5b 7e 6e ca 73 c7 ef
+00002e0 5d be de f9 e8 81 eb a5 0a a5 63 54 2c d7 1c d1
+00002f0 89 17 85 f8 16 94 f2 8a b2 a3 f5 b6 6d df 75 cd
+0000300 90 dd 64 bd 5d 55 4e f2 55 19 1b b7 cc ef 1b ea
+0000310 2e 05 9c f4 aa 1e a8 cd a6 82 c7 59 0f 5e 9d e0
+0000320 bb fc 6c d6 99 23 eb 36 ad c6 c5 e1 d8 e1 e2 3e
+0000330 d9 90 5a f7 91 5d 6f bc 33 6d 98 47 d2 7c 2e 2f
+0000340 99 a4 25 72 85 49 2c be 0b 5b af 8f e5 6e 81 a6
+0000350 a3 5a 6f 39 53 3a ab 7a 8b 1e 26 f7 46 6c 7d 26
+0000360 53 b3 22 31 94 d3 83 f2 18 4d f5 92 33 27 53 97
+0000370 0f d3 e6 55 9c a6 c5 31 87 6f d3 f3 ae 39 6f 56
+0000380 10 7b ab 7e d0 b4 ca f2 b8 05 be 3f 0e 6e 5a 75
+0000390 ab 0c f5 37 0e ba 8e 75 71 7a aa ed 7a dd 6a 63
+00003a0 be 9b a0 97 27 6a 6f e7 d3 8b c4 7c ec d3 91 56
+00003b0 d9 ac 5e bf 16 42 2f 00 1f 93 a2 23 87 bd e2 59
+00003c0 a0 de 1a 66 c8 62 eb 55 8f 91 17 b4 61 42 7a 50
+00003d0 40 03 34 40 03 34 40 03 34 40 03 34 40 03 34 40
+00003e0 03 34 40 03 34 40 03 34 40 03 34 40 03 34 40 03
+00003f0 34 40 03 34 40 03 34 ff 85 86 90 8b ea 67 90 0d
+0000400 e1 42 1b d2 61 d6 79 ec fd 3e 44 28 a4 51 6c 5c
+0000410 fc d2 72 ca ba 82 18 46 16 61 cd 93 a9 0f d1 24
+0000420 17 99 e2 2c 71 16 84 0c c8 7a 13 0f 9a 5e c5 f0
+0000430 79 64 e2 12 4d c8 82 a1 81 19 2d aa 44 6d 87 54
+0000440 84 71 c1 f6 d4 ca 25 8c 77 b9 08 c7 c8 5e 10 8a
+0000450 8f 61 ed 8c ba 30 1f 79 9a c7 60 34 2b b9 8c f8
+0000460 18 a6 83 1b e3 9f ad 79 fe fd 1b 8b f1 fc 41 6f
+0000470 d4 13 1f e3 b8 83 ba 64 92 e7 eb e4 77 05 8f ba
+0000480 fa 3b 00 00 ff ff 50 4b 07 08 a6 18 b1 91 5e 04
+0000490 00 00 e4 47 00 00 50 4b 01 02 14 00 14 00 08 00
+00004a0 08 00 00 00 00 00 a6 18 b1 91 5e 04 00 00 e4 47
+00004b0 00 00 0a 00 00 00 00 00 00 00 00 00 00 00 00 00
+00004c0 00 00 00 00 62 69 67 67 65 72 2e 7a 69 70 50 4b
+00004d0 05 06 00 00 00 00 01 00 01 00 38 00 00 00 96 04
+00004e0 00 00 00 00`
+	s = regexp.MustCompile(`[0-9a-f]{7}`).ReplaceAllString(s, "")
+	s = regexp.MustCompile(`\s+`).ReplaceAllString(s, "")
+	b, err := hex.DecodeString(s)
+	if err != nil {
+		panic(err)
+	}
+	return b
+}
+
+func returnBigZipBytes() (r io.ReaderAt, size int64) {
+	b := biggestZipBytes()
+	for i := 0; i < 2; i++ {
+		r, err := NewReader(bytes.NewReader(b), int64(len(b)))
+		if err != nil {
+			panic(err)
+		}
+		f, err := r.File[0].Open()
+		if err != nil {
+			panic(err)
+		}
+		b, err = ioutil.ReadAll(f)
+		if err != nil {
+			panic(err)
+		}
+	}
+	return bytes.NewReader(b), int64(len(b))
+}
+
 func TestIssue8186(t *testing.T) {
 	// Directory headers & data found in the TOC of a JAR file.
 	dirEnts := []string{
diff --git a/src/cmd/compile/internal/gc/parser.go b/src/cmd/compile/internal/gc/parser.go
index 282e855..054cf73 100644
--- a/src/cmd/compile/internal/gc/parser.go
+++ b/src/cmd/compile/internal/gc/parser.go
@@ -2501,6 +2501,24 @@ func (p *parser) interfacedcl() *Node {
 		ifacedcl(meth)
 		return meth
 
+	case '@', '?':
+		// newname indcl
+		// We arrive here when parsing an interface type declared inside
+		// an exported and inlineable function and the interface declares
+		// unexported methods (which are then package-qualified).
+		//
+		// Since the compiler always flattens embedded interfaces, we
+		// will never see an embedded package-qualified interface in export
+		// data; i.e., when we reach here we know it must be a method.
+		//
+		// See also issue 14164.
+		mname := newname(p.sym())
+		sig := p.indcl()
+
+		meth := Nod(ODCLFIELD, mname, sig)
+		ifacedcl(meth)
+		return meth
+
 	case '(':
 		p.next()
 		pname := p.packname(nil)
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index 5db4bc6..c81bd40 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -93,7 +93,8 @@ and test commands:
 		Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
 	-msan
 		enable interoperation with memory sanitizer.
-		Supported only on linux/amd64.
+		Supported only on linux/amd64,
+		and only with Clang/LLVM as the host C compiler.
 	-v
 		print the names of packages as they are compiled.
 	-work
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
index 1286700..a1f925e 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -72,7 +72,8 @@ and test commands:
 		Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
 	-msan
 		enable interoperation with memory sanitizer.
-		Supported only on linux/amd64.
+		Supported only on linux/amd64,
+		and only with Clang/LLVM as the host C compiler.
 	-v
 		print the names of packages as they are compiled.
 	-work
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index a901ca8..6d12f75 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -657,6 +657,9 @@ func TestGoBuildDashAInDevBranch(t *testing.T) {
 	tg.setenv("TESTGO_IS_GO_RELEASE", "0")
 	tg.run("build", "-v", "-a", "math")
 	tg.grepStderr("runtime", "testgo build -a math in dev branch DID NOT build runtime, but should have")
+
+	// Everything is out of date. Rebuild to leave things in a better state.
+	tg.run("install", "std")
 }
 
 func TestGoBuildDashAInReleaseBranch(t *testing.T) {
@@ -672,11 +675,80 @@ func TestGoBuildDashAInReleaseBranch(t *testing.T) {
 	tg.grepStderr("runtime", "testgo build -a math in release branch DID NOT build runtime, but should have")
 
 	// Now runtime.a is updated (newer mtime), so everything would look stale if not for being a release.
-	//
 	tg.run("build", "-v", "net/http")
 	tg.grepStderrNot("strconv", "testgo build -v net/http in release branch with newer runtime.a DID build strconv but should not have")
 	tg.grepStderrNot("golang.org/x/net/http2/hpack", "testgo build -v net/http in release branch with newer runtime.a DID build .../golang.org/x/net/http2/hpack but should not have")
 	tg.grepStderrNot("net/http", "testgo build -v net/http in release branch with newer runtime.a DID build net/http but should not have")
+
+	// Everything is out of date. Rebuild to leave things in a better state.
+	tg.run("install", "std")
+}
+
+func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) {
+	if testing.Short() {
+		t.Skip("don't rebuild the standard library in short mode")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+
+	addNL := func(name string) (restore func()) {
+		data, err := ioutil.ReadFile(name)
+		if err != nil {
+			t.Fatal(err)
+		}
+		old := data
+		data = append(data, '\n')
+		if err := ioutil.WriteFile(name, append(data, '\n'), 0666); err != nil {
+			t.Fatal(err)
+		}
+		tg.sleep()
+		return func() {
+			if err := ioutil.WriteFile(name, old, 0666); err != nil {
+				t.Fatal(err)
+			}
+		}
+	}
+
+	tg.setenv("TESTGO_IS_GO_RELEASE", "1")
+
+	tg.tempFile("d1/src/p1/p1.go", `package p1`)
+	tg.setenv("GOPATH", tg.path("d1"))
+	tg.run("install", "-a", "p1")
+	tg.wantNotStale("p1", "./testgo list claims p1 is stale, incorrectly")
+	tg.sleep()
+
+	// Changing mtime and content of runtime/internal/sys/sys.go
+	// should have no effect: we're in a release, which doesn't rebuild
+	// for general mtime or content changes.
+	sys := runtime.GOROOT() + "/src/runtime/internal/sys/sys.go"
+	restore := addNL(sys)
+	defer restore()
+	tg.wantNotStale("p1", "./testgo list claims p1 is stale, incorrectly, after updating runtime/internal/sys/sys.go")
+	restore()
+	tg.wantNotStale("p1", "./testgo list claims p1 is stale, incorrectly, after restoring runtime/internal/sys/sys.go")
+
+	// But changing runtime/internal/sys/zversion.go should have an effect:
+	// that's how we tell when we flip from one release to another.
+	zversion := runtime.GOROOT() + "/src/runtime/internal/sys/zversion.go"
+	restore = addNL(zversion)
+	defer restore()
+	tg.wantStale("p1", "./testgo list claims p1 is NOT stale, incorrectly, after changing to new release")
+	restore()
+	tg.wantNotStale("p1", "./testgo list claims p1 is stale, incorrectly, after changing back to old release")
+	addNL(zversion)
+	tg.wantStale("p1", "./testgo list claims p1 is NOT stale, incorrectly, after changing again to new release")
+	tg.run("install", "p1")
+	tg.wantNotStale("p1", "./testgo list claims p1 is stale after building with new release")
+
+	// Restore to "old" release.
+	restore()
+	tg.wantStale("p1", "./testgo list claims p1 is NOT stale, incorrectly, after changing to old release after new build")
+	tg.run("install", "p1")
+	tg.wantNotStale("p1", "./testgo list claims p1 is stale after building with old release")
+
+	// Everything is out of date. Rebuild to leave things in a better state.
+	tg.run("install", "std")
 }
 
 func TestGoListStandard(t *testing.T) {
@@ -756,8 +828,8 @@ func TestGoInstallRebuildsStalePackagesInOtherGOPATH(t *testing.T) {
 	sep := string(filepath.ListSeparator)
 	tg.setenv("GOPATH", tg.path("d1")+sep+tg.path("d2"))
 	tg.run("install", "p1")
-	tg.wantNotStale("p1", "./testgo list mypkg claims p1 is stale, incorrectly")
-	tg.wantNotStale("p2", "./testgo list mypkg claims p2 is stale, incorrectly")
+	tg.wantNotStale("p1", "./testgo list claims p1 is stale, incorrectly")
+	tg.wantNotStale("p2", "./testgo list claims p2 is stale, incorrectly")
 	tg.sleep()
 	if f, err := os.OpenFile(tg.path("d2/src/p2/p2.go"), os.O_WRONLY|os.O_APPEND, 0); err != nil {
 		t.Fatal(err)
@@ -766,12 +838,12 @@ func TestGoInstallRebuildsStalePackagesInOtherGOPATH(t *testing.T) {
 	} else {
 		tg.must(f.Close())
 	}
-	tg.wantStale("p2", "./testgo list mypkg claims p2 is NOT stale, incorrectly")
-	tg.wantStale("p1", "./testgo list mypkg claims p1 is NOT stale, incorrectly")
+	tg.wantStale("p2", "./testgo list claims p2 is NOT stale, incorrectly")
+	tg.wantStale("p1", "./testgo list claims p1 is NOT stale, incorrectly")
 
 	tg.run("install", "p1")
-	tg.wantNotStale("p2", "./testgo list mypkg claims p2 is stale after reinstall, incorrectly")
-	tg.wantNotStale("p1", "./testgo list mypkg claims p1 is stale after reinstall, incorrectly")
+	tg.wantNotStale("p2", "./testgo list claims p2 is stale after reinstall, incorrectly")
+	tg.wantNotStale("p1", "./testgo list claims p1 is stale after reinstall, incorrectly")
 }
 
 func TestGoInstallDetectsRemovedFiles(t *testing.T) {
@@ -1621,7 +1693,7 @@ func TestGoTestDashOWritesBinary(t *testing.T) {
 }
 
 // Issue 4568.
-func TestSymlinksDoNotConfuseGoList(t *testing.T) {
+func TestSymlinksList(t *testing.T) {
 	switch runtime.GOOS {
 	case "plan9", "windows":
 		t.Skipf("skipping symlink test on %s", runtime.GOOS)
@@ -1640,6 +1712,58 @@ func TestSymlinksDoNotConfuseGoList(t *testing.T) {
 	}
 }
 
+// Issue 14054.
+func TestSymlinksVendor(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9", "windows":
+		t.Skipf("skipping symlink test on %s", runtime.GOOS)
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GO15VENDOREXPERIMENT", "1")
+	tg.tempDir("gopath/src/dir1/vendor/v")
+	tg.tempFile("gopath/src/dir1/p.go", "package main\nimport _ `v`\nfunc main(){}")
+	tg.tempFile("gopath/src/dir1/vendor/v/v.go", "package v")
+	tg.must(os.Symlink(tg.path("gopath/src/dir1"), tg.path("symdir1")))
+	tg.setenv("GOPATH", tg.path("gopath"))
+	tg.cd(tg.path("symdir1"))
+	tg.run("list", "-f", "{{.Root}}", ".")
+	if strings.TrimSpace(tg.getStdout()) != tg.path("gopath") {
+		t.Error("list confused by symlinks")
+	}
+
+	// All of these should succeed, not die in vendor-handling code.
+	tg.run("run", "p.go")
+	tg.run("build")
+	tg.run("install")
+}
+
+func TestSymlinksInternal(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9", "windows":
+		t.Skipf("skipping symlink test on %s", runtime.GOOS)
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.tempDir("gopath/src/dir1/internal/v")
+	tg.tempFile("gopath/src/dir1/p.go", "package main\nimport _ `dir1/internal/v`\nfunc main(){}")
+	tg.tempFile("gopath/src/dir1/internal/v/v.go", "package v")
+	tg.must(os.Symlink(tg.path("gopath/src/dir1"), tg.path("symdir1")))
+	tg.setenv("GOPATH", tg.path("gopath"))
+	tg.cd(tg.path("symdir1"))
+	tg.run("list", "-f", "{{.Root}}", ".")
+	if strings.TrimSpace(tg.getStdout()) != tg.path("gopath") {
+		t.Error("list confused by symlinks")
+	}
+
+	// All of these should succeed, not die in internal-handling code.
+	tg.run("run", "p.go")
+	tg.run("build")
+	tg.run("install")
+}
+
 // Issue 4515.
 func TestInstallWithTags(t *testing.T) {
 	tg := testgo(t)
diff --git a/src/cmd/go/main.go b/src/cmd/go/main.go
index c8697ff..d384594 100644
--- a/src/cmd/go/main.go
+++ b/src/cmd/go/main.go
@@ -524,6 +524,15 @@ func hasFilePathPrefix(s, prefix string) bool {
 	}
 }
 
+// expandPath returns the symlink-expanded form of path.
+func expandPath(p string) string {
+	x, err := filepath.EvalSymlinks(p)
+	if err == nil {
+		return x
+	}
+	return p
+}
+
 // treeCanMatchPattern(pattern)(name) reports whether
 // name or children of name can possibly match pattern.
 // Pattern is the same limited glob accepted by matchPattern.
diff --git a/src/cmd/go/pkg.go b/src/cmd/go/pkg.go
index 112f820..a804ccd 100644
--- a/src/cmd/go/pkg.go
+++ b/src/cmd/go/pkg.go
@@ -415,11 +415,18 @@ func vendoredImportPath(parent *Package, path string) (found string) {
 	if parent == nil || parent.Root == "" || !go15VendorExperiment {
 		return path
 	}
+
 	dir := filepath.Clean(parent.Dir)
 	root := filepath.Join(parent.Root, "src")
+	if !hasFilePathPrefix(dir, root) {
+		// Look for symlinks before reporting error.
+		dir = expandPath(dir)
+		root = expandPath(root)
+	}
 	if !hasFilePathPrefix(dir, root) || len(dir) <= len(root) || dir[len(root)] != filepath.Separator {
 		fatalf("invalid vendoredImportPath: dir=%q root=%q separator=%q", dir, root, string(filepath.Separator))
 	}
+
 	vpath := "vendor/" + path
 	for i := len(dir); i >= len(root); i-- {
 		if i < len(dir) && dir[i] != filepath.Separator {
@@ -533,6 +540,13 @@ func disallowInternal(srcDir string, p *Package, stk *importStack) *Package {
 		return p
 	}
 
+	// Look for symlinks before reporting error.
+	srcDir = expandPath(srcDir)
+	parent = expandPath(parent)
+	if hasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
+		return p
+	}
+
 	// Internal is present, and srcDir is outside parent's tree. Not allowed.
 	perr := *p
 	perr.Error = &PackageError{
@@ -630,6 +644,13 @@ func disallowVendorVisibility(srcDir string, p *Package, stk *importStack) *Pack
 		return p
 	}
 
+	// Look for symlinks before reporting error.
+	srcDir = expandPath(srcDir)
+	parent = expandPath(parent)
+	if hasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
+		return p
+	}
+
 	// Vendor is present, and srcDir is outside parent's tree. Not allowed.
 	perr := *p
 	perr.Error = &PackageError{
@@ -1521,11 +1542,14 @@ func computeBuildID(p *Package) {
 		fmt.Fprintf(h, "file %s\n", file)
 	}
 
-	// Include the content of runtime/zversion.go in the hash
+	// Include the content of runtime/internal/sys/zversion.go in the hash
 	// for package runtime. This will give package runtime a
 	// different build ID in each Go release.
-	if p.Standard && p.ImportPath == "runtime" {
-		data, _ := ioutil.ReadFile(filepath.Join(p.Dir, "zversion.go"))
+	if p.Standard && p.ImportPath == "runtime/internal/sys" {
+		data, err := ioutil.ReadFile(filepath.Join(p.Dir, "zversion.go"))
+		if err != nil {
+			fatalf("go: %s", err)
+		}
 		fmt.Fprintf(h, "zversion %q\n", string(data))
 	}
 
diff --git a/src/cmd/go/vcs.go b/src/cmd/go/vcs.go
index 074dd8b..342edee 100644
--- a/src/cmd/go/vcs.go
+++ b/src/cmd/go/vcs.go
@@ -122,7 +122,7 @@ var vcsGit = &vcsCmd{
 	name: "Git",
 	cmd:  "git",
 
-	createCmd:   []string{"clone {repo} {dir}", "-C {dir} submodule update --init --recursive"},
+	createCmd:   []string{"clone {repo} {dir}", "-go-internal-cd {dir} submodule update --init --recursive"},
 	downloadCmd: []string{"pull --ff-only", "submodule update --init --recursive"},
 
 	tagCmd: []tagCmd{
@@ -335,6 +335,15 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool)
 		args[i] = expand(m, arg)
 	}
 
+	if len(args) >= 2 && args[0] == "-go-internal-cd" {
+		if filepath.IsAbs(args[1]) {
+			dir = args[1]
+		} else {
+			dir = filepath.Join(dir, args[1])
+		}
+		args = args[2:]
+	}
+
 	_, err := exec.LookPath(v.cmd)
 	if err != nil {
 		fmt.Fprintf(os.Stderr,
diff --git a/src/cmd/vet/cgo.go b/src/cmd/vet/cgo.go
index 8807952..1985a86 100644
--- a/src/cmd/vet/cgo.go
+++ b/src/cmd/vet/cgo.go
@@ -72,6 +72,9 @@ func cgoBaseType(f *File, arg ast.Expr) types.Type {
 		}
 		// Here arg is *f(v).
 		t := f.pkg.types[call.Fun].Type
+		if t == nil {
+			break
+		}
 		ptr, ok := t.Underlying().(*types.Pointer)
 		if !ok {
 			break
diff --git a/src/cmd/vet/print.go b/src/cmd/vet/print.go
index 5436c5b..a16e864 100644
--- a/src/cmd/vet/print.go
+++ b/src/cmd/vet/print.go
@@ -445,12 +445,12 @@ func (f *File) okPrintfArg(call *ast.CallExpr, state *formatState) (ok bool) {
 		return false
 	}
 	arg := call.Args[argNum]
+	if f.isFunctionValue(arg) && state.verb != 'p' && state.verb != 'T' {
+		f.Badf(call.Pos(), "arg %s in printf call is a function value, not a function call", f.gofmt(arg))
+		return false
+	}
 	if !f.matchArgType(v.typ, nil, arg) {
 		typeString := ""
-		if f.isFunctionValue(arg) {
-			f.Badf(call.Pos(), "arg %s in printf call is a function value, not a function call", f.gofmt(arg))
-			return false
-		}
 		if typ := f.pkg.types[arg].Type; typ != nil {
 			typeString = typ.String()
 		}
diff --git a/src/cmd/vet/testdata/cgo2.go b/src/cmd/vet/testdata/cgo2.go
new file mode 100644
index 0000000..276aea9
--- /dev/null
+++ b/src/cmd/vet/testdata/cgo2.go
@@ -0,0 +1,9 @@
+// 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.
+
+// Test the cgo checker on a file that doesn't use cgo.
+
+package testdata
+
+var _ = C.f(*p(**p))
diff --git a/src/cmd/vet/testdata/print.go b/src/cmd/vet/testdata/print.go
index beeb642..c5faa36 100644
--- a/src/cmd/vet/testdata/print.go
+++ b/src/cmd/vet/testdata/print.go
@@ -197,7 +197,10 @@ func PrintfTests() {
 	et5.error() // ok, not an error method.
 	// Can't print a function.
 	Printf("%d", someFunction) // ERROR "arg someFunction in printf call is a function value, not a function call"
+	Printf("%v", someFunction) // ERROR "arg someFunction in printf call is a function value, not a function call"
 	Println(someFunction)      // ERROR "arg someFunction in Println call is a function value, not a function call"
+	Printf("%p", someFunction) // ok: maybe someone wants to see the pointer
+	Printf("%T", someFunction) // ok: maybe someone wants to see the type
 	// Bug: used to recur forever.
 	Printf("%p %x", recursiveStructV, recursiveStructV.next)
 	Printf("%p %x", recursiveStruct1V, recursiveStruct1V.next)
diff --git a/src/net/http/clientserver_test.go b/src/net/http/clientserver_test.go
index 9b581e7..fbaa805 100644
--- a/src/net/http/clientserver_test.go
+++ b/src/net/http/clientserver_test.go
@@ -1001,13 +1001,17 @@ func TestTransportDiscardsUnneededConns(t *testing.T) {
 }
 
 // tests that Transport doesn't retain a pointer to the provided request.
-func TestTransportGCRequest_h1(t *testing.T) { testTransportGCRequest(t, h1Mode) }
-func TestTransportGCRequest_h2(t *testing.T) { testTransportGCRequest(t, h2Mode) }
-func testTransportGCRequest(t *testing.T, h2 bool) {
+func TestTransportGCRequest_Body_h1(t *testing.T)   { testTransportGCRequest(t, h1Mode, true) }
+func TestTransportGCRequest_Body_h2(t *testing.T)   { testTransportGCRequest(t, h2Mode, true) }
+func TestTransportGCRequest_NoBody_h1(t *testing.T) { testTransportGCRequest(t, h1Mode, false) }
+func TestTransportGCRequest_NoBody_h2(t *testing.T) { testTransportGCRequest(t, h2Mode, false) }
+func testTransportGCRequest(t *testing.T, h2, body bool) {
 	defer afterTest(t)
 	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
 		ioutil.ReadAll(r.Body)
-		io.WriteString(w, "Hello.")
+		if body {
+			io.WriteString(w, "Hello.")
+		}
 	}))
 	defer cst.close()
 
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
index e723629..11f33cf 100644
--- a/src/net/http/h2_bundle.go
+++ b/src/net/http/h2_bundle.go
@@ -2851,8 +2851,6 @@ func (sc *http2serverConn) logf(format string, args ...interface{}) {
 	}
 }
 
-var http2uintptrType = reflect.TypeOf(uintptr(0))
-
 // errno returns v's underlying uintptr, else 0.
 //
 // TODO: remove this helper function once http2 can use build
@@ -4220,7 +4218,9 @@ func (rws *http2responseWriterState) declareTrailer(k string) {
 
 		return
 	}
-	rws.trailers = append(rws.trailers, k)
+	if !http2strSliceContains(rws.trailers, k) {
+		rws.trailers = append(rws.trailers, k)
+	}
 }
 
 // writeChunk writes chunks from the bufio.Writer. But because
@@ -4288,6 +4288,10 @@ func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) {
 		return 0, nil
 	}
 
+	if rws.handlerDone {
+		rws.promoteUndeclaredTrailers()
+	}
+
 	endStream := rws.handlerDone && !rws.hasTrailers()
 	if len(p) > 0 || endStream {
 
@@ -4308,6 +4312,53 @@ func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) {
 	return len(p), nil
 }
 
+// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys
+// that, if present, signals that the map entry is actually for
+// the response trailers, and not the response headers. The prefix
+// is stripped after the ServeHTTP call finishes and the values are
+// sent in the trailers.
+//
+// This mechanism is intended only for trailers that are not known
+// prior to the headers being written. If the set of trailers is fixed
+// or known before the header is written, the normal Go trailers mechanism
+// is preferred:
+//    https://golang.org/pkg/net/http/#ResponseWriter
+//    https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
+const http2TrailerPrefix = "Trailer:"
+
+// promoteUndeclaredTrailers permits http.Handlers to set trailers
+// after the header has already been flushed. Because the Go
+// ResponseWriter interface has no way to set Trailers (only the
+// Header), and because we didn't want to expand the ResponseWriter
+// interface, and because nobody used trailers, and because RFC 2616
+// says you SHOULD (but not must) predeclare any trailers in the
+// header, the official ResponseWriter rules said trailers in Go must
+// be predeclared, and then we reuse the same ResponseWriter.Header()
+// map to mean both Headers and Trailers.  When it's time to write the
+// Trailers, we pick out the fields of Headers that were declared as
+// trailers. That worked for a while, until we found the first major
+// user of Trailers in the wild: gRPC (using them only over http2),
+// and gRPC libraries permit setting trailers mid-stream without
+// predeclarnig them. So: change of plans. We still permit the old
+// way, but we also permit this hack: if a Header() key begins with
+// "Trailer:", the suffix of that key is a Trailer. Because ':' is an
+// invalid token byte anyway, there is no ambiguity. (And it's already
+// filtered out) It's mildly hacky, but not terrible.
+//
+// This method runs after the Handler is done and promotes any Header
+// fields to be trailers.
+func (rws *http2responseWriterState) promoteUndeclaredTrailers() {
+	for k, vv := range rws.handlerHeader {
+		if !strings.HasPrefix(k, http2TrailerPrefix) {
+			continue
+		}
+		trailerKey := strings.TrimPrefix(k, http2TrailerPrefix)
+		rws.declareTrailer(trailerKey)
+		rws.handlerHeader[CanonicalHeaderKey(trailerKey)] = vv
+	}
+	sort.Strings(rws.trailers)
+}
+
 func (w *http2responseWriter) Flush() {
 	rws := w.rws
 	if rws == nil {
@@ -5611,10 +5662,10 @@ func (rl *http2clientConnReadLoop) processHeaderBlockFragment(frag []byte, strea
 			res.ContentLength = -1
 			res.Body = &http2gzipReader{body: res.Body}
 		}
+		rl.activeRes[cs.ID] = cs
 	}
 
 	cs.resTrailer = &res.Trailer
-	rl.activeRes[cs.ID] = cs
 	cs.resc <- http2resAndError{res: res}
 	rl.nextRes = nil
 	return nil
@@ -6258,8 +6309,16 @@ func http2encodeHeaders(enc *hpack.Encoder, h Header, keys []string) {
 	for _, k := range keys {
 		vv := h[k]
 		k = http2lowerHeader(k)
+		if !http2validHeaderFieldName(k) {
+
+			continue
+		}
 		isTE := k == "transfer-encoding"
 		for _, v := range vv {
+			if !http2validHeaderFieldValue(v) {
+
+				continue
+			}
 
 			if isTE && v != "trailers" {
 				continue
diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go
index 4dba352..54411ca 100644
--- a/src/net/http/httputil/reverseproxy.go
+++ b/src/net/http/httputil/reverseproxy.go
@@ -106,11 +106,12 @@ func copyHeader(dst, src http.Header) {
 // http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
 var hopHeaders = []string{
 	"Connection",
+	"Proxy-Connection", // non-standard but still sent by libcurl and rejected by e.g. google
 	"Keep-Alive",
 	"Proxy-Authenticate",
 	"Proxy-Authorization",
-	"Te", // canonicalized version of "TE"
-	"Trailers",
+	"Te",      // canonicalized version of "TE"
+	"Trailer", // not Trailers per URL above; http://www.rfc-editor.org/errata_search.php?eid=4522
 	"Transfer-Encoding",
 	"Upgrade",
 }
diff --git a/src/net/http/httputil/reverseproxy_test.go b/src/net/http/httputil/reverseproxy_test.go
index 7f203d8..0849427 100644
--- a/src/net/http/httputil/reverseproxy_test.go
+++ b/src/net/http/httputil/reverseproxy_test.go
@@ -45,9 +45,13 @@ func TestReverseProxy(t *testing.T) {
 		if c := r.Header.Get("Upgrade"); c != "" {
 			t.Errorf("handler got Upgrade header value %q", c)
 		}
+		if c := r.Header.Get("Proxy-Connection"); c != "" {
+			t.Errorf("handler got Proxy-Connection header value %q", c)
+		}
 		if g, e := r.Host, "some-name"; g != e {
 			t.Errorf("backend got Host header %q, want %q", g, e)
 		}
+		w.Header().Set("Trailers", "not a special header field name")
 		w.Header().Set("Trailer", "X-Trailer")
 		w.Header().Set("X-Foo", "bar")
 		w.Header().Set("Upgrade", "foo")
@@ -71,6 +75,7 @@ func TestReverseProxy(t *testing.T) {
 	getReq, _ := http.NewRequest("GET", frontend.URL, nil)
 	getReq.Host = "some-name"
 	getReq.Header.Set("Connection", "close")
+	getReq.Header.Set("Proxy-Connection", "should be deleted")
 	getReq.Header.Set("Upgrade", "foo")
 	getReq.Close = true
 	res, err := http.DefaultClient.Do(getReq)
@@ -86,6 +91,9 @@ func TestReverseProxy(t *testing.T) {
 	if c := res.Header.Get(fakeHopHeader); c != "" {
 		t.Errorf("got %s header value %q", fakeHopHeader, c)
 	}
+	if g, e := res.Header.Get("Trailers"), "not a special header field name"; g != e {
+		t.Errorf("header Trailers = %q; want %q", g, e)
+	}
 	if g, e := len(res.Header["X-Multi-Value"]), 2; g != e {
 		t.Errorf("got %d X-Multi-Value header values; expected %d", g, e)
 	}
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index 3b2a5f9..8cb89a4 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -2208,9 +2208,8 @@ func TestTransportTLSHandshakeTimeout(t *testing.T) {
 // Trying to repro golang.org/issue/3514
 func TestTLSServerClosesConnection(t *testing.T) {
 	defer afterTest(t)
-	if runtime.GOOS == "windows" {
-		t.Skip("skipping flaky test on Windows; golang.org/issue/7634")
-	}
+	setFlaky(t, 7634)
+
 	closedc := make(chan bool, 1)
 	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
 		if strings.Contains(r.URL.Path, "/keep-alive-then-die") {
diff --git a/src/net/net_test.go b/src/net/net_test.go
index 6dcfc21..cd62b43 100644
--- a/src/net/net_test.go
+++ b/src/net/net_test.go
@@ -9,6 +9,7 @@ import (
 	"os"
 	"runtime"
 	"testing"
+	"time"
 )
 
 func TestCloseRead(t *testing.T) {
@@ -209,6 +210,7 @@ func TestListenerClose(t *testing.T) {
 			defer os.Remove(ln.Addr().String())
 		}
 
+		dst := ln.Addr().String()
 		if err := ln.Close(); err != nil {
 			if perr := parseCloseError(err); perr != nil {
 				t.Error(perr)
@@ -222,9 +224,24 @@ func TestListenerClose(t *testing.T) {
 		}
 
 		if network == "tcp" {
-			cc, err := Dial("tcp", ln.Addr().String())
+			// We will have two TCP FSMs inside the
+			// kernel here. There's no guarantee that a
+			// signal comes from the far end FSM will be
+			// delivered immediately to the near end FSM,
+			// especially on the platforms that allow
+			// multiple consumer threads to pull pending
+			// established connections at the same time by
+			// enabling SO_REUSEPORT option such as Linux,
+			// DragonFly BSD. So we need to give some time
+			// quantum to the kernel.
+			//
+			// Note that net.inet.tcp.reuseport_ext=1 by
+			// default on DragonFly BSD.
+			time.Sleep(time.Millisecond)
+
+			cc, err := Dial("tcp", dst)
 			if err == nil {
-				t.Error("Dial to closed TCP listener succeeeded.")
+				t.Error("Dial to closed TCP listener succeeded.")
 				cc.Close()
 			}
 		}
@@ -272,6 +289,9 @@ func TestListenCloseListen(t *testing.T) {
 		}
 		addr := ln.Addr().String()
 		if err := ln.Close(); err != nil {
+			if perr := parseCloseError(err); perr != nil {
+				t.Error(perr)
+			}
 			t.Fatal(err)
 		}
 		ln, err = Listen("tcp", addr)
diff --git a/src/os/doc.go b/src/os/doc.go
index 389a8eb..869a28a 100644
--- a/src/os/doc.go
+++ b/src/os/doc.go
@@ -7,9 +7,13 @@ package os
 import "time"
 
 // FindProcess looks for a running process by its pid.
+//
 // The Process it returns can be used to obtain information
 // about the underlying operating system process.
-func FindProcess(pid int) (p *Process, err error) {
+//
+// On Unix systems, FindProcess always succeeds and returns a Process
+// for the given pid, regardless of whether the process exists.
+func FindProcess(pid int) (*Process, error) {
 	return findProcess(pid)
 }
 
diff --git a/src/runtime/cgo_mmap.go b/src/runtime/cgo_mmap.go
index ef5501c..c0396bd 100644
--- a/src/runtime/cgo_mmap.go
+++ b/src/runtime/cgo_mmap.go
@@ -15,12 +15,19 @@ import "unsafe"
 //go:linkname _cgo_mmap _cgo_mmap
 var _cgo_mmap unsafe.Pointer
 
-func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (ret unsafe.Pointer) {
+func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer {
 	if _cgo_mmap != nil {
+		// Make ret a uintptr so that writing to it in the
+		// function literal does not trigger a write barrier.
+		// A write barrier here could break because of the way
+		// that mmap uses the same value both as a pointer and
+		// an errno value.
+		// TODO: Fix mmap to return two values.
+		var ret uintptr
 		systemstack(func() {
 			ret = callCgoMmap(addr, n, prot, flags, fd, off)
 		})
-		return
+		return unsafe.Pointer(ret)
 	}
 	return sysMmap(addr, n, prot, flags, fd, off)
 }
@@ -31,4 +38,4 @@ func sysMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32)
 // cgoMmap calls the mmap function in the runtime/cgo package on the
 // callCgoMmap calls the mmap function in the runtime/cgo package
 // using the GCC calling convention.  It is implemented in assembly.
-func callCgoMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer
+func callCgoMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) uintptr
diff --git a/src/runtime/pprof/pprof_test.go b/src/runtime/pprof/pprof_test.go
index 621d21d..ab6b183 100644
--- a/src/runtime/pprof/pprof_test.go
+++ b/src/runtime/pprof/pprof_test.go
@@ -96,7 +96,7 @@ func parseProfile(t *testing.T, bytes []byte, f func(uintptr, []uintptr)) {
 	if l < 5+3 {
 		t.Logf("profile too short: %#x", val)
 		if badOS[runtime.GOOS] {
-			t.Skipf("ignoring failure on %s; see golang.org/issue/6047", runtime.GOOS)
+			t.Skipf("ignoring failure on %s; see golang.org/issue/13841", runtime.GOOS)
 			return
 		}
 		t.FailNow()
@@ -171,7 +171,7 @@ func testCPUProfile(t *testing.T, need []string, f func(dur time.Duration)) {
 	}
 
 	if badOS[runtime.GOOS] {
-		t.Skipf("ignoring failure on %s; see golang.org/issue/6047", runtime.GOOS)
+		t.Skipf("ignoring failure on %s; see golang.org/issue/13841", runtime.GOOS)
 		return
 	}
 	// Ignore the failure if the tests are running in a QEMU-based emulator,
@@ -420,11 +420,13 @@ func deepStack(depth int) int {
 	return deepStack(depth-1) + 1
 }
 
-// Operating systems that are expected to fail the tests. See issue 6047.
+// Operating systems that are expected to fail the tests. See issue 13841.
 var badOS = map[string]bool{
-	"darwin": true,
-	"netbsd": true,
-	"plan9":  true,
+	"darwin":    true,
+	"netbsd":    true,
+	"plan9":     true,
+	"dragonfly": true,
+	"solaris":   true,
 }
 
 func TestBlockProfile(t *testing.T) {
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index 2bc3c92..d1f5088 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -1602,11 +1602,19 @@ func startm(_p_ *p, spinning bool) {
 // Always runs without a P, so write barriers are not allowed.
 //go:nowritebarrier
 func handoffp(_p_ *p) {
+	// handoffp must start an M in any situation where
+	// findrunnable would return a G to run on _p_.
+
 	// if it has local work, start it straight away
 	if !runqempty(_p_) || sched.runqsize != 0 {
 		startm(_p_, false)
 		return
 	}
+	// if it has GC work, start it straight away
+	if gcBlackenEnabled != 0 && gcMarkWorkAvailable(_p_) {
+		startm(_p_, false)
+		return
+	}
 	// no local work, check that there are no spinning/idle M's,
 	// otherwise our help is not required
 	if atomic.Load(&sched.nmspinning)+atomic.Load(&sched.npidle) == 0 && atomic.Cas(&sched.nmspinning, 0, 1) { // TODO: fast atomic
@@ -1787,6 +1795,10 @@ func execute(gp *g, inheritTime bool) {
 func findrunnable() (gp *g, inheritTime bool) {
 	_g_ := getg()
 
+	// The conditions here and in handoffp must agree: if
+	// findrunnable would return a G to run, handoffp must start
+	// an M.
+
 top:
 	if sched.gcwaiting != 0 {
 		gcstopm()
diff --git a/src/runtime/runtime_test.go b/src/runtime/runtime_test.go
index 581f52b..a6150a7 100644
--- a/src/runtime/runtime_test.go
+++ b/src/runtime/runtime_test.go
@@ -310,13 +310,22 @@ func TestAppendSliceGrowth(t *testing.T) {
 }
 
 func TestGoroutineProfileTrivial(t *testing.T) {
-	n1, ok := GoroutineProfile(nil) // should fail, there's at least 1 goroutine
-	if n1 < 1 || ok {
-		t.Fatalf("GoroutineProfile(nil) = %d, %v, want >0, false", n1, ok)
-	}
-
-	n2, ok := GoroutineProfile(make([]StackRecord, n1))
-	if n2 != n1 || !ok {
-		t.Fatalf("GoroutineProfile(%d) = %d, %v, want %d, true", n1, n2, ok, n1)
+	// Calling GoroutineProfile twice in a row should find the same number of goroutines,
+	// but it's possible there are goroutines just about to exit, so we might end up
+	// with fewer in the second call. Try a few times; it should converge once those
+	// zombies are gone.
+	for i := 0; ; i++ {
+		n1, ok := GoroutineProfile(nil) // should fail, there's at least 1 goroutine
+		if n1 < 1 || ok {
+			t.Fatalf("GoroutineProfile(nil) = %d, %v, want >0, false", n1, ok)
+		}
+		n2, ok := GoroutineProfile(make([]StackRecord, n1))
+		if n2 == n1 && ok {
+			break
+		}
+		t.Logf("GoroutineProfile(%d) = %d, %v, want %d, true", n1, n2, ok, n1)
+		if i >= 10 {
+			t.Fatalf("GoroutineProfile not converging")
+		}
 	}
 }
diff --git a/src/runtime/sys_darwin_386.s b/src/runtime/sys_darwin_386.s
index c516ef2..ad3dca4 100644
--- a/src/runtime/sys_darwin_386.s
+++ b/src/runtime/sys_darwin_386.s
@@ -242,15 +242,21 @@ TEXT runtime·sigaction(SB),NOSPLIT,$0
 	MOVL	$0xf1, 0xf1  // crash
 	RET
 
-TEXT runtime·sigfwd(SB),NOSPLIT,$12-16
-	MOVL	sig+4(FP), AX
-	MOVL	AX, 0(SP)
-	MOVL	info+8(FP), AX
-	MOVL	AX, 4(SP)
-	MOVL	ctx+12(FP), AX
-	MOVL	AX, 8(SP)
+TEXT runtime·sigfwd(SB),NOSPLIT,$0-16
 	MOVL	fn+0(FP), AX
+	MOVL	sig+4(FP), BX
+	MOVL	info+8(FP), CX
+	MOVL	ctx+12(FP), DX
+	MOVL	SP, SI
+	SUBL	$32, SP		// align stack; handler might be C code
+	ANDL	$~15, SP
+	MOVL	BX, 0(SP)
+	MOVL	CX, 4(SP)
+	MOVL	DX, 8(SP)
+	MOVL	SI, 12(SP)
 	CALL	AX
+	MOVL	12(SP), AX
+	MOVL	AX, SP
 	RET
 
 TEXT runtime·sigreturn(SB),NOSPLIT,$12-8
diff --git a/src/sync/waitgroup_test.go b/src/sync/waitgroup_test.go
index a581660..8ec34fd 100644
--- a/src/sync/waitgroup_test.go
+++ b/src/sync/waitgroup_test.go
@@ -128,13 +128,16 @@ func TestWaitGroupMisuse3(t *testing.T) {
 		}
 	}()
 	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
-	done := make(chan interface{}, 1)
+	done := make(chan interface{}, 2)
 	// The detection is opportunistically, so we want it to panic
 	// at least in one run out of a million.
 	for i := 0; i < 1e6; i++ {
 		var wg WaitGroup
 		wg.Add(1)
 		go func() {
+			defer func() {
+				done <- recover()
+			}()
 			wg.Done()
 		}()
 		go func() {
@@ -150,8 +153,10 @@ func TestWaitGroupMisuse3(t *testing.T) {
 			wg.Wait()
 		}()
 		wg.Wait()
-		if err := <-done; err != nil {
-			panic(err)
+		for j := 0; j < 2; j++ {
+			if err := <-done; err != nil {
+				panic(err)
+			}
 		}
 	}
 	t.Fatal("Should panic")
diff --git a/src/unsafe/unsafe.go b/src/unsafe/unsafe.go
index 33b3114..532fa4a 100644
--- a/src/unsafe/unsafe.go
+++ b/src/unsafe/unsafe.go
@@ -63,7 +63,7 @@ type ArbitraryType int
 // (3) Conversion of a Pointer to a uintptr and back, with arithmetic.
 //
 // If p points into an allocated object, it can be advanced through the object
-// by conversion to uintptr, addition of an offset, and conversion back to uintptr.
+// by conversion to uintptr, addition of an offset, and conversion back to Pointer.
 //
 //	p = unsafe.Pointer(uintptr(p) + offset)
 //
diff --git a/test/fixedbugs/issue14164.dir/a.go b/test/fixedbugs/issue14164.dir/a.go
new file mode 100644
index 0000000..bf03051
--- /dev/null
+++ b/test/fixedbugs/issue14164.dir/a.go
@@ -0,0 +1,47 @@
+// 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
+
+// F is an exported function, small enough to be inlined.
+// It defines a local interface with an unexported method
+// f, which will appear with a package-qualified method
+// name in the export data.
+func F(x interface{}) bool {
+	_, ok := x.(interface {
+		f()
+	})
+	return ok
+}
+
+// Like F but with the unexported interface method f
+// defined via an embedded interface t. The compiler
+// always flattens embedded interfaces so there should
+// be no difference between F and G. Alas, currently
+// G is not inlineable (at least via export data), so
+// the issue is moot, here.
+func G(x interface{}) bool {
+	type t0 interface {
+		f()
+	}
+	_, ok := x.(interface {
+		t0
+	})
+	return ok
+}
+
+// Like G but now the embedded interface is declared
+// at package level. This function is inlineable via
+// export data. The export data representation is like
+// for F.
+func H(x interface{}) bool {
+	_, ok := x.(interface {
+		t1
+	})
+	return ok
+}
+
+type t1 interface {
+	f()
+}
diff --git a/test/fixedbugs/issue14164.dir/main.go b/test/fixedbugs/issue14164.dir/main.go
new file mode 100644
index 0000000..bcc6a63
--- /dev/null
+++ b/test/fixedbugs/issue14164.dir/main.go
@@ -0,0 +1,12 @@
+// 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 main
+
+// Verify that we can import package "a" containing an inlineable
+// function F that declares a local interface with a non-exported
+// method f.
+import _ "./a"
+
+func main() {}
diff --git a/test/fixedbugs/issue14164.go b/test/fixedbugs/issue14164.go
new file mode 100644
index 0000000..5247599
--- /dev/null
+++ b/test/fixedbugs/issue14164.go
@@ -0,0 +1,7 @@
+// 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.
+
+ignored

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-golang/golang.git



More information about the pkg-golang-commits mailing list