From 839657a730bd3c82d1b7932f996dd87448eb7d38 Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Sat, 2 May 2015 10:02:54 -0600 Subject: Imported Upstream version 1.4.2 --- VERSION | 2 +- doc/devel/release.html | 5 +++++ src/cmd/5g/cgen.c | 11 +++++----- src/cmd/gc/align.c | 5 +++++ src/cmd/gc/go.h | 1 + src/cmd/gc/inl.c | 9 +++++--- src/cmd/gc/subr.c | 9 ++++++++ src/cmd/gc/typecheck.c | 2 +- src/cmd/go/doc.go | 1 + src/cmd/go/generate.go | 5 +++++ src/cmd/go/generate_test.go | 6 ++++++ src/math/big/int.go | 2 +- src/math/big/int_test.go | 1 + src/runtime/mgc0.c | 3 +++ src/runtime/syscall_windows.go | 10 +++++---- src/runtime/syscall_windows_test.go | 8 +++++++ test/fixedbugs/issue9432.go | 15 +++++++++++++ test/fixedbugs/issue9537.dir/a.go | 25 +++++++++++++++++++++ test/fixedbugs/issue9537.dir/b.go | 43 +++++++++++++++++++++++++++++++++++++ test/fixedbugs/issue9537.go | 10 +++++++++ test/fixedbugs/issue9604.go | 29 +++++++++++++++++++++++++ test/fixedbugs/issue9634.go | 18 ++++++++++++++++ 22 files changed, 204 insertions(+), 16 deletions(-) create mode 100644 test/fixedbugs/issue9432.go create mode 100644 test/fixedbugs/issue9537.dir/a.go create mode 100644 test/fixedbugs/issue9537.dir/b.go create mode 100644 test/fixedbugs/issue9537.go create mode 100644 test/fixedbugs/issue9604.go create mode 100644 test/fixedbugs/issue9634.go diff --git a/VERSION b/VERSION index 9fcdb2c51..bcab27e8d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -go1.4.1 \ No newline at end of file +go1.4.2 \ No newline at end of file diff --git a/doc/devel/release.html b/doc/devel/release.html index 6e69ce70e..5a1a747da 100644 --- a/doc/devel/release.html +++ b/doc/devel/release.html @@ -26,6 +26,11 @@ go1.4.1 (released 2015/01/15) includes bug fixes to the linker and the log See the Go 1.4.1 milestone on our issue tracker for details.

+

+go1.4.2 (released 2015/02/17) includes bug fixes to the go command, the compiler and linker, and the runtime, syscall, reflect, and math/big packages. +See the Go 1.4.2 milestone on our issue tracker for details. +

+

go1.3 (released 2014/06/18)

diff --git a/src/cmd/5g/cgen.c b/src/cmd/5g/cgen.c index c535cfbef..87c64f6e8 100644 --- a/src/cmd/5g/cgen.c +++ b/src/cmd/5g/cgen.c @@ -236,18 +236,14 @@ cgen(Node *n, Node *res) cgen(nl, &n1); nodconst(&n2, nl->type, -1); gins(a, &n2, &n1); - gmove(&n1, res); - regfree(&n1); - goto ret; + goto norm; case OMINUS: regalloc(&n1, nl->type, N); cgen(nl, &n1); nodconst(&n2, nl->type, 0); gins(optoas(OMINUS, nl->type), &n2, &n1); - gmove(&n1, res); - regfree(&n1); - goto ret; + goto norm; // symmetric binary case OAND: @@ -483,12 +479,15 @@ abop: // asymmetric binary cgen(nl, &n1); } gins(a, &n2, &n1); +norm: // Normalize result for types smaller than word. if(n->type->width < widthptr) { switch(n->op) { case OADD: case OSUB: case OMUL: + case OCOM: + case OMINUS: gins(optoas(OAS, n->type), &n1, &n1); break; } diff --git a/src/cmd/gc/align.c b/src/cmd/gc/align.c index 6e5d149c7..63ed2e5af 100644 --- a/src/cmd/gc/align.c +++ b/src/cmd/gc/align.c @@ -128,6 +128,11 @@ dowidth(Type *t) return; } + // break infinite recursion if the broken recursive type + // is referenced again + if(t->broke && t->width == 0) + return; + // defer checkwidth calls until after we're done defercalc++; diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 965a0550d..bbb883513 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -974,6 +974,7 @@ EXTERN int funcdepth; EXTERN int typecheckok; EXTERN int compiling_runtime; EXTERN int compiling_wrappers; +EXTERN int inl_nonlocal; EXTERN int use_writebarrier; EXTERN int pure_go; EXTERN char* flag_installsuffix; diff --git a/src/cmd/gc/inl.c b/src/cmd/gc/inl.c index cf89b0090..45e15bb9b 100644 --- a/src/cmd/gc/inl.c +++ b/src/cmd/gc/inl.c @@ -804,9 +804,12 @@ inlvar(Node *var) n->curfn = curfn; // the calling function, not the called one n->addrtaken = var->addrtaken; - // esc pass wont run if we're inlining into a iface wrapper - // luckily, we can steal the results from the target func - if(var->esc == EscHeap) + // Esc pass wont run if we're inlining into a iface wrapper. + // Luckily, we can steal the results from the target func. + // If inlining a function defined in another package after + // escape analysis is done, treat all local vars as escaping. + // See issue 9537. + if(var->esc == EscHeap || (inl_nonlocal && var->op == ONAME)) addrescapes(n); curfn->dcl = list(curfn->dcl, n); diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index c3bc5af3b..26153d39b 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -2614,7 +2614,16 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface) fn->dupok = 1; typecheck(&fn, Etop); typechecklist(fn->nbody, Etop); + + // Set inl_nonlocal to whether we are calling a method on a + // type defined in a different package. Checked in inlvar. + if(!methodrcvr->local) + inl_nonlocal = 1; + inlcalls(fn); + + inl_nonlocal = 0; + curfn = nil; funccompile(fn, 0); } diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c index 714c66268..ce12f150a 100644 --- a/src/cmd/gc/typecheck.c +++ b/src/cmd/gc/typecheck.c @@ -1335,7 +1335,7 @@ reswitch: goto error; // Unpack multiple-return result before type-checking. - if(istype(t, TSTRUCT)) { + if(istype(t, TSTRUCT) && t->funarg) { t = t->type; if(istype(t, TFIELD)) t = t->type; diff --git a/src/cmd/go/doc.go b/src/cmd/go/doc.go index d0d8a8a5b..7191ee0f3 100644 --- a/src/cmd/go/doc.go +++ b/src/cmd/go/doc.go @@ -308,6 +308,7 @@ The generator is run in the package's source directory. Go generate accepts one specific flag: -run="" + TODO: This flag is unimplemented. if non-empty, specifies a regular expression to select directives whose command matches the expression. diff --git a/src/cmd/go/generate.go b/src/cmd/go/generate.go index baf4d2b55..3c0af8760 100644 --- a/src/cmd/go/generate.go +++ b/src/cmd/go/generate.go @@ -106,6 +106,7 @@ The generator is run in the package's source directory. Go generate accepts one specific flag: -run="" + TODO: This flag is unimplemented. if non-empty, specifies a regular expression to select directives whose command matches the expression. @@ -255,6 +256,10 @@ func (g *Generator) split(line string) []string { // Parse line, obeying quoted strings. var words []string line = line[len("//go:generate ") : len(line)-1] // Drop preamble and final newline. + // There may still be a carriage return. + if len(line) > 0 && line[len(line)-1] == '\r' { + line = line[:len(line)-1] + } // One (possibly quoted) word per iteration. Words: for { diff --git a/src/cmd/go/generate_test.go b/src/cmd/go/generate_test.go index 660ebabbe..2ec548630 100644 --- a/src/cmd/go/generate_test.go +++ b/src/cmd/go/generate_test.go @@ -40,9 +40,15 @@ func TestGenerateCommandParse(t *testing.T) { } g.setShorthand([]string{"-command", "yacc", "go", "tool", "yacc"}) for _, test := range splitTests { + // First with newlines. got := g.split("//go:generate " + test.in + "\n") if !reflect.DeepEqual(got, test.out) { t.Errorf("split(%q): got %q expected %q", test.in, got, test.out) } + // Then with CRLFs, thank you Windows. + got = g.split("//go:generate " + test.in + "\r\n") + if !reflect.DeepEqual(got, test.out) { + t.Errorf("split(%q): got %q expected %q", test.in, got, test.out) + } } } diff --git a/src/math/big/int.go b/src/math/big/int.go index d22e39e7c..ade5c2fc8 100644 --- a/src/math/big/int.go +++ b/src/math/big/int.go @@ -887,7 +887,7 @@ func (z *Int) AndNot(x, y *Int) *Int { } // x &^ (-y) == x &^ ^(y-1) == x & (y-1) - y1 := nat(nil).add(y.abs, natOne) + y1 := nat(nil).sub(y.abs, natOne) z.abs = z.abs.and(x.abs, y1) z.neg = false return z diff --git a/src/math/big/int_test.go b/src/math/big/int_test.go index 6070cf325..2d762dbc8 100644 --- a/src/math/big/int_test.go +++ b/src/math/big/int_test.go @@ -1201,6 +1201,7 @@ var bitwiseTests = []struct { {"-0x01", "-0x01", "-0x01", "-0x01", "0x00", "0x00"}, {"0x07", "0x08", "0x00", "0x0f", "0x0f", "0x07"}, {"0x05", "0x0f", "0x05", "0x0f", "0x0a", "0x00"}, + {"0xff", "-0x0a", "0xf6", "-0x01", "-0xf7", "0x09"}, {"0x013ff6", "0x9a4e", "0x1a46", "0x01bffe", "0x01a5b8", "0x0125b0"}, {"-0x013ff6", "0x9a4e", "0x800a", "-0x0125b2", "-0x01a5bc", "-0x01c000"}, {"-0x013ff6", "-0x9a4e", "-0x01bffe", "-0x1a46", "0x01a5b8", "0x8008"}, diff --git a/src/runtime/mgc0.c b/src/runtime/mgc0.c index 7754bad89..083beec22 100644 --- a/src/runtime/mgc0.c +++ b/src/runtime/mgc0.c @@ -350,6 +350,9 @@ scanblock(byte *b, uintptr n, byte *ptrmask) x -= (uintptr)arena_start>>PageShift; s = runtime·mheap.spans[x]; if(s == nil || k < s->start || obj >= s->limit || s->state != MSpanInUse) { + // Sometimes 32-bit heaps have holes. See issue 9872 + if(PtrSize == 4 && s == nil) + continue; // Stack pointers lie within the arena bounds but are not part of the GC heap. // Ignore them. if(s != nil && s->state == MSpanStack) diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go index 5b76ad573..51004b78a 100644 --- a/src/runtime/syscall_windows.go +++ b/src/runtime/syscall_windows.go @@ -54,11 +54,13 @@ func compileCallback(fn eface, cleanstack bool) (code uintptr) { panic("compilecallback: output parameter size is wrong") } argsize := uintptr(0) - for _, t := range (*[1024](*_type))(unsafe.Pointer(&ft.in[0]))[:len(ft.in)] { - if (*t).size > uintptrSize { - panic("compilecallback: input parameter size is wrong") + if len(ft.in) > 0 { + for _, t := range (*[1024](*_type))(unsafe.Pointer(&ft.in[0]))[:len(ft.in)] { + if (*t).size > uintptrSize { + panic("compilecallback: input parameter size is wrong") + } + argsize += uintptrSize } - argsize += uintptrSize } lock(&cbs.lock) diff --git a/src/runtime/syscall_windows_test.go b/src/runtime/syscall_windows_test.go index ce8a9ec1b..126bef62e 100644 --- a/src/runtime/syscall_windows_test.go +++ b/src/runtime/syscall_windows_test.go @@ -533,3 +533,11 @@ func main() { println(z) } ` + +func TestCallbackWithNoInputParameters(t *testing.T) { + // Test that NewCallback and NewCallbackCDecl can accept functions without + // input parameters, see issue 9871. + cb := func() uintptr { return 0 } + _ = syscall.NewCallback(cb) + _ = syscall.NewCallbackCDecl(cb) +} diff --git a/test/fixedbugs/issue9432.go b/test/fixedbugs/issue9432.go new file mode 100644 index 000000000..0d0bc960f --- /dev/null +++ b/test/fixedbugs/issue9432.go @@ -0,0 +1,15 @@ +// errorcheck + +// Copyright 2014 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. + +// gc used to recurse infinitely when dowidth is applied +// to a broken recursive type again. +// See golang.org/issue/9432. +package p + +type foo struct { // GCCGO_ERROR "invalid recursive type" + bar foo + blah foo +} // ERROR "invalid recursive type foo" diff --git a/test/fixedbugs/issue9537.dir/a.go b/test/fixedbugs/issue9537.dir/a.go new file mode 100644 index 000000000..818c9eb4a --- /dev/null +++ b/test/fixedbugs/issue9537.dir/a.go @@ -0,0 +1,25 @@ +// 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 a + +type X struct { + T [32]byte +} + +func (x *X) Get() []byte { + t := x.T + return t[:] +} + +func (x *X) RetPtr(i int) *int { + i++ + return &i +} + +func (x *X) RetRPtr(i int) (r1 int, r2 *int) { + r1 = i + 1 + r2 = &r1 + return +} diff --git a/test/fixedbugs/issue9537.dir/b.go b/test/fixedbugs/issue9537.dir/b.go new file mode 100644 index 000000000..52e64c81f --- /dev/null +++ b/test/fixedbugs/issue9537.dir/b.go @@ -0,0 +1,43 @@ +// 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 main + +import ( + "bytes" + + "./a" +) + +type X struct { + *a.X +} + +type Intf interface { + Get() []byte + RetPtr(int) *int + RetRPtr(int) (int, *int) +} + +func main() { + x := &a.X{T: [32]byte{1, 2, 3, 4}} + var ix Intf = X{x} + t1 := ix.Get() + t2 := x.Get() + if !bytes.Equal(t1, t2) { + panic(t1) + } + + p1 := ix.RetPtr(5) + p2 := x.RetPtr(7) + if *p1 != 6 || *p2 != 8 { + panic(*p1) + } + + r1, r2 := ix.RetRPtr(10) + r3, r4 := x.RetRPtr(13) + if r1 != 11 || *r2 != 11 || r3 != 14 || *r4 != 14 { + panic("bad RetRPtr") + } +} diff --git a/test/fixedbugs/issue9537.go b/test/fixedbugs/issue9537.go new file mode 100644 index 000000000..ac2d41b12 --- /dev/null +++ b/test/fixedbugs/issue9537.go @@ -0,0 +1,10 @@ +// rundir + +// 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 9537: Compiler does not run escape analysis on an inlined +// generated method wrapper. + +package ignored diff --git a/test/fixedbugs/issue9604.go b/test/fixedbugs/issue9604.go new file mode 100644 index 000000000..cd9e9e49e --- /dev/null +++ b/test/fixedbugs/issue9604.go @@ -0,0 +1,29 @@ +// 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. + +package main + +var x uint16 = 0xffff +var y uint16 = 0xfffe +var a uint16 = 0x7000 +var b uint16 = 0x9000 + +func main() { + // Make sure we truncate to smaller-width types after evaluating expressions. + // This is a problem for arm where there is no 16-bit comparison op. + if ^x != 0 { + panic("^uint16(0xffff) != 0") + } + if ^y != 1 { + panic("^uint16(0xfffe) != 1") + } + if -x != 1 { + panic("-uint16(0xffff) != 1") + } + if a+b != 0 { + panic("0x7000+0x9000 != 0") + } +} diff --git a/test/fixedbugs/issue9634.go b/test/fixedbugs/issue9634.go new file mode 100644 index 000000000..2d5aae4a3 --- /dev/null +++ b/test/fixedbugs/issue9634.go @@ -0,0 +1,18 @@ +// errorcheck + +// 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 9634: Structs are incorrectly unpacked when passed as an argument +// to append. + +package main + +func main() { + s := struct{ + t []int + u int + }{} + _ = append(s, 0) // ERROR "must be a slice|must be slice" +} -- cgit v1.2.3