summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2017-04-17 22:10:58 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2017-04-17 22:10:58 +0000
commit956a9d3770ca7cfcec334147c98e26bc00d044e0 (patch)
treea190311458c423b71ed9f800fd5bd43faa7dccc3
parent13be6c20301280dbd9172dc0fac31a6ed9c1e8e2 (diff)
downloadgcc-956a9d3770ca7cfcec334147c98e26bc00d044e0.tar.gz
libgo: update to Go 1.8.1 release
Reviewed-on: https://go-review.googlesource.com/40775 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@246957 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libgo/MERGE2
-rw-r--r--libgo/VERSION2
-rw-r--r--libgo/go/cmd/go/go_test.go18
-rw-r--r--libgo/go/cmd/go/pkg.go4
-rw-r--r--libgo/go/cmd/go/test.go21
-rw-r--r--libgo/go/crypto/tls/common.go1
-rw-r--r--libgo/go/crypto/tls/tls_test.go90
-rw-r--r--libgo/go/encoding/xml/marshal_test.go7
-rw-r--r--libgo/go/encoding/xml/read.go3
-rw-r--r--libgo/go/encoding/xml/xml_test.go34
-rw-r--r--libgo/go/image/png/reader.go5
-rw-r--r--libgo/go/image/png/reader_test.go10
-rw-r--r--libgo/go/internal/testenv/testenv.go9
-rw-r--r--libgo/go/internal/testenv/testenv_cgo.go11
-rw-r--r--libgo/go/net/http/http.go2
-rw-r--r--libgo/go/net/net.go2
-rw-r--r--libgo/go/os/exec/exec_test.go10
-rw-r--r--libgo/go/reflect/all_test.go35
-rw-r--r--libgo/go/runtime/crash_unix_test.go73
-rw-r--r--libgo/go/runtime/export_test.go13
-rw-r--r--libgo/go/runtime/runtime1.go6
-rw-r--r--libgo/go/runtime/sema.go1
-rw-r--r--libgo/go/text/template/multi_test.go37
-rw-r--r--libgo/go/text/template/template.go4
24 files changed, 359 insertions, 41 deletions
diff --git a/libgo/MERGE b/libgo/MERGE
index 16f346a2b8e..a5808db54ff 100644
--- a/libgo/MERGE
+++ b/libgo/MERGE
@@ -1,4 +1,4 @@
-cd6b6202dd1559b3ac63179b45f1833fcfbe7eca
+a4c18f063b6659079ca2848ca217a0587dabc001
The first line of this file holds the git revision number of the
last merge done from the master library sources.
diff --git a/libgo/VERSION b/libgo/VERSION
index 436edd93930..dce1d463ba1 100644
--- a/libgo/VERSION
+++ b/libgo/VERSION
@@ -1 +1 @@
-go1.8
+go1.8.1
diff --git a/libgo/go/cmd/go/go_test.go b/libgo/go/cmd/go/go_test.go
index 56de65ce55a..fa78578d121 100644
--- a/libgo/go/cmd/go/go_test.go
+++ b/libgo/go/cmd/go/go_test.go
@@ -2227,6 +2227,24 @@ func TestTestEmpty(t *testing.T) {
}
}
+func TestTestRaceInstall(t *testing.T) {
+ if !canRace {
+ t.Skip("no race detector")
+ }
+
+ tg := testgo(t)
+ defer tg.cleanup()
+ tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+
+ tg.tempDir("pkg")
+ pkgdir := tg.path("pkg")
+ tg.run("install", "-race", "-pkgdir="+pkgdir, "std")
+ tg.run("test", "-race", "-pkgdir="+pkgdir, "-i", "-v", "empty/pkg")
+ if tg.getStderr() != "" {
+ t.Error("go test -i -race: rebuilds cached packages")
+ }
+}
+
func TestBuildDryRunWithCgo(t *testing.T) {
if !canCgo {
t.Skip("skipping because cgo not enabled")
diff --git a/libgo/go/cmd/go/pkg.go b/libgo/go/cmd/go/pkg.go
index 61c1b9960ea..f0dc95670f9 100644
--- a/libgo/go/cmd/go/pkg.go
+++ b/libgo/go/cmd/go/pkg.go
@@ -970,10 +970,6 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
if p.Name == "main" && goarch == "arm" {
importPaths = append(importPaths, "math")
}
- // In coverage atomic mode everything depends on sync/atomic.
- if testCoverMode == "atomic" && (!p.Standard || (p.ImportPath != "runtime/cgo" && p.ImportPath != "runtime/race" && p.ImportPath != "sync/atomic")) {
- importPaths = append(importPaths, "sync/atomic")
- }
}
// Runtime and its internal packages depend on runtime/internal/sys,
diff --git a/libgo/go/cmd/go/test.go b/libgo/go/cmd/go/test.go
index 5c13b653f01..12990feb43c 100644
--- a/libgo/go/cmd/go/test.go
+++ b/libgo/go/cmd/go/test.go
@@ -548,6 +548,10 @@ func runTest(cmd *Command, args []string) {
// Prepare build + run + print actions for all packages being tested.
for _, p := range pkgs {
+ // sync/atomic import is inserted by the cover tool. See #18486
+ if testCover && testCoverMode == "atomic" {
+ ensureImport(p, "sync/atomic")
+ }
buildTest, runTest, printTest, err := b.test(p)
if err != nil {
str := err.Error()
@@ -639,6 +643,23 @@ func runTest(cmd *Command, args []string) {
b.do(root)
}
+// ensures that package p imports the named package.
+func ensureImport(p *Package, pkg string) {
+ for _, d := range p.deps {
+ if d.Name == pkg {
+ return
+ }
+ }
+
+ a := loadPackage(pkg, &importStack{})
+ if a.Error != nil {
+ fatalf("load %s: %v", pkg, a.Error)
+ }
+ computeStale(a)
+
+ p.imports = append(p.imports, a)
+}
+
func contains(x []string, s string) bool {
for _, t := range x {
if t == s {
diff --git a/libgo/go/crypto/tls/common.go b/libgo/go/crypto/tls/common.go
index 276d1761ea0..de833a90563 100644
--- a/libgo/go/crypto/tls/common.go
+++ b/libgo/go/crypto/tls/common.go
@@ -563,6 +563,7 @@ func (c *Config) Clone() *Config {
Certificates: c.Certificates,
NameToCertificate: c.NameToCertificate,
GetCertificate: c.GetCertificate,
+ GetClientCertificate: c.GetClientCertificate,
GetConfigForClient: c.GetConfigForClient,
VerifyPeerCertificate: c.VerifyPeerCertificate,
RootCAs: c.RootCAs,
diff --git a/libgo/go/crypto/tls/tls_test.go b/libgo/go/crypto/tls/tls_test.go
index 8933f4f2015..86812f0c974 100644
--- a/libgo/go/crypto/tls/tls_test.go
+++ b/libgo/go/crypto/tls/tls_test.go
@@ -13,13 +13,11 @@ import (
"io"
"io/ioutil"
"math"
- "math/rand"
"net"
"os"
"reflect"
"strings"
"testing"
- "testing/quick"
"time"
)
@@ -568,11 +566,50 @@ func TestConnCloseWrite(t *testing.T) {
}
}
-func TestClone(t *testing.T) {
+func TestCloneFuncFields(t *testing.T) {
+ const expectedCount = 5
+ called := 0
+
+ c1 := Config{
+ Time: func() time.Time {
+ called |= 1 << 0
+ return time.Time{}
+ },
+ GetCertificate: func(*ClientHelloInfo) (*Certificate, error) {
+ called |= 1 << 1
+ return nil, nil
+ },
+ GetClientCertificate: func(*CertificateRequestInfo) (*Certificate, error) {
+ called |= 1 << 2
+ return nil, nil
+ },
+ GetConfigForClient: func(*ClientHelloInfo) (*Config, error) {
+ called |= 1 << 3
+ return nil, nil
+ },
+ VerifyPeerCertificate: func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
+ called |= 1 << 4
+ return nil
+ },
+ }
+
+ c2 := c1.Clone()
+
+ c2.Time()
+ c2.GetCertificate(nil)
+ c2.GetClientCertificate(nil)
+ c2.GetConfigForClient(nil)
+ c2.VerifyPeerCertificate(nil, nil)
+
+ if called != (1<<expectedCount)-1 {
+ t.Fatalf("expected %d calls but saw calls %b", expectedCount, called)
+ }
+}
+
+func TestCloneNonFuncFields(t *testing.T) {
var c1 Config
v := reflect.ValueOf(&c1).Elem()
- rnd := rand.New(rand.NewSource(time.Now().Unix()))
typ := v.Type()
for i := 0; i < typ.NumField(); i++ {
f := v.Field(i)
@@ -581,40 +618,49 @@ func TestClone(t *testing.T) {
continue
}
- // testing/quick can't handle functions or interfaces.
- fn := typ.Field(i).Name
- switch fn {
+ // testing/quick can't handle functions or interfaces and so
+ // isn't used here.
+ switch fn := typ.Field(i).Name; fn {
case "Rand":
f.Set(reflect.ValueOf(io.Reader(os.Stdin)))
- continue
case "Time", "GetCertificate", "GetConfigForClient", "VerifyPeerCertificate", "GetClientCertificate":
- // DeepEqual can't compare functions.
- continue
+ // DeepEqual can't compare functions. If you add a
+ // function field to this list, you must also change
+ // TestCloneFuncFields to ensure that the func field is
+ // cloned.
case "Certificates":
f.Set(reflect.ValueOf([]Certificate{
{Certificate: [][]byte{{'b'}}},
}))
- continue
case "NameToCertificate":
f.Set(reflect.ValueOf(map[string]*Certificate{"a": nil}))
- continue
case "RootCAs", "ClientCAs":
f.Set(reflect.ValueOf(x509.NewCertPool()))
- continue
case "ClientSessionCache":
f.Set(reflect.ValueOf(NewLRUClientSessionCache(10)))
- continue
case "KeyLogWriter":
f.Set(reflect.ValueOf(io.Writer(os.Stdout)))
- continue
-
- }
-
- q, ok := quick.Value(f.Type(), rnd)
- if !ok {
- t.Fatalf("quick.Value failed on field %s", fn)
+ case "NextProtos":
+ f.Set(reflect.ValueOf([]string{"a", "b"}))
+ case "ServerName":
+ f.Set(reflect.ValueOf("b"))
+ case "ClientAuth":
+ f.Set(reflect.ValueOf(VerifyClientCertIfGiven))
+ case "InsecureSkipVerify", "SessionTicketsDisabled", "DynamicRecordSizingDisabled", "PreferServerCipherSuites":
+ f.Set(reflect.ValueOf(true))
+ case "MinVersion", "MaxVersion":
+ f.Set(reflect.ValueOf(uint16(VersionTLS12)))
+ case "SessionTicketKey":
+ f.Set(reflect.ValueOf([32]byte{}))
+ case "CipherSuites":
+ f.Set(reflect.ValueOf([]uint16{1, 2}))
+ case "CurvePreferences":
+ f.Set(reflect.ValueOf([]CurveID{CurveP256}))
+ case "Renegotiation":
+ f.Set(reflect.ValueOf(RenegotiateOnceAsClient))
+ default:
+ t.Errorf("all fields must be accounted for, but saw unknown field %q", fn)
}
- f.Set(q)
}
c2 := c1.Clone()
diff --git a/libgo/go/encoding/xml/marshal_test.go b/libgo/go/encoding/xml/marshal_test.go
index 5ec7ececa4d..0126146d332 100644
--- a/libgo/go/encoding/xml/marshal_test.go
+++ b/libgo/go/encoding/xml/marshal_test.go
@@ -2428,7 +2428,10 @@ func TestIssue16158(t *testing.T) {
err := Unmarshal([]byte(data), &struct {
B byte `xml:"b,attr,omitempty"`
}{})
- if err == nil {
- t.Errorf("Unmarshal: expected error, got nil")
+
+ // For Go 1.8.1 we've restored the old "no errors reported" behavior.
+ // We'll try again in Go 1.9 to report errors.
+ if err != nil {
+ t.Errorf("Unmarshal: expected nil, got error")
}
}
diff --git a/libgo/go/encoding/xml/read.go b/libgo/go/encoding/xml/read.go
index 5a89d5f504a..799b57e9d15 100644
--- a/libgo/go/encoding/xml/read.go
+++ b/libgo/go/encoding/xml/read.go
@@ -285,7 +285,8 @@ func (p *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error {
return nil
}
- return copyValue(val, []byte(attr.Value))
+ copyValue(val, []byte(attr.Value))
+ return nil
}
var (
diff --git a/libgo/go/encoding/xml/xml_test.go b/libgo/go/encoding/xml/xml_test.go
index dad6ed98c1b..f43a5e7eebc 100644
--- a/libgo/go/encoding/xml/xml_test.go
+++ b/libgo/go/encoding/xml/xml_test.go
@@ -797,3 +797,37 @@ func TestIssue12417(t *testing.T) {
}
}
}
+
+func TestIssue19333(t *testing.T) {
+ type X struct {
+ XMLName Name `xml:"X"`
+ A int `xml:",attr"`
+ C int
+ }
+
+ var tests = []struct {
+ input string
+ ok bool
+ }{
+ {`<X></X>`, true},
+ {`<X A=""></X>`, true},
+ {`<X A="bad"></X>`, true},
+ {`<X></X>`, true},
+ {`<X><C></C></X>`, false},
+ {`<X><C/></X>`, false},
+ {`<X><C>bad</C></X>`, false},
+ }
+
+ for _, tt := range tests {
+ err := Unmarshal([]byte(tt.input), new(X))
+ if tt.ok {
+ if err != nil {
+ t.Errorf("%s: unexpected error: %v", tt.input, err)
+ }
+ } else {
+ if err == nil {
+ t.Errorf("%s: unexpected success", tt.input)
+ }
+ }
+ }
+}
diff --git a/libgo/go/image/png/reader.go b/libgo/go/image/png/reader.go
index 32f78f0ffe8..8299df56735 100644
--- a/libgo/go/image/png/reader.go
+++ b/libgo/go/image/png/reader.go
@@ -612,6 +612,11 @@ func (d *decoder) readImagePass(r io.Reader, pass int, allocateOnly bool) (image
}
}
case cbG8:
+ if d.useTransparent {
+ // Match error from Go 1.7 and earlier.
+ // Go 1.9 will decode this properly.
+ return nil, chunkOrderError
+ }
copy(gray.Pix[pixOffset:], cdat)
pixOffset += gray.Stride
case cbGA8:
diff --git a/libgo/go/image/png/reader_test.go b/libgo/go/image/png/reader_test.go
index b9e9f4d02c6..503b5dc567b 100644
--- a/libgo/go/image/png/reader_test.go
+++ b/libgo/go/image/png/reader_test.go
@@ -629,3 +629,13 @@ func BenchmarkDecodeRGB(b *testing.B) {
func BenchmarkDecodeInterlacing(b *testing.B) {
benchmarkDecode(b, "testdata/benchRGB-interlace.png", 4)
}
+
+func TestIssue19553(t *testing.T) {
+ var buf = []byte{
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x85, 0x2c, 0x88, 0x80, 0x00, 0x00, 0x00, 0x02, 0x74, 0x52, 0x4e, 0x53, 0x00, 0xff, 0x5b, 0x91, 0x22, 0xb5, 0x00, 0x00, 0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0a, 0xf0, 0x00, 0x00, 0x0a, 0xf0, 0x01, 0x42, 0xac, 0x34, 0x98, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xd5, 0x04, 0x02, 0x12, 0x11, 0x11, 0xf7, 0x65, 0x3d, 0x8b, 0x00, 0x00, 0x00, 0x4f, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0xff, 0xff, 0xff, 0xb9, 0xbd, 0x70, 0xf0, 0x8c, 0x01, 0xc8, 0xaf, 0x6e, 0x99, 0x02, 0x05, 0xd9, 0x7b, 0xc1, 0xfc, 0x6b, 0xff, 0xa1, 0xa0, 0x87, 0x30, 0xff, 0xd9, 0xde, 0xbd, 0xd5, 0x4b, 0xf7, 0xee, 0xfd, 0x0e, 0xe3, 0xef, 0xcd, 0x06, 0x19, 0x14, 0xf5, 0x1e, 0xce, 0xef, 0x01, 0x31, 0x92, 0xd7, 0x82, 0x41, 0x31, 0x9c, 0x3f, 0x07, 0x02, 0xee, 0xa1, 0xaa, 0xff, 0xff, 0x9f, 0xe1, 0xd9, 0x56, 0x30, 0xf8, 0x0e, 0xe5, 0x03, 0x00, 0xa9, 0x42, 0x84, 0x3d, 0xdf, 0x8f, 0xa6, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
+ }
+ _, err := Decode(bytes.NewReader(buf))
+ if err != chunkOrderError {
+ t.Errorf("Decode: expected chunkOrderError for transparent gray8, got %v", err)
+ }
+}
diff --git a/libgo/go/internal/testenv/testenv.go b/libgo/go/internal/testenv/testenv.go
index fdba8b25c3a..71a692b367e 100644
--- a/libgo/go/internal/testenv/testenv.go
+++ b/libgo/go/internal/testenv/testenv.go
@@ -141,6 +141,15 @@ func MustHaveExternalNetwork(t *testing.T) {
}
}
+var haveCGO bool
+
+// MustHaveCGO calls t.Skip if cgo is not available.
+func MustHaveCGO(t *testing.T) {
+ if !haveCGO {
+ t.Skipf("skipping test: no cgo")
+ }
+}
+
// HasSymlink reports whether the current system can use os.Symlink.
func HasSymlink() bool {
ok, _ := hasSymlink()
diff --git a/libgo/go/internal/testenv/testenv_cgo.go b/libgo/go/internal/testenv/testenv_cgo.go
new file mode 100644
index 00000000000..e3d4d16b33e
--- /dev/null
+++ b/libgo/go/internal/testenv/testenv_cgo.go
@@ -0,0 +1,11 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build cgo
+
+package testenv
+
+func init() {
+ haveCGO = true
+}
diff --git a/libgo/go/net/http/http.go b/libgo/go/net/http/http.go
index 826f7ff3da5..b95ca89f409 100644
--- a/libgo/go/net/http/http.go
+++ b/libgo/go/net/http/http.go
@@ -20,7 +20,7 @@ const maxInt64 = 1<<63 - 1
// aLongTimeAgo is a non-zero time, far in the past, used for
// immediate cancelation of network operations.
-var aLongTimeAgo = time.Unix(233431200, 0)
+var aLongTimeAgo = time.Unix(1, 0)
// TODO(bradfitz): move common stuff here. The other files have accumulated
// generic http stuff in random places.
diff --git a/libgo/go/net/net.go b/libgo/go/net/net.go
index 81206ea1cb6..a8b57361e6c 100644
--- a/libgo/go/net/net.go
+++ b/libgo/go/net/net.go
@@ -468,7 +468,7 @@ func (e *OpError) Error() string {
var (
// aLongTimeAgo is a non-zero time, far in the past, used for
// immediate cancelation of dials.
- aLongTimeAgo = time.Unix(233431200, 0)
+ aLongTimeAgo = time.Unix(1, 0)
// nonDeadline and noCancel are just zero values for
// readability with functions taking too many parameters.
diff --git a/libgo/go/os/exec/exec_test.go b/libgo/go/os/exec/exec_test.go
index a9cceecd2a8..f13635138a1 100644
--- a/libgo/go/os/exec/exec_test.go
+++ b/libgo/go/os/exec/exec_test.go
@@ -266,9 +266,13 @@ func TestStdinCloseRace(t *testing.T) {
t.Fatalf("Start: %v", err)
}
go func() {
- if err := cmd.Process.Kill(); err != nil {
- t.Errorf("Kill: %v", err)
- }
+ // We don't check the error return of Kill. It is
+ // possible that the process has already exited, in
+ // which case Kill will return an error "process
+ // already finished". The purpose of this test is to
+ // see whether the race detector reports an error; it
+ // doesn't matter whether this Kill succeeds or not.
+ cmd.Process.Kill()
}()
go func() {
// Send the wrong string, so that the child fails even
diff --git a/libgo/go/reflect/all_test.go b/libgo/go/reflect/all_test.go
index 859de7c8670..3686167ed42 100644
--- a/libgo/go/reflect/all_test.go
+++ b/libgo/go/reflect/all_test.go
@@ -1681,6 +1681,11 @@ func (p Point) GCMethod(k int) int {
}
// This will be index 3.
+func (p Point) NoArgs() {
+ // Exercise no-argument/no-result paths.
+}
+
+// This will be index 4.
func (p Point) TotalDist(points ...Point) int {
tot := 0
for _, q := range points {
@@ -1709,6 +1714,15 @@ func TestMethod(t *testing.T) {
t.Errorf("Type MethodByName returned %d; want 275", i)
}
+ m, ok = TypeOf(p).MethodByName("NoArgs")
+ if !ok {
+ t.Fatalf("method by name failed")
+ }
+ n := len(m.Func.Call([]Value{ValueOf(p)}))
+ if n != 0 {
+ t.Errorf("NoArgs returned %d values; want 0", n)
+ }
+
i = TypeOf(&p).Method(1).Func.Call([]Value{ValueOf(&p), ValueOf(12)})[0].Int()
if i != 300 {
t.Errorf("Pointer Type Method returned %d; want 300", i)
@@ -1723,6 +1737,15 @@ func TestMethod(t *testing.T) {
t.Errorf("Pointer Type MethodByName returned %d; want 325", i)
}
+ m, ok = TypeOf(&p).MethodByName("NoArgs")
+ if !ok {
+ t.Fatalf("method by name failed")
+ }
+ n = len(m.Func.Call([]Value{ValueOf(&p)}))
+ if n != 0 {
+ t.Errorf("NoArgs returned %d values; want 0", n)
+ }
+
// Curried method of value.
tfunc := TypeOf((func(int) int)(nil))
v := ValueOf(p).Method(1)
@@ -1741,6 +1764,8 @@ func TestMethod(t *testing.T) {
if i != 375 {
t.Errorf("Value MethodByName returned %d; want 375", i)
}
+ v = ValueOf(p).MethodByName("NoArgs")
+ v.Call(nil)
// Curried method of pointer.
v = ValueOf(&p).Method(1)
@@ -1759,6 +1784,8 @@ func TestMethod(t *testing.T) {
if i != 425 {
t.Errorf("Pointer Value MethodByName returned %d; want 425", i)
}
+ v = ValueOf(&p).MethodByName("NoArgs")
+ v.Call(nil)
// Curried method of interface value.
// Have to wrap interface value in a struct to get at it.
@@ -1808,6 +1835,9 @@ func TestMethodValue(t *testing.T) {
if i != 275 {
t.Errorf("Value MethodByName returned %d; want 275", i)
}
+ v = ValueOf(p).MethodByName("NoArgs")
+ ValueOf(v.Interface()).Call(nil)
+ v.Interface().(func())()
// Curried method of pointer.
v = ValueOf(&p).Method(1)
@@ -1826,6 +1856,9 @@ func TestMethodValue(t *testing.T) {
if i != 325 {
t.Errorf("Pointer Value MethodByName returned %d; want 325", i)
}
+ v = ValueOf(&p).MethodByName("NoArgs")
+ ValueOf(v.Interface()).Call(nil)
+ v.Interface().(func())()
// Curried method of pointer to pointer.
pp := &p
@@ -1881,7 +1914,7 @@ func TestVariadicMethodValue(t *testing.T) {
// Curried method of value.
tfunc := TypeOf((func(...Point) int)(nil))
- v := ValueOf(p).Method(3)
+ v := ValueOf(p).Method(4)
if tt := v.Type(); tt != tfunc {
t.Errorf("Variadic Method Type is %s; want %s", tt, tfunc)
}
diff --git a/libgo/go/runtime/crash_unix_test.go b/libgo/go/runtime/crash_unix_test.go
index 97deed8b9d9..182c84b6392 100644
--- a/libgo/go/runtime/crash_unix_test.go
+++ b/libgo/go/runtime/crash_unix_test.go
@@ -9,6 +9,7 @@ package runtime_test
import (
"bytes"
"internal/testenv"
+ "io"
"io/ioutil"
"os"
"os/exec"
@@ -153,6 +154,78 @@ func loop(i int, c chan bool) {
}
`
+func TestPanicSystemstack(t *testing.T) {
+ // Test that GOTRACEBACK=crash prints both the system and user
+ // stack of other threads.
+
+ // The GOTRACEBACK=crash handler takes 0.1 seconds even if
+ // it's not writing a core file and potentially much longer if
+ // it is. Skip in short mode.
+ if testing.Short() {
+ t.Skip("Skipping in short mode (GOTRACEBACK=crash is slow)")
+ }
+
+ t.Parallel()
+ cmd := exec.Command(os.Args[0], "testPanicSystemstackInternal")
+ cmd = testEnv(cmd)
+ cmd.Env = append(cmd.Env, "GOTRACEBACK=crash")
+ pr, pw, err := os.Pipe()
+ if err != nil {
+ t.Fatal("creating pipe: ", err)
+ }
+ cmd.Stderr = pw
+ if err := cmd.Start(); err != nil {
+ t.Fatal("starting command: ", err)
+ }
+ defer cmd.Process.Wait()
+ defer cmd.Process.Kill()
+ if err := pw.Close(); err != nil {
+ t.Log("closing write pipe: ", err)
+ }
+ defer pr.Close()
+
+ // Wait for "x\nx\n" to indicate readiness.
+ buf := make([]byte, 4)
+ _, err = io.ReadFull(pr, buf)
+ if err != nil || string(buf) != "x\nx\n" {
+ t.Fatal("subprocess failed; output:\n", string(buf))
+ }
+
+ // Send SIGQUIT.
+ if err := cmd.Process.Signal(syscall.SIGQUIT); err != nil {
+ t.Fatal("signaling subprocess: ", err)
+ }
+
+ // Get traceback.
+ tb, err := ioutil.ReadAll(pr)
+ if err != nil {
+ t.Fatal("reading traceback from pipe: ", err)
+ }
+
+ // Traceback should have two testPanicSystemstackInternal's
+ // and two blockOnSystemStackInternal's.
+ if bytes.Count(tb, []byte("testPanicSystemstackInternal")) != 2 {
+ t.Fatal("traceback missing user stack:\n", string(tb))
+ } else if bytes.Count(tb, []byte("blockOnSystemStackInternal")) != 2 {
+ t.Fatal("traceback missing system stack:\n", string(tb))
+ }
+}
+
+func init() {
+ if len(os.Args) >= 2 && os.Args[1] == "testPanicSystemstackInternal" {
+ // Get two threads running on the system stack with
+ // something recognizable in the stack trace.
+ runtime.GOMAXPROCS(2)
+ go testPanicSystemstackInternal()
+ testPanicSystemstackInternal()
+ }
+}
+
+func testPanicSystemstackInternal() {
+ runtime.BlockOnSystemStack()
+ os.Exit(1) // Should be unreachable.
+}
+
func TestSignalExitStatus(t *testing.T) {
testenv.MustHaveGoBuild(t)
exe, err := buildTestProg(t, "testprog")
diff --git a/libgo/go/runtime/export_test.go b/libgo/go/runtime/export_test.go
index fcc1e6199a4..cc4b188b60c 100644
--- a/libgo/go/runtime/export_test.go
+++ b/libgo/go/runtime/export_test.go
@@ -243,3 +243,16 @@ func CountPagesInUse() (pagesInUse, counted uintptr) {
return
}
*/
+
+// BlockOnSystemStack switches to the system stack, prints "x\n" to
+// stderr, and blocks in a stack containing
+// "runtime.blockOnSystemStackInternal".
+func BlockOnSystemStack() {
+ systemstack(blockOnSystemStackInternal)
+}
+
+func blockOnSystemStackInternal() {
+ print("x\n")
+ lock(&deadlock)
+ lock(&deadlock)
+}
diff --git a/libgo/go/runtime/runtime1.go b/libgo/go/runtime/runtime1.go
index a41cfc81181..99c0f11930f 100644
--- a/libgo/go/runtime/runtime1.go
+++ b/libgo/go/runtime/runtime1.go
@@ -280,6 +280,12 @@ func check() {
throw("atomicor8")
}
+ m = [4]byte{0xff, 0xff, 0xff, 0xff}
+ atomic.And8(&m[1], 0x1)
+ if m[0] != 0xff || m[1] != 0x1 || m[2] != 0xff || m[3] != 0xff {
+ throw("atomicand8")
+ }
+
*(*uint64)(unsafe.Pointer(&j)) = ^uint64(0)
if j == j {
throw("float64nan")
diff --git a/libgo/go/runtime/sema.go b/libgo/go/runtime/sema.go
index 576a1fb7a20..37318ff9d55 100644
--- a/libgo/go/runtime/sema.go
+++ b/libgo/go/runtime/sema.go
@@ -171,6 +171,7 @@ func semrelease(addr *uint32) {
for x := root.head; x != nil; x = x.next {
if x.elem == unsafe.Pointer(addr) {
x.acquiretime = t0
+ break
}
}
mutexevent(t0-s.acquiretime, 3)
diff --git a/libgo/go/text/template/multi_test.go b/libgo/go/text/template/multi_test.go
index 8142f008fdf..5d8c08f06f1 100644
--- a/libgo/go/text/template/multi_test.go
+++ b/libgo/go/text/template/multi_test.go
@@ -363,7 +363,7 @@ func TestEmptyTemplate(t *testing.T) {
{[]string{"{{.}}", ""}, "twice", ""},
}
- for _, c := range cases {
+ for i, c := range cases {
root := New("root")
var (
@@ -378,10 +378,43 @@ func TestEmptyTemplate(t *testing.T) {
}
buf := &bytes.Buffer{}
if err := m.Execute(buf, c.in); err != nil {
- t.Fatal(err)
+ t.Error(i, err)
+ continue
}
if buf.String() != c.want {
t.Errorf("expected string %q: got %q", c.want, buf.String())
}
}
}
+
+// Issue 19249 was a regression in 1.8 caused by the handling of empty
+// templates added in that release, which got different answers depending
+// on the order templates appeared in the internal map.
+func TestIssue19294(t *testing.T) {
+ // The empty block in "xhtml" should be replaced during execution
+ // by the contents of "stylesheet", but if the internal map associating
+ // names with templates is built in the wrong order, the empty block
+ // looks non-empty and this doesn't happen.
+ var inlined = map[string]string{
+ "stylesheet": `{{define "stylesheet"}}stylesheet{{end}}`,
+ "xhtml": `{{block "stylesheet" .}}{{end}}`,
+ }
+ all := []string{"stylesheet", "xhtml"}
+ for i := 0; i < 100; i++ {
+ res, err := New("title.xhtml").Parse(`{{template "xhtml" .}}`)
+ if err != nil {
+ t.Fatal(err)
+ }
+ for _, name := range all {
+ _, err := res.New(name).Parse(inlined[name])
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+ var buf bytes.Buffer
+ res.Execute(&buf, 0)
+ if buf.String() != "stylesheet" {
+ t.Fatalf("iteration %d: got %q; expected %q", i, buf.String(), "stylesheet")
+ }
+ }
+}
diff --git a/libgo/go/text/template/template.go b/libgo/go/text/template/template.go
index b6fceb1795c..3b4f34b4db0 100644
--- a/libgo/go/text/template/template.go
+++ b/libgo/go/text/template/template.go
@@ -127,7 +127,7 @@ func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error
// Even if nt == t, we need to install it in the common.tmpl map.
if replace, err := t.associate(nt, tree); err != nil {
return nil, err
- } else if replace {
+ } else if replace || nt.Tree == nil {
nt.Tree = tree
}
return nt, nil
@@ -215,7 +215,7 @@ func (t *Template) associate(new *Template, tree *parse.Tree) (bool, error) {
if new.common != t.common {
panic("internal error: associate not common")
}
- if t.tmpl[new.name] != nil && parse.IsEmptyTree(tree.Root) && t.Tree != nil {
+ if old := t.tmpl[new.name]; old != nil && parse.IsEmptyTree(tree.Root) && old.Tree != nil {
// If a template by that name exists,
// don't replace it with an empty template.
return false, nil