Commit 9a80b5e1 authored by Russ Cox's avatar Russ Cox

all: merge master into release-branch.go1.6

Change-Id: I10a3abc28028e35c5d92d1bd33ac64fe0825eae7
parents 036b8fd4 f309bf3e
......@@ -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>
&lt;title&gt;{{"{{"}}block "title"}}Page Title{{"{{"}}end}}&lt;/title&gt;
&lt;body&gt;
&lt;h1&gt;{{"{{"}}template "title"}}&lt;/h1&gt;
{{"{{"}}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.
......
......@@ -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)
......
......@@ -1621,7 +1621,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 +1640,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)
......
......@@ -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.
......
......@@ -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{
......
......@@ -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()
}
......
......@@ -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)
......
......@@ -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()
......
......@@ -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
......
......@@ -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)
......
......@@ -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)
}
......
......@@ -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
......@@ -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()
......
......@@ -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
......
......@@ -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)
//
......
// 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()
}
// 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() {}
// 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment