[release-branch.go1.5] release: merge master branch into release-branch.go1.5.
Using merge instead of cherry-picks to simplify initial release.
Minor releases like Go 1.5.1 will have to use cherry-picks.
Fixes #12093.
Change-Id: If00393c58ace0da6f359b387cea9b779b123b920
diff --git a/doc/asm.html b/doc/asm.html
index ba88811..c992e14 100644
--- a/doc/asm.html
+++ b/doc/asm.html
@@ -741,10 +741,10 @@
</ul>
-<h3 id="ppc64">Power 64, a.k.a. ppc64</h3>
+<h3 id="ppc64">64-bit PowerPC, a.k.a. ppc64</h3>
<p>
-The Power 64 port is in an experimental state.
+The 64-bit PowerPC port is in an experimental state.
</p>
<p>
diff --git a/doc/contrib.html b/doc/contrib.html
index c286abc..4839035 100644
--- a/doc/contrib.html
+++ b/doc/contrib.html
@@ -34,6 +34,7 @@
<p>A <a href="/doc/devel/release.html">summary</a> of the changes between Go releases. Notes for the major releases:</p>
<ul>
+ <li><a href="/doc/go1.5">Go 1.5</a> <small>(August 2015)</small></li>
<li><a href="/doc/go1.4">Go 1.4</a> <small>(December 2014)</small></li>
<li><a href="/doc/go1.3">Go 1.3</a> <small>(June 2014)</small></li>
<li><a href="/doc/go1.2">Go 1.2</a> <small>(December 2013)</small></li>
diff --git a/doc/devel/release.html b/doc/devel/release.html
index ee6d3e0..7d72c8d 100644
--- a/doc/devel/release.html
+++ b/doc/devel/release.html
@@ -12,6 +12,13 @@
git checkout <i>release-branch</i>
</pre>
+<h2 id="go1.5">go1.5 (released 2015/08/19)</h2>
+
+<p>
+Go 1.5 is a major release of Go.
+Read the <a href="/doc/go1.5">Go 1.5 Release Notes</a> for more information.
+</p>
+
<h2 id="go1.4">go1.4 (released 2014/12/10)</h2>
<p>
diff --git a/doc/go1.5.html b/doc/go1.5.html
index 70ce94e..4e5832d 100644
--- a/doc/go1.5.html
+++ b/doc/go1.5.html
@@ -83,7 +83,8 @@
Due to an oversight, the rule that allowed the element type to be elided from slice literals was not
applied to map keys.
This has been <a href="/cl/2591">corrected</a> in Go 1.5.
-An example will make this clear: as of Go 1.5, this map literal,
+An example will make this clear.
+As of Go 1.5, this map literal,
</p>
<pre>
@@ -182,7 +183,7 @@
<p>
In Go 1.5, the order in which goroutines are scheduled has been changed.
The properties of the scheduler were never defined by the language,
-but programs that depended on the scheduling order may be broken
+but programs that depend on the scheduling order may be broken
by this change.
We have seen a few (erroneous) programs affected by this change.
If you have programs that implicitly depend on the scheduling
@@ -194,7 +195,7 @@
sets the default number of threads to run simultaneously,
defined by <code>GOMAXPROCS</code>, to the number
of cores available on the CPU.
-In prior releases it defaulted to 1.
+In prior releases the default was 1.
Programs that do not expect to run with multiple cores may
break inadvertently.
They can be updated by removing the restriction or by setting
@@ -236,8 +237,8 @@
</p>
<p>
-Also available as experiments are <code>ppc64</code> (IBM Power 64)
-and <code>ppc64le</code> (IBM Power 64, little-endian).
+Also available as experiments are <code>ppc64</code>
+and <code>ppc64le</code> (64-bit PowerPC, big- and little-endian).
Both these ports support <code>cgo</code> but
only with internal linking.
</p>
@@ -247,8 +248,8 @@
</p>
<p>
-On NaCl, Go 1.5 requires SDK version pepper-39 or above because it now uses the
-<code>get_random_bytes</code> system call.
+On NaCl, Go 1.5 requires SDK version pepper-41. Later pepper versions are not
+compatible due to the removal of the sRPC subsystem from the NaCl runtime.
</p>
<p>
@@ -292,7 +293,7 @@
mechanism as <code>go tool compile</code>,
<code>go tool asm</code>,
<code>and go tool link</code>.
-Also, the file suffixes <code>.6</code>, <code>.8</code> etc. for the
+Also, the file suffixes <code>.6</code>, <code>.8</code>, etc. for the
intermediate object files are also gone; now they are just plain <code>.o</code> files.
</p>
@@ -512,7 +513,7 @@
<li>
A new <code>-asmflags</code> build option
sets flags to pass to the assembler.
-However,
+However,
the <code>-ccflags</code> build option has been dropped;
it was specific to the old, now deleted C compiler .
</li>
@@ -523,14 +524,6 @@
</li>
<li>
-An <code>-asmflags</code> build option has been added to provide
-flags to the assembler.
-However,
-the <code>-ccflags</code> build option has been dropped;
-it was specific to the old, now deleted C compiler .
-</li>
-
-<li>
A new <code>-pkgdir</code> build option
sets the location of installed package archives,
to help isolate custom builds.
@@ -546,7 +539,7 @@
<li>
The <code>test</code> subcommand now has a <code>-count</code>
flag to specify how many times to run each test and benchmark.
-<a href="/pkg/testing/"><code>testing</code></a> package
+The <a href="/pkg/testing/"><code>testing</code></a> package
does the work here, through by the <code>-test.count</code> flag.
</li>
@@ -823,7 +816,7 @@
</li>
<li>
-Also in the <a href="/pkg/bytes/"><code>bytes</code></a> package,
+In the <a href="/pkg/bytes/"><code>bytes</code></a> package,
the <a href="/pkg/bytes/#Buffer"><code>Buffer</code></a> type
now has a <a href="/pkg/bytes/#Buffer.Cap"><code>Cap</code></a> method
that reports the number of bytes allocated within the buffer.
@@ -960,7 +953,7 @@
<li>
The <a href="/pkg/debug/elf/"><code>debug/elf</code></a>
-package now has support for the 64-bit Power architecture.
+package now has support for the 64-bit PowerPC architecture.
</li>
<li>
@@ -1032,14 +1025,14 @@
In the <a href="/pkg/image/"><code>image</code></a> package,
the <a href="/pkg/image/#Rectangle"><code>Rectangle</code></a> type
now implements the <a href="/pkg/image/#Image"><code>Image</code></a> interface,
-mask image when drawing.
+so a <code>Rectangle</code> can serve as a mask when drawing.
</li>
<li>
Also in the <a href="/pkg/image/"><code>image</code></a> package,
to assist in the handling of some JPEG images,
there is now support for 4:1:1 and 4:1:0 YCbCr subsampling and basic
-CMYK support, represented by the new image.CMYK struct.
+CMYK support, represented by the new <code>image.CMYK</code> struct.
</li>
<li>
@@ -1062,7 +1055,7 @@
In Go 1.5, that operation may yield a different value.
The correct code is, and always was, to select the high 8 bits:
<code>uint8(r>>8)</code>.
-Incidentally, <code>image/draw</code> package
+Incidentally, the <code>image/draw</code> package
provides better support for such conversions; see
<a href="https://blog.golang.org/go-imagedraw-package">this blog post</a>
for more information.
@@ -1095,9 +1088,8 @@
The <a href="/pkg/log/"><code>log</code></a> package
has a new <a href="/pkg/log/#LUTC"><code>LUTC</code></a> flag
that causes time stamps to be printed in the UTC time zone.
-It also adds a <a href="/pkg/log/#SetOutput"><code>SetOutput</code></a> function
-to set the output destination for the standard logger
-and a corresponding method for user-created loggers.
+It also adds a <a href="/pkg/log/#Logger.SetOutput"><code>SetOutput</code></a> method
+for user-created loggers.
</li>
<li>
@@ -1109,7 +1101,7 @@
<li>
The <a href="/pkg/math/big/"><code>math/big</code></a> package
adds a new <a href="/pkg/math/big/#Jacobi"><code>Jacobi</code></a>
-function for integers and a new method
+function for integers and a new
<a href="/pkg/math/big/#Int.ModSqrt"><code>ModSqrt</code></a>
method for the <a href="/pkg/math/big/#Int"><code>Int</code></a> type.
</li>
@@ -1201,7 +1193,7 @@
<li>
The <a href="/pkg/net/mail/"><code>net/mail</code></a> package
-adds a <a href="/pkg/net/mail/#AddressParser"><code>AddressParser</code></a>
+adds an <a href="/pkg/net/mail/#AddressParser"><code>AddressParser</code></a>
type that can parse mail addresses.
</li>
@@ -1252,11 +1244,11 @@
</li>
<li>
-The <a href="/pkg/sync/#WaitGroup"><code>WaitGroup</code></a> function in
+The <a href="/pkg/sync/#WaitGroup"><code>WaitGroup</code></a> implementation in
package <a href="/pkg/sync/"><code>sync</code></a>
now diagnoses code that races a call to <a href="/pkg/sync/#WaitGroup.Add"><code>Add</code></a>
against a return from <a href="/pkg/sync/#WaitGroup.Wait"><code>Wait</code></a>.
-If it detects this condition, <code>WaitGroup</code> panics.
+If it detects this condition, the implementation panics.
</li>
<li>
@@ -1288,7 +1280,7 @@
<li>
Also in the <a href="/pkg/text/template/"><code>text/template</code></a> and
<a href="/pkg/html/template/"><code>html/template</code></a> packages,
-a new <a href="/pkg/text/template/#Option"><code>Option</code></a> type
+a new <a href="/pkg/text/template/#Template.Option"><code>Option</code></a> method
allows customization of the behavior of the template during execution.
The sole implemented option allows control over how a missing key is
handled when indexing a map.
diff --git a/doc/install.html b/doc/install.html
index 9264f3a..e9f0f0d 100644
--- a/doc/install.html
+++ b/doc/install.html
@@ -33,11 +33,11 @@
<h2 id="requirements">System requirements</h2>
<p>
-The <code>gc</code> compiler supports the following operating systems and
-architectures. Please ensure your system meets these requirements before
-proceeding. If your OS or architecture is not on the list, it's possible that
-<code>gccgo</code> might support your setup; see
-<a href="/doc/install/gccgo">Setting up and using gccgo</a> for details.
+Go binary distributions are available for these supported operating systems and architectures.
+Please ensure your system meets these requirements before proceeding.
+If your OS or architecture is not on the list, you may be able to
+<a href="/doc/install/source">install from source</a> or
+<a href="/doc/install/gccgo">use gccgo instead</a>.
</p>
<table class="codetable" frame="border" summary="requirements">
@@ -47,9 +47,9 @@
<th align="center">Notes</th>
</tr>
<tr><td colspan="3"><hr></td></tr>
-<tr><td>FreeBSD 8-STABLE or later</td> <td>amd64, 386, arm</td> <td>Debian GNU/kFreeBSD not supported; FreeBSD/ARM needs FreeBSD 10 or later</td></tr>
-<tr><td>Linux 2.6.23 or later with glibc</td> <td>amd64, 386, arm</td> <td>CentOS/RHEL 5.x not supported; no binary distribution for ARM yet</td></tr>
-<tr><td>Mac OS X 10.7 or later</td> <td>amd64</td> <td>use the gcc<sup>†</sup> that comes with Xcode<sup>‡</sup></td></tr>
+<tr><td>FreeBSD 8-STABLE or later</td> <td>amd64</td> <td>Debian GNU/kFreeBSD not supported</td></tr>
+<tr><td>Linux 2.6.23 or later with glibc</td> <td>amd64, 386, arm</td> <td>CentOS/RHEL 5.x not supported; install from source for ARM</td></tr>
+<tr><td>Mac OS X 10.7 or later</td> <td>amd64</td> <td>use the clang or gcc<sup>†</sup> that comes with Xcode<sup>‡</sup></td></tr>
<tr><td>Windows XP or later</td> <td>amd64, 386</td> <td>use MinGW gcc<sup>†</sup>. No need for cygwin or msys.</td></tr>
</table>
diff --git a/src/cmd/compile/internal/amd64/ggen.go b/src/cmd/compile/internal/amd64/ggen.go
index 6425633..65cf694 100644
--- a/src/cmd/compile/internal/amd64/ggen.go
+++ b/src/cmd/compile/internal/amd64/ggen.go
@@ -306,7 +306,7 @@
* known to be dead.
*/
func savex(dr int, x *gc.Node, oldx *gc.Node, res *gc.Node, t *gc.Type) {
- r := reg[dr]
+ r := uint8(gc.GetReg(dr))
// save current ax and dx if they are live
// and not the destination
@@ -319,14 +319,14 @@
gmove(x, oldx)
x.Type = t
oldx.Etype = r // squirrel away old r value
- reg[dr] = 1
+ gc.SetReg(dr, 1)
}
}
func restx(x *gc.Node, oldx *gc.Node) {
if oldx.Op != 0 {
x.Type = gc.Types[gc.TINT64]
- reg[x.Reg] = oldx.Etype
+ gc.SetReg(int(x.Reg), int(oldx.Etype))
gmove(oldx, x)
gc.Regfree(oldx)
}
@@ -411,7 +411,7 @@
nr = &n5
}
- rcx := int(reg[x86.REG_CX])
+ rcx := gc.GetReg(x86.REG_CX)
var n1 gc.Node
gc.Nodreg(&n1, gc.Types[gc.TUINT32], x86.REG_CX)
diff --git a/src/cmd/compile/internal/amd64/reg.go b/src/cmd/compile/internal/amd64/reg.go
index 7d4f406..8fab639 100644
--- a/src/cmd/compile/internal/amd64/reg.go
+++ b/src/cmd/compile/internal/amd64/reg.go
@@ -40,8 +40,6 @@
NREGVAR = 32
)
-var reg [x86.MAXREG]uint8
-
var regname = []string{
".AX",
".CX",
diff --git a/src/cmd/compile/internal/arm64/ggen.go b/src/cmd/compile/internal/arm64/ggen.go
index 6b0b40e..cba4d99 100644
--- a/src/cmd/compile/internal/arm64/ggen.go
+++ b/src/cmd/compile/internal/arm64/ggen.go
@@ -418,15 +418,12 @@
c := uint64(w % 8) // bytes
q := uint64(w / 8) // dwords
- if reg[arm64.REGRT1-arm64.REG_R0] > 0 {
- gc.Fatal("R%d in use during clearfat", arm64.REGRT1-arm64.REG_R0)
- }
-
var r0 gc.Node
gc.Nodreg(&r0, gc.Types[gc.TUINT64], arm64.REGZERO)
var dst gc.Node
+
+ // REGRT1 is reserved on arm64, see arm64/gsubr.go.
gc.Nodreg(&dst, gc.Types[gc.Tptr], arm64.REGRT1)
- reg[arm64.REGRT1-arm64.REG_R0]++
gc.Agen(nl, &dst)
var boff uint64
@@ -484,8 +481,6 @@
p.To.Type = obj.TYPE_MEM
p.To.Offset = int64(t + boff)
}
-
- reg[arm64.REGRT1-arm64.REG_R0]--
}
// Called after regopt and peep have run.
diff --git a/src/cmd/compile/internal/arm64/reg.go b/src/cmd/compile/internal/arm64/reg.go
index 7bc756b..b84359a 100644
--- a/src/cmd/compile/internal/arm64/reg.go
+++ b/src/cmd/compile/internal/arm64/reg.go
@@ -39,8 +39,6 @@
NREGVAR = 64 /* 32 general + 32 floating */
)
-var reg [arm64.NREG + arm64.NFREG]uint8
-
var regname = []string{
".R0",
".R1",
diff --git a/src/cmd/compile/internal/gc/gsubr.go b/src/cmd/compile/internal/gc/gsubr.go
index 14dc927..2c575f3 100644
--- a/src/cmd/compile/internal/gc/gsubr.go
+++ b/src/cmd/compile/internal/gc/gsubr.go
@@ -602,6 +602,13 @@
var reg [100]int // count of references to reg
var regstk [100][]byte // allocation sites, when -v is given
+func GetReg(r int) int {
+ return reg[r-Thearch.REGMIN]
+}
+func SetReg(r, v int) {
+ reg[r-Thearch.REGMIN] = v
+}
+
func ginit() {
for r := range reg {
reg[r] = 1
diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go
index dc2ba75..befe3b2 100644
--- a/src/cmd/compile/internal/gc/typecheck.go
+++ b/src/cmd/compile/internal/gc/typecheck.go
@@ -2532,7 +2532,7 @@
n.Xoffset = f1.Width
n.Type = f1.Type
if obj.Fieldtrack_enabled > 0 {
- dotField[typeSym{t, s}] = f1
+ dotField[typeSym{t.Orig, s}] = f1
}
if t.Etype == TINTER {
if Isptr[n.Left.Type.Etype] {
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index 91c0a47..ce73018 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -3873,7 +3873,7 @@
if Isptr[t.Etype] {
t = t.Type
}
- field := dotField[typeSym{t, n.Right.Sym}]
+ field := dotField[typeSym{t.Orig, n.Right.Sym}]
if field == nil {
Fatal("usefield %v %v without paramfld", n.Left.Type, n.Right.Sym)
}
diff --git a/src/cmd/compile/internal/ppc64/ggen.go b/src/cmd/compile/internal/ppc64/ggen.go
index 1b936b8..5b282eb 100644
--- a/src/cmd/compile/internal/ppc64/ggen.go
+++ b/src/cmd/compile/internal/ppc64/ggen.go
@@ -71,7 +71,10 @@
for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
p = appendpp(p, ppc64.AMOVD, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGSP, 8+frame+lo+i)
}
- } else if cnt <= int64(128*gc.Widthptr) {
+ // TODO(dfc): https://golang.org/issue/12108
+ // If DUFFZERO is used inside a tail call (see genwrapper) it will
+ // overwrite the link register.
+ } else if false && cnt <= int64(128*gc.Widthptr) {
p = appendpp(p, ppc64.AADD, obj.TYPE_CONST, 0, 8+frame+lo-8, obj.TYPE_REG, ppc64.REGRT1, 0)
p.Reg = ppc64.REGSP
p = appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
@@ -442,7 +445,10 @@
// The loop leaves R3 on the last zeroed dword
boff = 8
- } else if q >= 4 {
+ // TODO(dfc): https://golang.org/issue/12108
+ // If DUFFZERO is used inside a tail call (see genwrapper) it will
+ // overwrite the link register.
+ } else if false && q >= 4 {
p := gins(ppc64.ASUB, nil, &dst)
p.From.Type = obj.TYPE_CONST
p.From.Offset = 8
diff --git a/src/cmd/compile/internal/x86/ggen.go b/src/cmd/compile/internal/x86/ggen.go
index dabc139..ae9881d 100644
--- a/src/cmd/compile/internal/x86/ggen.go
+++ b/src/cmd/compile/internal/x86/ggen.go
@@ -319,7 +319,7 @@
}
func savex(dr int, x *gc.Node, oldx *gc.Node, res *gc.Node, t *gc.Type) {
- r := int(reg[dr])
+ r := gc.GetReg(dr)
gc.Nodreg(x, gc.Types[gc.TINT32], dr)
// save current ax and dx if they are live
@@ -408,7 +408,7 @@
var oldcx gc.Node
var cx gc.Node
gc.Nodreg(&cx, gc.Types[gc.TUINT32], x86.REG_CX)
- if reg[x86.REG_CX] > 1 && !gc.Samereg(&cx, res) {
+ if gc.GetReg(x86.REG_CX) > 1 && !gc.Samereg(&cx, res) {
gc.Tempname(&oldcx, gc.Types[gc.TUINT32])
gmove(&cx, &oldcx)
}
diff --git a/src/cmd/compile/internal/x86/reg.go b/src/cmd/compile/internal/x86/reg.go
index 8c97171..b3a5fdf 100644
--- a/src/cmd/compile/internal/x86/reg.go
+++ b/src/cmd/compile/internal/x86/reg.go
@@ -37,8 +37,6 @@
NREGVAR = 16 /* 8 integer + 8 floating */
)
-var reg [x86.MAXREG]uint8
-
var regname = []string{
".ax",
".cx",
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index 512ed61..6077d93 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -521,9 +521,10 @@
The default output shows the package import path:
- code.google.com/p/google-api-go-client/books/v1
- code.google.com/p/goauth2/oauth
- code.google.com/p/sqlite
+ bytes
+ encoding/json
+ github.com/gorilla/mux
+ golang.org/x/net/html
The -f flag specifies an alternate format for the list, using the
syntax of package template. The default output is equivalent to -f
@@ -1284,7 +1285,7 @@
unique prefix that belongs to you. For example, paths used
internally at Google all begin with 'google', and paths
denoting remote repositories begin with the path to the code,
-such as 'code.google.com/p/project'.
+such as 'github.com/user/repo'.
As a special case, if the package list is a list of .go files from a
single directory, the command is applied to a single synthesized
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
index 718edd2..b7c7e05 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -1880,7 +1880,7 @@
cmd.Stdout = &buf
cmd.Stderr = &buf
cmd.Dir = dir
- cmd.Env = mergeEnvLists(env, envForDir(cmd.Dir))
+ cmd.Env = mergeEnvLists(env, envForDir(cmd.Dir, os.Environ()))
err := cmd.Run()
// cmd.Run will fail on Unix if some other process has the binary
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index 5b0f278..77b2628 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -2294,6 +2294,21 @@
tg.run("run", tg.path("run.go"))
}
+func TestIssue12096(t *testing.T) {
+ tg := testgo(t)
+ defer tg.cleanup()
+ tg.tempFile("test_test.go", `
+ package main
+ import ("os"; "testing")
+ func TestEnv(t *testing.T) {
+ if os.Getenv("TERM") != "" {
+ t.Fatal("TERM is set")
+ }
+ }`)
+ tg.unsetenv("TERM")
+ tg.run("test", tg.path("test_test.go"))
+}
+
func TestGoBuildOutput(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
@@ -2352,3 +2367,23 @@
tg.runFail("build", "-o", "whatever", "cmd/gofmt", "sync/atomic")
tg.grepStderr("multiple packages", "did not reject -o with multiple packages")
}
+
+func TestGoBuildARM(t *testing.T) {
+ if testing.Short() {
+ t.Skip("skipping cross-compile in short mode")
+ }
+
+ tg := testgo(t)
+ defer tg.cleanup()
+
+ tg.makeTempdir()
+ tg.cd(tg.path("."))
+
+ tg.setenv("GOARCH", "arm")
+ tg.setenv("GOOS", "linux")
+ tg.setenv("GOARM", "5")
+ tg.tempFile("hello.go", `package main
+ func main() {}`)
+ tg.run("build", "hello.go")
+ tg.grepStderrNot("unable to find math.a", "did not build math.a correctly")
+}
diff --git a/src/cmd/go/help.go b/src/cmd/go/help.go
index 0bc5ef9..5dff267 100644
--- a/src/cmd/go/help.go
+++ b/src/cmd/go/help.go
@@ -77,7 +77,7 @@
unique prefix that belongs to you. For example, paths used
internally at Google all begin with 'google', and paths
denoting remote repositories begin with the path to the code,
-such as 'code.google.com/p/project'.
+such as 'github.com/user/repo'.
As a special case, if the package list is a list of .go files from a
single directory, the command is applied to a single synthesized
diff --git a/src/cmd/go/list.go b/src/cmd/go/list.go
index f59c82e..35c7cc4 100644
--- a/src/cmd/go/list.go
+++ b/src/cmd/go/list.go
@@ -21,9 +21,10 @@
The default output shows the package import path:
- code.google.com/p/google-api-go-client/books/v1
- code.google.com/p/goauth2/oauth
- code.google.com/p/sqlite
+ bytes
+ encoding/json
+ github.com/gorilla/mux
+ golang.org/x/net/html
The -f flag specifies an alternate format for the list, using the
syntax of package template. The default output is equivalent to -f
diff --git a/src/cmd/go/main.go b/src/cmd/go/main.go
index 88a9441..8ebde89 100644
--- a/src/cmd/go/main.go
+++ b/src/cmd/go/main.go
@@ -446,11 +446,10 @@
// The environment is the current process's environment
// but with an updated $PWD, so that an os.Getwd in the
// child will be faster.
-func envForDir(dir string) []string {
- env := os.Environ()
+func envForDir(dir string, base []string) []string {
// Internally we only use rooted paths, so dir is rooted.
// Even if dir is not rooted, no harm done.
- return mergeEnvLists([]string{"PWD=" + dir}, env)
+ return mergeEnvLists([]string{"PWD=" + dir}, base)
}
// mergeEnvLists merges the two environment lists such that
diff --git a/src/cmd/go/note_test.go b/src/cmd/go/note_test.go
index fb25f94..3d64451 100644
--- a/src/cmd/go/note_test.go
+++ b/src/cmd/go/note_test.go
@@ -5,7 +5,8 @@
package main_test
import (
- "cmd/go"
+ main "cmd/go"
+ "runtime"
"testing"
)
@@ -22,4 +23,27 @@
if id != buildID {
t.Fatalf("buildID in hello binary = %q, want %q", id, buildID)
}
+
+ if runtime.GOOS == "linux" && runtime.GOARCH == "ppc64le" {
+ t.Skipf("skipping - golang.org/issue/11184")
+ }
+
+ switch runtime.GOOS {
+ case "plan9":
+ // no external linking
+ t.Logf("no external linking - skipping linkmode=external test")
+
+ case "solaris":
+ t.Logf("skipping - golang.org/issue/12178")
+
+ default:
+ tg.run("build", "-ldflags", "-buildid="+buildID+" -linkmode=external", "-o", tg.path("hello.exe"), tg.path("hello.go"))
+ id, err := main.ReadBuildIDFromBinary(tg.path("hello.exe"))
+ if err != nil {
+ t.Fatalf("reading build ID from hello binary (linkmode=external): %v", err)
+ }
+ if id != buildID {
+ t.Fatalf("buildID in hello binary = %q, want %q (linkmode=external)", id, buildID)
+ }
+ }
}
diff --git a/src/cmd/go/pkg.go b/src/cmd/go/pkg.go
index 6b78a47..61e3d8d 100644
--- a/src/cmd/go/pkg.go
+++ b/src/cmd/go/pkg.go
@@ -416,7 +416,7 @@
return path, nil
}
dir := filepath.Clean(parent.Dir)
- root := filepath.Clean(parent.Root)
+ root := filepath.Join(parent.Root, "src")
if !hasFilePathPrefix(dir, root) || len(dir) <= len(root) || dir[len(root)] != filepath.Separator {
fatalf("invalid vendoredImportPath: dir=%q root=%q separator=%q", dir, root, string(filepath.Separator))
}
@@ -836,7 +836,7 @@
importPaths = append(importPaths, "runtime/race")
}
// On ARM with GOARM=5, everything depends on math for the link.
- if p.ImportPath == "main" && goarch == "arm" {
+ if p.Name == "main" && goarch == "arm" {
importPaths = append(importPaths, "math")
}
}
@@ -1796,10 +1796,10 @@
return "", &os.PathError{Op: "parse", Path: filename, Err: errBuildIDUnknown}
}
- // Read the first 8 kB of the binary file.
+ // Read the first 16 kB of the binary file.
// That should be enough to find the build ID.
// In ELF files, the build ID is in the leading headers,
- // which are typically less than 4 kB, not to mention 8 kB.
+ // which are typically less than 4 kB, not to mention 16 kB.
// On other systems, we're trying to read enough that
// we get the beginning of the text segment in the read.
// The offset where the text segment begins in a hello
@@ -1807,7 +1807,7 @@
//
// Plan 9: 0x20
// Windows: 0x600
- // Mach-O: 0x1000
+ // Mach-O: 0x2000
//
f, err := os.Open(filename)
if err != nil {
@@ -1815,7 +1815,7 @@
}
defer f.Close()
- data := make([]byte, 8192)
+ data := make([]byte, 16*1024)
_, err = io.ReadFull(f, data)
if err == io.ErrUnexpectedEOF {
err = nil
diff --git a/src/cmd/go/test.go b/src/cmd/go/test.go
index 0ba1883..ba1ab82 100644
--- a/src/cmd/go/test.go
+++ b/src/cmd/go/test.go
@@ -1027,7 +1027,7 @@
cmd := exec.Command(args[0], args[1:]...)
cmd.Dir = a.p.Dir
- cmd.Env = envForDir(cmd.Dir)
+ cmd.Env = envForDir(cmd.Dir, origEnv)
var buf bytes.Buffer
if testStreamOutput {
cmd.Stdout = os.Stdout
diff --git a/src/cmd/go/testdata/testvendor2/src/p/p.go b/src/cmd/go/testdata/testvendor2/src/p/p.go
new file mode 100644
index 0000000..220b2b2
--- /dev/null
+++ b/src/cmd/go/testdata/testvendor2/src/p/p.go
@@ -0,0 +1,3 @@
+package p
+
+import "x"
diff --git a/src/cmd/go/testdata/testvendor2/vendor/x/x.go b/src/cmd/go/testdata/testvendor2/vendor/x/x.go
new file mode 100644
index 0000000..823aafd
--- /dev/null
+++ b/src/cmd/go/testdata/testvendor2/vendor/x/x.go
@@ -0,0 +1 @@
+package x
diff --git a/src/cmd/go/testflag.go b/src/cmd/go/testflag.go
index ee4ab18..1f3e3d3 100644
--- a/src/cmd/go/testflag.go
+++ b/src/cmd/go/testflag.go
@@ -36,6 +36,7 @@
{name: "cover", boolVar: &testCover},
{name: "covermode"},
{name: "coverpkg"},
+ {name: "exec"},
// passed to 6.out, adding a "test." prefix to the name if necessary: -v becomes -test.v.
{name: "bench", passToTest: true},
diff --git a/src/cmd/go/vcs.go b/src/cmd/go/vcs.go
index 2ee1057..28a7540 100644
--- a/src/cmd/go/vcs.go
+++ b/src/cmd/go/vcs.go
@@ -344,7 +344,7 @@
cmd := exec.Command(v.cmd, args...)
cmd.Dir = dir
- cmd.Env = envForDir(cmd.Dir)
+ cmd.Env = envForDir(cmd.Dir, os.Environ())
if buildX {
fmt.Printf("cd %s\n", dir)
fmt.Printf("%s %s\n", v.cmd, strings.Join(args, " "))
diff --git a/src/cmd/go/vendor_test.go b/src/cmd/go/vendor_test.go
index 611aceb..1e8cf9c 100644
--- a/src/cmd/go/vendor_test.go
+++ b/src/cmd/go/vendor_test.go
@@ -244,3 +244,15 @@
tg.run("list", "-f", `{{join .XTestImports "\n"}}`, "github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx3")
tg.grepStdout("go-get-issue-11864/vendor/vendor.org/tx3", "did not find vendor-expanded tx3")
}
+
+func TestVendor12156(t *testing.T) {
+ // Former index out of range panic.
+ 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")
+ tg.grepStderr(`cannot find package "x"`, "wrong error")
+}
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
index 33f250d..55b12e5 100644
--- a/src/cmd/link/internal/ld/data.go
+++ b/src/cmd/link/internal/ld/data.go
@@ -778,7 +778,6 @@
}
eaddr := addr + size
- var n int64
var q []byte
for ; sym != nil; sym = sym.Next {
if !sym.Reachable {
@@ -797,20 +796,18 @@
}
fmt.Fprintf(&Bso, "%.6x\t%-20s\n", uint64(int64(addr)), sym.Name)
- n = sym.Size
q = sym.P
- for n >= 16 {
- fmt.Fprintf(&Bso, "%.6x\t%-20.16I\n", uint64(addr), q)
+ for len(q) >= 16 {
+ fmt.Fprintf(&Bso, "%.6x\t% x\n", uint64(addr), q[:16])
addr += 16
q = q[16:]
- n -= 16
}
- if n > 0 {
- fmt.Fprintf(&Bso, "%.6x\t%-20.*I\n", uint64(addr), int(n), q)
+ if len(q) > 0 {
+ fmt.Fprintf(&Bso, "%.6x\t% x\n", uint64(addr), q)
+ addr += int64(len(q))
}
- addr += n
}
if addr < eaddr {
diff --git a/src/cmd/trace/trace.go b/src/cmd/trace/trace.go
index 0d2451b..e6eb320 100644
--- a/src/cmd/trace/trace.go
+++ b/src/cmd/trace/trace.go
@@ -10,8 +10,8 @@
"internal/trace"
"log"
"net/http"
- "os"
"path/filepath"
+ "runtime"
"strconv"
"strings"
)
@@ -63,7 +63,7 @@
// httpTraceViewerHTML serves static part of trace-viewer.
// This URL is queried from templTrace HTML.
func httpTraceViewerHTML(w http.ResponseWriter, r *http.Request) {
- http.ServeFile(w, r, filepath.Join(os.Getenv("GOROOT"), "misc", "trace", "trace_viewer_lean.html"))
+ http.ServeFile(w, r, filepath.Join(runtime.GOROOT(), "misc", "trace", "trace_viewer_lean.html"))
}
// httpJsonTrace serves json trace, requested from within templTrace HTML.
diff --git a/src/cmd/vet/asmdecl.go b/src/cmd/vet/asmdecl.go
index 6bdfdbf..e4a9871 100644
--- a/src/cmd/vet/asmdecl.go
+++ b/src/cmd/vet/asmdecl.go
@@ -58,13 +58,13 @@
}
var (
- asmArch386 = asmArch{"386", 4, 4, 4, false, "SP", false}
- asmArchArm = asmArch{"arm", 4, 4, 4, false, "R13", true}
- asmArchArm64 = asmArch{"arm64", 8, 8, 8, false, "RSP", true}
- asmArchAmd64 = asmArch{"amd64", 8, 8, 8, false, "SP", false}
- asmArchAmd64p32 = asmArch{"amd64p32", 4, 4, 8, false, "SP", false}
- asmArchPower64 = asmArch{"power64", 8, 8, 8, true, "R1", true}
- asmArchPower64LE = asmArch{"power64le", 8, 8, 8, false, "R1", true}
+ asmArch386 = asmArch{"386", 4, 4, 4, false, "SP", false}
+ asmArchArm = asmArch{"arm", 4, 4, 4, false, "R13", true}
+ asmArchArm64 = asmArch{"arm64", 8, 8, 8, false, "RSP", true}
+ asmArchAmd64 = asmArch{"amd64", 8, 8, 8, false, "SP", false}
+ asmArchAmd64p32 = asmArch{"amd64p32", 4, 4, 8, false, "SP", false}
+ asmArchPpc64 = asmArch{"ppc64", 8, 8, 8, true, "R1", true}
+ asmArchPpc64LE = asmArch{"ppc64le", 8, 8, 8, false, "R1", true}
arches = []*asmArch{
&asmArch386,
@@ -72,8 +72,8 @@
&asmArchArm64,
&asmArchAmd64,
&asmArchAmd64p32,
- &asmArchPower64,
- &asmArchPower64LE,
+ &asmArchPpc64,
+ &asmArchPpc64LE,
}
)
@@ -86,7 +86,7 @@
asmUnnamedFP = re(`[^+\-0-9](([0-9]+)\(FP\))`)
asmSP = re(`[^+\-0-9](([0-9]+)\(([A-Z0-9]+)\))`)
asmOpcode = re(`^\s*(?:[A-Z0-9a-z_]+:)?\s*([A-Z]+)\s*([^,]*)(?:,\s*(.*))?`)
- power64Suff = re(`([BHWD])(ZU|Z|U|BR)?$`)
+ ppc64Suff = re(`([BHWD])(ZU|Z|U|BR)?$`)
)
func asmCheck(pkg *Package) {
@@ -589,9 +589,9 @@
case 'D', 'Q':
src = 8
}
- case "power64", "power64le":
+ case "ppc64", "ppc64le":
// Strip standard suffixes to reveal size letter.
- m := power64Suff.FindStringSubmatch(op)
+ m := ppc64Suff.FindStringSubmatch(op)
if m != nil {
switch m[1][0] {
case 'B':
diff --git a/src/cmd/yacc/yacc.go b/src/cmd/yacc/yacc.go
index 53c0fab..4f83f50 100644
--- a/src/cmd/yacc/yacc.go
+++ b/src/cmd/yacc/yacc.go
@@ -699,18 +699,20 @@
}
}
- // put out names of token names
+ // put out names of tokens
ftable.WriteRune('\n')
fmt.Fprintf(ftable, "var %sToknames = [...]string{\n", prefix)
for i := 1; i <= ntokens; i++ {
- fmt.Fprintf(ftable, "\t\"%v\",\n", tokset[i].name)
+ fmt.Fprintf(ftable, "\t%q,\n", tokset[i].name)
}
fmt.Fprintf(ftable, "}\n")
- // put out names of state names
+ // put out names of states.
+ // commented out to avoid a huge table just for debugging.
+ // re-enable to have the names in the binary.
fmt.Fprintf(ftable, "var %sStatenames = [...]string{", prefix)
// for i:=TOKSTART; i<=ntokens; i++ {
- // fmt.Fprintf(ftable, "\t\"%v\",\n", tokset[i].name);
+ // fmt.Fprintf(ftable, "\t%q,\n", tokset[i].name);
// }
fmt.Fprintf(ftable, "}\n")
@@ -3471,6 +3473,7 @@
var $$lval $$SymType
var $$VAL $$SymType
var $$Dollar []$$SymType
+ _ = $$Dollar // silence set and not used
$$S := make([]$$SymType, $$MaxDepth)
Nerrs := 0 /* number of errors */
diff --git a/src/fmt/scan.go b/src/fmt/scan.go
index 21ed091..5b9b516 100644
--- a/src/fmt/scan.go
+++ b/src/fmt/scan.go
@@ -888,7 +888,6 @@
func (s *ss) hexByte() (b byte, ok bool) {
rune1 := s.getRune()
if rune1 == eof {
- s.UnreadRune()
return
}
value1, ok := hexDigit(rune1)
diff --git a/src/fmt/scan_test.go b/src/fmt/scan_test.go
index 694f93e..a378436 100644
--- a/src/fmt/scan_test.go
+++ b/src/fmt/scan_test.go
@@ -1128,3 +1128,31 @@
}
}
}
+
+// Test for issue 12090: Was unreading at EOF, double-scanning a byte.
+
+type hexBytes [2]byte
+
+func (h *hexBytes) Scan(ss ScanState, verb rune) error {
+ var b []byte
+ _, err := Fscanf(ss, "%4x", &b)
+ if err != nil {
+ panic(err) // Really shouldn't happen.
+ }
+ copy((*h)[:], b)
+ return err
+}
+
+func TestHexByte(t *testing.T) {
+ var h hexBytes
+ n, err := Sscanln("0123\n", &h)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if n != 1 {
+ t.Fatalf("expected 1 item; scanned %d", n)
+ }
+ if h[0] != 0x01 || h[1] != 0x23 {
+ t.Fatalf("expected 0123 got %x", h)
+ }
+}
diff --git a/src/net/cgo_unix.go b/src/net/cgo_unix.go
index d9d5f03..cb89d65 100644
--- a/src/net/cgo_unix.go
+++ b/src/net/cgo_unix.go
@@ -222,6 +222,11 @@
break
}
}
+ // Add trailing dot to match pure Go reverse resolver
+ // and all other lookup routines. See golang.org/issue/12189.
+ if len(b) > 0 && b[len(b)-1] != '.' {
+ b = append(b, '.')
+ }
return []string{string(b)}, nil, true
}
diff --git a/src/net/conf.go b/src/net/conf.go
index 01bb585..c92e579 100644
--- a/src/net/conf.go
+++ b/src/net/conf.go
@@ -19,7 +19,7 @@
// forceCgoLookupHost forces CGO to always be used, if available.
forceCgoLookupHost bool
- netGo bool // "netgo" build tag in use (or no cgo)
+ netGo bool // go DNS resolution forced
netCgo bool // cgo DNS resolution forced
// machine has an /etc/mdns.allow file
@@ -112,6 +112,12 @@
}
}
+// canUseCgo reports whether calling cgo functions is allowed
+// for non-hostname lookups.
+func (c *conf) canUseCgo() bool {
+ return c.hostLookupOrder("") == hostLookupCgo
+}
+
// hostLookupOrder determines which strategy to use to resolve hostname.
func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) {
if c.dnsDebugLevel > 1 {
diff --git a/src/net/http/server.go b/src/net/http/server.go
index 1b292ea..a3e4355 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -473,7 +473,7 @@
if debugServerConnections {
c.rwc = newLoggingConn("server", c.rwc)
}
- c.sr = liveSwitchReader{r: c.rwc}
+ c.sr.r = c.rwc
c.lr = io.LimitReader(&c.sr, noLimit).(*io.LimitedReader)
br := newBufioReader(c.lr)
bw := newBufioWriterSize(checkConnErrorWriter{c}, 4<<10)
@@ -2015,10 +2015,7 @@
if addr == "" {
addr = ":https"
}
- config := &tls.Config{}
- if srv.TLSConfig != nil {
- *config = *srv.TLSConfig
- }
+ config := cloneTLSConfig(srv.TLSConfig)
if config.NextProtos == nil {
config.NextProtos = []string{"http/1.1"}
}
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
index 09434f1..70d1864 100644
--- a/src/net/http/transport.go
+++ b/src/net/http/transport.go
@@ -645,16 +645,9 @@
if cm.targetScheme == "https" && !tlsDial {
// Initiate TLS and check remote host name against certificate.
- cfg := t.TLSClientConfig
- if cfg == nil || cfg.ServerName == "" {
- host := cm.tlsHost()
- if cfg == nil {
- cfg = &tls.Config{ServerName: host}
- } else {
- clone := *cfg // shallow clone
- clone.ServerName = host
- cfg = &clone
- }
+ cfg := cloneTLSClientConfig(t.TLSClientConfig)
+ if cfg.ServerName == "" {
+ cfg.ServerName = cm.tlsHost()
}
plainConn := pconn.conn
tlsConn := tls.Client(plainConn, cfg)
@@ -1399,3 +1392,70 @@
return false
}
}
+
+// cloneTLSConfig returns a shallow clone of the exported
+// fields of cfg, ignoring the unexported sync.Once, which
+// contains a mutex and must not be copied.
+//
+// The cfg must not be in active use by tls.Server, or else
+// there can still be a race with tls.Server updating SessionTicketKey
+// and our copying it, and also a race with the server setting
+// SessionTicketsDisabled=false on failure to set the random
+// ticket key.
+//
+// If cfg is nil, a new zero tls.Config is returned.
+func cloneTLSConfig(cfg *tls.Config) *tls.Config {
+ if cfg == nil {
+ return &tls.Config{}
+ }
+ return &tls.Config{
+ Rand: cfg.Rand,
+ Time: cfg.Time,
+ Certificates: cfg.Certificates,
+ NameToCertificate: cfg.NameToCertificate,
+ GetCertificate: cfg.GetCertificate,
+ RootCAs: cfg.RootCAs,
+ NextProtos: cfg.NextProtos,
+ ServerName: cfg.ServerName,
+ ClientAuth: cfg.ClientAuth,
+ ClientCAs: cfg.ClientCAs,
+ InsecureSkipVerify: cfg.InsecureSkipVerify,
+ CipherSuites: cfg.CipherSuites,
+ PreferServerCipherSuites: cfg.PreferServerCipherSuites,
+ SessionTicketsDisabled: cfg.SessionTicketsDisabled,
+ SessionTicketKey: cfg.SessionTicketKey,
+ ClientSessionCache: cfg.ClientSessionCache,
+ MinVersion: cfg.MinVersion,
+ MaxVersion: cfg.MaxVersion,
+ CurvePreferences: cfg.CurvePreferences,
+ }
+}
+
+// cloneTLSClientConfig is like cloneTLSConfig but omits
+// the fields SessionTicketsDisabled and SessionTicketKey.
+// This makes it safe to call cloneTLSClientConfig on a config
+// in active use by a server.
+func cloneTLSClientConfig(cfg *tls.Config) *tls.Config {
+ if cfg == nil {
+ return &tls.Config{}
+ }
+ return &tls.Config{
+ Rand: cfg.Rand,
+ Time: cfg.Time,
+ Certificates: cfg.Certificates,
+ NameToCertificate: cfg.NameToCertificate,
+ GetCertificate: cfg.GetCertificate,
+ RootCAs: cfg.RootCAs,
+ NextProtos: cfg.NextProtos,
+ ServerName: cfg.ServerName,
+ ClientAuth: cfg.ClientAuth,
+ ClientCAs: cfg.ClientCAs,
+ InsecureSkipVerify: cfg.InsecureSkipVerify,
+ CipherSuites: cfg.CipherSuites,
+ PreferServerCipherSuites: cfg.PreferServerCipherSuites,
+ ClientSessionCache: cfg.ClientSessionCache,
+ MinVersion: cfg.MinVersion,
+ MaxVersion: cfg.MaxVersion,
+ CurvePreferences: cfg.CurvePreferences,
+ }
+}
diff --git a/src/net/lookup_test.go b/src/net/lookup_test.go
index a42ae29..86957b5 100644
--- a/src/net/lookup_test.go
+++ b/src/net/lookup_test.go
@@ -5,6 +5,7 @@
package net
import (
+ "bytes"
"fmt"
"strings"
"testing"
@@ -392,3 +393,111 @@
// happen due to issue 4856 for now.
t.Logf("%v succeeded, %v failed (%v timeout, %v temporary, %v other, %v unknown)", qstats.succeeded, qstats.failed, qstats.timeout, qstats.temporary, qstats.other, qstats.unknown)
}
+
+func TestLookupDots(t *testing.T) {
+ if testing.Short() || !*testExternal {
+ t.Skipf("skipping external network test")
+ }
+
+ fixup := forceGoDNS()
+ defer fixup()
+ testDots(t, "go")
+
+ if forceCgoDNS() {
+ testDots(t, "cgo")
+ }
+}
+
+func testDots(t *testing.T, mode string) {
+ names, err := LookupAddr("8.8.8.8") // Google dns server
+ if err != nil {
+ t.Errorf("LookupAddr(8.8.8.8): %v (mode=%v)", err, mode)
+ } else {
+ for _, name := range names {
+ if !strings.HasSuffix(name, ".google.com.") {
+ t.Errorf("LookupAddr(8.8.8.8) = %v, want names ending in .google.com. with trailing dot (mode=%v)", names, mode)
+ break
+ }
+ }
+ }
+
+ cname, err := LookupCNAME("www.mit.edu")
+ if err != nil || !strings.HasSuffix(cname, ".") {
+ t.Errorf("LookupCNAME(www.mit.edu) = %v, %v, want cname ending in . with trailing dot (mode=%v)", cname, err, mode)
+ }
+
+ mxs, err := LookupMX("google.com")
+ if err != nil {
+ t.Errorf("LookupMX(google.com): %v (mode=%v)", err, mode)
+ } else {
+ for _, mx := range mxs {
+ if !strings.HasSuffix(mx.Host, ".google.com.") {
+ t.Errorf("LookupMX(google.com) = %v, want names ending in .google.com. with trailing dot (mode=%v)", mxString(mxs), mode)
+ break
+ }
+ }
+ }
+
+ nss, err := LookupNS("google.com")
+ if err != nil {
+ t.Errorf("LookupNS(google.com): %v (mode=%v)", err, mode)
+ } else {
+ for _, ns := range nss {
+ if !strings.HasSuffix(ns.Host, ".google.com.") {
+ t.Errorf("LookupNS(google.com) = %v, want names ending in .google.com. with trailing dot (mode=%v)", nsString(nss), mode)
+ break
+ }
+ }
+ }
+
+ cname, srvs, err := LookupSRV("xmpp-server", "tcp", "google.com")
+ if err != nil {
+ t.Errorf("LookupSRV(xmpp-server, tcp, google.com): %v (mode=%v)", err, mode)
+ } else {
+ if !strings.HasSuffix(cname, ".google.com.") {
+ t.Errorf("LookupSRV(xmpp-server, tcp, google.com) returned cname=%v, want name ending in .google.com. with trailing dot (mode=%v)", cname, mode)
+ }
+ for _, srv := range srvs {
+ if !strings.HasSuffix(srv.Target, ".google.com.") {
+ t.Errorf("LookupSRV(xmpp-server, tcp, google.com) returned addrs=%v, want names ending in .google.com. with trailing dot (mode=%v)", srvString(srvs), mode)
+ break
+ }
+ }
+ }
+}
+
+func mxString(mxs []*MX) string {
+ var buf bytes.Buffer
+ sep := ""
+ fmt.Fprintf(&buf, "[")
+ for _, mx := range mxs {
+ fmt.Fprintf(&buf, "%s%s:%d", sep, mx.Host, mx.Pref)
+ sep = " "
+ }
+ fmt.Fprintf(&buf, "]")
+ return buf.String()
+}
+
+func nsString(nss []*NS) string {
+ var buf bytes.Buffer
+ sep := ""
+ fmt.Fprintf(&buf, "[")
+ for _, ns := range nss {
+ fmt.Fprintf(&buf, "%s%s", sep, ns.Host)
+ sep = " "
+ }
+ fmt.Fprintf(&buf, "]")
+ return buf.String()
+}
+
+func srvString(srvs []*SRV) string {
+ var buf bytes.Buffer
+ sep := ""
+ fmt.Fprintf(&buf, "[")
+ for _, srv := range srvs {
+ fmt.Fprintf(&buf, "%s%s:%d:%d:%d", sep, srv.Target, srv.Port, srv.Priority, srv.Weight)
+ sep = " "
+ }
+ fmt.Fprintf(&buf, "]")
+ return buf.String()
+}
diff --git a/src/net/lookup_unix.go b/src/net/lookup_unix.go
index 1c811d2..a64da8b 100644
--- a/src/net/lookup_unix.go
+++ b/src/net/lookup_unix.go
@@ -74,19 +74,21 @@
}
func lookupPort(network, service string) (int, error) {
- port, err, ok := cgoLookupPort(network, service)
- if !ok {
- port, err = goLookupPort(network, service)
+ if systemConf().canUseCgo() {
+ if port, err, ok := cgoLookupPort(network, service); ok {
+ return port, err
+ }
}
- return port, err
+ return goLookupPort(network, service)
}
func lookupCNAME(name string) (string, error) {
- cname, err, ok := cgoLookupCNAME(name)
- if !ok {
- cname, err = goLookupCNAME(name)
+ if systemConf().canUseCgo() {
+ if cname, err, ok := cgoLookupCNAME(name); ok {
+ return cname, err
+ }
}
- return cname, err
+ return goLookupCNAME(name)
}
func lookupSRV(service, proto, name string) (string, []*SRV, error) {
@@ -148,9 +150,10 @@
}
func lookupAddr(addr string) ([]string, error) {
- ptrs, err, ok := cgoLookupPTR(addr)
- if !ok {
- ptrs, err = goLookupPTR(addr)
+ if systemConf().canUseCgo() {
+ if ptrs, err, ok := cgoLookupPTR(addr); ok {
+ return ptrs, err
+ }
}
- return ptrs, err
+ return goLookupPTR(addr)
}
diff --git a/src/net/mail/message.go b/src/net/mail/message.go
index 8ddb313..266ac50 100644
--- a/src/net/mail/message.go
+++ b/src/net/mail/message.go
@@ -171,7 +171,14 @@
// Format address local@domain
at := strings.LastIndex(a.Address, "@")
- local, domain := a.Address[:at], a.Address[at+1:]
+ var local, domain string
+ if at < 0 {
+ // This is a malformed address ("@" is required in addr-spec);
+ // treat the whole address as local-part.
+ local = a.Address
+ } else {
+ local, domain = a.Address[:at], a.Address[at+1:]
+ }
// Add quotes if needed
// TODO: rendering quoted local part and rendering printable name
diff --git a/src/net/mail/message_test.go b/src/net/mail/message_test.go
index ffe9af9..1b42274 100644
--- a/src/net/mail/message_test.go
+++ b/src/net/mail/message_test.go
@@ -483,6 +483,14 @@
&Address{Name: "Böb Jacöb", Address: "bob@example.com"},
`=?utf-8?q?B=C3=B6b_Jac=C3=B6b?= <bob@example.com>`,
},
+ { // https://golang.org/issue/12098
+ &Address{Name: "Rob", Address: ""},
+ `"Rob" <@>`,
+ },
+ { // https://golang.org/issue/12098
+ &Address{Name: "Rob", Address: "@"},
+ `"Rob" <@>`,
+ },
}
for _, test := range tests {
s := test.addr.String()
diff --git a/src/net/net.go b/src/net/net.go
index 75510a2..6e84c3a 100644
--- a/src/net/net.go
+++ b/src/net/net.go
@@ -35,6 +35,46 @@
}
go handleConnection(conn)
}
+
+Name Resolution
+
+The method for resolving domain names, whether indirectly with functions like Dial
+or directly with functions like LookupHost and LookupAddr, varies by operating system.
+
+On Unix systems, the resolver has two options for resolving names.
+It can use a pure Go resolver that sends DNS requests directly to the servers
+listed in /etc/resolv.conf, or it can use a cgo-based resolver that calls C
+library routines such as getaddrinfo and getnameinfo.
+
+By default the pure Go resolver is used, because a blocked DNS request consumes
+only a goroutine, while a blocked C call consumes an operating system thread.
+When cgo is available, the cgo-based resolver is used instead under a variety of
+conditions: on systems that do not let programs make direct DNS requests (OS X),
+when the LOCALDOMAIN environment variable is present (even if empty),
+when the RES_OPTIONS or HOSTALIASES environment variable is non-empty,
+when the ASR_CONFIG environment variable is non-empty (OpenBSD only),
+when /etc/resolv.conf or /etc/nsswitch.conf specify the use of features that the
+Go resolver does not implement, and when the name being looked up ends in .local
+or is an mDNS name.
+
+The resolver decision can be overridden by setting the netdns value of the
+GODEBUG environment variable (see package runtime) to go or cgo, as in:
+
+ export GODEBUG=netdns=go # force pure Go resolver
+ export GODEBUG=netdns=cgo # force cgo resolver
+
+The decision can also be forced while building the Go source tree
+by setting the netgo or netcgo build tag.
+
+A numeric netdns setting, as in GODEBUG=netdns=1, causes the resolver
+to print debugging information about its decisions.
+To force a particular resolver while also printing debugging information,
+join the two settings by a plus sign, as in GODEBUG=netdns=go+1.
+
+On Plan 9, the resolver always accesses /net/cs and /net/dns.
+
+On Windows, the resolver always uses C library functions, such as GetAddrInfo and DnsQuery.
+
*/
package net
diff --git a/src/net/non_unix_test.go b/src/net/non_unix_test.go
new file mode 100644
index 0000000..eddca56
--- /dev/null
+++ b/src/net/non_unix_test.go
@@ -0,0 +1,11 @@
+// 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 nacl plan9 windows
+
+package net
+
+// See unix_test.go for what these (don't) do.
+func forceGoDNS() func() { return func() {} }
+func forceCgoDNS() bool { return false }
diff --git a/src/net/unix_test.go b/src/net/unix_test.go
index 59f5c2d..358ff31 100644
--- a/src/net/unix_test.go
+++ b/src/net/unix_test.go
@@ -404,3 +404,28 @@
}
}
}
+
+// forceGoDNS forces the resolver configuration to use the pure Go resolver
+// and returns a fixup function to restore the old settings.
+func forceGoDNS() func() {
+ c := systemConf()
+ oldGo := c.netGo
+ oldCgo := c.netCgo
+ fixup := func() {
+ c.netGo = oldGo
+ c.netCgo = oldCgo
+ }
+ c.netGo = true
+ c.netCgo = false
+ return fixup
+}
+
+// forceCgoDNS forces the resolver configuration to use the cgo resolver
+// and returns true to indicate that it did so.
+// (On non-Unix systems forceCgoDNS returns false.)
+func forceCgoDNS() bool {
+ c := systemConf()
+ c.netGo = false
+ c.netCgo = true
+ return true
+}
diff --git a/src/runtime/asm_arm.s b/src/runtime/asm_arm.s
index 91dccdc..9c32e42 100644
--- a/src/runtime/asm_arm.s
+++ b/src/runtime/asm_arm.s
@@ -752,6 +752,8 @@
B runtime·atomicstore(SB)
// armPublicationBarrier is a native store/store barrier for ARMv7+.
+// On earlier ARM revisions, armPublicationBarrier is a no-op.
+// This will not work on SMP ARMv6 machines, if any are in use.
// To implement publiationBarrier in sys_$GOOS_arm.s using the native
// instructions, use:
//
@@ -759,6 +761,9 @@
// B runtime·armPublicationBarrier(SB)
//
TEXT runtime·armPublicationBarrier(SB),NOSPLIT,$-4-0
+ MOVB runtime·goarm(SB), R11
+ CMP $7, R11
+ BLT 2(PC)
WORD $0xf57ff05e // DMB ST
RET
diff --git a/src/runtime/mbitmap.go b/src/runtime/mbitmap.go
index c439158..fd6b4b1 100644
--- a/src/runtime/mbitmap.go
+++ b/src/runtime/mbitmap.go
@@ -109,6 +109,9 @@
// subtract1 returns the byte pointer p-1.
//go:nowritebarrier
+//
+// nosplit because it is used during write barriers and must not be preempted.
+//go:nosplit
func subtract1(p *byte) *byte {
// Note: wrote out full expression instead of calling subtractb(p, 1)
// to reduce the number of temporaries generated by the
@@ -245,6 +248,9 @@
// next returns the heapBits describing the next pointer-sized word in memory.
// That is, if h describes address p, h.next() describes p+ptrSize.
// Note that next does not modify h. The caller must record the result.
+//
+// nosplit because it is used during write barriers and must not be preempted.
+//go:nosplit
func (h heapBits) next() heapBits {
if h.shift < 3*heapBitsShift {
return heapBits{h.bitp, h.shift + heapBitsShift}
@@ -293,6 +299,9 @@
// isPointer reports whether the heap bits describe a pointer word.
// h must describe the initial word of the object.
+//
+// nosplit because it is used during write barriers and must not be preempted.
+//go:nosplit
func (h heapBits) isPointer() bool {
return (*h.bitp>>h.shift)&bitPointer != 0
}
diff --git a/src/runtime/os1_darwin.go b/src/runtime/os1_darwin.go
index 08ec611..e070229 100644
--- a/src/runtime/os1_darwin.go
+++ b/src/runtime/os1_darwin.go
@@ -34,14 +34,19 @@
// bsdthread_register delayed until end of goenvs so that we
// can look at the environment first.
+ ncpu = getncpu()
+}
+
+func getncpu() int32 {
// Use sysctl to fetch hw.ncpu.
mib := [2]uint32{6, 3}
out := uint32(0)
nout := unsafe.Sizeof(out)
ret := sysctl(&mib[0], 2, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
- if ret >= 0 {
- ncpu = int32(out)
+ if ret >= 0 && int32(out) > 0 {
+ return int32(out)
}
+ return 1
}
var urandom_dev = []byte("/dev/urandom\x00")
diff --git a/src/runtime/os_darwin_arm.go b/src/runtime/os_darwin_arm.go
index d3336c0..1ccc959 100644
--- a/src/runtime/os_darwin_arm.go
+++ b/src/runtime/os_darwin_arm.go
@@ -5,7 +5,14 @@
package runtime
func checkgoarm() {
- return // TODO(minux)
+ // TODO(minux): FP checks like in os_linux_arm.go.
+
+ // osinit not called yet, so ncpu not set: must use getncpu directly.
+ if getncpu() > 1 && goarm < 7 {
+ print("runtime: this system has multiple CPUs and must use\n")
+ print("atomic synchronization instructions. Recompile using GOARM=7.\n")
+ exit(1)
+ }
}
//go:nosplit
diff --git a/src/runtime/os_freebsd_arm.go b/src/runtime/os_freebsd_arm.go
index e049cbf..1f2add2 100644
--- a/src/runtime/os_freebsd_arm.go
+++ b/src/runtime/os_freebsd_arm.go
@@ -5,7 +5,14 @@
package runtime
func checkgoarm() {
- // TODO(minux)
+ // TODO(minux): FP checks like in os_linux_arm.go.
+
+ // osinit not called yet, so ncpu not set: must use getncpu directly.
+ if getncpu() > 1 && goarm < 7 {
+ print("runtime: this system has multiple CPUs and must use\n")
+ print("atomic synchronization instructions. Recompile using GOARM=7.\n")
+ exit(1)
+ }
}
//go:nosplit
diff --git a/src/runtime/os_linux_arm.go b/src/runtime/os_linux_arm.go
index 6c74c81..3749640 100644
--- a/src/runtime/os_linux_arm.go
+++ b/src/runtime/os_linux_arm.go
@@ -19,7 +19,6 @@
var randomNumber uint32
var armArch uint8 = 6 // we default to ARMv6
var hwcap uint32 // set by setup_auxv
-var goarm uint8 // set by 5l
func checkgoarm() {
if goarm > 5 && hwcap&_HWCAP_VFP == 0 {
diff --git a/src/runtime/os_nacl_arm.go b/src/runtime/os_nacl_arm.go
index a43e7c4..f94c183 100644
--- a/src/runtime/os_nacl_arm.go
+++ b/src/runtime/os_nacl_arm.go
@@ -5,7 +5,13 @@
package runtime
func checkgoarm() {
- return // NaCl/ARM only supports ARMv7
+ // TODO(minux): FP checks like in os_linux_arm.go.
+
+ // NaCl/ARM only supports ARMv7
+ if goarm != 7 {
+ print("runtime: NaCl requires ARMv7. Recompile using GOARM=7.\n")
+ exit(1)
+ }
}
//go:nosplit
diff --git a/src/runtime/os_netbsd_arm.go b/src/runtime/os_netbsd_arm.go
index 83c4c06..03032e8 100644
--- a/src/runtime/os_netbsd_arm.go
+++ b/src/runtime/os_netbsd_arm.go
@@ -16,7 +16,14 @@
}
func checkgoarm() {
- // TODO(minux)
+ // TODO(minux): FP checks like in os_linux_arm.go.
+
+ // osinit not called yet, so ncpu not set: must use getncpu directly.
+ if getncpu() > 1 && goarm < 7 {
+ print("runtime: this system has multiple CPUs and must use\n")
+ print("atomic synchronization instructions. Recompile using GOARM=7.\n")
+ exit(1)
+ }
}
//go:nosplit
diff --git a/src/runtime/os_openbsd_arm.go b/src/runtime/os_openbsd_arm.go
index be3f330..b46fef0 100644
--- a/src/runtime/os_openbsd_arm.go
+++ b/src/runtime/os_openbsd_arm.go
@@ -5,7 +5,14 @@
package runtime
func checkgoarm() {
- // TODO(minux)
+ // TODO(minux): FP checks like in os_linux_arm.go.
+
+ // osinit not called yet, so ncpu not set: must use getncpu directly.
+ if getncpu() > 1 && goarm < 7 {
+ print("runtime: this system has multiple CPUs and must use\n")
+ print("atomic synchronization instructions. Recompile using GOARM=7.\n")
+ exit(1)
+ }
}
//go:nosplit
diff --git a/src/runtime/panic.go b/src/runtime/panic.go
index c8158b9..a166281 100644
--- a/src/runtime/panic.go
+++ b/src/runtime/panic.go
@@ -327,7 +327,7 @@
freedefer(d)
// Note: we ignore recovers here because Goexit isn't a panic
}
- goexit()
+ goexit1()
}
// Print all currently active panics. Used when crashing.
diff --git a/src/runtime/proc1.go b/src/runtime/proc1.go
index 23beaf5..09cb775 100644
--- a/src/runtime/proc1.go
+++ b/src/runtime/proc1.go
@@ -1348,7 +1348,23 @@
// GoSysExit has to happen when we have a P, but before GoStart.
// So we emit it here.
if gp.syscallsp != 0 && gp.sysblocktraced {
- traceGoSysExit(gp.sysexitseq, gp.sysexitticks)
+ // Since gp.sysblocktraced is true, we must emit an event.
+ // There is a race between the code that initializes sysexitseq
+ // and sysexitticks (in exitsyscall, which runs without a P,
+ // and therefore is not stopped with the rest of the world)
+ // and the code that initializes a new trace.
+ // The recorded sysexitseq and sysexitticks must therefore
+ // be treated as "best effort". If they are valid for this trace,
+ // then great, use them for greater accuracy.
+ // But if they're not valid for this trace, assume that the
+ // trace was started after the actual syscall exit (but before
+ // we actually managed to start the goroutine, aka right now),
+ // and assign a fresh time stamp to keep the log consistent.
+ seq, ts := gp.sysexitseq, gp.sysexitticks
+ if seq == 0 || int64(seq)-int64(trace.seqStart) < 0 {
+ seq, ts = tracestamp()
+ }
+ traceGoSysExit(seq, ts)
}
traceGoStart()
}
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index a157f01..57cd869 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -645,6 +645,8 @@
cpuid_ecx uint32
cpuid_edx uint32
lfenceBeforeRdtsc bool
+
+ goarm uint8 // set by cmd/link on arm systems
)
// Set by the linker so the runtime can determine the buildmode.
diff --git a/src/runtime/stubs.go b/src/runtime/stubs.go
index e6b0156..d725bb1 100644
--- a/src/runtime/stubs.go
+++ b/src/runtime/stubs.go
@@ -128,7 +128,20 @@
func reflectcall(argtype *_type, fn, arg unsafe.Pointer, argsize uint32, retoffset uint32)
func procyield(cycles uint32)
-func goexit()
+
+type neverCallThisFunction struct{}
+
+// goexit is the return stub at the top of every goroutine call stack.
+// Each goroutine stack is constructed as if goexit called the
+// goroutine's entry point function, so that when the entry point
+// function returns, it will return to goexit, which will call goexit1
+// to perform the actual exit.
+//
+// This function must never be called directly. Call goexit1 instead.
+// gentraceback assumes that goexit terminates the stack. A direct
+// call on the stack will cause gentraceback to stop walking the stack
+// prematurely and if there are leftover stack barriers it may panic.
+func goexit(neverCallThisFunction)
// Not all cgocallback_gofunc frames are actually cgocallback_gofunc,
// so not all have these arguments. Mark them uintptr so that the GC
diff --git a/src/sort/sort.go b/src/sort/sort.go
index 0a446c8..c7c3042 100644
--- a/src/sort/sort.go
+++ b/src/sort/sort.go
@@ -300,7 +300,7 @@
// V. Raman in Algorithmica (1996) 16, 115-160:
// This algorithm either needs additional 2n bits or works only if there
// are enough different elements available to encode some permutations
-// which have to be undone later (so not stable an any input).
+// which have to be undone later (so not stable on any input).
// - All the optimal in-place sorting/merging algorithms I found are either
// unstable or rely on enough different elements in each step to encode the
// performed block rearrangements. See also "In-Place Merging Algorithms",
diff --git a/test/fixedbugs/issue12133.go b/test/fixedbugs/issue12133.go
new file mode 100644
index 0000000..0b66c56
--- /dev/null
+++ b/test/fixedbugs/issue12133.go
@@ -0,0 +1,26 @@
+// run
+
+// 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.
+
+// Issue 12133. The CX register was getting clobbered
+// because we did not keep track of its allocation correctly.
+
+package main
+
+import "fmt"
+
+func main() {
+ want := uint(48)
+ got := f1(48)
+ if got != want {
+ fmt.Println("got", got, ", wanted", want)
+ panic("bad")
+ }
+}
+func f1(v1 uint) uint {
+ switch {
+ } // prevent inlining
+ return v1 >> ((1 >> v1) + (1 >> v1))
+}