diff mbox series

libgo patch committed: Update to 1.11.1 release

Message ID CAOyqgcUvB-kdRrroQinesh6YoN6fntbRCpxbGUDk=bkKdOL4OA@mail.gmail.com
State New
Headers show
Series libgo patch committed: Update to 1.11.1 release | expand

Commit Message

Ian Lance Taylor Oct. 8, 2018, 2:21 p.m. UTC
This patch updates libgo to the 1.11.1 release.  Bootstrapped and ran
Go testsuite on x86_64-pc-linux-gnu.  Committed to mainline.

Ian
diff mbox series

Patch

Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 264882)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@ 
-d0739c13ca3686df1f8d0fae7c6c5caaed058503
+a9da4d34a2f878a5058f7e7d2beef52aa62471a1
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: libgo/MERGE
===================================================================
--- libgo/MERGE	(revision 264813)
+++ libgo/MERGE	(working copy)
@@ -1,4 +1,4 @@ 
-41e62b8c49d21659b48a95216e3062032285250f
+26957168c4c0cdcc7ca4f0b19d0eb19474d224ac
 
 The first line of this file holds the git revision number of the
 last merge done from the master library sources.
Index: libgo/VERSION
===================================================================
--- libgo/VERSION	(revision 264813)
+++ libgo/VERSION	(working copy)
@@ -1 +1 @@ 
-go1.11
+go1.11.1
Index: libgo/go/cmd/go/alldocs.go
===================================================================
--- libgo/go/cmd/go/alldocs.go	(revision 264813)
+++ libgo/go/cmd/go/alldocs.go	(working copy)
@@ -1449,6 +1449,12 @@ 
 // 		The directory where the go command will write
 // 		temporary source files, packages, and binaries.
 //
+// Each entry in the GOFLAGS list must be a standalone flag.
+// Because the entries are space-separated, flag values must
+// not contain spaces. In some cases, you can provide multiple flag
+// values instead: for example, to set '-ldflags=-s -w'
+// you can use 'GOFLAGS=-ldflags=-s -ldflags=-w'.
+//
 // Environment variables for use with cgo:
 //
 // 	CC
Index: libgo/go/cmd/go/internal/help/helpdoc.go
===================================================================
--- libgo/go/cmd/go/internal/help/helpdoc.go	(revision 264813)
+++ libgo/go/cmd/go/internal/help/helpdoc.go	(working copy)
@@ -507,6 +507,12 @@  General-purpose environment variables:
 		The directory where the go command will write
 		temporary source files, packages, and binaries.
 
+Each entry in the GOFLAGS list must be a standalone flag.
+Because the entries are space-separated, flag values must
+not contain spaces. In some cases, you can provide multiple flag
+values instead: for example, to set '-ldflags=-s -w'
+you can use 'GOFLAGS=-ldflags=-s -ldflags=-w'.
+
 Environment variables for use with cgo:
 
 	CC
Index: libgo/go/cmd/go/internal/work/exec.go
===================================================================
--- libgo/go/cmd/go/internal/work/exec.go	(revision 264813)
+++ libgo/go/cmd/go/internal/work/exec.go	(working copy)
@@ -224,7 +224,9 @@  func (b *Builder) buildActionID(a *Actio
 		if len(p.SFiles) > 0 {
 			fmt.Fprintf(h, "asm %q %q %q\n", b.toolID("asm"), forcedAsmflags, p.Internal.Asmflags)
 		}
-		fmt.Fprintf(h, "GO$GOARCH=%s\n", os.Getenv("GO"+strings.ToUpper(cfg.BuildContext.GOARCH))) // GO386, GOARM, etc
+		// GO386, GOARM, GOMIPS, etc.
+		baseArch := strings.TrimSuffix(cfg.BuildContext.GOARCH, "le")
+		fmt.Fprintf(h, "GO$GOARCH=%s\n", os.Getenv("GO"+strings.ToUpper(baseArch)))
 
 		// TODO(rsc): Convince compiler team not to add more magic environment variables,
 		// or perhaps restrict the environment variables passed to subprocesses.
Index: libgo/go/cmd/go/internal/work/security.go
===================================================================
--- libgo/go/cmd/go/internal/work/security.go	(revision 264813)
+++ libgo/go/cmd/go/internal/work/security.go	(working copy)
@@ -170,6 +170,7 @@  var validLinkerFlags = []*regexp.Regexp{
 	re(`-Wl,-e[=,][a-zA-Z0-9]*`),
 	re(`-Wl,--enable-new-dtags`),
 	re(`-Wl,--end-group`),
+	re(`-Wl,--(no-)?export-dynamic`),
 	re(`-Wl,-framework,[^,@\-][^,]+`),
 	re(`-Wl,-headerpad_max_install_names`),
 	re(`-Wl,--no-undefined`),
Index: libgo/go/cmd/go/script_test.go
===================================================================
--- libgo/go/cmd/go/script_test.go	(revision 264813)
+++ libgo/go/cmd/go/script_test.go	(working copy)
@@ -635,6 +635,9 @@  func scriptMatch(ts *testScript, neg boo
 		text = string(data)
 	}
 
+	// Matching against workdir would be misleading.
+	text = strings.Replace(text, ts.workdir, "$WORK", -1)
+
 	if neg {
 		if re.MatchString(text) {
 			if isGrep {
Index: libgo/go/crypto/x509/verify.go
===================================================================
--- libgo/go/crypto/x509/verify.go	(revision 264813)
+++ libgo/go/crypto/x509/verify.go	(working copy)
@@ -894,8 +894,8 @@  func validHostname(host string) bool {
 			if c == '-' && j != 0 {
 				continue
 			}
-			if c == '_' {
-				// _ is not a valid character in hostnames, but it's commonly
+			if c == '_' || c == ':' {
+				// Not valid characters in hostnames, but commonly
 				// found in deployments outside the WebPKI.
 				continue
 			}
Index: libgo/go/crypto/x509/verify_test.go
===================================================================
--- libgo/go/crypto/x509/verify_test.go	(revision 264813)
+++ libgo/go/crypto/x509/verify_test.go	(working copy)
@@ -1881,6 +1881,7 @@  func TestValidHostname(t *testing.T) {
 		{"foo.*.example.com", false},
 		{"exa_mple.com", true},
 		{"foo,bar", false},
+		{"project-dev:us-central1:main", true},
 	}
 	for _, tt := range tests {
 		if got := validHostname(tt.host); got != tt.want {
Index: libgo/go/encoding/json/decode.go
===================================================================
--- libgo/go/encoding/json/decode.go	(revision 264813)
+++ libgo/go/encoding/json/decode.go	(working copy)
@@ -672,6 +672,7 @@  func (d *decodeState) object(v reflect.V
 	}
 
 	var mapElem reflect.Value
+	originalErrorContext := d.errorContext
 
 	for {
 		// Read opening " of string key or closing }.
@@ -832,8 +833,7 @@  func (d *decodeState) object(v reflect.V
 			return errPhase
 		}
 
-		d.errorContext.Struct = ""
-		d.errorContext.Field = ""
+		d.errorContext = originalErrorContext
 	}
 	return nil
 }
@@ -991,7 +991,7 @@  func (d *decodeState) literalStore(item
 			if fromQuoted {
 				return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())
 			}
-			return &UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())}
+			d.saveError(&UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())})
 		case reflect.Interface:
 			n, err := d.convertNumber(s)
 			if err != nil {
Index: libgo/go/encoding/json/decode_test.go
===================================================================
--- libgo/go/encoding/json/decode_test.go	(revision 264813)
+++ libgo/go/encoding/json/decode_test.go	(working copy)
@@ -371,6 +371,10 @@  func (b *intWithPtrMarshalText) Unmarsha
 	return (*intWithMarshalText)(b).UnmarshalText(data)
 }
 
+type mapStringToStringData struct {
+	Data map[string]string `json:"data"`
+}
+
 type unmarshalTest struct {
 	in                    string
 	ptr                   interface{}
@@ -401,6 +405,7 @@  var unmarshalTests = []unmarshalTest{
 	{in: `"invalid: \uD834x\uDD1E"`, ptr: new(string), out: "invalid: \uFFFDx\uFFFD"},
 	{in: "null", ptr: new(interface{}), out: nil},
 	{in: `{"X": [1,2,3], "Y": 4}`, ptr: new(T), out: T{Y: 4}, err: &UnmarshalTypeError{"array", reflect.TypeOf(""), 7, "T", "X"}},
+	{in: `{"X": 23}`, ptr: new(T), out: T{}, err: &UnmarshalTypeError{"number", reflect.TypeOf(""), 8, "T", "X"}}, {in: `{"x": 1}`, ptr: new(tx), out: tx{}},
 	{in: `{"x": 1}`, ptr: new(tx), out: tx{}},
 	{in: `{"x": 1}`, ptr: new(tx), err: fmt.Errorf("json: unknown field \"x\""), disallowUnknownFields: true},
 	{in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: float64(1), F2: int32(2), F3: Number("3")}},
@@ -866,6 +871,18 @@  var unmarshalTests = []unmarshalTest{
 		err:                   fmt.Errorf("json: unknown field \"extra\""),
 		disallowUnknownFields: true,
 	},
+	// issue 26444
+	// UnmarshalTypeError without field & struct values
+	{
+		in:  `{"data":{"test1": "bob", "test2": 123}}`,
+		ptr: new(mapStringToStringData),
+		err: &UnmarshalTypeError{Value: "number", Type: reflect.TypeOf(""), Offset: 37, Struct: "mapStringToStringData", Field: "data"},
+	},
+	{
+		in:  `{"data":{"test1": 123, "test2": "bob"}}`,
+		ptr: new(mapStringToStringData),
+		err: &UnmarshalTypeError{Value: "number", Type: reflect.TypeOf(""), Offset: 21, Struct: "mapStringToStringData", Field: "data"},
+	},
 }
 
 func TestMarshal(t *testing.T) {
Index: libgo/go/go/types/api_test.go
===================================================================
--- libgo/go/go/types/api_test.go	(revision 264813)
+++ libgo/go/go/types/api_test.go	(working copy)
@@ -262,6 +262,8 @@  func TestTypesInfo(t *testing.T) {
 		{`package x0; func _() { var x struct {f string}; x.f := 0 }`, `x.f`, `string`},
 		{`package x1; func _() { var z string; type x struct {f string}; y := &x{q: z}}`, `z`, `string`},
 		{`package x2; func _() { var a, b string; type x struct {f string}; z := &x{f: a; f: b;}}`, `b`, `string`},
+		{`package x3; var x = panic("");`, `panic`, `func(interface{})`},
+		{`package x4; func _() { panic("") }`, `panic`, `func(interface{})`},
 	}
 
 	for _, test := range tests {
Index: libgo/go/go/types/builtins.go
===================================================================
--- libgo/go/go/types/builtins.go	(revision 264813)
+++ libgo/go/go/types/builtins.go	(working copy)
@@ -476,7 +476,7 @@  func (check *Checker) builtin(x *operand
 		// panic(x)
 		// record panic call if inside a function with result parameters
 		// (for use in Checker.isTerminating)
-		if check.sig.results.Len() > 0 {
+		if check.sig != nil && check.sig.results.Len() > 0 {
 			// function has result parameters
 			p := check.isPanic
 			if p == nil {
Index: libgo/go/net/dnsclient_unix.go
===================================================================
--- libgo/go/net/dnsclient_unix.go	(revision 264813)
+++ libgo/go/net/dnsclient_unix.go	(working copy)
@@ -27,6 +27,20 @@  import (
 	"golang_org/x/net/dns/dnsmessage"
 )
 
+var (
+	errLameReferral              = errors.New("lame referral")
+	errCannotUnmarshalDNSMessage = errors.New("cannot unmarshal DNS message")
+	errCannotMarshalDNSMessage   = errors.New("cannot marshal DNS message")
+	errServerMisbehaving         = errors.New("server misbehaving")
+	errInvalidDNSResponse        = errors.New("invalid DNS response")
+	errNoAnswerFromDNSServer     = errors.New("no answer from DNS server")
+
+	// errServerTemporarlyMisbehaving is like errServerMisbehaving, except
+	// that when it gets translated to a DNSError, the IsTemporary field
+	// gets set to true.
+	errServerTemporarlyMisbehaving = errors.New("server misbehaving")
+)
+
 func newRequest(q dnsmessage.Question) (id uint16, udpReq, tcpReq []byte, err error) {
 	id = uint16(rand.Int()) ^ uint16(time.Now().UnixNano())
 	b := dnsmessage.NewBuilder(make([]byte, 2, 514), dnsmessage.Header{ID: id, RecursionDesired: true})
@@ -105,14 +119,14 @@  func dnsStreamRoundTrip(c Conn, id uint1
 	var p dnsmessage.Parser
 	h, err := p.Start(b[:n])
 	if err != nil {
-		return dnsmessage.Parser{}, dnsmessage.Header{}, errors.New("cannot unmarshal DNS message")
+		return dnsmessage.Parser{}, dnsmessage.Header{}, errCannotUnmarshalDNSMessage
 	}
 	q, err := p.Question()
 	if err != nil {
-		return dnsmessage.Parser{}, dnsmessage.Header{}, errors.New("cannot unmarshal DNS message")
+		return dnsmessage.Parser{}, dnsmessage.Header{}, errCannotUnmarshalDNSMessage
 	}
 	if !checkResponse(id, query, h, q) {
-		return dnsmessage.Parser{}, dnsmessage.Header{}, errors.New("invalid DNS response")
+		return dnsmessage.Parser{}, dnsmessage.Header{}, errInvalidDNSResponse
 	}
 	return p, h, nil
 }
@@ -122,7 +136,7 @@  func (r *Resolver) exchange(ctx context.
 	q.Class = dnsmessage.ClassINET
 	id, udpReq, tcpReq, err := newRequest(q)
 	if err != nil {
-		return dnsmessage.Parser{}, dnsmessage.Header{}, errors.New("cannot marshal DNS message")
+		return dnsmessage.Parser{}, dnsmessage.Header{}, errCannotMarshalDNSMessage
 	}
 	for _, network := range []string{"udp", "tcp"} {
 		ctx, cancel := context.WithDeadline(ctx, time.Now().Add(timeout))
@@ -147,31 +161,31 @@  func (r *Resolver) exchange(ctx context.
 			return dnsmessage.Parser{}, dnsmessage.Header{}, mapErr(err)
 		}
 		if err := p.SkipQuestion(); err != dnsmessage.ErrSectionDone {
-			return dnsmessage.Parser{}, dnsmessage.Header{}, errors.New("invalid DNS response")
+			return dnsmessage.Parser{}, dnsmessage.Header{}, errInvalidDNSResponse
 		}
 		if h.Truncated { // see RFC 5966
 			continue
 		}
 		return p, h, nil
 	}
-	return dnsmessage.Parser{}, dnsmessage.Header{}, errors.New("no answer from DNS server")
+	return dnsmessage.Parser{}, dnsmessage.Header{}, errNoAnswerFromDNSServer
 }
 
 // checkHeader performs basic sanity checks on the header.
 func checkHeader(p *dnsmessage.Parser, h dnsmessage.Header, name, server string) error {
+	if h.RCode == dnsmessage.RCodeNameError {
+		return errNoSuchHost
+	}
+
 	_, err := p.AnswerHeader()
 	if err != nil && err != dnsmessage.ErrSectionDone {
-		return &DNSError{
-			Err:    "cannot unmarshal DNS message",
-			Name:   name,
-			Server: server,
-		}
+		return errCannotUnmarshalDNSMessage
 	}
 
 	// libresolv continues to the next server when it receives
 	// an invalid referral response. See golang.org/issue/15434.
 	if h.RCode == dnsmessage.RCodeSuccess && !h.Authoritative && !h.RecursionAvailable && err == dnsmessage.ErrSectionDone {
-		return &DNSError{Err: "lame referral", Name: name, Server: server}
+		return errLameReferral
 	}
 
 	if h.RCode != dnsmessage.RCodeSuccess && h.RCode != dnsmessage.RCodeNameError {
@@ -180,11 +194,10 @@  func checkHeader(p *dnsmessage.Parser, h
 		// a name error and we didn't get success,
 		// the server is behaving incorrectly or
 		// having temporary trouble.
-		err := &DNSError{Err: "server misbehaving", Name: name, Server: server}
 		if h.RCode == dnsmessage.RCodeServerFailure {
-			err.IsTemporary = true
+			return errServerTemporarlyMisbehaving
 		}
-		return err
+		return errServerMisbehaving
 	}
 
 	return nil
@@ -194,28 +207,16 @@  func skipToAnswer(p *dnsmessage.Parser,
 	for {
 		h, err := p.AnswerHeader()
 		if err == dnsmessage.ErrSectionDone {
-			return &DNSError{
-				Err:    errNoSuchHost.Error(),
-				Name:   name,
-				Server: server,
-			}
+			return errNoSuchHost
 		}
 		if err != nil {
-			return &DNSError{
-				Err:    "cannot unmarshal DNS message",
-				Name:   name,
-				Server: server,
-			}
+			return errCannotUnmarshalDNSMessage
 		}
 		if h.Type == qtype {
 			return nil
 		}
 		if err := p.SkipAnswer(); err != nil {
-			return &DNSError{
-				Err:    "cannot unmarshal DNS message",
-				Name:   name,
-				Server: server,
-			}
+			return errCannotUnmarshalDNSMessage
 		}
 	}
 }
@@ -229,7 +230,7 @@  func (r *Resolver) tryOneName(ctx contex
 
 	n, err := dnsmessage.NewName(name)
 	if err != nil {
-		return dnsmessage.Parser{}, "", errors.New("cannot marshal DNS message")
+		return dnsmessage.Parser{}, "", errCannotMarshalDNSMessage
 	}
 	q := dnsmessage.Question{
 		Name:  n,
@@ -243,38 +244,62 @@  func (r *Resolver) tryOneName(ctx contex
 
 			p, h, err := r.exchange(ctx, server, q, cfg.timeout)
 			if err != nil {
-				lastErr = &DNSError{
+				dnsErr := &DNSError{
 					Err:    err.Error(),
 					Name:   name,
 					Server: server,
 				}
 				if nerr, ok := err.(Error); ok && nerr.Timeout() {
-					lastErr.(*DNSError).IsTimeout = true
+					dnsErr.IsTimeout = true
 				}
 				// Set IsTemporary for socket-level errors. Note that this flag
 				// may also be used to indicate a SERVFAIL response.
 				if _, ok := err.(*OpError); ok {
-					lastErr.(*DNSError).IsTemporary = true
+					dnsErr.IsTemporary = true
 				}
+				lastErr = dnsErr
 				continue
 			}
 
-			// The name does not exist, so trying another server won't help.
-			//
-			// TODO: indicate this in a more obvious way, such as a field on DNSError?
-			if h.RCode == dnsmessage.RCodeNameError {
-				return dnsmessage.Parser{}, "", &DNSError{Err: errNoSuchHost.Error(), Name: name, Server: server}
-			}
-
-			lastErr = checkHeader(&p, h, name, server)
-			if lastErr != nil {
+			if err := checkHeader(&p, h, name, server); err != nil {
+				dnsErr := &DNSError{
+					Err:    err.Error(),
+					Name:   name,
+					Server: server,
+				}
+				if err == errServerTemporarlyMisbehaving {
+					dnsErr.IsTemporary = true
+				}
+				if err == errNoSuchHost {
+					// The name does not exist, so trying
+					// another server won't help.
+					//
+					// TODO: indicate this in a more
+					// obvious way, such as a field on
+					// DNSError?
+					return p, server, dnsErr
+				}
+				lastErr = dnsErr
 				continue
 			}
 
-			lastErr = skipToAnswer(&p, qtype, name, server)
-			if lastErr == nil {
+			err = skipToAnswer(&p, qtype, name, server)
+			if err == nil {
 				return p, server, nil
 			}
+			lastErr = &DNSError{
+				Err:    err.Error(),
+				Name:   name,
+				Server: server,
+			}
+			if err == errNoSuchHost {
+				// The name does not exist, so trying another
+				// server won't help.
+				//
+				// TODO: indicate this in a more obvious way,
+				// such as a field on DNSError?
+				return p, server, lastErr
+			}
 		}
 	}
 	return dnsmessage.Parser{}, "", lastErr
Index: libgo/go/net/dnsclient_unix_test.go
===================================================================
--- libgo/go/net/dnsclient_unix_test.go	(revision 264813)
+++ libgo/go/net/dnsclient_unix_test.go	(working copy)
@@ -1427,28 +1427,35 @@  func TestDNSGoroutineRace(t *testing.T)
 	}
 }
 
+func lookupWithFake(fake fakeDNSServer, name string, typ dnsmessage.Type) error {
+	r := Resolver{PreferGo: true, Dial: fake.DialContext}
+
+	resolvConf.mu.RLock()
+	conf := resolvConf.dnsConfig
+	resolvConf.mu.RUnlock()
+
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	_, _, err := r.tryOneName(ctx, conf, name, typ)
+	return err
+}
+
 // Issue 8434: verify that Temporary returns true on an error when rcode
 // is SERVFAIL
 func TestIssue8434(t *testing.T) {
-	msg := dnsmessage.Message{
-		Header: dnsmessage.Header{
-			RCode: dnsmessage.RCodeServerFailure,
+	err := lookupWithFake(fakeDNSServer{
+		rh: func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) {
+			return dnsmessage.Message{
+				Header: dnsmessage.Header{
+					ID:       q.ID,
+					Response: true,
+					RCode:    dnsmessage.RCodeServerFailure,
+				},
+				Questions: q.Questions,
+			}, nil
 		},
-	}
-	b, err := msg.Pack()
-	if err != nil {
-		t.Fatal("Pack failed:", err)
-	}
-	var p dnsmessage.Parser
-	h, err := p.Start(b)
-	if err != nil {
-		t.Fatal("Start failed:", err)
-	}
-	if err := p.SkipAllQuestions(); err != nil {
-		t.Fatal("SkipAllQuestions failed:", err)
-	}
-
-	err = checkHeader(&p, h, "golang.org", "foo:53")
+	}, "golang.org.", dnsmessage.TypeALL)
 	if err == nil {
 		t.Fatal("expected an error")
 	}
@@ -1464,50 +1471,76 @@  func TestIssue8434(t *testing.T) {
 	}
 }
 
-// Issue 12778: verify that NXDOMAIN without RA bit errors as
-// "no such host" and not "server misbehaving"
+// TestNoSuchHost verifies that tryOneName works correctly when the domain does
+// not exist.
+//
+// Issue 12778: verify that NXDOMAIN without RA bit errors as "no such host"
+// and not "server misbehaving"
 //
 // Issue 25336: verify that NXDOMAIN errors fail fast.
-func TestIssue12778(t *testing.T) {
-	lookups := 0
-	fake := fakeDNSServer{
-		rh: func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) {
-			lookups++
-			return dnsmessage.Message{
-				Header: dnsmessage.Header{
-					ID:                 q.ID,
-					Response:           true,
-					RCode:              dnsmessage.RCodeNameError,
-					RecursionAvailable: false,
-				},
-				Questions: q.Questions,
-			}, nil
+//
+// Issue 27525: verify that empty answers fail fast.
+func TestNoSuchHost(t *testing.T) {
+	tests := []struct {
+		name string
+		f    func(string, string, dnsmessage.Message, time.Time) (dnsmessage.Message, error)
+	}{
+		{
+			"NXDOMAIN",
+			func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) {
+				return dnsmessage.Message{
+					Header: dnsmessage.Header{
+						ID:                 q.ID,
+						Response:           true,
+						RCode:              dnsmessage.RCodeNameError,
+						RecursionAvailable: false,
+					},
+					Questions: q.Questions,
+				}, nil
+			},
+		},
+		{
+			"no answers",
+			func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) {
+				return dnsmessage.Message{
+					Header: dnsmessage.Header{
+						ID:                 q.ID,
+						Response:           true,
+						RCode:              dnsmessage.RCodeSuccess,
+						RecursionAvailable: false,
+						Authoritative:      true,
+					},
+					Questions: q.Questions,
+				}, nil
+			},
 		},
 	}
-	r := Resolver{PreferGo: true, Dial: fake.DialContext}
-
-	resolvConf.mu.RLock()
-	conf := resolvConf.dnsConfig
-	resolvConf.mu.RUnlock()
-
-	ctx, cancel := context.WithCancel(context.Background())
-	defer cancel()
 
-	_, _, err := r.tryOneName(ctx, conf, ".", dnsmessage.TypeALL)
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			lookups := 0
+			err := lookupWithFake(fakeDNSServer{
+				rh: func(n, s string, q dnsmessage.Message, d time.Time) (dnsmessage.Message, error) {
+					lookups++
+					return test.f(n, s, q, d)
+				},
+			}, ".", dnsmessage.TypeALL)
 
-	if lookups != 1 {
-		t.Errorf("got %d lookups, wanted 1", lookups)
-	}
+			if lookups != 1 {
+				t.Errorf("got %d lookups, wanted 1", lookups)
+			}
 
-	if err == nil {
-		t.Fatal("expected an error")
-	}
-	de, ok := err.(*DNSError)
-	if !ok {
-		t.Fatalf("err = %#v; wanted a *net.DNSError", err)
-	}
-	if de.Err != errNoSuchHost.Error() {
-		t.Fatalf("Err = %#v; wanted %q", de.Err, errNoSuchHost.Error())
+			if err == nil {
+				t.Fatal("expected an error")
+			}
+			de, ok := err.(*DNSError)
+			if !ok {
+				t.Fatalf("err = %#v; wanted a *net.DNSError", err)
+			}
+			if de.Err != errNoSuchHost.Error() {
+				t.Fatalf("Err = %#v; wanted %q", de.Err, errNoSuchHost.Error())
+			}
+		})
 	}
 }
 
@@ -1535,3 +1568,56 @@  func TestDNSDialTCP(t *testing.T) {
 		t.Fatal("exhange failed:", err)
 	}
 }
+
+// Issue 27763: verify that two strings in one TXT record are concatenated.
+func TestTXTRecordTwoStrings(t *testing.T) {
+	fake := fakeDNSServer{
+		rh: func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) {
+			r := dnsmessage.Message{
+				Header: dnsmessage.Header{
+					ID:       q.Header.ID,
+					Response: true,
+					RCode:    dnsmessage.RCodeSuccess,
+				},
+				Questions: q.Questions,
+				Answers: []dnsmessage.Resource{
+					{
+						Header: dnsmessage.ResourceHeader{
+							Name:  q.Questions[0].Name,
+							Type:  dnsmessage.TypeA,
+							Class: dnsmessage.ClassINET,
+						},
+						Body: &dnsmessage.TXTResource{
+							TXT: []string{"string1 ", "string2"},
+						},
+					},
+					{
+						Header: dnsmessage.ResourceHeader{
+							Name:  q.Questions[0].Name,
+							Type:  dnsmessage.TypeA,
+							Class: dnsmessage.ClassINET,
+						},
+						Body: &dnsmessage.TXTResource{
+							TXT: []string{"onestring"},
+						},
+					},
+				},
+			}
+			return r, nil
+		},
+	}
+	r := Resolver{PreferGo: true, Dial: fake.DialContext}
+	txt, err := r.lookupTXT(context.Background(), "golang.org")
+	if err != nil {
+		t.Fatal("LookupTXT failed:", err)
+	}
+	if want := 2; len(txt) != want {
+		t.Fatalf("len(txt), got %d, want %d", len(txt), want)
+	}
+	if want := "string1 string2"; txt[0] != want {
+		t.Errorf("txt[0], got %q, want %q", txt[0], want)
+	}
+	if want := "onestring"; txt[1] != want {
+		t.Errorf("txt[1], got %q, want %q", txt[1], want)
+	}
+}
Index: libgo/go/net/http/roundtrip_js.go
===================================================================
--- libgo/go/net/http/roundtrip_js.go	(revision 264813)
+++ libgo/go/net/http/roundtrip_js.go	(working copy)
@@ -116,7 +116,9 @@  func (t *Transport) RoundTrip(req *Reque
 
 		b := result.Get("body")
 		var body io.ReadCloser
-		if b != js.Undefined() {
+		// The body is undefined when the browser does not support streaming response bodies (Firefox),
+		// and null in certain error cases, i.e. when the request is blocked because of CORS settings.
+		if b != js.Undefined() && b != js.Null() {
 			body = &streamReader{stream: b.Call("getReader")}
 		} else {
 			// Fall back to using ArrayBuffer
Index: libgo/go/net/lookup_unix.go
===================================================================
--- libgo/go/net/lookup_unix.go	(revision 264813)
+++ libgo/go/net/lookup_unix.go	(working copy)
@@ -299,11 +299,21 @@  func (r *Resolver) lookupTXT(ctx context
 				Server: server,
 			}
 		}
+		// Multiple strings in one TXT record need to be
+		// concatenated without separator to be consistent
+		// with previous Go resolver.
+		n := 0
+		for _, s := range txt.TXT {
+			n += len(s)
+		}
+		txtJoin := make([]byte, 0, n)
+		for _, s := range txt.TXT {
+			txtJoin = append(txtJoin, s...)
+		}
 		if len(txts) == 0 {
-			txts = txt.TXT
-		} else {
-			txts = append(txts, txt.TXT...)
+			txts = make([]string, 0, 1)
 		}
+		txts = append(txts, string(txtJoin))
 	}
 	return txts, nil
 }
Index: libgo/go/net/splice_test.go
===================================================================
--- libgo/go/net/splice_test.go	(revision 264813)
+++ libgo/go/net/splice_test.go	(working copy)
@@ -124,6 +124,7 @@  func testSpliceBig(t *testing.T) {
 func testSpliceHonorsLimitedReader(t *testing.T) {
 	t.Run("stopsAfterN", testSpliceStopsAfterN)
 	t.Run("updatesN", testSpliceUpdatesN)
+	t.Run("readerAtLimit", testSpliceReaderAtLimit)
 }
 
 func testSpliceStopsAfterN(t *testing.T) {
@@ -210,7 +211,7 @@  func testSpliceUpdatesN(t *testing.T) {
 	}
 }
 
-func testSpliceReaderAtEOF(t *testing.T) {
+func testSpliceReaderAtLimit(t *testing.T) {
 	clientUp, serverUp, err := spliceTestSocketPair("tcp")
 	if err != nil {
 		t.Fatal(err)
@@ -224,22 +225,64 @@  func testSpliceReaderAtEOF(t *testing.T)
 	defer clientDown.Close()
 	defer serverDown.Close()
 
-	serverUp.Close()
-	_, err, handled := splice(serverDown.(*TCPConn).fd, serverUp)
+	lr := &io.LimitedReader{
+		N: 0,
+		R: serverUp,
+	}
+	_, err, handled := splice(serverDown.(*TCPConn).fd, lr)
 	if !handled {
 		if serr, ok := err.(*os.SyscallError); ok && serr.Syscall == "pipe2" && serr.Err == syscall.ENOSYS {
 			t.Skip("pipe2 not supported")
 		}
 
-		t.Errorf("closed connection: got err = %v, handled = %t, want handled = true", err, handled)
+		t.Errorf("exhausted LimitedReader: got err = %v, handled = %t, want handled = true", err, handled)
 	}
-	lr := &io.LimitedReader{
-		N: 0,
-		R: serverUp,
+}
+
+func testSpliceReaderAtEOF(t *testing.T) {
+	clientUp, serverUp, err := spliceTestSocketPair("tcp")
+	if err != nil {
+		t.Fatal(err)
 	}
-	_, err, handled = splice(serverDown.(*TCPConn).fd, lr)
-	if !handled {
-		t.Errorf("exhausted LimitedReader: got err = %v, handled = %t, want handled = true", err, handled)
+	defer clientUp.Close()
+	clientDown, serverDown, err := spliceTestSocketPair("tcp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer clientDown.Close()
+
+	serverUp.Close()
+
+	// We'd like to call net.splice here and check the handled return
+	// value, but we disable splice on old Linux kernels.
+	//
+	// In that case, poll.Splice and net.splice return a non-nil error
+	// and handled == false. We'd ideally like to see handled == true
+	// because the source reader is at EOF, but if we're running on an old
+	// kernel, and splice is disabled, we won't see EOF from net.splice,
+	// because we won't touch the reader at all.
+	//
+	// Trying to untangle the errors from net.splice and match them
+	// against the errors created by the poll package would be brittle,
+	// so this is a higher level test.
+	//
+	// The following ReadFrom should return immediately, regardless of
+	// whether splice is disabled or not. The other side should then
+	// get a goodbye signal. Test for the goodbye signal.
+	msg := "bye"
+	go func() {
+		serverDown.(*TCPConn).ReadFrom(serverUp)
+		io.WriteString(serverDown, msg)
+		serverDown.Close()
+	}()
+
+	buf := make([]byte, 3)
+	_, err = io.ReadFull(clientDown, buf)
+	if err != nil {
+		t.Errorf("clientDown: %v", err)
+	}
+	if string(buf) != msg {
+		t.Errorf("clientDown got %q, want %q", buf, msg)
 	}
 }
 
Index: libgo/go/reflect/all_test.go
===================================================================
--- libgo/go/reflect/all_test.go	(revision 264813)
+++ libgo/go/reflect/all_test.go	(working copy)
@@ -5864,7 +5864,7 @@  func clobber() {
 type funcLayoutTest struct {
 	rcvr, t                  Type
 	size, argsize, retOffset uintptr
-	stack                    []byte // pointer bitmap: 1 is pointer, 0 is scalar (or uninitialized)
+	stack                    []byte // pointer bitmap: 1 is pointer, 0 is scalar
 	gc                       []byte
 }
 
@@ -5886,7 +5886,7 @@  func init() {
 			6 * PtrSize,
 			4 * PtrSize,
 			4 * PtrSize,
-			[]byte{1, 0, 1},
+			[]byte{1, 0, 1, 0, 1},
 			[]byte{1, 0, 1, 0, 1},
 		})
 
Index: libgo/go/reflect/makefunc_ffi.go
===================================================================
--- libgo/go/reflect/makefunc_ffi.go	(revision 264813)
+++ libgo/go/reflect/makefunc_ffi.go	(working copy)
@@ -33,7 +33,7 @@  func FFICallbackGo(results unsafe.Pointe
 	ap := params
 	for _, rt := range ftyp.in {
 		p := unsafe_New(rt)
-		memmove(p, *(*unsafe.Pointer)(ap), rt.size)
+		typedmemmove(rt, p, *(*unsafe.Pointer)(ap))
 		v := Value{rt, p, flag(rt.Kind()) | flagIndir}
 		in = append(in, v)
 		ap = (unsafe.Pointer)(uintptr(ap) + ptrSize)
@@ -59,7 +59,7 @@  func FFICallbackGo(results unsafe.Pointe
 		if v.flag&flagIndir == 0 && (v.kind() == Ptr || v.kind() == UnsafePointer) {
 			*(*unsafe.Pointer)(addr) = v.ptr
 		} else {
-			memmove(addr, v.ptr, typ.size)
+			typedmemmove(typ, addr, v.ptr)
 		}
 		off += typ.size
 	}
Index: libgo/go/reflect/value.go
===================================================================
--- libgo/go/reflect/value.go	(revision 264813)
+++ libgo/go/reflect/value.go	(working copy)
@@ -323,7 +323,7 @@  var callGC bool // for testing; see Test
 
 func (v Value) call(op string, in []Value) []Value {
 	// Get function pointer, type.
-	t := v.typ
+	t := (*funcType)(unsafe.Pointer(v.typ))
 	var (
 		fn   unsafe.Pointer
 		rcvr Value
@@ -472,7 +472,7 @@  func (v Value) call(op string, in []Valu
 // The return value rcvrtype gives the method's actual receiver type.
 // The return value t gives the method type signature (without the receiver).
 // The return value fn is a pointer to the method code.
-func methodReceiver(op string, v Value, methodIndex int) (rcvrtype, t *rtype, fn unsafe.Pointer) {
+func methodReceiver(op string, v Value, methodIndex int) (rcvrtype *rtype, t *funcType, fn unsafe.Pointer) {
 	i := methodIndex
 	if v.typ.Kind() == Interface {
 		tt := (*interfaceType)(unsafe.Pointer(v.typ))
@@ -489,7 +489,7 @@  func methodReceiver(op string, v Value,
 		}
 		rcvrtype = iface.itab.typ
 		fn = unsafe.Pointer(&iface.itab.fun[i])
-		t = m.typ
+		t = (*funcType)(unsafe.Pointer(m.typ))
 	} else {
 		rcvrtype = v.typ
 		ms := v.typ.exportedMethods()
@@ -501,7 +501,7 @@  func methodReceiver(op string, v Value,
 			panic("reflect: " + op + " of unexported method")
 		}
 		fn = unsafe.Pointer(&m.tfn)
-		t = m.mtyp
+		t = (*funcType)(unsafe.Pointer(m.mtyp))
 	}
 	return
 }
@@ -2399,10 +2399,14 @@  func mapiternext(it unsafe.Pointer)
 
 //go:noescape
 func maplen(m unsafe.Pointer) int
-func call(typ *rtype, fnaddr unsafe.Pointer, isInterface bool, isMethod bool, params *unsafe.Pointer, results *unsafe.Pointer)
+func call(typ *funcType, fnaddr unsafe.Pointer, isInterface bool, isMethod bool, params *unsafe.Pointer, results *unsafe.Pointer)
 
 func ifaceE2I(t *rtype, src interface{}, dst unsafe.Pointer)
 
+// memmove copies size bytes to dst from src. No write barriers are used.
+//go:noescape
+func memmove(dst, src unsafe.Pointer, size uintptr)
+
 // typedmemmove copies a value of type t to dst from src.
 //go:noescape
 func typedmemmove(t *rtype, dst, src unsafe.Pointer)
@@ -2412,10 +2416,6 @@  func typedmemmove(t *rtype, dst, src uns
 //go:noescape
 func typedslicecopy(elemType *rtype, dst, src sliceHeader) int
 
-//go:noescape
-//extern memmove
-func memmove(adst, asrc unsafe.Pointer, n uintptr)
-
 // Dummy annotation marking that the value x escapes,
 // for use in cases where the reflect code is so clever that
 // the compiler cannot follow.
Index: libgo/go/runtime/chan.go
===================================================================
--- libgo/go/runtime/chan.go	(revision 264813)
+++ libgo/go/runtime/chan.go	(working copy)
@@ -102,7 +102,7 @@  func makechan(t *chantype, size int) *hc
 		// Queue or element size is zero.
 		c = (*hchan)(mallocgc(hchanSize, nil, true))
 		// Race detector uses this location for synchronization.
-		c.buf = unsafe.Pointer(c)
+		c.buf = c.raceaddr()
 	case elem.kind&kindNoPointers != 0:
 		// Elements do not contain pointers.
 		// Allocate hchan and buf in one call.
@@ -166,7 +166,7 @@  func chansend(c *hchan, ep unsafe.Pointe
 	}
 
 	if raceenabled {
-		racereadpc(unsafe.Pointer(c), callerpc, funcPC(chansend))
+		racereadpc(c.raceaddr(), callerpc, funcPC(chansend))
 	}
 
 	// Fast path: check for failed non-blocking operation without acquiring the lock.
@@ -352,8 +352,8 @@  func closechan(c *hchan) {
 
 	if raceenabled {
 		callerpc := getcallerpc()
-		racewritepc(unsafe.Pointer(c), callerpc, funcPC(closechan))
-		racerelease(unsafe.Pointer(c))
+		racewritepc(c.raceaddr(), callerpc, funcPC(closechan))
+		racerelease(c.raceaddr())
 	}
 
 	c.closed = 1
@@ -376,7 +376,7 @@  func closechan(c *hchan) {
 		gp := sg.g
 		gp.param = nil
 		if raceenabled {
-			raceacquireg(gp, unsafe.Pointer(c))
+			raceacquireg(gp, c.raceaddr())
 		}
 		gp.schedlink.set(glist)
 		glist = gp
@@ -395,7 +395,7 @@  func closechan(c *hchan) {
 		gp := sg.g
 		gp.param = nil
 		if raceenabled {
-			raceacquireg(gp, unsafe.Pointer(c))
+			raceacquireg(gp, c.raceaddr())
 		}
 		gp.schedlink.set(glist)
 		glist = gp
@@ -477,7 +477,7 @@  func chanrecv(c *hchan, ep unsafe.Pointe
 
 	if c.closed != 0 && c.qcount == 0 {
 		if raceenabled {
-			raceacquire(unsafe.Pointer(c))
+			raceacquire(c.raceaddr())
 		}
 		unlock(&c.lock)
 		if ep != nil {
@@ -755,6 +755,15 @@  func (q *waitq) dequeue() *sudog {
 	}
 }
 
+func (c *hchan) raceaddr() unsafe.Pointer {
+	// Treat read-like and write-like operations on the channel to
+	// happen at this address. Avoid using the address of qcount
+	// or dataqsiz, because the len() and cap() builtins read
+	// those addresses, and we don't want them racing with
+	// operations like close().
+	return unsafe.Pointer(&c.buf)
+}
+
 func racesync(c *hchan, sg *sudog) {
 	racerelease(chanbuf(c, 0))
 	raceacquireg(sg.g, chanbuf(c, 0))
Index: libgo/go/runtime/mbarrier.go
===================================================================
--- libgo/go/runtime/mbarrier.go	(revision 264813)
+++ libgo/go/runtime/mbarrier.go	(working copy)
@@ -309,6 +309,19 @@  func typedmemclr(typ *_type, ptr unsafe.
 	memclrNoHeapPointers(ptr, typ.size)
 }
 
+//go:linkname reflect_typedmemclr reflect.typedmemclr
+func reflect_typedmemclr(typ *_type, ptr unsafe.Pointer) {
+	typedmemclr(typ, ptr)
+}
+
+//go:linkname reflect_typedmemclrpartial reflect.typedmemclrpartial
+func reflect_typedmemclrpartial(typ *_type, ptr unsafe.Pointer, off, size uintptr) {
+	if typ.kind&kindNoPointers == 0 {
+		bulkBarrierPreWrite(uintptr(ptr), 0, size)
+	}
+	memclrNoHeapPointers(ptr, size)
+}
+
 // memclrHasPointers clears n bytes of typed memory starting at ptr.
 // The caller must ensure that the type of the object at ptr has
 // pointers, usually by checking typ.kind&kindNoPointers. However, ptr
Index: libgo/go/runtime/os_darwin.go
===================================================================
--- libgo/go/runtime/os_darwin.go	(revision 264813)
+++ libgo/go/runtime/os_darwin.go	(working copy)
@@ -34,6 +34,10 @@  func semacreate(mp *m) {
 
 //go:nosplit
 func semasleep(ns int64) int32 {
+	var start int64
+	if ns >= 0 {
+		start = nanotime()
+	}
 	mp := getg().m
 	pthread_mutex_lock(&mp.mutex)
 	for {
@@ -43,8 +47,13 @@  func semasleep(ns int64) int32 {
 			return 0
 		}
 		if ns >= 0 {
+			spent := nanotime() - start
+			if spent >= ns {
+				pthread_mutex_unlock(&mp.mutex)
+				return -1
+			}
 			var t timespec
-			t.set_nsec(ns)
+			t.set_nsec(ns - spent)
 			err := pthread_cond_timedwait_relative_np(&mp.cond, &mp.mutex, &t)
 			if err == _ETIMEDOUT {
 				pthread_mutex_unlock(&mp.mutex)
Index: libgo/go/runtime/os_netbsd.go
===================================================================
--- libgo/go/runtime/os_netbsd.go	(revision 264813)
+++ libgo/go/runtime/os_netbsd.go	(working copy)
@@ -29,15 +29,9 @@  func semacreate(mp *m) {
 //go:nosplit
 func semasleep(ns int64) int32 {
 	_g_ := getg()
-
-	// Compute sleep deadline.
-	var tsp *timespec
-	var ts timespec
+	var deadline int64
 	if ns >= 0 {
-		var nsec int32
-		ts.set_sec(int64(timediv(ns, 1000000000, &nsec)))
-		ts.set_nsec(nsec)
-		tsp = &ts
+		deadline = nanotime() + ns
 	}
 
 	for {
@@ -50,18 +44,21 @@  func semasleep(ns int64) int32 {
 		}
 
 		// Sleep until unparked by semawakeup or timeout.
+		var tsp *timespec
+		var ts timespec
+		if ns >= 0 {
+			wait := deadline - nanotime()
+			if wait <= 0 {
+				return -1
+			}
+			var nsec int32
+			ts.set_sec(timediv(wait, 1000000000, &nsec))
+			ts.set_nsec(nsec)
+			tsp = &ts
+		}
 		ret := lwp_park(_CLOCK_MONOTONIC, _TIMER_RELTIME, tsp, 0, unsafe.Pointer(&_g_.m.waitsemacount), nil)
 		if ret == _ETIMEDOUT {
 			return -1
-		} else if ret == _EINTR && ns >= 0 {
-			// Avoid sleeping forever if we keep getting
-			// interrupted (for example by the profiling
-			// timer). It would be if tsp upon return had the
-			// remaining time to sleep, but this is good enough.
-			var nsec int32
-			ns /= 2
-			ts.set_sec(timediv(ns, 1000000000, &nsec))
-			ts.set_nsec(nsec)
 		}
 	}
 }
Index: libgo/go/runtime/select.go
===================================================================
--- libgo/go/runtime/select.go	(revision 264813)
+++ libgo/go/runtime/select.go	(working copy)
@@ -426,7 +426,7 @@  rclose:
 		typedmemclr(c.elemtype, cas.elem)
 	}
 	if raceenabled {
-		raceacquire(unsafe.Pointer(c))
+		raceacquire(c.raceaddr())
 	}
 	goto retc
 
Index: libgo/go/runtime/trace/annotation.go
===================================================================
--- libgo/go/runtime/trace/annotation.go	(revision 264813)
+++ libgo/go/runtime/trace/annotation.go	(working copy)
@@ -24,13 +24,13 @@  type traceContextKey struct{}
 // If the end function is called multiple times, only the first
 // call is used in the latency measurement.
 //
-//   ctx, task := trace.NewTask(ctx, "awesome task")
-//   trace.WithRegion(ctx, prepWork)
+//   ctx, task := trace.NewTask(ctx, "awesomeTask")
+//   trace.WithRegion(ctx, "preparation", prepWork)
 //   // preparation of the task
 //   go func() {  // continue processing the task in a separate goroutine.
 //       defer task.End()
-//       trace.WithRegion(ctx, remainingWork)
-//   }
+//       trace.WithRegion(ctx, "remainingWork", remainingWork)
+//   }()
 func NewTask(pctx context.Context, taskType string) (ctx context.Context, task *Task) {
 	pid := fromContext(pctx).id
 	id := newID()