---
doc/contribute.html | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/doc/contribute.html b/doc/contribute.html
index a321a8646f..4619c81124 100644
--- a/doc/contribute.html
+++ b/doc/contribute.html
@@ -198,9 +198,13 @@ prints help text, not an error.
-Note to Git aficionados: The git-codereview command is not required to
+Note to Git aficionados:
+The git-codereview command is not required to
upload and manage Gerrit code reviews. For those who prefer plain Git, the text
-below gives the Git equivalent of each git-codereview command. If you do use plain
+below gives the Git equivalent of each git-codereview command.
+
+
+If you do use plain
Git, note that you still need the commit hooks that the git-codereview command
configures; those hooks add a Gerrit Change-Id line to the commit
message and check that all Go source files have been formatted with gofmt. Even
@@ -208,6 +212,12 @@ if you intend to use plain Git for daily work, install the hooks in a new Git
checkout by running git-codereview hooks.
+
+The workflow described below assumes a single change per branch.
+It is also possible to prepare a sequence of (usually related) changes in a single branch.
+See the git-codereview documentation for details.
+
+
Set up git aliases
From c4f902bef4c7edb9b051cec6c3da6690dc045203 Mon Sep 17 00:00:00 2001
From: Russ Cox
Date: Wed, 17 Feb 2016 10:41:03 -0500
Subject: [PATCH 024/117] net/http: update bundle command
This is the bundle command's new usage and new output header,
after CL 19428.
Actually running this command would work but would bring in
a newer x/net/http2 that we don't want yet.
Change-Id: Ic6082ca00102a2df1f7632eebf9aca41fdcdb444
Reviewed-on: https://go-review.googlesource.com/19551
Reviewed-by: Ian Lance Taylor
Reviewed-by: Chris Broadfoot
---
src/net/http/h2_bundle.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
index d8be49c0de..4e19b3e71f 100644
--- a/src/net/http/h2_bundle.go
+++ b/src/net/http/h2_bundle.go
@@ -1,5 +1,5 @@
-// Code generated by golang.org/x/tools/cmd/bundle command:
-// $ bundle golang.org/x/net/http2 net/http http2
+// Code generated by golang.org/x/tools/cmd/bundle.
+//go:generate bundle -o h2_bundle.go -prefix http2 -import golang.org/x/net/http2/hpack=internal/golang.org/x/net/http2/hpack golang.org/x/net/http2
// Package http2 implements the HTTP/2 protocol.
//
From 939a9424de5c3d0a0d2e1769778b5b0aa9c61954 Mon Sep 17 00:00:00 2001
From: Russ Cox
Date: Wed, 17 Feb 2016 10:39:13 -0500
Subject: [PATCH 025/117] doc: remove DRAFT tags from go1.6.html
Go 1.6 is soon (but not yet).
Fixes #14301.
Change-Id: I85e329b643adcb5d4fa680c5333fbc1f928d4d9d
Reviewed-on: https://go-review.googlesource.com/19550
Reviewed-by: Ian Lance Taylor
Reviewed-by: Chris Broadfoot
---
doc/go1.6.html | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/doc/go1.6.html b/doc/go1.6.html
index 4937fc9a59..17c3536aeb 100644
--- a/doc/go1.6.html
+++ b/doc/go1.6.html
@@ -1,5 +1,5 @@
@@ -13,14 +13,6 @@ Edit .,s;^([a-z][A-Za-z0-9_/]+)\.([A-Z][A-Za-z0-9_]+\.)?([A-Z][A-Za-z0-9_]+)([ .
ul li { margin: 0.5em 0; }
-
-NOTE: This is a DRAFT of the Go 1.6 release notes, prepared for the Go 1.6 beta.
-Go 1.6 has NOT yet been released.
-By our regular schedule, it is expected some time in February 2016.
-
-
-
-
Introduction to Go 1.6
From 6030c7531539619003e651e8836f451ea6b832b0 Mon Sep 17 00:00:00 2001
From: Chris Broadfoot
Date: Wed, 17 Feb 2016 14:02:26 -0800
Subject: [PATCH 026/117] doc: document Go 1.6
Change-Id: I4910105d48ed650289ecb1490d556929db05bc38
Reviewed-on: https://go-review.googlesource.com/19526
Reviewed-by: Andrew Gerrand
Reviewed-on: https://go-review.googlesource.com/19527
---
doc/devel/release.html | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/doc/devel/release.html b/doc/devel/release.html
index ad060a8ce6..6cdbe1d608 100644
--- a/doc/devel/release.html
+++ b/doc/devel/release.html
@@ -30,6 +30,13 @@ to fix critical security problems in both Go 1.4 and Go 1.5 as they arise.
See the security policy for more details.
+go1.6 (released 2015/02/17)
+
+
+Go 1.6 is a major release of Go.
+Read the Go 1.6 Release Notes for more information.
+
+
go1.5 (released 2015/08/19)
From 6b9a0fa356de3c733c14951e42ca31cfafe7ff79 Mon Sep 17 00:00:00 2001
From: Rahul Chaudhry
Date: Wed, 17 Feb 2016 14:55:16 -0800
Subject: [PATCH 027/117] doc: fix typo in go1.6 release date.
Change-Id: If15fdcd3cd49394a0c1dffd39fbbeede11081ccb
Reviewed-on: https://go-review.googlesource.com/19528
Reviewed-by: Chris Broadfoot
---
doc/devel/release.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/devel/release.html b/doc/devel/release.html
index 6cdbe1d608..e0c2ac0219 100644
--- a/doc/devel/release.html
+++ b/doc/devel/release.html
@@ -30,7 +30,7 @@ to fix critical security problems in both Go 1.4 and Go 1.5 as they arise.
See the security policy for more details.
-go1.6 (released 2015/02/17)
+go1.6 (released 2016/02/17)
Go 1.6 is a major release of Go.
From c51f9173ad2711f5b1a5af9d95dae9e711e13ebb Mon Sep 17 00:00:00 2001
From: Robert Griesemer
Date: Thu, 18 Feb 2016 09:42:28 -0800
Subject: [PATCH 028/117] go/constant: fix doc strings
Fixes #14357.
Change-Id: I91acff0b0cc7be2bcbad68925a19a437dbd4c83d
Reviewed-on: https://go-review.googlesource.com/19620
Reviewed-by: Alan Donovan
---
src/go/constant/value.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/go/constant/value.go b/src/go/constant/value.go
index 310814df71..1b0938dda4 100644
--- a/src/go/constant/value.go
+++ b/src/go/constant/value.go
@@ -276,10 +276,10 @@ func smallRat(x *big.Float) bool {
// MakeUnknown returns the Unknown value.
func MakeUnknown() Value { return unknownVal{} }
-// MakeBool returns the Bool value for x.
+// MakeBool returns the Bool value for b.
func MakeBool(b bool) Value { return boolVal(b) }
-// MakeString returns the String value for x.
+// MakeString returns the String value for s.
func MakeString(s string) Value { return stringVal(s) }
// MakeInt64 returns the Int value for x.
From 3e91e8aa356328c5a7c2ab0f6291f99c69145cdc Mon Sep 17 00:00:00 2001
From: Alberto Donizetti
Date: Sat, 30 Jan 2016 21:50:07 +0100
Subject: [PATCH 029/117] go/internal/gcimporter: add missing argument to error
message
Change-Id: I3071f0e876506c6dc283e97bc15f157bf2ff011e
Reviewed-on: https://go-review.googlesource.com/19641
Reviewed-by: Robert Griesemer
---
src/go/internal/gcimporter/gcimporter.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/go/internal/gcimporter/gcimporter.go b/src/go/internal/gcimporter/gcimporter.go
index d70ec083c3..052277f4fe 100644
--- a/src/go/internal/gcimporter/gcimporter.go
+++ b/src/go/internal/gcimporter/gcimporter.go
@@ -385,7 +385,7 @@ func (p *parser) getPkg(id, name string) *types.Package {
if pname := pkg.Name(); pname == "" {
pkg.SetName(name)
} else if pname != name {
- p.errorf("%s package name mismatch: %s (given) vs %s (expected)", pname, name)
+ p.errorf("%s package name mismatch: %s (given) vs %s (expected)", id, pname, name)
}
}
return pkg
From 8fd1634f443cebcb176c7a95104b61240733e420 Mon Sep 17 00:00:00 2001
From: Matt Bostock
Date: Tue, 16 Feb 2016 18:53:46 +0000
Subject: [PATCH 030/117] sort: Fix typo in stable sort comment
Fix `reverences`, which I believe should read as `references`.
Change-Id: I450efcbeee0f8861a84b209f2e6636764034232a
Reviewed-on: https://go-review.googlesource.com/19469
Reviewed-by: Russ Cox
---
src/sort/sort.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/sort/sort.go b/src/sort/sort.go
index ac8f4a661f..5eb45c6d4a 100644
--- a/src/sort/sort.go
+++ b/src/sort/sort.go
@@ -335,7 +335,7 @@ func StringsAreSorted(a []string) bool { return IsSorted(StringSlice(a)) }
// unstable or rely on enough different elements in each step to encode the
// performed block rearrangements. See also "In-Place Merging Algorithms",
// Denham Coates-Evely, Department of Computer Science, Kings College,
-// January 2004 and the reverences in there.
+// January 2004 and the references in there.
// - Often "optimal" algorithms are optimal in the number of assignments
// but Interface has only Swap as operation.
From a576e9883cd1a79ddcf1c258b4e72ef164e9a1c8 Mon Sep 17 00:00:00 2001
From: Robert Griesemer
Date: Thu, 18 Feb 2016 11:43:52 -0800
Subject: [PATCH 031/117] text/scanner: mention package when reporting errors
to stderr
Fixes #14166.
Change-Id: I325b283a1d53e73a6d862611c446820ab94a161c
Reviewed-on: https://go-review.googlesource.com/19622
Reviewed-by: Damien Neil
---
src/text/scanner/scanner.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/text/scanner/scanner.go b/src/text/scanner/scanner.go
index 0155800f34..dd87850fcd 100644
--- a/src/text/scanner/scanner.go
+++ b/src/text/scanner/scanner.go
@@ -333,7 +333,7 @@ func (s *Scanner) error(msg string) {
if !pos.IsValid() {
pos = s.Pos()
}
- fmt.Fprintf(os.Stderr, "%s: %s\n", pos, msg)
+ fmt.Fprintf(os.Stderr, "text/scanner: %s: %s\n", pos, msg)
}
func (s *Scanner) isIdentRune(ch rune, i int) bool {
From 1a94431a78c4de5182dd43b438701cca80455746 Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Wed, 13 Jan 2016 15:51:16 -0800
Subject: [PATCH 032/117] cmd/cgo: support multiple-value special form in
VarDecl
Fixes #13930.
Change-Id: I124b7d31d1f2be05b7f23dafd1e52d9f3f02f3f0
Reviewed-on: https://go-review.googlesource.com/18623
Run-TryBot: Matthew Dempsky
Reviewed-by: Ian Lance Taylor
---
misc/cgo/test/issue13930.go | 13 +++++++++++++
src/cmd/cgo/ast.go | 6 +++++-
src/cmd/cgo/doc.go | 3 ++-
3 files changed, 20 insertions(+), 2 deletions(-)
create mode 100644 misc/cgo/test/issue13930.go
diff --git a/misc/cgo/test/issue13930.go b/misc/cgo/test/issue13930.go
new file mode 100644
index 0000000000..3a22459e68
--- /dev/null
+++ b/misc/cgo/test/issue13930.go
@@ -0,0 +1,13 @@
+// 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.
+
+// Issue 13930. Test that cgo's multiple-value special form for
+// C function calls works in variable declaration statements.
+
+package cgotest
+
+// #include
+import "C"
+
+var _, _ = C.abs(0)
diff --git a/src/cmd/cgo/ast.go b/src/cmd/cgo/ast.go
index c3a24c2b76..4c5dc9a23d 100644
--- a/src/cmd/cgo/ast.go
+++ b/src/cmd/cgo/ast.go
@@ -447,7 +447,11 @@ func (f *File) walk(x interface{}, context string, visit func(*File, interface{}
case *ast.ImportSpec:
case *ast.ValueSpec:
f.walk(&n.Type, "type", visit)
- f.walk(n.Values, "expr", visit)
+ if len(n.Names) == 2 && len(n.Values) == 1 {
+ f.walk(&n.Values[0], "as2", visit)
+ } else {
+ f.walk(n.Values, "expr", visit)
+ }
case *ast.TypeSpec:
f.walk(&n.Type, "type", visit)
diff --git a/src/cmd/cgo/doc.go b/src/cmd/cgo/doc.go
index bd38a5c153..8b4e2bfd58 100644
--- a/src/cmd/cgo/doc.go
+++ b/src/cmd/cgo/doc.go
@@ -148,8 +148,9 @@ assignment context to retrieve both the return value (if any) and the
C errno variable as an error (use _ to skip the result value if the
function returns void). For example:
- n, err := C.sqrt(-1)
+ n, err = C.sqrt(-1)
_, err := C.voidFunc()
+ var n, err = C.sqrt(1)
Calling C function pointers is currently not supported, however you can
declare Go variables which hold C function pointers and pass them
From 5bbb98df0960f57dca73cb7640456608d4cc0917 Mon Sep 17 00:00:00 2001
From: Damien Neil
Date: Mon, 8 Feb 2016 17:20:59 -0800
Subject: [PATCH 033/117] cmd/go, cmd/link: make builds deterministic
Add the following flags when supported by the compiler:
-gno-record-gcc-switches
-fdebug-prefix-map=$WORK=/tmp/go-build
Add an empty NAME symbol to the ELF .symtab. GNU ld will add a NAME
symbol when one is not present; including one of our own prevents it
from adding a reference to the link tempdir.
Fixes #13247 for compilers that support -fdebug-prefix-map. (gcc, clang
in the near future.)
Change-Id: I221c71fc59cd23ee8c99bcc038793ff4623c9ffc
Reviewed-on: https://go-review.googlesource.com/19363
Reviewed-by: Ian Lance Taylor
Run-TryBot: Damien Neil
---
src/cmd/go/build.go | 40 +++++++++++++++++++++---------
src/cmd/go/go_test.go | 27 ++++++++++++++++++++
src/cmd/link/internal/ld/symtab.go | 5 ++++
3 files changed, 60 insertions(+), 12 deletions(-)
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
index f2a2a6014f..1932f324ea 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -686,6 +686,7 @@ type builder struct {
work string // the temporary work directory (ends in filepath.Separator)
actionCache map[cacheKey]*action // a cache of already-constructed actions
mkdirCache map[string]bool // a cache of created directories
+ flagCache map[string]bool // a cache of supported compiler flags
print func(args ...interface{}) (int, error)
output sync.Mutex
@@ -2927,6 +2928,14 @@ func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
// disable word wrapping in error messages
a = append(a, "-fmessage-length=0")
+ // Tell gcc not to include the work directory in object files.
+ if b.gccSupportsFlag("-fdebug-prefix-map=a=b") {
+ // -gno-record-gcc-switches is supported by all gcc/clang
+ // versions that support -fdebug-prefix-map.
+ a = append(a, "-gno-record-gcc-switches")
+ a = append(a, "-fdebug-prefix-map="+b.work+"=/tmp/go-build")
+ }
+
// On OS X, some of the compilers behave as if -fno-common
// is always set, and the Mach-O linker in 6l/8l assumes this.
// See https://golang.org/issue/3253.
@@ -2941,19 +2950,24 @@ func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
// -no-pie must be passed when doing a partial link with -Wl,-r. But -no-pie is
// not supported by all compilers.
func (b *builder) gccSupportsNoPie() bool {
- if goos != "linux" {
- // On some BSD platforms, error messages from the
- // compiler make it to the console despite cmd.Std*
- // all being nil. As -no-pie is only required on linux
- // systems so far, we only test there.
- return false
+ return b.gccSupportsFlag("-no-pie")
+}
+
+// gccSupportsFlag checks to see if the compiler supports a flag.
+func (b *builder) gccSupportsFlag(flag string) bool {
+ b.exec.Lock()
+ defer b.exec.Unlock()
+ if b, ok := b.flagCache[flag]; ok {
+ return b
}
- src := filepath.Join(b.work, "trivial.c")
- if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
- return false
+ if b.flagCache == nil {
+ src := filepath.Join(b.work, "trivial.c")
+ if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
+ return false
+ }
+ b.flagCache = make(map[string]bool)
}
- cmdArgs := b.gccCmd(b.work)
- cmdArgs = append(cmdArgs, "-no-pie", "-c", "trivial.c")
+ cmdArgs := append(envList("CC", defaultCC), flag, "-c", "trivial.c")
if buildN || buildX {
b.showcmd(b.work, "%s", joinUnambiguously(cmdArgs))
if buildN {
@@ -2964,7 +2978,9 @@ func (b *builder) gccSupportsNoPie() bool {
cmd.Dir = b.work
cmd.Env = envForDir(cmd.Dir, os.Environ())
out, err := cmd.CombinedOutput()
- return err == nil && !bytes.Contains(out, []byte("unrecognized"))
+ supported := err == nil && !bytes.Contains(out, []byte("unrecognized"))
+ b.flagCache[flag] = supported
+ return supported
}
// gccArchArgs returns arguments to pass to gcc based on the architecture.
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index 39e0f3e56d..e55fc360de 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -2759,3 +2759,30 @@ func TestParallelTest(t *testing.T) {
tg.setenv("GOPATH", tg.path("."))
tg.run("test", "-p=4", "p1", "p2", "p3", "p4")
}
+
+func TestCgoConsistentResults(t *testing.T) {
+ if !canCgo {
+ t.Skip("skipping because cgo not enabled")
+ }
+
+ tg := testgo(t)
+ defer tg.cleanup()
+ tg.parallel()
+ tg.makeTempdir()
+ tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+ exe1 := tg.path("cgotest1" + exeSuffix)
+ exe2 := tg.path("cgotest2" + exeSuffix)
+ tg.run("build", "-o", exe1, "cgotest")
+ tg.run("build", "-x", "-o", exe2, "cgotest")
+ b1, err := ioutil.ReadFile(exe1)
+ tg.must(err)
+ b2, err := ioutil.ReadFile(exe2)
+ tg.must(err)
+
+ if !tg.doGrepMatch(`-fdebug-prefix-map=\$WORK`, &tg.stderr) {
+ t.Skip("skipping because C compiler does not support -fdebug-prefix-map")
+ }
+ if !bytes.Equal(b1, b2) {
+ t.Error("building cgotest twice did not produce the same output")
+ }
+}
diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go
index 3e6169e453..b87ca81007 100644
--- a/src/cmd/link/internal/ld/symtab.go
+++ b/src/cmd/link/internal/ld/symtab.go
@@ -215,6 +215,11 @@ func Asmelfsym() {
dwarfaddelfsectionsyms()
+ // Some linkers will add a FILE sym if one is not present.
+ // Avoid having the working directory inserted into the symbol table.
+ putelfsyment(0, 0, 0, STB_LOCAL<<4|STT_FILE, SHN_ABS, 0)
+ numelfsym++
+
elfbind = STB_LOCAL
genasmsym(putelfsym)
From 7d80291c4c8bce8754b6e1aeb962aed1ceef64dc Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Tue, 1 Dec 2015 11:58:41 -0800
Subject: [PATCH 034/117] cmd/compile: eliminate Io.importsafe
It was only really necessary for ensuring that package runtime should
be treated as safe even without a "safe" marker, but mkbuiltin.go now
compiles it with -u.
Change-Id: Ifbcc62436ce40ab732ece667141afd82c1d3b64b
Reviewed-on: https://go-review.googlesource.com/19625
Reviewed-by: Robert Griesemer
Run-TryBot: Robert Griesemer
TryBot-Result: Gobot Gobot
---
src/cmd/compile/internal/gc/go.go | 17 ++++++++---------
src/cmd/compile/internal/gc/lex.go | 1 -
src/cmd/compile/internal/gc/parser.go | 8 ++++----
3 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
index 3146caed2f..8053aaffe9 100644
--- a/src/cmd/compile/internal/gc/go.go
+++ b/src/cmd/compile/internal/gc/go.go
@@ -386,15 +386,14 @@ type Sig struct {
}
type Io struct {
- infile string
- bin *obj.Biobuf
- cp string // used for content when bin==nil
- last int
- peekc int
- peekc1 int // second peekc for ...
- nlsemi bool
- eofnl bool
- importsafe bool
+ infile string
+ bin *obj.Biobuf
+ cp string // used for content when bin==nil
+ last int
+ peekc int
+ peekc1 int // second peekc for ...
+ nlsemi bool
+ eofnl bool
}
type Dlist struct {
diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
index b9c27357bb..f1112e5af8 100644
--- a/src/cmd/compile/internal/gc/lex.go
+++ b/src/cmd/compile/internal/gc/lex.go
@@ -884,7 +884,6 @@ func cannedimports(file string, cp string) {
curio.infile = file
curio.cp = cp
curio.nlsemi = false
- curio.importsafe = false
typecheckok = true
incannedimport = 1
diff --git a/src/cmd/compile/internal/gc/parser.go b/src/cmd/compile/internal/gc/parser.go
index 054cf73656..2e4be63a34 100644
--- a/src/cmd/compile/internal/gc/parser.go
+++ b/src/cmd/compile/internal/gc/parser.go
@@ -71,7 +71,6 @@ func (p *parser) loadsys() {
} else {
cannedimports("runtime.Builtin", runtimeimport)
}
- curio.importsafe = true
p.import_package()
p.import_there()
@@ -467,9 +466,10 @@ func (p *parser) import_package() {
p.import_error()
}
+ importsafe := false
if p.tok == LNAME {
if p.sym_.Name == "safe" {
- curio.importsafe = true
+ importsafe = true
}
p.next()
}
@@ -484,9 +484,9 @@ func (p *parser) import_package() {
if incannedimport == 0 {
importpkg.Direct = true
}
- importpkg.Safe = curio.importsafe
+ importpkg.Safe = importsafe
- if safemode != 0 && !curio.importsafe {
+ if safemode != 0 && !importsafe {
Yyerror("cannot import unsafe package %q", importpkg.Path)
}
}
From 7555f7f2bf1636443b6013c90e45698894af75e1 Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Tue, 1 Dec 2015 11:52:32 -0800
Subject: [PATCH 035/117] cmd/compile: cleanup mkbuiltin.go
Changes largely in preparation for eventually switching the builtin
export data to use the new binary format.
Replace fancy incremental line-by-line scanning with simply reading
the entire object file into memory, finding the export data section,
and processing it that way.
Just use "package runtime" and "package unsafe" in the builtin Go
source files so we don't need to rewrite references to "PACKAGE".
Stop looking for init_PACKAGE_function; it doesn't exist anyway.
Compile package runtime with -u so that its export data marks it as a
"safe" package.
Eliminate requirement to pass "runtime" and "unsafe" as command-line
arguments so that just "go run mkbuiltin.go" works.
Only rewrite builtin.go when successful.
Change-Id: I4addfde9e0cfb30607c7a83de686bde0ad1f035a
Reviewed-on: https://go-review.googlesource.com/19624
Reviewed-by: Robert Griesemer
Run-TryBot: Robert Griesemer
TryBot-Result: Gobot Gobot
---
src/cmd/compile/internal/gc/builtin.go | 2 +-
.../compile/internal/gc/builtin/runtime.go | 2 +-
src/cmd/compile/internal/gc/builtin/unsafe.go | 2 +-
src/cmd/compile/internal/gc/lex.go | 2 +-
src/cmd/compile/internal/gc/mkbuiltin.go | 88 ++++++++-----------
src/cmd/compile/internal/gc/parser.go | 2 +-
6 files changed, 41 insertions(+), 57 deletions(-)
diff --git a/src/cmd/compile/internal/gc/builtin.go b/src/cmd/compile/internal/gc/builtin.go
index 4199fb35cc..1e1f85a4a1 100644
--- a/src/cmd/compile/internal/gc/builtin.go
+++ b/src/cmd/compile/internal/gc/builtin.go
@@ -3,7 +3,7 @@
package gc
const runtimeimport = "" +
- "package runtime\n" +
+ "package runtime safe\n" +
"func @\"\".newobject (@\"\".typ·2 *byte) (? *any)\n" +
"func @\"\".panicindex ()\n" +
"func @\"\".panicslice ()\n" +
diff --git a/src/cmd/compile/internal/gc/builtin/runtime.go b/src/cmd/compile/internal/gc/builtin/runtime.go
index a50fc2e293..08f925f41c 100644
--- a/src/cmd/compile/internal/gc/builtin/runtime.go
+++ b/src/cmd/compile/internal/gc/builtin/runtime.go
@@ -8,7 +8,7 @@
// +build ignore
-package PACKAGE
+package runtime
// emitted by compiler, not referred to by go programs
diff --git a/src/cmd/compile/internal/gc/builtin/unsafe.go b/src/cmd/compile/internal/gc/builtin/unsafe.go
index ce508692eb..a7fc8aa53e 100644
--- a/src/cmd/compile/internal/gc/builtin/unsafe.go
+++ b/src/cmd/compile/internal/gc/builtin/unsafe.go
@@ -8,7 +8,7 @@
// +build ignore
-package PACKAGE
+package unsafe
type Pointer uintptr // not really; filled in by compiler
diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
index f1112e5af8..a2a8be1610 100644
--- a/src/cmd/compile/internal/gc/lex.go
+++ b/src/cmd/compile/internal/gc/lex.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:generate go run mkbuiltin.go runtime unsafe
+//go:generate go run mkbuiltin.go
package gc
diff --git a/src/cmd/compile/internal/gc/mkbuiltin.go b/src/cmd/compile/internal/gc/mkbuiltin.go
index b1e4458692..1b6cc4ae38 100644
--- a/src/cmd/compile/internal/gc/mkbuiltin.go
+++ b/src/cmd/compile/internal/gc/mkbuiltin.go
@@ -4,95 +4,79 @@
// +build ignore
-// Generate builtin.go from builtin/runtime.go and builtin/unsafe.go
-// (passed as arguments on the command line by a go:generate comment).
+// Generate builtin.go from builtin/runtime.go and builtin/unsafe.go.
// Run this after changing builtin/runtime.go and builtin/unsafe.go
// or after changing the export metadata format in the compiler.
// Either way, you need to have a working compiler binary first.
package main
import (
- "bufio"
+ "bytes"
"fmt"
"io"
+ "io/ioutil"
"log"
"os"
"os/exec"
- "strings"
)
func main() {
- f, err := os.Create("builtin.go")
- if err != nil {
- log.Fatal(err)
- }
- defer f.Close()
- w := bufio.NewWriter(f)
+ var b bytes.Buffer
+ fmt.Fprintln(&b, "// AUTO-GENERATED by mkbuiltin.go; DO NOT EDIT")
+ fmt.Fprintln(&b, "")
+ fmt.Fprintln(&b, "package gc")
- fmt.Fprintln(w, "// AUTO-GENERATED by mkbuiltin.go; DO NOT EDIT")
- fmt.Fprintln(w, "")
- fmt.Fprintln(w, "package gc")
+ mkbuiltin(&b, "runtime")
+ mkbuiltin(&b, "unsafe")
- for _, name := range os.Args[1:] {
- mkbuiltin(w, name)
- }
-
- if err := w.Flush(); err != nil {
+ if err := ioutil.WriteFile("builtin.go", b.Bytes(), 0666); err != nil {
log.Fatal(err)
}
}
-// Compile .go file, import data from .6 file, and write Go string version.
+// Compile .go file, import data from .o file, and write Go string version.
func mkbuiltin(w io.Writer, name string) {
- if err := exec.Command("go", "tool", "compile", "-A", "builtin/"+name+".go").Run(); err != nil {
+ args := []string{"tool", "compile", "-A"}
+ if name == "runtime" {
+ args = append(args, "-u")
+ }
+ args = append(args, "builtin/"+name+".go")
+
+ if err := exec.Command("go", args...).Run(); err != nil {
log.Fatal(err)
}
obj := name + ".o"
defer os.Remove(obj)
- r, err := os.Open(obj)
+ b, err := ioutil.ReadFile(obj)
if err != nil {
log.Fatal(err)
}
- defer r.Close()
- scanner := bufio.NewScanner(r)
// Look for $$ that introduces imports.
- for scanner.Scan() {
- if strings.Contains(scanner.Text(), "$$") {
- goto Begin
- }
+ i := bytes.Index(b, []byte("\n$$\n"))
+ if i < 0 {
+ log.Fatal("did not find beginning of imports")
}
- log.Fatal("did not find beginning of imports")
+ i += 4
-Begin:
- initfunc := fmt.Sprintf("init_%s_function", name)
-
- fmt.Fprintf(w, "\nconst %simport = \"\" +\n", name)
-
- // sys.go claims to be in package PACKAGE to avoid
- // conflicts during "go tool compile sys.go". Rename PACKAGE to $2.
- replacer := strings.NewReplacer("PACKAGE", name)
-
- // Process imports, stopping at $$ that closes them.
- for scanner.Scan() {
- p := scanner.Text()
- if strings.Contains(p, "$$") {
- goto End
- }
+ // Look for $$ that closes imports.
+ j := bytes.Index(b[i:], []byte("\n$$\n"))
+ if j < 0 {
+ log.Fatal("did not find end of imports")
+ }
+ j += i + 4
+ // Process and reformat imports.
+ fmt.Fprintf(w, "\nconst %simport = \"\"", name)
+ for _, p := range bytes.SplitAfter(b[i:j], []byte("\n")) {
// Chop leading white space.
- p = strings.TrimLeft(p, " \t")
-
- // Cut out decl of init_$1_function - it doesn't exist.
- if strings.Contains(p, initfunc) {
+ p = bytes.TrimLeft(p, " \t")
+ if len(p) == 0 {
continue
}
- fmt.Fprintf(w, "\t%q +\n", replacer.Replace(p)+"\n")
+ fmt.Fprintf(w, " +\n\t%q", p)
}
- log.Fatal("did not find end of imports")
-
-End:
- fmt.Fprintf(w, "\t\"$$\\n\"\n")
+ fmt.Fprintf(w, "\n")
}
diff --git a/src/cmd/compile/internal/gc/parser.go b/src/cmd/compile/internal/gc/parser.go
index 2e4be63a34..dc6ae72d5f 100644
--- a/src/cmd/compile/internal/gc/parser.go
+++ b/src/cmd/compile/internal/gc/parser.go
@@ -67,7 +67,7 @@ func (p *parser) loadsys() {
importpkg = Runtimepkg
if Debug['A'] != 0 {
- cannedimports("runtime.Builtin", "package runtime\n\n$$\n\n")
+ cannedimports("runtime.Builtin", "package runtime safe\n\n$$\n\n")
} else {
cannedimports("runtime.Builtin", runtimeimport)
}
From 98cc8b4cf219384792e19dec9bc17a0e49c466f6 Mon Sep 17 00:00:00 2001
From: Rhys Hiltner
Date: Thu, 18 Feb 2016 13:35:49 -0800
Subject: [PATCH 036/117] cmd/link/internal/ld: remove unused call to os.Getwd
This call to os.Getwd (or getwd) has been part of the linker since the C
implementation in 7d507dc6e6. It stopped being used in 26438d4d80, and
survived the conversion to Go in 1f9dbb60ef.
Its return value goes unused (the linker gets the value for AT_comp_dir in
dwarf.go), remove it.
Change-Id: I3d4594813bb4ee0a6af31a36e19d99ec4b863677
Reviewed-on: https://go-review.googlesource.com/19655
Reviewed-by: Ian Lance Taylor
Run-TryBot: Ian Lance Taylor
TryBot-Result: Gobot Gobot
---
src/cmd/link/internal/ld/sym.go | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/src/cmd/link/internal/ld/sym.go b/src/cmd/link/internal/ld/sym.go
index 731f3ede94..6122b85298 100644
--- a/src/cmd/link/internal/ld/sym.go
+++ b/src/cmd/link/internal/ld/sym.go
@@ -34,8 +34,6 @@ package ld
import (
"cmd/internal/obj"
"log"
- "os"
- "path/filepath"
"strconv"
)
@@ -70,13 +68,6 @@ func linknew(arch *LinkArch) *Link {
log.Fatalf("invalid goarch %s (want %s)", p, arch.Name)
}
- var buf string
- buf, _ = os.Getwd()
- if buf == "" {
- buf = "/???"
- }
- buf = filepath.ToSlash(buf)
-
ctxt.Headtype = headtype(obj.Getgoos())
if ctxt.Headtype < 0 {
log.Fatalf("unknown goos %s", obj.Getgoos())
From 2eeaaaae7530337c23b0d4d76ac519e677c125dd Mon Sep 17 00:00:00 2001
From: Brad Fitzpatrick
Date: Fri, 19 Feb 2016 04:29:13 +0530
Subject: [PATCH 037/117] net/http: fix bug where http2 wasn't enabled on
DefaultTransport
I had accidentally disabled a headline feature at the last second. :(
Fixes #14391
Change-Id: I1992c9b801072b7538b95c55242be174075ff932
Reviewed-on: https://go-review.googlesource.com/19672
Reviewed-by: Ian Lance Taylor
Run-TryBot: Brad Fitzpatrick
TryBot-Result: Gobot Gobot
---
src/net/http/transport.go | 10 +++++++---
src/net/http/transport_test.go | 5 +++++
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
index baf71d5e85..1e3ea11d9c 100644
--- a/src/net/http/transport.go
+++ b/src/net/http/transport.go
@@ -176,9 +176,13 @@ func (t *Transport) onceSetNextProtoDefaults() {
// Issue 14275.
return
}
- if t.ExpectContinueTimeout != 0 {
- // Unsupported in http2, so disable http2 for now.
- // Issue 13851.
+ if t.ExpectContinueTimeout != 0 && t != DefaultTransport {
+ // ExpectContinueTimeout is unsupported in http2, so
+ // if they explicitly asked for it (as opposed to just
+ // using the DefaultTransport, which sets it), then
+ // disable http2 for now.
+ //
+ // Issue 13851. (and changed in Issue 14391)
return
}
t2, err := http2configureTransport(t)
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index 0c901b30a4..d9da078fa0 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -2888,6 +2888,11 @@ func TestTransportAutomaticHTTP2(t *testing.T) {
testTransportAutoHTTP(t, &Transport{}, true)
}
+// golang.org/issue/14391: also check DefaultTransport
+func TestTransportAutomaticHTTP2_DefaultTransport(t *testing.T) {
+ testTransportAutoHTTP(t, DefaultTransport.(*Transport), true)
+}
+
func TestTransportAutomaticHTTP2_TLSNextProto(t *testing.T) {
testTransportAutoHTTP(t, &Transport{
TLSNextProto: make(map[string]func(string, *tls.Conn) RoundTripper),
From 3ddfaa5653cfc5c8663319d017a5fb4de97814f4 Mon Sep 17 00:00:00 2001
From: Benoit Sigoure
Date: Fri, 5 Feb 2016 17:18:46 -0800
Subject: [PATCH 038/117] cmd/gofmt: Ignore file not found errors.
gofmt prints an error to stderr when a file is deleted during its
`filepath.Walk()', which can happen in builds that change the tree
concurrently with gofmt running.
Change-Id: Ia1aa4804f6bc2172baf061c093e16fe56a3ee50c
Reviewed-on: https://go-review.googlesource.com/19301
Reviewed-by: Robert Griesemer
---
src/cmd/gofmt/gofmt.go | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/cmd/gofmt/gofmt.go b/src/cmd/gofmt/gofmt.go
index cfebeffe4a..b10b804fd2 100644
--- a/src/cmd/gofmt/gofmt.go
+++ b/src/cmd/gofmt/gofmt.go
@@ -143,7 +143,9 @@ func visitFile(path string, f os.FileInfo, err error) error {
if err == nil && isGoFile(f) {
err = processFile(path, nil, os.Stdout, false)
}
- if err != nil {
+ // Don't complain if a file was deleted in the meantime (i.e.
+ // the directory changed concurrently while running gofmt).
+ if err != nil && !os.IsNotExist(err) {
report(err)
}
return nil
From 952c2fd606fad19b930937ca0d5c5571d7f5d4cb Mon Sep 17 00:00:00 2001
From: Ian Gudger
Date: Thu, 18 Feb 2016 11:29:05 -0800
Subject: [PATCH 039/117] net: fix packDomainName encoding of root and invalid
names
Fixes #14372
Change-Id: I40d594582639e87ef2574d37ac868e37ffaa17dc
Reviewed-on: https://go-review.googlesource.com/19623
Reviewed-by: Matthew Dempsky
---
src/net/dnsmsg.go | 36 ++++++++++++++--
src/net/dnsmsg_test.go | 97 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 130 insertions(+), 3 deletions(-)
diff --git a/src/net/dnsmsg.go b/src/net/dnsmsg.go
index 93078fe849..2ec4c8c301 100644
--- a/src/net/dnsmsg.go
+++ b/src/net/dnsmsg.go
@@ -406,6 +406,13 @@ func packDomainName(s string, msg []byte, off int) (off1 int, ok bool) {
s += "."
}
+ // Allow root domain.
+ if s == "." {
+ msg[off] = 0
+ off++
+ return off, true
+ }
+
// Each dot ends a segment of the name.
// We trade each dot byte for a length byte.
// There is also a trailing zero.
@@ -422,8 +429,13 @@ func packDomainName(s string, msg []byte, off int) (off1 int, ok bool) {
if i-begin >= 1<<6 { // top two bits of length must be clear
return len(msg), false
}
+ if i-begin == 0 {
+ return len(msg), false
+ }
+
msg[off] = byte(i - begin)
off++
+
for j := begin; j < i; j++ {
msg[off] = s[j]
off++
@@ -494,6 +506,9 @@ Loop:
return "", len(msg), false
}
}
+ if len(s) == 0 {
+ s = "."
+ }
if ptr == 0 {
off1 = off
}
@@ -803,20 +818,32 @@ func (dns *dnsMsg) Pack() (msg []byte, ok bool) {
// Pack it in: header and then the pieces.
off := 0
off, ok = packStruct(&dh, msg, off)
+ if !ok {
+ return nil, false
+ }
for i := 0; i < len(question); i++ {
off, ok = packStruct(&question[i], msg, off)
+ if !ok {
+ return nil, false
+ }
}
for i := 0; i < len(answer); i++ {
off, ok = packRR(answer[i], msg, off)
+ if !ok {
+ return nil, false
+ }
}
for i := 0; i < len(ns); i++ {
off, ok = packRR(ns[i], msg, off)
+ if !ok {
+ return nil, false
+ }
}
for i := 0; i < len(extra); i++ {
off, ok = packRR(extra[i], msg, off)
- }
- if !ok {
- return nil, false
+ if !ok {
+ return nil, false
+ }
}
return msg[0:off], true
}
@@ -848,6 +875,9 @@ func (dns *dnsMsg) Unpack(msg []byte) bool {
for i := 0; i < len(dns.question); i++ {
off, ok = unpackStruct(&dns.question[i], msg, off)
+ if !ok {
+ return false
+ }
}
for i := 0; i < int(dh.Ancount); i++ {
rec, off, ok = unpackRR(msg, off)
diff --git a/src/net/dnsmsg_test.go b/src/net/dnsmsg_test.go
index 1078d77ceb..339fb83c62 100644
--- a/src/net/dnsmsg_test.go
+++ b/src/net/dnsmsg_test.go
@@ -10,6 +10,103 @@ import (
"testing"
)
+func TestStructPackUnpack(t *testing.T) {
+ want := dnsQuestion{
+ Name: ".",
+ Qtype: dnsTypeA,
+ Qclass: dnsClassINET,
+ }
+ buf := make([]byte, 50)
+ n, ok := packStruct(&want, buf, 0)
+ if !ok {
+ t.Fatal("packing failed")
+ }
+ buf = buf[:n]
+ got := dnsQuestion{}
+ n, ok = unpackStruct(&got, buf, 0)
+ if !ok {
+ t.Fatal("unpacking failed")
+ }
+ if n != len(buf) {
+ t.Error("unpacked different amount than packed: got n = %d, want = %d", n, len(buf))
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Errorf("got = %+v, want = %+v", got, want)
+ }
+}
+
+func TestDomainNamePackUnpack(t *testing.T) {
+ tests := []struct {
+ in string
+ want string
+ ok bool
+ }{
+ {"", ".", true},
+ {".", ".", true},
+ {"google..com", "", false},
+ {"google.com", "google.com.", true},
+ {"google..com.", "", false},
+ {"google.com.", "google.com.", true},
+ {".google.com.", "", false},
+ {"www..google.com.", "", false},
+ {"www.google.com.", "www.google.com.", true},
+ }
+
+ for _, test := range tests {
+ buf := make([]byte, 30)
+ n, ok := packDomainName(test.in, buf, 0)
+ if ok != test.ok {
+ t.Errorf("packing of %s: got ok = %t, want = %t", test.in, ok, test.ok)
+ continue
+ }
+ if !test.ok {
+ continue
+ }
+ buf = buf[:n]
+ got, n, ok := unpackDomainName(buf, 0)
+ if !ok {
+ t.Errorf("unpacking for %s failed", test.in)
+ continue
+ }
+ if n != len(buf) {
+ t.Error(
+ "unpacked different amount than packed for %s: got n = %d, want = %d",
+ test.in,
+ n,
+ len(buf),
+ )
+ }
+ if got != test.want {
+ t.Errorf("unpacking packing of %s: got = %s, want = %s", test.in, got, test.want)
+ }
+ }
+}
+
+func TestDNSPackUnpack(t *testing.T) {
+ want := dnsMsg{
+ question: []dnsQuestion{{
+ Name: ".",
+ Qtype: dnsTypeAAAA,
+ Qclass: dnsClassINET,
+ }},
+ answer: []dnsRR{},
+ ns: []dnsRR{},
+ extra: []dnsRR{},
+ }
+ b, ok := want.Pack()
+ if !ok {
+ t.Fatal("packing failed")
+ }
+ var got dnsMsg
+ ok = got.Unpack(b)
+ if !ok {
+ t.Fatal("unpacking failed")
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Errorf("got = %+v, want = %+v", got, want)
+ }
+}
+
func TestDNSParseSRVReply(t *testing.T) {
data, err := hex.DecodeString(dnsSRVReply)
if err != nil {
From b04f3b06ec347543b0eafe82dcfb0e05885d3feb Mon Sep 17 00:00:00 2001
From: Nathan VanBenschoten
Date: Tue, 22 Dec 2015 02:40:47 -0500
Subject: [PATCH 040/117] all: replace strings.Index with strings.Contains
where possible
Change-Id: Ia613f1c37bfce800ece0533a5326fca91d99a66a
Reviewed-on: https://go-review.googlesource.com/18120
Reviewed-by: Robert Griesemer
Run-TryBot: Robert Griesemer
---
src/cmd/compile/internal/big/ratconv.go | 4 ++--
src/cmd/compile/internal/gc/bexport.go | 2 +-
src/encoding/csv/writer.go | 2 +-
src/encoding/gob/codec_test.go | 2 +-
src/encoding/gob/encoder_test.go | 8 ++++----
src/encoding/gob/gobencdec_test.go | 4 ++--
src/encoding/xml/marshal.go | 2 +-
src/fmt/scan_test.go | 8 ++++----
src/go/doc/comment.go | 2 +-
src/go/types/universe.go | 2 +-
src/math/big/ratconv.go | 4 ++--
src/mime/grammar.go | 2 +-
src/net/http/fs.go | 2 +-
src/net/rpc/server_test.go | 4 ++--
src/net/url/url.go | 2 +-
src/os/exec/lp_windows.go | 2 +-
src/path/filepath/match.go | 4 ++--
src/path/filepath/match_test.go | 2 +-
src/path/match.go | 2 +-
src/regexp/regexp.go | 2 +-
src/regexp/syntax/regexp.go | 2 +-
src/runtime/debug/stack_test.go | 2 +-
src/text/template/exec.go | 2 +-
src/text/template/funcs.go | 2 +-
src/text/template/parse/lex.go | 4 ++--
src/time/format_test.go | 2 +-
26 files changed, 38 insertions(+), 38 deletions(-)
diff --git a/src/cmd/compile/internal/big/ratconv.go b/src/cmd/compile/internal/big/ratconv.go
index 4566ff4e39..57df124e88 100644
--- a/src/cmd/compile/internal/big/ratconv.go
+++ b/src/cmd/compile/internal/big/ratconv.go
@@ -15,7 +15,7 @@ import (
)
func ratTok(ch rune) bool {
- return strings.IndexRune("+-/0123456789.eE", ch) >= 0
+ return strings.ContainsRune("+-/0123456789.eE", ch)
}
// Scan is a support routine for fmt.Scanner. It accepts the formats
@@ -25,7 +25,7 @@ func (z *Rat) Scan(s fmt.ScanState, ch rune) error {
if err != nil {
return err
}
- if strings.IndexRune("efgEFGv", ch) < 0 {
+ if !strings.ContainsRune("efgEFGv", ch) {
return errors.New("Rat.Scan: invalid verb")
}
if _, ok := z.SetString(string(tok)); !ok {
diff --git a/src/cmd/compile/internal/gc/bexport.go b/src/cmd/compile/internal/gc/bexport.go
index b49f0fb552..3edd0488e7 100644
--- a/src/cmd/compile/internal/gc/bexport.go
+++ b/src/cmd/compile/internal/gc/bexport.go
@@ -877,7 +877,7 @@ func (p *exporter) byte(b byte) {
// tracef is like fmt.Printf but it rewrites the format string
// to take care of indentation.
func (p *exporter) tracef(format string, args ...interface{}) {
- if strings.IndexAny(format, "<>\n") >= 0 {
+ if strings.ContainsAny(format, "<>\n") {
var buf bytes.Buffer
for i := 0; i < len(format); i++ {
// no need to deal with runes
diff --git a/src/encoding/csv/writer.go b/src/encoding/csv/writer.go
index 353d91f238..a6056285b4 100644
--- a/src/encoding/csv/writer.go
+++ b/src/encoding/csv/writer.go
@@ -130,7 +130,7 @@ func (w *Writer) fieldNeedsQuotes(field string) bool {
if field == "" {
return false
}
- if field == `\.` || strings.IndexRune(field, w.Comma) >= 0 || strings.IndexAny(field, "\"\r\n") >= 0 {
+ if field == `\.` || strings.ContainsRune(field, w.Comma) || strings.ContainsAny(field, "\"\r\n") {
return true
}
diff --git a/src/encoding/gob/codec_test.go b/src/encoding/gob/codec_test.go
index 8efcdc78ff..b772171f93 100644
--- a/src/encoding/gob/codec_test.go
+++ b/src/encoding/gob/codec_test.go
@@ -970,7 +970,7 @@ func TestBadRecursiveType(t *testing.T) {
err := NewEncoder(b).Encode(&rec)
if err == nil {
t.Error("expected error; got none")
- } else if strings.Index(err.Error(), "recursive") < 0 {
+ } else if !strings.Contains(err.Error(), "recursive") {
t.Error("expected recursive type error; got", err)
}
// Can't test decode easily because we can't encode one, so we can't pass one to a Decoder.
diff --git a/src/encoding/gob/encoder_test.go b/src/encoding/gob/encoder_test.go
index 570d79696b..811dd2b18c 100644
--- a/src/encoding/gob/encoder_test.go
+++ b/src/encoding/gob/encoder_test.go
@@ -280,7 +280,7 @@ func TestValueError(t *testing.T) {
}
t4p := &Type4{3}
var t4 Type4 // note: not a pointer.
- if err := encAndDec(t4p, t4); err == nil || strings.Index(err.Error(), "pointer") < 0 {
+ if err := encAndDec(t4p, t4); err == nil || !strings.Contains(err.Error(), "pointer") {
t.Error("expected error about pointer; got", err)
}
}
@@ -388,7 +388,7 @@ func TestSingletons(t *testing.T) {
t.Errorf("expected error decoding %v: %s", test.in, test.err)
continue
case err != nil && test.err != "":
- if strings.Index(err.Error(), test.err) < 0 {
+ if !strings.Contains(err.Error(), test.err) {
t.Errorf("wrong error decoding %v: wanted %s, got %v", test.in, test.err, err)
}
continue
@@ -414,7 +414,7 @@ func TestStructNonStruct(t *testing.T) {
var ns NonStruct
if err := encAndDec(s, &ns); err == nil {
t.Error("should get error for struct/non-struct")
- } else if strings.Index(err.Error(), "type") < 0 {
+ } else if !strings.Contains(err.Error(), "type") {
t.Error("for struct/non-struct expected type error; got", err)
}
// Now try the other way
@@ -424,7 +424,7 @@ func TestStructNonStruct(t *testing.T) {
}
if err := encAndDec(ns, &s); err == nil {
t.Error("should get error for non-struct/struct")
- } else if strings.Index(err.Error(), "type") < 0 {
+ } else if !strings.Contains(err.Error(), "type") {
t.Error("for non-struct/struct expected type error; got", err)
}
}
diff --git a/src/encoding/gob/gobencdec_test.go b/src/encoding/gob/gobencdec_test.go
index eb76b481d1..d674f0c784 100644
--- a/src/encoding/gob/gobencdec_test.go
+++ b/src/encoding/gob/gobencdec_test.go
@@ -548,7 +548,7 @@ func TestGobEncoderFieldTypeError(t *testing.T) {
if err == nil {
t.Fatal("expected decode error for mismatched fields (encoder to non-decoder)")
}
- if strings.Index(err.Error(), "type") < 0 {
+ if !strings.Contains(err.Error(), "type") {
t.Fatal("expected type error; got", err)
}
// Non-encoder to GobDecoder: error
@@ -562,7 +562,7 @@ func TestGobEncoderFieldTypeError(t *testing.T) {
if err == nil {
t.Fatal("expected decode error for mismatched fields (non-encoder to decoder)")
}
- if strings.Index(err.Error(), "type") < 0 {
+ if !strings.Contains(err.Error(), "type") {
t.Fatal("expected type error; got", err)
}
}
diff --git a/src/encoding/xml/marshal.go b/src/encoding/xml/marshal.go
index 8ebd693030..9fcd5d7695 100644
--- a/src/encoding/xml/marshal.go
+++ b/src/encoding/xml/marshal.go
@@ -850,7 +850,7 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
switch k {
case reflect.String:
s := vf.String()
- dashDash = strings.Index(s, "--") >= 0
+ dashDash = strings.Contains(s, "--")
dashLast = s[len(s)-1] == '-'
if !dashDash {
p.WriteString(s)
diff --git a/src/fmt/scan_test.go b/src/fmt/scan_test.go
index 7ac74dcb4b..ce6f08659a 100644
--- a/src/fmt/scan_test.go
+++ b/src/fmt/scan_test.go
@@ -519,7 +519,7 @@ func testScanfMulti(name string, t *testing.T) {
if err != nil {
if test.err == "" {
t.Errorf("got error scanning (%q, %q): %q", test.format, test.text, err)
- } else if strings.Index(err.Error(), test.err) < 0 {
+ } else if !strings.Contains(err.Error(), test.err) {
t.Errorf("got wrong error scanning (%q, %q): %q; expected %q", test.format, test.text, err, test.err)
}
continue
@@ -613,7 +613,7 @@ func TestScanNotPointer(t *testing.T) {
_, err := Fscan(r, a)
if err == nil {
t.Error("expected error scanning non-pointer")
- } else if strings.Index(err.Error(), "pointer") < 0 {
+ } else if !strings.Contains(err.Error(), "pointer") {
t.Errorf("expected pointer error scanning non-pointer, got: %s", err)
}
}
@@ -623,7 +623,7 @@ func TestScanlnNoNewline(t *testing.T) {
_, err := Sscanln("1 x\n", &a)
if err == nil {
t.Error("expected error scanning string missing newline")
- } else if strings.Index(err.Error(), "newline") < 0 {
+ } else if !strings.Contains(err.Error(), "newline") {
t.Errorf("expected newline error scanning string missing newline, got: %s", err)
}
}
@@ -634,7 +634,7 @@ func TestScanlnWithMiddleNewline(t *testing.T) {
_, err := Fscanln(r, &a, &b)
if err == nil {
t.Error("expected error scanning string with extra newline")
- } else if strings.Index(err.Error(), "newline") < 0 {
+ } else if !strings.Contains(err.Error(), "newline") {
t.Errorf("expected newline error scanning string with extra newline, got: %s", err)
}
}
diff --git a/src/go/doc/comment.go b/src/go/doc/comment.go
index f414ca4090..5631539abc 100644
--- a/src/go/doc/comment.go
+++ b/src/go/doc/comment.go
@@ -225,7 +225,7 @@ func heading(line string) string {
}
// exclude lines with illegal characters
- if strings.IndexAny(line, ",.;:!?+*/=()[]{}_^°&§~%#@<\">\\") >= 0 {
+ if strings.ContainsAny(line, ",.;:!?+*/=()[]{}_^°&§~%#@<\">\\") {
return ""
}
diff --git a/src/go/types/universe.go b/src/go/types/universe.go
index 40185c1ad4..cc3bd5a370 100644
--- a/src/go/types/universe.go
+++ b/src/go/types/universe.go
@@ -196,7 +196,7 @@ func init() {
//
func def(obj Object) {
name := obj.Name()
- if strings.Index(name, " ") >= 0 {
+ if strings.Contains(name, " ") {
return // nothing to do
}
// fix Obj link for named types
diff --git a/src/math/big/ratconv.go b/src/math/big/ratconv.go
index 4566ff4e39..57df124e88 100644
--- a/src/math/big/ratconv.go
+++ b/src/math/big/ratconv.go
@@ -15,7 +15,7 @@ import (
)
func ratTok(ch rune) bool {
- return strings.IndexRune("+-/0123456789.eE", ch) >= 0
+ return strings.ContainsRune("+-/0123456789.eE", ch)
}
// Scan is a support routine for fmt.Scanner. It accepts the formats
@@ -25,7 +25,7 @@ func (z *Rat) Scan(s fmt.ScanState, ch rune) error {
if err != nil {
return err
}
- if strings.IndexRune("efgEFGv", ch) < 0 {
+ if !strings.ContainsRune("efgEFGv", ch) {
return errors.New("Rat.Scan: invalid verb")
}
if _, ok := z.SetString(string(tok)); !ok {
diff --git a/src/mime/grammar.go b/src/mime/grammar.go
index 31b66e8f03..6a6f71dbd4 100644
--- a/src/mime/grammar.go
+++ b/src/mime/grammar.go
@@ -11,7 +11,7 @@ import (
// isTSpecial reports whether rune is in 'tspecials' as defined by RFC
// 1521 and RFC 2045.
func isTSpecial(r rune) bool {
- return strings.IndexRune(`()<>@,;:\"/[]?=`, r) != -1
+ return strings.ContainsRune(`()<>@,;:\"/[]?=`, r)
}
// isTokenChar reports whether rune is in 'token' as defined by RFC
diff --git a/src/net/http/fs.go b/src/net/http/fs.go
index f61c138c1d..8a5b8bba37 100644
--- a/src/net/http/fs.go
+++ b/src/net/http/fs.go
@@ -34,7 +34,7 @@ import (
type Dir string
func (d Dir) Open(name string) (File, error) {
- if filepath.Separator != '/' && strings.IndexRune(name, filepath.Separator) >= 0 ||
+ if filepath.Separator != '/' && strings.ContainsRune(name, filepath.Separator) ||
strings.Contains(name, "\x00") {
return nil, errors.New("http: invalid character in file path")
}
diff --git a/src/net/rpc/server_test.go b/src/net/rpc/server_test.go
index 8871c88133..cf171ac4fb 100644
--- a/src/net/rpc/server_test.go
+++ b/src/net/rpc/server_test.go
@@ -183,7 +183,7 @@ func testRPC(t *testing.T, addr string) {
err = client.Call("Arith.Unknown", args, reply)
if err == nil {
t.Error("expected error calling unknown service")
- } else if strings.Index(err.Error(), "method") < 0 {
+ } else if !strings.Contains(err.Error(), "method") {
t.Error("expected error about method; got", err)
}
@@ -226,7 +226,7 @@ func testRPC(t *testing.T, addr string) {
err = client.Call("Arith.Add", reply, reply) // args, reply would be the correct thing to use
if err == nil {
t.Error("expected error calling Arith.Add with wrong arg type")
- } else if strings.Index(err.Error(), "type") < 0 {
+ } else if !strings.Contains(err.Error(), "type") {
t.Error("expected error about type; got", err)
}
diff --git a/src/net/url/url.go b/src/net/url/url.go
index 1a93e3496e..b7e25ecfcb 100644
--- a/src/net/url/url.go
+++ b/src/net/url/url.go
@@ -511,7 +511,7 @@ func parseAuthority(authority string) (user *Userinfo, host string, err error) {
return nil, host, nil
}
userinfo := authority[:i]
- if strings.Index(userinfo, ":") < 0 {
+ if !strings.Contains(userinfo, ":") {
if userinfo, err = unescape(userinfo, encodeUserPassword); err != nil {
return nil, "", err
}
diff --git a/src/os/exec/lp_windows.go b/src/os/exec/lp_windows.go
index c3efd67e9e..0b0712dcad 100644
--- a/src/os/exec/lp_windows.go
+++ b/src/os/exec/lp_windows.go
@@ -70,7 +70,7 @@ func LookPath(file string) (f string, err error) {
}
exts = append(exts, e)
}
- if strings.IndexAny(file, `:\/`) != -1 {
+ if strings.ContainsAny(file, `:\/`) {
if f, err = findExecutable(file, exts); err == nil {
return
}
diff --git a/src/path/filepath/match.go b/src/path/filepath/match.go
index 89f16de355..d64bf84fc0 100644
--- a/src/path/filepath/match.go
+++ b/src/path/filepath/match.go
@@ -49,7 +49,7 @@ Pattern:
star, chunk, pattern = scanChunk(pattern)
if star && chunk == "" {
// Trailing * matches rest of string unless it has a /.
- return strings.Index(name, string(Separator)) < 0, nil
+ return !strings.Contains(name, string(Separator)), nil
}
// Look for match at current position.
t, ok, err := matchChunk(chunk, name)
@@ -305,5 +305,5 @@ func glob(dir, pattern string, matches []string) (m []string, e error) {
// recognized by Match.
func hasMeta(path string) bool {
// TODO(niemeyer): Should other magic characters be added here?
- return strings.IndexAny(path, "*?[") >= 0
+ return strings.ContainsAny(path, "*?[")
}
diff --git a/src/path/filepath/match_test.go b/src/path/filepath/match_test.go
index 0edbfc70c4..d8bab7f4da 100644
--- a/src/path/filepath/match_test.go
+++ b/src/path/filepath/match_test.go
@@ -88,7 +88,7 @@ func TestMatch(t *testing.T) {
pattern := tt.pattern
s := tt.s
if runtime.GOOS == "windows" {
- if strings.Index(pattern, "\\") >= 0 {
+ if strings.Contains(pattern, "\\") {
// no escape allowed on windows.
continue
}
diff --git a/src/path/match.go b/src/path/match.go
index 75dd3b38e7..8d9aa513b1 100644
--- a/src/path/match.go
+++ b/src/path/match.go
@@ -43,7 +43,7 @@ Pattern:
star, chunk, pattern = scanChunk(pattern)
if star && chunk == "" {
// Trailing * matches rest of string unless it has a /.
- return strings.Index(name, "/") < 0, nil
+ return !strings.Contains(name, "/"), nil
}
// Look for match at current position.
t, ok, err := matchChunk(chunk, name)
diff --git a/src/regexp/regexp.go b/src/regexp/regexp.go
index d7d0edb993..42ae6e1d7a 100644
--- a/src/regexp/regexp.go
+++ b/src/regexp/regexp.go
@@ -454,7 +454,7 @@ func Match(pattern string, b []byte) (matched bool, err error) {
// in Expand, so for instance $1 represents the text of the first submatch.
func (re *Regexp) ReplaceAllString(src, repl string) string {
n := 2
- if strings.Index(repl, "$") >= 0 {
+ if strings.Contains(repl, "$") {
n = 2 * (re.numSubexp + 1)
}
b := re.replaceAll(nil, src, n, func(dst []byte, match []int) []byte {
diff --git a/src/regexp/syntax/regexp.go b/src/regexp/syntax/regexp.go
index 75822cf981..ca5724063b 100644
--- a/src/regexp/syntax/regexp.go
+++ b/src/regexp/syntax/regexp.go
@@ -252,7 +252,7 @@ const meta = `\.+*?()|[]{}^$`
func escape(b *bytes.Buffer, r rune, force bool) {
if unicode.IsPrint(r) {
- if strings.IndexRune(meta, r) >= 0 || force {
+ if strings.ContainsRune(meta, r) || force {
b.WriteRune('\\')
}
b.WriteRune(r)
diff --git a/src/runtime/debug/stack_test.go b/src/runtime/debug/stack_test.go
index f54437231b..9376e82b84 100644
--- a/src/runtime/debug/stack_test.go
+++ b/src/runtime/debug/stack_test.go
@@ -59,7 +59,7 @@ func TestStack(t *testing.T) {
}
func check(t *testing.T, line, has string) {
- if strings.Index(line, has) < 0 {
+ if !strings.Contains(line, has) {
t.Errorf("expected %q in %q", has, line)
}
}
diff --git a/src/text/template/exec.go b/src/text/template/exec.go
index efe1817173..5ea45a4c53 100644
--- a/src/text/template/exec.go
+++ b/src/text/template/exec.go
@@ -446,7 +446,7 @@ func (s *state) idealConstant(constant *parse.NumberNode) reflect.Value {
switch {
case constant.IsComplex:
return reflect.ValueOf(constant.Complex128) // incontrovertible.
- case constant.IsFloat && !isHexConstant(constant.Text) && strings.IndexAny(constant.Text, ".eE") >= 0:
+ case constant.IsFloat && !isHexConstant(constant.Text) && strings.ContainsAny(constant.Text, ".eE"):
return reflect.ValueOf(constant.Float64)
case constant.IsInt:
n := int(constant.Int64)
diff --git a/src/text/template/funcs.go b/src/text/template/funcs.go
index 49e9e7419a..58b8ea372d 100644
--- a/src/text/template/funcs.go
+++ b/src/text/template/funcs.go
@@ -515,7 +515,7 @@ func HTMLEscape(w io.Writer, b []byte) {
// HTMLEscapeString returns the escaped HTML equivalent of the plain text data s.
func HTMLEscapeString(s string) string {
// Avoid allocation if we can.
- if strings.IndexAny(s, `'"&<>`) < 0 {
+ if !strings.ContainsAny(s, `'"&<>`) {
return s
}
var b bytes.Buffer
diff --git a/src/text/template/parse/lex.go b/src/text/template/parse/lex.go
index ea93e05142..079c0ea6f7 100644
--- a/src/text/template/parse/lex.go
+++ b/src/text/template/parse/lex.go
@@ -155,7 +155,7 @@ func (l *lexer) ignore() {
// accept consumes the next rune if it's from the valid set.
func (l *lexer) accept(valid string) bool {
- if strings.IndexRune(valid, l.next()) >= 0 {
+ if strings.ContainsRune(valid, l.next()) {
return true
}
l.backup()
@@ -164,7 +164,7 @@ func (l *lexer) accept(valid string) bool {
// acceptRun consumes a run of runes from the valid set.
func (l *lexer) acceptRun(valid string) {
- for strings.IndexRune(valid, l.next()) >= 0 {
+ for strings.ContainsRune(valid, l.next()) {
}
l.backup()
}
diff --git a/src/time/format_test.go b/src/time/format_test.go
index af950a7c25..8c47dbcdd1 100644
--- a/src/time/format_test.go
+++ b/src/time/format_test.go
@@ -447,7 +447,7 @@ func TestParseErrors(t *testing.T) {
_, err := Parse(test.format, test.value)
if err == nil {
t.Errorf("expected error for %q %q", test.format, test.value)
- } else if strings.Index(err.Error(), test.expect) < 0 {
+ } else if !strings.Contains(err.Error(), test.expect) {
t.Errorf("expected error with %q for %q %q; got %s", test.expect, test.format, test.value, err)
}
}
From 76f272d71746fec4cc91f6772e81d8745aa65384 Mon Sep 17 00:00:00 2001
From: Russ Cox
Date: Sun, 24 Jan 2016 11:14:46 -0500
Subject: [PATCH 041/117] cmd/asm: remove support for amd64 3DNow! instructions
3DNotAnymore!
These only ever existed on AMD (not Intel) processors,
and AMD cancelled support for them in August 2010.
Change-Id: Ia362259add9d4f5788fd151fb373f91288677407
Reviewed-on: https://go-review.googlesource.com/19611
Reviewed-by: Ian Lance Taylor
---
src/cmd/asm/internal/arch/arch.go | 2 --
src/cmd/internal/obj/x86/a.out.go | 24 -------------------
src/cmd/internal/obj/x86/anames.go | 23 -------------------
src/cmd/internal/obj/x86/asm6.go | 37 ------------------------------
4 files changed, 86 deletions(-)
diff --git a/src/cmd/asm/internal/arch/arch.go b/src/cmd/asm/internal/arch/arch.go
index c14a13cdb1..f9436cb7f2 100644
--- a/src/cmd/asm/internal/arch/arch.go
+++ b/src/cmd/asm/internal/arch/arch.go
@@ -162,8 +162,6 @@ func archX86(linkArch *obj.LinkArch) *Arch {
instructions["MOVDQ2Q"] = x86.AMOVQ
instructions["MOVNTDQ"] = x86.AMOVNTO
instructions["MOVOA"] = x86.AMOVO
- instructions["PF2ID"] = x86.APF2IL
- instructions["PI2FD"] = x86.API2FL
instructions["PSLLDQ"] = x86.APSLLO
instructions["PSRLDQ"] = x86.APSRLO
instructions["PADDD"] = x86.APADDL
diff --git a/src/cmd/internal/obj/x86/a.out.go b/src/cmd/internal/obj/x86/a.out.go
index 12eaa90bf6..28c973b4a8 100644
--- a/src/cmd/internal/obj/x86/a.out.go
+++ b/src/cmd/internal/obj/x86/a.out.go
@@ -644,23 +644,6 @@ const (
APEXTRD
APEXTRQ
APEXTRW
- APFACC
- APFADD
- APFCMPEQ
- APFCMPGE
- APFCMPGT
- APFMAX
- APFMIN
- APFMUL
- APFNACC
- APFPNACC
- APFRCP
- APFRCPI2T
- APFRCPIT1
- APFRSQIT1
- APFRSQRT
- APFSUB
- APFSUBR
APHADDD
APHADDSW
APHADDW
@@ -691,7 +674,6 @@ const (
APMOVZXWD
APMOVZXWQ
APMULDQ
- APMULHRW
APMULHUW
APMULHW
APMULLD
@@ -722,7 +704,6 @@ const (
APSUBUSB
APSUBUSW
APSUBW
- APSWAPL
APUNPCKHBW
APUNPCKHLQ
APUNPCKHQDQ
@@ -761,11 +742,6 @@ const (
AUNPCKLPS
AXORPD
AXORPS
-
- APF2IW
- APF2IL
- API2FW
- API2FL
ARETFW
ARETFL
ARETFQ
diff --git a/src/cmd/internal/obj/x86/anames.go b/src/cmd/internal/obj/x86/anames.go
index 1875eae418..3c3bc03622 100644
--- a/src/cmd/internal/obj/x86/anames.go
+++ b/src/cmd/internal/obj/x86/anames.go
@@ -593,23 +593,6 @@ var Anames = []string{
"PEXTRD",
"PEXTRQ",
"PEXTRW",
- "PFACC",
- "PFADD",
- "PFCMPEQ",
- "PFCMPGE",
- "PFCMPGT",
- "PFMAX",
- "PFMIN",
- "PFMUL",
- "PFNACC",
- "PFPNACC",
- "PFRCP",
- "PFRCPI2T",
- "PFRCPIT1",
- "PFRSQIT1",
- "PFRSQRT",
- "PFSUB",
- "PFSUBR",
"PHADDD",
"PHADDSW",
"PHADDW",
@@ -640,7 +623,6 @@ var Anames = []string{
"PMOVZXWD",
"PMOVZXWQ",
"PMULDQ",
- "PMULHRW",
"PMULHUW",
"PMULHW",
"PMULLD",
@@ -671,7 +653,6 @@ var Anames = []string{
"PSUBUSB",
"PSUBUSW",
"PSUBW",
- "PSWAPL",
"PUNPCKHBW",
"PUNPCKHLQ",
"PUNPCKHQDQ",
@@ -710,10 +691,6 @@ var Anames = []string{
"UNPCKLPS",
"XORPD",
"XORPS",
- "PF2IW",
- "PF2IL",
- "PI2FW",
- "PI2FL",
"RETFW",
"RETFL",
"RETFQ",
diff --git a/src/cmd/internal/obj/x86/asm6.go b/src/cmd/internal/obj/x86/asm6.go
index 4ed1d8790b..a06d3097ad 100644
--- a/src/cmd/internal/obj/x86/asm6.go
+++ b/src/cmd/internal/obj/x86/asm6.go
@@ -184,7 +184,6 @@ const (
Zm2_r
Zm_r_xm
Zm_r_i_xm
- Zm_r_3d
Zm_r_xm_nr
Zr_m_xm_nr
Zibm_r /* mmx1,mmx2/mem64,imm8 */
@@ -753,10 +752,6 @@ var yxrrl = []ytab{
{Yxr, Ynone, Yrl, Zm_r, 1},
}
-var ymfp = []ytab{
- {Ymm, Ynone, Ymr, Zm_r_3d, 1},
-}
-
var ymrxr = []ytab{
{Ymr, Ynone, Yxr, Zm_r, 1},
{Yxm, Ynone, Yxr, Zm_r_xm, 1},
@@ -1085,7 +1080,6 @@ var optab =
{ACVTPD2PS, yxm, Pe, [23]uint8{0x5a}},
{ACVTPS2PL, yxcvm1, Px, [23]uint8{Pe, 0x5b, Pm, 0x2d}},
{ACVTPS2PD, yxm, Pm, [23]uint8{0x5a}},
- {API2FW, ymfp, Px, [23]uint8{0x0c}},
{ACVTSD2SL, yxcvfl, Pf2, [23]uint8{0x2d}},
{ACVTSD2SQ, yxcvfq, Pw, [23]uint8{Pf2, 0x2d}},
{ACVTSD2SS, yxm, Pf2, [23]uint8{0x5a}},
@@ -1303,26 +1297,6 @@ var optab =
{APEXTRB, yextr, Pq, [23]uint8{0x3a, 0x14, 00}},
{APEXTRD, yextr, Pq, [23]uint8{0x3a, 0x16, 00}},
{APEXTRQ, yextr, Pq3, [23]uint8{0x3a, 0x16, 00}},
- {APF2IL, ymfp, Px, [23]uint8{0x1d}},
- {APF2IW, ymfp, Px, [23]uint8{0x1c}},
- {API2FL, ymfp, Px, [23]uint8{0x0d}},
- {APFACC, ymfp, Px, [23]uint8{0xae}},
- {APFADD, ymfp, Px, [23]uint8{0x9e}},
- {APFCMPEQ, ymfp, Px, [23]uint8{0xb0}},
- {APFCMPGE, ymfp, Px, [23]uint8{0x90}},
- {APFCMPGT, ymfp, Px, [23]uint8{0xa0}},
- {APFMAX, ymfp, Px, [23]uint8{0xa4}},
- {APFMIN, ymfp, Px, [23]uint8{0x94}},
- {APFMUL, ymfp, Px, [23]uint8{0xb4}},
- {APFNACC, ymfp, Px, [23]uint8{0x8a}},
- {APFPNACC, ymfp, Px, [23]uint8{0x8e}},
- {APFRCP, ymfp, Px, [23]uint8{0x96}},
- {APFRCPIT1, ymfp, Px, [23]uint8{0xa6}},
- {APFRCPI2T, ymfp, Px, [23]uint8{0xb6}},
- {APFRSQIT1, ymfp, Px, [23]uint8{0xa7}},
- {APFRSQRT, ymfp, Px, [23]uint8{0x97}},
- {APFSUB, ymfp, Px, [23]uint8{0x9a}},
- {APFSUBR, ymfp, Px, [23]uint8{0xaa}},
{APHADDD, ymmxmm0f38, Px, [23]uint8{0x0F, 0x38, 0x02, 0, 0x66, 0x0F, 0x38, 0x02, 0}},
{APHADDSW, yxm_q4, Pq4, [23]uint8{0x03}},
{APHADDW, yxm_q4, Pq4, [23]uint8{0x01}},
@@ -1353,7 +1327,6 @@ var optab =
{APMOVZXWD, yxm_q4, Pq4, [23]uint8{0x33}},
{APMOVZXWQ, yxm_q4, Pq4, [23]uint8{0x34}},
{APMULDQ, yxm_q4, Pq4, [23]uint8{0x28}},
- {APMULHRW, ymfp, Px, [23]uint8{0xb7}},
{APMULHUW, ymm, Py1, [23]uint8{0xe4, Pe, 0xe4}},
{APMULHW, ymm, Py1, [23]uint8{0xe5, Pe, 0xe5}},
{APMULLD, yxm_q4, Pq4, [23]uint8{0x40}},
@@ -1395,7 +1368,6 @@ var optab =
{APSUBUSB, yxm, Pe, [23]uint8{0xd8}},
{APSUBUSW, yxm, Pe, [23]uint8{0xd9}},
{APSUBW, yxm, Pe, [23]uint8{0xf9}},
- {APSWAPL, ymfp, Px, [23]uint8{0xbb}},
{APUNPCKHBW, ymm, Py1, [23]uint8{0x68, Pe, 0x68}},
{APUNPCKHLQ, ymm, Py1, [23]uint8{0x6a, Pe, 0x6a}},
{APUNPCKHQDQ, yxm, Pe, [23]uint8{0x6d}},
@@ -3533,15 +3505,6 @@ func doasm(ctxt *obj.Link, p *obj.Prog) {
ctxt.Andptr[0] = byte(p.To.Offset)
ctxt.Andptr = ctxt.Andptr[1:]
- case Zm_r_3d:
- ctxt.Andptr[0] = 0x0f
- ctxt.Andptr = ctxt.Andptr[1:]
- ctxt.Andptr[0] = 0x0f
- ctxt.Andptr = ctxt.Andptr[1:]
- asmand(ctxt, p, &p.From, &p.To)
- ctxt.Andptr[0] = byte(op)
- ctxt.Andptr = ctxt.Andptr[1:]
-
case Zibm_r, Zibr_m:
for {
tmp1 := z
From 0b4f5782664b1e5ff6006cc3a66de520ed1c7c79 Mon Sep 17 00:00:00 2001
From: Russ Cox
Date: Mon, 25 Jan 2016 15:21:10 -0500
Subject: [PATCH 042/117] cmd/asm: remove nonexistent amd64 instructions
These have no accepted input syntax and,
as far as I can tell, do not actually exist.
Change-Id: Iafdfb71adccad76230191d922eb7ddf78b7d5898
Reviewed-on: https://go-review.googlesource.com/19612
Reviewed-by: Ian Lance Taylor
---
src/cmd/internal/obj/x86/a.out.go | 9 ---------
src/cmd/internal/obj/x86/anames.go | 9 ---------
src/cmd/internal/obj/x86/asm6.go | 2 --
3 files changed, 20 deletions(-)
diff --git a/src/cmd/internal/obj/x86/a.out.go b/src/cmd/internal/obj/x86/a.out.go
index 28c973b4a8..dacf612bc2 100644
--- a/src/cmd/internal/obj/x86/a.out.go
+++ b/src/cmd/internal/obj/x86/a.out.go
@@ -289,8 +289,6 @@ const (
AFMOVX
AFMOVXP
- AFCOMB
- AFCOMBP
AFCOMD
AFCOMDP
AFCOMDPP
@@ -620,14 +618,7 @@ const (
APADDUSW
APADDW
APAND
- APANDB
- APANDL
APANDN
- APANDSB
- APANDSW
- APANDUSB
- APANDUSW
- APANDW
APAVGB
APAVGW
APCMPEQB
diff --git a/src/cmd/internal/obj/x86/anames.go b/src/cmd/internal/obj/x86/anames.go
index 3c3bc03622..3b59e2f36f 100644
--- a/src/cmd/internal/obj/x86/anames.go
+++ b/src/cmd/internal/obj/x86/anames.go
@@ -255,8 +255,6 @@ var Anames = []string{
"FMOVWP",
"FMOVX",
"FMOVXP",
- "FCOMB",
- "FCOMBP",
"FCOMD",
"FCOMDP",
"FCOMDPP",
@@ -569,14 +567,7 @@ var Anames = []string{
"PADDUSW",
"PADDW",
"PAND",
- "PANDB",
- "PANDL",
"PANDN",
- "PANDSB",
- "PANDSW",
- "PANDUSB",
- "PANDUSW",
- "PANDW",
"PAVGB",
"PAVGW",
"PCMPEQB",
diff --git a/src/cmd/internal/obj/x86/asm6.go b/src/cmd/internal/obj/x86/asm6.go
index a06d3097ad..2b71822799 100644
--- a/src/cmd/internal/obj/x86/asm6.go
+++ b/src/cmd/internal/obj/x86/asm6.go
@@ -1525,8 +1525,6 @@ var optab =
{AFCMOVNE, yfcmv, Px, [23]uint8{0xdb, 01}},
{AFCMOVNU, yfcmv, Px, [23]uint8{0xdb, 03}},
{AFCMOVUN, yfcmv, Px, [23]uint8{0xda, 03}},
- {AFCOMB, nil, 0, [23]uint8{}},
- {AFCOMBP, nil, 0, [23]uint8{}},
{AFCOMD, yfadd, Px, [23]uint8{0xdc, 02, 0xd8, 02, 0xdc, 02}}, /* botch */
{AFCOMDP, yfadd, Px, [23]uint8{0xdc, 03, 0xd8, 03, 0xdc, 03}}, /* botch */
{AFCOMDPP, ycompp, Px, [23]uint8{0xde, 03}},
From 51b624e6a29b135ce0fadb22b678acf4998ff16f Mon Sep 17 00:00:00 2001
From: Russ Cox
Date: Thu, 28 Jan 2016 22:50:03 -0500
Subject: [PATCH 043/117] cmd/link: remove alternate -X flag spelling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The Go 1.6 release notes say we'll remove the “-X name value” form
(in favor of the “-X name=value” form) in Go 1.7.
Do that.
Also establish the doc/go1.7.txt file.
Change-Id: Ie4565a6bc5dbcf155181754d8d92bfbb23c75338
Reviewed-on: https://go-review.googlesource.com/19614
Reviewed-by: Ian Lance Taylor
---
doc/go1.7.txt | 13 +++++++++++++
src/cmd/go/go_test.go | 4 ++--
src/cmd/link/internal/ld/pobj.go | 27 ---------------------------
test/linkx_run.go | 2 +-
4 files changed, 16 insertions(+), 30 deletions(-)
create mode 100644 doc/go1.7.txt
diff --git a/doc/go1.7.txt b/doc/go1.7.txt
new file mode 100644
index 0000000000..b2573bef83
--- /dev/null
+++ b/doc/go1.7.txt
@@ -0,0 +1,13 @@
+Tools:
+
+cmd/link: "-X name value" form gone (CL XXX)
+
+Ports:
+
+SOMETHING WILL HAPPEN
+
+API additions and behavior changes:
+
+SOMETHING WILL HAPPEN
+
+
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index e55fc360de..7d38915176 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -1657,8 +1657,8 @@ func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) {
func main() {
println(extern)
}`)
- tg.run("run", "-ldflags", `-X main.extern "hello world"`, tg.path("main.go"))
- tg.grepStderr("^hello world", `ldflags -X main.extern 'hello world' failed`)
+ tg.run("run", "-ldflags", `-X "main.extern=hello world"`, tg.path("main.go"))
+ tg.grepStderr("^hello world", `ldflags -X "main.extern=hello world"' failed`)
}
func TestGoTestCpuprofileLeavesBinaryBehind(t *testing.T) {
diff --git a/src/cmd/link/internal/ld/pobj.go b/src/cmd/link/internal/ld/pobj.go
index 808d377f8a..9ec14c24ed 100644
--- a/src/cmd/link/internal/ld/pobj.go
+++ b/src/cmd/link/internal/ld/pobj.go
@@ -119,33 +119,6 @@ func Ldmain() {
obj.Flagstr("memprofile", "write memory profile to `file`", &memprofile)
obj.Flagint64("memprofilerate", "set runtime.MemProfileRate to `rate`", &memprofilerate)
- // Clumsy hack to preserve old two-argument -X name val syntax for old scripts.
- // Rewrite that syntax into new syntax -X name=val.
- // TODO(rsc): Delete this hack in Go 1.6 or later.
- var args []string
- for i := 0; i < len(os.Args); i++ {
- arg := os.Args[i]
- if (arg == "-X" || arg == "--X") && i+2 < len(os.Args) && !strings.Contains(os.Args[i+1], "=") {
- fmt.Fprintf(os.Stderr, "link: warning: option %s %s %s may not work in future releases; use %s %s=%s\n",
- arg, os.Args[i+1], os.Args[i+2],
- arg, os.Args[i+1], os.Args[i+2])
- args = append(args, arg)
- args = append(args, os.Args[i+1]+"="+os.Args[i+2])
- i += 2
- continue
- }
- if (strings.HasPrefix(arg, "-X=") || strings.HasPrefix(arg, "--X=")) && i+1 < len(os.Args) && strings.Count(arg, "=") == 1 {
- fmt.Fprintf(os.Stderr, "link: warning: option %s %s may not work in future releases; use %s=%s\n",
- arg, os.Args[i+1],
- arg, os.Args[i+1])
- args = append(args, arg+"="+os.Args[i+1])
- i++
- continue
- }
- args = append(args, arg)
- }
- os.Args = args
-
obj.Flagparse(usage)
startProfile()
diff --git a/test/linkx_run.go b/test/linkx_run.go
index a6c7c67014..440271ac4a 100644
--- a/test/linkx_run.go
+++ b/test/linkx_run.go
@@ -18,7 +18,7 @@ import (
)
func main() {
- test(" ") // old deprecated syntax
+ // test(" ") // old deprecated & removed syntax
test("=") // new syntax
}
From 3e23442518d9c66def2ae48f83026e29c5f26609 Mon Sep 17 00:00:00 2001
From: Russ Cox
Date: Thu, 28 Jan 2016 22:51:50 -0500
Subject: [PATCH 044/117] cmd/go: remove GO15VENDOREXPERIMENT variable
The Go 1.6 release notes say that Go 1.7 will remove support
for the GO15VENDOREXPERIMENT environment variable,
making vendoring always on. Do that.
Change-Id: Iba8b79532455828869c1a8076a82edce84259468
Reviewed-on: https://go-review.googlesource.com/19615
Reviewed-by: Ian Lance Taylor
---
doc/go1.7.txt | 3 ++-
src/cmd/go/alldocs.go | 8 --------
src/cmd/go/env.go | 6 ------
src/cmd/go/help.go | 8 --------
src/cmd/go/pkg.go | 19 +++----------------
src/cmd/go/vcs.go | 8 ++++----
src/cmd/go/vendor_test.go | 14 --------------
7 files changed, 9 insertions(+), 57 deletions(-)
diff --git a/doc/go1.7.txt b/doc/go1.7.txt
index b2573bef83..15efa287ce 100644
--- a/doc/go1.7.txt
+++ b/doc/go1.7.txt
@@ -1,6 +1,7 @@
Tools:
-cmd/link: "-X name value" form gone (CL XXX)
+cmd/go: GO15VENDOREXPERIMENT gone, assumed on (CL 19615)
+cmd/link: "-X name value" form gone (CL 19614)
Ports:
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index c81bd40864..bbad8d40e9 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -1022,12 +1022,6 @@ Vendor directories do not affect the placement of new repositories
being checked out for the first time by 'go get': those are always
placed in the main GOPATH, never in a vendor subtree.
-In Go 1.5, as an experiment, setting the environment variable
-GO15VENDOREXPERIMENT=1 enabled these features.
-As of Go 1.6 they are on by default. To turn them off, set
-GO15VENDOREXPERIMENT=0. In Go 1.7, the environment
-variable will stop having any effect.
-
See https://golang.org/s/go15vendor for details.
@@ -1094,8 +1088,6 @@ Special-purpose environment variables:
installed in a location other than where it is built.
File names in stack traces are rewritten from GOROOT to
GOROOT_FINAL.
- GO15VENDOREXPERIMENT
- Set to 0 to disable vendoring semantics.
GO_EXTLINK_ENABLED
Whether the linker should use external linking mode
when using -linkmode=auto with code that uses cgo.
diff --git a/src/cmd/go/env.go b/src/cmd/go/env.go
index 24f612756b..8d427b37c2 100644
--- a/src/cmd/go/env.go
+++ b/src/cmd/go/env.go
@@ -33,11 +33,6 @@ func mkEnv() []envVar {
var b builder
b.init()
- vendorExpValue := "0"
- if go15VendorExperiment {
- vendorExpValue = "1"
- }
-
env := []envVar{
{"GOARCH", goarch},
{"GOBIN", gobin},
@@ -49,7 +44,6 @@ func mkEnv() []envVar {
{"GORACE", os.Getenv("GORACE")},
{"GOROOT", goroot},
{"GOTOOLDIR", toolDir},
- {"GO15VENDOREXPERIMENT", vendorExpValue},
// disable escape codes in clang errors
{"TERM", "dumb"},
diff --git a/src/cmd/go/help.go b/src/cmd/go/help.go
index d8e7efedb3..de5e5ddeab 100644
--- a/src/cmd/go/help.go
+++ b/src/cmd/go/help.go
@@ -421,12 +421,6 @@ Vendor directories do not affect the placement of new repositories
being checked out for the first time by 'go get': those are always
placed in the main GOPATH, never in a vendor subtree.
-In Go 1.5, as an experiment, setting the environment variable
-GO15VENDOREXPERIMENT=1 enabled these features.
-As of Go 1.6 they are on by default. To turn them off, set
-GO15VENDOREXPERIMENT=0. In Go 1.7, the environment
-variable will stop having any effect.
-
See https://golang.org/s/go15vendor for details.
`,
}
@@ -497,8 +491,6 @@ Special-purpose environment variables:
installed in a location other than where it is built.
File names in stack traces are rewritten from GOROOT to
GOROOT_FINAL.
- GO15VENDOREXPERIMENT
- Set to 0 to disable vendoring semantics.
GO_EXTLINK_ENABLED
Whether the linker should use external linking mode
when using -linkmode=auto with code that uses cgo.
diff --git a/src/cmd/go/pkg.go b/src/cmd/go/pkg.go
index 0c0cf07e71..6b5ead2b8c 100644
--- a/src/cmd/go/pkg.go
+++ b/src/cmd/go/pkg.go
@@ -263,15 +263,6 @@ func reloadPackage(arg string, stk *importStack) *Package {
return loadPackage(arg, stk)
}
-// The Go 1.5 vendoring experiment was enabled by setting GO15VENDOREXPERIMENT=1.
-// In Go 1.6 this is on by default and is disabled by setting GO15VENDOREXPERIMENT=0.
-// In Go 1.7 the variable will stop having any effect.
-// The variable is obnoxiously long so that years from now when people find it in
-// their profiles and wonder what it does, there is some chance that a web search
-// might answer the question.
-// There is a copy of this variable in src/go/build/build.go. Delete that one when this one goes away.
-var go15VendorExperiment = os.Getenv("GO15VENDOREXPERIMENT") != "0"
-
// dirToImportPath returns the pseudo-import path we use for a package
// outside the Go path. It begins with _/ and then contains the full path
// to the directory. If the package lives in c:\home\gopher\my\pkg then
@@ -361,7 +352,7 @@ func loadImport(path, srcDir string, parent *Package, stk *importStack, importPo
// TODO: After Go 1, decide when to pass build.AllowBinary here.
// See issue 3268 for mistakes to avoid.
buildMode := build.ImportComment
- if !go15VendorExperiment || mode&useVendor == 0 || path != origPath {
+ if mode&useVendor == 0 || path != origPath {
// Not vendoring, or we already found the vendored path.
buildMode |= build.IgnoreVendor
}
@@ -371,7 +362,7 @@ func loadImport(path, srcDir string, parent *Package, stk *importStack, importPo
bp.BinDir = gobin
}
if err == nil && !isLocal && bp.ImportComment != "" && bp.ImportComment != path &&
- (!go15VendorExperiment || (!strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/"))) {
+ !strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/") {
err = fmt.Errorf("code in directory %s expects import %q", bp.Dir, bp.ImportComment)
}
p.load(stk, bp, err)
@@ -412,7 +403,7 @@ func isDir(path string) bool {
// x/vendor/path, vendor/path, or else stay path if none of those exist.
// vendoredImportPath returns the expanded path or, if no expansion is found, the original.
func vendoredImportPath(parent *Package, path string) (found string) {
- if parent == nil || parent.Root == "" || !go15VendorExperiment {
+ if parent == nil || parent.Root == "" {
return path
}
@@ -580,10 +571,6 @@ func findInternal(path string) (index int, ok bool) {
// If the import is allowed, disallowVendor returns the original package p.
// If not, it returns a new package containing just an appropriate error.
func disallowVendor(srcDir, path string, p *Package, stk *importStack) *Package {
- if !go15VendorExperiment {
- return p
- }
-
// The stack includes p.ImportPath.
// If that's the only thing on the stack, we started
// with a name given on the command line, not an
diff --git a/src/cmd/go/vcs.go b/src/cmd/go/vcs.go
index 342edee50d..797d91fb96 100644
--- a/src/cmd/go/vcs.go
+++ b/src/cmd/go/vcs.go
@@ -383,7 +383,7 @@ func (v *vcsCmd) ping(scheme, repo string) error {
// The parent of dir must exist; dir must not.
func (v *vcsCmd) create(dir, repo string) error {
for _, cmd := range v.createCmd {
- if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
+ if strings.Contains(cmd, "submodule") {
continue
}
if err := v.run(".", cmd, "dir", dir, "repo", repo); err != nil {
@@ -396,7 +396,7 @@ func (v *vcsCmd) create(dir, repo string) error {
// download downloads any new changes for the repo in dir.
func (v *vcsCmd) download(dir string) error {
for _, cmd := range v.downloadCmd {
- if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
+ if strings.Contains(cmd, "submodule") {
continue
}
if err := v.run(dir, cmd); err != nil {
@@ -445,7 +445,7 @@ func (v *vcsCmd) tagSync(dir, tag string) error {
if tag == "" && v.tagSyncDefault != nil {
for _, cmd := range v.tagSyncDefault {
- if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
+ if strings.Contains(cmd, "submodule") {
continue
}
if err := v.run(dir, cmd); err != nil {
@@ -456,7 +456,7 @@ func (v *vcsCmd) tagSync(dir, tag string) error {
}
for _, cmd := range v.tagSyncCmd {
- if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
+ if strings.Contains(cmd, "submodule") {
continue
}
if err := v.run(dir, cmd, "tag", tag); err != nil {
diff --git a/src/cmd/go/vendor_test.go b/src/cmd/go/vendor_test.go
index 006a8c9d3f..40fe309b6d 100644
--- a/src/cmd/go/vendor_test.go
+++ b/src/cmd/go/vendor_test.go
@@ -20,7 +20,6 @@ func TestVendorImports(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
- tg.setenv("GO15VENDOREXPERIMENT", "1")
tg.run("list", "-f", "{{.ImportPath}} {{.Imports}}", "vend/...")
want := `
vend [vend/vendor/p r]
@@ -51,7 +50,6 @@ func TestVendorBuild(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
- tg.setenv("GO15VENDOREXPERIMENT", "1")
tg.run("build", "vend/x")
}
@@ -59,7 +57,6 @@ func TestVendorRun(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
- tg.setenv("GO15VENDOREXPERIMENT", "1")
tg.cd(filepath.Join(tg.pwd(), "testdata/src/vend/hello"))
tg.run("run", "hello.go")
tg.grepStdout("hello, world", "missing hello world output")
@@ -74,7 +71,6 @@ func TestVendorGOPATH(t *testing.T) {
}
gopath := changeVolume(filepath.Join(tg.pwd(), "testdata"), strings.ToLower)
tg.setenv("GOPATH", gopath)
- tg.setenv("GO15VENDOREXPERIMENT", "1")
cd := changeVolume(filepath.Join(tg.pwd(), "testdata/src/vend/hello"), strings.ToUpper)
tg.cd(cd)
tg.run("run", "hello.go")
@@ -85,7 +81,6 @@ func TestVendorTest(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
- tg.setenv("GO15VENDOREXPERIMENT", "1")
tg.cd(filepath.Join(tg.pwd(), "testdata/src/vend/hello"))
tg.run("test", "-v")
tg.grepStdout("TestMsgInternal", "missing use in internal test")
@@ -96,7 +91,6 @@ func TestVendorInvalid(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
- tg.setenv("GO15VENDOREXPERIMENT", "1")
tg.runFail("build", "vend/x/invalid")
tg.grepStderr("must be imported as foo", "missing vendor import error")
@@ -106,7 +100,6 @@ func TestVendorImportError(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
- tg.setenv("GO15VENDOREXPERIMENT", "1")
tg.runFail("build", "vend/x/vendor/p/p")
@@ -173,7 +166,6 @@ func TestVendorGet(t *testing.T) {
package p
const C = 1`)
tg.setenv("GOPATH", tg.path("."))
- tg.setenv("GO15VENDOREXPERIMENT", "1")
tg.cd(tg.path("src/v"))
tg.run("run", "m.go")
tg.run("test")
@@ -192,7 +184,6 @@ func TestVendorGetUpdate(t *testing.T) {
defer tg.cleanup()
tg.makeTempdir()
tg.setenv("GOPATH", tg.path("."))
- tg.setenv("GO15VENDOREXPERIMENT", "1")
tg.run("get", "github.com/rsc/go-get-issue-11864")
tg.run("get", "-u", "github.com/rsc/go-get-issue-11864")
}
@@ -204,7 +195,6 @@ func TestGetSubmodules(t *testing.T) {
defer tg.cleanup()
tg.makeTempdir()
tg.setenv("GOPATH", tg.path("."))
- tg.setenv("GO15VENDOREXPERIMENT", "1")
tg.run("get", "-d", "github.com/rsc/go-get-issue-12612")
tg.run("get", "-u", "-d", "github.com/rsc/go-get-issue-12612")
}
@@ -213,7 +203,6 @@ func TestVendorCache(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/testvendor"))
- tg.setenv("GO15VENDOREXPERIMENT", "1")
tg.runFail("build", "p")
tg.grepStderr("must be imported as x", "did not fail to build p")
}
@@ -225,7 +214,6 @@ func TestVendorTest2(t *testing.T) {
defer tg.cleanup()
tg.makeTempdir()
tg.setenv("GOPATH", tg.path("."))
- tg.setenv("GO15VENDOREXPERIMENT", "1")
tg.run("get", "github.com/rsc/go-get-issue-11864")
// build -i should work
@@ -251,7 +239,6 @@ func TestVendorList(t *testing.T) {
defer tg.cleanup()
tg.makeTempdir()
tg.setenv("GOPATH", tg.path("."))
- tg.setenv("GO15VENDOREXPERIMENT", "1")
tg.run("get", "github.com/rsc/go-get-issue-11864")
tg.run("list", "-f", `{{join .TestImports "\n"}}`, "github.com/rsc/go-get-issue-11864/t")
@@ -272,7 +259,6 @@ func TestVendor12156(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/testvendor2"))
- tg.setenv("GO15VENDOREXPERIMENT", "1")
tg.cd(filepath.Join(tg.pwd(), "testdata/testvendor2/src/p"))
tg.runFail("build", "p.go")
tg.grepStderrNot("panic", "panicked")
From 53ebde225e0ecaff8c3b71356a4726fad753d47c Mon Sep 17 00:00:00 2001
From: Russ Cox
Date: Mon, 1 Feb 2016 12:22:39 -0500
Subject: [PATCH 045/117] cmd/cgo: do not use gcc -xc - to compile standard
input
We have private reports of compilers that mishandle that.
Write to a temporary file instead.
Change-Id: I92e3cf4274b1a8048741e07fb52b8900c93b915e
Reviewed-on: https://go-review.googlesource.com/19616
Reviewed-by: Ian Lance Taylor
---
src/cmd/cgo/util.go | 47 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/src/cmd/cgo/util.go b/src/cmd/cgo/util.go
index 3adb8e8783..52ca160ad9 100644
--- a/src/cmd/cgo/util.go
+++ b/src/cmd/cgo/util.go
@@ -8,6 +8,7 @@ import (
"bytes"
"fmt"
"go/token"
+ "io/ioutil"
"os"
"os/exec"
)
@@ -16,6 +17,43 @@ import (
// It returns the output to standard output and standard error.
// ok indicates whether the command exited successfully.
func run(stdin []byte, argv []string) (stdout, stderr []byte, ok bool) {
+ if i := find(argv, "-xc"); i >= 0 && argv[len(argv)-1] == "-" {
+ // Some compilers have trouble with standard input.
+ // Others have trouble with -xc.
+ // Avoid both problems by writing a file with a .c extension.
+ f, err := ioutil.TempFile("", "cgo-gcc-input-")
+ if err != nil {
+ fatalf("%s", err)
+ }
+ name := f.Name()
+ f.Close()
+ if err := ioutil.WriteFile(name+".c", stdin, 0666); err != nil {
+ os.Remove(name)
+ fatalf("%s", err)
+ }
+ defer os.Remove(name)
+ defer os.Remove(name + ".c")
+
+ // Build new argument list without -xc and trailing -.
+ new := append(argv[:i:i], argv[i+1:len(argv)-1]...)
+
+ // Since we are going to write the file to a temporary directory,
+ // we will need to add -I . explicitly to the command line:
+ // any #include "foo" before would have looked in the current
+ // directory as the directory "holding" standard input, but now
+ // the temporary directory holds the input.
+ // We've also run into compilers that reject "-I." but allow "-I", ".",
+ // so be sure to use two arguments.
+ // This matters mainly for people invoking cgo -godefs by hand.
+ new = append(new, "-I", ".")
+
+ // Finish argument list with path to C file.
+ new = append(new, name+".c")
+
+ argv = new
+ stdin = nil
+ }
+
p := exec.Command(argv[0], argv[1:]...)
p.Stdin = bytes.NewReader(stdin)
var bout, berr bytes.Buffer
@@ -30,6 +68,15 @@ func run(stdin []byte, argv []string) (stdout, stderr []byte, ok bool) {
return
}
+func find(argv []string, target string) int {
+ for i, arg := range argv {
+ if arg == target {
+ return i
+ }
+ }
+ return -1
+}
+
func lineno(pos token.Pos) string {
return fset.Position(pos).String()
}
From fe5eac63c4b8d8f9d541d40f9055c3e4d4454d67 Mon Sep 17 00:00:00 2001
From: Russ Cox
Date: Thu, 4 Feb 2016 14:16:58 -0500
Subject: [PATCH 046/117] cmd/internal/obj: hoist fieldtrack code out of x86
back end
Change-Id: I38e59088c37426d914ce2b4dfc79f3d476e06f49
Reviewed-on: https://go-review.googlesource.com/19617
Reviewed-by: David Crawshaw
Reviewed-by: Ian Lance Taylor
---
src/cmd/internal/obj/obj.go | 18 ++++++++++++++++++
src/cmd/internal/obj/objfile.go | 1 +
src/cmd/internal/obj/x86/asm6.go | 9 ---------
3 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/src/cmd/internal/obj/obj.go b/src/cmd/internal/obj/obj.go
index 30ab54912e..343c93a6ee 100644
--- a/src/cmd/internal/obj/obj.go
+++ b/src/cmd/internal/obj/obj.go
@@ -281,3 +281,21 @@ func linkgetline(ctxt *Link, lineno int32, f **LSym, l *int32) {
func Linkprfile(ctxt *Link, line int) {
fmt.Printf("%s ", ctxt.LineHist.LineString(line))
}
+
+func fieldtrack(ctxt *Link, cursym *LSym) {
+ p := cursym.Text
+ if p == nil || p.Link == nil { // handle external functions and ELF section symbols
+ return
+ }
+ ctxt.Cursym = cursym
+
+ for ; p != nil; p = p.Link {
+ if p.As == AUSEFIELD {
+ r := Addrel(ctxt.Cursym)
+ r.Off = 0
+ r.Siz = 0
+ r.Sym = p.From.Sym
+ r.Type = R_USEFIELD
+ }
+ }
+}
diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go
index 8d4a506843..bae64f4a29 100644
--- a/src/cmd/internal/obj/objfile.go
+++ b/src/cmd/internal/obj/objfile.go
@@ -298,6 +298,7 @@ func Flushplist(ctxt *Link) {
ctxt.Arch.Follow(ctxt, s)
ctxt.Arch.Preprocess(ctxt, s)
ctxt.Arch.Assemble(ctxt, s)
+ fieldtrack(ctxt, s)
linkpcln(ctxt, s)
}
diff --git a/src/cmd/internal/obj/x86/asm6.go b/src/cmd/internal/obj/x86/asm6.go
index 2b71822799..115350637f 100644
--- a/src/cmd/internal/obj/x86/asm6.go
+++ b/src/cmd/internal/obj/x86/asm6.go
@@ -4556,15 +4556,6 @@ func asmins(ctxt *obj.Link, p *obj.Prog) {
ctxt.Andptr = ctxt.And[:]
ctxt.Asmode = int(p.Mode)
- if p.As == obj.AUSEFIELD {
- r := obj.Addrel(ctxt.Cursym)
- r.Off = 0
- r.Siz = 0
- r.Sym = p.From.Sym
- r.Type = obj.R_USEFIELD
- return
- }
-
if ctxt.Headtype == obj.Hnacl && p.Mode == 32 {
switch p.As {
case obj.ARET:
From 9aa630faa868fde13af74e5b22ddba89a635d837 Mon Sep 17 00:00:00 2001
From: Russ Cox
Date: Mon, 8 Feb 2016 07:08:14 -0500
Subject: [PATCH 047/117] cmd/dist: accept "//+build" with no spaces, like
go/build
The go/build parser accepts "//+build", with no spaces.
Make the cmd/dist bootstrap parser do the same.
While in theory we should always use the space form,
I copied some code that did not into the standard tree,
and I was very confused that 'go test' had had no problem
but then make.bash died.
(As a reminder, cmd/dist does not use go/build because
cmd/dist must build against earlier versions of Go.)
Change-Id: I90a18014bd878247b8811487e5c1a7589260cbfc
Reviewed-on: https://go-review.googlesource.com/19618
Reviewed-by: Ian Lance Taylor
---
src/cmd/dist/build.go | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go
index 39a88ccab5..7f2f75341f 100644
--- a/src/cmd/dist/build.go
+++ b/src/cmd/dist/build.go
@@ -754,7 +754,7 @@ func matchtag(tag string) bool {
}
return !matchtag(tag[1:])
}
- return tag == goos || tag == goarch || tag == "cmd_go_bootstrap" || tag == "go1.1" || (goos == "android" && tag == "linux")
+ return tag == "gc" || tag == goos || tag == goarch || tag == "cmd_go_bootstrap" || tag == "go1.1" || (goos == "android" && tag == "linux")
}
// shouldbuild reports whether we should build this file.
@@ -798,10 +798,15 @@ func shouldbuild(file, dir string) bool {
if p == "" {
continue
}
- if strings.Contains(p, "package documentation") {
+ code := p
+ i := strings.Index(code, "//")
+ if i > 0 {
+ code = strings.TrimSpace(code[:i])
+ }
+ if code == "package documentation" {
return false
}
- if strings.Contains(p, "package main") && dir != "cmd/go" && dir != "cmd/cgo" {
+ if code == "package main" && dir != "cmd/go" && dir != "cmd/cgo" {
return false
}
if !strings.HasPrefix(p, "//") {
@@ -810,11 +815,11 @@ func shouldbuild(file, dir string) bool {
if !strings.Contains(p, "+build") {
continue
}
- fields := splitfields(p)
- if len(fields) < 2 || fields[1] != "+build" {
+ fields := splitfields(p[2:])
+ if len(fields) < 1 || fields[0] != "+build" {
continue
}
- for _, p := range fields[2:] {
+ for _, p := range fields[1:] {
if matchfield(p) {
goto fieldmatch
}
From 277024bd6f3ecc9f34729cbeb95e226f70004733 Mon Sep 17 00:00:00 2001
From: Mohit Agarwal
Date: Fri, 19 Feb 2016 19:35:46 +0530
Subject: [PATCH 048/117] cmd/go: don't set GO15VENDOREXPERIMENT in
TestSymlinksVendor
Change-Id: I14947b64bdafd975bf3915eceb07f98897304a85
Reviewed-on: https://go-review.googlesource.com/19708
Reviewed-by: Ian Lance Taylor
Run-TryBot: Ian Lance Taylor
TryBot-Result: Gobot Gobot
---
src/cmd/go/go_test.go | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index 7d38915176..ae426088ea 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -1726,7 +1726,6 @@ func TestSymlinksVendor(t *testing.T) {
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")
From c8e7b34b599c9e3c6747b3e8182e65a2145fd06f Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor
Date: Thu, 18 Feb 2016 11:04:05 -0800
Subject: [PATCH 049/117] runtime: skip cgo check for non-pointer slice
elements
Fixes #14387.
Change-Id: Icc98be80f549c5e1f55c5e693bfea97b456a6c41
Reviewed-on: https://go-review.googlesource.com/19621
Run-TryBot: Ian Lance Taylor
TryBot-Result: Gobot Gobot
Reviewed-by: Brad Fitzpatrick
---
src/runtime/cgocall.go | 3 +++
src/runtime/crash_cgo_test.go | 31 +++++++++++++++++++++++++
src/runtime/testdata/testprogcgo/cgo.go | 10 ++++++++
3 files changed, 44 insertions(+)
diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go
index 66115fd8b4..fef8add46f 100644
--- a/src/runtime/cgocall.go
+++ b/src/runtime/cgocall.go
@@ -463,6 +463,9 @@ func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) {
if !top {
panic(errorString(msg))
}
+ if st.elem.kind&kindNoPointers != 0 {
+ return
+ }
for i := 0; i < s.cap; i++ {
cgoCheckArg(st.elem, p, true, false, msg)
p = add(p, st.elem.size)
diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
index d7b367f941..7685582aa8 100644
--- a/src/runtime/crash_cgo_test.go
+++ b/src/runtime/crash_cgo_test.go
@@ -7,10 +7,12 @@
package runtime_test
import (
+ "internal/testenv"
"os/exec"
"runtime"
"strings"
"testing"
+ "time"
)
func TestCgoCrashHandler(t *testing.T) {
@@ -147,3 +149,32 @@ func TestEnsureDropM(t *testing.T) {
t.Errorf("expected %q, got %v", want, got)
}
}
+
+// Test for issue 14387.
+// Test that the program that doesn't need any cgo pointer checking
+// takes about the same amount of time with it as without it.
+func TestCgoCheckBytes(t *testing.T) {
+ // Make sure we don't count the build time as part of the run time.
+ testenv.MustHaveGoBuild(t)
+ exe, err := buildTestProg(t, "testprogcgo")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ cmd := testEnv(exec.Command(exe, "CgoCheckBytes"))
+
+ start := time.Now()
+ cmd.Run()
+ d1 := time.Since(start)
+
+ cmd = testEnv(exec.Command(exe, "CgoCheckBytes"))
+ cmd.Env = append(cmd.Env, "GODEBUG=cgocheck=0")
+
+ start = time.Now()
+ cmd.Run()
+ d2 := time.Since(start)
+
+ if d2*10 < d1 {
+ t.Errorf("cgo check too slow: got %v, expected at most %v", d1, d2*10)
+ }
+}
diff --git a/src/runtime/testdata/testprogcgo/cgo.go b/src/runtime/testdata/testprogcgo/cgo.go
index cf1af8268c..5d2550dbb0 100644
--- a/src/runtime/testdata/testprogcgo/cgo.go
+++ b/src/runtime/testdata/testprogcgo/cgo.go
@@ -6,17 +6,20 @@ package main
/*
void foo1(void) {}
+void foo2(void* p) {}
*/
import "C"
import (
"fmt"
"runtime"
"time"
+ "unsafe"
)
func init() {
register("CgoSignalDeadlock", CgoSignalDeadlock)
register("CgoTraceback", CgoTraceback)
+ register("CgoCheckBytes", CgoCheckBytes)
}
func CgoSignalDeadlock() {
@@ -78,3 +81,10 @@ func CgoTraceback() {
runtime.Stack(buf, true)
fmt.Printf("OK\n")
}
+
+func CgoCheckBytes() {
+ b := make([]byte, 1e6)
+ for i := 0; i < 1e3; i++ {
+ C.foo2(unsafe.Pointer(&b[0]))
+ }
+}
From 5c5e8d41054940ccf9e1c025bf21c86e85f33bde Mon Sep 17 00:00:00 2001
From: Tal Shprecher
Date: Sat, 13 Feb 2016 22:39:16 -0800
Subject: [PATCH 050/117] cmd/compile: avoid leak of dottype expression if type
does not contain pointers.
Fixes #13805
Change-Id: Ica9aae2e054b74f67d28ab27f72c52a3f03eeb59
Reviewed-on: https://go-review.googlesource.com/19489
Run-TryBot: Michael Matloob
TryBot-Result: Gobot Gobot
Reviewed-by: David Chase
---
src/cmd/compile/internal/gc/esc.go | 15 ++++++++++-----
src/cmd/compile/internal/gc/typecheck.go | 1 -
test/escape_iface.go | 20 ++++++++++++++++++++
3 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go
index ff983e717e..ccdb781040 100644
--- a/src/cmd/compile/internal/gc/esc.go
+++ b/src/cmd/compile/internal/gc/esc.go
@@ -962,7 +962,7 @@ func escassign(e *EscState, dst *Node, src *Node) {
dst = &e.theSink
}
- case ODOT: // treat "dst.x = src" as "dst = src"
+ case ODOT: // treat "dst.x = src" as "dst = src"
escassign(e, dst.Left, src)
return
@@ -1042,7 +1042,6 @@ func escassign(e *EscState, dst *Node, src *Node) {
ODOTMETH,
// treat recv.meth as a value with recv in it, only happens in ODEFER and OPROC
// iface.method already leaks iface in esccall, no need to put in extra ODOTINTER edge here
- ODOTTYPE,
ODOTTYPE2,
OSLICE,
OSLICE3,
@@ -1052,6 +1051,12 @@ func escassign(e *EscState, dst *Node, src *Node) {
// Conversions, field access, slice all preserve the input value.
escassign(e, dst, src.Left)
+ case ODOTTYPE:
+ if src.Type != nil && !haspointers(src.Type) {
+ break
+ }
+ escassign(e, dst, src.Left)
+
case OAPPEND:
// Append returns first argument.
// Subsequent arguments are already leaked because they are operands to append.
@@ -1549,9 +1554,9 @@ func escflows(e *EscState, dst *Node, src *Node) {
// finding an OADDR just means we're following the upstream of a dereference,
// so this address doesn't leak (yet).
// If level == 0, it means the /value/ of this node can reach the root of this flood.
-// so if this node is an OADDR, it's argument should be marked as escaping iff
-// it's currfn/e->loopdepth are different from the flood's root.
-// Once an object has been moved to the heap, all of it's upstream should be considered
+// so if this node is an OADDR, its argument should be marked as escaping iff
+// its currfn/e->loopdepth are different from the flood's root.
+// Once an object has been moved to the heap, all of its upstream should be considered
// escaping to the global scope.
func escflood(e *EscState, dst *Node) {
switch dst.Op {
diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go
index f74bb334aa..8fd6f85575 100644
--- a/src/cmd/compile/internal/gc/typecheck.go
+++ b/src/cmd/compile/internal/gc/typecheck.go
@@ -936,7 +936,6 @@ OpSwitch:
n.Type = n.Right.Type
n.Right = nil
if n.Type == nil {
- n.Type = nil
return
}
}
diff --git a/test/escape_iface.go b/test/escape_iface.go
index 2b1144ad2c..9149fa1770 100644
--- a/test/escape_iface.go
+++ b/test/escape_iface.go
@@ -225,3 +225,23 @@ func dotTypeEscape() *T2 { // #11931
T1: *(x.(*T1)), // ERROR "&T2 literal escapes to heap"
}
}
+
+func dotTypeEscape2() { // #13805
+ {
+ i := 0
+ var v int
+ var x interface{} = i // ERROR "i does not escape"
+ *(&v) = x.(int) // ERROR "&v does not escape"
+ }
+ {
+ i := 0
+ var x interface{} = i // ERROR "i does not escape"
+ sink = x.(int) // ERROR "x.\(int\) escapes to heap"
+
+ }
+ {
+ i := 0 // ERROR "moved to heap: i"
+ var x interface{} = &i // ERROR "&i escapes to heap"
+ sink = x.(*int) // ERROR "x.\(\*int\) escapes to heap"
+ }
+}
From 9a184b22eef79ac0570330a17cf81a15a58bbf76 Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Thu, 18 Feb 2016 16:44:06 -0800
Subject: [PATCH 051/117] cmd/compile: refresh builtin.go
The export data format was augmented with a new "unsafe-uintptr" tag
in https://golang.org/cl/18584, but builtin.go was not regenerated.
While here, add a test to make sure builtin.go stays up to date in the
future.
Change-Id: I4ae17da29f0855bef6ec0fcc10e7082c8427d39c
Reviewed-on: https://go-review.googlesource.com/19681
Run-TryBot: Matthew Dempsky
TryBot-Result: Gobot Gobot
Reviewed-by: Robert Griesemer
---
src/cmd/compile/internal/gc/builtin.go | 72 ++++++++++-----------
src/cmd/compile/internal/gc/builtin_test.go | 31 +++++++++
src/cmd/compile/internal/gc/mkbuiltin.go | 13 +++-
3 files changed, 79 insertions(+), 37 deletions(-)
create mode 100644 src/cmd/compile/internal/gc/builtin_test.go
diff --git a/src/cmd/compile/internal/gc/builtin.go b/src/cmd/compile/internal/gc/builtin.go
index 1e1f85a4a1..7583e8fa13 100644
--- a/src/cmd/compile/internal/gc/builtin.go
+++ b/src/cmd/compile/internal/gc/builtin.go
@@ -44,7 +44,7 @@ const runtimeimport = "" +
"func @\"\".stringtoslicerune (? *[32]rune, ? string) (? []rune)\n" +
"func @\"\".stringiter (? string, ? int) (? int)\n" +
"func @\"\".stringiter2 (? string, ? int) (@\"\".retk·1 int, @\"\".retv·2 rune)\n" +
- "func @\"\".slicecopy (@\"\".to·2 any, @\"\".fr·3 any, @\"\".wid·4 uintptr) (? int)\n" +
+ "func @\"\".slicecopy (@\"\".to·2 any, @\"\".fr·3 any, @\"\".wid·4 uintptr \"unsafe-uintptr\") (? int)\n" +
"func @\"\".slicestringcopy (@\"\".to·2 any, @\"\".fr·3 any) (? int)\n" +
"func @\"\".typ2Itab (@\"\".typ·2 *byte, @\"\".typ2·3 *byte, @\"\".cache·4 **byte) (@\"\".ret·1 *byte)\n" +
"func @\"\".convI2E (@\"\".elem·2 any) (@\"\".ret·1 any)\n" +
@@ -91,31 +91,31 @@ const runtimeimport = "" +
"func @\"\".writebarrierstring (@\"\".dst·1 *any, @\"\".src·2 any)\n" +
"func @\"\".writebarrierslice (@\"\".dst·1 *any, @\"\".src·2 any)\n" +
"func @\"\".writebarrieriface (@\"\".dst·1 *any, @\"\".src·2 any)\n" +
- "func @\"\".writebarrierfat01 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat10 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat11 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat001 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat010 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat011 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat100 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat101 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat110 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat111 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat0001 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat0010 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat0011 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat0100 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat0101 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat0110 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat0111 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat1000 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat1001 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat1010 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat1011 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat1100 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat1101 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat1110 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
- "func @\"\".writebarrierfat1111 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat01 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat10 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat11 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat001 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat010 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat011 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat100 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat101 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat110 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat111 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat0001 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat0010 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat0011 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat0100 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat0101 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat0110 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat0111 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat1000 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat1001 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat1010 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat1011 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat1100 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat1101 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat1110 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ "func @\"\".writebarrierfat1111 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
"func @\"\".typedmemmove (@\"\".typ·1 *byte, @\"\".dst·2 *any, @\"\".src·3 *any)\n" +
"func @\"\".typedslicecopy (@\"\".typ·2 *byte, @\"\".dst·3 any, @\"\".src·4 any) (? int)\n" +
"func @\"\".selectnbsend (@\"\".chanType·2 *byte, @\"\".hchan·3 chan<- any, @\"\".elem·4 *any) (? bool)\n" +
@@ -131,9 +131,9 @@ const runtimeimport = "" +
"func @\"\".makeslice (@\"\".typ·2 *byte, @\"\".nel·3 int64, @\"\".cap·4 int64) (@\"\".ary·1 []any)\n" +
"func @\"\".growslice (@\"\".typ·2 *byte, @\"\".old·3 []any, @\"\".cap·4 int) (@\"\".ary·1 []any)\n" +
"func @\"\".growslice_n (@\"\".typ·2 *byte, @\"\".old·3 []any, @\"\".n·4 int) (@\"\".ary·1 []any)\n" +
- "func @\"\".memmove (@\"\".to·1 *any, @\"\".frm·2 *any, @\"\".length·3 uintptr)\n" +
- "func @\"\".memclr (@\"\".ptr·1 *byte, @\"\".length·2 uintptr)\n" +
- "func @\"\".memequal (@\"\".x·2 *any, @\"\".y·3 *any, @\"\".size·4 uintptr) (? bool)\n" +
+ "func @\"\".memmove (@\"\".to·1 *any, @\"\".frm·2 *any, @\"\".length·3 uintptr \"unsafe-uintptr\")\n" +
+ "func @\"\".memclr (@\"\".ptr·1 *byte, @\"\".length·2 uintptr \"unsafe-uintptr\")\n" +
+ "func @\"\".memequal (@\"\".x·2 *any, @\"\".y·3 *any, @\"\".size·4 uintptr \"unsafe-uintptr\") (? bool)\n" +
"func @\"\".memequal8 (@\"\".x·2 *any, @\"\".y·3 *any) (? bool)\n" +
"func @\"\".memequal16 (@\"\".x·2 *any, @\"\".y·3 *any) (? bool)\n" +
"func @\"\".memequal32 (@\"\".x·2 *any, @\"\".y·3 *any) (? bool)\n" +
@@ -148,14 +148,14 @@ const runtimeimport = "" +
"func @\"\".int64tofloat64 (? int64) (? float64)\n" +
"func @\"\".uint64tofloat64 (? uint64) (? float64)\n" +
"func @\"\".complex128div (@\"\".num·2 complex128, @\"\".den·3 complex128) (@\"\".quo·1 complex128)\n" +
- "func @\"\".racefuncenter (? uintptr)\n" +
+ "func @\"\".racefuncenter (? uintptr \"unsafe-uintptr\")\n" +
"func @\"\".racefuncexit ()\n" +
- "func @\"\".raceread (? uintptr)\n" +
- "func @\"\".racewrite (? uintptr)\n" +
- "func @\"\".racereadrange (@\"\".addr·1 uintptr, @\"\".size·2 uintptr)\n" +
- "func @\"\".racewriterange (@\"\".addr·1 uintptr, @\"\".size·2 uintptr)\n" +
- "func @\"\".msanread (@\"\".addr·1 uintptr, @\"\".size·2 uintptr)\n" +
- "func @\"\".msanwrite (@\"\".addr·1 uintptr, @\"\".size·2 uintptr)\n" +
+ "func @\"\".raceread (? uintptr \"unsafe-uintptr\")\n" +
+ "func @\"\".racewrite (? uintptr \"unsafe-uintptr\")\n" +
+ "func @\"\".racereadrange (@\"\".addr·1 uintptr \"unsafe-uintptr\", @\"\".size·2 uintptr \"unsafe-uintptr\")\n" +
+ "func @\"\".racewriterange (@\"\".addr·1 uintptr \"unsafe-uintptr\", @\"\".size·2 uintptr \"unsafe-uintptr\")\n" +
+ "func @\"\".msanread (@\"\".addr·1 uintptr \"unsafe-uintptr\", @\"\".size·2 uintptr \"unsafe-uintptr\")\n" +
+ "func @\"\".msanwrite (@\"\".addr·1 uintptr \"unsafe-uintptr\", @\"\".size·2 uintptr \"unsafe-uintptr\")\n" +
"\n" +
"$$\n"
diff --git a/src/cmd/compile/internal/gc/builtin_test.go b/src/cmd/compile/internal/gc/builtin_test.go
new file mode 100644
index 0000000000..94111e640d
--- /dev/null
+++ b/src/cmd/compile/internal/gc/builtin_test.go
@@ -0,0 +1,31 @@
+// 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 gc_test
+
+import (
+ "bytes"
+ "internal/testenv"
+ "io/ioutil"
+ "os/exec"
+ "testing"
+)
+
+func TestBuiltin(t *testing.T) {
+ testenv.MustHaveGoRun(t)
+
+ old, err := ioutil.ReadFile("builtin.go")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ new, err := exec.Command("go", "run", "mkbuiltin.go", "-stdout").Output()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if !bytes.Equal(old, new) {
+ t.Fatal("builtin.go out of date; run mkbuiltin.go")
+ }
+}
diff --git a/src/cmd/compile/internal/gc/mkbuiltin.go b/src/cmd/compile/internal/gc/mkbuiltin.go
index 1b6cc4ae38..13cde5e8aa 100644
--- a/src/cmd/compile/internal/gc/mkbuiltin.go
+++ b/src/cmd/compile/internal/gc/mkbuiltin.go
@@ -12,6 +12,7 @@ package main
import (
"bytes"
+ "flag"
"fmt"
"io"
"io/ioutil"
@@ -20,7 +21,11 @@ import (
"os/exec"
)
+var stdout = flag.Bool("stdout", false, "write to stdout instead of builtin.go")
+
func main() {
+ flag.Parse()
+
var b bytes.Buffer
fmt.Fprintln(&b, "// AUTO-GENERATED by mkbuiltin.go; DO NOT EDIT")
fmt.Fprintln(&b, "")
@@ -29,7 +34,13 @@ func main() {
mkbuiltin(&b, "runtime")
mkbuiltin(&b, "unsafe")
- if err := ioutil.WriteFile("builtin.go", b.Bytes(), 0666); err != nil {
+ var err error
+ if *stdout {
+ _, err = os.Stdout.Write(b.Bytes())
+ } else {
+ err = ioutil.WriteFile("builtin.go", b.Bytes(), 0666)
+ }
+ if err != nil {
log.Fatal(err)
}
}
From 0e34737c9aea6680b0a2a135cdf80557d61b83ce Mon Sep 17 00:00:00 2001
From: Damien Neil
Date: Fri, 19 Feb 2016 09:58:22 -0800
Subject: [PATCH 052/117] cmd/go: don't assume cc supports
-gno-record-gcc-switches
NetBSD's C compiler appears to support -fdebug-prefix-map but
not -gno-record-gcc-switches. Remove assumption that support
for the former implies the latter.
Change-Id: Iecad9e4f497ea4edc1ce440010e6fe19dc3e0566
Reviewed-on: https://go-review.googlesource.com/19686
Reviewed-by: Ian Lance Taylor
Run-TryBot: Ian Lance Taylor
TryBot-Result: Gobot Gobot
---
src/cmd/go/build.go | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
index 1932f324ea..e65aee4a27 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -2930,12 +2930,15 @@ func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
// Tell gcc not to include the work directory in object files.
if b.gccSupportsFlag("-fdebug-prefix-map=a=b") {
- // -gno-record-gcc-switches is supported by all gcc/clang
- // versions that support -fdebug-prefix-map.
- a = append(a, "-gno-record-gcc-switches")
a = append(a, "-fdebug-prefix-map="+b.work+"=/tmp/go-build")
}
+ // Tell gcc not to include flags in object files, which defeats the
+ // point of -fdebug-prefix-map above.
+ if b.gccSupportsFlag("-gno-record-gcc-switches") {
+ a = append(a, "-gno-record-gcc-switches")
+ }
+
// On OS X, some of the compilers behave as if -fno-common
// is always set, and the Mach-O linker in 6l/8l assumes this.
// See https://golang.org/issue/3253.
From fb2af2b35b8d2ad832f2398e981ea78c64b0663b Mon Sep 17 00:00:00 2001
From: David Chase
Date: Fri, 19 Feb 2016 12:06:31 -0500
Subject: [PATCH 053/117] cmd/compile: don't walk field-name syntax in esc.go
Walking the field name as if it were an expression
caused a called to haspointers with a TFIELD, which panics.
Trigger was a field at a large offset within a large struct,
combined with a struct literal expression mentioning that
field.
Fixes #14405
Change-Id: I4589badae27cf3d7cf365f3a66c13447512f41f9
Reviewed-on: https://go-review.googlesource.com/19699
Reviewed-by: Russ Cox
Run-TryBot: David Chase
TryBot-Result: Gobot Gobot
---
src/cmd/compile/internal/gc/esc.go | 13 ++++++++++---
src/cmd/compile/internal/gc/fmt.go | 2 +-
test/fixedbugs/issue14405.go | 17 +++++++++++++++++
3 files changed, 28 insertions(+), 4 deletions(-)
create mode 100644 test/fixedbugs/issue14405.go
diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go
index ccdb781040..1a5a433eeb 100644
--- a/src/cmd/compile/internal/gc/esc.go
+++ b/src/cmd/compile/internal/gc/esc.go
@@ -576,6 +576,12 @@ func esc(e *EscState, n *Node, up *Node) {
if n == nil {
return
}
+ if n.Type != nil && n.Type.Etype == TFIELD {
+ // This is the left side of x:y in a struct literal.
+ // x is syntax, not an expression.
+ // See #14405.
+ return
+ }
lno := int(setlineno(n))
@@ -602,9 +608,10 @@ func esc(e *EscState, n *Node, up *Node) {
// Big stuff escapes unconditionally
// "Big" conditions that were scattered around in walk have been gathered here
- if n.Esc != EscHeap && n.Type != nil && (n.Type.Width > MaxStackVarSize ||
- n.Op == ONEW && n.Type.Type.Width >= 1<<16 ||
- n.Op == OMAKESLICE && !isSmallMakeSlice(n)) {
+ if n.Esc != EscHeap && n.Type != nil &&
+ (n.Type.Width > MaxStackVarSize ||
+ n.Op == ONEW && n.Type.Type.Width >= 1<<16 ||
+ n.Op == OMAKESLICE && !isSmallMakeSlice(n)) {
if Debug['m'] > 1 {
Warnl(int(n.Lineno), "%v is too large for stack", n)
}
diff --git a/src/cmd/compile/internal/gc/fmt.go b/src/cmd/compile/internal/gc/fmt.go
index d00e5a6c46..c0a1170839 100644
--- a/src/cmd/compile/internal/gc/fmt.go
+++ b/src/cmd/compile/internal/gc/fmt.go
@@ -1542,7 +1542,7 @@ func nodedump(n *Node, flag int) string {
} else {
fmt.Fprintf(&buf, "%v%v", Oconv(int(n.Op), 0), Jconv(n, 0))
}
- if recur && n.Type == nil && n.Name.Param.Ntype != nil {
+ if recur && n.Type == nil && n.Name != nil && n.Name.Param != nil && n.Name.Param.Ntype != nil {
indent(&buf)
fmt.Fprintf(&buf, "%v-ntype%v", Oconv(int(n.Op), 0), n.Name.Param.Ntype)
}
diff --git a/test/fixedbugs/issue14405.go b/test/fixedbugs/issue14405.go
new file mode 100644
index 0000000000..c2a89464ea
--- /dev/null
+++ b/test/fixedbugs/issue14405.go
@@ -0,0 +1,17 @@
+// compile
+
+// 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.
+
+// Mention of field with large offset in struct literal causes crash
+package p
+
+type T struct {
+ Slice [1 << 20][]int
+ Ptr *int
+}
+
+func New(p *int) *T {
+ return &T{Ptr: p}
+}
From 1402e522c6e372d055748d8437bd2a127acacdca Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Tue, 1 Dec 2015 12:02:42 -0800
Subject: [PATCH 054/117] cmd/compile: load builtin export data only once
Previously, the builtin runtime export data was reparsed before every
Go source file, and the unsafe export data was reparsed for every
import of package unsafe. Now, we parse both of them just once ahead
of time.
This does mean package unsafe's export data will be loaded even when
compiling packages that don't import it, but it's tiny anyway.
Change-Id: Ic6931bc58f6d62f664348bfa932f92d4ccacc3ef
Reviewed-on: https://go-review.googlesource.com/19626
TryBot-Result: Gobot Gobot
Reviewed-by: Robert Griesemer
---
src/cmd/compile/internal/gc/lex.go | 30 +++++++++++++++++++++++++--
src/cmd/compile/internal/gc/parser.go | 23 --------------------
2 files changed, 28 insertions(+), 25 deletions(-)
diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
index a2a8be1610..8161cad568 100644
--- a/src/cmd/compile/internal/gc/lex.go
+++ b/src/cmd/compile/internal/gc/lex.go
@@ -311,6 +311,8 @@ func Main() {
lexlineno = 1
const BOM = 0xFEFF
+ loadsys()
+
for _, infile = range flag.Args() {
if trace && Debug['x'] != 0 {
fmt.Printf("--- %s ---\n", infile)
@@ -656,6 +658,30 @@ func findpkg(name string) (file string, ok bool) {
return "", false
}
+// loadsys loads the definitions for the low-level runtime and unsafe functions,
+// so that the compiler can generate calls to them,
+// but does not make the names "runtime" or "unsafe" visible as packages.
+func loadsys() {
+ if Debug['A'] != 0 {
+ return
+ }
+
+ block = 1
+ iota_ = -1000000
+
+ importpkg = Runtimepkg
+ cannedimports("runtime.Builtin", runtimeimport)
+ thenewparser.import_package()
+ thenewparser.import_there()
+
+ importpkg = unsafepkg
+ cannedimports("unsafe.o", unsafeimport)
+ thenewparser.import_package()
+ thenewparser.import_there()
+
+ importpkg = nil
+}
+
func fakeimport() {
importpkg = mkpkg("fake")
cannedimports("fake.o", "$$\n")
@@ -706,8 +732,8 @@ func importfile(f *Val, line int) {
errorexit()
}
- importpkg = mkpkg(f.U.(string))
- cannedimports("unsafe.o", unsafeimport)
+ importpkg = unsafepkg
+ cannedimports("unsafe.o", "package unsafe\n\n$$\n\n")
imported_unsafe = true
return
}
diff --git a/src/cmd/compile/internal/gc/parser.go b/src/cmd/compile/internal/gc/parser.go
index dc6ae72d5f..7e521d1f7d 100644
--- a/src/cmd/compile/internal/gc/parser.go
+++ b/src/cmd/compile/internal/gc/parser.go
@@ -51,33 +51,10 @@ func pop_parser() {
// parse_file sets up a new parser and parses a single Go source file.
func parse_file() {
thenewparser = parser{}
- thenewparser.loadsys()
thenewparser.next()
thenewparser.file()
}
-// loadsys loads the definitions for the low-level runtime functions,
-// so that the compiler can generate calls to them,
-// but does not make the name "runtime" visible as a package.
-func (p *parser) loadsys() {
- if trace && Debug['x'] != 0 {
- defer p.trace("loadsys")()
- }
-
- importpkg = Runtimepkg
-
- if Debug['A'] != 0 {
- cannedimports("runtime.Builtin", "package runtime safe\n\n$$\n\n")
- } else {
- cannedimports("runtime.Builtin", runtimeimport)
- }
-
- p.import_package()
- p.import_there()
-
- importpkg = nil
-}
-
type parser struct {
tok int32 // next token (one-token look-ahead)
op Op // valid if tok == LASOP
From d930d69fd95e410107e84231f57ff629d1ef7f21 Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Tue, 1 Dec 2015 12:05:30 -0800
Subject: [PATCH 055/117] cmd/compile: make -A and -newexport compatible
Packages compiled with -A may reference the builtin "any" type, so it
needs to be included in the list of predeclared types for binary
import/export.
Also, when -A is used, mark all symbols as SymExport instead of
SymPackage in importsym. This parallels the logic in autoexport and
is necessary to prevent a "export/package mismatch" errors in
exportsym during dumpexport's verifyExport pass.
Change-Id: Iff5ec5fbfe2219525ec9d1a975307fa8936af9b9
Reviewed-on: https://go-review.googlesource.com/19627
Reviewed-by: Robert Griesemer
Run-TryBot: Matthew Dempsky
TryBot-Result: Gobot Gobot
---
src/cmd/compile/internal/gc/bexport.go | 3 +++
src/cmd/compile/internal/gc/export.go | 2 +-
src/go/internal/gcimporter/bimport.go | 4 ++++
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/cmd/compile/internal/gc/bexport.go b/src/cmd/compile/internal/gc/bexport.go
index 3edd0488e7..ff0465f64c 100644
--- a/src/cmd/compile/internal/gc/bexport.go
+++ b/src/cmd/compile/internal/gc/bexport.go
@@ -1035,6 +1035,9 @@ func predeclared() []*Type {
// package unsafe
Types[TUNSAFEPTR],
+
+ // any type, for builtin export data
+ Types[TANY],
}
}
return predecl
diff --git a/src/cmd/compile/internal/gc/export.go b/src/cmd/compile/internal/gc/export.go
index e50cf383d7..1b61d7f228 100644
--- a/src/cmd/compile/internal/gc/export.go
+++ b/src/cmd/compile/internal/gc/export.go
@@ -442,7 +442,7 @@ func importsym(s *Sym, op Op) *Sym {
// mark the symbol so it is not reexported
if s.Def == nil {
- if exportname(s.Name) || initname(s.Name) {
+ if Debug['A'] != 0 || exportname(s.Name) || initname(s.Name) {
s.Flags |= SymExport
} else {
s.Flags |= SymPackage // package scope
diff --git a/src/go/internal/gcimporter/bimport.go b/src/go/internal/gcimporter/bimport.go
index 68690424a1..ad1c4cd02a 100644
--- a/src/go/internal/gcimporter/bimport.go
+++ b/src/go/internal/gcimporter/bimport.go
@@ -678,4 +678,8 @@ var predeclared = []types.Type{
// package unsafe
types.Typ[types.UnsafePointer],
+
+ // any type, for builtin export data
+ // TODO(mdempsky): Provide an actual Type value to represent "any"?
+ types.Typ[types.Invalid],
}
From 113c4d25818e67599d3ff647480e4e68d6857f82 Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Tue, 1 Dec 2015 12:15:25 -0800
Subject: [PATCH 056/117] cmd/compile: refactor import statement parsing
Combine parser's import_stmt and import_here methods as a single new
importdcl method, and cleanup conditional logic slightly to make the
code easier to follow.
Also, eliminate importfile's unused line parameter, and get rid of all
of its duplicate type assertions.
Change-Id: Ic37ae8490afedc533f98ead9feef383e3599bc01
Reviewed-on: https://go-review.googlesource.com/19629
Reviewed-by: Robert Griesemer
Run-TryBot: Matthew Dempsky
TryBot-Result: Gobot Gobot
---
src/cmd/compile/internal/gc/go.go | 2 -
src/cmd/compile/internal/gc/lex.go | 24 +++--
src/cmd/compile/internal/gc/parser.go | 134 ++++++++++++--------------
3 files changed, 70 insertions(+), 90 deletions(-)
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
index 8053aaffe9..ebc6a5171b 100644
--- a/src/cmd/compile/internal/gc/go.go
+++ b/src/cmd/compile/internal/gc/go.go
@@ -492,8 +492,6 @@ var debugstr string
var Debug_checknil int
var Debug_typeassert int
-var importmyname *Sym // my name for package
-
var localpkg *Pkg // package being compiled
var importpkg *Pkg // package being imported
diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
index 8161cad568..83f25a5e2a 100644
--- a/src/cmd/compile/internal/gc/lex.go
+++ b/src/cmd/compile/internal/gc/lex.go
@@ -687,21 +687,21 @@ func fakeimport() {
cannedimports("fake.o", "$$\n")
}
-// TODO(gri) line argument doesn't appear to be used
-func importfile(f *Val, line int) {
- if _, ok := f.U.(string); !ok {
+func importfile(f *Val) {
+ path_, ok := f.U.(string)
+ if !ok {
Yyerror("import statement not a string")
fakeimport()
return
}
- if len(f.U.(string)) == 0 {
+ if len(path_) == 0 {
Yyerror("import path is empty")
fakeimport()
return
}
- if isbadimport(f.U.(string)) {
+ if isbadimport(path_) {
fakeimport()
return
}
@@ -710,18 +710,16 @@ func importfile(f *Val, line int) {
// but we reserve the import path "main" to identify
// the main package, just as we reserve the import
// path "math" to identify the standard math package.
- if f.U.(string) == "main" {
+ if path_ == "main" {
Yyerror("cannot import \"main\"")
errorexit()
}
- if myimportpath != "" && f.U.(string) == myimportpath {
- Yyerror("import %q while compiling that package (import cycle)", f.U.(string))
+ if myimportpath != "" && path_ == myimportpath {
+ Yyerror("import %q while compiling that package (import cycle)", path_)
errorexit()
}
- path_ := f.U.(string)
-
if mapped, ok := importMap[path_]; ok {
path_ = mapped
}
@@ -763,7 +761,7 @@ func importfile(f *Val, line int) {
file, found := findpkg(path_)
if !found {
- Yyerror("can't find import: %q", f.U.(string))
+ Yyerror("can't find import: %q", path_)
errorexit()
}
@@ -788,7 +786,7 @@ func importfile(f *Val, line int) {
var imp *obj.Biobuf
imp, err = obj.Bopenr(file)
if err != nil {
- Yyerror("can't open import: %q: %v", f.U.(string), err)
+ Yyerror("can't open import: %q: %v", path_, err)
errorexit()
}
@@ -878,7 +876,7 @@ func importfile(f *Val, line int) {
incannedimport = 0
default:
- Yyerror("no import in %q", f.U.(string))
+ Yyerror("no import in %q", path_)
}
}
diff --git a/src/cmd/compile/internal/gc/parser.go b/src/cmd/compile/internal/gc/parser.go
index 7e521d1f7d..6081383918 100644
--- a/src/cmd/compile/internal/gc/parser.go
+++ b/src/cmd/compile/internal/gc/parser.go
@@ -323,108 +323,92 @@ func (p *parser) import_() {
p.want(LIMPORT)
if p.got('(') {
for p.tok != EOF && p.tok != ')' {
- p.import_stmt()
+ p.importdcl()
if !p.osemi(')') {
break
}
}
p.want(')')
} else {
- p.import_stmt()
- }
-}
-
-func (p *parser) import_stmt() {
- if trace && Debug['x'] != 0 {
- defer p.trace("import_stmt")()
- }
-
- line := int32(p.import_here())
- if p.tok == LPACKAGE {
- p.import_package()
- p.import_there()
-
- ipkg := importpkg
- my := importmyname
- importpkg = nil
- importmyname = nil
-
- if my == nil {
- my = Lookup(ipkg.Name)
- }
-
- pack := Nod(OPACK, nil, nil)
- pack.Sym = my
- pack.Name.Pkg = ipkg
- pack.Lineno = line
-
- if strings.HasPrefix(my.Name, ".") {
- importdot(ipkg, pack)
- return
- }
- if my.Name == "init" {
- lineno = line
- Yyerror("cannot import package as init - init must be a func")
- return
- }
- if my.Name == "_" {
- return
- }
- if my.Def != nil {
- lineno = line
- redeclare(my, "as imported package name")
- }
- my.Def = pack
- my.Lastlineno = line
- my.Block = 1 // at top level
-
- return
- }
-
- p.import_there()
- // When an invalid import path is passed to importfile,
- // it calls Yyerror and then sets up a fake import with
- // no package statement. This allows us to test more
- // than one invalid import statement in a single file.
- if nerrors == 0 {
- Fatalf("phase error in import")
+ p.importdcl()
}
}
// ImportSpec = [ "." | PackageName ] ImportPath .
// ImportPath = string_lit .
-//
-// import_here switches the underlying lexed source to the export data
-// of the imported package.
-func (p *parser) import_here() int {
+func (p *parser) importdcl() {
if trace && Debug['x'] != 0 {
- defer p.trace("import_here")()
+ defer p.trace("importdcl")()
}
- importmyname = nil
+ var my *Sym
switch p.tok {
case LNAME, '@', '?':
// import with given name
- importmyname = p.sym()
+ my = p.sym()
case '.':
// import into my name space
- importmyname = Lookup(".")
+ my = Lookup(".")
p.next()
}
- var path Val
- if p.tok == LLITERAL {
- path = p.val
- p.next()
- } else {
+ if p.tok != LLITERAL {
p.syntax_error("missing import path; require quoted string")
p.advance(';', ')')
+ return
}
- line := parserline()
- importfile(&path, line)
- return line
+ line := int32(parserline())
+ path := p.val
+ p.next()
+
+ importfile(&path)
+ if p.tok != LPACKAGE {
+ // When an invalid import path is passed to importfile,
+ // it calls Yyerror and then sets up a fake import with
+ // no package statement. This allows us to test more
+ // than one invalid import statement in a single file.
+ p.import_there()
+ if nerrors == 0 {
+ Fatalf("phase error in import")
+ }
+ return
+ }
+ p.import_package()
+ p.import_there()
+
+ ipkg := importpkg
+ importpkg = nil
+
+ if my == nil {
+ my = Lookup(ipkg.Name)
+ }
+
+ pack := Nod(OPACK, nil, nil)
+ pack.Sym = my
+ pack.Name.Pkg = ipkg
+ pack.Lineno = line
+
+ if strings.HasPrefix(my.Name, ".") {
+ importdot(ipkg, pack)
+ return
+ }
+ if my.Name == "init" {
+ lineno = line
+ Yyerror("cannot import package as init - init must be a func")
+ return
+ }
+ if my.Name == "_" {
+ return
+ }
+ if my.Def != nil {
+ lineno = line
+ redeclare(my, "as imported package name")
+ }
+ my.Def = pack
+ my.Lastlineno = line
+ my.Block = 1 // at top level
}
// import_package parses the header of an imported package as exported
From 5a9c128a0313df72973259bea946262cb8973d86 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Mo=CC=88hrmann?=
Date: Fri, 19 Feb 2016 22:45:38 +0100
Subject: [PATCH 057/117] fmt: remove math package dependency and avoid float
operations
Remove floating point comparisons and rely only on the information
directly provided by appendFloat.
Make restoring the zero padding flag explicit instead of using a defer.
Rearrange some case distinctions to remove duplicated code.
Add more test cases for zero padded floating point numbers with sign.
benchmark old ns/op new ns/op delta
BenchmarkSprintfFloat-4 187 180 -3.74%
Change-Id: Ifa2ae85257909f40b1b18118c92b516933271729
Reviewed-on: https://go-review.googlesource.com/19721
Reviewed-by: Rob Pike
---
src/fmt/fmt_test.go | 6 ++++++
src/fmt/format.go | 43 +++++++++++++++++--------------------------
2 files changed, 23 insertions(+), 26 deletions(-)
diff --git a/src/fmt/fmt_test.go b/src/fmt/fmt_test.go
index 793f709a79..8d7c36ceb1 100644
--- a/src/fmt/fmt_test.go
+++ b/src/fmt/fmt_test.go
@@ -259,6 +259,12 @@ var fmtTests = []struct {
{"%+.3F", float32(-1.0), "-1.000"},
{"%+07.2f", 1.0, "+001.00"},
{"%+07.2f", -1.0, "-001.00"},
+ {"%-07.2f", 1.0, "1.00 "},
+ {"%-07.2f", -1.0, "-1.00 "},
+ {"%+-07.2f", 1.0, "+1.00 "},
+ {"%+-07.2f", -1.0, "-1.00 "},
+ {"%-+07.2f", 1.0, "+1.00 "},
+ {"%-+07.2f", -1.0, "-1.00 "},
{"%+10.2f", +1.0, " +1.00"},
{"%+10.2f", -1.0, " -1.00"},
{"% .3E", -1.0, "-1.000E+00"},
diff --git a/src/fmt/format.go b/src/fmt/format.go
index 517b18f7d4..bf9d00bbc0 100644
--- a/src/fmt/format.go
+++ b/src/fmt/format.go
@@ -5,7 +5,6 @@
package fmt
import (
- "math"
"strconv"
"unicode/utf8"
)
@@ -405,42 +404,34 @@ func doPrec(f *fmt, def int) int {
// formatFloat formats a float64; it is an efficient equivalent to f.pad(strconv.FormatFloat()...).
func (f *fmt) formatFloat(v float64, verb byte, prec, n int) {
// Format number, reserving space for leading + sign if needed.
- num := strconv.AppendFloat(f.intbuf[0:1], v, verb, prec, n)
+ num := strconv.AppendFloat(f.intbuf[:1], v, verb, prec, n)
if num[1] == '-' || num[1] == '+' {
num = num[1:]
} else {
num[0] = '+'
}
- // Special handling for infinity, which doesn't look like a number so shouldn't be padded with zeros.
- if math.IsInf(v, 0) {
- if f.zero {
- defer func() { f.zero = true }()
- f.zero = false
- }
- }
- // num is now a signed version of the number.
- // If we're zero padding, want the sign before the leading zeros.
- // Achieve this by writing the sign out and then padding the unsigned number.
- if f.zero && f.widPresent && f.wid > len(num) {
- if f.space && v >= 0 {
- f.buf.WriteByte(' ') // This is what C does: even with zero, f.space means space.
- f.wid--
- } else if f.plus || v < 0 {
- f.buf.WriteByte(num[0])
- f.wid--
- }
- f.pad(num[1:])
- return
- }
// f.space says to replace a leading + with a space.
if f.space && num[0] == '+' {
num[0] = ' '
+ }
+ // Special handling for "+Inf" and "-Inf",
+ // which don't look like a number so shouldn't be padded with zeros.
+ if num[1] == 'I' {
+ oldZero := f.zero
+ f.zero = false
f.pad(num)
+ f.zero = oldZero
return
}
- // Now we know the sign is attached directly to the number, if present at all.
- // We want a sign if asked for, if it's negative, or if it's infinity (+Inf vs. -Inf).
- if f.plus || num[0] == '-' || math.IsInf(v, 0) {
+ // We want a sign if asked for and if the sign is not positive.
+ if f.plus || num[0] != '+' {
+ // If we're zero padding we want the sign before the leading zeros.
+ // Achieve this by writing the sign out and then padding the unsigned number.
+ if f.zero && f.widPresent && f.wid > len(num) {
+ f.buf.WriteByte(num[0])
+ f.wid--
+ num = num[1:]
+ }
f.pad(num)
return
}
From 0d5e6a3f07414ecf6a14bc601532aa305296f562 Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor
Date: Fri, 19 Feb 2016 11:42:34 -0800
Subject: [PATCH 058/117] cmd/api: fix benchmark to ignore internal packages
Change-Id: I8ee46287ae0744efa83ad343997ad6835520fa5c
Reviewed-on: https://go-review.googlesource.com/19688
Run-TryBot: Ian Lance Taylor
TryBot-Result: Gobot Gobot
Reviewed-by: Brad Fitzpatrick
---
src/cmd/api/goapi_test.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/cmd/api/goapi_test.go b/src/cmd/api/goapi_test.go
index 1d2cc9ac82..a3fe0efedc 100644
--- a/src/cmd/api/goapi_test.go
+++ b/src/cmd/api/goapi_test.go
@@ -178,7 +178,7 @@ func BenchmarkAll(b *testing.B) {
for _, context := range contexts {
w := NewWalker(context, filepath.Join(build.Default.GOROOT, "src"))
for _, name := range pkgNames {
- if name != "unsafe" && !strings.HasPrefix(name, "cmd/") {
+ if name != "unsafe" && !strings.HasPrefix(name, "cmd/") && !internalPkg.MatchString(name) {
pkg, _ := w.Import(name)
w.export(pkg)
}
From 7d3a40978aaa69c3cf08068a83252927b4514e9d Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Tue, 1 Dec 2015 12:19:36 -0800
Subject: [PATCH 059/117] cmd/compile: refactor export data parsing
Merge push_parser and pop_parser into a single parse_import function
and inline unimportfile. Shake out function boundaries a little bit so
that the symmetry is readily visible.
Move the import_package call into parse_import (and inline
import_there into import_package). This means importfile no longer
needs to provide fake import data to be needlessly lexed/parsed every
time it's called.
Also, instead of indicating import success/failure by whether the next
token is "package", import_spec can just check whether importpkg is
non-nil.
Tangentially, this somehow alters the diagnostics produced for
test/fixedbugs/issue11610.go. However, the new diagnostics are more
consistent with those produced when the empty import statement is
absent, which seems more desirable than maintaining the previous
errors.
Change-Id: I5cd1c22aa14da8a743ef569ff084711d137279d5
Reviewed-on: https://go-review.googlesource.com/19650
Reviewed-by: Robert Griesemer
---
src/cmd/compile/internal/gc/lex.go | 99 +++++++--------------------
src/cmd/compile/internal/gc/parser.go | 58 ++++------------
test/fixedbugs/issue11610.go | 4 +-
3 files changed, 39 insertions(+), 122 deletions(-)
diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
index 83f25a5e2a..0bcfb3687d 100644
--- a/src/cmd/compile/internal/gc/lex.go
+++ b/src/cmd/compile/internal/gc/lex.go
@@ -671,38 +671,30 @@ func loadsys() {
importpkg = Runtimepkg
cannedimports("runtime.Builtin", runtimeimport)
- thenewparser.import_package()
- thenewparser.import_there()
importpkg = unsafepkg
cannedimports("unsafe.o", unsafeimport)
- thenewparser.import_package()
- thenewparser.import_there()
importpkg = nil
}
-func fakeimport() {
- importpkg = mkpkg("fake")
- cannedimports("fake.o", "$$\n")
-}
-
func importfile(f *Val) {
+ if importpkg != nil {
+ Fatalf("importpkg not nil")
+ }
+
path_, ok := f.U.(string)
if !ok {
Yyerror("import statement not a string")
- fakeimport()
return
}
if len(path_) == 0 {
Yyerror("import path is empty")
- fakeimport()
return
}
if isbadimport(path_) {
- fakeimport()
return
}
@@ -731,7 +723,6 @@ func importfile(f *Val) {
}
importpkg = unsafepkg
- cannedimports("unsafe.o", "package unsafe\n\n$$\n\n")
imported_unsafe = true
return
}
@@ -739,7 +730,6 @@ func importfile(f *Val) {
if islocalname(path_) {
if path_[0] == '/' {
Yyerror("import path cannot be absolute path")
- fakeimport()
return
}
@@ -754,7 +744,6 @@ func importfile(f *Val) {
path_ = cleanbuf
if isbadimport(path_) {
- fakeimport()
return
}
}
@@ -767,28 +756,18 @@ func importfile(f *Val) {
importpkg = mkpkg(path_)
- // If we already saw that package, feed a dummy statement
- // to the lexer to avoid parsing export data twice.
if importpkg.Imported {
- tag := ""
- if importpkg.Safe {
- tag = "safe"
- }
-
- p := fmt.Sprintf("package %s %s\n$$\n", importpkg.Name, tag)
- cannedimports(file, p)
return
}
importpkg.Imported = true
- var err error
- var imp *obj.Biobuf
- imp, err = obj.Bopenr(file)
+ imp, err := obj.Bopenr(file)
if err != nil {
Yyerror("can't open import: %q: %v", path_, err)
errorexit()
}
+ defer obj.Bterm(imp)
if strings.HasSuffix(file, ".a") {
if !skiptopkgdef(imp) {
@@ -845,74 +824,44 @@ func importfile(f *Val) {
case '\n':
// old export format
pushedio = curio
-
- curio.bin = imp
- curio.peekc = 0
- curio.peekc1 = 0
- curio.infile = file
- curio.nlsemi = false
+ curio = Io{bin: imp, infile: file}
typecheckok = true
- push_parser()
+ parse_import()
+
+ typecheckok = false
+ curio = pushedio
+ pushedio.bin = nil
case 'B':
// new export format
obj.Bgetc(imp) // skip \n after $$B
Import(imp)
- // continue as if the package was imported before (see above)
- tag := ""
- if importpkg.Safe {
- tag = "safe"
- }
- p := fmt.Sprintf("package %s %s\n$$\n", importpkg.Name, tag)
- cannedimports(file, p)
- // Reset incannedimport flag (we are not truly in a
- // canned import) - this will cause importpkg.Direct to
- // be set via parser.import_package (was issue #13977).
- //
- // TODO(gri) Remove this global variable and convoluted
- // code in the process of streamlining the import code.
- incannedimport = 0
-
default:
Yyerror("no import in %q", path_)
- }
-}
-
-func unimportfile() {
- pop_parser()
-
- if curio.bin != nil {
- obj.Bterm(curio.bin)
- curio.bin = nil
- } else {
- lexlineno-- // re correct sys.6 line number
+ errorexit()
}
- curio = pushedio
-
- pushedio.bin = nil
- incannedimport = 0
- typecheckok = false
+ if safemode != 0 && !importpkg.Safe {
+ Yyerror("cannot import unsafe package %q", importpkg.Path)
+ }
}
func cannedimports(file string, cp string) {
lexlineno++ // if sys.6 is included on line 1,
-
pushedio = curio
-
- curio.bin = nil
- curio.peekc = 0
- curio.peekc1 = 0
- curio.infile = file
- curio.cp = cp
- curio.nlsemi = false
-
+ curio = Io{infile: file, cp: cp}
typecheckok = true
incannedimport = 1
- push_parser()
+ parse_import()
+
+ typecheckok = false
+ incannedimport = 0
+ curio = pushedio
+ pushedio.bin = nil
+ lexlineno-- // re correct sys.6 line number
}
func isSpace(c int) bool {
diff --git a/src/cmd/compile/internal/gc/parser.go b/src/cmd/compile/internal/gc/parser.go
index 6081383918..4a49836e8d 100644
--- a/src/cmd/compile/internal/gc/parser.go
+++ b/src/cmd/compile/internal/gc/parser.go
@@ -20,13 +20,11 @@ import (
const trace = false // if set, parse tracing can be enabled with -x
-// TODO(gri) Once we handle imports w/o redirecting the underlying
-// source of the lexer we can get rid of these. They are here for
-// compatibility with the existing yacc-based parser setup (issue 13242).
-var thenewparser parser // the parser in use
-var savedstate []parser // saved parser state, used during import
+// TODO(gri) Once we stop supporting the legacy export data format
+// we can get rid of this (issue 13242).
+var fileparser parser // the Go source file parser in use
-func push_parser() {
+func parse_import() {
// Indentation (for tracing) must be preserved across parsers
// since we are changing the lexer source (and parser state)
// under foot, in the middle of productions. This won't be
@@ -34,25 +32,16 @@ func push_parser() {
// be the push/pop_parser functionality.
// (Instead we could just use a global variable indent, but
// but eventually indent should be parser-specific anyway.)
- indent := thenewparser.indent
- savedstate = append(savedstate, thenewparser)
- thenewparser = parser{indent: indent} // preserve indentation
- thenewparser.next()
-}
-
-func pop_parser() {
- indent := thenewparser.indent
- n := len(savedstate) - 1
- thenewparser = savedstate[n]
- thenewparser.indent = indent // preserve indentation
- savedstate = savedstate[:n]
+ importparser := parser{indent: fileparser.indent} // preserve indentation
+ importparser.next()
+ importparser.import_package()
}
// parse_file sets up a new parser and parses a single Go source file.
func parse_file() {
- thenewparser = parser{}
- thenewparser.next()
- thenewparser.file()
+ fileparser = parser{}
+ fileparser.next()
+ fileparser.file()
}
type parser struct {
@@ -364,23 +353,18 @@ func (p *parser) importdcl() {
p.next()
importfile(&path)
- if p.tok != LPACKAGE {
- // When an invalid import path is passed to importfile,
- // it calls Yyerror and then sets up a fake import with
- // no package statement. This allows us to test more
- // than one invalid import statement in a single file.
- p.import_there()
+ if importpkg == nil {
if nerrors == 0 {
Fatalf("phase error in import")
}
return
}
- p.import_package()
- p.import_there()
ipkg := importpkg
importpkg = nil
+ ipkg.Direct = true
+
if my == nil {
my = Lookup(ipkg.Name)
}
@@ -442,23 +426,8 @@ func (p *parser) import_package() {
} else if importpkg.Name != name {
Yyerror("conflicting names %s and %s for package %q", importpkg.Name, name, importpkg.Path)
}
- if incannedimport == 0 {
- importpkg.Direct = true
- }
importpkg.Safe = importsafe
- if safemode != 0 && !importsafe {
- Yyerror("cannot import unsafe package %q", importpkg.Path)
- }
-}
-
-// import_there parses the imported package definitions and then switches
-// the underlying lexed source back to the importing package.
-func (p *parser) import_there() {
- if trace && Debug['x'] != 0 {
- defer p.trace("import_there")()
- }
-
defercheckwidth()
p.hidden_import_list()
@@ -469,7 +438,6 @@ func (p *parser) import_there() {
}
resumecheckwidth()
- unimportfile()
}
// Declaration = ConstDecl | TypeDecl | VarDecl .
diff --git a/test/fixedbugs/issue11610.go b/test/fixedbugs/issue11610.go
index a326249ed4..56f245dee5 100644
--- a/test/fixedbugs/issue11610.go
+++ b/test/fixedbugs/issue11610.go
@@ -9,9 +9,9 @@
package a
import"" // ERROR "import path is empty"
-var? // ERROR "invalid declaration"
+var? // ERROR "unexpected \?"
-var x int // ERROR "unexpected var"
+var x int // ERROR "unexpected var" "cannot declare name"
func main() {
}
From 699a2ba137fec09371da431907431ec2020a58af Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Fri, 19 Feb 2016 18:36:02 -0800
Subject: [PATCH 060/117] cmd/compile: switch cannedimports to use a Biobuf
Allows eliminating the separate lexer code paths for reading from cp
in the next CL.
Change-Id: I49098ecef32b735c4a01374443c2f847235ff964
Reviewed-on: https://go-review.googlesource.com/19750
Reviewed-by: Robert Griesemer
---
src/cmd/compile/internal/gc/lex.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
index 0bcfb3687d..e506f7a117 100644
--- a/src/cmd/compile/internal/gc/lex.go
+++ b/src/cmd/compile/internal/gc/lex.go
@@ -851,7 +851,7 @@ func importfile(f *Val) {
func cannedimports(file string, cp string) {
lexlineno++ // if sys.6 is included on line 1,
pushedio = curio
- curio = Io{infile: file, cp: cp}
+ curio = Io{infile: file, bin: obj.Binitr(strings.NewReader(cp))}
typecheckok = true
incannedimport = 1
From f8e41f6f5907ce832cc263bdce749117d4d0b342 Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Wed, 2 Dec 2015 11:30:34 -0800
Subject: [PATCH 061/117] cmd/compile: eliminate Io.infile and Io.cp
infile is never read and cp is never written. Both are unneeded.
Change-Id: I0a90bb772a53a580ea4be8e5f0f770da7c1acf3a
Reviewed-on: https://go-review.googlesource.com/19651
Reviewed-by: Brad Fitzpatrick
Reviewed-by: Dave Cheney
Reviewed-by: Robert Griesemer
---
src/cmd/compile/internal/gc/go.go | 2 --
src/cmd/compile/internal/gc/lex.go | 48 +++++++++++-------------------
2 files changed, 17 insertions(+), 33 deletions(-)
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
index ebc6a5171b..71a5d88ccb 100644
--- a/src/cmd/compile/internal/gc/go.go
+++ b/src/cmd/compile/internal/gc/go.go
@@ -386,9 +386,7 @@ type Sig struct {
}
type Io struct {
- infile string
bin *obj.Biobuf
- cp string // used for content when bin==nil
last int
peekc int
peekc1 int // second peekc for ...
diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
index e506f7a117..57b2959de6 100644
--- a/src/cmd/compile/internal/gc/lex.go
+++ b/src/cmd/compile/internal/gc/lex.go
@@ -320,7 +320,6 @@ func Main() {
linehistpush(infile)
- curio.infile = infile
var err error
curio.bin, err = obj.Bopenr(infile)
if err != nil {
@@ -824,7 +823,7 @@ func importfile(f *Val) {
case '\n':
// old export format
pushedio = curio
- curio = Io{bin: imp, infile: file}
+ curio = Io{bin: imp}
typecheckok = true
parse_import()
@@ -851,7 +850,7 @@ func importfile(f *Val) {
func cannedimports(file string, cp string) {
lexlineno++ // if sys.6 is included on line 1,
pushedio = curio
- curio = Io{infile: file, bin: obj.Binitr(strings.NewReader(cp))}
+ curio = Io{bin: obj.Binitr(strings.NewReader(cp))}
typecheckok = true
incannedimport = 1
@@ -1903,42 +1902,29 @@ func getc() int {
goto check
}
- if curio.bin == nil {
- if len(curio.cp) == 0 {
- c = 0
- } else {
- c = int(curio.cp[0])
- curio.cp = curio.cp[1:]
+loop:
+ c = obj.Bgetc(curio.bin)
+ // recognize BOM (U+FEFF): UTF-8 encoding is 0xef 0xbb 0xbf
+ if c == 0xef {
+ buf, err := curio.bin.Peek(2)
+ if err != nil {
+ yyerrorl(int(lexlineno), "illegal UTF-8 sequence ef % x followed by read error (%v)", string(buf), err)
+ errorexit()
}
- } else {
- loop:
- c = obj.Bgetc(curio.bin)
- // recognize BOM (U+FEFF): UTF-8 encoding is 0xef 0xbb 0xbf
- if c == 0xef {
- buf, err := curio.bin.Peek(2)
- if err != nil {
- yyerrorl(int(lexlineno), "illegal UTF-8 sequence ef % x followed by read error (%v)", string(buf), err)
- errorexit()
- }
- if buf[0] == 0xbb && buf[1] == 0xbf {
- yyerrorl(int(lexlineno), "Unicode (UTF-8) BOM in middle of file")
+ if buf[0] == 0xbb && buf[1] == 0xbf {
+ yyerrorl(int(lexlineno), "Unicode (UTF-8) BOM in middle of file")
- // consume BOM bytes
- obj.Bgetc(curio.bin)
- obj.Bgetc(curio.bin)
- goto loop
- }
+ // consume BOM bytes
+ obj.Bgetc(curio.bin)
+ obj.Bgetc(curio.bin)
+ goto loop
}
}
check:
switch c {
case 0:
- if curio.bin != nil {
- Yyerror("illegal NUL byte")
- break
- }
- fallthrough
+ Yyerror("illegal NUL byte")
// insert \n at EOF
case EOF:
From 4e6e8e8c582bcd7d74378be31f070eecf0f1d5e4 Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Fri, 19 Feb 2016 18:39:25 -0800
Subject: [PATCH 062/117] cmd/compile: change two pushedio.bin tests to use
importpkg instead
pushedio.bin and importpkg are both non-nil iff we're parsing an
package's export data, so "pushedio.bin == nil" and "importpkg == nil"
are equivalent tests.
Change-Id: I571ee908fef867117ef72c5da1eb24fe9b3fd12d
Reviewed-on: https://go-review.googlesource.com/19751
Reviewed-by: Robert Griesemer
---
src/cmd/compile/internal/gc/lex.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
index 57b2959de6..ae201a7d97 100644
--- a/src/cmd/compile/internal/gc/lex.go
+++ b/src/cmd/compile/internal/gc/lex.go
@@ -1936,7 +1936,7 @@ check:
fallthrough
case '\n':
- if pushedio.bin == nil {
+ if importpkg == nil {
lexlineno++
}
}
@@ -1948,7 +1948,7 @@ check:
func ungetc(c int) {
curio.peekc1 = curio.peekc
curio.peekc = c
- if c == '\n' && pushedio.bin == nil {
+ if c == '\n' && importpkg == nil {
lexlineno--
}
}
From 338a891e79444de97d6f485b1632d42899c47c6d Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Fri, 19 Feb 2016 18:47:01 -0800
Subject: [PATCH 063/117] cmd/compile: eliminate pushedio and savedstate
While here, get drop the lexlineno{++,--} hacks for canned imports.
They were added in commit d3237f9, but don't seem to serve any
purpose.
Change-Id: I00f9e6be0ae9f217f2fa113b85e041dfd0303757
Reviewed-on: https://go-review.googlesource.com/19652
Reviewed-by: Robert Griesemer
Run-TryBot: Matthew Dempsky
---
src/cmd/compile/internal/gc/go.go | 2 --
src/cmd/compile/internal/gc/lex.go | 51 ++++++---------------------
src/cmd/compile/internal/gc/parser.go | 14 ++++++--
3 files changed, 22 insertions(+), 45 deletions(-)
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
index 71a5d88ccb..7cfc2c9057 100644
--- a/src/cmd/compile/internal/gc/go.go
+++ b/src/cmd/compile/internal/gc/go.go
@@ -451,8 +451,6 @@ var dotlist [10]Dlist // size is max depth of embeddeds
var curio Io
-var pushedio Io
-
var lexlineno int32
var lineno int32
diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
index ae201a7d97..91b521e95b 100644
--- a/src/cmd/compile/internal/gc/lex.go
+++ b/src/cmd/compile/internal/gc/lex.go
@@ -320,22 +320,15 @@ func Main() {
linehistpush(infile)
- var err error
- curio.bin, err = obj.Bopenr(infile)
+ bin, err := obj.Bopenr(infile)
if err != nil {
fmt.Printf("open %s: %v\n", infile, err)
errorexit()
}
- curio.peekc = 0
- curio.peekc1 = 0
- curio.nlsemi = false
- curio.eofnl = false
- curio.last = 0
-
// Skip initial BOM if present.
- if obj.Bgetrune(curio.bin) != BOM {
- obj.Bungetrune(curio.bin)
+ if obj.Bgetrune(bin) != BOM {
+ obj.Bungetrune(bin)
}
block = 1
@@ -343,15 +336,13 @@ func Main() {
imported_unsafe = false
- parse_file()
+ parse_file(bin)
if nsyntaxerrors != 0 {
errorexit()
}
linehistpop()
- if curio.bin != nil {
- obj.Bterm(curio.bin)
- }
+ obj.Bterm(bin)
}
testdclstack()
@@ -667,14 +658,16 @@ func loadsys() {
block = 1
iota_ = -1000000
+ incannedimport = 1
importpkg = Runtimepkg
- cannedimports("runtime.Builtin", runtimeimport)
+ parse_import(obj.Binitr(strings.NewReader(runtimeimport)))
importpkg = unsafepkg
- cannedimports("unsafe.o", unsafeimport)
+ parse_import(obj.Binitr(strings.NewReader(unsafeimport)))
importpkg = nil
+ incannedimport = 0
}
func importfile(f *Val) {
@@ -822,15 +815,7 @@ func importfile(f *Val) {
switch c {
case '\n':
// old export format
- pushedio = curio
- curio = Io{bin: imp}
- typecheckok = true
-
- parse_import()
-
- typecheckok = false
- curio = pushedio
- pushedio.bin = nil
+ parse_import(imp)
case 'B':
// new export format
@@ -847,22 +832,6 @@ func importfile(f *Val) {
}
}
-func cannedimports(file string, cp string) {
- lexlineno++ // if sys.6 is included on line 1,
- pushedio = curio
- curio = Io{bin: obj.Binitr(strings.NewReader(cp))}
- typecheckok = true
- incannedimport = 1
-
- parse_import()
-
- typecheckok = false
- incannedimport = 0
- curio = pushedio
- pushedio.bin = nil
- lexlineno-- // re correct sys.6 line number
-}
-
func isSpace(c int) bool {
return c == ' ' || c == '\t' || c == '\n' || c == '\r'
}
diff --git a/src/cmd/compile/internal/gc/parser.go b/src/cmd/compile/internal/gc/parser.go
index 4a49836e8d..e41f3b9e86 100644
--- a/src/cmd/compile/internal/gc/parser.go
+++ b/src/cmd/compile/internal/gc/parser.go
@@ -13,6 +13,7 @@ package gc
// to handle optional commas and semicolons before a closing ) or } .
import (
+ "cmd/internal/obj"
"fmt"
"strconv"
"strings"
@@ -24,7 +25,10 @@ const trace = false // if set, parse tracing can be enabled with -x
// we can get rid of this (issue 13242).
var fileparser parser // the Go source file parser in use
-func parse_import() {
+func parse_import(bin *obj.Biobuf) {
+ pushedio := curio
+ curio = Io{bin: bin}
+
// Indentation (for tracing) must be preserved across parsers
// since we are changing the lexer source (and parser state)
// under foot, in the middle of productions. This won't be
@@ -35,10 +39,14 @@ func parse_import() {
importparser := parser{indent: fileparser.indent} // preserve indentation
importparser.next()
importparser.import_package()
+
+ curio = pushedio
}
// parse_file sets up a new parser and parses a single Go source file.
-func parse_file() {
+func parse_file(bin *obj.Biobuf) {
+ curio = Io{bin: bin}
+
fileparser = parser{}
fileparser.next()
fileparser.file()
@@ -428,6 +436,7 @@ func (p *parser) import_package() {
}
importpkg.Safe = importsafe
+ typecheckok = true
defercheckwidth()
p.hidden_import_list()
@@ -438,6 +447,7 @@ func (p *parser) import_package() {
}
resumecheckwidth()
+ typecheckok = false
}
// Declaration = ConstDecl | TypeDecl | VarDecl .
From 3e40f13cf3bf3f23f3f2f60dec174a1bdad57f16 Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Fri, 19 Feb 2016 18:51:24 -0800
Subject: [PATCH 064/117] cmd/compile: eliminate global fileparser
Change-Id: I9b8b13731ccc2ba33d21642b12cc614dde0804b1
Reviewed-on: https://go-review.googlesource.com/19752
Reviewed-by: Robert Griesemer
Run-TryBot: Matthew Dempsky
---
src/cmd/compile/internal/gc/lex.go | 8 ++++----
src/cmd/compile/internal/gc/parser.go | 19 ++++---------------
2 files changed, 8 insertions(+), 19 deletions(-)
diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
index 91b521e95b..66cc01862d 100644
--- a/src/cmd/compile/internal/gc/lex.go
+++ b/src/cmd/compile/internal/gc/lex.go
@@ -661,16 +661,16 @@ func loadsys() {
incannedimport = 1
importpkg = Runtimepkg
- parse_import(obj.Binitr(strings.NewReader(runtimeimport)))
+ parse_import(obj.Binitr(strings.NewReader(runtimeimport)), nil)
importpkg = unsafepkg
- parse_import(obj.Binitr(strings.NewReader(unsafeimport)))
+ parse_import(obj.Binitr(strings.NewReader(unsafeimport)), nil)
importpkg = nil
incannedimport = 0
}
-func importfile(f *Val) {
+func importfile(f *Val, indent []byte) {
if importpkg != nil {
Fatalf("importpkg not nil")
}
@@ -815,7 +815,7 @@ func importfile(f *Val) {
switch c {
case '\n':
// old export format
- parse_import(imp)
+ parse_import(imp, indent)
case 'B':
// new export format
diff --git a/src/cmd/compile/internal/gc/parser.go b/src/cmd/compile/internal/gc/parser.go
index e41f3b9e86..048b81e01b 100644
--- a/src/cmd/compile/internal/gc/parser.go
+++ b/src/cmd/compile/internal/gc/parser.go
@@ -21,22 +21,11 @@ import (
const trace = false // if set, parse tracing can be enabled with -x
-// TODO(gri) Once we stop supporting the legacy export data format
-// we can get rid of this (issue 13242).
-var fileparser parser // the Go source file parser in use
-
-func parse_import(bin *obj.Biobuf) {
+func parse_import(bin *obj.Biobuf, indent []byte) {
pushedio := curio
curio = Io{bin: bin}
- // Indentation (for tracing) must be preserved across parsers
- // since we are changing the lexer source (and parser state)
- // under foot, in the middle of productions. This won't be
- // needed anymore once we fix issue 13242, but neither will
- // be the push/pop_parser functionality.
- // (Instead we could just use a global variable indent, but
- // but eventually indent should be parser-specific anyway.)
- importparser := parser{indent: fileparser.indent} // preserve indentation
+ importparser := parser{indent: indent} // preserve indentation
importparser.next()
importparser.import_package()
@@ -47,7 +36,7 @@ func parse_import(bin *obj.Biobuf) {
func parse_file(bin *obj.Biobuf) {
curio = Io{bin: bin}
- fileparser = parser{}
+ fileparser := parser{}
fileparser.next()
fileparser.file()
}
@@ -360,7 +349,7 @@ func (p *parser) importdcl() {
path := p.val
p.next()
- importfile(&path)
+ importfile(&path, p.indent)
if importpkg == nil {
if nerrors == 0 {
Fatalf("phase error in import")
From 315f4c70f123cfbf061d097543af555547acd9c7 Mon Sep 17 00:00:00 2001
From: Shenghou Ma
Date: Thu, 18 Feb 2016 16:29:39 -0500
Subject: [PATCH 065/117] runtime: use correct psABI SP alignment before
calling libc mmap
Fixes #14384.
Change-Id: Ib025cf2d20754b4c2db52f0a8a4717fd303371d6
Reviewed-on: https://go-review.googlesource.com/19660
Run-TryBot: Minux Ma
TryBot-Result: Gobot Gobot
Reviewed-by: Ian Lance Taylor
Reviewed-by: Austin Clements
---
src/runtime/sys_linux_amd64.s | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/runtime/sys_linux_amd64.s b/src/runtime/sys_linux_amd64.s
index aed85cb0aa..f407078176 100644
--- a/src/runtime/sys_linux_amd64.s
+++ b/src/runtime/sys_linux_amd64.s
@@ -258,7 +258,7 @@ TEXT runtime·sysMmap(SB),NOSPLIT,$0
// Call the function stored in _cgo_mmap using the GCC calling convention.
// This must be called on the system stack.
-TEXT runtime·callCgoMmap(SB),NOSPLIT,$0
+TEXT runtime·callCgoMmap(SB),NOSPLIT,$16
MOVQ addr+0(FP), DI
MOVQ n+8(FP), SI
MOVL prot+16(FP), DX
@@ -266,7 +266,11 @@ TEXT runtime·callCgoMmap(SB),NOSPLIT,$0
MOVL fd+24(FP), R8
MOVL off+28(FP), R9
MOVQ _cgo_mmap(SB), AX
+ MOVQ SP, BX
+ ANDQ $~15, SP // alignment as per amd64 psABI
+ MOVQ BX, 0(SP)
CALL AX
+ MOVQ 0(SP), SP
MOVQ AX, ret+32(FP)
RET
From 5efbdd9d10908206d4e0351cb4724c5fefdfa2be Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Fri, 22 Jan 2016 13:31:57 -0800
Subject: [PATCH 066/117] net: fix race in (*resolverConfig).tryUpdate
Fixes #14072.
Change-Id: Ie31caa06690ac621906fc5acd34da2efa4e2049f
Reviewed-on: https://go-review.googlesource.com/18860
Reviewed-by: Mikio Hara
Run-TryBot: Mikio Hara
---
src/net/dnsclient_unix.go | 22 ++++++----------------
src/net/dnsconfig_unix.go | 28 +++++++++++++++++++---------
src/net/dnsconfig_unix_test.go | 2 ++
3 files changed, 27 insertions(+), 25 deletions(-)
diff --git a/src/net/dnsclient_unix.go b/src/net/dnsclient_unix.go
index 17188f0024..736e57322c 100644
--- a/src/net/dnsclient_unix.go
+++ b/src/net/dnsclient_unix.go
@@ -229,7 +229,6 @@ type resolverConfig struct {
// time to recheck resolv.conf.
ch chan struct{} // guards lastChecked and modTime
lastChecked time.Time // last time resolv.conf was checked
- modTime time.Time // time of resolv.conf modification
mu sync.RWMutex // protects dnsConfig
dnsConfig *dnsConfig // parsed resolv.conf structure used in lookups
@@ -239,16 +238,12 @@ var resolvConf resolverConfig
// init initializes conf and is only called via conf.initOnce.
func (conf *resolverConfig) init() {
- // Set dnsConfig, modTime, and lastChecked so we don't parse
+ // Set dnsConfig and lastChecked so we don't parse
// resolv.conf twice the first time.
conf.dnsConfig = systemConf().resolv
if conf.dnsConfig == nil {
conf.dnsConfig = dnsReadConfig("/etc/resolv.conf")
}
-
- if fi, err := os.Stat("/etc/resolv.conf"); err == nil {
- conf.modTime = fi.ModTime()
- }
conf.lastChecked = time.Now()
// Prepare ch so that only one update of resolverConfig may
@@ -274,17 +269,12 @@ func (conf *resolverConfig) tryUpdate(name string) {
}
conf.lastChecked = now
+ var mtime time.Time
if fi, err := os.Stat(name); err == nil {
- if fi.ModTime().Equal(conf.modTime) {
- return
- }
- conf.modTime = fi.ModTime()
- } else {
- // If modTime wasn't set prior, assume nothing has changed.
- if conf.modTime.IsZero() {
- return
- }
- conf.modTime = time.Time{}
+ mtime = fi.ModTime()
+ }
+ if mtime.Equal(conf.dnsConfig.mtime) {
+ return
}
dnsConf := dnsReadConfig(name)
diff --git a/src/net/dnsconfig_unix.go b/src/net/dnsconfig_unix.go
index 6073fdb6d8..0515ca90de 100644
--- a/src/net/dnsconfig_unix.go
+++ b/src/net/dnsconfig_unix.go
@@ -8,18 +8,21 @@
package net
+import "time"
+
var defaultNS = []string{"127.0.0.1", "::1"}
type dnsConfig struct {
- servers []string // servers to use
- search []string // suffixes to append to local name
- ndots int // number of dots in name to trigger absolute lookup
- timeout int // seconds before giving up on packet
- attempts int // lost packets before giving up on server
- rotate bool // round robin among servers
- unknownOpt bool // anything unknown was encountered
- lookup []string // OpenBSD top-level database "lookup" order
- err error // any error that occurs during open of resolv.conf
+ servers []string // servers to use
+ search []string // suffixes to append to local name
+ ndots int // number of dots in name to trigger absolute lookup
+ timeout int // seconds before giving up on packet
+ attempts int // lost packets before giving up on server
+ rotate bool // round robin among servers
+ unknownOpt bool // anything unknown was encountered
+ lookup []string // OpenBSD top-level database "lookup" order
+ err error // any error that occurs during open of resolv.conf
+ mtime time.Time // time of resolv.conf modification
}
// See resolv.conf(5) on a Linux machine.
@@ -38,6 +41,13 @@ func dnsReadConfig(filename string) *dnsConfig {
return conf
}
defer file.close()
+ if fi, err := file.file.Stat(); err == nil {
+ conf.mtime = fi.ModTime()
+ } else {
+ conf.servers = defaultNS
+ conf.err = err
+ return conf
+ }
for line, ok := file.readLine(); ok; line, ok = file.readLine() {
if len(line) > 0 && (line[0] == ';' || line[0] == '#') {
// comment.
diff --git a/src/net/dnsconfig_unix_test.go b/src/net/dnsconfig_unix_test.go
index c8eed61890..849c0da93b 100644
--- a/src/net/dnsconfig_unix_test.go
+++ b/src/net/dnsconfig_unix_test.go
@@ -10,6 +10,7 @@ import (
"os"
"reflect"
"testing"
+ "time"
)
var dnsReadConfigTests = []struct {
@@ -76,6 +77,7 @@ func TestDNSReadConfig(t *testing.T) {
if conf.err != nil {
t.Fatal(conf.err)
}
+ conf.mtime = time.Time{}
if !reflect.DeepEqual(conf, tt.want) {
t.Errorf("%s:\ngot: %+v\nwant: %+v", tt.name, conf, tt.want)
}
From 3a11c8d3190210c510c152471ddb85eb36a15e76 Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Sat, 20 Feb 2016 00:00:53 -0800
Subject: [PATCH 067/117] cmd/compile: simplify if statement parsing
Somewhat notably, this means long if statement chains are now parsed
recursively, rather than iteratively. This shouldn't be a concern
though, as several other functions (e.g., gen, typecheck, walk)
already use recursion to process the parsed if statement Node trees.
Change-Id: Ic8c12ace9021c870d60c06f5db86a48c4ec57084
Reviewed-on: https://go-review.googlesource.com/19756
Reviewed-by: Robert Griesemer
Run-TryBot: Robert Griesemer
TryBot-Result: Gobot Gobot
---
src/cmd/compile/internal/gc/parser.go | 61 +++------------------------
1 file changed, 6 insertions(+), 55 deletions(-)
diff --git a/src/cmd/compile/internal/gc/parser.go b/src/cmd/compile/internal/gc/parser.go
index 048b81e01b..3a5b508393 100644
--- a/src/cmd/compile/internal/gc/parser.go
+++ b/src/cmd/compile/internal/gc/parser.go
@@ -1064,65 +1064,16 @@ func (p *parser) if_stmt() *Node {
stmt.Nbody = p.loop_body("if clause")
- l := p.elseif_list_else() // does markdcl
-
- n := stmt
- popdcl()
- for nn := l; nn != nil; nn = nn.Next {
- if nn.N.Op == OIF {
- popdcl()
- }
- n.Rlist = list1(nn.N)
- n = nn.N
- }
-
- return stmt
-}
-
-func (p *parser) elseif() *NodeList {
- if trace && Debug['x'] != 0 {
- defer p.trace("elseif")()
- }
-
- // LELSE LIF already consumed
- markdcl() // matching popdcl in if_stmt
-
- stmt := p.if_header()
- if stmt.Left == nil {
- Yyerror("missing condition in if statement")
- }
-
- stmt.Nbody = p.loop_body("if clause")
-
- return list1(stmt)
-}
-
-func (p *parser) elseif_list_else() (l *NodeList) {
- if trace && Debug['x'] != 0 {
- defer p.trace("elseif_list_else")()
- }
-
- for p.got(LELSE) {
- if p.got(LIF) {
- l = concat(l, p.elseif())
+ if p.got(LELSE) {
+ if p.tok == LIF {
+ stmt.Rlist = list1(p.if_stmt())
} else {
- l = concat(l, p.else_())
- break
+ stmt.Rlist = list1(p.compound_stmt(true))
}
}
- return l
-}
-
-func (p *parser) else_() *NodeList {
- if trace && Debug['x'] != 0 {
- defer p.trace("else")()
- }
-
- l := &NodeList{N: p.compound_stmt(true)}
- l.End = l
- return l
-
+ popdcl()
+ return stmt
}
// switch_stmt parses both expression and type switch statements.
From 41eb5ca089be5495ab2299e2b6778fb8ceb8010a Mon Sep 17 00:00:00 2001
From: David Crawshaw
Date: Wed, 17 Feb 2016 09:41:12 -0500
Subject: [PATCH 068/117] cmd/link: typo in error message
Change-Id: Ideeef320d6a01a10c89524b6d895a64210a60f64
Reviewed-on: https://go-review.googlesource.com/19693
Reviewed-by: Brad Fitzpatrick
Run-TryBot: David Crawshaw
TryBot-Result: Gobot Gobot
---
src/cmd/link/internal/ld/dwarf.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go
index a96b37a4be..fb3d8fb2cd 100644
--- a/src/cmd/link/internal/ld/dwarf.go
+++ b/src/cmd/link/internal/ld/dwarf.go
@@ -951,7 +951,7 @@ func defgotype(gotype *LSym) *DWDie {
}
if !strings.HasPrefix(gotype.Name, "type.") {
- Diag("dwarf: type name doesn't start with \".type\": %s", gotype.Name)
+ Diag("dwarf: type name doesn't start with \"type.\": %s", gotype.Name)
return mustFind(&dwtypes, "")
}
From e6d6ad47f52fa40dd07bb74b2df349321fad1eeb Mon Sep 17 00:00:00 2001
From: David Crawshaw
Date: Tue, 16 Feb 2016 15:30:32 -0500
Subject: [PATCH 069/117] cmd/compile: update some type names in comments
Change-Id: I741a1205bc6256c08b36efed43652bfbb75e4401
Reviewed-on: https://go-review.googlesource.com/19691
Reviewed-by: Brad Fitzpatrick
Run-TryBot: David Crawshaw
TryBot-Result: Gobot Gobot
---
src/cmd/compile/internal/gc/go.go | 3 +-
src/cmd/compile/internal/gc/reflect.go | 48 +++++++++++++-------------
2 files changed, 25 insertions(+), 26 deletions(-)
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
index 7cfc2c9057..13a28c8720 100644
--- a/src/cmd/compile/internal/gc/go.go
+++ b/src/cmd/compile/internal/gc/go.go
@@ -329,8 +329,7 @@ const (
const (
// types of channel
- // must match ../../pkg/nreflect/type.go:/Chandir
- Cxxx = 0
+ // must match ../../../../reflect/type.go:/ChanDir
Crecv = 1 << 0
Csend = 1 << 1
Cboth = Crecv | Csend
diff --git a/src/cmd/compile/internal/gc/reflect.go b/src/cmd/compile/internal/gc/reflect.go
index 264955c702..8693e3c112 100644
--- a/src/cmd/compile/internal/gc/reflect.go
+++ b/src/cmd/compile/internal/gc/reflect.go
@@ -45,7 +45,7 @@ func siglt(a, b *Sig) bool {
// the given map type. This type is not visible to users -
// we include only enough information to generate a correct GC
// program for it.
-// Make sure this stays in sync with ../../runtime/hashmap.go!
+// Make sure this stays in sync with ../../../../runtime/hashmap.go!
const (
BUCKETSIZE = 8
MAXKEYSIZE = 128
@@ -150,7 +150,7 @@ func mapbucket(t *Type) *Type {
}
// Builds a type representing a Hmap structure for the given map type.
-// Make sure this stays in sync with ../../runtime/hashmap.go!
+// Make sure this stays in sync with ../../../../runtime/hashmap.go!
func hmap(t *Type) *Type {
if t.Hmap != nil {
return t.Hmap
@@ -187,7 +187,7 @@ func hiter(t *Type) *Type {
}
// build a struct:
- // hash_iter {
+ // hiter {
// key *Key
// val *Value
// t *MapType
@@ -201,7 +201,7 @@ func hiter(t *Type) *Type {
// bucket uintptr
// checkBucket uintptr
// }
- // must match ../../runtime/hashmap.go:hash_iter.
+ // must match ../../../../runtime/hashmap.go:hiter.
var field [12]*Type
field[0] = makefield("key", Ptrto(t.Down))
@@ -474,7 +474,7 @@ func dgopkgpath(s *Sym, ot int, pkg *Pkg) int {
}
// uncommonType
-// ../../runtime/type.go:/uncommonType
+// ../../../../runtime/type.go:/uncommonType
func dextratype(sym *Sym, off int, t *Type, ptroff int) int {
m := methods(t)
if t.Sym == nil && len(m) == 0 {
@@ -514,7 +514,7 @@ func dextratype(sym *Sym, off int, t *Type, ptroff int) int {
// methods
for _, a := range m {
// method
- // ../../runtime/type.go:/method
+ // ../../../../runtime/type.go:/method
ot = dgostringptr(s, ot, a.name)
ot = dgopkgpath(s, ot, a.pkg)
@@ -711,21 +711,21 @@ func dcommontype(s *Sym, ot int, t *Type) int {
gcsym, useGCProg, ptrdata := dgcsym(t)
- // ../../pkg/reflect/type.go:/^type.commonType
+ // ../../../../reflect/type.go:/^type.rtype
// actual type structure
- // type commonType struct {
+ // type rtype struct {
// size uintptr
- // ptrsize uintptr
+ // ptrdata uintptr
// hash uint32
// _ uint8
// align uint8
// fieldAlign uint8
// kind uint8
- // alg unsafe.Pointer
- // gcdata unsafe.Pointer
+ // alg *typeAlg
+ // gcdata *byte
// string *string
- // *extraType
- // ptrToThis *Type
+ // *uncommonType
+ // ptrToThis *rtype
// }
ot = duintptr(s, ot, uint64(t.Width))
ot = duintptr(s, ot, uint64(ptrdata))
@@ -1011,7 +1011,7 @@ ok:
case TARRAY:
if t.Bound >= 0 {
- // ../../runtime/type.go:/ArrayType
+ // ../../../../runtime/type.go:/arrayType
s1 := dtypesym(t.Type)
t2 := typ(TARRAY)
@@ -1024,7 +1024,7 @@ ok:
ot = dsymptr(s, ot, s2, 0)
ot = duintptr(s, ot, uint64(t.Bound))
} else {
- // ../../runtime/type.go:/SliceType
+ // ../../../../runtime/type.go:/sliceType
s1 := dtypesym(t.Type)
ot = dcommontype(s, ot, t)
@@ -1032,7 +1032,7 @@ ok:
ot = dsymptr(s, ot, s1, 0)
}
- // ../../runtime/type.go:/ChanType
+ // ../../../../runtime/type.go:/chanType
case TCHAN:
s1 := dtypesym(t.Type)
@@ -1091,7 +1091,7 @@ ok:
dtypesym(a.type_)
}
- // ../../../runtime/type.go:/InterfaceType
+ // ../../../../runtime/type.go:/interfaceType
ot = dcommontype(s, ot, t)
xt = ot - 2*Widthptr
@@ -1099,14 +1099,14 @@ ok:
ot = duintxx(s, ot, uint64(n), Widthint)
ot = duintxx(s, ot, uint64(n), Widthint)
for _, a := range m {
- // ../../../runtime/type.go:/imethod
+ // ../../../../runtime/type.go:/imethod
ot = dgostringptr(s, ot, a.name)
ot = dgopkgpath(s, ot, a.pkg)
ot = dsymptr(s, ot, dtypesym(a.type_), 0)
}
- // ../../../runtime/type.go:/MapType
+ // ../../../../runtime/type.go:/mapType
case TMAP:
s1 := dtypesym(t.Down)
@@ -1141,20 +1141,20 @@ ok:
case TPTR32, TPTR64:
if t.Type.Etype == TANY {
- // ../../runtime/type.go:/UnsafePointerType
+ // ../../../../runtime/type.go:/UnsafePointerType
ot = dcommontype(s, ot, t)
break
}
- // ../../runtime/type.go:/PtrType
+ // ../../../../runtime/type.go:/ptrType
s1 := dtypesym(t.Type)
ot = dcommontype(s, ot, t)
xt = ot - 2*Widthptr
ot = dsymptr(s, ot, s1, 0)
- // ../../runtime/type.go:/StructType
+ // ../../../../runtime/type.go:/structType
// for security, only the exported fields.
case TSTRUCT:
n := 0
@@ -1170,7 +1170,7 @@ ok:
ot = duintxx(s, ot, uint64(n), Widthint)
ot = duintxx(s, ot, uint64(n), Widthint)
for t1 := t.Type; t1 != nil; t1 = t1.Down {
- // ../../runtime/type.go:/structField
+ // ../../../../runtime/type.go:/structField
if t1.Sym != nil && t1.Embedded == 0 {
ot = dgostringptr(s, ot, t1.Sym.Name)
if exportname(t1.Sym.Name) {
@@ -1350,7 +1350,7 @@ func dalgsym(t *Type) *Sym {
ggloblsym(eqfunc, int32(Widthptr), obj.DUPOK|obj.RODATA)
}
- // ../../runtime/alg.go:/typeAlg
+ // ../../../../runtime/alg.go:/typeAlg
ot := 0
ot = dsymptr(s, ot, hashfunc, 0)
From 9194421eedfd64d2d71e66cbf060d19502610c30 Mon Sep 17 00:00:00 2001
From: Mikio Hara
Date: Fri, 19 Feb 2016 17:41:44 +0900
Subject: [PATCH 070/117] net: deflake TestDialerDualStackFDLeak
We need to stop the mock listener certainly for preventing it from
pulling up pending connections during measurement.
Fixes #14223.
Change-Id: Ia40db01d1262963697b83ca867563dec77d772e3
Reviewed-on: https://go-review.googlesource.com/19246
Run-TryBot: Mikio Hara
TryBot-Result: Gobot Gobot
Reviewed-by: Ian Lance Taylor
---
src/net/dial_test.go | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/net/dial_test.go b/src/net/dial_test.go
index 2311b10824..1a9dfb26d3 100644
--- a/src/net/dial_test.go
+++ b/src/net/dial_test.go
@@ -176,6 +176,7 @@ func TestDialerDualStackFDLeak(t *testing.T) {
t.Skip("both IPv4 and IPv6 are required")
}
+ before := sw.Sockets()
origTestHookLookupIP := testHookLookupIP
defer func() { testHookLookupIP = origTestHookLookupIP }()
testHookLookupIP = lookupLocalhost
@@ -195,17 +196,15 @@ func TestDialerDualStackFDLeak(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- defer dss.teardown()
if err := dss.buildup(handler); err != nil {
+ dss.teardown()
t.Fatal(err)
}
- before := sw.Sockets()
- const T = 100 * time.Millisecond
const N = 10
var wg sync.WaitGroup
wg.Add(N)
- d := &Dialer{DualStack: true, Timeout: T}
+ d := &Dialer{DualStack: true, Timeout: 100 * time.Millisecond}
for i := 0; i < N; i++ {
go func() {
defer wg.Done()
@@ -218,7 +217,7 @@ func TestDialerDualStackFDLeak(t *testing.T) {
}()
}
wg.Wait()
- time.Sleep(2 * T) // wait for the dial racers to stop
+ dss.teardown()
after := sw.Sockets()
if len(after) != len(before) {
t.Errorf("got %d; want %d", len(after), len(before))
From 6716a54e368be250b3840fcdef3c2437886e02e6 Mon Sep 17 00:00:00 2001
From: Mikio Hara
Date: Fri, 19 Feb 2016 17:37:04 +0900
Subject: [PATCH 071/117] net: make newLocalListener handle network argument
correcly
Change-Id: I8987e705af069846e6668e2f2104e0254e695139
Reviewed-on: https://go-review.googlesource.com/19706
Run-TryBot: Mikio Hara
TryBot-Result: Gobot Gobot
Reviewed-by: Ian Lance Taylor
---
src/net/mockserver_test.go | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/src/net/mockserver_test.go b/src/net/mockserver_test.go
index dd6f4df3b9..38b317af7d 100644
--- a/src/net/mockserver_test.go
+++ b/src/net/mockserver_test.go
@@ -30,10 +30,20 @@ func testUnixAddr() string {
func newLocalListener(network string) (Listener, error) {
switch network {
- case "tcp", "tcp4", "tcp6":
+ case "tcp":
+ if supportsIPv4 {
+ if ln, err := Listen("tcp4", "127.0.0.1:0"); err == nil {
+ return ln, nil
+ }
+ }
+ if supportsIPv6 {
+ return Listen("tcp6", "[::1]:0")
+ }
+ case "tcp4":
if supportsIPv4 {
return Listen("tcp4", "127.0.0.1:0")
}
+ case "tcp6":
if supportsIPv6 {
return Listen("tcp6", "[::1]:0")
}
From 64d2a88105d503d1a0275388823b8112a870d13b Mon Sep 17 00:00:00 2001
From: Mikio Hara
Date: Fri, 19 Feb 2016 17:34:54 +0900
Subject: [PATCH 072/117] net/internal/socktest: add missing support for
AcceptEx
Change-Id: I37faedc6fa316fffac80093b01e15429995b0f5b
Reviewed-on: https://go-review.googlesource.com/19705
Reviewed-by: Ian Lance Taylor
---
src/net/internal/socktest/switch.go | 2 +-
src/net/internal/socktest/sys_windows.go | 30 ++++++++++++++++++++++++
2 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/src/net/internal/socktest/switch.go b/src/net/internal/socktest/switch.go
index 8bef06b97c..3c37b6ff80 100644
--- a/src/net/internal/socktest/switch.go
+++ b/src/net/internal/socktest/switch.go
@@ -121,7 +121,7 @@ const (
FilterSocket FilterType = iota // for Socket
FilterConnect // for Connect or ConnectEx
FilterListen // for Listen
- FilterAccept // for Accept or Accept4
+ FilterAccept // for Accept, Accept4 or AcceptEx
FilterGetsockoptInt // for GetsockoptInt
FilterClose // for Close or Closesocket
)
diff --git a/src/net/internal/socktest/sys_windows.go b/src/net/internal/socktest/sys_windows.go
index e61bf2be60..2e3d2bc7fc 100644
--- a/src/net/internal/socktest/sys_windows.go
+++ b/src/net/internal/socktest/sys_windows.go
@@ -154,3 +154,33 @@ func (sw *Switch) Listen(s syscall.Handle, backlog int) (err error) {
sw.stats.getLocked(so.Cookie).Listened++
return nil
}
+
+// AcceptEx wraps syscall.AcceptEx.
+func (sw *Switch) AcceptEx(ls syscall.Handle, as syscall.Handle, b *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, rcvd *uint32, overlapped *syscall.Overlapped) error {
+ so := sw.sockso(ls)
+ if so == nil {
+ return syscall.AcceptEx(ls, as, b, rxdatalen, laddrlen, raddrlen, rcvd, overlapped)
+ }
+ sw.fmu.RLock()
+ f, _ := sw.fltab[FilterAccept]
+ sw.fmu.RUnlock()
+
+ af, err := f.apply(so)
+ if err != nil {
+ return err
+ }
+ so.Err = syscall.AcceptEx(ls, as, b, rxdatalen, laddrlen, raddrlen, rcvd, overlapped)
+ if err = af.apply(so); err != nil {
+ return err
+ }
+
+ sw.smu.Lock()
+ defer sw.smu.Unlock()
+ if so.Err != nil {
+ sw.stats.getLocked(so.Cookie).AcceptFailed++
+ return so.Err
+ }
+ nso := sw.addLocked(as, so.Cookie.Family(), so.Cookie.Type(), so.Cookie.Protocol())
+ sw.stats.getLocked(nso.Cookie).Accepted++
+ return nil
+}
From 92b74d0940cd46e3a480137844d9d61986f7d895 Mon Sep 17 00:00:00 2001
From: Mikio Hara
Date: Fri, 19 Feb 2016 17:45:22 +0900
Subject: [PATCH 073/117] net: add missing aborted connection handling on
accept test
This change adds TestAcceptIgnoreAbortedConnRequest to test accepting
aborted connection requests on all supported platforms except Plan 9.
Change-Id: I5936b04085184ff348539962289b1167ec4ac619
Reviewed-on: https://go-review.googlesource.com/19707
Reviewed-by: Ian Lance Taylor
Run-TryBot: Mikio Hara
TryBot-Result: Gobot Gobot
---
src/net/error_plan9_test.go | 2 ++
src/net/error_posix_test.go | 10 -------
src/net/error_unix_test.go | 21 +++++++++++++
src/net/error_windows_test.go | 19 ++++++++++++
src/net/fd_windows.go | 2 +-
src/net/hook_windows.go | 11 +++----
src/net/main_windows_test.go | 3 ++
src/net/net_test.go | 56 +++++++++++++++++++++++++++++++++++
8 files changed, 108 insertions(+), 16 deletions(-)
create mode 100644 src/net/error_unix_test.go
create mode 100644 src/net/error_windows_test.go
diff --git a/src/net/error_plan9_test.go b/src/net/error_plan9_test.go
index 495ea96534..d7c7f1487f 100644
--- a/src/net/error_plan9_test.go
+++ b/src/net/error_plan9_test.go
@@ -9,6 +9,8 @@ import "syscall"
var (
errTimedout = syscall.ETIMEDOUT
errOpNotSupported = syscall.EPLAN9
+
+ abortedConnRequestErrors []error
)
func isPlatformError(err error) bool {
diff --git a/src/net/error_posix_test.go b/src/net/error_posix_test.go
index 981cc837ba..b411a378df 100644
--- a/src/net/error_posix_test.go
+++ b/src/net/error_posix_test.go
@@ -12,16 +12,6 @@ import (
"testing"
)
-var (
- errTimedout = syscall.ETIMEDOUT
- errOpNotSupported = syscall.EOPNOTSUPP
-)
-
-func isPlatformError(err error) bool {
- _, ok := err.(syscall.Errno)
- return ok
-}
-
func TestSpuriousENOTAVAIL(t *testing.T) {
for _, tt := range []struct {
error
diff --git a/src/net/error_unix_test.go b/src/net/error_unix_test.go
new file mode 100644
index 0000000000..db66d0acf1
--- /dev/null
+++ b/src/net/error_unix_test.go
@@ -0,0 +1,21 @@
+// Copyright 2015 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 !plan9,!windows
+
+package net
+
+import "syscall"
+
+var (
+ errTimedout = syscall.ETIMEDOUT
+ errOpNotSupported = syscall.EOPNOTSUPP
+
+ abortedConnRequestErrors = []error{syscall.ECONNABORTED} // see accept in fd_unix.go
+)
+
+func isPlatformError(err error) bool {
+ _, ok := err.(syscall.Errno)
+ return ok
+}
diff --git a/src/net/error_windows_test.go b/src/net/error_windows_test.go
new file mode 100644
index 0000000000..834a9de441
--- /dev/null
+++ b/src/net/error_windows_test.go
@@ -0,0 +1,19 @@
+// Copyright 2015 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 net
+
+import "syscall"
+
+var (
+ errTimedout = syscall.ETIMEDOUT
+ errOpNotSupported = syscall.EOPNOTSUPP
+
+ abortedConnRequestErrors = []error{syscall.ERROR_NETNAME_DELETED, syscall.WSAECONNRESET} // see accept in fd_windows.go
+)
+
+func isPlatformError(err error) bool {
+ _, ok := err.(syscall.Errno)
+ return ok
+}
diff --git a/src/net/fd_windows.go b/src/net/fd_windows.go
index fd50d772d6..abdee9d02c 100644
--- a/src/net/fd_windows.go
+++ b/src/net/fd_windows.go
@@ -579,7 +579,7 @@ func (fd *netFD) acceptOne(rawsa []syscall.RawSockaddrAny, o *operation) (*netFD
o.handle = s
o.rsan = int32(unsafe.Sizeof(rawsa[0]))
_, err = rsrv.ExecIO(o, "AcceptEx", func(o *operation) error {
- return syscall.AcceptEx(o.fd.sysfd, o.handle, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o)
+ return acceptFunc(o.fd.sysfd, o.handle, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o)
})
if err != nil {
netfd.Close()
diff --git a/src/net/hook_windows.go b/src/net/hook_windows.go
index 126b0ebdd1..63ea35ab8c 100644
--- a/src/net/hook_windows.go
+++ b/src/net/hook_windows.go
@@ -13,9 +13,10 @@ var (
testHookDialChannel = func() { time.Sleep(time.Millisecond) } // see golang.org/issue/5349
// Placeholders for socket system calls.
- socketFunc func(int, int, int) (syscall.Handle, error) = syscall.Socket
- closeFunc func(syscall.Handle) error = syscall.Closesocket
- connectFunc func(syscall.Handle, syscall.Sockaddr) error = syscall.Connect
- connectExFunc func(syscall.Handle, syscall.Sockaddr, *byte, uint32, *uint32, *syscall.Overlapped) error = syscall.ConnectEx
- listenFunc func(syscall.Handle, int) error = syscall.Listen
+ socketFunc func(int, int, int) (syscall.Handle, error) = syscall.Socket
+ closeFunc func(syscall.Handle) error = syscall.Closesocket
+ connectFunc func(syscall.Handle, syscall.Sockaddr) error = syscall.Connect
+ connectExFunc func(syscall.Handle, syscall.Sockaddr, *byte, uint32, *uint32, *syscall.Overlapped) error = syscall.ConnectEx
+ listenFunc func(syscall.Handle, int) error = syscall.Listen
+ acceptFunc func(syscall.Handle, syscall.Handle, *byte, uint32, uint32, uint32, *uint32, *syscall.Overlapped) error = syscall.AcceptEx
)
diff --git a/src/net/main_windows_test.go b/src/net/main_windows_test.go
index 2d829743ec..b879717425 100644
--- a/src/net/main_windows_test.go
+++ b/src/net/main_windows_test.go
@@ -11,6 +11,7 @@ var (
origConnect = connectFunc
origConnectEx = connectExFunc
origListen = listenFunc
+ origAccept = acceptFunc
)
func installTestHooks() {
@@ -19,6 +20,7 @@ func installTestHooks() {
connectFunc = sw.Connect
connectExFunc = sw.ConnectEx
listenFunc = sw.Listen
+ acceptFunc = sw.AcceptEx
}
func uninstallTestHooks() {
@@ -27,6 +29,7 @@ func uninstallTestHooks() {
connectFunc = origConnect
connectExFunc = origConnectEx
listenFunc = origListen
+ acceptFunc = origAccept
}
func forceCloseSockets() {
diff --git a/src/net/net_test.go b/src/net/net_test.go
index cd62b4373e..94392928c2 100644
--- a/src/net/net_test.go
+++ b/src/net/net_test.go
@@ -6,6 +6,7 @@ package net
import (
"io"
+ "net/internal/socktest"
"os"
"runtime"
"testing"
@@ -304,3 +305,58 @@ func TestListenCloseListen(t *testing.T) {
}
t.Fatalf("failed to listen/close/listen on same address after %d tries", maxTries)
}
+
+// See golang.org/issue/6163, golang.org/issue/6987.
+func TestAcceptIgnoreAbortedConnRequest(t *testing.T) {
+ switch runtime.GOOS {
+ case "plan9":
+ t.Skipf("%s does not have full support of socktest", runtime.GOOS)
+ }
+
+ syserr := make(chan error)
+ go func() {
+ defer close(syserr)
+ for _, err := range abortedConnRequestErrors {
+ syserr <- err
+ }
+ }()
+ sw.Set(socktest.FilterAccept, func(so *socktest.Status) (socktest.AfterFilter, error) {
+ if err, ok := <-syserr; ok {
+ return nil, err
+ }
+ return nil, nil
+ })
+ defer sw.Set(socktest.FilterAccept, nil)
+
+ operr := make(chan error, 1)
+ handler := func(ls *localServer, ln Listener) {
+ defer close(operr)
+ c, err := ln.Accept()
+ if err != nil {
+ if perr := parseAcceptError(err); perr != nil {
+ operr <- perr
+ }
+ operr <- err
+ return
+ }
+ c.Close()
+ }
+ ls, err := newLocalServer("tcp")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer ls.teardown()
+ if err := ls.buildup(handler); err != nil {
+ t.Fatal(err)
+ }
+
+ c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
+ if err != nil {
+ t.Fatal(err)
+ }
+ c.Close()
+
+ for err := range operr {
+ t.Error(err)
+ }
+}
From de6a5881bbf85113186d9cfdbe51fd3165ba7e4c Mon Sep 17 00:00:00 2001
From: Josh Bleecher Snyder
Date: Thu, 2 Jul 2015 17:56:13 -0700
Subject: [PATCH 074/117] bytes: make Buffer comment more accurate
Change-Id: Ief22b3dbba9616dd40bf3ea8e2633d3c5e7d1886
Reviewed-on: https://go-review.googlesource.com/19761
Reviewed-by: Brad Fitzpatrick
---
src/bytes/buffer.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/bytes/buffer.go b/src/bytes/buffer.go
index ddaba3bff3..f135b46959 100644
--- a/src/bytes/buffer.go
+++ b/src/bytes/buffer.go
@@ -17,7 +17,7 @@ import (
type Buffer struct {
buf []byte // contents are the bytes buf[off : len(buf)]
off int // read at &buf[off], write at &buf[len(buf)]
- runeBytes [utf8.UTFMax]byte // avoid allocation of slice on each WriteByte or Rune
+ runeBytes [utf8.UTFMax]byte // avoid allocation of slice on each call to WriteRune
bootstrap [64]byte // memory to hold first slice; helps small buffers (Printf) avoid allocation.
lastRead readOp // last read operation, so that Unread* can work correctly.
}
From 1dbba1a2b7c5d04bc7ad560010a887b441feb0f4 Mon Sep 17 00:00:00 2001
From: Josh Bleecher Snyder
Date: Mon, 4 May 2015 14:56:52 -0700
Subject: [PATCH 075/117] encoding/hex: minor cleanup
Change-Id: I404fd946dd0607fa41e2abe0d1d8081d4433ff0a
Reviewed-on: https://go-review.googlesource.com/19762
Reviewed-by: Brad Fitzpatrick
Run-TryBot: Brad Fitzpatrick
TryBot-Result: Gobot Gobot
---
src/encoding/hex/hex.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/encoding/hex/hex.go b/src/encoding/hex/hex.go
index d1fc7024a9..a51b1db61c 100644
--- a/src/encoding/hex/hex.go
+++ b/src/encoding/hex/hex.go
@@ -105,7 +105,7 @@ func Dump(data []byte) string {
dumper := Dumper(&buf)
dumper.Write(data)
dumper.Close()
- return string(buf.Bytes())
+ return buf.String()
}
// Dumper returns a WriteCloser that writes a hex dump of all written data to
From 5fc43c94bf3ba6158d970488bff715e60f37e33f Mon Sep 17 00:00:00 2001
From: Josh Bleecher Snyder
Date: Tue, 26 May 2015 15:41:42 -0700
Subject: [PATCH 076/117] net/url: simplify value lookup
Change-Id: Ic998c189003d4dee758fca3b5ac954d5b54d3d36
Reviewed-on: https://go-review.googlesource.com/19764
Reviewed-by: Brad Fitzpatrick
Run-TryBot: Brad Fitzpatrick
TryBot-Result: Gobot Gobot
---
src/net/url/url.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/net/url/url.go b/src/net/url/url.go
index b7e25ecfcb..b3513a85a3 100644
--- a/src/net/url/url.go
+++ b/src/net/url/url.go
@@ -709,8 +709,8 @@ func (v Values) Get(key string) string {
if v == nil {
return ""
}
- vs, ok := v[key]
- if !ok || len(vs) == 0 {
+ vs := v[key]
+ if len(vs) == 0 {
return ""
}
return vs[0]
From 5621b09dadca86202e3c921b3a1e323ec60b2742 Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Fri, 19 Feb 2016 23:01:10 -0800
Subject: [PATCH 077/117] cmd/compile: simplify import path handling
Change-Id: I64c9b4c4978520a9bc989b7fd7d5708d364dc88a
Reviewed-on: https://go-review.googlesource.com/19755
Run-TryBot: Matthew Dempsky
TryBot-Result: Gobot Gobot
Reviewed-by: Robert Griesemer
---
src/cmd/compile/internal/gc/go.go | 7 -------
src/cmd/compile/internal/gc/lex.go | 19 +++++++------------
2 files changed, 7 insertions(+), 19 deletions(-)
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
index 13a28c8720..9b55eb8848 100644
--- a/src/cmd/compile/internal/gc/go.go
+++ b/src/cmd/compile/internal/gc/go.go
@@ -397,11 +397,6 @@ type Dlist struct {
field *Type
}
-type Idir struct {
- link *Idir
- dir string
-}
-
// argument passing to/from
// smagic and umagic
type Magic struct {
@@ -519,8 +514,6 @@ var Tptr EType // either TPTR32 or TPTR64
var myimportpath string
-var idirs *Idir
-
var localimport string
var asmhdr string
diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
index 66cc01862d..08545df953 100644
--- a/src/cmd/compile/internal/gc/lex.go
+++ b/src/cmd/compile/internal/gc/lex.go
@@ -561,17 +561,12 @@ func skiptopkgdef(b *obj.Biobuf) bool {
return true
}
-func addidir(dir string) {
- if dir == "" {
- return
- }
+var idirs []string
- var pp **Idir
- for pp = &idirs; *pp != nil; pp = &(*pp).link {
+func addidir(dir string) {
+ if dir != "" {
+ idirs = append(idirs, dir)
}
- *pp = new(Idir)
- (*pp).link = nil
- (*pp).dir = dir
}
// is this path a local name? begins with ./ or ../ or /
@@ -610,12 +605,12 @@ func findpkg(name string) (file string, ok bool) {
return "", false
}
- for p := idirs; p != nil; p = p.link {
- file = fmt.Sprintf("%s/%s.a", p.dir, name)
+ for _, dir := range idirs {
+ file = fmt.Sprintf("%s/%s.a", dir, name)
if _, err := os.Stat(file); err == nil {
return file, true
}
- file = fmt.Sprintf("%s/%s.o", p.dir, name)
+ file = fmt.Sprintf("%s/%s.o", dir, name)
if _, err := os.Stat(file); err == nil {
return file, true
}
From 11e51ed4bc3d901c4272ba57bde4771bb7d8f6f6 Mon Sep 17 00:00:00 2001
From: Robert Griesemer
Date: Sat, 20 Feb 2016 11:06:35 -0800
Subject: [PATCH 078/117] cmd/compile: remove gratuituous copying of lexer
token data
Rename yySymType to lexer; should eventually capture all lexer state.
Embed lexer in parser and access lexer token data directly.
Change-Id: I246194705d594f80426f3ba77d8580af9185daf7
Reviewed-on: https://go-review.googlesource.com/19759
Reviewed-by: Matthew Dempsky
---
src/cmd/compile/internal/gc/lex.go | 29 ++++++++++++++++-----------
src/cmd/compile/internal/gc/parser.go | 19 ++++--------------
2 files changed, 21 insertions(+), 27 deletions(-)
diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
index 08545df953..a6f65bec62 100644
--- a/src/cmd/compile/internal/gc/lex.go
+++ b/src/cmd/compile/internal/gc/lex.go
@@ -866,10 +866,15 @@ func isfrog(c int) bool {
return false
}
-type yySymType struct {
- sym *Sym
- val Val
- op Op
+type lexer struct {
+ // TODO(gri) move other lexer state here and out of global variables
+ // (source, current line number, etc.)
+
+ // current token
+ tok int32
+ sym_ *Sym // valid if tok == LNAME
+ val Val // valid if tok == LLITERAL
+ op Op // valid if tok == LASOP
}
const (
@@ -920,7 +925,7 @@ const (
LRSH
)
-func _yylex(yylval *yySymType) int32 {
+func (yylval *lexer) _yylex() int32 {
var c1 int
var op Op
var escflag int
@@ -1402,7 +1407,7 @@ talph:
if Debug['x'] != 0 {
fmt.Printf("lex: %s %s\n", s, lexname(int(s.Lexical)))
}
- yylval.sym = s
+ yylval.sym_ = s
return int32(s.Lexical)
ncu:
@@ -1828,16 +1833,16 @@ func pragcgo(text string) {
}
}
-func yylex(yylval *yySymType) int32 {
- lx := _yylex(yylval)
+func (l *lexer) next() {
+ tok := l._yylex()
- if curio.nlsemi && lx == EOF {
+ if curio.nlsemi && tok == EOF {
// Treat EOF as "end of line" for the purposes
// of inserting a semicolon.
- lx = ';'
+ tok = ';'
}
- switch lx {
+ switch tok {
case LNAME,
LLITERAL,
LBREAK,
@@ -1855,7 +1860,7 @@ func yylex(yylval *yySymType) int32 {
curio.nlsemi = false
}
- return lx
+ l.tok = tok
}
func getc() int {
diff --git a/src/cmd/compile/internal/gc/parser.go b/src/cmd/compile/internal/gc/parser.go
index 3a5b508393..deae40c21b 100644
--- a/src/cmd/compile/internal/gc/parser.go
+++ b/src/cmd/compile/internal/gc/parser.go
@@ -42,21 +42,10 @@ func parse_file(bin *obj.Biobuf) {
}
type parser struct {
- tok int32 // next token (one-token look-ahead)
- op Op // valid if tok == LASOP
- val Val // valid if tok == LLITERAL
- sym_ *Sym // valid if tok == LNAME
- fnest int // function nesting level (for error handling)
- xnest int // expression nesting level (for complit ambiguity resolution)
- yy yySymType // for temporary use by next
- indent []byte // tracing support
-}
-
-func (p *parser) next() {
- p.tok = yylex(&p.yy)
- p.op = p.yy.op
- p.val = p.yy.val
- p.sym_ = p.yy.sym
+ lexer
+ fnest int // function nesting level (for error handling)
+ xnest int // expression nesting level (for complit ambiguity resolution)
+ indent []byte // tracing support
}
func (p *parser) got(tok int32) bool {
From 20ee67acc920807d19d336b1cc1614d2ad529953 Mon Sep 17 00:00:00 2001
From: Robert Griesemer
Date: Sat, 20 Feb 2016 11:16:21 -0800
Subject: [PATCH 079/117] cmd/compile: test for lower-case letters first in
isAlpha
Lower-case letters are more common in identifiers.
Change-Id: I49c39e3ac810eea57d15c1433608daec212c9792
Reviewed-on: https://go-review.googlesource.com/19760
Reviewed-by: Matthew Dempsky
---
src/cmd/compile/internal/gc/lex.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
index a6f65bec62..55d988b70a 100644
--- a/src/cmd/compile/internal/gc/lex.go
+++ b/src/cmd/compile/internal/gc/lex.go
@@ -832,7 +832,7 @@ func isSpace(c int) bool {
}
func isAlpha(c int) bool {
- return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'
+ return 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z'
}
func isDigit(c int) bool {
From aa5b44aeabccd25a320d6ea609c41781bdbf5ce0 Mon Sep 17 00:00:00 2001
From: Robert Griesemer
Date: Sat, 20 Feb 2016 12:53:34 -0800
Subject: [PATCH 080/117] cmd/compile: set lexer nlsemi state directly
The old code used an extra function call and switch to inspect the
current token and determine the new state of curio.nlsemi. However,
the lexer knows the token w/o the need of an extra test and thus
can set curio.nlsemi directly:
- removed need for extra function call in next
- renamed _yylex to next
- set nlsemi at the point a token is identified
- moved nlsemi from curio to lexer - it's really part of the lexer state
This change makes the lexer call sequence less convoluted and should
also speed up the lexing a bit.
Change-Id: Iaf2683081f04231cb62c94e1400d455f98f6f82a
Reviewed-on: https://go-review.googlesource.com/19765
Reviewed-by: Matthew Dempsky
---
src/cmd/compile/internal/gc/go.go | 1 -
src/cmd/compile/internal/gc/lex.go | 135 +++++++++++++++--------------
2 files changed, 71 insertions(+), 65 deletions(-)
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
index 9b55eb8848..d21b2fb196 100644
--- a/src/cmd/compile/internal/gc/go.go
+++ b/src/cmd/compile/internal/gc/go.go
@@ -389,7 +389,6 @@ type Io struct {
last int
peekc int
peekc1 int // second peekc for ...
- nlsemi bool
eofnl bool
}
diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
index 55d988b70a..54c69c5449 100644
--- a/src/cmd/compile/internal/gc/lex.go
+++ b/src/cmd/compile/internal/gc/lex.go
@@ -869,6 +869,7 @@ func isfrog(c int) bool {
type lexer struct {
// TODO(gri) move other lexer state here and out of global variables
// (source, current line number, etc.)
+ nlsemi bool // if set, '\n' and EOF translate to ';'
// current token
tok int32
@@ -925,7 +926,7 @@ const (
LRSH
)
-func (yylval *lexer) _yylex() int32 {
+func (l *lexer) next() {
var c1 int
var op Op
var escflag int
@@ -936,27 +937,31 @@ func (yylval *lexer) _yylex() int32 {
prevlineno = lineno
+ nlsemi := l.nlsemi
+ l.nlsemi = false
+
l0:
+ // skip white space
c := getc()
- if isSpace(c) {
- if c == '\n' && curio.nlsemi {
+ for isSpace(c) {
+ if c == '\n' && nlsemi {
ungetc(c)
if Debug['x'] != 0 {
fmt.Printf("lex: implicit semi\n")
}
- return ';'
+ l.tok = ';'
+ return
}
-
- goto l0
+ c = getc()
}
- lineno = lexlineno // start of token
+ // start of token
+ lineno = lexlineno
if c >= utf8.RuneSelf {
// all multibyte runes are alpha
cp = &lexbuf
cp.Reset()
-
goto talph
}
@@ -1049,7 +1054,17 @@ l0:
case EOF:
lineno = prevlineno
ungetc(EOF)
- return -1
+ // Treat EOF as "end of line" for the purposes
+ // of inserting a semicolon.
+ if nlsemi {
+ if Debug['x'] != 0 {
+ fmt.Printf("lex: implicit semi\n")
+ }
+ l.tok = ';'
+ return
+ }
+ l.tok = -1
+ return
case '_':
cp = &lexbuf
@@ -1137,14 +1152,16 @@ l0:
}
x := new(Mpint)
- yylval.val.U = x
+ l.val.U = x
Mpmovecfix(x, v)
x.Rune = true
if Debug['x'] != 0 {
fmt.Printf("lex: codepoint literal\n")
}
litbuf = "string literal"
- return LLITERAL
+ l.nlsemi = true
+ l.tok = LLITERAL
+ return
case '/':
c1 = getc()
@@ -1217,6 +1234,7 @@ l0:
case '+':
c1 = getc()
if c1 == '+' {
+ l.nlsemi = true
c = int(LINC)
goto lx
}
@@ -1229,6 +1247,7 @@ l0:
case '-':
c1 = getc()
if c1 == '-' {
+ l.nlsemi = true
c = int(LDEC)
goto lx
}
@@ -1339,6 +1358,10 @@ l0:
goto asop
}
+ case ')', ']', '}':
+ l.nlsemi = true
+ goto lx
+
default:
goto lx
}
@@ -1363,14 +1386,16 @@ lx:
goto l0
}
- return int32(c)
+ l.tok = int32(c)
+ return
asop:
- yylval.op = op
+ l.op = op
if Debug['x'] != 0 {
fmt.Printf("lex: TOKEN ASOP %s=\n", goopnames[op])
}
- return LASOP
+ l.tok = LASOP
+ return
// cp is set to lexbuf and some
// prefix has been stored
@@ -1407,26 +1432,33 @@ talph:
if Debug['x'] != 0 {
fmt.Printf("lex: %s %s\n", s, lexname(int(s.Lexical)))
}
- yylval.sym_ = s
- return int32(s.Lexical)
+ l.sym_ = s
+ switch s.Lexical {
+ case LNAME, LRETURN, LBREAK, LCONTINUE, LFALL:
+ l.nlsemi = true
+ }
+ l.tok = int32(s.Lexical)
+ return
ncu:
cp = nil
ungetc(c)
str = lexbuf.String()
- yylval.val.U = new(Mpint)
- mpatofix(yylval.val.U.(*Mpint), str)
- if yylval.val.U.(*Mpint).Ovf {
+ l.val.U = new(Mpint)
+ mpatofix(l.val.U.(*Mpint), str)
+ if l.val.U.(*Mpint).Ovf {
Yyerror("overflow in constant")
- Mpmovecfix(yylval.val.U.(*Mpint), 0)
+ Mpmovecfix(l.val.U.(*Mpint), 0)
}
if Debug['x'] != 0 {
fmt.Printf("lex: integer literal\n")
}
litbuf = "literal " + str
- return LLITERAL
+ l.nlsemi = true
+ l.tok = LLITERAL
+ return
casedot:
for {
@@ -1475,45 +1507,50 @@ casei:
cp = nil
str = lexbuf.String()
- yylval.val.U = new(Mpcplx)
- Mpmovecflt(&yylval.val.U.(*Mpcplx).Real, 0.0)
- mpatoflt(&yylval.val.U.(*Mpcplx).Imag, str)
- if yylval.val.U.(*Mpcplx).Imag.Val.IsInf() {
+ l.val.U = new(Mpcplx)
+ Mpmovecflt(&l.val.U.(*Mpcplx).Real, 0.0)
+ mpatoflt(&l.val.U.(*Mpcplx).Imag, str)
+ if l.val.U.(*Mpcplx).Imag.Val.IsInf() {
Yyerror("overflow in imaginary constant")
- Mpmovecflt(&yylval.val.U.(*Mpcplx).Imag, 0.0)
+ Mpmovecflt(&l.val.U.(*Mpcplx).Imag, 0.0)
}
if Debug['x'] != 0 {
fmt.Printf("lex: imaginary literal\n")
}
litbuf = "literal " + str
- return LLITERAL
+ l.nlsemi = true
+ l.tok = LLITERAL
+ return
caseout:
cp = nil
ungetc(c)
str = lexbuf.String()
- yylval.val.U = newMpflt()
- mpatoflt(yylval.val.U.(*Mpflt), str)
- if yylval.val.U.(*Mpflt).Val.IsInf() {
+ l.val.U = newMpflt()
+ mpatoflt(l.val.U.(*Mpflt), str)
+ if l.val.U.(*Mpflt).Val.IsInf() {
Yyerror("overflow in float constant")
- Mpmovecflt(yylval.val.U.(*Mpflt), 0.0)
+ Mpmovecflt(l.val.U.(*Mpflt), 0.0)
}
if Debug['x'] != 0 {
fmt.Printf("lex: floating literal\n")
}
litbuf = "literal " + str
- return LLITERAL
+ l.nlsemi = true
+ l.tok = LLITERAL
+ return
strlit:
- yylval.val.U = internString(cp.Bytes())
+ l.val.U = internString(cp.Bytes())
if Debug['x'] != 0 {
fmt.Printf("lex: string literal\n")
}
litbuf = "string literal"
- return LLITERAL
+ l.nlsemi = true
+ l.tok = LLITERAL
}
var internedStrings = map[string]string{}
@@ -1833,36 +1870,6 @@ func pragcgo(text string) {
}
}
-func (l *lexer) next() {
- tok := l._yylex()
-
- if curio.nlsemi && tok == EOF {
- // Treat EOF as "end of line" for the purposes
- // of inserting a semicolon.
- tok = ';'
- }
-
- switch tok {
- case LNAME,
- LLITERAL,
- LBREAK,
- LCONTINUE,
- LFALL,
- LRETURN,
- LINC,
- LDEC,
- ')',
- '}',
- ']':
- curio.nlsemi = true
-
- default:
- curio.nlsemi = false
- }
-
- l.tok = tok
-}
-
func getc() int {
c := curio.peekc
if c != 0 {
From 5dc053b9dec4dc25fac195065ad32462ac28a543 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Mo=CC=88hrmann?=
Date: Sun, 21 Feb 2016 10:46:59 +0100
Subject: [PATCH 081/117] fmt: fix zero padding for NaN
Makes zero padding of NaN and infinities consistent
by using spaces instead of zeroes to pad NaN.
Adds more tests for NaN formatting.
Fixes #14421
Change-Id: Ia20f8e878cc81ac72a744ec10d65e84b94e09c6a
Reviewed-on: https://go-review.googlesource.com/19723
Reviewed-by: Rob Pike
---
src/fmt/fmt_test.go | 11 ++++++++++-
src/fmt/format.go | 8 ++++++--
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/src/fmt/fmt_test.go b/src/fmt/fmt_test.go
index 8d7c36ceb1..1d9d015f4a 100644
--- a/src/fmt/fmt_test.go
+++ b/src/fmt/fmt_test.go
@@ -386,6 +386,9 @@ var fmtTests = []struct {
{"%20e", math.Inf(1), " +Inf"},
{"%-20f", math.Inf(-1), "-Inf "},
{"%20g", math.NaN(), " NaN"},
+ {"%+20f", math.NaN(), " +NaN"},
+ {"% -20f", math.NaN(), " NaN "},
+ {"%+-20f", math.NaN(), "+NaN "},
// arrays
{"%v", array, "[1 2 3 4 5]"},
@@ -654,13 +657,19 @@ var fmtTests = []struct {
// Complex numbers: exhaustively tested in TestComplexFormatting.
{"%7.2f", 1 + 2i, "( 1.00 +2.00i)"},
{"%+07.2f", -1 - 2i, "(-001.00-002.00i)"},
- // Zero padding does not apply to infinities.
+ // Zero padding does not apply to infinities and NaN.
{"%020f", math.Inf(-1), " -Inf"},
{"%020f", math.Inf(+1), " +Inf"},
+ {"%020f", math.NaN(), " NaN"},
{"% 020f", math.Inf(-1), " -Inf"},
{"% 020f", math.Inf(+1), " Inf"},
+ {"% 020f", math.NaN(), " NaN"},
{"%+020f", math.Inf(-1), " -Inf"},
{"%+020f", math.Inf(+1), " +Inf"},
+ {"%+020f", math.NaN(), " +NaN"},
+ {"%-020f", math.Inf(-1), "-Inf "},
+ {"%-020f", math.Inf(+1), "+Inf "},
+ {"%-020f", math.NaN(), "NaN "},
{"%20f", -1.0, " -1.000000"},
// Make sure we can handle very large widths.
{"%0100f", -1.0, zeroFill("-", 99, "1.000000")},
diff --git a/src/fmt/format.go b/src/fmt/format.go
index bf9d00bbc0..c811cc6a3d 100644
--- a/src/fmt/format.go
+++ b/src/fmt/format.go
@@ -414,11 +414,15 @@ func (f *fmt) formatFloat(v float64, verb byte, prec, n int) {
if f.space && num[0] == '+' {
num[0] = ' '
}
- // Special handling for "+Inf" and "-Inf",
+ // Special handling for infinities and NaN,
// which don't look like a number so shouldn't be padded with zeros.
- if num[1] == 'I' {
+ if num[1] == 'I' || num[1] == 'N' {
oldZero := f.zero
f.zero = false
+ // Remove sign before NaN if not asked for.
+ if num[1] == 'N' && !f.space && !f.plus {
+ num = num[1:]
+ }
f.pad(num)
f.zero = oldZero
return
From e43c74a0d8848d58814e1a8302d8f115d7f0b874 Mon Sep 17 00:00:00 2001
From: Josh Bleecher Snyder
Date: Wed, 27 Jan 2016 12:49:13 -0800
Subject: [PATCH 082/117] all: use cannot instead of can not
You can not use cannot, but you cannot spell cannot can not.
Change-Id: I2f0971481a460804de96fd8c9e46a9cc62a3fc5b
Reviewed-on: https://go-review.googlesource.com/19772
Reviewed-by: Rob Pike
---
src/archive/zip/writer.go | 2 +-
src/cmd/cgo/doc.go | 2 +-
src/cmd/cgo/gcc.go | 4 ++--
src/cmd/compile/internal/gc/lex.go | 2 +-
src/cmd/go/go_test.go | 2 +-
src/database/sql/sql.go | 2 +-
src/log/syslog/syslog.go | 2 +-
src/net/http/server.go | 2 +-
src/net/http/transport.go | 2 +-
src/os/signal/doc.go | 2 +-
src/runtime/cgocall.go | 2 +-
src/runtime/mbarrier.go | 2 +-
src/runtime/mfixalloc.go | 4 ++--
src/runtime/mstats.go | 4 ++--
src/runtime/norace_linux_test.go | 2 +-
src/runtime/norace_test.go | 2 +-
src/runtime/os1_darwin.go | 2 +-
src/runtime/os1_dragonfly.go | 2 +-
src/runtime/os1_freebsd.go | 2 +-
src/runtime/os1_linux.go | 2 +-
src/runtime/os1_nacl.go | 2 +-
src/runtime/os1_netbsd.go | 2 +-
src/runtime/os1_plan9.go | 2 +-
src/runtime/os1_windows.go | 2 +-
src/runtime/os3_solaris.go | 2 +-
src/runtime/sys_darwin_arm.s | 2 +-
src/runtime/sys_darwin_arm64.s | 2 +-
src/runtime/vdso_linux_amd64.go | 2 +-
src/sync/pool.go | 2 +-
29 files changed, 32 insertions(+), 32 deletions(-)
diff --git a/src/archive/zip/writer.go b/src/archive/zip/writer.go
index 5ce66e6be5..3a9292e380 100644
--- a/src/archive/zip/writer.go
+++ b/src/archive/zip/writer.go
@@ -52,7 +52,7 @@ func (w *Writer) Flush() error {
}
// Close finishes writing the zip file by writing the central directory.
-// It does not (and can not) close the underlying writer.
+// It does not (and cannot) close the underlying writer.
func (w *Writer) Close() error {
if w.last != nil && !w.last.closed {
if err := w.last.close(); err != nil {
diff --git a/src/cmd/cgo/doc.go b/src/cmd/cgo/doc.go
index 8b4e2bfd58..90c2584c7f 100644
--- a/src/cmd/cgo/doc.go
+++ b/src/cmd/cgo/doc.go
@@ -133,7 +133,7 @@ C's union types are represented as a Go byte array with the same length.
Go structs cannot embed fields with C types.
-Go code can not refer to zero-sized fields that occur at the end of
+Go code cannot refer to zero-sized fields that occur at the end of
non-empty C structs. To get the address of such a field (which is the
only operation you can do with a zero-sized field) you must take the
address of the struct and add the size of the struct.
diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go
index fb5049c1a1..5bfdef785c 100644
--- a/src/cmd/cgo/gcc.go
+++ b/src/cmd/cgo/gcc.go
@@ -432,7 +432,7 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
fmt.Fprintf(&b, "\t0,\n")
}
}
- // for the last entry, we can not use 0, otherwise
+ // for the last entry, we cannot use 0, otherwise
// in case all __cgodebug_data is zero initialized,
// LLVM-based gcc will place the it in the __DATA.__common
// zero-filled section (our debug/macho doesn't support
@@ -2025,7 +2025,7 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
// We can't permit that, because then the size of the Go
// struct will not be the same as the size of the C struct.
// Our only option in such a case is to remove the field,
- // which means that it can not be referenced from Go.
+ // which means that it cannot be referenced from Go.
for off > 0 && sizes[len(sizes)-1] == 0 {
n := len(sizes)
fld = fld[0 : n-1]
diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
index 54c69c5449..0f8b20cea0 100644
--- a/src/cmd/compile/internal/gc/lex.go
+++ b/src/cmd/compile/internal/gc/lex.go
@@ -255,7 +255,7 @@ func Main() {
msanpkg.Name = "msan"
}
if flag_race != 0 && flag_msan != 0 {
- log.Fatal("can not use both -race and -msan")
+ log.Fatal("cannot use both -race and -msan")
} else if flag_race != 0 || flag_msan != 0 {
instrumenting = true
}
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index ae426088ea..51931769d5 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -2337,7 +2337,7 @@ func TestGoGetHTTPS404(t *testing.T) {
tg.run("get", "bazil.org/fuse/fs/fstestutil")
}
-// Test that you can not import a main package.
+// Test that you cannot import a main package.
func TestIssue4210(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go
index d8e7cb77af..28c36160b5 100644
--- a/src/database/sql/sql.go
+++ b/src/database/sql/sql.go
@@ -199,7 +199,7 @@ type Scanner interface {
// time.Time
// nil - for NULL values
//
- // An error should be returned if the value can not be stored
+ // An error should be returned if the value cannot be stored
// without loss of information.
Scan(src interface{}) error
}
diff --git a/src/log/syslog/syslog.go b/src/log/syslog/syslog.go
index 4bf447626f..0e342242ec 100644
--- a/src/log/syslog/syslog.go
+++ b/src/log/syslog/syslog.go
@@ -85,7 +85,7 @@ type Writer struct {
}
// This interface and the separate syslog_unix.go file exist for
-// Solaris support as implemented by gccgo. On Solaris you can not
+// Solaris support as implemented by gccgo. On Solaris you cannot
// simply open a TCP connection to the syslog daemon. The gccgo
// sources have a syslog_solaris.go file that implements unixSyslog to
// return a type that satisfies this interface and simply calls the C
diff --git a/src/net/http/server.go b/src/net/http/server.go
index 5e3b6084ae..1b5cda3159 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -2032,7 +2032,7 @@ const (
// For HTTP/2, StateActive fires on the transition from zero
// to one active request, and only transitions away once all
// active requests are complete. That means that ConnState
- // can not be used to do per-request work; ConnState only notes
+ // cannot be used to do per-request work; ConnState only notes
// the overall state of the connection.
StateActive
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
index 1e3ea11d9c..feedb3420d 100644
--- a/src/net/http/transport.go
+++ b/src/net/http/transport.go
@@ -418,7 +418,7 @@ func (t *Transport) CloseIdleConnections() {
// CancelRequest cancels an in-flight request by closing its connection.
// CancelRequest should only be called after RoundTrip has returned.
//
-// Deprecated: Use Request.Cancel instead. CancelRequest can not cancel
+// Deprecated: Use Request.Cancel instead. CancelRequest cannot cancel
// HTTP/2 requests.
func (t *Transport) CancelRequest(req *Request) {
t.reqMu.Lock()
diff --git a/src/os/signal/doc.go b/src/os/signal/doc.go
index 80e66cffe5..9ee547b15d 100644
--- a/src/os/signal/doc.go
+++ b/src/os/signal/doc.go
@@ -11,7 +11,7 @@ package on Windows and Plan 9, see below.
Types of signals
The signals SIGKILL and SIGSTOP may not be caught by a program, and
-therefore can not be affected by this package.
+therefore cannot be affected by this package.
Synchronous signals are signals triggered by errors in program
execution: SIGBUS, SIGFPE, and SIGSEGV. These are only considered
diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go
index fef8add46f..f632f7ab5a 100644
--- a/src/runtime/cgocall.go
+++ b/src/runtime/cgocall.go
@@ -340,7 +340,7 @@ var racecgosync uint64 // represents possible synchronization in C code
// When and if we implement a moving garbage collector,
// cgoCheckPointer will pin the pointer for the duration of the cgo
// call. (This is necessary but not sufficient; the cgo program will
-// also have to change to pin Go pointers that can not point to Go
+// also have to change to pin Go pointers that cannot point to Go
// pointers.)
// cgoCheckPointer checks if the argument contains a Go pointer that
diff --git a/src/runtime/mbarrier.go b/src/runtime/mbarrier.go
index 45086c43cd..1204e8143e 100644
--- a/src/runtime/mbarrier.go
+++ b/src/runtime/mbarrier.go
@@ -100,7 +100,7 @@ func gcmarkwb_m(slot *uintptr, ptr uintptr) {
// related operations. In particular there are times when the GC assumes
// that the world is stopped but scheduler related code is still being
// executed, dealing with syscalls, dealing with putting gs on runnable
-// queues and so forth. This code can not execute write barriers because
+// queues and so forth. This code cannot execute write barriers because
// the GC might drop them on the floor. Stopping the world involves removing
// the p associated with an m. We use the fact that m.p == nil to indicate
// that we are in one these critical section and throw if the write is of
diff --git a/src/runtime/mfixalloc.go b/src/runtime/mfixalloc.go
index 8653a6a99f..569a304cf4 100644
--- a/src/runtime/mfixalloc.go
+++ b/src/runtime/mfixalloc.go
@@ -30,8 +30,8 @@ type fixalloc struct {
}
// A generic linked list of blocks. (Typically the block is bigger than sizeof(MLink).)
-// Since assignments to mlink.next will result in a write barrier being preformed
-// this can not be used by some of the internal GC structures. For example when
+// Since assignments to mlink.next will result in a write barrier being performed
+// this cannot be used by some of the internal GC structures. For example when
// the sweeper is placing an unmarked object on the free list it does not want the
// write barrier to be called since that could result in the object being reachable.
type mlink struct {
diff --git a/src/runtime/mstats.go b/src/runtime/mstats.go
index 368687d006..8ae636077b 100644
--- a/src/runtime/mstats.go
+++ b/src/runtime/mstats.go
@@ -165,7 +165,7 @@ type MemStats struct {
// Size of the trailing by_size array differs between Go and C,
// and all data after by_size is local to runtime, not exported.
-// NumSizeClasses was changed, but we can not change Go struct because of backward compatibility.
+// NumSizeClasses was changed, but we cannot change Go struct because of backward compatibility.
// sizeof_C_MStats is what C thinks about size of Go struct.
var sizeof_C_MStats = unsafe.Offsetof(memstats.by_size) + 61*unsafe.Sizeof(memstats.by_size[0])
@@ -192,7 +192,7 @@ func readmemstats_m(stats *MemStats) {
updatememstats(nil)
// Size of the trailing by_size array differs between Go and C,
- // NumSizeClasses was changed, but we can not change Go struct because of backward compatibility.
+ // NumSizeClasses was changed, but we cannot change Go struct because of backward compatibility.
memmove(unsafe.Pointer(stats), unsafe.Pointer(&memstats), sizeof_C_MStats)
// Stack numbers are part of the heap numbers, separate those out for user consumption
diff --git a/src/runtime/norace_linux_test.go b/src/runtime/norace_linux_test.go
index bbf9d0b413..049801d3fc 100644
--- a/src/runtime/norace_linux_test.go
+++ b/src/runtime/norace_linux_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// The file contains tests that can not run under race detector for some reason.
+// The file contains tests that cannot run under race detector for some reason.
// +build !race
package runtime_test
diff --git a/src/runtime/norace_test.go b/src/runtime/norace_test.go
index 3681bf190d..e9b39b2f45 100644
--- a/src/runtime/norace_test.go
+++ b/src/runtime/norace_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// The file contains tests that can not run under race detector for some reason.
+// The file contains tests that cannot run under race detector for some reason.
// +build !race
package runtime_test
diff --git a/src/runtime/os1_darwin.go b/src/runtime/os1_darwin.go
index 5c00407b2f..19bb0f16e0 100644
--- a/src/runtime/os1_darwin.go
+++ b/src/runtime/os1_darwin.go
@@ -157,7 +157,7 @@ func sigblock() {
}
// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
+// Called on the new thread, cannot allocate memory.
func minit() {
// Initialize signal handling.
_g_ := getg()
diff --git a/src/runtime/os1_dragonfly.go b/src/runtime/os1_dragonfly.go
index bf3e1ccb83..7e4f84e6a3 100644
--- a/src/runtime/os1_dragonfly.go
+++ b/src/runtime/os1_dragonfly.go
@@ -133,7 +133,7 @@ func sigblock() {
}
// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
+// Called on the new thread, cannot allocate memory.
func minit() {
_g_ := getg()
diff --git a/src/runtime/os1_freebsd.go b/src/runtime/os1_freebsd.go
index 79d995476e..f00fdf4389 100644
--- a/src/runtime/os1_freebsd.go
+++ b/src/runtime/os1_freebsd.go
@@ -136,7 +136,7 @@ func sigblock() {
}
// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
+// Called on the new thread, cannot allocate memory.
func minit() {
_g_ := getg()
diff --git a/src/runtime/os1_linux.go b/src/runtime/os1_linux.go
index b38cfc14f9..2d53b934f5 100644
--- a/src/runtime/os1_linux.go
+++ b/src/runtime/os1_linux.go
@@ -225,7 +225,7 @@ func sigblock() {
func gettid() uint32
// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
+// Called on the new thread, cannot allocate memory.
func minit() {
// Initialize signal handling.
_g_ := getg()
diff --git a/src/runtime/os1_nacl.go b/src/runtime/os1_nacl.go
index dab205de6a..5526d906d8 100644
--- a/src/runtime/os1_nacl.go
+++ b/src/runtime/os1_nacl.go
@@ -30,7 +30,7 @@ func sigblock() {
}
// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
+// Called on the new thread, cannot allocate memory.
func minit() {
_g_ := getg()
diff --git a/src/runtime/os1_netbsd.go b/src/runtime/os1_netbsd.go
index eab8eb8702..e32df9585c 100644
--- a/src/runtime/os1_netbsd.go
+++ b/src/runtime/os1_netbsd.go
@@ -167,7 +167,7 @@ func sigblock() {
}
// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
+// Called on the new thread, cannot allocate memory.
func minit() {
_g_ := getg()
_g_.m.procid = uint64(lwp_self())
diff --git a/src/runtime/os1_plan9.go b/src/runtime/os1_plan9.go
index 7506d591df..9911077911 100644
--- a/src/runtime/os1_plan9.go
+++ b/src/runtime/os1_plan9.go
@@ -33,7 +33,7 @@ func sigblock() {
}
// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
+// Called on the new thread, cannot allocate memory.
func minit() {
// Mask all SSE floating-point exceptions
// when running on the 64-bit kernel.
diff --git a/src/runtime/os1_windows.go b/src/runtime/os1_windows.go
index a28e11e088..8d46bca36d 100644
--- a/src/runtime/os1_windows.go
+++ b/src/runtime/os1_windows.go
@@ -399,7 +399,7 @@ func sigblock() {
}
// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
+// Called on the new thread, cannot allocate memory.
func minit() {
var thandle uintptr
stdcall7(_DuplicateHandle, currentProcess, currentThread, currentProcess, uintptr(unsafe.Pointer(&thandle)), 0, 0, _DUPLICATE_SAME_ACCESS)
diff --git a/src/runtime/os3_solaris.go b/src/runtime/os3_solaris.go
index 7ebb35c8e9..fdc817d3f7 100644
--- a/src/runtime/os3_solaris.go
+++ b/src/runtime/os3_solaris.go
@@ -208,7 +208,7 @@ func sigblock() {
}
// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
+// Called on the new thread, cannot allocate memory.
func minit() {
_g_ := getg()
asmcgocall(unsafe.Pointer(funcPC(miniterrno)), unsafe.Pointer(&libc____errno))
diff --git a/src/runtime/sys_darwin_arm.s b/src/runtime/sys_darwin_arm.s
index 82a8db9914..6b6437dddd 100644
--- a/src/runtime/sys_darwin_arm.s
+++ b/src/runtime/sys_darwin_arm.s
@@ -261,7 +261,7 @@ cont:
MOVW R1, 24(R6)
// switch stack and g
- MOVW R6, R13 // sigtramp can not re-entrant, so no need to back up R13.
+ MOVW R6, R13 // sigtramp is not re-entrant, so no need to back up R13.
MOVW R5, g
BL (R0)
diff --git a/src/runtime/sys_darwin_arm64.s b/src/runtime/sys_darwin_arm64.s
index d0034d5a33..a3b851d2fc 100644
--- a/src/runtime/sys_darwin_arm64.s
+++ b/src/runtime/sys_darwin_arm64.s
@@ -245,7 +245,7 @@ cont:
MOVD R1, 48(R6)
// switch stack and g
- MOVD R6, RSP // sigtramp can not re-entrant, so no need to back up RSP.
+ MOVD R6, RSP // sigtramp is not re-entrant, so no need to back up RSP.
MOVD R5, g
BL (R0)
diff --git a/src/runtime/vdso_linux_amd64.go b/src/runtime/vdso_linux_amd64.go
index 38914bb2b9..42571e063c 100644
--- a/src/runtime/vdso_linux_amd64.go
+++ b/src/runtime/vdso_linux_amd64.go
@@ -263,7 +263,7 @@ func vdso_find_version(info *vdso_info, ver *version_key) int32 {
def = (*elf64Verdef)(add(unsafe.Pointer(def), uintptr(def.vd_next)))
}
- return -1 // can not match any version
+ return -1 // cannot match any version
}
func vdso_parse_symbols(info *vdso_info, version int32) {
diff --git a/src/sync/pool.go b/src/sync/pool.go
index 381af0bead..4fb1a1af9d 100644
--- a/src/sync/pool.go
+++ b/src/sync/pool.go
@@ -149,7 +149,7 @@ func (p *Pool) getSlow() (x interface{}) {
func (p *Pool) pin() *poolLocal {
pid := runtime_procPin()
// In pinSlow we store to localSize and then to local, here we load in opposite order.
- // Since we've disabled preemption, GC can not happen in between.
+ // Since we've disabled preemption, GC cannot happen in between.
// Thus here we must observe local at least as large localSize.
// We can observe a newer/larger local, it is fine (we must observe its zero-initialized-ness).
s := atomic.LoadUintptr(&p.localSize) // load-acquire
From 9ad41f6243e7947ce1569140382f8847cc2a80dd Mon Sep 17 00:00:00 2001
From: Suharsh Sivakumar
Date: Wed, 3 Feb 2016 13:22:40 -0800
Subject: [PATCH 083/117] net: ensure lookupStatic* returns copy of slice to
disallow cache corruption.
Fixes #14212
Change-Id: I74325dfaa1fb48f4b281c2d42157b563f1e42a94
Reviewed-on: https://go-review.googlesource.com/19201
Reviewed-by: Mikio Hara
---
src/net/hosts.go | 8 ++++--
src/net/hosts_test.go | 62 +++++++++++++++++++++++++++++++++----------
2 files changed, 54 insertions(+), 16 deletions(-)
diff --git a/src/net/hosts.go b/src/net/hosts.go
index c4de1b6a97..9c101c6ef5 100644
--- a/src/net/hosts.go
+++ b/src/net/hosts.go
@@ -110,7 +110,9 @@ func lookupStaticHost(host string) []string {
lowerHost := []byte(host)
lowerASCIIBytes(lowerHost)
if ips, ok := hosts.byName[absDomainName(lowerHost)]; ok {
- return ips
+ ipsCp := make([]string, len(ips))
+ copy(ipsCp, ips)
+ return ipsCp
}
}
return nil
@@ -127,7 +129,9 @@ func lookupStaticAddr(addr string) []string {
}
if len(hosts.byAddr) != 0 {
if hosts, ok := hosts.byAddr[addr]; ok {
- return hosts
+ hostsCp := make([]string, len(hosts))
+ copy(hostsCp, hosts)
+ return hostsCp
}
}
return nil
diff --git a/src/net/hosts_test.go b/src/net/hosts_test.go
index 4c67bfa982..5d6c9cfe19 100644
--- a/src/net/hosts_test.go
+++ b/src/net/hosts_test.go
@@ -64,13 +64,17 @@ func TestLookupStaticHost(t *testing.T) {
for _, tt := range lookupStaticHostTests {
testHookHostsPath = tt.name
for _, ent := range tt.ents {
- ins := []string{ent.in, absDomainName([]byte(ent.in)), strings.ToLower(ent.in), strings.ToUpper(ent.in)}
- for _, in := range ins {
- addrs := lookupStaticHost(in)
- if !reflect.DeepEqual(addrs, ent.out) {
- t.Errorf("%s, lookupStaticHost(%s) = %v; want %v", tt.name, in, addrs, ent.out)
- }
- }
+ testStaticHost(t, tt.name, ent)
+ }
+ }
+}
+
+func testStaticHost(t *testing.T, hostsPath string, ent staticHostEntry) {
+ ins := []string{ent.in, absDomainName([]byte(ent.in)), strings.ToLower(ent.in), strings.ToUpper(ent.in)}
+ for _, in := range ins {
+ addrs := lookupStaticHost(in)
+ if !reflect.DeepEqual(addrs, ent.out) {
+ t.Errorf("%s, lookupStaticHost(%s) = %v; want %v", hostsPath, in, addrs, ent.out)
}
}
}
@@ -129,13 +133,43 @@ func TestLookupStaticAddr(t *testing.T) {
for _, tt := range lookupStaticAddrTests {
testHookHostsPath = tt.name
for _, ent := range tt.ents {
- hosts := lookupStaticAddr(ent.in)
- for i := range ent.out {
- ent.out[i] = absDomainName([]byte(ent.out[i]))
- }
- if !reflect.DeepEqual(hosts, ent.out) {
- t.Errorf("%s, lookupStaticAddr(%s) = %v; want %v", tt.name, ent.in, hosts, ent.out)
- }
+ testStaticAddr(t, tt.name, ent)
}
}
}
+
+func testStaticAddr(t *testing.T, hostsPath string, ent staticHostEntry) {
+ hosts := lookupStaticAddr(ent.in)
+ for i := range ent.out {
+ ent.out[i] = absDomainName([]byte(ent.out[i]))
+ }
+ if !reflect.DeepEqual(hosts, ent.out) {
+ t.Errorf("%s, lookupStaticAddr(%s) = %v; want %v", hostsPath, ent.in, hosts, ent.out)
+ }
+}
+
+func TestHostCacheModification(t *testing.T) {
+ // Ensure that programs can't modify the internals of the host cache.
+ // See https://github.com/golang/go/issues/14212.
+ defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+
+ testHookHostsPath = "testdata/ipv4-hosts"
+ ent := staticHostEntry{"localhost", []string{"127.0.0.1", "127.0.0.2", "127.0.0.3"}}
+ testStaticHost(t, testHookHostsPath, ent)
+ // Modify the addresses return by lookupStaticHost.
+ addrs := lookupStaticHost(ent.in)
+ for i := range addrs {
+ addrs[i] += "junk"
+ }
+ testStaticHost(t, testHookHostsPath, ent)
+
+ testHookHostsPath = "testdata/ipv6-hosts"
+ ent = staticHostEntry{"::1", []string{"localhost"}}
+ testStaticAddr(t, testHookHostsPath, ent)
+ // Modify the hosts return by lookupStaticAddr.
+ hosts := lookupStaticAddr(ent.in)
+ for i := range hosts {
+ hosts[i] += "junk"
+ }
+ testStaticAddr(t, testHookHostsPath, ent)
+}
From 4cef0e980a5d4fca2b7d26ec26eb1de954cecc21 Mon Sep 17 00:00:00 2001
From: Josh Bleecher Snyder
Date: Mon, 4 May 2015 15:02:09 -0700
Subject: [PATCH 084/117] cmd/compile: don't generate algs for [0]T and [1]T
All [0]T values are equal.
[1]T values are equal iff their sole components are.
This types show up most frequently as a by-product of variadic
function calls, such as fmt.Printf("abc") or fmt.Printf("%v", x).
Cuts 12k off cmd/go and 22k off golang.org/x/tools/cmd/godoc, approx 0.1% each.
For #6853 and #9930
Change-Id: Ic9b7aeb8cc945804246340f6f5e67bbf6008773e
Reviewed-on: https://go-review.googlesource.com/19766
Reviewed-by: David Crawshaw
Run-TryBot: David Crawshaw
TryBot-Result: Gobot Gobot
---
src/cmd/compile/internal/gc/subr.go | 9 +++++++++
src/cmd/compile/internal/gc/walk.go | 15 +++++++++++++++
2 files changed, 24 insertions(+)
diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go
index 0d25ddf2af..a17d7df60d 100644
--- a/src/cmd/compile/internal/gc/subr.go
+++ b/src/cmd/compile/internal/gc/subr.go
@@ -465,6 +465,15 @@ func algtype1(t *Type, bad **Type) int {
return a
}
+ switch t.Bound {
+ case 0:
+ // We checked above that the element type is comparable.
+ return AMEM
+ case 1:
+ // Single-element array is same as its lone element.
+ return a
+ }
+
return -1 // needs special compare
case TSTRUCT:
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index e008317562..f324d5e00f 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -3193,6 +3193,21 @@ func walkcompare(np **Node, init **NodeList) {
return
}
+ if t.Etype == TARRAY {
+ // Zero- or single-element array, of any type.
+ switch t.Bound {
+ case 0:
+ finishcompare(np, n, Nodbool(n.Op == OEQ), init)
+ return
+ case 1:
+ l0 := Nod(OINDEX, l, Nodintconst(0))
+ r0 := Nod(OINDEX, r, Nodintconst(0))
+ a := Nod(n.Op, l0, r0)
+ finishcompare(np, n, a, init)
+ return
+ }
+ }
+
if t.Etype == TSTRUCT && countfield(t) <= 4 {
// Struct of four or fewer fields.
// Inline comparisons.
From bc8458ab02878ae64af860f1cade78b6fa97e994 Mon Sep 17 00:00:00 2001
From: Josh Bleecher Snyder
Date: Mon, 4 May 2015 16:12:52 -0700
Subject: [PATCH 085/117] cmd/compile: use && in generated eq algs
This allows the compiler to generate better code
containing fewer jumps and only a single return value.
Cuts 12k off cmd/go and 16k off golang.org/x/tools/cmd/godoc, approx 0.1% each.
For #6853 and #9930
Change-Id: I009616df797760b01e09f06357a2d6fd6ebcf307
Reviewed-on: https://go-review.googlesource.com/19767
Reviewed-by: David Crawshaw
Run-TryBot: David Crawshaw
TryBot-Result: Gobot Gobot
---
src/cmd/compile/internal/gc/subr.go | 67 ++++++++++++++++-------------
1 file changed, 38 insertions(+), 29 deletions(-)
diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go
index a17d7df60d..a04c538e26 100644
--- a/src/cmd/compile/internal/gc/subr.go
+++ b/src/cmd/compile/internal/gc/subr.go
@@ -2649,17 +2649,13 @@ func genhash(sym *Sym, t *Type) {
safemode = old_safemode
}
-// Return node for
-// if p.field != q.field { return false }
+// eqfield returns the node
+// p.field == q.field
func eqfield(p *Node, q *Node, field *Node) *Node {
nx := Nod(OXDOT, p, field)
ny := Nod(OXDOT, q, field)
- nif := Nod(OIF, nil, nil)
- nif.Left = Nod(ONE, nx, ny)
- r := Nod(ORETURN, nil, nil)
- r.List = list(r.List, Nodbool(false))
- nif.Nbody = list(nif.Nbody, r)
- return nif
+ ne := Nod(OEQ, nx, ny)
+ return ne
}
func eqmemfunc(size int64, type_ *Type, needsize *int) *Node {
@@ -2680,8 +2676,8 @@ func eqmemfunc(size int64, type_ *Type, needsize *int) *Node {
return fn
}
-// Return node for
-// if !memequal(&p.field, &q.field [, size]) { return false }
+// eqmem returns the node
+// memequal(&p.field, &q.field [, size])
func eqmem(p *Node, q *Node, field *Node, size int64) *Node {
var needsize int
@@ -2699,15 +2695,11 @@ func eqmem(p *Node, q *Node, field *Node, size int64) *Node {
call.List = list(call.List, Nodintconst(size))
}
- nif := Nod(OIF, nil, nil)
- nif.Left = Nod(ONOT, call, nil)
- r := Nod(ORETURN, nil, nil)
- r.List = list(r.List, Nodbool(false))
- nif.Nbody = list(nif.Nbody, r)
- return nif
+ return call
}
-// Generate a helper function to check equality of two values of type t.
+// geneq generates a helper function to
+// check equality of two values of type t.
func geneq(sym *Sym, t *Type) {
if Debug['r'] != 0 {
fmt.Printf("geneq %v %v\n", sym, t)
@@ -2777,12 +2769,18 @@ func geneq(sym *Sym, t *Type) {
nrange.Nbody = list(nrange.Nbody, nif)
fn.Nbody = list(fn.Nbody, nrange)
- // Walk the struct using memequal for runs of AMEM
+ // return true
+ ret := Nod(ORETURN, nil, nil)
+ ret.List = list(ret.List, Nodbool(true))
+ fn.Nbody = list(fn.Nbody, ret)
+
+ // Walk the struct using memequal for runs of AMEM
// and calling specific equality tests for the others.
// Skip blank-named fields.
case TSTRUCT:
var first *Type
+ var conjuncts []*Node
offend := int64(0)
var size int64
for t1 := t.Type; ; t1 = t1.Down {
@@ -2805,17 +2803,17 @@ func geneq(sym *Sym, t *Type) {
// cross-package unexported fields.
if first != nil {
if first.Down == t1 {
- fn.Nbody = list(fn.Nbody, eqfield(np, nq, newname(first.Sym)))
+ conjuncts = append(conjuncts, eqfield(np, nq, newname(first.Sym)))
} else if first.Down.Down == t1 {
- fn.Nbody = list(fn.Nbody, eqfield(np, nq, newname(first.Sym)))
+ conjuncts = append(conjuncts, eqfield(np, nq, newname(first.Sym)))
first = first.Down
if !isblanksym(first.Sym) {
- fn.Nbody = list(fn.Nbody, eqfield(np, nq, newname(first.Sym)))
+ conjuncts = append(conjuncts, eqfield(np, nq, newname(first.Sym)))
}
} else {
// More than two fields: use memequal.
size = offend - first.Width // first->width is offset
- fn.Nbody = list(fn.Nbody, eqmem(np, nq, newname(first.Sym), size))
+ conjuncts = append(conjuncts, eqmem(np, nq, newname(first.Sym), size))
}
first = nil
@@ -2829,16 +2827,27 @@ func geneq(sym *Sym, t *Type) {
}
// Check this field, which is not just memory.
- fn.Nbody = list(fn.Nbody, eqfield(np, nq, newname(t1.Sym)))
+ conjuncts = append(conjuncts, eqfield(np, nq, newname(t1.Sym)))
}
+
+ var and *Node
+ switch len(conjuncts) {
+ case 0:
+ and = Nodbool(true)
+ case 1:
+ and = conjuncts[0]
+ default:
+ and = Nod(OANDAND, conjuncts[0], conjuncts[1])
+ for _, conjunct := range conjuncts[2:] {
+ and = Nod(OANDAND, and, conjunct)
+ }
+ }
+
+ ret := Nod(ORETURN, nil, nil)
+ ret.List = list(ret.List, and)
+ fn.Nbody = list(fn.Nbody, ret)
}
- // return true
- r := Nod(ORETURN, nil, nil)
-
- r.List = list(r.List, Nodbool(true))
- fn.Nbody = list(fn.Nbody, r)
-
if Debug['r'] != 0 {
dumplist("geneq body", fn.Nbody)
}
From e960302410fafaf595c1ad92c28c61da3a254d63 Mon Sep 17 00:00:00 2001
From: Shenghou Ma
Date: Sun, 21 Feb 2016 13:56:08 -0500
Subject: [PATCH 086/117] runtime: when crash with panic, call user
Error/String methods before freezing the world
Fixes #14432.
Change-Id: I0a92ef86de95de39217df9a664d8034ef685a906
Reviewed-on: https://go-review.googlesource.com/19792
Reviewed-by: Ian Lance Taylor
Run-TryBot: Minux Ma
TryBot-Result: Gobot Gobot
---
src/runtime/crash_cgo_test.go | 9 ++++++
src/runtime/crash_test.go | 16 +++++++++++
src/runtime/panic.go | 19 +++++++++++++
src/runtime/testdata/testprog/deadlock.go | 25 ++++++++++++++++
src/runtime/testdata/testprogcgo/deadlock.go | 30 ++++++++++++++++++++
5 files changed, 99 insertions(+)
create mode 100644 src/runtime/testdata/testprogcgo/deadlock.go
diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
index 7685582aa8..63769e801c 100644
--- a/src/runtime/crash_cgo_test.go
+++ b/src/runtime/crash_cgo_test.go
@@ -178,3 +178,12 @@ func TestCgoCheckBytes(t *testing.T) {
t.Errorf("cgo check too slow: got %v, expected at most %v", d1, d2*10)
}
}
+
+func TestCgoPanicDeadlock(t *testing.T) {
+ // test issue 14432
+ got := runTestProg(t, "testprogcgo", "CgoPanicDeadlock")
+ want := "panic: cgo error\n\n"
+ if !strings.HasPrefix(got, want) {
+ t.Fatalf("output does not start with %q:\n%s", want, got)
+ }
+}
diff --git a/src/runtime/crash_test.go b/src/runtime/crash_test.go
index 5f0e77b0dc..de45e832f8 100644
--- a/src/runtime/crash_test.go
+++ b/src/runtime/crash_test.go
@@ -336,3 +336,19 @@ func TestPanicTraceback(t *testing.T) {
output = output[idx[1]:]
}
}
+
+func testPanicDeadlock(t *testing.T, name string, want string) {
+ // test issue 14432
+ output := runTestProg(t, "testprog", name)
+ if !strings.HasPrefix(output, want) {
+ t.Fatalf("output does not start with %q:\n%s", want, output)
+ }
+}
+
+func TestPanicDeadlockGosched(t *testing.T) {
+ testPanicDeadlock(t, "GoschedInPanic", "panic: errorThatGosched\n\n")
+}
+
+func TestPanicDeadlockSyscall(t *testing.T) {
+ testPanicDeadlock(t, "SyscallInPanic", "1\n2\npanic: 3\n\n")
+}
diff --git a/src/runtime/panic.go b/src/runtime/panic.go
index ba07330e35..349e997395 100644
--- a/src/runtime/panic.go
+++ b/src/runtime/panic.go
@@ -333,6 +333,21 @@ func Goexit() {
goexit1()
}
+// Call all Error and String methods before freezing the world.
+// Used when crashing with panicking.
+// This must match types handled by printany.
+func preprintpanics(p *_panic) {
+ for p != nil {
+ switch v := p.arg.(type) {
+ case error:
+ p.arg = v.Error()
+ case stringer:
+ p.arg = v.String()
+ }
+ p = p.link
+ }
+}
+
// Print all currently active panics. Used when crashing.
func printpanics(p *_panic) {
if p.link != nil {
@@ -459,6 +474,10 @@ func gopanic(e interface{}) {
}
// ran out of deferred calls - old-school panic now
+ // Because it is unsafe to call arbitrary user code after freezing
+ // the world, we call preprintpanics to invoke all necessary Error
+ // and String methods to prepare the panic strings before startpanic.
+ preprintpanics(gp._panic)
startpanic()
printpanics(gp._panic)
dopanic(0) // should not return
diff --git a/src/runtime/testdata/testprog/deadlock.go b/src/runtime/testdata/testprog/deadlock.go
index 73fbf6224d..ff9c82d61b 100644
--- a/src/runtime/testdata/testprog/deadlock.go
+++ b/src/runtime/testdata/testprog/deadlock.go
@@ -30,6 +30,8 @@ func init() {
register("PanicAfterGoexit", PanicAfterGoexit)
register("RecoveredPanicAfterGoexit", RecoveredPanicAfterGoexit)
register("PanicTraceback", PanicTraceback)
+ register("GoschedInPanic", GoschedInPanic)
+ register("SyscallInPanic", SyscallInPanic)
}
func SimpleDeadlock() {
@@ -152,6 +154,29 @@ func GoexitInPanic() {
runtime.Goexit()
}
+type errorThatGosched struct{}
+
+func (errorThatGosched) Error() string {
+ runtime.Gosched()
+ return "errorThatGosched"
+}
+
+func GoschedInPanic() {
+ panic(errorThatGosched{})
+}
+
+type errorThatPrint struct{}
+
+func (errorThatPrint) Error() string {
+ fmt.Println("1")
+ fmt.Println("2")
+ return "3"
+}
+
+func SyscallInPanic() {
+ panic(errorThatPrint{})
+}
+
func PanicAfterGoexit() {
defer func() {
panic("hello")
diff --git a/src/runtime/testdata/testprogcgo/deadlock.go b/src/runtime/testdata/testprogcgo/deadlock.go
new file mode 100644
index 0000000000..ac8855af3b
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/deadlock.go
@@ -0,0 +1,30 @@
+// 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
+
+/*
+char *geterror() {
+ return "cgo error";
+}
+*/
+import "C"
+import (
+ "fmt"
+)
+
+func init() {
+ register("CgoPanicDeadlock", CgoPanicDeadlock)
+}
+
+type cgoError struct{}
+
+func (cgoError) Error() string {
+ fmt.Print("") // necessary to trigger the deadlock
+ return C.GoString(C.geterror())
+}
+
+func CgoPanicDeadlock() {
+ panic(cgoError{})
+}
From 8ffe496ae792a1cdc845c1c019323cf6c05fbb32 Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Sat, 20 Feb 2016 22:52:15 -0800
Subject: [PATCH 087/117] cmd/compile, runtime: eliminate unnecessary algorithm
types
There's no need for 8 different ways to represent that a type is
non-comparable.
While here, move AMEM out of the runtime-known algorithm values since
it's not needed at run-time, and get rid of the unused AUNK constant.
Change-Id: Ie23972b692c6f27fc5f1a908561b3e26ef5a50e9
Reviewed-on: https://go-review.googlesource.com/19779
Run-TryBot: Matthew Dempsky
TryBot-Result: Gobot Gobot
Reviewed-by: David Crawshaw
---
src/cmd/compile/internal/gc/go.go | 13 ++-----------
src/cmd/compile/internal/gc/subr.go | 22 +++++++---------------
src/runtime/alg.go | 20 ++------------------
3 files changed, 11 insertions(+), 44 deletions(-)
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
index d21b2fb196..3923bc6e31 100644
--- a/src/cmd/compile/internal/gc/go.go
+++ b/src/cmd/compile/internal/gc/go.go
@@ -28,30 +28,21 @@ const (
const (
// These values are known by runtime.
- // The MEMx and NOEQx values must run in parallel. See algtype.
- AMEM = iota
+ ANOEQ = iota
AMEM0
AMEM8
AMEM16
AMEM32
AMEM64
AMEM128
- ANOEQ
- ANOEQ0
- ANOEQ8
- ANOEQ16
- ANOEQ32
- ANOEQ64
- ANOEQ128
ASTRING
AINTER
ANILINTER
- ASLICE
AFLOAT32
AFLOAT64
ACPLX64
ACPLX128
- AUNK = 100
+ AMEM = 100
)
const (
diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go
index a04c538e26..ba0a257b3b 100644
--- a/src/cmd/compile/internal/gc/subr.go
+++ b/src/cmd/compile/internal/gc/subr.go
@@ -509,28 +509,20 @@ func algtype1(t *Type, bad **Type) int {
func algtype(t *Type) int {
a := algtype1(t, nil)
- if a == AMEM || a == ANOEQ {
- if Isslice(t) {
- return ASLICE
- }
+ if a == AMEM {
switch t.Width {
case 0:
- return a + AMEM0 - AMEM
-
+ return AMEM0
case 1:
- return a + AMEM8 - AMEM
-
+ return AMEM8
case 2:
- return a + AMEM16 - AMEM
-
+ return AMEM16
case 4:
- return a + AMEM32 - AMEM
-
+ return AMEM32
case 8:
- return a + AMEM64 - AMEM
-
+ return AMEM64
case 16:
- return a + AMEM128 - AMEM
+ return AMEM128
}
}
diff --git a/src/runtime/alg.go b/src/runtime/alg.go
index 9ea0eb0187..541649c62d 100644
--- a/src/runtime/alg.go
+++ b/src/runtime/alg.go
@@ -16,24 +16,16 @@ const (
// type algorithms - known to compiler
const (
- alg_MEM = iota
+ alg_NOEQ = iota
alg_MEM0
alg_MEM8
alg_MEM16
alg_MEM32
alg_MEM64
alg_MEM128
- alg_NOEQ
- alg_NOEQ0
- alg_NOEQ8
- alg_NOEQ16
- alg_NOEQ32
- alg_NOEQ64
- alg_NOEQ128
alg_STRING
alg_INTER
alg_NILINTER
- alg_SLICE
alg_FLOAT32
alg_FLOAT64
alg_CPLX64
@@ -77,24 +69,16 @@ func memhash128(p unsafe.Pointer, h uintptr) uintptr {
func memhash_varlen(p unsafe.Pointer, h uintptr) uintptr
var algarray = [alg_max]typeAlg{
- alg_MEM: {nil, nil}, // not used
+ alg_NOEQ: {nil, nil},
alg_MEM0: {memhash0, memequal0},
alg_MEM8: {memhash8, memequal8},
alg_MEM16: {memhash16, memequal16},
alg_MEM32: {memhash32, memequal32},
alg_MEM64: {memhash64, memequal64},
alg_MEM128: {memhash128, memequal128},
- alg_NOEQ: {nil, nil},
- alg_NOEQ0: {nil, nil},
- alg_NOEQ8: {nil, nil},
- alg_NOEQ16: {nil, nil},
- alg_NOEQ32: {nil, nil},
- alg_NOEQ64: {nil, nil},
- alg_NOEQ128: {nil, nil},
alg_STRING: {strhash, strequal},
alg_INTER: {interhash, interequal},
alg_NILINTER: {nilinterhash, nilinterequal},
- alg_SLICE: {nil, nil},
alg_FLOAT32: {f32hash, f32equal},
alg_FLOAT64: {f64hash, f64equal},
alg_CPLX64: {c64hash, c64equal},
From 8caf19c46f9d7cc9011d7acdc464768b5fb15d7e Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Sat, 20 Feb 2016 20:33:34 -0800
Subject: [PATCH 088/117] net: fix TestUpdateResolvConf after CL 18860
When writing a fake dnsConfig to conf.dnsConfig, set lastChecked to an
hour into the future. This causes dnsclient_unix.go's
tryUpdate("/etc/resolv.conf") calls to short-circuit and ignore that
/etc/resolv.conf's mtime differs from the test's fake resolv.conf
file. We only need to zero out lastChecked in teardown.
While here, this makes two other tryUpdate(conf.path) test calls
pointless, since they'll now short circuit too.
Fixes #14437.
Change-Id: Ieb520388e319b9826dfa49f134907f4927608a53
Reviewed-on: https://go-review.googlesource.com/19777
Run-TryBot: Matthew Dempsky
TryBot-Result: Gobot Gobot
Reviewed-by: Mikio Hara
---
src/net/dnsclient_unix_test.go | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go
index 934f25b2c9..d7f00c784d 100644
--- a/src/net/dnsclient_unix_test.go
+++ b/src/net/dnsclient_unix_test.go
@@ -124,20 +124,20 @@ func (conf *resolvConfTest) writeAndUpdate(lines []string) error {
return err
}
f.Close()
- if err := conf.forceUpdate(conf.path); err != nil {
+ if err := conf.forceUpdate(conf.path, time.Now().Add(time.Hour)); err != nil {
return err
}
return nil
}
-func (conf *resolvConfTest) forceUpdate(name string) error {
+func (conf *resolvConfTest) forceUpdate(name string, lastChecked time.Time) error {
dnsConf := dnsReadConfig(name)
conf.mu.Lock()
conf.dnsConfig = dnsConf
conf.mu.Unlock()
for i := 0; i < 5; i++ {
if conf.tryAcquireSema() {
- conf.lastChecked = time.Time{}
+ conf.lastChecked = lastChecked
conf.releaseSema()
return nil
}
@@ -153,7 +153,7 @@ func (conf *resolvConfTest) servers() []string {
}
func (conf *resolvConfTest) teardown() error {
- err := conf.forceUpdate("/etc/resolv.conf")
+ err := conf.forceUpdate("/etc/resolv.conf", time.Time{})
os.RemoveAll(conf.dir)
return err
}
@@ -353,7 +353,6 @@ func TestGoLookupIPWithResolverConfig(t *testing.T) {
t.Error(err)
continue
}
- conf.tryUpdate(conf.path)
addrs, err := goLookupIP(tt.name)
if err != nil {
if err, ok := err.(*DNSError); !ok || (err.Name != tt.error.(*DNSError).Name || err.Server != tt.error.(*DNSError).Server || err.IsTimeout != tt.error.(*DNSError).IsTimeout) {
@@ -392,7 +391,6 @@ func TestGoLookupIPOrderFallbackToFile(t *testing.T) {
if err := conf.writeAndUpdate([]string{}); err != nil {
t.Fatal(err)
}
- conf.tryUpdate(conf.path)
// Redirect host file lookups.
defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
testHookHostsPath = "testdata/hosts"
From a4b143bc22ff471a96c42458833998151df70cc0 Mon Sep 17 00:00:00 2001
From: Shenghou Ma
Date: Sat, 19 Sep 2015 06:59:06 -0400
Subject: [PATCH 089/117] go/types: skip $GOROOT/src/*.go in TestStdlib
Change-Id: I4a75d98a48675e2beb5b4843fb2c6ff5d4c8d2a2
Reviewed-on: https://go-review.googlesource.com/14769
Reviewed-by: Robert Griesemer
---
src/go/types/stdlib_test.go | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/src/go/types/stdlib_test.go b/src/go/types/stdlib_test.go
index 09f2585bcf..97e6a69521 100644
--- a/src/go/types/stdlib_test.go
+++ b/src/go/types/stdlib_test.go
@@ -266,13 +266,16 @@ func walkDirs(t *testing.T, dir string) {
}
// typecheck package in directory
- files, err := pkgFilenames(dir)
- if err != nil {
- t.Error(err)
- return
- }
- if files != nil {
- typecheck(t, dir, files)
+ // but ignore files directly under $GOROOT/src (might be temporary test files).
+ if dir != filepath.Join(runtime.GOROOT(), "src") {
+ files, err := pkgFilenames(dir)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ if files != nil {
+ typecheck(t, dir, files)
+ }
}
// traverse subdirectories, but don't walk into testdata
From d70c04cf08683e2b0a26fb13808f8cacb1bcdd38 Mon Sep 17 00:00:00 2001
From: Shenghou Ma
Date: Sat, 20 Feb 2016 23:24:27 -0500
Subject: [PATCH 090/117] runtime: fix missing word in comment
Change-Id: I6cb8ac7b59812e82111ab3b0f8303ab8194a5129
Reviewed-on: https://go-review.googlesource.com/19791
Reviewed-by: Ian Lance Taylor
Run-TryBot: Ian Lance Taylor
TryBot-Result: Gobot Gobot
---
src/runtime/proc.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index d1f5088b50..389917916f 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -2406,7 +2406,7 @@ func entersyscallblock_handoff() {
// The goroutine g exited its system call.
// Arrange for it to run on a cpu again.
// This is called only from the go syscall library, not
-// from the low-level system calls used by the
+// from the low-level system calls used by the runtime.
//go:nosplit
func exitsyscall(dummy int32) {
_g_ := getg()
From 89cfdda44dec9f1e4e7f9ac360638fecee2482c6 Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Sat, 20 Feb 2016 18:49:22 -0800
Subject: [PATCH 091/117] cmd/compile: replace Order's use of NodeLists with
slices
Order's "temp" and "free" fields use NodeLists in a rather
non-idiomatic way. Instead of using the "list" or "concat" functions,
it manipulates them directly and without the normal invariants (e.g.,
it doesn't maintain the "End" field).
Rather than convert it to more typical usage, just replace with a
slice, which ends up much simpler anyway.
Passes toolstash/buildall.
Change-Id: Ibd0f24324bd674c0d5bb1bc40d073b01e7824ad5
Reviewed-on: https://go-review.googlesource.com/19776
Run-TryBot: Matthew Dempsky
TryBot-Result: Gobot Gobot
Reviewed-by: Ian Lance Taylor
---
src/cmd/compile/internal/gc/order.go | 55 +++++++++-------------------
1 file changed, 17 insertions(+), 38 deletions(-)
diff --git a/src/cmd/compile/internal/gc/order.go b/src/cmd/compile/internal/gc/order.go
index a2e12284d0..ddd6cb9719 100644
--- a/src/cmd/compile/internal/gc/order.go
+++ b/src/cmd/compile/internal/gc/order.go
@@ -42,8 +42,7 @@ import (
// Order holds state during the ordering process.
type Order struct {
out *NodeList // list of generated statements
- temp *NodeList // head of stack of temporary variables
- free *NodeList // free list of NodeList* structs (for use in temp)
+ temp []*Node // stack of temporary variables
}
// Order rewrites fn->nbody to apply the ordering constraints
@@ -68,14 +67,7 @@ func ordertemp(t *Type, order *Order, clear bool) *Node {
order.out = list(order.out, a)
}
- l := order.free
- if l == nil {
- l = new(NodeList)
- }
- order.free = l.Next
- l.Next = order.temp
- l.N = var_
- order.temp = l
+ order.temp = append(order.temp, var_)
return var_
}
@@ -215,41 +207,34 @@ func orderaddrtemp(np **Node, order *Order) {
*np = ordercopyexpr(n, n.Type, order, 0)
}
+type ordermarker int
+
// Marktemp returns the top of the temporary variable stack.
-func marktemp(order *Order) *NodeList {
- return order.temp
+func marktemp(order *Order) ordermarker {
+ return ordermarker(len(order.temp))
}
// Poptemp pops temporaries off the stack until reaching the mark,
// which must have been returned by marktemp.
-func poptemp(mark *NodeList, order *Order) {
- var l *NodeList
-
- for {
- l = order.temp
- if l == mark {
- break
- }
- order.temp = l.Next
- l.Next = order.free
- order.free = l
- }
+func poptemp(mark ordermarker, order *Order) {
+ order.temp = order.temp[:mark]
}
// Cleantempnopop emits to *out VARKILL instructions for each temporary
// above the mark on the temporary stack, but it does not pop them
// from the stack.
-func cleantempnopop(mark *NodeList, order *Order, out **NodeList) {
+func cleantempnopop(mark ordermarker, order *Order, out **NodeList) {
var kill *Node
- for l := order.temp; l != mark; l = l.Next {
- if l.N.Name.Keepalive {
- l.N.Name.Keepalive = false
- kill = Nod(OVARLIVE, l.N, nil)
+ for i := len(order.temp) - 1; i >= int(mark); i-- {
+ n := order.temp[i]
+ if n.Name.Keepalive {
+ n.Name.Keepalive = false
+ kill = Nod(OVARLIVE, n, nil)
typecheck(&kill, Etop)
*out = list(*out, kill)
}
- kill = Nod(OVARKILL, l.N, nil)
+ kill = Nod(OVARKILL, n, nil)
typecheck(&kill, Etop)
*out = list(*out, kill)
}
@@ -257,7 +242,7 @@ func cleantempnopop(mark *NodeList, order *Order, out **NodeList) {
// Cleantemp emits VARKILL instructions for each temporary above the
// mark on the temporary stack and removes them from the stack.
-func cleantemp(top *NodeList, order *Order) {
+func cleantemp(top ordermarker, order *Order) {
cleantempnopop(top, order, &order.out)
poptemp(top, order)
}
@@ -289,13 +274,7 @@ func orderexprinplace(np **Node, outer *Order) {
// insert new temporaries from order
// at head of outer list.
- lp := &order.temp
-
- for *lp != nil {
- lp = &(*lp).Next
- }
- *lp = outer.temp
- outer.temp = order.temp
+ outer.temp = append(outer.temp, order.temp...)
*np = n
}
From 8847a5913a5970b5f5c062f767c369da683648d6 Mon Sep 17 00:00:00 2001
From: Austin Clements
Date: Thu, 18 Feb 2016 17:28:04 -0500
Subject: [PATCH 092/117] runtime: remove unused parfor code
Change-Id: Ibbfae20cab48163f22d661604ef730705f2b97ba
Reviewed-on: https://go-review.googlesource.com/19661
Run-TryBot: Austin Clements
TryBot-Result: Gobot Gobot
Reviewed-by: Brad Fitzpatrick
---
src/runtime/export_test.go | 36 ------
src/runtime/parfor.go | 217 -------------------------------------
src/runtime/parfor_test.go | 128 ----------------------
3 files changed, 381 deletions(-)
delete mode 100644 src/runtime/parfor.go
delete mode 100644 src/runtime/parfor_test.go
diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go
index 5400c1d14e..245cc88aae 100644
--- a/src/runtime/export_test.go
+++ b/src/runtime/export_test.go
@@ -45,42 +45,6 @@ func LFStackPop(head *uint64) *LFNode {
return (*LFNode)(unsafe.Pointer(lfstackpop(head)))
}
-type ParFor struct {
- body func(*ParFor, uint32)
- done uint32
- Nthr uint32
- thrseq uint32
- Cnt uint32
- wait bool
-}
-
-func NewParFor(nthrmax uint32) *ParFor {
- var desc *ParFor
- systemstack(func() {
- desc = (*ParFor)(unsafe.Pointer(parforalloc(nthrmax)))
- })
- return desc
-}
-
-func ParForSetup(desc *ParFor, nthr, n uint32, wait bool, body func(*ParFor, uint32)) {
- systemstack(func() {
- parforsetup((*parfor)(unsafe.Pointer(desc)), nthr, n, wait,
- *(*func(*parfor, uint32))(unsafe.Pointer(&body)))
- })
-}
-
-func ParForDo(desc *ParFor) {
- systemstack(func() {
- parfordo((*parfor)(unsafe.Pointer(desc)))
- })
-}
-
-func ParForIters(desc *ParFor, tid uint32) (uint32, uint32) {
- desc1 := (*parfor)(unsafe.Pointer(desc))
- pos := desc1.thr[tid].pos
- return uint32(pos), uint32(pos >> 32)
-}
-
func GCMask(x interface{}) (ret []byte) {
systemstack(func() {
ret = getgcmask(x)
diff --git a/src/runtime/parfor.go b/src/runtime/parfor.go
deleted file mode 100644
index 9e11cb3e12..0000000000
--- a/src/runtime/parfor.go
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 2012 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.
-
-// Parallel for algorithm.
-
-package runtime
-
-import (
- "runtime/internal/atomic"
- "runtime/internal/sys"
-)
-
-// A parfor holds state for the parallel for operation.
-type parfor struct {
- body func(*parfor, uint32) // executed for each element
- done uint32 // number of idle threads
- nthr uint32 // total number of threads
- thrseq uint32 // thread id sequencer
- cnt uint32 // iteration space [0, cnt)
- wait bool // if true, wait while all threads finish processing,
- // otherwise parfor may return while other threads are still working
-
- thr []parforthread // thread descriptors
-
- // stats
- nsteal uint64
- nstealcnt uint64
- nprocyield uint64
- nosyield uint64
- nsleep uint64
-}
-
-// A parforthread holds state for a single thread in the parallel for.
-type parforthread struct {
- // the thread's iteration space [32lsb, 32msb)
- pos uint64
- // stats
- nsteal uint64
- nstealcnt uint64
- nprocyield uint64
- nosyield uint64
- nsleep uint64
- pad [sys.CacheLineSize]byte
-}
-
-func parforalloc(nthrmax uint32) *parfor {
- return &parfor{
- thr: make([]parforthread, nthrmax),
- }
-}
-
-// Parforsetup initializes desc for a parallel for operation with nthr
-// threads executing n jobs.
-//
-// On return the nthr threads are each expected to call parfordo(desc)
-// to run the operation. During those calls, for each i in [0, n), one
-// thread will be used invoke body(desc, i).
-// If wait is true, no parfordo will return until all work has been completed.
-// If wait is false, parfordo may return when there is a small amount
-// of work left, under the assumption that another thread has that
-// work well in hand.
-func parforsetup(desc *parfor, nthr, n uint32, wait bool, body func(*parfor, uint32)) {
- if desc == nil || nthr == 0 || nthr > uint32(len(desc.thr)) || body == nil {
- print("desc=", desc, " nthr=", nthr, " count=", n, " body=", body, "\n")
- throw("parfor: invalid args")
- }
-
- desc.body = body
- desc.done = 0
- desc.nthr = nthr
- desc.thrseq = 0
- desc.cnt = n
- desc.wait = wait
- desc.nsteal = 0
- desc.nstealcnt = 0
- desc.nprocyield = 0
- desc.nosyield = 0
- desc.nsleep = 0
-
- for i := range desc.thr {
- begin := uint32(uint64(n) * uint64(i) / uint64(nthr))
- end := uint32(uint64(n) * uint64(i+1) / uint64(nthr))
- desc.thr[i].pos = uint64(begin) | uint64(end)<<32
- }
-}
-
-func parfordo(desc *parfor) {
- // Obtain 0-based thread index.
- tid := atomic.Xadd(&desc.thrseq, 1) - 1
- if tid >= desc.nthr {
- print("tid=", tid, " nthr=", desc.nthr, "\n")
- throw("parfor: invalid tid")
- }
-
- // If single-threaded, just execute the for serially.
- body := desc.body
- if desc.nthr == 1 {
- for i := uint32(0); i < desc.cnt; i++ {
- body(desc, i)
- }
- return
- }
-
- me := &desc.thr[tid]
- mypos := &me.pos
- for {
- for {
- // While there is local work,
- // bump low index and execute the iteration.
- pos := atomic.Xadd64(mypos, 1)
- begin := uint32(pos) - 1
- end := uint32(pos >> 32)
- if begin < end {
- body(desc, begin)
- continue
- }
- break
- }
-
- // Out of work, need to steal something.
- idle := false
- for try := uint32(0); ; try++ {
- // If we don't see any work for long enough,
- // increment the done counter...
- if try > desc.nthr*4 && !idle {
- idle = true
- atomic.Xadd(&desc.done, 1)
- }
-
- // ...if all threads have incremented the counter,
- // we are done.
- extra := uint32(0)
- if !idle {
- extra = 1
- }
- if desc.done+extra == desc.nthr {
- if !idle {
- atomic.Xadd(&desc.done, 1)
- }
- goto exit
- }
-
- // Choose a random victim for stealing.
- var begin, end uint32
- victim := fastrand1() % (desc.nthr - 1)
- if victim >= tid {
- victim++
- }
- victimpos := &desc.thr[victim].pos
- for {
- // See if it has any work.
- pos := atomic.Load64(victimpos)
- begin = uint32(pos)
- end = uint32(pos >> 32)
- if begin+1 >= end {
- end = 0
- begin = end
- break
- }
- if idle {
- atomic.Xadd(&desc.done, -1)
- idle = false
- }
- begin2 := begin + (end-begin)/2
- newpos := uint64(begin) | uint64(begin2)<<32
- if atomic.Cas64(victimpos, pos, newpos) {
- begin = begin2
- break
- }
- }
- if begin < end {
- // Has successfully stolen some work.
- if idle {
- throw("parfor: should not be idle")
- }
- atomic.Store64(mypos, uint64(begin)|uint64(end)<<32)
- me.nsteal++
- me.nstealcnt += uint64(end) - uint64(begin)
- break
- }
-
- // Backoff.
- if try < desc.nthr {
- // nothing
- } else if try < 4*desc.nthr {
- me.nprocyield++
- procyield(20)
- } else if !desc.wait {
- // If a caller asked not to wait for the others, exit now
- // (assume that most work is already done at this point).
- if !idle {
- atomic.Xadd(&desc.done, 1)
- }
- goto exit
- } else if try < 6*desc.nthr {
- me.nosyield++
- osyield()
- } else {
- me.nsleep++
- usleep(1)
- }
- }
- }
-
-exit:
- atomic.Xadd64(&desc.nsteal, int64(me.nsteal))
- atomic.Xadd64(&desc.nstealcnt, int64(me.nstealcnt))
- atomic.Xadd64(&desc.nprocyield, int64(me.nprocyield))
- atomic.Xadd64(&desc.nosyield, int64(me.nosyield))
- atomic.Xadd64(&desc.nsleep, int64(me.nsleep))
- me.nsteal = 0
- me.nstealcnt = 0
- me.nprocyield = 0
- me.nosyield = 0
- me.nsleep = 0
-}
diff --git a/src/runtime/parfor_test.go b/src/runtime/parfor_test.go
deleted file mode 100644
index 5d22aecc9b..0000000000
--- a/src/runtime/parfor_test.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2012 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.
-
-// The race detector does not understand ParFor synchronization.
-// +build !race
-
-package runtime_test
-
-import (
- . "runtime"
- "testing"
-)
-
-// Simple serial sanity test for parallelfor.
-func TestParFor(t *testing.T) {
- const P = 1
- const N = 20
- data := make([]uint64, N)
- for i := uint64(0); i < N; i++ {
- data[i] = i
- }
- desc := NewParFor(P)
- ParForSetup(desc, P, N, true, func(desc *ParFor, i uint32) {
- data[i] = data[i]*data[i] + 1
- })
- ParForDo(desc)
- for i := uint64(0); i < N; i++ {
- if data[i] != i*i+1 {
- t.Fatalf("Wrong element %d: %d", i, data[i])
- }
- }
-}
-
-// Test that nonblocking parallelfor does not block.
-func TestParFor2(t *testing.T) {
- const P = 7
- const N = 1003
- data := make([]uint64, N)
- for i := uint64(0); i < N; i++ {
- data[i] = i
- }
- desc := NewParFor(P)
- ParForSetup(desc, P, N, false, func(desc *ParFor, i uint32) {
- data[i] = data[i]*data[i] + 1
- })
- for p := 0; p < P; p++ {
- ParForDo(desc)
- }
- for i := uint64(0); i < N; i++ {
- if data[i] != i*i+1 {
- t.Fatalf("Wrong element %d: %d", i, data[i])
- }
- }
-}
-
-// Test that iterations are properly distributed.
-func TestParForSetup(t *testing.T) {
- const P = 11
- const N = 101
- desc := NewParFor(P)
- for n := uint32(0); n < N; n++ {
- for p := uint32(1); p <= P; p++ {
- ParForSetup(desc, p, n, true, func(desc *ParFor, i uint32) {})
- sum := uint32(0)
- size0 := uint32(0)
- end0 := uint32(0)
- for i := uint32(0); i < p; i++ {
- begin, end := ParForIters(desc, i)
- size := end - begin
- sum += size
- if i == 0 {
- size0 = size
- if begin != 0 {
- t.Fatalf("incorrect begin: %d (n=%d, p=%d)", begin, n, p)
- }
- } else {
- if size != size0 && size != size0+1 {
- t.Fatalf("incorrect size: %d/%d (n=%d, p=%d)", size, size0, n, p)
- }
- if begin != end0 {
- t.Fatalf("incorrect begin/end: %d/%d (n=%d, p=%d)", begin, end0, n, p)
- }
- }
- end0 = end
- }
- if sum != n {
- t.Fatalf("incorrect sum: %d/%d (p=%d)", sum, n, p)
- }
- }
- }
-}
-
-// Test parallel parallelfor.
-func TestParForParallel(t *testing.T) {
- N := uint64(1e7)
- if testing.Short() {
- N /= 10
- }
- data := make([]uint64, N)
- for i := uint64(0); i < N; i++ {
- data[i] = i
- }
- P := GOMAXPROCS(-1)
- c := make(chan bool, P)
- desc := NewParFor(uint32(P))
- ParForSetup(desc, uint32(P), uint32(N), false, func(desc *ParFor, i uint32) {
- data[i] = data[i]*data[i] + 1
- })
- for p := 1; p < P; p++ {
- go func() {
- ParForDo(desc)
- c <- true
- }()
- }
- ParForDo(desc)
- for p := 1; p < P; p++ {
- <-c
- }
- for i := uint64(0); i < N; i++ {
- if data[i] != i*i+1 {
- t.Fatalf("Wrong element %d: %d", i, data[i])
- }
- }
-
- data, desc = nil, nil
- GC()
-}
From 5609a48931593a0ba88cab4a54ea5c426b292c3e Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Sat, 20 Feb 2016 21:36:12 -0800
Subject: [PATCH 093/117] cmd/compile: make cmpstackvarlt properly asymmetric
Previously, given two Nodes n1 and n2 of different non-PAUTO classes
(e.g., PPARAM and PPARAMOUT), cmpstackvarlt(n1, n2) and
cmpstackvarlt(n2, n1) both returned true, which is nonsense.
This doesn't seem to cause any visible miscompilation problems, but
notably fixing it does cause toolstash/buildall to fail.
Change-Id: I33b2c66e902c5eced875d8fbf18b7cfdc81e8aed
Reviewed-on: https://go-review.googlesource.com/19778
Run-TryBot: Matthew Dempsky
Reviewed-by: Ian Lance Taylor
TryBot-Result: Gobot Gobot
---
src/cmd/compile/internal/gc/pgen.go | 22 +++++-----------------
src/cmd/compile/internal/gc/pgen_test.go | 14 ++++++++++++++
2 files changed, 19 insertions(+), 17 deletions(-)
diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go
index ffc0ab9cfb..3471b977ed 100644
--- a/src/cmd/compile/internal/gc/pgen.go
+++ b/src/cmd/compile/internal/gc/pgen.go
@@ -186,21 +186,12 @@ func emitptrargsmap() {
// the top of the stack and increasing in size.
// Non-autos sort on offset.
func cmpstackvarlt(a, b *Node) bool {
- if a.Class != b.Class {
- if a.Class == PAUTO {
- return false
- }
- return true
+ if (a.Class == PAUTO) != (b.Class == PAUTO) {
+ return b.Class == PAUTO
}
if a.Class != PAUTO {
- if a.Xoffset < b.Xoffset {
- return true
- }
- if a.Xoffset > b.Xoffset {
- return false
- }
- return false
+ return a.Xoffset < b.Xoffset
}
if a.Used != b.Used {
@@ -219,11 +210,8 @@ func cmpstackvarlt(a, b *Node) bool {
return ap
}
- if a.Type.Width < b.Type.Width {
- return false
- }
- if a.Type.Width > b.Type.Width {
- return true
+ if a.Type.Width != b.Type.Width {
+ return a.Type.Width > b.Type.Width
}
return a.Sym.Name < b.Sym.Name
diff --git a/src/cmd/compile/internal/gc/pgen_test.go b/src/cmd/compile/internal/gc/pgen_test.go
index ebc9101135..909b8a9507 100644
--- a/src/cmd/compile/internal/gc/pgen_test.go
+++ b/src/cmd/compile/internal/gc/pgen_test.go
@@ -40,6 +40,16 @@ func TestCmpstackvar(t *testing.T) {
Node{Class: PFUNC, Xoffset: 10},
false,
},
+ {
+ Node{Class: PPARAM, Xoffset: 10},
+ Node{Class: PPARAMOUT, Xoffset: 20},
+ true,
+ },
+ {
+ Node{Class: PPARAMOUT, Xoffset: 10},
+ Node{Class: PPARAM, Xoffset: 20},
+ true,
+ },
{
Node{Class: PAUTO, Used: true},
Node{Class: PAUTO, Used: false},
@@ -101,6 +111,10 @@ func TestCmpstackvar(t *testing.T) {
if got != d.lt {
t.Errorf("want %#v < %#v", d.a, d.b)
}
+ // If we expect a < b to be true, check that b < a is false.
+ if d.lt && cmpstackvarlt(&d.b, &d.a) {
+ t.Errorf("unexpected %#v < %#v", d.b, d.a)
+ }
}
}
From d0c11577b9c6d584959aceddf97266b9cbc336d0 Mon Sep 17 00:00:00 2001
From: Keith Randall
Date: Sun, 21 Feb 2016 20:43:14 -0800
Subject: [PATCH 094/117] cmd/compile: inline {i,e}facethash
These functions are really simple, the overhead of calling
them (in both time and code size) is larger than the inlined versions.
Reorganize how the nil case in a type switch is handled, as we have
to check for nil explicitly now anyway.
Saves about 0.8% in the binary size of the go tool.
Change-Id: I8501b62d72fde43650b79f52b5f699f1fbd0e7e7
Reviewed-on: https://go-review.googlesource.com/19814
Run-TryBot: Keith Randall
TryBot-Result: Gobot Gobot
Reviewed-by: Josh Bleecher Snyder
---
src/cmd/compile/internal/gc/builtin.go | 2 -
.../compile/internal/gc/builtin/runtime.go | 2 -
src/cmd/compile/internal/gc/swt.go | 76 +++++++++++++------
src/runtime/iface.go | 16 ----
4 files changed, 53 insertions(+), 43 deletions(-)
diff --git a/src/cmd/compile/internal/gc/builtin.go b/src/cmd/compile/internal/gc/builtin.go
index 7583e8fa13..4a6e56fe47 100644
--- a/src/cmd/compile/internal/gc/builtin.go
+++ b/src/cmd/compile/internal/gc/builtin.go
@@ -66,8 +66,6 @@ const runtimeimport = "" +
"func @\"\".panicdottype (@\"\".have·1 *byte, @\"\".want·2 *byte, @\"\".iface·3 *byte)\n" +
"func @\"\".ifaceeq (@\"\".i1·2 any, @\"\".i2·3 any) (@\"\".ret·1 bool)\n" +
"func @\"\".efaceeq (@\"\".i1·2 any, @\"\".i2·3 any) (@\"\".ret·1 bool)\n" +
- "func @\"\".ifacethash (@\"\".i1·2 any) (@\"\".ret·1 uint32)\n" +
- "func @\"\".efacethash (@\"\".i1·2 any) (@\"\".ret·1 uint32)\n" +
"func @\"\".makemap (@\"\".mapType·2 *byte, @\"\".hint·3 int64, @\"\".mapbuf·4 *any, @\"\".bucketbuf·5 *any) (@\"\".hmap·1 map[any]any)\n" +
"func @\"\".mapaccess1 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 *any) (@\"\".val·1 *any)\n" +
"func @\"\".mapaccess1_fast32 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 any) (@\"\".val·1 *any)\n" +
diff --git a/src/cmd/compile/internal/gc/builtin/runtime.go b/src/cmd/compile/internal/gc/builtin/runtime.go
index 08f925f41c..0fe6242e74 100644
--- a/src/cmd/compile/internal/gc/builtin/runtime.go
+++ b/src/cmd/compile/internal/gc/builtin/runtime.go
@@ -83,8 +83,6 @@ func panicdottype(have, want, iface *byte)
func ifaceeq(i1 any, i2 any) (ret bool)
func efaceeq(i1 any, i2 any) (ret bool)
-func ifacethash(i1 any) (ret uint32)
-func efacethash(i1 any) (ret uint32)
// *byte is really *runtime.Type
func makemap(mapType *byte, hint int64, mapbuf *any, bucketbuf *any) (hmap map[any]any)
diff --git a/src/cmd/compile/internal/gc/swt.go b/src/cmd/compile/internal/gc/swt.go
index f0433f3df7..661b3ee5a9 100644
--- a/src/cmd/compile/internal/gc/swt.go
+++ b/src/cmd/compile/internal/gc/swt.go
@@ -549,20 +549,6 @@ func (s *typeSwitch) walk(sw *Node) {
// set up labels and jumps
casebody(sw, s.facename)
- // calculate type hash
- t := cond.Right.Type
- if isnilinter(t) {
- a = syslook("efacethash", 1)
- } else {
- a = syslook("ifacethash", 1)
- }
- substArgTypes(a, t)
- a = Nod(OCALL, a, nil)
- a.List = list1(s.facename)
- a = Nod(OAS, s.hashname, a)
- typecheck(&a, Etop)
- cas = list(cas, a)
-
cc := caseClauses(sw, switchKindType)
sw.List = nil
var def *Node
@@ -572,22 +558,66 @@ func (s *typeSwitch) walk(sw *Node) {
} else {
def = Nod(OBREAK, nil, nil)
}
+ var typenil *Node
+ if len(cc) > 0 && cc[0].typ == caseKindTypeNil {
+ typenil = cc[0].node.Right
+ cc = cc[1:]
+ }
+
+ // For empty interfaces, do:
+ // if e._type == nil {
+ // do nil case if it exists, otherwise default
+ // }
+ // h := e._type.hash
+ // Use a similar strategy for non-empty interfaces.
+
+ // Get interface descriptor word.
+ typ := Nod(OITAB, s.facename, nil)
+
+ // Check for nil first.
+ i := Nod(OIF, nil, nil)
+ i.Left = Nod(OEQ, typ, nodnil())
+ if typenil != nil {
+ // Do explicit nil case right here.
+ i.Nbody = list1(typenil)
+ } else {
+ // Jump to default case.
+ lbl := newCaseLabel()
+ i.Nbody = list1(Nod(OGOTO, lbl, nil))
+ // Wrap default case with label.
+ blk := Nod(OBLOCK, nil, nil)
+ blk.List = list(list1(Nod(OLABEL, lbl, nil)), def)
+ def = blk
+ }
+ typecheck(&i.Left, Erv)
+ cas = list(cas, i)
+
+ if !isnilinter(cond.Right.Type) {
+ // Load type from itab.
+ typ = Nod(ODOTPTR, typ, nil)
+ typ.Type = Ptrto(Types[TUINT8])
+ typ.Typecheck = 1
+ typ.Xoffset = int64(Widthptr) // offset of _type in runtime.itab
+ typ.Bounded = true // guaranteed not to fault
+ }
+ // Load hash from type.
+ h := Nod(ODOTPTR, typ, nil)
+ h.Type = Types[TUINT32]
+ h.Typecheck = 1
+ h.Xoffset = int64(2 * Widthptr) // offset of hash in runtime._type
+ h.Bounded = true // guaranteed not to fault
+ a = Nod(OAS, s.hashname, h)
+ typecheck(&a, Etop)
+ cas = list(cas, a)
// insert type equality check into each case block
for _, c := range cc {
n := c.node
switch c.typ {
- case caseKindTypeNil:
- var v Val
- v.U = new(NilVal)
- a = Nod(OIF, nil, nil)
- a.Left = Nod(OEQ, s.facename, nodlit(v))
- typecheck(&a.Left, Erv)
- a.Nbody = list1(n.Right) // if i==nil { goto l }
- n.Right = a
-
case caseKindTypeVar, caseKindTypeConst:
n.Right = s.typeone(n)
+ default:
+ Fatalf("typeSwitch with bad kind: %d", c.typ)
}
}
diff --git a/src/runtime/iface.go b/src/runtime/iface.go
index 71dc865e07..50dff77e42 100644
--- a/src/runtime/iface.go
+++ b/src/runtime/iface.go
@@ -398,22 +398,6 @@ func assertE2E2(inter *interfacetype, e eface, r *eface) bool {
return true
}
-func ifacethash(i iface) uint32 {
- tab := i.tab
- if tab == nil {
- return 0
- }
- return tab._type.hash
-}
-
-func efacethash(e eface) uint32 {
- t := e._type
- if t == nil {
- return 0
- }
- return t.hash
-}
-
func iterate_itabs(fn func(*itab)) {
for _, h := range &hash {
for ; h != nil; h = h.link {
From f28bbb776a050cc3edca2bbe1241d81217a7a251 Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Mon, 2 Nov 2015 10:46:58 -0800
Subject: [PATCH 095/117] cmd/compile: move hiter, hmap, and scase definitions
into builtin.go
Also eliminates per-maptype hiter and hmap types, since they're not
really needed anyway. Update packages reflect and runtime
accordingly.
Reduces golang.org/x/tools/cmd/godoc's text segment by ~170kB:
text data bss dec hex filename
13085702 140640 151520 13377862 cc2146 godoc.before
12915382 140640 151520 13207542 c987f6 godoc.after
Updates #6853.
Change-Id: I948b2bc1f22d477c1756204996b4e3e1fb568d81
Reviewed-on: https://go-review.googlesource.com/16610
Reviewed-by: Keith Randall
---
src/cmd/compile/internal/gc/builtin.go | 10 +-
.../compile/internal/gc/builtin/runtime.go | 49 +++++++++-
src/cmd/compile/internal/gc/fmt.go | 8 --
src/cmd/compile/internal/gc/go.go | 4 +-
src/cmd/compile/internal/gc/range.go | 22 +++--
src/cmd/compile/internal/gc/reflect.go | 94 +------------------
src/cmd/compile/internal/gc/select.go | 30 +-----
src/cmd/compile/internal/gc/subr.go | 13 ++-
src/cmd/compile/internal/gc/walk.go | 4 +-
src/reflect/type.go | 1 -
src/runtime/hashmap.go | 15 ++-
src/runtime/runtime2.go | 2 -
src/runtime/select.go | 4 +-
src/runtime/type.go | 1 -
14 files changed, 94 insertions(+), 163 deletions(-)
diff --git a/src/cmd/compile/internal/gc/builtin.go b/src/cmd/compile/internal/gc/builtin.go
index 4a6e56fe47..d1827ef0fe 100644
--- a/src/cmd/compile/internal/gc/builtin.go
+++ b/src/cmd/compile/internal/gc/builtin.go
@@ -4,6 +4,10 @@ package gc
const runtimeimport = "" +
"package runtime safe\n" +
+ "type @\"\".hbucket uint8\n" +
+ "type @\"\".hmap struct { @\"\".count int; @\"\".flags uint8; B uint8; @\"\".hash0 uint32; @\"\".buckets *@\"\".hbucket; @\"\".oldbuckets *@\"\".hbucket; @\"\".nevacuate uintptr; @\"\".overflow *[2]*[]*@\"\".hbucket }\n" +
+ "type @\"\".hiter struct { @\"\".key *byte; @\"\".value *byte; @\"\".t *byte; @\"\".h *@\"\".hmap; @\"\".buckets *@\"\".hbucket; @\"\".bptr *@\"\".hbucket; @\"\".overflow [2]*[]*@\"\".hbucket; @\"\".startBucket uintptr; @\"\".offset uint8; @\"\".wrapped bool; B uint8; @\"\".i uint8; @\"\".bucket uintptr; @\"\".checkBucket uintptr }\n" +
+ "type @\"\".scase struct { @\"\".elem *byte; @\"\".c *byte; @\"\".pc uintptr; @\"\".kind uint16; @\"\".so uint16; @\"\".receivedp *bool; @\"\".releasetime int64 }\n" +
"func @\"\".newobject (@\"\".typ·2 *byte) (? *any)\n" +
"func @\"\".panicindex ()\n" +
"func @\"\".panicslice ()\n" +
@@ -66,7 +70,7 @@ const runtimeimport = "" +
"func @\"\".panicdottype (@\"\".have·1 *byte, @\"\".want·2 *byte, @\"\".iface·3 *byte)\n" +
"func @\"\".ifaceeq (@\"\".i1·2 any, @\"\".i2·3 any) (@\"\".ret·1 bool)\n" +
"func @\"\".efaceeq (@\"\".i1·2 any, @\"\".i2·3 any) (@\"\".ret·1 bool)\n" +
- "func @\"\".makemap (@\"\".mapType·2 *byte, @\"\".hint·3 int64, @\"\".mapbuf·4 *any, @\"\".bucketbuf·5 *any) (@\"\".hmap·1 map[any]any)\n" +
+ "func @\"\".makemap (@\"\".mapType·2 *byte, @\"\".hint·3 int64, @\"\".mapbuf·4 *@\"\".hmap, @\"\".bucketbuf·5 *any) (@\"\".hmap·1 map[any]any)\n" +
"func @\"\".mapaccess1 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 *any) (@\"\".val·1 *any)\n" +
"func @\"\".mapaccess1_fast32 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 any) (@\"\".val·1 *any)\n" +
"func @\"\".mapaccess1_fast64 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 any) (@\"\".val·1 *any)\n" +
@@ -76,9 +80,9 @@ const runtimeimport = "" +
"func @\"\".mapaccess2_fast64 (@\"\".mapType·3 *byte, @\"\".hmap·4 map[any]any, @\"\".key·5 any) (@\"\".val·1 *any, @\"\".pres·2 bool)\n" +
"func @\"\".mapaccess2_faststr (@\"\".mapType·3 *byte, @\"\".hmap·4 map[any]any, @\"\".key·5 any) (@\"\".val·1 *any, @\"\".pres·2 bool)\n" +
"func @\"\".mapassign1 (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".key·3 *any, @\"\".val·4 *any)\n" +
- "func @\"\".mapiterinit (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".hiter·3 *any)\n" +
+ "func @\"\".mapiterinit (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".hiter·3 *@\"\".hiter)\n" +
"func @\"\".mapdelete (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".key·3 *any)\n" +
- "func @\"\".mapiternext (@\"\".hiter·1 *any)\n" +
+ "func @\"\".mapiternext (@\"\".hiter·1 *@\"\".hiter)\n" +
"func @\"\".makechan (@\"\".chanType·2 *byte, @\"\".hint·3 int64) (@\"\".hchan·1 chan any)\n" +
"func @\"\".chanrecv1 (@\"\".chanType·1 *byte, @\"\".hchan·2 <-chan any, @\"\".elem·3 *any)\n" +
"func @\"\".chanrecv2 (@\"\".chanType·2 *byte, @\"\".hchan·3 <-chan any, @\"\".elem·4 *any) (? bool)\n" +
diff --git a/src/cmd/compile/internal/gc/builtin/runtime.go b/src/cmd/compile/internal/gc/builtin/runtime.go
index 0fe6242e74..e067d0bfa8 100644
--- a/src/cmd/compile/internal/gc/builtin/runtime.go
+++ b/src/cmd/compile/internal/gc/builtin/runtime.go
@@ -12,6 +12,49 @@ package runtime
// emitted by compiler, not referred to by go programs
+type hbucket byte // placeholder
+
+// Changes here must also be made in src/runtime/hashmap.go.
+type hmap struct {
+ count int
+ flags uint8
+ B uint8
+ hash0 uint32
+ buckets *hbucket
+ oldbuckets *hbucket
+ nevacuate uintptr
+ overflow *[2]*[]*hbucket
+}
+
+// Changes here must also be made in src/runtime/hashmap.go.
+type hiter struct {
+ key *byte // field name known to walkrange
+ value *byte // field name known to walkrange
+ t *byte // *maptype
+ h *hmap
+ buckets *hbucket
+ bptr *hbucket
+ overflow [2]*[]*hbucket
+ startBucket uintptr
+ offset uint8
+ wrapped bool
+ B uint8
+ i uint8
+ bucket uintptr
+ checkBucket uintptr
+}
+
+// Changes here must also be made in src/runtime/select.go.
+type scase struct {
+ elem *byte
+ c *byte
+ pc uintptr
+ kind uint16
+ so uint16
+ receivedp *bool
+ releasetime int64
+}
+
func newobject(typ *byte) *any
func panicindex()
func panicslice()
@@ -85,7 +128,7 @@ func ifaceeq(i1 any, i2 any) (ret bool)
func efaceeq(i1 any, i2 any) (ret bool)
// *byte is really *runtime.Type
-func makemap(mapType *byte, hint int64, mapbuf *any, bucketbuf *any) (hmap map[any]any)
+func makemap(mapType *byte, hint int64, mapbuf *hmap, bucketbuf *any) (hmap map[any]any)
func mapaccess1(mapType *byte, hmap map[any]any, key *any) (val *any)
func mapaccess1_fast32(mapType *byte, hmap map[any]any, key any) (val *any)
func mapaccess1_fast64(mapType *byte, hmap map[any]any, key any) (val *any)
@@ -95,9 +138,9 @@ func mapaccess2_fast32(mapType *byte, hmap map[any]any, key any) (val *any, pres
func mapaccess2_fast64(mapType *byte, hmap map[any]any, key any) (val *any, pres bool)
func mapaccess2_faststr(mapType *byte, hmap map[any]any, key any) (val *any, pres bool)
func mapassign1(mapType *byte, hmap map[any]any, key *any, val *any)
-func mapiterinit(mapType *byte, hmap map[any]any, hiter *any)
+func mapiterinit(mapType *byte, hmap map[any]any, hiter *hiter)
func mapdelete(mapType *byte, hmap map[any]any, key *any)
-func mapiternext(hiter *any)
+func mapiternext(hiter *hiter)
// *byte is really *runtime.Type
func makechan(chanType *byte, hint int64) (hchan chan any)
diff --git a/src/cmd/compile/internal/gc/fmt.go b/src/cmd/compile/internal/gc/fmt.go
index c0a1170839..91035b5d07 100644
--- a/src/cmd/compile/internal/gc/fmt.go
+++ b/src/cmd/compile/internal/gc/fmt.go
@@ -647,14 +647,6 @@ func typefmt(t *Type, flag int) string {
return fmt.Sprintf("map.bucket[%v]%v", t.Map.Down, t.Map.Type)
}
- if t.Map.Hmap == t {
- return fmt.Sprintf("map.hdr[%v]%v", t.Map.Down, t.Map.Type)
- }
-
- if t.Map.Hiter == t {
- return fmt.Sprintf("map.iter[%v]%v", t.Map.Down, t.Map.Type)
- }
-
Yyerror("unknown internal map type")
}
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
index 3923bc6e31..3c00f72ec1 100644
--- a/src/cmd/compile/internal/gc/go.go
+++ b/src/cmd/compile/internal/gc/go.go
@@ -191,9 +191,7 @@ type Type struct {
// TMAP
Bucket *Type // internal type representing a hash bucket
- Hmap *Type // internal type representing a Hmap (map header object)
- Hiter *Type // internal type representing hash iterator state
- Map *Type // link from the above 3 internal types back to the map type.
+ Map *Type // link from hash bucket type back to the map type.
Maplineno int32 // first use of TFORW as map key
Embedlineno int32 // first use of TFORW as embedded type
diff --git a/src/cmd/compile/internal/gc/range.go b/src/cmd/compile/internal/gc/range.go
index 4386bcfeed..8c2eca20d4 100644
--- a/src/cmd/compile/internal/gc/range.go
+++ b/src/cmd/compile/internal/gc/range.go
@@ -223,24 +223,28 @@ func walkrange(n *Node) {
case TMAP:
ha := a
- th := hiter(t)
+ th := syslook("hiter", 0).Type
+ keytype := t.Down
+ valtype := t.Type
+
hit := prealloc[n]
hit.Type = th
n.Left = nil
- keyname := newname(th.Type.Sym) // depends on layout of iterator struct. See reflect.go:hiter
- valname := newname(th.Type.Down.Sym) // ditto
+
+ // These depend on hiter's field names. See builtin/runtime.go:hiter.
+ keyname := newname(Pkglookup("key", Runtimepkg))
+ valname := newname(Pkglookup("value", Runtimepkg))
fn := syslook("mapiterinit", 1)
-
- substArgTypes(fn, t.Down, t.Type, th)
+ substArgTypes(fn, keytype, valtype)
init = list(init, mkcall1(fn, nil, nil, typename(t), ha, Nod(OADDR, hit, nil)))
n.Left = Nod(ONE, Nod(ODOT, hit, keyname), nodnil())
- fn = syslook("mapiternext", 1)
- substArgTypes(fn, th)
- n.Right = mkcall1(fn, nil, nil, Nod(OADDR, hit, nil))
+ n.Right = mkcall("mapiternext", nil, nil, Nod(OADDR, hit, nil))
key := Nod(ODOT, hit, keyname)
+ key = Nod(OCONVNOP, key, nil)
+ key.Type = Ptrto(keytype)
key = Nod(OIND, key, nil)
if v1 == nil {
body = nil
@@ -248,6 +252,8 @@ func walkrange(n *Node) {
body = list1(Nod(OAS, v1, key))
} else {
val := Nod(ODOT, hit, valname)
+ val = Nod(OCONVNOP, val, nil)
+ val.Type = Ptrto(valtype)
val = Nod(OIND, val, nil)
a := Nod(OAS2, nil, nil)
a.List = list(list1(v1), v2)
diff --git a/src/cmd/compile/internal/gc/reflect.go b/src/cmd/compile/internal/gc/reflect.go
index 8693e3c112..369d015f19 100644
--- a/src/cmd/compile/internal/gc/reflect.go
+++ b/src/cmd/compile/internal/gc/reflect.go
@@ -149,92 +149,6 @@ func mapbucket(t *Type) *Type {
return bucket
}
-// Builds a type representing a Hmap structure for the given map type.
-// Make sure this stays in sync with ../../../../runtime/hashmap.go!
-func hmap(t *Type) *Type {
- if t.Hmap != nil {
- return t.Hmap
- }
-
- bucket := mapbucket(t)
- var field [8]*Type
- field[0] = makefield("count", Types[TINT])
- field[1] = makefield("flags", Types[TUINT8])
- field[2] = makefield("B", Types[TUINT8])
- field[3] = makefield("hash0", Types[TUINT32])
- field[4] = makefield("buckets", Ptrto(bucket))
- field[5] = makefield("oldbuckets", Ptrto(bucket))
- field[6] = makefield("nevacuate", Types[TUINTPTR])
- field[7] = makefield("overflow", Types[TUNSAFEPTR])
-
- h := typ(TSTRUCT)
- h.Noalg = true
- h.Local = t.Local
- h.Type = field[0]
- for n := int32(0); n < int32(len(field)-1); n++ {
- field[n].Down = field[n+1]
- }
- field[len(field)-1].Down = nil
- dowidth(h)
- t.Hmap = h
- h.Map = t
- return h
-}
-
-func hiter(t *Type) *Type {
- if t.Hiter != nil {
- return t.Hiter
- }
-
- // build a struct:
- // hiter {
- // key *Key
- // val *Value
- // t *MapType
- // h *Hmap
- // buckets *Bucket
- // bptr *Bucket
- // overflow0 unsafe.Pointer
- // overflow1 unsafe.Pointer
- // startBucket uintptr
- // stuff uintptr
- // bucket uintptr
- // checkBucket uintptr
- // }
- // must match ../../../../runtime/hashmap.go:hiter.
- var field [12]*Type
- field[0] = makefield("key", Ptrto(t.Down))
-
- field[1] = makefield("val", Ptrto(t.Type))
- field[2] = makefield("t", Ptrto(Types[TUINT8]))
- field[3] = makefield("h", Ptrto(hmap(t)))
- field[4] = makefield("buckets", Ptrto(mapbucket(t)))
- field[5] = makefield("bptr", Ptrto(mapbucket(t)))
- field[6] = makefield("overflow0", Types[TUNSAFEPTR])
- field[7] = makefield("overflow1", Types[TUNSAFEPTR])
- field[8] = makefield("startBucket", Types[TUINTPTR])
- field[9] = makefield("stuff", Types[TUINTPTR]) // offset+wrapped+B+I
- field[10] = makefield("bucket", Types[TUINTPTR])
- field[11] = makefield("checkBucket", Types[TUINTPTR])
-
- // build iterator struct holding the above fields
- i := typ(TSTRUCT)
-
- i.Noalg = true
- i.Type = field[0]
- for n := int32(0); n < int32(len(field)-1); n++ {
- field[n].Down = field[n+1]
- }
- field[len(field)-1].Down = nil
- dowidth(i)
- if i.Width != int64(12*Widthptr) {
- Yyerror("hash_iter size not correct %d %d", i.Width, 12*Widthptr)
- }
- t.Hiter = i
- i.Map = t
- return i
-}
-
// f is method type, with receiver.
// return function type, receiver as first argument (or not).
func methodfunc(f *Type, receiver *Type) *Type {
@@ -1112,13 +1026,11 @@ ok:
s2 := dtypesym(t.Type)
s3 := dtypesym(mapbucket(t))
- s4 := dtypesym(hmap(t))
ot = dcommontype(s, ot, t)
xt = ot - 2*Widthptr
ot = dsymptr(s, ot, s1, 0)
ot = dsymptr(s, ot, s2, 0)
ot = dsymptr(s, ot, s3, 0)
- ot = dsymptr(s, ot, s4, 0)
if t.Down.Width > MAXKEYSIZE {
ot = duint8(s, ot, uint8(Widthptr))
ot = duint8(s, ot, 1) // indirect
@@ -1339,8 +1251,10 @@ func dalgsym(t *Type) *Sym {
hashfunc = typesymprefix(".hashfunc", t)
eqfunc = typesymprefix(".eqfunc", t)
- genhash(hash, t)
- geneq(eq, t)
+ if Debug['A'] == 0 {
+ genhash(hash, t)
+ geneq(eq, t)
+ }
// make Go funcs (closures) for calling hash and equal from Go
dsymptr(hashfunc, 0, hash, 0)
diff --git a/src/cmd/compile/internal/gc/select.go b/src/cmd/compile/internal/gc/select.go
index e770c8f18d..9a619a6d5a 100644
--- a/src/cmd/compile/internal/gc/select.go
+++ b/src/cmd/compile/internal/gc/select.go
@@ -318,35 +318,9 @@ out:
lineno = int32(lno)
}
-// Keep in sync with src/runtime/runtime2.go and src/runtime/select.go.
+// Keep in sync with src/runtime/select.go.
func selecttype(size int32) *Type {
- // TODO(dvyukov): it's possible to generate SudoG and Scase only once
- // and then cache; and also cache Select per size.
- sudog := Nod(OTSTRUCT, nil, nil)
-
- sudog.List = list(sudog.List, Nod(ODCLFIELD, newname(Lookup("g")), typenod(Ptrto(Types[TUINT8]))))
- sudog.List = list(sudog.List, Nod(ODCLFIELD, newname(Lookup("selectdone")), typenod(Ptrto(Types[TUINT8]))))
- sudog.List = list(sudog.List, Nod(ODCLFIELD, newname(Lookup("next")), typenod(Ptrto(Types[TUINT8]))))
- sudog.List = list(sudog.List, Nod(ODCLFIELD, newname(Lookup("prev")), typenod(Ptrto(Types[TUINT8]))))
- sudog.List = list(sudog.List, Nod(ODCLFIELD, newname(Lookup("elem")), typenod(Ptrto(Types[TUINT8]))))
- sudog.List = list(sudog.List, Nod(ODCLFIELD, newname(Lookup("releasetime")), typenod(Types[TUINT64])))
- sudog.List = list(sudog.List, Nod(ODCLFIELD, newname(Lookup("nrelease")), typenod(Types[TINT32])))
- sudog.List = list(sudog.List, Nod(ODCLFIELD, newname(Lookup("waitlink")), typenod(Ptrto(Types[TUINT8]))))
- typecheck(&sudog, Etype)
- sudog.Type.Noalg = true
- sudog.Type.Local = true
-
- scase := Nod(OTSTRUCT, nil, nil)
- scase.List = list(scase.List, Nod(ODCLFIELD, newname(Lookup("elem")), typenod(Ptrto(Types[TUINT8]))))
- scase.List = list(scase.List, Nod(ODCLFIELD, newname(Lookup("chan")), typenod(Ptrto(Types[TUINT8]))))
- scase.List = list(scase.List, Nod(ODCLFIELD, newname(Lookup("pc")), typenod(Types[TUINTPTR])))
- scase.List = list(scase.List, Nod(ODCLFIELD, newname(Lookup("kind")), typenod(Types[TUINT16])))
- scase.List = list(scase.List, Nod(ODCLFIELD, newname(Lookup("so")), typenod(Types[TUINT16])))
- scase.List = list(scase.List, Nod(ODCLFIELD, newname(Lookup("receivedp")), typenod(Ptrto(Types[TUINT8]))))
- scase.List = list(scase.List, Nod(ODCLFIELD, newname(Lookup("releasetime")), typenod(Types[TUINT64])))
- typecheck(&scase, Etype)
- scase.Type.Noalg = true
- scase.Type.Local = true
+ scase := syslook("scase", 0)
sel := Nod(OTSTRUCT, nil, nil)
sel.List = list(sel.List, Nod(ODCLFIELD, newname(Lookup("tcase")), typenod(Types[TUINT16])))
diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go
index ba0a257b3b..f48b7cdc4f 100644
--- a/src/cmd/compile/internal/gc/subr.go
+++ b/src/cmd/compile/internal/gc/subr.go
@@ -1419,16 +1419,21 @@ func deep(t *Type) *Type {
if t == nil {
return nil
}
+ if t.Etype == TANY {
+ nt := shallow(t)
+ nt.Copyany = true
+ return nt
+ }
+ if t.Sym != nil {
+ // share named types
+ return t
+ }
var nt *Type
switch t.Etype {
default:
nt = t // share from here down
- case TANY:
- nt = shallow(t)
- nt.Copyany = true
-
case TPTR32, TPTR64, TCHAN, TARRAY:
nt = shallow(t)
nt.Type = deep(t.Type)
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index f324d5e00f..f3112c3a61 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -1375,7 +1375,7 @@ opswitch:
r := nodnil() // bucket buffer
if n.Esc == EscNone {
// Allocate hmap buffer on stack.
- var_ := temp(hmap(t))
+ var_ := temp(syslook("hmap", 0).Type)
a = Nod(OAS, var_, nil) // zero temp
typecheck(&a, Etop)
@@ -1393,7 +1393,7 @@ opswitch:
r = Nod(OADDR, var_, nil)
}
- substArgTypes(fn, hmap(t), mapbucket(t), t.Down, t.Type)
+ substArgTypes(fn, mapbucket(t), t.Down, t.Type)
n = mkcall1(fn, n.Type, init, typename(n.Type), conv(n.Left, Types[TINT64]), a, r)
case OMAKESLICE:
diff --git a/src/reflect/type.go b/src/reflect/type.go
index 003c610cb1..91563dcf7e 100644
--- a/src/reflect/type.go
+++ b/src/reflect/type.go
@@ -340,7 +340,6 @@ type mapType struct {
key *rtype // map key type
elem *rtype // map element (value) type
bucket *rtype // internal bucket structure
- hmap *rtype // internal map header
keysize uint8 // size of key slot
indirectkey uint8 // store ptr to key instead of key itself
valuesize uint8 // size of value slot
diff --git a/src/runtime/hashmap.go b/src/runtime/hashmap.go
index 892a79a914..fcfcd4b607 100644
--- a/src/runtime/hashmap.go
+++ b/src/runtime/hashmap.go
@@ -102,6 +102,7 @@ const (
)
// A header for a Go map.
+// Changes here must also be made in src/cmd/compile/internal/gc/builtin/runtime.go.
type hmap struct {
// Note: the format of the Hmap is encoded in ../../cmd/internal/gc/reflect.go and
// ../reflect/type.go. Don't change this structure without also changing that code!
@@ -137,11 +138,10 @@ type bmap struct {
}
// A hash iteration structure.
-// If you modify hiter, also change cmd/internal/gc/reflect.go to indicate
-// the layout of this structure.
+// Changes here must also be made in src/cmd/compile/internal/gc/builtin/runtime.go.
type hiter struct {
- key unsafe.Pointer // Must be in first position. Write nil to indicate iteration end (see cmd/internal/gc/range.go).
- value unsafe.Pointer // Must be in second position (see cmd/internal/gc/range.go).
+ key unsafe.Pointer // Write nil to indicate iteration end (see cmd/compile/internal/gc/range.go).
+ value unsafe.Pointer
t *maptype
h *hmap
buckets unsafe.Pointer // bucket ptr at hash_iter initialization time
@@ -188,11 +188,10 @@ func (h *hmap) createOverflow() {
// If h != nil, the map can be created directly in h.
// If bucket != nil, bucket can be used as the first bucket.
func makemap(t *maptype, hint int64, h *hmap, bucket unsafe.Pointer) *hmap {
- if sz := unsafe.Sizeof(hmap{}); sz > 48 || sz != uintptr(t.hmap.size) {
- println("runtime: sizeof(hmap) =", sz, ", t.hmap.size =", t.hmap.size)
+ if sz := unsafe.Sizeof(hmap{}); sz > 48 {
+ println("runtime: sizeof(hmap) =", sz)
throw("bad hmap size")
}
-
if hint < 0 || int64(int32(hint)) != hint {
panic("makemap: size out of range")
// TODO: make hint an int, then none of this nonsense
@@ -254,7 +253,7 @@ func makemap(t *maptype, hint int64, h *hmap, bucket unsafe.Pointer) *hmap {
// initialize Hmap
if h == nil {
- h = (*hmap)(newobject(t.hmap))
+ h = &hmap{}
}
h.count = 0
h.B = B
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index 917fe89d38..379fe2678b 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -160,8 +160,6 @@ type gobuf struct {
bp uintptr // for GOEXPERIMENT=framepointer
}
-// Known to compiler.
-// Changes here must also be made in src/cmd/internal/gc/select.go's selecttype.
type sudog struct {
g *g
selectdone *uint32
diff --git a/src/runtime/select.go b/src/runtime/select.go
index b6c3fea001..25ebdaa595 100644
--- a/src/runtime/select.go
+++ b/src/runtime/select.go
@@ -22,7 +22,7 @@ const (
// Select statement header.
// Known to compiler.
-// Changes here must also be made in src/cmd/internal/gc/select.go's selecttype.
+// Changes here must also be made in src/cmd/compile/internal/gc/select.go's selecttype.
type hselect struct {
tcase uint16 // total count of scase[]
ncase uint16 // currently filled scase[]
@@ -33,7 +33,7 @@ type hselect struct {
// Select case descriptor.
// Known to compiler.
-// Changes here must also be made in src/cmd/internal/gc/select.go's selecttype.
+// Changes here must also be made in src/cmd/compile/internal/gc/builtin/runtime.go.
type scase struct {
elem unsafe.Pointer // data element
c *hchan // chan
diff --git a/src/runtime/type.go b/src/runtime/type.go
index d5f3bb1ef0..8350976491 100644
--- a/src/runtime/type.go
+++ b/src/runtime/type.go
@@ -60,7 +60,6 @@ type maptype struct {
key *_type
elem *_type
bucket *_type // internal type representing a hash bucket
- hmap *_type // internal type representing a hmap
keysize uint8 // size of key slot
indirectkey bool // store ptr to key instead of key itself
valuesize uint8 // size of value slot
From 028247d2cd82243b44b00c5da477f971112e5ff9 Mon Sep 17 00:00:00 2001
From: Josh Bleecher Snyder
Date: Thu, 11 Jun 2015 13:56:28 -0700
Subject: [PATCH 096/117] cmd/compile: reuse []Flow
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Benchmarked using compilebench on a quiet
but rather old OS X laptop.
Benchmarks from others would be welcome,
since the numbers look too good to be true.
name old time/op new time/op delta
Template 331ms ± 9% 303ms ± 4% -8.25% (p=0.000 n=24+24)
GoTypes 946ms ± 4% 888ms ± 3% -6.17% (p=0.000 n=24+25)
Compiler 3.20s ± 1% 3.10s ± 2% -3.07% (p=0.000 n=24+25)
name old alloc/op new alloc/op delta
Template 72.5MB ± 0% 61.8MB ± 0% -14.76% (p=0.000 n=25+24)
GoTypes 224MB ± 0% 189MB ± 0% -15.65% (p=0.000 n=25+25)
Compiler 695MB ± 0% 561MB ± 0% -19.26% (p=0.000 n=25+25)
name old allocs/op new allocs/op delta
Template 498k ± 0% 497k ± 0% -0.21% (p=0.000 n=25+23)
GoTypes 1.47M ± 0% 1.47M ± 0% -0.25% (p=0.000 n=25+25)
Compiler 4.09M ± 0% 4.08M ± 0% -0.18% (p=0.000 n=25+23)
Change-Id: I2394bc748128d721863453257fa5756c410f7898
Reviewed-on: https://go-review.googlesource.com/19771
Reviewed-by: Russ Cox
Run-TryBot: Russ Cox
TryBot-Result: Gobot Gobot
---
src/cmd/compile/internal/gc/popt.go | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/src/cmd/compile/internal/gc/popt.go b/src/cmd/compile/internal/gc/popt.go
index 4d71ab643d..b708222845 100644
--- a/src/cmd/compile/internal/gc/popt.go
+++ b/src/cmd/compile/internal/gc/popt.go
@@ -241,6 +241,19 @@ var flowmark int
// will not have flow graphs and consequently will not be optimized.
const MaxFlowProg = 50000
+var ffcache []Flow // reusable []Flow, to reduce allocation
+
+func growffcache(n int) {
+ if n > cap(ffcache) {
+ n = (n * 5) / 4
+ if n > MaxFlowProg {
+ n = MaxFlowProg
+ }
+ ffcache = make([]Flow, n)
+ }
+ ffcache = ffcache[:n]
+}
+
func Flowstart(firstp *obj.Prog, newData func() interface{}) *Graph {
// Count and mark instructions to annotate.
nf := 0
@@ -268,7 +281,9 @@ func Flowstart(firstp *obj.Prog, newData func() interface{}) *Graph {
// Allocate annotations and assign to instructions.
graph := new(Graph)
- ff := make([]Flow, nf)
+
+ growffcache(nf)
+ ff := ffcache
start := &ff[0]
id := 0
var last *Flow
@@ -331,6 +346,10 @@ func Flowend(graph *Graph) {
f.Prog.Info.Flags = 0 // drop cached proginfo
f.Prog.Opt = nil
}
+ clear := ffcache[:graph.Num]
+ for i := range clear {
+ clear[i] = Flow{}
+ }
}
// find looping structure
From f39cca94af880253be22cdbb30d0a7d385f6b516 Mon Sep 17 00:00:00 2001
From: Robert Griesemer