Patchwork libgo patch committed: Update to current Go library

login
register
mail settings
Submitter Ian Taylor
Date Nov. 27, 2013, 1:05 a.m.
Message ID <mcr1u22r6vw.fsf@iant-glaptop.roam.corp.google.com>
Download mbox | patch
Permalink /patch/294453/
State New
Headers show

Comments

Ian Taylor - Nov. 27, 2013, 1:05 a.m.
This patch updates libgo to the current Go library sources, which will
almost certainly be the Go library included in the Go 1.2 release.
Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian

Patch

diff -r 827fb5004620 libgo/MERGE
--- a/libgo/MERGE	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/MERGE	Tue Nov 26 16:47:25 2013 -0800
@@ -1,4 +1,4 @@ 
-7ebbddd21330
+65bf677ab8d8
 
 The first line of this file holds the Mercurial revision number of the
 last merge done from the master library sources.
diff -r 827fb5004620 libgo/go/database/sql/driver/driver.go
--- a/libgo/go/database/sql/driver/driver.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/database/sql/driver/driver.go	Tue Nov 26 16:47:25 2013 -0800
@@ -140,8 +140,8 @@ 
 }
 
 // ColumnConverter may be optionally implemented by Stmt if the
-// the statement is aware of its own columns' types and can
-// convert from any type to a driver Value.
+// statement is aware of its own columns' types and can convert from
+// any type to a driver Value.
 type ColumnConverter interface {
 	// ColumnConverter returns a ValueConverter for the provided
 	// column index.  If the type of a specific column isn't known
diff -r 827fb5004620 libgo/go/database/sql/sql.go
--- a/libgo/go/database/sql/sql.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/database/sql/sql.go	Tue Nov 26 16:47:25 2013 -0800
@@ -201,7 +201,7 @@ 
 	connRequests *list.List // of connRequest
 	numOpen      int
 	pendingOpens int
-	// Used to sygnal the need for new connections
+	// Used to signal the need for new connections
 	// a goroutine running connectionOpener() reads on this chan and
 	// maybeOpenNewConnections sends on the chan (one send per needed connection)
 	// It is closed during db.Close(). The close tells the connectionOpener
@@ -1637,7 +1637,16 @@ 
 
 // A Result summarizes an executed SQL command.
 type Result interface {
+	// LastInsertId returns the integer generated by the database
+	// in response to a command. Typically this will be from an
+	// "auto increment" column when inserting a new row. Not all
+	// databases support this feature, and the syntax of such
+	// statements varies.
 	LastInsertId() (int64, error)
+
+	// RowsAffected returns the number of rows affected by an
+	// update, insert, or delete. Not every database or database
+	// driver may support this.
 	RowsAffected() (int64, error)
 }
 
diff -r 827fb5004620 libgo/go/debug/dwarf/const.go
--- a/libgo/go/debug/dwarf/const.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/debug/dwarf/const.go	Tue Nov 26 16:47:25 2013 -0800
@@ -207,9 +207,8 @@ 
 	formRef8        format = 0x14
 	formRefUdata    format = 0x15
 	formIndirect    format = 0x16
-	// following are defined in DWARF 4
 	formSecOffset   format = 0x17
-	formExprLoc     format = 0x18
+	formExprloc     format = 0x18
 	formFlagPresent format = 0x19
 	formRefSig8     format = 0x20
 )
diff -r 827fb5004620 libgo/go/debug/dwarf/entry.go
--- a/libgo/go/debug/dwarf/entry.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/debug/dwarf/entry.go	Tue Nov 26 16:47:25 2013 -0800
@@ -185,29 +185,15 @@ 
 		case formUdata:
 			val = int64(b.uint())
 
-		// exprloc
-		case formExprLoc:
-			val = b.bytes(int(b.uint()))
-
 		// flag
 		case formFlag:
 			val = b.uint8() == 1
+		// New in DWARF 4.
 		case formFlagPresent:
 			// The attribute is implicitly indicated as present, and no value is
 			// encoded in the debugging information entry itself.
 			val = true
 
-		// lineptr, loclistptr, macptr, rangelistptr
-		case formSecOffset:
-			is64, known := b.format.dwarf64()
-			if !known {
-				b.error("unknown size for DW_FORM_sec_offset")
-			} else if is64 {
-				val = Offset(b.uint64())
-			} else {
-				val = Offset(b.uint32())
-			}
-
 		// reference to other entry
 		case formRefAddr:
 			vers := b.format.version()
@@ -235,8 +221,6 @@ 
 			val = Offset(b.uint64()) + ubase
 		case formRefUdata:
 			val = Offset(b.uint()) + ubase
-		case formRefSig8:
-			val = b.uint64()
 
 		// string
 		case formString:
@@ -253,6 +237,30 @@ 
 				b.err = b1.err
 				return nil
 			}
+
+		// lineptr, loclistptr, macptr, rangelistptr
+		// New in DWARF 4, but clang can generate them with -gdwarf-2.
+		// Section reference, replacing use of formData4 and formData8.
+		case formSecOffset:
+			is64, known := b.format.dwarf64()
+			if !known {
+				b.error("unknown size for DW_FORM_sec_offset")
+			} else if is64 {
+				val = int64(b.uint64())
+			} else {
+				val = int64(b.uint32())
+			}
+
+		// exprloc
+		// New in DWARF 4.
+		case formExprloc:
+			val = b.bytes(int(b.uint()))
+
+		// reference
+		// New in DWARF 4.
+		case formRefSig8:
+			// 64-bit type signature.
+			val = b.uint64()
 		}
 		e.Field[i].Val = val
 	}
diff -r 827fb5004620 libgo/go/encoding/gob/doc.go
--- a/libgo/go/encoding/gob/doc.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/encoding/gob/doc.go	Tue Nov 26 16:47:25 2013 -0800
@@ -86,13 +86,13 @@ 
 at top the level will fail. A struct field of chan or func type is treated exactly
 like an unexported field and is ignored.
 
-Gob can encode a value of any type implementing the GobEncoder,
-encoding.BinaryMarshaler, or encoding.TextMarshaler interfaces by calling the
-corresponding method, in that order of preference.
+Gob can encode a value of any type implementing the GobEncoder or
+encoding.BinaryMarshaler interfaces by calling the corresponding method,
+in that order of preference.
 
-Gob can decode a value of any type implementing the GobDecoder,
-encoding.BinaryUnmarshaler, or encoding.TextUnmarshaler interfaces by calling
-the corresponding method, again in that order of preference.
+Gob can decode a value of any type implementing the GobDecoder or
+encoding.BinaryUnmarshaler interfaces by calling the corresponding method,
+again in that order of preference.
 
 Encoding Details
 
diff -r 827fb5004620 libgo/go/encoding/gob/gobencdec_test.go
--- a/libgo/go/encoding/gob/gobencdec_test.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/encoding/gob/gobencdec_test.go	Tue Nov 26 16:47:25 2013 -0800
@@ -11,6 +11,7 @@ 
 	"errors"
 	"fmt"
 	"io"
+	"net"
 	"strings"
 	"testing"
 	"time"
@@ -767,3 +768,17 @@ 
 		t.Fatalf("expected nil, got %v", err2)
 	}
 }
+
+func TestNetIP(t *testing.T) {
+	// Encoding of net.IP{1,2,3,4} in Go 1.1.
+	enc := []byte{0x07, 0x0a, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04}
+
+	var ip net.IP
+	err := NewDecoder(bytes.NewReader(enc)).Decode(&ip)
+	if err != nil {
+		t.Fatalf("decode: %v", err)
+	}
+	if ip.String() != "1.2.3.4" {
+		t.Errorf("decoded to %v, want 1.2.3.4", ip.String())
+	}
+}
diff -r 827fb5004620 libgo/go/encoding/gob/type.go
--- a/libgo/go/encoding/gob/type.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/encoding/gob/type.go	Tue Nov 26 16:47:25 2013 -0800
@@ -88,18 +88,25 @@ 
 		ut.externalEnc, ut.encIndir = xGob, indir
 	} else if ok, indir := implementsInterface(ut.user, binaryMarshalerInterfaceType); ok {
 		ut.externalEnc, ut.encIndir = xBinary, indir
-	} else if ok, indir := implementsInterface(ut.user, textMarshalerInterfaceType); ok {
-		ut.externalEnc, ut.encIndir = xText, indir
 	}
 
+	// NOTE(rsc): Would like to allow MarshalText here, but results in incompatibility
+	// with older encodings for net.IP. See golang.org/issue/6760.
+	// } else if ok, indir := implementsInterface(ut.user, textMarshalerInterfaceType); ok {
+	// 	ut.externalEnc, ut.encIndir = xText, indir
+	// }
+
 	if ok, indir := implementsInterface(ut.user, gobDecoderInterfaceType); ok {
 		ut.externalDec, ut.decIndir = xGob, indir
 	} else if ok, indir := implementsInterface(ut.user, binaryUnmarshalerInterfaceType); ok {
 		ut.externalDec, ut.decIndir = xBinary, indir
-	} else if ok, indir := implementsInterface(ut.user, textUnmarshalerInterfaceType); ok {
-		ut.externalDec, ut.decIndir = xText, indir
 	}
 
+	// See note above.
+	// } else if ok, indir := implementsInterface(ut.user, textUnmarshalerInterfaceType); ok {
+	// 	ut.externalDec, ut.decIndir = xText, indir
+	// }
+
 	userTypeCache[rt] = ut
 	return
 }
diff -r 827fb5004620 libgo/go/encoding/xml/read.go
--- a/libgo/go/encoding/xml/read.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/encoding/xml/read.go	Tue Nov 26 16:47:25 2013 -0800
@@ -53,7 +53,7 @@ 
 //      Unmarshal records the attribute value in that field.
 //
 //   * If the XML element contains character data, that data is
-//      accumulated in the first struct field that has tag "chardata".
+//      accumulated in the first struct field that has tag ",chardata".
 //      The struct field may have type []byte or string.
 //      If there is no such field, the character data is discarded.
 //
diff -r 827fb5004620 libgo/go/go/doc/synopsis.go
--- a/libgo/go/go/doc/synopsis.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/go/doc/synopsis.go	Tue Nov 26 16:47:25 2013 -0800
@@ -22,6 +22,9 @@ 
 		if q == ' ' && p == '.' && (!unicode.IsUpper(pp) || unicode.IsUpper(ppp)) {
 			return i
 		}
+		if p == '。' || p == '.' {
+			return i
+		}
 		ppp, pp, p = pp, p, q
 	}
 	return len(s)
diff -r 827fb5004620 libgo/go/go/doc/synopsis_test.go
--- a/libgo/go/go/doc/synopsis_test.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/go/doc/synopsis_test.go	Tue Nov 26 16:47:25 2013 -0800
@@ -28,6 +28,8 @@ 
 	{"P. Q.   ", 8, "P. Q."},
 	{"Package Καλημέρα κόσμε.", 36, "Package Καλημέρα κόσμε."},
 	{"Package こんにちは 世界\n", 31, "Package こんにちは 世界"},
+	{"Package こんにちは。世界", 26, "Package こんにちは。"},
+	{"Package 안녕.世界", 17, "Package 안녕."},
 	{"Package foo does bar.", 21, "Package foo does bar."},
 	{"Copyright 2012 Google, Inc. Package foo does bar.", 27, ""},
 	{"All Rights reserved. Package foo does bar.", 20, ""},
diff -r 827fb5004620 libgo/go/net/hosts_test.go
--- a/libgo/go/net/hosts_test.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/net/hosts_test.go	Tue Nov 26 16:47:25 2013 -0800
@@ -53,6 +53,19 @@ 
 	hostsPath = p
 }
 
+// https://code.google.com/p/go/issues/detail?id=6646
+func TestSingleLineHostsFile(t *testing.T) {
+	p := hostsPath
+	hostsPath = "testdata/hosts_singleline"
+
+	ips := lookupStaticHost("odin")
+	if len(ips) != 1 || ips[0] != "127.0.0.2" {
+		t.Errorf("lookupStaticHost = %v, want %v", ips, []string{"127.0.0.2"})
+	}
+
+	hostsPath = p
+}
+
 func TestLookupHost(t *testing.T) {
 	// Can't depend on this to return anything in particular,
 	// but if it does return something, make sure it doesn't
diff -r 827fb5004620 libgo/go/net/http/httputil/dump.go
--- a/libgo/go/net/http/httputil/dump.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/net/http/httputil/dump.go	Tue Nov 26 16:47:25 2013 -0800
@@ -45,13 +45,27 @@ 
 func (c *dumpConn) SetReadDeadline(t time.Time) error  { return nil }
 func (c *dumpConn) SetWriteDeadline(t time.Time) error { return nil }
 
+type neverEnding byte
+
+func (b neverEnding) Read(p []byte) (n int, err error) {
+	for i := range p {
+		p[i] = byte(b)
+	}
+	return len(p), nil
+}
+
 // DumpRequestOut is like DumpRequest but includes
 // headers that the standard http.Transport adds,
 // such as User-Agent.
 func DumpRequestOut(req *http.Request, body bool) ([]byte, error) {
 	save := req.Body
+	dummyBody := false
 	if !body || req.Body == nil {
 		req.Body = nil
+		if req.ContentLength != 0 {
+			req.Body = ioutil.NopCloser(io.LimitReader(neverEnding('x'), req.ContentLength))
+			dummyBody = true
+		}
 	} else {
 		var err error
 		save, req.Body, err = drainBody(req.Body)
@@ -99,7 +113,19 @@ 
 	if err != nil {
 		return nil, err
 	}
-	return buf.Bytes(), nil
+	dump := buf.Bytes()
+
+	// If we used a dummy body above, remove it now.
+	// TODO: if the req.ContentLength is large, we allocate memory
+	// unnecessarily just to slice it off here.  But this is just
+	// a debug function, so this is acceptable for now. We could
+	// discard the body earlier if this matters.
+	if dummyBody {
+		if i := bytes.Index(dump, []byte("\r\n\r\n")); i >= 0 {
+			dump = dump[:i+4]
+		}
+	}
+	return dump, nil
 }
 
 // delegateReader is a reader that delegates to another reader,
diff -r 827fb5004620 libgo/go/net/http/httputil/dump_test.go
--- a/libgo/go/net/http/httputil/dump_test.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/net/http/httputil/dump_test.go	Tue Nov 26 16:47:25 2013 -0800
@@ -20,6 +20,7 @@ 
 
 	WantDump    string
 	WantDumpOut string
+	NoBody      bool // if true, set DumpRequest{,Out} body to false
 }
 
 var dumpTests = []dumpTest{
@@ -83,6 +84,31 @@ 
 			"User-Agent: Go 1.1 package http\r\n" +
 			"Accept-Encoding: gzip\r\n\r\n",
 	},
+
+	// Request with Body, but Dump requested without it.
+	{
+		Req: http.Request{
+			Method: "POST",
+			URL: &url.URL{
+				Scheme: "http",
+				Host:   "post.tld",
+				Path:   "/",
+			},
+			ContentLength: 6,
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+		},
+
+		Body: []byte("abcdef"),
+
+		WantDumpOut: "POST / HTTP/1.1\r\n" +
+			"Host: post.tld\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"Content-Length: 6\r\n" +
+			"Accept-Encoding: gzip\r\n\r\n",
+
+		NoBody: true,
+	},
 }
 
 func TestDumpRequest(t *testing.T) {
@@ -105,7 +131,7 @@ 
 
 		if tt.WantDump != "" {
 			setBody()
-			dump, err := DumpRequest(&tt.Req, true)
+			dump, err := DumpRequest(&tt.Req, !tt.NoBody)
 			if err != nil {
 				t.Errorf("DumpRequest #%d: %s", i, err)
 				continue
@@ -118,7 +144,7 @@ 
 
 		if tt.WantDumpOut != "" {
 			setBody()
-			dump, err := DumpRequestOut(&tt.Req, true)
+			dump, err := DumpRequestOut(&tt.Req, !tt.NoBody)
 			if err != nil {
 				t.Errorf("DumpRequestOut #%d: %s", i, err)
 				continue
diff -r 827fb5004620 libgo/go/net/parse.go
--- a/libgo/go/net/parse.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/net/parse.go	Tue Nov 26 16:47:25 2013 -0800
@@ -54,7 +54,7 @@ 
 		if n >= 0 {
 			f.data = f.data[0 : ln+n]
 		}
-		if err == io.EOF {
+		if err == io.EOF || err == io.ErrUnexpectedEOF {
 			f.atEOF = true
 		}
 	}
diff -r 827fb5004620 libgo/go/net/testdata/hosts_singleline
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgo/go/net/testdata/hosts_singleline	Tue Nov 26 16:47:25 2013 -0800
@@ -0,0 +1,1 @@ 
+127.0.0.2	odin
\ No newline at end of file
diff -r 827fb5004620 libgo/go/net/textproto/reader.go
--- a/libgo/go/net/textproto/reader.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/net/textproto/reader.go	Tue Nov 26 16:47:25 2013 -0800
@@ -574,13 +574,10 @@ 
 		// and upper case after each dash.
 		// (Host, User-Agent, If-Modified-Since).
 		// MIME headers are ASCII only, so no Unicode issues.
-		if a[i] == ' ' {
-			a[i] = '-'
-			upper = true
-			continue
-		}
 		c := a[i]
-		if upper && 'a' <= c && c <= 'z' {
+		if c == ' ' {
+			c = '-'
+		} else if upper && 'a' <= c && c <= 'z' {
 			c -= toLower
 		} else if !upper && 'A' <= c && c <= 'Z' {
 			c += toLower
diff -r 827fb5004620 libgo/go/net/textproto/reader_test.go
--- a/libgo/go/net/textproto/reader_test.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/net/textproto/reader_test.go	Tue Nov 26 16:47:25 2013 -0800
@@ -25,6 +25,10 @@ 
 	{"user-agent", "User-Agent"},
 	{"USER-AGENT", "User-Agent"},
 	{"üser-agenT", "üser-Agent"}, // non-ASCII unchanged
+
+	// This caused a panic due to mishandling of a space:
+	{"C Ontent-Transfer-Encoding", "C-Ontent-Transfer-Encoding"},
+	{"foo bar", "Foo-Bar"},
 }
 
 func TestCanonicalMIMEHeaderKey(t *testing.T) {
diff -r 827fb5004620 libgo/go/net/url/url.go
--- a/libgo/go/net/url/url.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/net/url/url.go	Tue Nov 26 16:47:25 2013 -0800
@@ -558,8 +558,8 @@ 
 	return err
 }
 
-// Encode encodes the values into ``URL encoded'' form.
-// e.g. "foo=bar&bar=baz"
+// Encode encodes the values into ``URL encoded'' form
+// ("bar=baz&foo=quux") sorted by key.
 func (v Values) Encode() string {
 	if v == nil {
 		return ""
diff -r 827fb5004620 libgo/go/os/file_unix.go
--- a/libgo/go/os/file_unix.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/os/file_unix.go	Tue Nov 26 16:47:25 2013 -0800
@@ -176,14 +176,11 @@ 
 	fi = make([]FileInfo, len(names))
 	for i, filename := range names {
 		fip, lerr := lstat(dirname + filename)
-		if lerr == nil {
-			fi[i] = fip
-		} else {
+		if lerr != nil {
 			fi[i] = &fileStat{name: filename}
-			if err == nil {
-				err = lerr
-			}
+			continue
 		}
+		fi[i] = fip
 	}
 	return fi, err
 }
diff -r 827fb5004620 libgo/go/os/os_unix_test.go
--- a/libgo/go/os/os_unix_test.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/os/os_unix_test.go	Tue Nov 26 16:47:25 2013 -0800
@@ -92,8 +92,8 @@ 
 	defer func() { *LstatP = Lstat }()
 
 	dirs, err := handle.Readdir(-1)
-	if err != ErrInvalid {
-		t.Fatalf("Expected Readdir to return ErrInvalid, got %v", err)
+	if err != nil {
+		t.Fatalf("Expected Readdir to return no error, got %v", err)
 	}
 	foundfail := false
 	for _, dir := range dirs {
diff -r 827fb5004620 libgo/go/runtime/pprof/pprof_test.go
--- a/libgo/go/runtime/pprof/pprof_test.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/runtime/pprof/pprof_test.go	Tue Nov 26 16:47:25 2013 -0800
@@ -8,6 +8,7 @@ 
 	"bytes"
 	"fmt"
 	"hash/crc32"
+	"math/big"
 	"os/exec"
 	"regexp"
 	"runtime"
@@ -123,6 +124,10 @@ 
 		}
 	})
 
+	if len(need) == 0 {
+		return
+	}
+
 	var total uintptr
 	for i, name := range need {
 		total += have[i]
@@ -237,6 +242,26 @@ 
 	}
 }
 
+// Test that profiling of division operations is okay, especially on ARM. See issue 6681.
+func TestMathBigDivide(t *testing.T) {
+	testCPUProfile(t, nil, func() {
+		t := time.After(5 * time.Second)
+		pi := new(big.Int)
+		for {
+			for i := 0; i < 100; i++ {
+				n := big.NewInt(2646693125139304345)
+				d := big.NewInt(842468587426513207)
+				pi.Div(n, d)
+			}
+			select {
+			case <-t:
+				return
+			default:
+			}
+		}
+	})
+}
+
 // Operating systems that are expected to fail the tests. See issue 6047.
 var badOS = map[string]bool{
 	"darwin":  true,
diff -r 827fb5004620 libgo/go/strings/replace.go
--- a/libgo/go/strings/replace.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/strings/replace.go	Tue Nov 26 16:47:25 2013 -0800
@@ -364,17 +364,18 @@ 
 
 func (r *singleStringReplacer) Replace(s string) string {
 	var buf []byte
-	i := 0
+	i, matched := 0, false
 	for {
 		match := r.finder.next(s[i:])
 		if match == -1 {
 			break
 		}
+		matched = true
 		buf = append(buf, s[i:i+match]...)
 		buf = append(buf, r.value...)
 		i += match + len(r.finder.pattern)
 	}
-	if buf == nil {
+	if !matched {
 		return s
 	}
 	buf = append(buf, s[i:]...)
diff -r 827fb5004620 libgo/go/strings/replace_test.go
--- a/libgo/go/strings/replace_test.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/strings/replace_test.go	Tue Nov 26 16:47:25 2013 -0800
@@ -261,10 +261,21 @@ 
 	testCases = append(testCases,
 		testCase{abcMatcher, "", ""},
 		testCase{abcMatcher, "ab", "ab"},
+		testCase{abcMatcher, "abc", "[match]"},
 		testCase{abcMatcher, "abcd", "[match]d"},
 		testCase{abcMatcher, "cabcabcdabca", "c[match][match]d[match]a"},
 	)
 
+	// Issue 6659 cases (more single string replacer)
+
+	noHello := NewReplacer("Hello", "")
+	testCases = append(testCases,
+		testCase{noHello, "Hello", ""},
+		testCase{noHello, "Hellox", "x"},
+		testCase{noHello, "xHello", "x"},
+		testCase{noHello, "xHellox", "xx"},
+	)
+
 	// No-arg test cases.
 
 	nop := NewReplacer()
diff -r 827fb5004620 libgo/go/testing/testing.go
--- a/libgo/go/testing/testing.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/testing/testing.go	Tue Nov 26 16:47:25 2013 -0800
@@ -73,17 +73,19 @@ 
 //
 // Example functions without output comments are compiled but not executed.
 //
-// The naming convention to declare examples for a function F, a type T and
+// The naming convention to declare examples for the package, a function F, a type T and
 // method M on type T are:
 //
+//     func Example() { ... }
 //     func ExampleF() { ... }
 //     func ExampleT() { ... }
 //     func ExampleT_M() { ... }
 //
-// Multiple example functions for a type/function/method may be provided by
+// Multiple example functions for a package/type/function/method may be provided by
 // appending a distinct suffix to the name. The suffix must start with a
 // lower-case letter.
 //
+//     func Example_suffix() { ... }
 //     func ExampleF_suffix() { ... }
 //     func ExampleT_suffix() { ... }
 //     func ExampleT_M_suffix() { ... }
diff -r 827fb5004620 libgo/go/time/export_test.go
--- a/libgo/go/time/export_test.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/time/export_test.go	Tue Nov 26 16:47:25 2013 -0800
@@ -18,4 +18,7 @@ 
 	localOnce.Do(initTestingZone)
 }
 
-var ParseTimeZone = parseTimeZone
+var (
+	ForceZipFileForTesting = forceZipFileForTesting
+	ParseTimeZone          = parseTimeZone
+)
diff -r 827fb5004620 libgo/go/time/time_test.go
--- a/libgo/go/time/time_test.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/time/time_test.go	Tue Nov 26 16:47:25 2013 -0800
@@ -578,6 +578,18 @@ 
 	}
 }
 
+func TestLoadLocationZipFile(t *testing.T) {
+	t.Skip("gccgo does not use the zip file")
+
+	ForceZipFileForTesting(true)
+	defer ForceZipFileForTesting(false)
+
+	_, err := LoadLocation("Australia/Sydney")
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
 var rubyTests = []ParseTest{
 	{"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0800 2010", true, true, 1, 0},
 	// Ignore the time zone in the test. If it parses, it'll be OK.
diff -r 827fb5004620 libgo/go/time/zoneinfo_plan9.go
--- a/libgo/go/time/zoneinfo_plan9.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/time/zoneinfo_plan9.go	Tue Nov 26 16:47:25 2013 -0800
@@ -154,3 +154,7 @@ 
 	}
 	return nil, errors.New("unknown time zone " + name)
 }
+
+func forceZipFileForTesting(zipOnly bool) {
+	// We only use the zip file anyway.
+}
diff -r 827fb5004620 libgo/go/time/zoneinfo_unix.go
--- a/libgo/go/time/zoneinfo_unix.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/time/zoneinfo_unix.go	Tue Nov 26 16:47:25 2013 -0800
@@ -28,7 +28,19 @@ 
 	"/usr/share/zoneinfo/",
 	"/usr/share/lib/zoneinfo/",
 	"/usr/lib/locale/TZ/",
-	runtime.GOROOT() + "/lib/time/zoneinfo/",
+	runtime.GOROOT() + "/lib/time/zoneinfo.zip",
+}
+
+var origZoneDirs = zoneDirs
+
+func forceZipFileForTesting(zipOnly bool) {
+	zoneDirs = make([]string, len(origZoneDirs))
+	copy(zoneDirs, origZoneDirs)
+	if zipOnly {
+		for i := 0; i < len(zoneDirs)-1; i++ {
+			zoneDirs[i] = "/XXXNOEXIST"
+		}
+	}
 }
 
 func initLocal() {
diff -r 827fb5004620 libgo/go/time/zoneinfo_windows.go
--- a/libgo/go/time/zoneinfo_windows.go	Tue Nov 26 15:22:17 2013 -0800
+++ b/libgo/go/time/zoneinfo_windows.go	Tue Nov 26 16:47:25 2013 -0800
@@ -264,3 +264,7 @@ 
 	}
 	return nil, errors.New("unknown time zone " + name)
 }
+
+func forceZipFileForTesting(zipOnly bool) {
+	// We only use the zip file anyway.
+}