diff options
author | Michael Stapelberg <stapelberg@debian.org> | 2013-12-03 09:43:15 +0100 |
---|---|---|
committer | Michael Stapelberg <stapelberg@debian.org> | 2013-12-03 09:43:15 +0100 |
commit | 64d2a7c8945ba05af859901f5e248f1befdd8621 (patch) | |
tree | 013fcb7e9e3296ecdda876012252c36bd6bcb063 /test | |
parent | b901efe83e212f0c34c769c079e41373da12d723 (diff) | |
download | golang-64d2a7c8945ba05af859901f5e248f1befdd8621.tar.gz |
Imported Upstream version 1.2upstream/1.2
Diffstat (limited to 'test')
99 files changed, 3101 insertions, 367 deletions
diff --git a/test/bench/shootout/timing.log b/test/bench/shootout/timing.log index ee1f889b4..4e7d17a11 100644 --- a/test/bench/shootout/timing.log +++ b/test/bench/shootout/timing.log @@ -1161,3 +1161,94 @@ chameneos 6000000 gccgo -O2 chameneosredux.go 11.28u 6.68s 18.00r gc chameneosredux 6.94u 0.00s 6.96r +# May 23, 2013 +# Go 1.1, which includes precise GC, new scheduler, faster maps. +# 20%-ish speedups across many benchmarks. +# gccgo showing significant improvement (even though it's not yet up to Go 1.1) +# +# Standouts: +# fannkuch, regex-dna, k-nucleotide, threadring, chameneos + +fasta -n 25000000 + gcc -m64 -O2 fasta.c 1.54u 0.01s 1.55r + gccgo -O2 fasta.go 1.42u 0.00s 1.43r + gc fasta 1.50u 0.01s 1.52r # -16% + gc_B fasta 1.46u 0.00s 1.46r # -17% + +reverse-complement < output-of-fasta-25000000 + gcc -m64 -O2 reverse-complement.c 0.87u 0.37s 4.36r + gccgo -O2 reverse-complement.go 0.77u 0.15s 0.93r # -15% + gc reverse-complement 0.99u 0.12s 1.12r # -15% + gc_B reverse-complement 0.85u 0.17s 1.02r # -21% + +nbody -n 50000000 + gcc -m64 -O2 nbody.c -lm 13.50u 0.00s 13.53r + gccgo -O2 nbody.go 13.98u 0.01s 14.02r + gc nbody 16.63u 0.01s 16.67r + gc_B nbody 15.74u 0.00s 15.76r + +binary-tree 15 # too slow to use 20 + gcc -m64 -O2 binary-tree.c -lm 0.61u 0.00s 0.61r + gccgo -O2 binary-tree.go 1.11u 0.01s 1.12r # -13% + gccgo -O2 binary-tree-freelist.go 0.22u 0.01s 0.23r + gc binary-tree 1.83u 0.02s 1.83r # -7% + gc binary-tree-freelist 0.32u 0.00s 0.32r + +fannkuch 12 + gcc -m64 -O2 fannkuch.c 45.56u 0.00s 45.67r + gccgo -O2 fannkuch.go 57.71u 0.00s 57.85r # -4% + gccgo -O2 fannkuch-parallel.go 146.31u 0.00s 37.50r #-37% + gc fannkuch 70.06u 0.03s 70.17r # -3% + gc fannkuch-parallel 131.88u 0.06s 33.59r # -23% + gc_B fannkuch 45.55u 0.02s 45.63r # -15% + +regex-dna 100000 + gcc -m64 -O2 regex-dna.c -lpcre 0.44u 0.01s 0.45r + gccgo -O2 regex-dna.go 5.59u 0.00s 5.61r # -14% + gccgo -O2 regex-dna-parallel.go 10.85u 0.30s 3.34r # -24% + gc regex-dna 2.23u 0.01s 2.25r # -43% + gc regex-dna-parallel 2.35u 0.00s 0.93r # -40% + gc_B regex-dna 2.24u 0.01s 2.25r # -43% + +spectral-norm 5500 + gcc -m64 -O2 spectral-norm.c -lm 14.84u 0.00s 14.88r + gccgo -O2 spectral-norm.go 15.33u 0.00s 15.37r + gc spectral-norm 16.75u 0.02s 16.79r # -15% + gc_B spectral-norm 16.77u 0.01s 16.79r # -15% + +k-nucleotide 1000000 + gcc -O2 k-nucleotide.c -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lglib-2.0 4.50u 0.00s 4.52r + gccgo -O2 k-nucleotide.go 3.72u 0.04s 3.77r # -21% + gccgo -O2 k-nucleotide-parallel.go 3.88u 0.03s 1.42r # -35% + gc k-nucleotide 6.32u 0.01s 6.33r # -31% + gc k-nucleotide-parallel 6.47u 0.05s 2.13r # -33% + gc_B k-nucleotide 6.45u 0.01s 6.47r # - 28% + +mandelbrot 16000 + gcc -m64 -O2 mandelbrot.c 36.03u 0.00s 36.11r + gccgo -O2 mandelbrot.go 37.61u 0.00s 37.74r # -14% + gc mandelbrot 38.19u 0.05s 38.29r + gc_B mandelbrot 38.19u 0.03s 38.26r + +meteor 2098 + gcc -m64 -O2 meteor-contest.c 0.08u 0.00s 0.08r + gccgo -O2 meteor-contest.go 0.09u 0.01s 0.10r + gc meteor-contest 0.12u 0.00s 0.12r # -15% although perhaps just noise + gc_B meteor-contest 0.11u 0.00s 0.12r # -8% although perhaps just noise + +pidigits 10000 + gcc -m64 -O2 pidigits.c -lgmp 2.27u 0.00s 2.28r + gccgo -O2 pidigits.go 8.95u 0.02s 8.99r + gc pidigits 2.88u 0.14s 2.91r + gc_B pidigits 2.92u 0.10s 2.91r + +threadring 50000000 + gcc -m64 -O2 threadring.c -lpthread 14.75u 167.88s 212.23r + gccgo -O2 threadring.go 36.72u 12.08s 48.91r # -29% + gc threadring 10.93u 0.01s 10.95r # -16% + +chameneos 6000000 + gcc -m64 -O2 chameneosredux.c -lpthread 8.89u 56.62s 9.75r + gccgo -O2 chameneosredux.go 9.48u 2.48s 11.99r # -33% + gc chameneosredux 5.80u 0.00s 5.81r # -16% + diff --git a/test/blank.go b/test/blank.go index 7f7d9f6f7..0539debb1 100644 --- a/test/blank.go +++ b/test/blank.go @@ -27,6 +27,10 @@ func (T) _() { func (T) _() { } +type U struct { + _ struct{ a, b, c int } +} + const ( c0 = iota _ @@ -107,8 +111,7 @@ func main() { panic(sum) } - // exp/ssa/interp doesn't yet skip blank fields in struct - // equivalence. It also cannot support unsafe.Pointer. + // go.tools/ssa/interp cannot support unsafe.Pointer. if os.Getenv("GOSSAINTERP") == "" { type T1 struct{ x, y, z int } t1 := *(*T)(unsafe.Pointer(&T1{1, 2, 3})) @@ -116,6 +119,13 @@ func main() { if t1 != t2 { panic("T{} != T{}") } + + var u1, u2 interface{} + u1 = *(*U)(unsafe.Pointer(&T1{1, 2, 3})) + u2 = *(*U)(unsafe.Pointer(&T1{4, 5, 6})) + if u1 != u2 { + panic("U{} != U{}") + } } h(a, b) diff --git a/test/blank1.go b/test/blank1.go index 4edb2db70..54a72976b 100644 --- a/test/blank1.go +++ b/test/blank1.go @@ -13,9 +13,16 @@ var t struct { _ int } +type T struct { + _ []int +} + func main() { _() // ERROR "cannot use _ as value" x := _+1 // ERROR "cannot use _ as value" _ = x - _ = t._ // ERROR "cannot refer to blank field" + _ = t._ // ERROR "cannot refer to blank field|invalid use of" + + var v1, v2 T + _ = v1 == v2 // ERROR "cannot be compared|non-comparable" } diff --git a/test/chan/doubleselect.go b/test/chan/doubleselect.go index ac559302d..6be3faf55 100644 --- a/test/chan/doubleselect.go +++ b/test/chan/doubleselect.go @@ -36,7 +36,7 @@ func sender(n int, c1, c2, c3, c4 chan<- int) { } // mux receives the values from sender and forwards them onto another channel. -// It would be simplier to just have sender's four cases all be the same +// It would be simpler to just have sender's four cases all be the same // channel, but this doesn't actually trigger the bug. func mux(out chan<- int, in <-chan int, done chan<- bool) { for v := range in { diff --git a/test/chan/select2.go b/test/chan/select2.go index 4a0813912..ccf9dab81 100644 --- a/test/chan/select2.go +++ b/test/chan/select2.go @@ -47,7 +47,8 @@ func main() { runtime.GC() runtime.ReadMemStats(memstats) - if memstats.Alloc-alloc > 1.1e5 { + // Be careful to avoid wraparound. + if memstats.Alloc > alloc && memstats.Alloc-alloc > 1.1e5 { println("BUG: too much memory for 100,000 selects:", memstats.Alloc-alloc) } } diff --git a/test/cmp.go b/test/cmp.go index 5be64561d..73de502f3 100644 --- a/test/cmp.go +++ b/test/cmp.go @@ -43,8 +43,8 @@ func main() { var d string = "hel" // try to get different pointer d = d + "lo" - // exp/ssa/interp can't handle unsafe.Pointer. - if os.Getenv("GOSSAINTERP") != "" { + // go.tools/ssa/interp can't handle unsafe.Pointer. + if os.Getenv("GOSSAINTERP") == "" { if stringptr(c) == stringptr(d) { panic("compiler too smart -- got same string") } @@ -296,7 +296,7 @@ func main() { { var x = struct { x int - _ []int + _ string y float64 _ float64 z int diff --git a/test/cmp6.go b/test/cmp6.go index 7d99aae18..839c274bc 100644 --- a/test/cmp6.go +++ b/test/cmp6.go @@ -53,7 +53,7 @@ func main() { // Comparison of structs should have a good message use(t3 == t3) // ERROR "struct|expected" - use(t4 == t4) // ok; the []int is a blank field + use(t4 == t4) // ERROR "cannot be compared|non-comparable" // Slices, functions, and maps too. var x []int diff --git a/test/const6.go b/test/const6.go index c04435db6..c005ac369 100644 --- a/test/const6.go +++ b/test/const6.go @@ -19,12 +19,12 @@ var ( c4 mybool = c2 == (1 < 2) c5 mybool = 1 < 2 c6 mybool1 = x < y - c7 = c1 == c2 // ERROR "mismatched types" - c8 = c2 == c6 // ERROR "mismatched types" - c9 = c1 == c6 // ERROR "mismatched types" + c7 = c1 == c2 // ERROR "mismatched types|incompatible types" + c8 = c2 == c6 // ERROR "mismatched types|incompatible types" + c9 = c1 == c6 // ERROR "mismatched types|incompatible types" _ = c2 && (x < y) _ = c2 && (1 < 2) - _ = c1 && c2 // ERROR "mismatched types" - _ = c2 && c6 // ERROR "mismatched types" - _ = c1 && c6 // ERROR "mismatched types" + _ = c1 && c2 // ERROR "mismatched types|incompatible types" + _ = c2 && c6 // ERROR "mismatched types|incompatible types" + _ = c1 && c6 // ERROR "mismatched types|incompatible types" ) diff --git a/test/deferfin.go b/test/deferfin.go new file mode 100644 index 000000000..f9a74eba9 --- /dev/null +++ b/test/deferfin.go @@ -0,0 +1,59 @@ +// run + +// Copyright 2013 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. + +// Test that defers do not prevent garbage collection. + +package main + +import ( + "runtime" + "sync" + "sync/atomic" + "time" +) + +var sink func() + +func main() { + // Does not work on 32-bits due to partially conservative GC. + // Try to enable when we have fully precise GC. + if runtime.GOARCH != "amd64" { + return + } + N := 10 + count := int32(N) + var wg sync.WaitGroup + wg.Add(N) + for i := 0; i < N; i++ { + go func() { + defer wg.Done() + v := new(int) + f := func() { + if *v != 0 { + panic("oops") + } + } + if *v != 0 { + // let the compiler think f escapes + sink = f + } + runtime.SetFinalizer(v, func(p *int) { + atomic.AddInt32(&count, -1) + }) + defer f() + }() + } + wg.Wait() + for i := 0; i < 3; i++ { + time.Sleep(10 * time.Millisecond) + runtime.GC() + } + if count != 0 { + println(count, "out of", N, "finalizer are not called") + panic("not all finalizers are called") + } +} + diff --git a/test/divmod.go b/test/divmod.go new file mode 100644 index 000000000..49fed0222 --- /dev/null +++ b/test/divmod.go @@ -0,0 +1,460 @@ +// run + +// Copyright 2013 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. + +// Test division of variables. Generate many test cases, +// compute correct answer using shift and subtract, +// and then compare against results from divison and +// modulus operators. +// +// Primarily useful for testing software div/mod. + +package main + +const long = false + +func main() { + if long { + // About 3e9 test cases (calls to checkdiv3). + // Too long for everyday testing. + gen2(3, 64, 2, 64, checkdiv1) + println(ntest) + } else { + // About 4e6 test cases (calls to checkdiv3). + // Runs for 8 seconds on ARM chromebook, much faster elsewhere. + gen2(2, 64, 1, 64, checkdiv1) + } +} + +// generate all uint64 values x where x has at most n bits set in the low w +// and call f(x) for each. +func gen1(n, w int, f func(uint64)) { + gen(0, 0, n, w-1, f) +} + +func gen(val uint64, nbits, maxbits, pos int, f func(uint64)) { + if pos < 0 { + f(val) + return + } + gen(val, nbits, maxbits, pos-1, f) + if nbits < maxbits { + gen(val|1<<uint(pos), nbits+1, maxbits, pos-1, f) + } +} + +// generate all uint64 values x, y where x has at most n1 bits set in the low w1 +// and y has at most n2 bits set in the low w2 and call f(x, y) for each. +func gen2(n1, w1, n2, w2 int, f func(uint64, uint64)) { + gen1(n1, w1, func(x uint64) { + gen1(n2, w2, func(y uint64) { + f(x, y) + }) + }) +} + +// x and y are uint64s with at most 2 bits set. +// Check those values and values above and below, +// along with bitwise inversions of the same (done in checkdiv2). +func checkdiv1(x, y uint64) { + checkdiv2(x, y) + // If the low bit is set in x or y, adding or subtracting 1 + // produces a number that checkdiv1 is going to be called + // with anyway, so don't duplicate effort. + if x&1 == 0 { + checkdiv2(x+1, y) + checkdiv2(x-1, y) + } + if y&1 == 0 { + checkdiv2(x, y-1) + checkdiv2(x, y+1) + if x&1 == 0 { + checkdiv2(x+1, y-1) + checkdiv2(x-1, y-1) + checkdiv2(x-1, y+1) + checkdiv2(x+1, y+1) + } + } +} + +func checkdiv2(x, y uint64) { + checkdiv3(x, y) + checkdiv3(^x, y) + checkdiv3(x, ^y) + checkdiv3(^x, ^y) +} + +var ntest int64 = 0 + +func checkdiv3(x, y uint64) { + ntest++ + if ntest&(ntest-1) == 0 && long { + println(ntest, "...") + } + checkuint64(x, y) + if (uint64(uint32(x)) == x || uint64(uint32(^x)) == ^x) && (uint64(uint32(y)) == y || uint64(uint32(^y)) == ^y) { + checkuint32(uint32(x), uint32(y)) + } + if (uint64(uint16(x)) == x || uint64(uint16(^x)) == ^x) && (uint64(uint16(y)) == y || uint64(uint16(^y)) == ^y) { + checkuint16(uint16(x), uint16(y)) + } + if (uint64(uint8(x)) == x || uint64(uint8(^x)) == ^x) && (uint64(uint8(y)) == y || uint64(uint8(^y)) == ^y) { + checkuint8(uint8(x), uint8(y)) + } + + + sx := int64(x) + sy := int64(y) + checkint64(sx, sy) + if (int64(int32(sx)) == sx || int64(int32(^sx)) == ^sx) && (int64(int32(sy)) == sy || int64(int32(^sy)) == ^sy) { + checkint32(int32(sx), int32(sy)) + } + if (int64(int16(sx)) == sx || int64(int16(^sx)) == ^sx) && (int64(int16(sy)) == sy || int64(int16(^sy)) == ^sy) { + checkint16(int16(sx), int16(sy)) + } + if (int64(int8(sx)) == sx || int64(int8(^sx)) == ^sx) && (int64(int8(sy)) == sy || int64(int8(^sy)) == ^sy) { + checkint8(int8(sx), int8(sy)) + } +} + +// Check result of x/y, x%y for various types. + +func checkuint(x, y uint) { + if y == 0 { + divzerouint(x, y) + modzerouint(x, y) + return + } + q, r := udiv(uint64(x), uint64(y)) + q1 := x/y + r1 := x%y + if q1 != uint(q) { + print("uint(", x, "/", y, ") = ", q1, ", want ", q, "\n") + } + if r1 != uint(r) { + print("uint(", x, "%", y, ") = ", r1, ", want ", r, "\n") + } +} + +func checkuint64(x, y uint64) { + if y == 0 { + divzerouint64(x, y) + modzerouint64(x, y) + return + } + q, r := udiv(x, y) + q1 := x/y + r1 := x%y + if q1 != q { + print("uint64(", x, "/", y, ") = ", q1, ", want ", q, "\n") + } + if r1 != r { + print("uint64(", x, "%", y, ") = ", r1, ", want ", r, "\n") + } +} + +func checkuint32(x, y uint32) { + if y == 0 { + divzerouint32(x, y) + modzerouint32(x, y) + return + } + q, r := udiv(uint64(x), uint64(y)) + q1 := x/y + r1 := x%y + if q1 != uint32(q) { + print("uint32(", x, "/", y, ") = ", q1, ", want ", q, "\n") + } + if r1 != uint32(r) { + print("uint32(", x, "%", y, ") = ", r1, ", want ", r, "\n") + } +} + +func checkuint16(x, y uint16) { + if y == 0 { + divzerouint16(x, y) + modzerouint16(x, y) + return + } + q, r := udiv(uint64(x), uint64(y)) + q1 := x/y + r1 := x%y + if q1 != uint16(q) { + print("uint16(", x, "/", y, ") = ", q1, ", want ", q, "\n") + } + if r1 != uint16(r) { + print("uint16(", x, "%", y, ") = ", r1, ", want ", r, "\n") + } +} + +func checkuint8(x, y uint8) { + if y == 0 { + divzerouint8(x, y) + modzerouint8(x, y) + return + } + q, r := udiv(uint64(x), uint64(y)) + q1 := x/y + r1 := x%y + if q1 != uint8(q) { + print("uint8(", x, "/", y, ") = ", q1, ", want ", q, "\n") + } + if r1 != uint8(r) { + print("uint8(", x, "%", y, ") = ", r1, ", want ", r, "\n") + } +} + +func checkint(x, y int) { + if y == 0 { + divzeroint(x, y) + modzeroint(x, y) + return + } + q, r := idiv(int64(x), int64(y)) + q1 := x/y + r1 := x%y + if q1 != int(q) { + print("int(", x, "/", y, ") = ", q1, ", want ", q, "\n") + } + if r1 != int(r) { + print("int(", x, "%", y, ") = ", r1, ", want ", r, "\n") + } +} + +func checkint64(x, y int64) { + if y == 0 { + divzeroint64(x, y) + modzeroint64(x, y) + return + } + q, r := idiv(x, y) + q1 := x/y + r1 := x%y + if q1 != q { + print("int64(", x, "/", y, ") = ", q1, ", want ", q, "\n") + } + if r1 != r { + print("int64(", x, "%", y, ") = ", r1, ", want ", r, "\n") + } +} + +func checkint32(x, y int32) { + if y == 0 { + divzeroint32(x, y) + modzeroint32(x, y) + return + } + q, r := idiv(int64(x), int64(y)) + q1 := x/y + r1 := x%y + if q1 != int32(q) { + print("int32(", x, "/", y, ") = ", q1, ", want ", q, "\n") + } + if r1 != int32(r) { + print("int32(", x, "%", y, ") = ", r1, ", want ", r, "\n") + } +} + +func checkint16(x, y int16) { + if y == 0 { + divzeroint16(x, y) + modzeroint16(x, y) + return + } + q, r := idiv(int64(x), int64(y)) + q1 := x/y + r1 := x%y + if q1 != int16(q) { + print("int16(", x, "/", y, ") = ", q1, ", want ", q, "\n") + } + if r1 != int16(r) { + print("int16(", x, "%", y, ") = ", r1, ", want ", r, "\n") + } +} + +func checkint8(x, y int8) { + if y == 0 { + divzeroint8(x, y) + modzeroint8(x, y) + return + } + q, r := idiv(int64(x), int64(y)) + q1 := x/y + r1 := x%y + if q1 != int8(q) { + print("int8(", x, "/", y, ") = ", q1, ", want ", q, "\n") + } + if r1 != int8(r) { + print("int8(", x, "%", y, ") = ", r1, ", want ", r, "\n") + } +} + +func divzerouint(x, y uint) uint { + defer checkudivzero("uint", uint64(x)) + return x / y +} + +func divzerouint64(x, y uint64) uint64 { + defer checkudivzero("uint64", uint64(x)) + return x / y +} + +func divzerouint32(x, y uint32) uint32 { + defer checkudivzero("uint32", uint64(x)) + return x / y +} + +func divzerouint16(x, y uint16) uint16 { + defer checkudivzero("uint16", uint64(x)) + return x / y +} + +func divzerouint8(x, y uint8) uint8 { + defer checkudivzero("uint8", uint64(x)) + return x / y +} + +func checkudivzero(typ string, x uint64) { + if recover() == nil { + print(typ, "(", x, " / 0) did not panic") + } +} + +func divzeroint(x, y int) int { + defer checkdivzero("int", int64(x)) + return x / y +} + +func divzeroint64(x, y int64) int64 { + defer checkdivzero("int64", int64(x)) + return x / y +} + +func divzeroint32(x, y int32) int32 { + defer checkdivzero("int32", int64(x)) + return x / y +} + +func divzeroint16(x, y int16) int16 { + defer checkdivzero("int16", int64(x)) + return x / y +} + +func divzeroint8(x, y int8) int8 { + defer checkdivzero("int8", int64(x)) + return x / y +} + +func checkdivzero(typ string, x int64) { + if recover() == nil { + print(typ, "(", x, " / 0) did not panic") + } +} + +func modzerouint(x, y uint) uint { + defer checkumodzero("uint", uint64(x)) + return x % y +} + +func modzerouint64(x, y uint64) uint64 { + defer checkumodzero("uint64", uint64(x)) + return x % y +} + +func modzerouint32(x, y uint32) uint32 { + defer checkumodzero("uint32", uint64(x)) + return x % y +} + +func modzerouint16(x, y uint16) uint16 { + defer checkumodzero("uint16", uint64(x)) + return x % y +} + +func modzerouint8(x, y uint8) uint8 { + defer checkumodzero("uint8", uint64(x)) + return x % y +} + +func checkumodzero(typ string, x uint64) { + if recover() == nil { + print(typ, "(", x, " % 0) did not panic") + } +} + +func modzeroint(x, y int) int { + defer checkmodzero("int", int64(x)) + return x % y +} + +func modzeroint64(x, y int64) int64 { + defer checkmodzero("int64", int64(x)) + return x % y +} + +func modzeroint32(x, y int32) int32 { + defer checkmodzero("int32", int64(x)) + return x % y +} + +func modzeroint16(x, y int16) int16 { + defer checkmodzero("int16", int64(x)) + return x % y +} + +func modzeroint8(x, y int8) int8 { + defer checkmodzero("int8", int64(x)) + return x % y +} + +func checkmodzero(typ string, x int64) { + if recover() == nil { + print(typ, "(", x, " % 0) did not panic") + } +} + +// unsigned divide and mod using shift and subtract. +func udiv(x, y uint64) (q, r uint64) { + sh := 0 + for y+y > y && y+y <= x { + sh++ + y <<= 1 + } + for ; sh >= 0; sh-- { + q <<= 1 + if x >= y { + x -= y + q |= 1 + } + y >>= 1 + } + return q, x +} + +// signed divide and mod: do unsigned and adjust signs. +func idiv(x, y int64) (q, r int64) { + // special case for minint / -1 = minint + if x-1 > x && y == -1 { + return x, 0 + } + ux := uint64(x) + uy := uint64(y) + if x < 0 { + ux = -ux + } + if y < 0 { + uy = -uy + } + uq, ur := udiv(ux, uy) + q = int64(uq) + r = int64(ur) + if x < 0 { + r = -r + } + if (x < 0) != (y < 0) { + q = -q + } + return q, r +} diff --git a/test/errchk b/test/errchk index b8b312a92..de0c4fd2f 100755 --- a/test/errchk +++ b/test/errchk @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Copyright 2009 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. diff --git a/test/escape2.go b/test/escape2.go index 511b74a1c..be89c2d84 100644 --- a/test/escape2.go +++ b/test/escape2.go @@ -1136,6 +1136,7 @@ func foo126() { px = &i // ERROR "&i escapes" }() } + _ = px } var px *int @@ -1325,3 +1326,34 @@ func foo142() { t := new(Tm) // ERROR "escapes to heap" gf = t.M // ERROR "t.M escapes to heap" } + +// issue 3888. +func foo143() { + for i := 0; i < 1000; i++ { + func() { // ERROR "func literal does not escape" + for i := 0; i < 1; i++ { + var t Tm + t.M() // ERROR "t does not escape" + } + }() + } +} + +// issue 5773 +// Check that annotations take effect regardless of whether they +// are before or after the use in the source code. + +//go:noescape + +func foo144a(*int) + +func foo144() { + var x int + foo144a(&x) // ERROR "&x does not escape" + var y int + foo144b(&y) // ERROR "&y does not escape" +} + +//go:noescape + +func foo144b(*int) diff --git a/test/escape5.go b/test/escape5.go index 6b327fe9e..c9646872d 100644 --- a/test/escape5.go +++ b/test/escape5.go @@ -142,3 +142,10 @@ func f9() { var j T1 // ERROR "moved to heap: j" f8(&j) // ERROR "&j escapes to heap" } + +func f10() { + // These don't escape but are too big for the stack + var x [1<<30]byte // ERROR "moved to heap: x" + var y = make([]byte, 1<<30) // ERROR "does not escape" + _ = x[0] + y[0] +} diff --git a/test/fixedbugs/bug086.go b/test/fixedbugs/bug086.go index f03982b30..40d236206 100644 --- a/test/fixedbugs/bug086.go +++ b/test/fixedbugs/bug086.go @@ -6,12 +6,12 @@ package main -func f() int { // GCCGO_ERROR "control" +func f() int { if false { return 0; } // we should not be able to return successfully w/o a return statement -} // GC_ERROR "return" +} // ERROR "return" func main() { print(f(), "\n"); diff --git a/test/fixedbugs/bug205.go b/test/fixedbugs/bug205.go index 769837d04..1e0d9d1f3 100644 --- a/test/fixedbugs/bug205.go +++ b/test/fixedbugs/bug205.go @@ -11,8 +11,8 @@ var s string; var m map[string]int; func main() { - println(t["hi"]); // ERROR "non-integer slice index" - println(s["hi"]); // ERROR "non-integer string index" - println(m[0]); // ERROR "as type string in map index" + println(t["hi"]); // ERROR "non-integer slice index|must be integer" + println(s["hi"]); // ERROR "non-integer string index|must be integer" + println(m[0]); // ERROR "cannot use.*as type string" } diff --git a/test/fixedbugs/bug295.go b/test/fixedbugs/bug295.go index e2e5206ca..63a12a3a7 100644 --- a/test/fixedbugs/bug295.go +++ b/test/fixedbugs/bug295.go @@ -6,7 +6,9 @@ package main -import . "testing" // defines top-level T +import . "testing" // defines file-level T + +type _ B // make use of package "testing" (but don't refer to T) type S struct { T int diff --git a/test/fixedbugs/bug385_64.go b/test/fixedbugs/bug385_64.go index b5621b210..aef03c389 100644 --- a/test/fixedbugs/bug385_64.go +++ b/test/fixedbugs/bug385_64.go @@ -10,13 +10,214 @@ package main -func main() { // ERROR "stack frame too large" - var arr [1000200030]int32 - arr_bkup := arr - _ = arr_bkup -} +var z [10<<20]byte -func F() { // ERROR "stack frame too large" - var arr [1 << 30]int32 - _ = arr[42] +func main() { // ERROR "stack frame too large" + // seq 1 206 | sed 's/.*/ var x& [10<<20]byte; z = x&/' + var x1 [10<<20]byte; z = x1 + var x2 [10<<20]byte; z = x2 + var x3 [10<<20]byte; z = x3 + var x4 [10<<20]byte; z = x4 + var x5 [10<<20]byte; z = x5 + var x6 [10<<20]byte; z = x6 + var x7 [10<<20]byte; z = x7 + var x8 [10<<20]byte; z = x8 + var x9 [10<<20]byte; z = x9 + var x10 [10<<20]byte; z = x10 + var x11 [10<<20]byte; z = x11 + var x12 [10<<20]byte; z = x12 + var x13 [10<<20]byte; z = x13 + var x14 [10<<20]byte; z = x14 + var x15 [10<<20]byte; z = x15 + var x16 [10<<20]byte; z = x16 + var x17 [10<<20]byte; z = x17 + var x18 [10<<20]byte; z = x18 + var x19 [10<<20]byte; z = x19 + var x20 [10<<20]byte; z = x20 + var x21 [10<<20]byte; z = x21 + var x22 [10<<20]byte; z = x22 + var x23 [10<<20]byte; z = x23 + var x24 [10<<20]byte; z = x24 + var x25 [10<<20]byte; z = x25 + var x26 [10<<20]byte; z = x26 + var x27 [10<<20]byte; z = x27 + var x28 [10<<20]byte; z = x28 + var x29 [10<<20]byte; z = x29 + var x30 [10<<20]byte; z = x30 + var x31 [10<<20]byte; z = x31 + var x32 [10<<20]byte; z = x32 + var x33 [10<<20]byte; z = x33 + var x34 [10<<20]byte; z = x34 + var x35 [10<<20]byte; z = x35 + var x36 [10<<20]byte; z = x36 + var x37 [10<<20]byte; z = x37 + var x38 [10<<20]byte; z = x38 + var x39 [10<<20]byte; z = x39 + var x40 [10<<20]byte; z = x40 + var x41 [10<<20]byte; z = x41 + var x42 [10<<20]byte; z = x42 + var x43 [10<<20]byte; z = x43 + var x44 [10<<20]byte; z = x44 + var x45 [10<<20]byte; z = x45 + var x46 [10<<20]byte; z = x46 + var x47 [10<<20]byte; z = x47 + var x48 [10<<20]byte; z = x48 + var x49 [10<<20]byte; z = x49 + var x50 [10<<20]byte; z = x50 + var x51 [10<<20]byte; z = x51 + var x52 [10<<20]byte; z = x52 + var x53 [10<<20]byte; z = x53 + var x54 [10<<20]byte; z = x54 + var x55 [10<<20]byte; z = x55 + var x56 [10<<20]byte; z = x56 + var x57 [10<<20]byte; z = x57 + var x58 [10<<20]byte; z = x58 + var x59 [10<<20]byte; z = x59 + var x60 [10<<20]byte; z = x60 + var x61 [10<<20]byte; z = x61 + var x62 [10<<20]byte; z = x62 + var x63 [10<<20]byte; z = x63 + var x64 [10<<20]byte; z = x64 + var x65 [10<<20]byte; z = x65 + var x66 [10<<20]byte; z = x66 + var x67 [10<<20]byte; z = x67 + var x68 [10<<20]byte; z = x68 + var x69 [10<<20]byte; z = x69 + var x70 [10<<20]byte; z = x70 + var x71 [10<<20]byte; z = x71 + var x72 [10<<20]byte; z = x72 + var x73 [10<<20]byte; z = x73 + var x74 [10<<20]byte; z = x74 + var x75 [10<<20]byte; z = x75 + var x76 [10<<20]byte; z = x76 + var x77 [10<<20]byte; z = x77 + var x78 [10<<20]byte; z = x78 + var x79 [10<<20]byte; z = x79 + var x80 [10<<20]byte; z = x80 + var x81 [10<<20]byte; z = x81 + var x82 [10<<20]byte; z = x82 + var x83 [10<<20]byte; z = x83 + var x84 [10<<20]byte; z = x84 + var x85 [10<<20]byte; z = x85 + var x86 [10<<20]byte; z = x86 + var x87 [10<<20]byte; z = x87 + var x88 [10<<20]byte; z = x88 + var x89 [10<<20]byte; z = x89 + var x90 [10<<20]byte; z = x90 + var x91 [10<<20]byte; z = x91 + var x92 [10<<20]byte; z = x92 + var x93 [10<<20]byte; z = x93 + var x94 [10<<20]byte; z = x94 + var x95 [10<<20]byte; z = x95 + var x96 [10<<20]byte; z = x96 + var x97 [10<<20]byte; z = x97 + var x98 [10<<20]byte; z = x98 + var x99 [10<<20]byte; z = x99 + var x100 [10<<20]byte; z = x100 + var x101 [10<<20]byte; z = x101 + var x102 [10<<20]byte; z = x102 + var x103 [10<<20]byte; z = x103 + var x104 [10<<20]byte; z = x104 + var x105 [10<<20]byte; z = x105 + var x106 [10<<20]byte; z = x106 + var x107 [10<<20]byte; z = x107 + var x108 [10<<20]byte; z = x108 + var x109 [10<<20]byte; z = x109 + var x110 [10<<20]byte; z = x110 + var x111 [10<<20]byte; z = x111 + var x112 [10<<20]byte; z = x112 + var x113 [10<<20]byte; z = x113 + var x114 [10<<20]byte; z = x114 + var x115 [10<<20]byte; z = x115 + var x116 [10<<20]byte; z = x116 + var x117 [10<<20]byte; z = x117 + var x118 [10<<20]byte; z = x118 + var x119 [10<<20]byte; z = x119 + var x120 [10<<20]byte; z = x120 + var x121 [10<<20]byte; z = x121 + var x122 [10<<20]byte; z = x122 + var x123 [10<<20]byte; z = x123 + var x124 [10<<20]byte; z = x124 + var x125 [10<<20]byte; z = x125 + var x126 [10<<20]byte; z = x126 + var x127 [10<<20]byte; z = x127 + var x128 [10<<20]byte; z = x128 + var x129 [10<<20]byte; z = x129 + var x130 [10<<20]byte; z = x130 + var x131 [10<<20]byte; z = x131 + var x132 [10<<20]byte; z = x132 + var x133 [10<<20]byte; z = x133 + var x134 [10<<20]byte; z = x134 + var x135 [10<<20]byte; z = x135 + var x136 [10<<20]byte; z = x136 + var x137 [10<<20]byte; z = x137 + var x138 [10<<20]byte; z = x138 + var x139 [10<<20]byte; z = x139 + var x140 [10<<20]byte; z = x140 + var x141 [10<<20]byte; z = x141 + var x142 [10<<20]byte; z = x142 + var x143 [10<<20]byte; z = x143 + var x144 [10<<20]byte; z = x144 + var x145 [10<<20]byte; z = x145 + var x146 [10<<20]byte; z = x146 + var x147 [10<<20]byte; z = x147 + var x148 [10<<20]byte; z = x148 + var x149 [10<<20]byte; z = x149 + var x150 [10<<20]byte; z = x150 + var x151 [10<<20]byte; z = x151 + var x152 [10<<20]byte; z = x152 + var x153 [10<<20]byte; z = x153 + var x154 [10<<20]byte; z = x154 + var x155 [10<<20]byte; z = x155 + var x156 [10<<20]byte; z = x156 + var x157 [10<<20]byte; z = x157 + var x158 [10<<20]byte; z = x158 + var x159 [10<<20]byte; z = x159 + var x160 [10<<20]byte; z = x160 + var x161 [10<<20]byte; z = x161 + var x162 [10<<20]byte; z = x162 + var x163 [10<<20]byte; z = x163 + var x164 [10<<20]byte; z = x164 + var x165 [10<<20]byte; z = x165 + var x166 [10<<20]byte; z = x166 + var x167 [10<<20]byte; z = x167 + var x168 [10<<20]byte; z = x168 + var x169 [10<<20]byte; z = x169 + var x170 [10<<20]byte; z = x170 + var x171 [10<<20]byte; z = x171 + var x172 [10<<20]byte; z = x172 + var x173 [10<<20]byte; z = x173 + var x174 [10<<20]byte; z = x174 + var x175 [10<<20]byte; z = x175 + var x176 [10<<20]byte; z = x176 + var x177 [10<<20]byte; z = x177 + var x178 [10<<20]byte; z = x178 + var x179 [10<<20]byte; z = x179 + var x180 [10<<20]byte; z = x180 + var x181 [10<<20]byte; z = x181 + var x182 [10<<20]byte; z = x182 + var x183 [10<<20]byte; z = x183 + var x184 [10<<20]byte; z = x184 + var x185 [10<<20]byte; z = x185 + var x186 [10<<20]byte; z = x186 + var x187 [10<<20]byte; z = x187 + var x188 [10<<20]byte; z = x188 + var x189 [10<<20]byte; z = x189 + var x190 [10<<20]byte; z = x190 + var x191 [10<<20]byte; z = x191 + var x192 [10<<20]byte; z = x192 + var x193 [10<<20]byte; z = x193 + var x194 [10<<20]byte; z = x194 + var x195 [10<<20]byte; z = x195 + var x196 [10<<20]byte; z = x196 + var x197 [10<<20]byte; z = x197 + var x198 [10<<20]byte; z = x198 + var x199 [10<<20]byte; z = x199 + var x200 [10<<20]byte; z = x200 + var x201 [10<<20]byte; z = x201 + var x202 [10<<20]byte; z = x202 + var x203 [10<<20]byte; z = x203 + var x204 [10<<20]byte; z = x204 + var x205 [10<<20]byte; z = x205 + var x206 [10<<20]byte; z = x206 } diff --git a/test/fixedbugs/bug435.go b/test/fixedbugs/bug435.go index 9c30b143b..45323d8ee 100644 --- a/test/fixedbugs/bug435.go +++ b/test/fixedbugs/bug435.go @@ -12,4 +12,4 @@ package main func foo() { - bar(1, // ERROR "unexpected|missing|undefined" + bar(1, // ERROR "unexpected|missing|undefined"
\ No newline at end of file diff --git a/test/fixedbugs/bug459.go b/test/fixedbugs/bug459.go index 80abe5d51..014f2ef01 100644 --- a/test/fixedbugs/bug459.go +++ b/test/fixedbugs/bug459.go @@ -9,7 +9,7 @@ package flag -var commandLine = NewFlagSet() // ERROR "loop" +var commandLine = NewFlagSet() // ERROR "loop|depends upon itself" type FlagSet struct { } diff --git a/test/fixedbugs/bug460.dir/a.go b/test/fixedbugs/bug460.dir/a.go index 02a287b31..29049d9aa 100644 --- a/test/fixedbugs/bug460.dir/a.go +++ b/test/fixedbugs/bug460.dir/a.go @@ -6,4 +6,8 @@ package a type Foo struct { int + int8 + error + rune + byte } diff --git a/test/fixedbugs/bug460.dir/b.go b/test/fixedbugs/bug460.dir/b.go index 1868afe07..5c0a0c47e 100644 --- a/test/fixedbugs/bug460.dir/b.go +++ b/test/fixedbugs/bug460.dir/b.go @@ -9,6 +9,9 @@ import "./a" var x a.Foo func main() { - x.int = 20 // ERROR "unexported field" + x.int = 20 // ERROR "unexported field" + x.int8 = 20 // ERROR "unexported field" + x.error = nil // ERROR "unexported field" + x.rune = 'a' // ERROR "unexported field" + x.byte = 20 // ERROR "unexported field" } - diff --git a/test/fixedbugs/bug475.go b/test/fixedbugs/bug475.go new file mode 100644 index 000000000..1bd6fa35c --- /dev/null +++ b/test/fixedbugs/bug475.go @@ -0,0 +1,22 @@ +// compile + +// Copyright 2013 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. + +// Variable in enclosing function with same name as field in struct +// composite literal confused gccgo. + +package p + +type s1 struct { + f *s1 +} + +func F() { + var f *s1 + _ = func() { + _ = s1{f: nil} + } + _ = f +} diff --git a/test/fixedbugs/bug476.go b/test/fixedbugs/bug476.go new file mode 100644 index 000000000..4ea217404 --- /dev/null +++ b/test/fixedbugs/bug476.go @@ -0,0 +1,23 @@ +// compile + +// Copyright 2013 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. + +// Logical operation on named boolean type returns the same type, +// supporting an implicit convertion to an interface type. This used +// to crash gccgo. + +package p + +type B bool + +func (b B) M() {} + +type I interface { + M() +} + +func F(a, b B) I { + return a && b +} diff --git a/test/fixedbugs/bug477.go b/test/fixedbugs/bug477.go new file mode 100644 index 000000000..86289afa6 --- /dev/null +++ b/test/fixedbugs/bug477.go @@ -0,0 +1,34 @@ +// compile + +// Copyright 2013 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. + +// Test multiple identical unnamed structs with methods. This caused +// a compilation error with gccgo. + +package p + +type S1 struct{} + +func (s S1) M() {} + +type S2 struct { + F1 struct { + S1 + } + F2 struct { + S1 + } +} + +type I interface { + M() +} + +func F() { + var s2 S2 + var i1 I = s2.F1 + var i2 I = s2.F2 + _, _ = i1, i2 +} diff --git a/test/fixedbugs/bug478.dir/a.go b/test/fixedbugs/bug478.dir/a.go new file mode 100644 index 000000000..a40e454f9 --- /dev/null +++ b/test/fixedbugs/bug478.dir/a.go @@ -0,0 +1,9 @@ +// Copyright 2013 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 p1 + +type S1 struct{} + +func (s S1) f() {} diff --git a/test/fixedbugs/bug478.dir/b.go b/test/fixedbugs/bug478.dir/b.go new file mode 100644 index 000000000..c0fdf1127 --- /dev/null +++ b/test/fixedbugs/bug478.dir/b.go @@ -0,0 +1,13 @@ +// Copyright 2013 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 p2 + +import "./a" + +type S2 struct { + p1.S1 +} + +func (s S2) f() {} diff --git a/test/fixedbugs/bug478.go b/test/fixedbugs/bug478.go new file mode 100644 index 000000000..5e339e801 --- /dev/null +++ b/test/fixedbugs/bug478.go @@ -0,0 +1,10 @@ +// compiledir + +// Copyright 2013 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. + +// Using the same unexported name for a method as a method on an +// imported embedded type caused a gccgo compilation failure. + +package ignored diff --git a/test/fixedbugs/bug479.dir/a.go b/test/fixedbugs/bug479.dir/a.go new file mode 100644 index 000000000..5ff3bef1d --- /dev/null +++ b/test/fixedbugs/bug479.dir/a.go @@ -0,0 +1,15 @@ +// Copyright 2013 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 p + +import "unsafe" + +type S2 struct {} + +const C = unsafe.Sizeof(S2{}) + +type S1 struct { + S2 +} diff --git a/test/fixedbugs/bug479.dir/b.go b/test/fixedbugs/bug479.dir/b.go new file mode 100644 index 000000000..a1b27b332 --- /dev/null +++ b/test/fixedbugs/bug479.dir/b.go @@ -0,0 +1,16 @@ +// Copyright 2013 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 "./a" + +type S3 struct { + p.S1 +} + +func main() { + var i interface{} = S3{} + _ = i +} diff --git a/test/fixedbugs/bug479.go b/test/fixedbugs/bug479.go new file mode 100644 index 000000000..f8a0f93c7 --- /dev/null +++ b/test/fixedbugs/bug479.go @@ -0,0 +1,10 @@ +// rundir + +// Copyright 2013 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. + +// Gccgo was not consistent in deciding how to compare a struct type +// for equality, leading to an undefined symbol at link time. + +package ignored diff --git a/test/fixedbugs/issue3783.go b/test/fixedbugs/issue3783.go index 35df5d8f6..d7a4a2e8f 100644 --- a/test/fixedbugs/issue3783.go +++ b/test/fixedbugs/issue3783.go @@ -8,5 +8,5 @@ package foo var i int -func (*i) bar() // ERROR "not a type" +func (*i) bar() // ERROR "not a type|expected type" diff --git a/test/fixedbugs/issue3925.go b/test/fixedbugs/issue3925.go index 2f8786fc7..a62d4392e 100644 --- a/test/fixedbugs/issue3925.go +++ b/test/fixedbugs/issue3925.go @@ -12,12 +12,12 @@ package foo var _ = map[string]string{ "1": "2", - "3", "4", // ERROR "missing key" + "3", "4", // ERROR "missing key|must have keys" } var _ = []string{ "foo", "bar", - 20, // ERROR "cannot use" + 20, // ERROR "cannot use|incompatible type" } diff --git a/test/fixedbugs/issue4085a.go b/test/fixedbugs/issue4085a.go index 8a52b268f..089637d86 100644 --- a/test/fixedbugs/issue4085a.go +++ b/test/fixedbugs/issue4085a.go @@ -9,10 +9,10 @@ package main type T []int func main() { - _ = make(T, -1) // ERROR "negative" - _ = make(T, 0.5) // ERROR "constant 0.5 truncated to integer" - _ = make(T, 1.0) // ok - _ = make(T, 1<<63) // ERROR "len argument too large" - _ = make(T, 0, -1) // ERROR "negative cap" + _ = make(T, -1) // ERROR "negative" + _ = make(T, 0.5) // ERROR "constant 0.5 truncated to integer|non-integer len argument" + _ = make(T, 1.0) // ok + _ = make(T, 1<<63) // ERROR "len argument too large" + _ = make(T, 0, -1) // ERROR "negative cap" _ = make(T, 10, 0) // ERROR "len larger than cap" } diff --git a/test/fixedbugs/issue4097.go b/test/fixedbugs/issue4097.go index fa942c9db..c2b7d9b4f 100644 --- a/test/fixedbugs/issue4097.go +++ b/test/fixedbugs/issue4097.go @@ -7,5 +7,5 @@ package foo var s [][10]int -const m = len(s[len(s)-1]) // ERROR "is not a constant" +const m = len(s[len(s)-1]) // ERROR "is not a constant|is not constant" diff --git a/test/fixedbugs/issue4232.go b/test/fixedbugs/issue4232.go index 29ddfa8a9..e5daa6562 100644 --- a/test/fixedbugs/issue4232.go +++ b/test/fixedbugs/issue4232.go @@ -8,26 +8,26 @@ package p func f() { var a [10]int - _ = a[-1] // ERROR "invalid array index -1" - _ = a[-1:] // ERROR "invalid slice index -1" - _ = a[:-1] // ERROR "invalid slice index -1" - _ = a[10] // ERROR "invalid array index 10" + _ = a[-1] // ERROR "invalid array index -1|index out of bounds" + _ = a[-1:] // ERROR "invalid slice index -1|index out of bounds" + _ = a[:-1] // ERROR "invalid slice index -1|index out of bounds" + _ = a[10] // ERROR "invalid array index 10|index out of bounds" var s []int - _ = s[-1] // ERROR "invalid slice index -1" - _ = s[-1:] // ERROR "invalid slice index -1" - _ = s[:-1] // ERROR "invalid slice index -1" + _ = s[-1] // ERROR "invalid slice index -1|index out of bounds" + _ = s[-1:] // ERROR "invalid slice index -1|index out of bounds" + _ = s[:-1] // ERROR "invalid slice index -1|index out of bounds" _ = s[10] const c = "foo" - _ = c[-1] // ERROR "invalid string index -1" - _ = c[-1:] // ERROR "invalid slice index -1" - _ = c[:-1] // ERROR "invalid slice index -1" - _ = c[3] // ERROR "invalid string index 3" + _ = c[-1] // ERROR "invalid string index -1|index out of bounds" + _ = c[-1:] // ERROR "invalid slice index -1|index out of bounds" + _ = c[:-1] // ERROR "invalid slice index -1|index out of bounds" + _ = c[3] // ERROR "invalid string index 3|index out of bounds" var t string - _ = t[-1] // ERROR "invalid string index -1" - _ = t[-1:] // ERROR "invalid slice index -1" - _ = t[:-1] // ERROR "invalid slice index -1" + _ = t[-1] // ERROR "invalid string index -1|index out of bounds" + _ = t[-1:] // ERROR "invalid slice index -1|index out of bounds" + _ = t[:-1] // ERROR "invalid slice index -1|index out of bounds" _ = t[3] } diff --git a/test/fixedbugs/issue4251.go b/test/fixedbugs/issue4251.go index a14e0896a..4adec2bab 100644 --- a/test/fixedbugs/issue4251.go +++ b/test/fixedbugs/issue4251.go @@ -9,13 +9,13 @@ package p func F1(s []byte) []byte { - return s[2:1] // ERROR "inverted" + return s[2:1] // ERROR "invalid slice index" } func F2(a [10]byte) []byte { - return a[2:1] // ERROR "inverted" + return a[2:1] // ERROR "invalid slice index" } func F3(s string) string { - return s[2:1] // ERROR "inverted" + return s[2:1] // ERROR "invalid slice index" } diff --git a/test/fixedbugs/issue4452.go b/test/fixedbugs/issue4452.go index c75da9024..54dd214d6 100644 --- a/test/fixedbugs/issue4452.go +++ b/test/fixedbugs/issue4452.go @@ -9,5 +9,5 @@ package main func main() { - _ = [...]int(4) // ERROR "use of \[\.\.\.\] array outside of array literal" + _ = [...]int(4) // ERROR "\[\.\.\.\].*outside of array literal" } diff --git a/test/fixedbugs/issue4458.go b/test/fixedbugs/issue4458.go index 8ee3e879e..820f18cb8 100644 --- a/test/fixedbugs/issue4458.go +++ b/test/fixedbugs/issue4458.go @@ -16,5 +16,5 @@ func (T) foo() {} func main() { av := T{} pav := &av - (**T).foo(&pav) // ERROR "no method foo" + (**T).foo(&pav) // ERROR "no method foo|requires named type or pointer to named" } diff --git a/test/fixedbugs/issue4463.go b/test/fixedbugs/issue4463.go index fe07af71f..70977ceb7 100644 --- a/test/fixedbugs/issue4463.go +++ b/test/fixedbugs/issue4463.go @@ -45,17 +45,17 @@ func F() { (println("bar")) (recover()) - go append(a, 0) // ERROR "discards result" - go cap(a) // ERROR "discards result" - go complex(1, 2) // ERROR "discards result" - go imag(1i) // ERROR "discards result" - go len(a) // ERROR "discards result" - go make([]int, 10) // ERROR "discards result" - go new(int) // ERROR "discards result" - go real(1i) // ERROR "discards result" - go unsafe.Alignof(a) // ERROR "discards result" - go unsafe.Offsetof(s.f) // ERROR "discards result" - go unsafe.Sizeof(a) // ERROR "discards result" + go append(a, 0) // ERROR "not used|discards result" + go cap(a) // ERROR "not used|discards result" + go complex(1, 2) // ERROR "not used|discards result" + go imag(1i) // ERROR "not used|discards result" + go len(a) // ERROR "not used|discards result" + go make([]int, 10) // ERROR "not used|discards result" + go new(int) // ERROR "not used|discards result" + go real(1i) // ERROR "not used|discards result" + go unsafe.Alignof(a) // ERROR "not used|discards result" + go unsafe.Offsetof(s.f) // ERROR "not used|discards result" + go unsafe.Sizeof(a) // ERROR "not used|discards result" go close(c) go copy(a, a) @@ -65,17 +65,17 @@ func F() { go println("bar") go recover() - defer append(a, 0) // ERROR "discards result" - defer cap(a) // ERROR "discards result" - defer complex(1, 2) // ERROR "discards result" - defer imag(1i) // ERROR "discards result" - defer len(a) // ERROR "discards result" - defer make([]int, 10) // ERROR "discards result" - defer new(int) // ERROR "discards result" - defer real(1i) // ERROR "discards result" - defer unsafe.Alignof(a) // ERROR "discards result" - defer unsafe.Offsetof(s.f) // ERROR "discards result" - defer unsafe.Sizeof(a) // ERROR "discards result" + defer append(a, 0) // ERROR "not used|discards result" + defer cap(a) // ERROR "not used|discards result" + defer complex(1, 2) // ERROR "not used|discards result" + defer imag(1i) // ERROR "not used|discards result" + defer len(a) // ERROR "not used|discards result" + defer make([]int, 10) // ERROR "not used|discards result" + defer new(int) // ERROR "not used|discards result" + defer real(1i) // ERROR "not used|discards result" + defer unsafe.Alignof(a) // ERROR "not used|discards result" + defer unsafe.Offsetof(s.f) // ERROR "not used|discards result" + defer unsafe.Sizeof(a) // ERROR "not used|discards result" defer close(c) defer copy(a, a) diff --git a/test/fixedbugs/issue4517d.go b/test/fixedbugs/issue4517d.go new file mode 100644 index 000000000..f601db66f --- /dev/null +++ b/test/fixedbugs/issue4517d.go @@ -0,0 +1,9 @@ +// errorcheck + +// 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. + +package p + +import init "fmt" // ERROR "cannot import package as init - init must be a func" diff --git a/test/fixedbugs/issue4545.go b/test/fixedbugs/issue4545.go index 3f2de16d2..501caadb0 100644 --- a/test/fixedbugs/issue4545.go +++ b/test/fixedbugs/issue4545.go @@ -13,7 +13,7 @@ import "fmt" func main() { var s uint - fmt.Println(1.0 + 1<<s) // ERROR "invalid operation" - x := 1.0 + 1<<s // ERROR "invalid operation" + fmt.Println(1.0 + 1<<s) // ERROR "invalid operation|non-integer type" + x := 1.0 + 1<<s // ERROR "invalid operation|non-integer type" _ = x } diff --git a/test/fixedbugs/issue4776.go b/test/fixedbugs/issue4776.go new file mode 100644 index 000000000..c38dc09b1 --- /dev/null +++ b/test/fixedbugs/issue4776.go @@ -0,0 +1,10 @@ +// errorcheck + +// Copyright 2013 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 4776: missing package declaration error should be fatal. + +type MyInt int32 // ERROR "package statement must be first" + diff --git a/test/fixedbugs/issue4813.go b/test/fixedbugs/issue4813.go index 0ca9d3f72..20dc58795 100644 --- a/test/fixedbugs/issue4813.go +++ b/test/fixedbugs/issue4813.go @@ -31,22 +31,22 @@ var ( a3 = A[f2] // ERROR "truncated" a4 = A[c] a5 = A[c2] // ERROR "truncated" - a6 = A[vf] // ERROR "non-integer" - a7 = A[vc] // ERROR "non-integer" + a6 = A[vf] // ERROR "non-integer|must be integer" + a7 = A[vc] // ERROR "non-integer|must be integer" s1 = S[i] s2 = S[f] s3 = S[f2] // ERROR "truncated" s4 = S[c] s5 = S[c2] // ERROR "truncated" - s6 = S[vf] // ERROR "non-integer" - s7 = S[vc] // ERROR "non-integer" + s6 = S[vf] // ERROR "non-integer|must be integer" + s7 = S[vc] // ERROR "non-integer|must be integer" t1 = T[i] t2 = T[f] t3 = T[f2] // ERROR "truncated" t4 = T[c] t5 = T[c2] // ERROR "truncated" - t6 = T[vf] // ERROR "non-integer" - t7 = T[vc] // ERROR "non-integer" + t6 = T[vf] // ERROR "non-integer|must be integer" + t7 = T[vc] // ERROR "non-integer|must be integer" ) diff --git a/test/fixedbugs/issue4847.go b/test/fixedbugs/issue4847.go new file mode 100644 index 000000000..a99e80129 --- /dev/null +++ b/test/fixedbugs/issue4847.go @@ -0,0 +1,24 @@ +// errorcheck + +// Copyright 2013 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 4847: initialization loop is not detected. + +package p + +type ( + E int + S int +) + +type matcher func(s *S) E + +func matchList(s *S) E { return matcher(matchAnyFn)(s) } + +var foo = matcher(matchList) + +var matchAny = matcher(matchList) // ERROR "initialization loop" + +func matchAnyFn(s *S) (err E) { return matchAny(s) } diff --git a/test/fixedbugs/issue5172.go b/test/fixedbugs/issue5172.go new file mode 100644 index 000000000..2dd542a5d --- /dev/null +++ b/test/fixedbugs/issue5172.go @@ -0,0 +1,19 @@ +// errorcheck + +// Copyright 2013 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 5172: spurious warn about type conversion on broken type inside go and defer + +package main + +type foo struct { + x bar // ERROR "undefined" +} + +func main() { + var f foo + go f.bar() + defer f.bar() +} diff --git a/test/fixedbugs/issue5358.go b/test/fixedbugs/issue5358.go new file mode 100644 index 000000000..75aa9533d --- /dev/null +++ b/test/fixedbugs/issue5358.go @@ -0,0 +1,17 @@ +// errorcheck + +// Copyright 2013 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 5358: incorrect error message when using f(g()) form on ... args. + +package main + +func f(x int, y ...int) {} + +func g() (int, []int) + +func main() { + f(g()) // ERROR "as type int in" +} diff --git a/test/fixedbugs/issue5493.go b/test/fixedbugs/issue5493.go index 827281bdc..affc07b58 100644 --- a/test/fixedbugs/issue5493.go +++ b/test/fixedbugs/issue5493.go @@ -51,7 +51,7 @@ func main() { runtime.GC() } if count != 0 { - println(count, "out of", N, "finalizer are called") + println(count, "out of", N, "finalizer are not called") panic("not all finalizers are called") } } diff --git a/test/fixedbugs/issue5581.go b/test/fixedbugs/issue5581.go new file mode 100644 index 000000000..8c2d59729 --- /dev/null +++ b/test/fixedbugs/issue5581.go @@ -0,0 +1,34 @@ +// errorcheck + +// Used to emit a spurious "invalid recursive type" error. +// See golang.org/issue/5581. + +// Copyright 2013 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 "fmt" + +func NewBar() *Bar { return nil } + +func (x *Foo) Method() (int, error) { + for y := range x.m { + _ = y.A + } + return 0, nil +} + +type Foo struct { + m map[*Bar]int +} + +type Bar struct { + A *Foo + B chan Blah // ERROR "undefined: Blah" +} + +func main() { + fmt.Println("Hello, playground") +} diff --git a/test/fixedbugs/issue5609.go b/test/fixedbugs/issue5609.go new file mode 100644 index 000000000..ea770b486 --- /dev/null +++ b/test/fixedbugs/issue5609.go @@ -0,0 +1,13 @@ +// errorcheck + +// Copyright 2013 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 5609: overflow when calculating array size + +package pkg + +const Large uint64 = 18446744073709551615 + +var foo [Large]uint64 // ERROR "array bound is too large|array bound overflows" diff --git a/test/fixedbugs/issue5698.go b/test/fixedbugs/issue5698.go new file mode 100644 index 000000000..035bbd35d --- /dev/null +++ b/test/fixedbugs/issue5698.go @@ -0,0 +1,18 @@ +// errorcheck + +// Copyright 2013 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 5698: can define a key type with slices. + +package main + +type Key struct { + a int16 // the compiler was confused by the padding. + b []int +} + +type Val struct{} + +type Map map[Key]Val // ERROR "invalid map key type" diff --git a/test/fixedbugs/issue5704.go b/test/fixedbugs/issue5704.go new file mode 100644 index 000000000..1dfa07214 --- /dev/null +++ b/test/fixedbugs/issue5704.go @@ -0,0 +1,46 @@ +// run + +// 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. + +// Issue 5704: Conversions of empty strings to byte +// or rune slices return empty but non-nil slices. + +package main + +type ( + mystring string + mybytes []byte + myrunes []rune +) + +func checkBytes(s []byte, arg string) { + if len(s) != 0 { + panic("len(" + arg + ") != 0") + } + if s == nil { + panic(arg + " == nil") + } +} + +func checkRunes(s []rune, arg string) { + if len(s) != 0 { + panic("len(" + arg + ") != 0") + } + if s == nil { + panic(arg + " == nil") + } +} + +func main() { + checkBytes([]byte(""), `[]byte("")`) + checkBytes([]byte(mystring("")), `[]byte(mystring(""))`) + checkBytes(mybytes(""), `mybytes("")`) + checkBytes(mybytes(mystring("")), `mybytes(mystring(""))`) + + checkRunes([]rune(""), `[]rune("")`) + checkRunes([]rune(mystring("")), `[]rune(mystring(""))`) + checkRunes(myrunes(""), `myrunes("")`) + checkRunes(myrunes(mystring("")), `myrunes(mystring(""))`) +} diff --git a/test/fixedbugs/issue5856.go b/test/fixedbugs/issue5856.go new file mode 100644 index 000000000..35cadf8c9 --- /dev/null +++ b/test/fixedbugs/issue5856.go @@ -0,0 +1,38 @@ +// run + +// Copyright 2013 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 ( + "fmt" + "os" + "runtime" + "strings" +) + +func main() { + f() + panic("deferred function not run") +} + +var x = 1 + +func f() { + if x == 0 { + return + } + defer g() + panic("panic") +} + +func g() { + _, file, line, _ := runtime.Caller(2) + if !strings.HasSuffix(file, "issue5856.go") || line != 28 { + fmt.Printf("BUG: defer called from %s:%d, want issue5856.go:28\n", file, line) + os.Exit(1) + } + os.Exit(0) +} diff --git a/test/fixedbugs/issue5910.dir/a.go b/test/fixedbugs/issue5910.dir/a.go new file mode 100644 index 000000000..b236c15c7 --- /dev/null +++ b/test/fixedbugs/issue5910.dir/a.go @@ -0,0 +1,22 @@ +// Copyright 2013 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 Package struct { + name string +} + +type Future struct { + result chan struct { + *Package + error + } +} + +func (t *Future) Result() (*Package, error) { + result := <-t.result + t.result <- result + return result.Package, result.error +} diff --git a/test/fixedbugs/issue5910.dir/main.go b/test/fixedbugs/issue5910.dir/main.go new file mode 100644 index 000000000..c5d42ea09 --- /dev/null +++ b/test/fixedbugs/issue5910.dir/main.go @@ -0,0 +1,12 @@ +// Copyright 2013 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 "a" + +func main() { + f := new(a.Future) + f.Result() +} diff --git a/test/fixedbugs/issue5910.go b/test/fixedbugs/issue5910.go new file mode 100644 index 000000000..54e74bac8 --- /dev/null +++ b/test/fixedbugs/issue5910.go @@ -0,0 +1,10 @@ +// compiledir + +// Copyright 2013 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 5910: parsing of unnamed struct types +// in inlined bodies was broken. + +package ignored diff --git a/test/fixedbugs/issue5957.dir/a.go b/test/fixedbugs/issue5957.dir/a.go new file mode 100644 index 000000000..7411d5fcd --- /dev/null +++ b/test/fixedbugs/issue5957.dir/a.go @@ -0,0 +1,3 @@ +package surprise + +var X int diff --git a/test/fixedbugs/issue5957.dir/b.go b/test/fixedbugs/issue5957.dir/b.go new file mode 100644 index 000000000..9bc561b9c --- /dev/null +++ b/test/fixedbugs/issue5957.dir/b.go @@ -0,0 +1,2 @@ +package surprise2 + diff --git a/test/fixedbugs/issue5957.dir/c.go b/test/fixedbugs/issue5957.dir/c.go new file mode 100644 index 000000000..42c88177b --- /dev/null +++ b/test/fixedbugs/issue5957.dir/c.go @@ -0,0 +1,12 @@ +package p + +import ( + "./a" // ERROR "imported and not used: \x22a\x22 as surprise" + "./b" // ERROR "imported and not used: \x22b\x22 as surprise2" + b "./b" // ERROR "imported and not used: \x22b\x22$" + foo "math" // ERROR "imported and not used: \x22math\x22 as foo" + "fmt" // actually used + "strings" // ERROR "imported and not used: \x22strings\x22" +) + +var _ = fmt.Printf diff --git a/test/fixedbugs/issue5957.go b/test/fixedbugs/issue5957.go new file mode 100644 index 000000000..891d8e6d2 --- /dev/null +++ b/test/fixedbugs/issue5957.go @@ -0,0 +1,7 @@ +// errorcheckdir + +// Copyright 2013 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 ignored diff --git a/test/fixedbugs/issue5963.go b/test/fixedbugs/issue5963.go new file mode 100644 index 000000000..190e8f456 --- /dev/null +++ b/test/fixedbugs/issue5963.go @@ -0,0 +1,50 @@ +// run + +// Copyright 2013 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. + +// Used to die in runtime due to init goroutine exiting while +// locked to main thread. + +package main + +import ( + "os" + "runtime" +) + +func init() { + c := make(chan int, 1) + defer func() { + c <- 0 + }() + go func() { + os.Exit(<-c) + }() + runtime.Goexit() +} + +func main() { +} + +/* Before fix: + +invalid m->locked = 2 +fatal error: internal lockOSThread error + +goroutine 2 [runnable]: +runtime.MHeap_Scavenger() + /Users/rsc/g/go/src/pkg/runtime/mheap.c:438 +runtime.goexit() + /Users/rsc/g/go/src/pkg/runtime/proc.c:1313 +created by runtime.main + /Users/rsc/g/go/src/pkg/runtime/proc.c:165 + +goroutine 3 [runnable]: +main.func·002() + /Users/rsc/g/go/test/fixedbugs/issue5963.go:22 +created by main.init·1 + /Users/rsc/g/go/test/fixedbugs/issue5963.go:24 +0xb9 +exit status 2 +*/ diff --git a/test/fixedbugs/issue6004.go b/test/fixedbugs/issue6004.go new file mode 100644 index 000000000..45aaffd2c --- /dev/null +++ b/test/fixedbugs/issue6004.go @@ -0,0 +1,15 @@ +// errorcheck + +// Copyright 2013 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 + +func main() { + _ = nil // ERROR "use of untyped nil" + _, _ = nil, 1 // ERROR "use of untyped nil" + _, _ = 1, nil // ERROR "use of untyped nil" + _ = append(nil, 1, 2, 3) // ERROR "untyped nil" +} + diff --git a/test/fixedbugs/issue6036.go b/test/fixedbugs/issue6036.go new file mode 100644 index 000000000..5f787c569 --- /dev/null +++ b/test/fixedbugs/issue6036.go @@ -0,0 +1,44 @@ +// +build amd64 +// compile + +// Copyright 2013 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 6036: 6g's backend generates OINDREG with +// offsets larger than 32-bit. + +package main + +type T struct { + Large [1 << 31]byte + A int + B int +} + +func F(t *T) { + t.B = t.A +} + +type T2 [1<<31 + 2]byte + +func F2(t *T2) { + t[1<<31+1] = 42 +} + +type T3 [1<<15 + 1][1<<15 + 1]int + +func F3(t *T3) { + t[1<<15][1<<15] = 42 +} + +type S struct { + A int32 + B int32 +} + +type T4 [1<<29 + 1]S + +func F4(t *T4) { + t[1<<29].B = 42 +} diff --git a/test/fixedbugs/issue6055.go b/test/fixedbugs/issue6055.go new file mode 100644 index 000000000..698f62ac9 --- /dev/null +++ b/test/fixedbugs/issue6055.go @@ -0,0 +1,35 @@ +// run + +// Copyright 2013 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 "runtime" + +type Closer interface { + Close() +} + +func nilInterfaceDeferCall() { + defer func() { + // make sure a traceback happens with jmpdefer on the stack + runtime.GC() + }() + var x Closer + defer x.Close() +} + +func shouldPanic(f func()) { + defer func() { + if recover() == nil { + panic("did not panic") + } + }() + f() +} + +func main() { + shouldPanic(nilInterfaceDeferCall) +} diff --git a/test/fixedbugs/issue6131.go b/test/fixedbugs/issue6131.go new file mode 100644 index 000000000..817e4a877 --- /dev/null +++ b/test/fixedbugs/issue6131.go @@ -0,0 +1,20 @@ +// compile + +// Copyright 2013 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 6131: missing typecheck after reducing +// n%1 == 0 to a constant value. + +package main + +func isGood(n int) bool { + return n%1 == 0 +} + +func main() { + if !isGood(256) { + panic("!isGood") + } +} diff --git a/test/fixedbugs/issue6140.go b/test/fixedbugs/issue6140.go new file mode 100644 index 000000000..d494933b2 --- /dev/null +++ b/test/fixedbugs/issue6140.go @@ -0,0 +1,31 @@ +// compile + +// Copyright 2013 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 6140: compiler incorrectly rejects method values +// whose receiver has an unnamed interface type. + +package p + +type T *interface { + m() int +} + +var x T + +var _ = (*x).m + +var y interface { + m() int +} + +var _ = y.m + +type I interface { + String() string +} + +var z *struct{ I } +var _ = z.String diff --git a/test/fixedbugs/issue6247.go b/test/fixedbugs/issue6247.go new file mode 100644 index 000000000..eea8f9c87 --- /dev/null +++ b/test/fixedbugs/issue6247.go @@ -0,0 +1,17 @@ +// compile + +// Copyright 2013 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 6247: 5g used to be confused by the numbering +// of floating-point registers. + +package main + +var p map[string]interface{} +var v interface{} + +func F() { + p["hello"] = v.(complex128) * v.(complex128) +} diff --git a/test/fixedbugs/issue6269.go b/test/fixedbugs/issue6269.go new file mode 100644 index 000000000..af5feb728 --- /dev/null +++ b/test/fixedbugs/issue6269.go @@ -0,0 +1,39 @@ +// run + +// Copyright 2013 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 6269: name collision on method names for function local types. + +package main + +type foo struct{} + +func (foo) Error() string { + return "ok" +} + +type bar struct{} + +func (bar) Error() string { + return "fail" +} + +func unused() { + type collision struct { + bar + } + _ = collision{} +} + +func main() { + type collision struct { + foo + } + s := error(collision{}) + if str := s.Error(); str != "ok" { + println("s.Error() ==", str) + panic(`s.Error() != "ok"`) + } +} diff --git a/test/fixedbugs/issue6298.go b/test/fixedbugs/issue6298.go new file mode 100644 index 000000000..6303dbe5b --- /dev/null +++ b/test/fixedbugs/issue6298.go @@ -0,0 +1,15 @@ +// compile + +// golang.org/issue/6298. +// Used to cause "internal error: typename ideal bool" + +// Copyright 2013 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 + +func main() { + var x interface{} = "abc"[0] == 'a' + _ = x +} diff --git a/test/fixedbugs/issue6399.go b/test/fixedbugs/issue6399.go new file mode 100644 index 000000000..b3d1c855b --- /dev/null +++ b/test/fixedbugs/issue6399.go @@ -0,0 +1,27 @@ +// compile + +package main + +type Foo interface { + Print() +} + +type Bar struct{} + +func (b Bar) Print() {} + +func main() { + b := make([]Bar, 20) + f := make([]Foo, 20) + for i := range f { + f[i] = b[i] + } + T(f) + _ = make([]struct{}, 1) +} + +func T(f []Foo) { + for i := range f { + f[i].Print() + } +} diff --git a/test/fixedbugs/issue6513.dir/a.go b/test/fixedbugs/issue6513.dir/a.go new file mode 100644 index 000000000..da90ca377 --- /dev/null +++ b/test/fixedbugs/issue6513.dir/a.go @@ -0,0 +1,7 @@ +// Copyright 2013 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 T struct{ int } diff --git a/test/fixedbugs/issue6513.dir/b.go b/test/fixedbugs/issue6513.dir/b.go new file mode 100644 index 000000000..3b35b2d32 --- /dev/null +++ b/test/fixedbugs/issue6513.dir/b.go @@ -0,0 +1,9 @@ +// Copyright 2013 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 b + +import "./a" + +type U struct{ a.T } diff --git a/test/fixedbugs/issue6513.dir/main.go b/test/fixedbugs/issue6513.dir/main.go new file mode 100644 index 000000000..f09b72748 --- /dev/null +++ b/test/fixedbugs/issue6513.dir/main.go @@ -0,0 +1,16 @@ +// Copyright 2013 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 ( + "./a" + "./b" +) + +func main() { + var t a.T + var u b.U + _, _ = t, u +} diff --git a/test/fixedbugs/issue6513.go b/test/fixedbugs/issue6513.go new file mode 100644 index 000000000..b32e0c561 --- /dev/null +++ b/test/fixedbugs/issue6513.go @@ -0,0 +1,10 @@ +// compiledir + +// Copyright 2013 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 6513: embedded builtins may get incorrect qualified +// field name during import. + +package ignored diff --git a/test/import1.go b/test/import1.go index 56b29d58c..d2bb55cbf 100644 --- a/test/import1.go +++ b/test/import1.go @@ -14,5 +14,6 @@ import bufio "os" // ERROR "redeclared|redefinition|incompatible" "imported and import ( "fmt" // GCCGO_ERROR "previous|not used" - fmt "math" // ERROR "redeclared|redefinition|incompatible" "imported and not used" + fmt "math" // ERROR "redeclared|redefinition|incompatible" "imported and not used: \x22math\x22 as fmt" + . "math" // ERROR "imported and not used: \x22math\x22$" ) diff --git a/test/index.go b/test/index.go index f9360c102..a8c471bb3 100644 --- a/test/index.go +++ b/test/index.go @@ -164,7 +164,7 @@ func testExpr(b *bufio.Writer, expr string) { if pass == 0 { fmt.Fprintf(b, "\ttest(func(){use(%s)}, %q)\n", expr, expr) } else { - fmt.Fprintf(b, "\tuse(%s) // ERROR \"index|overflow|truncated\"\n", expr) + fmt.Fprintf(b, "\tuse(%s) // ERROR \"index|overflow|truncated|must be integer\"\n", expr) } } diff --git a/test/interface/explicit.go b/test/interface/explicit.go index eb81156e0..36fa1a422 100644 --- a/test/interface/explicit.go +++ b/test/interface/explicit.go @@ -80,3 +80,22 @@ var m2 M = jj // ERROR "incompatible|wrong type for M method" var m3 = M(ii) // ERROR "invalid|missing" var m4 = M(jj) // ERROR "invalid|wrong type for M method" + + +type B1 interface { + _() +} + +type B2 interface { + M() + _() +} + +type T2 struct{} + +func (t *T2) M() {} +func (t *T2) _() {} + +// Check that nothing satisfies an interface with blank methods. +var b1 B1 = &T2{} // ERROR "incompatible|missing _ method" +var b2 B2 = &T2{} // ERROR "incompatible|missing _ method" diff --git a/test/interface/fail.go b/test/interface/fail.go index 72b854dc0..81eb6cb3c 100644 --- a/test/interface/fail.go +++ b/test/interface/fail.go @@ -14,18 +14,33 @@ type I interface { func main() { shouldPanic(p1) + shouldPanic(p2) } func p1() { var s *S var i I - var e interface {} + var e interface{} e = s i = e.(I) _ = i } -type S struct { +type S struct{} + +func (s *S) _() {} + +type B interface { + _() +} + +func p2() { + var s *S + var b B + var e interface{} + e = s + b = e.(B) + _ = b } func shouldPanic(f func()) { diff --git a/test/mapnan.go b/test/mapnan.go index 60b35fbea..f081cab01 100644 --- a/test/mapnan.go +++ b/test/mapnan.go @@ -13,17 +13,13 @@ import ( "fmt" "math" "time" - "syscall" ) func main() { // Test that NaNs in maps don't go quadratic. t := func(n int) time.Duration { - var u0 syscall.Rusage - if err := syscall.Getrusage(0, &u0); err != nil { - panic(err) - } + t1 := time.Now() m := map[float64]int{} nan := math.NaN() for i := 0; i < n; i++ { @@ -32,11 +28,7 @@ func main() { if len(m) != n { panic("wrong size map after nan insertion") } - var u1 syscall.Rusage - if err := syscall.Getrusage(0, &u1); err != nil { - panic(err) - } - return time.Duration(u1.Utime.Nano() - u0.Utime.Nano()) + return time.Since(t1) } // Depending on the machine and OS, this test might be too fast diff --git a/test/method2.go b/test/method2.go index b63da10dc..aaa850e71 100644 --- a/test/method2.go +++ b/test/method2.go @@ -21,7 +21,7 @@ func (p *P1) val() int { return 1 } // ERROR "receiver.* pointer|invalid pointer type I interface{} type I1 interface{} -func (p I) val() int { return 1 } // ERROR "receiver.*interface|invalid pointer or interface receiver" +func (p I) val() int { return 1 } // ERROR "receiver.*interface|invalid pointer or interface receiver" func (p *I1) val() int { return 1 } // ERROR "receiver.*interface|invalid pointer or interface receiver" type Val interface { @@ -33,4 +33,5 @@ var _ = (*Val).val // ERROR "method" var v Val var pv = &v -var _ = pv.val() // ERROR "method" +var _ = pv.val() // ERROR "method" +var _ = pv.val // ERROR "method" diff --git a/test/nilcheck.go b/test/nilcheck.go new file mode 100644 index 000000000..fe05d05c9 --- /dev/null +++ b/test/nilcheck.go @@ -0,0 +1,184 @@ +// errorcheck -0 -N -d=nil + +// Copyright 2013 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. + +// Test that nil checks are inserted. +// Optimization is disabled, so redundant checks are not removed. + +package p + +type Struct struct { + X int + Y float64 +} + +type BigStruct struct { + X int + Y float64 + A [1<<20]int + Z string +} + +type Empty struct { +} + +type Empty1 struct { + Empty +} + +var ( + intp *int + arrayp *[10]int + array0p *[0]int + bigarrayp *[1<<26]int + structp *Struct + bigstructp *BigStruct + emptyp *Empty + empty1p *Empty1 +) + +func f1() { + _ = *intp // ERROR "nil check" + _ = *arrayp // ERROR "nil check" + _ = *array0p // ERROR "nil check" + _ = *array0p // ERROR "nil check" + _ = *intp // ERROR "nil check" + _ = *arrayp // ERROR "nil check" + _ = *structp // ERROR "nil check" + _ = *emptyp // ERROR "nil check" + _ = *arrayp // ERROR "nil check" +} + +func f2() { + var ( + intp *int + arrayp *[10]int + array0p *[0]int + bigarrayp *[1<<20]int + structp *Struct + bigstructp *BigStruct + emptyp *Empty + empty1p *Empty1 + ) + + _ = *intp // ERROR "nil check" + _ = *arrayp // ERROR "nil check" + _ = *array0p // ERROR "nil check" + _ = *array0p // ERROR "nil check" + _ = *intp // ERROR "nil check" + _ = *arrayp // ERROR "nil check" + _ = *structp // ERROR "nil check" + _ = *emptyp // ERROR "nil check" + _ = *arrayp // ERROR "nil check" + _ = *bigarrayp // ERROR "nil check" + _ = *bigstructp // ERROR "nil check" + _ = *empty1p // ERROR "nil check" +} + +func fx10k() *[10000]int +var b bool + + +func f3(x *[10000]int) { + // Using a huge type and huge offsets so the compiler + // does not expect the memory hardware to fault. + _ = x[9999] // ERROR "nil check" + + for { + if x[9999] != 0 { // ERROR "nil check" + break + } + } + + x = fx10k() + _ = x[9999] // ERROR "nil check" + if b { + _ = x[9999] // ERROR "nil check" + } else { + _ = x[9999] // ERROR "nil check" + } + _ = x[9999] // ERROR "nil check" + + x = fx10k() + if b { + _ = x[9999] // ERROR "nil check" + } else { + _ = x[9999] // ERROR "nil check" + } + _ = x[9999] // ERROR "nil check" + + fx10k() + // This one is a bit redundant, if we figured out that + // x wasn't going to change across the function call. + // But it's a little complex to do and in practice doesn't + // matter enough. + _ = x[9999] // ERROR "nil check" +} + +func f3a() { + x := fx10k() + y := fx10k() + z := fx10k() + _ = &x[9] // ERROR "nil check" + y = z + _ = &x[9] // ERROR "nil check" + x = y + _ = &x[9] // ERROR "nil check" +} + +func f3b() { + x := fx10k() + y := fx10k() + _ = &x[9] // ERROR "nil check" + y = x + _ = &x[9] // ERROR "nil check" + x = y + _ = &x[9] // ERROR "nil check" +} + +func fx10() *[10]int + +func f4(x *[10]int) { + // Most of these have no checks because a real memory reference follows, + // and the offset is small enough that if x is nil, the address will still be + // in the first unmapped page of memory. + + _ = x[9] // ERROR "nil check" + + for { + if x[9] != 0 { // ERROR "nil check" + break + } + } + + x = fx10() + _ = x[9] // ERROR "nil check" + if b { + _ = x[9] // ERROR "nil check" + } else { + _ = x[9] // ERROR "nil check" + } + _ = x[9] // ERROR "nil check" + + x = fx10() + if b { + _ = x[9] // ERROR "nil check" + } else { + _ = &x[9] // ERROR "nil check" + } + _ = x[9] // ERROR "nil check" + + fx10() + _ = x[9] // ERROR "nil check" + + x = fx10() + y := fx10() + _ = &x[9] // ERROR "nil check" + y = x + _ = &x[9] // ERROR "nil check" + x = y + _ = &x[9] // ERROR "nil check" +} + diff --git a/test/nilptr.go b/test/nilptr.go index 793e99673..9631d1618 100644 --- a/test/nilptr.go +++ b/test/nilptr.go @@ -40,6 +40,10 @@ func main() { shouldPanic(p10) shouldPanic(p11) shouldPanic(p12) + shouldPanic(p13) + shouldPanic(p14) + shouldPanic(p15) + shouldPanic(p16) } func shouldPanic(f func()) { @@ -152,3 +156,27 @@ func p12() { var p *T = nil println(*(&((*p).i))) } + +// Tests suggested in golang.org/issue/6080. + +func p13() { + var x *[10]int + y := x[:] + _ = y +} + +func p14() { + println((*[1]int)(nil)[:]) +} + +func p15() { + for i := range (*[1]int)(nil)[:] { + _ = i + } +} + +func p16() { + for i, v := range (*[1]int)(nil)[:] { + _ = i + v + } +} diff --git a/test/nilptr2.go b/test/nilptr2.go new file mode 100644 index 000000000..57a5f8068 --- /dev/null +++ b/test/nilptr2.go @@ -0,0 +1,128 @@ +// run + +// Copyright 2013 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 + +func main() { + ok := true + for _, tt := range tests { + func() { + defer func() { + if err := recover(); err == nil { + println(tt.name, "did not panic") + ok = false + } + }() + tt.fn() + }() + } + if !ok { + println("BUG") + } +} + +var intp *int +var slicep *[]byte +var a10p *[10]int +var a10Mp *[1<<20]int +var structp *Struct +var bigstructp *BigStruct +var i int +var m *M +var m1 *M1 +var m2 *M2 + +func use(interface{}) { +} + +var tests = []struct{ + name string + fn func() +}{ + // Edit .+1,/^}/s/^[^ ].+/ {"&", func() { println(&) }},\n {"\&&", func() { println(\&&) }},/g + {"*intp", func() { println(*intp) }}, + {"&*intp", func() { println(&*intp) }}, + {"*slicep", func() { println(*slicep) }}, + {"&*slicep", func() { println(&*slicep) }}, + {"(*slicep)[0]", func() { println((*slicep)[0]) }}, + {"&(*slicep)[0]", func() { println(&(*slicep)[0]) }}, + {"(*slicep)[i]", func() { println((*slicep)[i]) }}, + {"&(*slicep)[i]", func() { println(&(*slicep)[i]) }}, + {"*a10p", func() { use(*a10p) }}, + {"&*a10p", func() { println(&*a10p) }}, + {"a10p[0]", func() { println(a10p[0]) }}, + {"&a10p[0]", func() { println(&a10p[0]) }}, + {"a10p[i]", func() { println(a10p[i]) }}, + {"&a10p[i]", func() { println(&a10p[i]) }}, + {"*structp", func() { use(*structp) }}, + {"&*structp", func() { println(&*structp) }}, + {"structp.i", func() { println(structp.i) }}, + {"&structp.i", func() { println(&structp.i) }}, + {"structp.j", func() { println(structp.j) }}, + {"&structp.j", func() { println(&structp.j) }}, + {"structp.k", func() { println(structp.k) }}, + {"&structp.k", func() { println(&structp.k) }}, + {"structp.x[0]", func() { println(structp.x[0]) }}, + {"&structp.x[0]", func() { println(&structp.x[0]) }}, + {"structp.x[i]", func() { println(structp.x[i]) }}, + {"&structp.x[i]", func() { println(&structp.x[i]) }}, + {"structp.x[9]", func() { println(structp.x[9]) }}, + {"&structp.x[9]", func() { println(&structp.x[9]) }}, + {"structp.l", func() { println(structp.l) }}, + {"&structp.l", func() { println(&structp.l) }}, + {"*bigstructp", func() { use(*bigstructp) }}, + {"&*bigstructp", func() { println(&*bigstructp) }}, + {"bigstructp.i", func() { println(bigstructp.i) }}, + {"&bigstructp.i", func() { println(&bigstructp.i) }}, + {"bigstructp.j", func() { println(bigstructp.j) }}, + {"&bigstructp.j", func() { println(&bigstructp.j) }}, + {"bigstructp.k", func() { println(bigstructp.k) }}, + {"&bigstructp.k", func() { println(&bigstructp.k) }}, + {"bigstructp.x[0]", func() { println(bigstructp.x[0]) }}, + {"&bigstructp.x[0]", func() { println(&bigstructp.x[0]) }}, + {"bigstructp.x[i]", func() { println(bigstructp.x[i]) }}, + {"&bigstructp.x[i]", func() { println(&bigstructp.x[i]) }}, + {"bigstructp.x[9]", func() { println(bigstructp.x[9]) }}, + {"&bigstructp.x[9]", func() { println(&bigstructp.x[9]) }}, + {"bigstructp.x[100<<20]", func() { println(bigstructp.x[100<<20]) }}, + {"&bigstructp.x[100<<20]", func() { println(&bigstructp.x[100<<20]) }}, + {"bigstructp.l", func() { println(bigstructp.l) }}, + {"&bigstructp.l", func() { println(&bigstructp.l) }}, + {"m1.F()", func() { println(m1.F()) }}, + {"m1.M.F()", func() { println(m1.M.F()) }}, + {"m2.F()", func() { println(m2.F()) }}, + {"m2.M.F()", func() { println(m2.M.F()) }}, +} + +type Struct struct { + i int + j float64 + k string + x [10]int + l []byte +} + +type BigStruct struct { + i int + j float64 + k string + x [128<<20]byte + l []byte +} + +type M struct { +} + +func (m *M) F() int {return 0} + +type M1 struct { + M +} + +type M2 struct { + x int + M +} diff --git a/test/nilptr3.go b/test/nilptr3.go new file mode 100644 index 000000000..08597a02d --- /dev/null +++ b/test/nilptr3.go @@ -0,0 +1,191 @@ +// errorcheck -0 -d=nil + +// Copyright 2013 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. + +// Test that nil checks are removed. +// Optimization is enabled. + +package p + +type Struct struct { + X int + Y float64 +} + +type BigStruct struct { + X int + Y float64 + A [1<<20]int + Z string +} + +type Empty struct { +} + +type Empty1 struct { + Empty +} + +var ( + intp *int + arrayp *[10]int + array0p *[0]int + bigarrayp *[1<<26]int + structp *Struct + bigstructp *BigStruct + emptyp *Empty + empty1p *Empty1 +) + +func f1() { + _ = *intp // ERROR "generated nil check" + + // This one should be removed but the block copy needs + // to be turned into its own pseudo-op in order to see + // the indirect. + _ = *arrayp // ERROR "generated nil check" + + // 0-byte indirect doesn't suffice + _ = *array0p // ERROR "generated nil check" + _ = *array0p // ERROR "removed repeated nil check" 386 + + _ = *intp // ERROR "removed repeated nil check" + _ = *arrayp // ERROR "removed repeated nil check" + _ = *structp // ERROR "generated nil check" + _ = *emptyp // ERROR "generated nil check" + _ = *arrayp // ERROR "removed repeated nil check" +} + +func f2() { + var ( + intp *int + arrayp *[10]int + array0p *[0]int + bigarrayp *[1<<20]int + structp *Struct + bigstructp *BigStruct + emptyp *Empty + empty1p *Empty1 + ) + + _ = *intp // ERROR "generated nil check" + _ = *arrayp // ERROR "generated nil check" + _ = *array0p // ERROR "generated nil check" + _ = *array0p // ERROR "removed repeated nil check" + _ = *intp // ERROR "removed repeated nil check" + _ = *arrayp // ERROR "removed repeated nil check" + _ = *structp // ERROR "generated nil check" + _ = *emptyp // ERROR "generated nil check" + _ = *arrayp // ERROR "removed repeated nil check" + _ = *bigarrayp // ERROR "generated nil check" ARM removed nil check before indirect!! + _ = *bigstructp // ERROR "generated nil check" + _ = *empty1p // ERROR "generated nil check" +} + +func fx10k() *[10000]int +var b bool + + +func f3(x *[10000]int) { + // Using a huge type and huge offsets so the compiler + // does not expect the memory hardware to fault. + _ = x[9999] // ERROR "generated nil check" + + for { + if x[9999] != 0 { // ERROR "generated nil check" + break + } + } + + x = fx10k() + _ = x[9999] // ERROR "generated nil check" + if b { + _ = x[9999] // ERROR "removed repeated nil check" + } else { + _ = x[9999] // ERROR "removed repeated nil check" + } + _ = x[9999] // ERROR "generated nil check" + + x = fx10k() + if b { + _ = x[9999] // ERROR "generated nil check" + } else { + _ = x[9999] // ERROR "generated nil check" + } + _ = x[9999] // ERROR "generated nil check" + + fx10k() + // This one is a bit redundant, if we figured out that + // x wasn't going to change across the function call. + // But it's a little complex to do and in practice doesn't + // matter enough. + _ = x[9999] // ERROR "generated nil check" +} + +func f3a() { + x := fx10k() + y := fx10k() + z := fx10k() + _ = &x[9] // ERROR "generated nil check" + y = z + _ = &x[9] // ERROR "removed repeated nil check" + x = y + _ = &x[9] // ERROR "generated nil check" +} + +func f3b() { + x := fx10k() + y := fx10k() + _ = &x[9] // ERROR "generated nil check" + y = x + _ = &x[9] // ERROR "removed repeated nil check" + x = y + _ = &x[9] // ERROR "removed repeated nil check" +} + +func fx10() *[10]int + +func f4(x *[10]int) { + // Most of these have no checks because a real memory reference follows, + // and the offset is small enough that if x is nil, the address will still be + // in the first unmapped page of memory. + + _ = x[9] // ERROR "removed nil check before indirect" + + for { + if x[9] != 0 { // ERROR "removed nil check before indirect" + break + } + } + + x = fx10() + _ = x[9] // ERROR "removed nil check before indirect" + if b { + _ = x[9] // ERROR "removed nil check before indirect" + } else { + _ = x[9] // ERROR "removed nil check before indirect" + } + _ = x[9] // ERROR "removed nil check before indirect" + + x = fx10() + if b { + _ = x[9] // ERROR "removed nil check before indirect" + } else { + _ = &x[9] // ERROR "generated nil check" + } + _ = x[9] // ERROR "removed nil check before indirect" + + fx10() + _ = x[9] // ERROR "removed nil check before indirect" + + x = fx10() + y := fx10() + _ = &x[9] // ERROR "generated nil check" + y = x + _ = &x[9] // ERROR "removed repeated nil check" + x = y + _ = &x[9] // ERROR "removed repeated nil check" +} + diff --git a/test/recover.go b/test/recover.go index 7c27d7c4d..071be6667 100644 --- a/test/recover.go +++ b/test/recover.go @@ -10,31 +10,72 @@ package main import ( "os" + "reflect" "runtime" ) func main() { + // go.tools/ssa/interp still has: + // - some lesser bugs in recover() + // - incomplete support for reflection + interp := os.Getenv("GOSSAINTERP") != "" + test1() test1WithClosures() test2() test3() - // exp/ssa/interp still has some bugs in recover(). - if os.Getenv("GOSSAINTERP") == "" { + if !interp { test4() - test5() } + test5() test6() test6WithClosures() test7() + test8() + test9() + if !interp { + test9reflect1() + test9reflect2() + } + test10() + if !interp { + test10reflect1() + test10reflect2() + } + test11() + if !interp { + test11reflect1() + test11reflect2() + } + test12() + if !interp { + test12reflect1() + test12reflect2() + } + test13() + if !interp { + test13reflect1() + test13reflect2() + } + test14() + if !interp { + test14reflect1() + test14reflect2() + test15() + } } func die() { runtime.Breakpoint() // can't depend on panic } -func mustRecover(x interface{}) { - mustNotRecover() // because it's not a defer call - v := recover() +func mustRecoverBody(v1, v2, v3, x interface{}) { + v := v1 + if v != nil { + println("spurious recover", v) + die() + } + v = v2 if v == nil { println("missing recover") die() // panic is useless here @@ -45,13 +86,21 @@ func mustRecover(x interface{}) { } // the value should be gone now regardless - v = recover() + v = v3 if v != nil { println("recover didn't recover") die() } } +func doubleRecover() interface{} { + return recover() +} + +func mustRecover(x interface{}) { + mustRecoverBody(doubleRecover(), recover(), recover(), x) +} + func mustNotRecover() { v := recover() if v != nil { @@ -277,3 +326,180 @@ func test8() { die() } } + +type I interface { + M() +} + +// pointer receiver, so no wrapper in i.M() +type T1 struct{} + +func (*T1) M() { + mustRecoverBody(doubleRecover(), recover(), recover(), 9) +} + +func test9() { + var i I = &T1{} + defer i.M() + panic(9) +} + +func test9reflect1() { + f := reflect.ValueOf(&T1{}).Method(0).Interface().(func()) + defer f() + panic(9) +} + +func test9reflect2() { + f := reflect.TypeOf(&T1{}).Method(0).Func.Interface().(func(*T1)) + defer f(&T1{}) + panic(9) +} + +// word-sized value receiver, so no wrapper in i.M() +type T2 uintptr + +func (T2) M() { + mustRecoverBody(doubleRecover(), recover(), recover(), 10) +} + +func test10() { + var i I = T2(0) + defer i.M() + panic(10) +} + +func test10reflect1() { + f := reflect.ValueOf(T2(0)).Method(0).Interface().(func()) + defer f() + panic(10) +} + +func test10reflect2() { + f := reflect.TypeOf(T2(0)).Method(0).Func.Interface().(func(T2)) + defer f(T2(0)) + panic(10) +} + +// tiny receiver, so basic wrapper in i.M() +type T3 struct{} + +func (T3) M() { + mustRecoverBody(doubleRecover(), recover(), recover(), 11) +} + +func test11() { + var i I = T3{} + defer i.M() + panic(11) +} + +func test11reflect1() { + f := reflect.ValueOf(T3{}).Method(0).Interface().(func()) + defer f() + panic(11) +} + +func test11reflect2() { + f := reflect.TypeOf(T3{}).Method(0).Func.Interface().(func(T3)) + defer f(T3{}) + panic(11) +} + +// large receiver, so basic wrapper in i.M() +type T4 [2]string + +func (T4) M() { + mustRecoverBody(doubleRecover(), recover(), recover(), 12) +} + +func test12() { + var i I = T4{} + defer i.M() + panic(12) +} + +func test12reflect1() { + f := reflect.ValueOf(T4{}).Method(0).Interface().(func()) + defer f() + panic(12) +} + +func test12reflect2() { + f := reflect.TypeOf(T4{}).Method(0).Func.Interface().(func(T4)) + defer f(T4{}) + panic(12) +} + +// enormous receiver, so wrapper splits stack to call M +type T5 [8192]byte + +func (T5) M() { + mustRecoverBody(doubleRecover(), recover(), recover(), 13) +} + +func test13() { + var i I = T5{} + defer i.M() + panic(13) +} + +func test13reflect1() { + f := reflect.ValueOf(T5{}).Method(0).Interface().(func()) + defer f() + panic(13) +} + +func test13reflect2() { + f := reflect.TypeOf(T5{}).Method(0).Func.Interface().(func(T5)) + defer f(T5{}) + panic(13) +} + +// enormous receiver + enormous method frame, so wrapper splits stack to call M, +// and then M splits stack to allocate its frame. +// recover must look back two frames to find the panic. +type T6 [8192]byte + +var global byte + +func (T6) M() { + var x [8192]byte + x[0] = 1 + x[1] = 2 + for i := range x { + global += x[i] + } + mustRecoverBody(doubleRecover(), recover(), recover(), 14) +} + +func test14() { + var i I = T6{} + defer i.M() + panic(14) +} + +func test14reflect1() { + f := reflect.ValueOf(T6{}).Method(0).Interface().(func()) + defer f() + panic(14) +} + +func test14reflect2() { + f := reflect.TypeOf(T6{}).Method(0).Func.Interface().(func(T6)) + defer f(T6{}) + panic(14) +} + +// function created by reflect.MakeFunc + +func reflectFunc(args []reflect.Value) (results []reflect.Value) { + mustRecoverBody(doubleRecover(), recover(), recover(), 15) + return nil +} + +func test15() { + f := reflect.MakeFunc(reflect.TypeOf((func())(nil)), reflectFunc).Interface().(func()) + defer f() + panic(15) +} diff --git a/test/recover3.go b/test/recover3.go index ebfa0a307..e17bfb3f6 100644 --- a/test/recover3.go +++ b/test/recover3.go @@ -64,7 +64,8 @@ func main() { i = 99999 var sl []int - check("array-bounds", func() { println(p[i]) }, "index out of range") + p1 := new([10]int) + check("array-bounds", func() { println(p1[i]) }, "index out of range") check("slice-bounds", func() { println(sl[i]) }, "index out of range") var inter interface{} diff --git a/test/return.go b/test/return.go index dcf32f86f..482f22bd5 100644 --- a/test/return.go +++ b/test/return.go @@ -272,7 +272,6 @@ func _() int { } // ERROR "missing return" func _() int { -L: print(1) if x == nil { panic(2) @@ -666,17 +665,6 @@ func _() int { } } -func _() int { - print(1) - switch x.(type) { - case int: - print(2) - fallthrough - default: - return 4 - } -} - // if no default or some case doesn't terminate, switch is no longer okay func _() int { @@ -713,17 +701,6 @@ func _() int { switch x.(type) { case int: print(2) - fallthrough - case float64: - return 4 - } -} // ERROR "missing return" - -func _() int { - print(1) - switch x.(type) { - case int: - print(2) panic(3) } } // ERROR "missing return" @@ -994,7 +971,6 @@ func _() int { } // ERROR "missing return" func _() int { -L: if x == nil { panic(2) } else if x == 1 { @@ -1356,16 +1332,6 @@ func _() int { } } -func _() int { - switch x.(type) { - case int: - print(2) - fallthrough - default: - return 4 - } -} - // if no default or some case doesn't terminate, switch is no longer okay func _() int { @@ -1398,16 +1364,6 @@ func _() int { switch x.(type) { case int: print(2) - fallthrough - case float64: - return 4 - } -} // ERROR "missing return" - -func _() int { - switch x.(type) { - case int: - print(2) panic(3) } } // ERROR "missing return" @@ -1450,6 +1406,16 @@ L: } } // ERROR "missing return" +func _() int { + switch x.(type) { + default: + return 4 + case int, float64: + print(2) + panic(3) + } +} + // again, with func literals var _ = func() int { @@ -1708,7 +1674,6 @@ var _ = func() int { } // ERROR "missing return" var _ = func() int { -L: print(1) if x == nil { panic(2) @@ -2102,17 +2067,6 @@ var _ = func() int { } } -var _ = func() int { - print(1) - switch x.(type) { - case int: - print(2) - fallthrough - default: - return 4 - } -} - // if no default or some case doesn't terminate, switch is no longer okay var _ = func() int { @@ -2149,17 +2103,6 @@ var _ = func() int { switch x.(type) { case int: print(2) - fallthrough - case float64: - return 4 - } -} // ERROR "missing return" - -var _ = func() int { - print(1) - switch x.(type) { - case int: - print(2) panic(3) } } // ERROR "missing return" @@ -2430,7 +2373,6 @@ var _ = func() int { } // ERROR "missing return" var _ = func() int { -L: if x == nil { panic(2) } else if x == 1 { @@ -2792,16 +2734,6 @@ var _ = func() int { } } -var _ = func() int { - switch x.(type) { - case int: - print(2) - fallthrough - default: - return 4 - } -} - // if no default or some case doesn't terminate, switch is no longer okay var _ = func() int { @@ -2834,16 +2766,6 @@ var _ = func() int { switch x.(type) { case int: print(2) - fallthrough - case float64: - return 4 - } -} // ERROR "missing return" - -var _ = func() int { - switch x.(type) { - case int: - print(2) panic(3) } } // ERROR "missing return" @@ -2886,4 +2808,14 @@ L: } } // ERROR "missing return" +var _ = func() int { + switch x.(type) { + default: + return 4 + case int, float64: + print(2) + panic(3) + } +} + /**/ diff --git a/test/run.go b/test/run.go index 5e167d6b0..f1f1ec034 100644 --- a/test/run.go +++ b/test/run.go @@ -27,6 +27,7 @@ import ( "sort" "strconv" "strings" + "unicode" ) var ( @@ -134,7 +135,7 @@ func main() { if !*verbose && test.err == nil { continue } - fmt.Printf("%-20s %-20s: %s\n", test.action, test.goFileName(), errStr) + fmt.Printf("# go run run.go -- %s\n%-20s %-20s: %s\n", path.Join(test.dir, test.gofile), test.action, test.goFileName(), errStr) } if *summary { @@ -299,14 +300,17 @@ func goDirPackages(longdir string) ([][]string, error) { return pkgs, nil } +type context struct { + GOOS string + GOARCH string +} + // shouldTest looks for build tags in a source file and returns // whether the file should be used according to the tags. func shouldTest(src string, goos, goarch string) (ok bool, whyNot string) { if idx := strings.Index(src, "\npackage"); idx >= 0 { src = src[:idx] } - notgoos := "!" + goos - notgoarch := "!" + goarch for _, line := range strings.Split(src, "\n") { line = strings.TrimSpace(line) if strings.HasPrefix(line, "//") { @@ -318,29 +322,59 @@ func shouldTest(src string, goos, goarch string) (ok bool, whyNot string) { if len(line) == 0 || line[0] != '+' { continue } + ctxt := &context{ + GOOS: goos, + GOARCH: goarch, + } words := strings.Fields(line) if words[0] == "+build" { - for _, word := range words { - switch word { - case goos, goarch: - return true, "" - case notgoos, notgoarch: - continue - default: - if word[0] == '!' { - // NOT something-else - return true, "" - } + ok := false + for _, word := range words[1:] { + if ctxt.match(word) { + ok = true + break } } - // no matching tag found. - return false, line + if !ok { + // no matching tag found. + return false, line + } } } - // no build tags. + // no build tags return true, "" } +func (ctxt *context) match(name string) bool { + if name == "" { + return false + } + if i := strings.Index(name, ","); i >= 0 { + // comma-separated list + return ctxt.match(name[:i]) && ctxt.match(name[i+1:]) + } + if strings.HasPrefix(name, "!!") { // bad syntax, reject always + return false + } + if strings.HasPrefix(name, "!") { // negation + return len(name) > 1 && !ctxt.match(name[1:]) + } + + // Tags must be letters, digits, underscores or dots. + // Unlike in Go identifiers, all digits are fine (e.g., "386"). + for _, c := range name { + if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' { + return false + } + } + + if name == ctxt.GOOS || name == ctxt.GOARCH { + return true + } + + return false +} + func init() { checkShouldTest() } // run runs a test. @@ -815,7 +849,7 @@ func defaultRunOutputLimit() int { return cpu } -// checkShouldTest runs canity checks on the shouldTest function. +// checkShouldTest runs sanity checks on the shouldTest function. func checkShouldTest() { assert := func(ok bool, _ string) { if !ok { @@ -823,11 +857,28 @@ func checkShouldTest() { } } assertNot := func(ok bool, _ string) { assert(!ok, "") } + + // Simple tests. assert(shouldTest("// +build linux", "linux", "arm")) assert(shouldTest("// +build !windows", "linux", "arm")) assertNot(shouldTest("// +build !windows", "windows", "amd64")) - assertNot(shouldTest("// +build arm 386", "linux", "amd64")) + + // A file with no build tags will always be tested. assert(shouldTest("// This is a test.", "os", "arch")) + + // Build tags separated by a space are OR-ed together. + assertNot(shouldTest("// +build arm 386", "linux", "amd64")) + + // Build tags seperated by a comma are AND-ed together. + assertNot(shouldTest("// +build !windows,!plan9", "windows", "amd64")) + assertNot(shouldTest("// +build !windows,!plan9", "plan9", "386")) + + // Build tags on multiple lines are AND-ed together. + assert(shouldTest("// +build !windows\n// +build amd64", "linux", "amd64")) + assertNot(shouldTest("// +build !windows\n// +build amd64", "windows", "amd64")) + + // Test that (!a OR !b) matches anything. + assert(shouldTest("// +build !windows !plan9", "windows", "amd64")) } // envForDir returns a copy of the environment diff --git a/test/shift1.go b/test/shift1.go index 71f7861c6..44a3792c4 100644 --- a/test/shift1.go +++ b/test/shift1.go @@ -23,7 +23,7 @@ var ( // non-constant shift expressions var ( - e1 = g(2.0 << s) // ERROR "invalid" "as type interface" + e1 = g(2.0 << s) // ERROR "invalid|shift of non-integer operand" "as type interface" f1 = h(2 << s) // ERROR "invalid" "as type float64" g1 int64 = 1.1 << s // ERROR "truncated" ) @@ -39,12 +39,12 @@ var ( var ( // issues 4882, 4936. - a3 = 1.0<<s + 0 // ERROR "invalid operation|shift of non-integer operand" + a3 = 1.0<<s + 0 // ERROR "invalid|shift of non-integer operand" // issue 4937 - b3 = 1<<s + 1 + 1.0 // ERROR "invalid operation|shift of non-integer operand" + b3 = 1<<s + 1 + 1.0 // ERROR "invalid|shift of non-integer operand" // issue 5014 - c3 = complex(1<<s, 0) // ERROR "shift of type float64" - d3 int = complex(1<<s, 3) // ERROR "cannot use.*as type int" "shift of type float64" + c3 = complex(1<<s, 0) // ERROR "invalid|shift of type float64" + d3 int = complex(1<<s, 3) // ERROR "non-integer|cannot use.*as type int" "shift of type float64" e3 = real(1 << s) // ERROR "invalid" f3 = imag(1 << s) // ERROR "invalid" ) @@ -61,60 +61,61 @@ func _() { o = 1<<s == 2<<s // 1 and 2 have type int; o == true if ints are 32bits in size // next test only fails on 32bit systems // p = 1<<s == 1<<33 // illegal if ints are 32bits in size: 1 has type int, but 1<<33 overflows int - u = 1.0 << s // ERROR "float64" - u1 = 1.0<<s != 0 // ERROR "float64" - u2 = 1<<s != 1.0 // ERROR "float64" - v float32 = 1 << s // ERROR "float32" + u = 1.0 << s // ERROR "non-integer|float64" + u1 = 1.0<<s != 0 // ERROR "non-integer|float64" + u2 = 1<<s != 1.0 // ERROR "non-integer|float64" + v float32 = 1 << s // ERROR "non-integer|float32" w int64 = 1.0 << 33 // 1.0<<33 is a constant shift expression + _, _, _, _, _, _, _, _, _, _ = j, k, m, n, o, u, u1, u2, v, w ) } // shifts in comparisons w/ untyped operands var ( _ = 1<<s == 1 - _ = 1<<s == 1. // ERROR "shift of type float64" - _ = 1.<<s == 1 // ERROR "shift of type float64" - _ = 1.<<s == 1. // ERROR "shift of type float64" + _ = 1<<s == 1. // ERROR "invalid|shift of type float64" + _ = 1.<<s == 1 // ERROR "invalid|shift of type float64" + _ = 1.<<s == 1. // ERROR "invalid|non-integer|shift of type float64" _ = 1<<s+1 == 1 - _ = 1<<s+1 == 1. // ERROR "shift of type float64" - _ = 1<<s+1. == 1 // ERROR "shift of type float64" - _ = 1<<s+1. == 1. // ERROR "shift of type float64" - _ = 1.<<s+1 == 1 // ERROR "shift of type float64" - _ = 1.<<s+1 == 1. // ERROR "shift of type float64" - _ = 1.<<s+1. == 1 // ERROR "shift of type float64" - _ = 1.<<s+1. == 1. // ERROR "shift of type float64" + _ = 1<<s+1 == 1. // ERROR "invalid|shift of type float64" + _ = 1<<s+1. == 1 // ERROR "invalid|shift of type float64" + _ = 1<<s+1. == 1. // ERROR "invalid|shift of type float64" + _ = 1.<<s+1 == 1 // ERROR "invalid|shift of type float64" + _ = 1.<<s+1 == 1. // ERROR "invalid|shift of type float64" + _ = 1.<<s+1. == 1 // ERROR "invalid|shift of type float64" + _ = 1.<<s+1. == 1. // ERROR "invalid|non-integer|shift of type float64" _ = 1<<s == 1<<s - _ = 1<<s == 1.<<s // ERROR "shift of type float64" - _ = 1.<<s == 1<<s // ERROR "shift of type float64" - _ = 1.<<s == 1.<<s // ERROR "shift of type float64" + _ = 1<<s == 1.<<s // ERROR "invalid|shift of type float64" + _ = 1.<<s == 1<<s // ERROR "invalid|shift of type float64" + _ = 1.<<s == 1.<<s // ERROR "invalid|non-integer|shift of type float64" _ = 1<<s+1<<s == 1 - _ = 1<<s+1<<s == 1. // ERROR "shift of type float64" - _ = 1<<s+1.<<s == 1 // ERROR "shift of type float64" - _ = 1<<s+1.<<s == 1. // ERROR "shift of type float64" - _ = 1.<<s+1<<s == 1 // ERROR "shift of type float64" - _ = 1.<<s+1<<s == 1. // ERROR "shift of type float64" - _ = 1.<<s+1.<<s == 1 // ERROR "shift of type float64" - _ = 1.<<s+1.<<s == 1. // ERROR "shift of type float64" + _ = 1<<s+1<<s == 1. // ERROR "invalid|shift of type float64" + _ = 1<<s+1.<<s == 1 // ERROR "invalid|shift of type float64" + _ = 1<<s+1.<<s == 1. // ERROR "invalid|shift of type float64" + _ = 1.<<s+1<<s == 1 // ERROR "invalid|shift of type float64" + _ = 1.<<s+1<<s == 1. // ERROR "invalid|shift of type float64" + _ = 1.<<s+1.<<s == 1 // ERROR "invalid|shift of type float64" + _ = 1.<<s+1.<<s == 1. // ERROR "invalid|non-integer|shift of type float64" _ = 1<<s+1<<s == 1<<s+1<<s - _ = 1<<s+1<<s == 1<<s+1.<<s // ERROR "shift of type float64" - _ = 1<<s+1<<s == 1.<<s+1<<s // ERROR "shift of type float64" - _ = 1<<s+1<<s == 1.<<s+1.<<s // ERROR "shift of type float64" - _ = 1<<s+1.<<s == 1<<s+1<<s // ERROR "shift of type float64" - _ = 1<<s+1.<<s == 1<<s+1.<<s // ERROR "shift of type float64" - _ = 1<<s+1.<<s == 1.<<s+1<<s // ERROR "shift of type float64" - _ = 1<<s+1.<<s == 1.<<s+1.<<s // ERROR "shift of type float64" - _ = 1.<<s+1<<s == 1<<s+1<<s // ERROR "shift of type float64" - _ = 1.<<s+1<<s == 1<<s+1.<<s // ERROR "shift of type float64" - _ = 1.<<s+1<<s == 1.<<s+1<<s // ERROR "shift of type float64" - _ = 1.<<s+1<<s == 1.<<s+1.<<s // ERROR "shift of type float64" - _ = 1.<<s+1.<<s == 1<<s+1<<s // ERROR "shift of type float64" - _ = 1.<<s+1.<<s == 1<<s+1.<<s // ERROR "shift of type float64" - _ = 1.<<s+1.<<s == 1.<<s+1<<s // ERROR "shift of type float64" - _ = 1.<<s+1.<<s == 1.<<s+1.<<s // ERROR "shift of type float64" + _ = 1<<s+1<<s == 1<<s+1.<<s // ERROR "invalid|shift of type float64" + _ = 1<<s+1<<s == 1.<<s+1<<s // ERROR "invalid|shift of type float64" + _ = 1<<s+1<<s == 1.<<s+1.<<s // ERROR "invalid|shift of type float64" + _ = 1<<s+1.<<s == 1<<s+1<<s // ERROR "invalid|shift of type float64" + _ = 1<<s+1.<<s == 1<<s+1.<<s // ERROR "invalid|shift of type float64" + _ = 1<<s+1.<<s == 1.<<s+1<<s // ERROR "invalid|shift of type float64" + _ = 1<<s+1.<<s == 1.<<s+1.<<s // ERROR "invalid|non-integer|shift of type float64" + _ = 1.<<s+1<<s == 1<<s+1<<s // ERROR "invalid|shift of type float64" + _ = 1.<<s+1<<s == 1<<s+1.<<s // ERROR "invalid|shift of type float64" + _ = 1.<<s+1<<s == 1.<<s+1<<s // ERROR "invalid|shift of type float64" + _ = 1.<<s+1<<s == 1.<<s+1.<<s // ERROR "invalid|non-integer|shift of type float64" + _ = 1.<<s+1.<<s == 1<<s+1<<s // ERROR "invalid|shift of type float64" + _ = 1.<<s+1.<<s == 1<<s+1.<<s // ERROR "invalid|non-integer|shift of type float64" + _ = 1.<<s+1.<<s == 1.<<s+1<<s // ERROR "invalid|non-integer|shift of type float64" + _ = 1.<<s+1.<<s == 1.<<s+1.<<s // ERROR "invalid|non-integer|shift of type float64" ) // shifts in comparisons w/ typed operands @@ -122,21 +123,21 @@ var ( x int _ = 1<<s == x _ = 1.<<s == x - _ = 1.1<<s == x // ERROR "1.1 truncated" + _ = 1.1<<s == x // ERROR "truncated" _ = 1<<s+x == 1 _ = 1<<s+x == 1. - _ = 1<<s+x == 1.1 // ERROR "1.1 truncated" + _ = 1<<s+x == 1.1 // ERROR "truncated" _ = 1.<<s+x == 1 _ = 1.<<s+x == 1. - _ = 1.<<s+x == 1.1 // ERROR "1.1 truncated" - _ = 1.1<<s+x == 1 // ERROR "1.1 truncated" - _ = 1.1<<s+x == 1. // ERROR "1.1 truncated" - _ = 1.1<<s+x == 1.1 // ERROR "1.1 truncated" + _ = 1.<<s+x == 1.1 // ERROR "truncated" + _ = 1.1<<s+x == 1 // ERROR "truncated" + _ = 1.1<<s+x == 1. // ERROR "truncated" + _ = 1.1<<s+x == 1.1 // ERROR "truncated" _ = 1<<s == x<<s _ = 1.<<s == x<<s - _ = 1.1<<s == x<<s // ERROR "1.1 truncated" + _ = 1.1<<s == x<<s // ERROR "truncated" ) // shifts as operands in non-arithmetic operations and as arguments @@ -146,43 +147,43 @@ func _() { _ = a[1<<s] _ = a[1.] // For now, the spec disallows these. We may revisit past Go 1.1. - _ = a[1.<<s] // ERROR "shift of type float64" - _ = a[1.1<<s] // ERROR "shift of type float64" + _ = a[1.<<s] // ERROR "integer|shift of type float64" + _ = a[1.1<<s] // ERROR "integer|shift of type float64" _ = make([]int, 1) _ = make([]int, 1.) _ = make([]int, 1.<<s) - _ = make([]int, 1.1<<s) // ERROR "1.1 truncated" + _ = make([]int, 1.1<<s) // ERROR "non-integer|truncated" _ = float32(1) - _ = float32(1 << s) // ERROR "shift of type float32" + _ = float32(1 << s) // ERROR "non-integer|shift of type float32" _ = float32(1.) - _ = float32(1. << s) // ERROR "shift of type float32" - _ = float32(1.1 << s) // ERROR "shift of type float32" + _ = float32(1. << s) // ERROR "non-integer|shift of type float32" + _ = float32(1.1 << s) // ERROR "non-integer|shift of type float32" _ = append(a, 1<<s) _ = append(a, 1.<<s) - _ = append(a, 1.1<<s) // ERROR "1.1 truncated" + _ = append(a, 1.1<<s) // ERROR "truncated" var b []float32 - _ = append(b, 1<<s) // ERROR "type float32" - _ = append(b, 1.<<s) // ERROR "type float32" - _ = append(b, 1.1<<s) // ERROR "type float32" + _ = append(b, 1<<s) // ERROR "non-integer|type float32" + _ = append(b, 1.<<s) // ERROR "non-integer|type float32" + _ = append(b, 1.1<<s) // ERROR "non-integer|type float32" - _ = complex(1.<<s, 0) // ERROR "shift of type float64" - _ = complex(1.1<<s, 0) // ERROR "shift of type float64" - _ = complex(0, 1.<<s) // ERROR "shift of type float64" - _ = complex(0, 1.1<<s) // ERROR "shift of type float64" + _ = complex(1.<<s, 0) // ERROR "non-integer|shift of type float64" + _ = complex(1.1<<s, 0) // ERROR "non-integer|shift of type float64" + _ = complex(0, 1.<<s) // ERROR "non-integer|shift of type float64" + _ = complex(0, 1.1<<s) // ERROR "non-integer|shift of type float64" var a4 float64 var b4 int - _ = complex(1<<s, a4) // ERROR "shift of type float64" - _ = complex(1<<s, b4) // ERROR "invalid" + _ = complex(1<<s, a4) // ERROR "non-integer|shift of type float64" + _ = complex(1<<s, b4) // ERROR "invalid|non-integer|" var m1 map[int]string delete(m1, 1<<s) delete(m1, 1.<<s) - delete(m1, 1.1<<s) // ERROR "1.1 truncated|shift of type float64" + delete(m1, 1.1<<s) // ERROR "truncated|shift of type float64" var m2 map[float32]string delete(m2, 1<<s) // ERROR "invalid|cannot use 1 << s as type float32" @@ -195,46 +196,46 @@ func _() { var s uint _ = 1 << (1 << s) _ = 1 << (1. << s) - _ = 1 << (1.1 << s) // ERROR "1.1 truncated" - _ = 1. << (1 << s) // ERROR "shift of type float64" - _ = 1. << (1. << s) // ERROR "shift of type float64" - _ = 1.1 << (1.1 << s) // ERROR "invalid|1.1 truncated" + _ = 1 << (1.1 << s) // ERROR "non-integer|truncated" + _ = 1. << (1 << s) // ERROR "non-integer|shift of type float64" + _ = 1. << (1. << s) // ERROR "non-integer|shift of type float64" + _ = 1.1 << (1.1 << s) // ERROR "invalid|non-integer|truncated" _ = (1 << s) << (1 << s) _ = (1 << s) << (1. << s) - _ = (1 << s) << (1.1 << s) // ERROR "1.1 truncated" - _ = (1. << s) << (1 << s) // ERROR "shift of type float64" - _ = (1. << s) << (1. << s) // ERROR "shift of type float64" - _ = (1.1 << s) << (1.1 << s) // ERROR "invalid|1.1 truncated" + _ = (1 << s) << (1.1 << s) // ERROR "truncated" + _ = (1. << s) << (1 << s) // ERROR "non-integer|shift of type float64" + _ = (1. << s) << (1. << s) // ERROR "non-integer|shift of type float64" + _ = (1.1 << s) << (1.1 << s) // ERROR "invalid|non-integer|truncated" var x int x = 1 << (1 << s) x = 1 << (1. << s) - x = 1 << (1.1 << s) // ERROR "1.1 truncated" + x = 1 << (1.1 << s) // ERROR "truncated" x = 1. << (1 << s) x = 1. << (1. << s) - x = 1.1 << (1.1 << s) // ERROR "1.1 truncated" + x = 1.1 << (1.1 << s) // ERROR "truncated" x = (1 << s) << (1 << s) x = (1 << s) << (1. << s) - x = (1 << s) << (1.1 << s) // ERROR "1.1 truncated" + x = (1 << s) << (1.1 << s) // ERROR "truncated" x = (1. << s) << (1 << s) x = (1. << s) << (1. << s) - x = (1.1 << s) << (1.1 << s) // ERROR "1.1 truncated" + x = (1.1 << s) << (1.1 << s) // ERROR "truncated" var y float32 - y = 1 << (1 << s) // ERROR "type float32" - y = 1 << (1. << s) // ERROR "type float32" - y = 1 << (1.1 << s) // ERROR "invalid|1.1 truncated|float32" - y = 1. << (1 << s) // ERROR "type float32" - y = 1. << (1. << s) // ERROR "type float32" - y = 1.1 << (1.1 << s) // ERROR "invalid|1.1 truncated|float32" + y = 1 << (1 << s) // ERROR "non-integer|type float32" + y = 1 << (1. << s) // ERROR "non-integer|type float32" + y = 1 << (1.1 << s) // ERROR "invalid|truncated|float32" + y = 1. << (1 << s) // ERROR "non-integer|type float32" + y = 1. << (1. << s) // ERROR "non-integer|type float32" + y = 1.1 << (1.1 << s) // ERROR "invalid|truncated|float32" var z complex128 - z = (1 << s) << (1 << s) // ERROR "type complex128" - z = (1 << s) << (1. << s) // ERROR "type complex128" - z = (1 << s) << (1.1 << s) // ERROR "invalid|1.1 truncated|complex128" - z = (1. << s) << (1 << s) // ERROR "type complex128" - z = (1. << s) << (1. << s) // ERROR "type complex128" - z = (1.1 << s) << (1.1 << s) // ERROR "invalid|1.1 truncated|complex128" + z = (1 << s) << (1 << s) // ERROR "non-integer|type complex128" + z = (1 << s) << (1. << s) // ERROR "non-integer|type complex128" + z = (1 << s) << (1.1 << s) // ERROR "invalid|truncated|complex128" + z = (1. << s) << (1 << s) // ERROR "non-integer|type complex128" + z = (1. << s) << (1. << s) // ERROR "non-integer|type complex128" + z = (1.1 << s) << (1.1 << s) // ERROR "invalid|truncated|complex128" } diff --git a/test/shift2.go b/test/shift2.go index 88ef3c40f..80e6bbc19 100644 --- a/test/shift2.go +++ b/test/shift2.go @@ -20,6 +20,7 @@ var ( i = 1 << s // 1 has type int j int32 = 1 << s // 1 has type int32; j == 0 k = uint64(1 << s) // 1 has type uint64; k == 1<<33 + l = g(1 << s) // 1 has type int m int = 1.0 << s // legal: 1.0 has type int w int64 = 1.0 << 33 // legal: 1.0<<33 is a constant shift expression ) diff --git a/test/sizeof.go b/test/sizeof.go index 9aa95677d..c3db1e5c3 100644 --- a/test/sizeof.go +++ b/test/sizeof.go @@ -1,4 +1,4 @@ -// compile +// run // Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style @@ -58,35 +58,35 @@ func main() { type ( S1 struct { - A int32 + A int64 S2 } S2 struct { - B int32 + B int64 S3 } S3 struct { - C int32 + C int64 S4 } S4 struct { - D int32 + D int64 S5 } S5 struct { - E int32 + E int64 S6 } S6 struct { - F int32 + F int64 S7 } S7 struct { - G int32 + G int64 S8 } S8 struct { - H int32 + H int64 *S1 } ) @@ -96,24 +96,24 @@ func testDeep() { switch { case unsafe.Offsetof(s1.A) != 0: panic("unsafe.Offsetof(s1.A) != 0") - case unsafe.Offsetof(s1.B) != 4: - panic("unsafe.Offsetof(s1.B) != 4") - case unsafe.Offsetof(s1.C) != 8: - panic("unsafe.Offsetof(s1.C) != 8") - case unsafe.Offsetof(s1.D) != 12: - panic("unsafe.Offsetof(s1.D) != 12") - case unsafe.Offsetof(s1.E) != 16: - panic("unsafe.Offsetof(s1.E) != 16") - case unsafe.Offsetof(s1.F) != 20: - panic("unsafe.Offsetof(s1.F) != 20") - case unsafe.Offsetof(s1.G) != 24: - panic("unsafe.Offsetof(s1.G) != 24") - case unsafe.Offsetof(s1.H) != 28: - panic("unsafe.Offsetof(s1.H) != 28") - case unsafe.Offsetof(s1.S1) != 32: - panic("unsafe.Offsetof(s1.S1) != 32") - case unsafe.Offsetof(s1.S1.S2.S3.S4.S5.S6.S7.S8.S1.S2) != 4: - panic("unsafe.Offsetof(s1.S1.S2.S3.S4.S5.S6.S7.S8.S1.S2) != 4") + case unsafe.Offsetof(s1.B) != 8: + panic("unsafe.Offsetof(s1.B) != 8") + case unsafe.Offsetof(s1.C) != 16: + panic("unsafe.Offsetof(s1.C) != 16") + case unsafe.Offsetof(s1.D) != 24: + panic("unsafe.Offsetof(s1.D) != 24") + case unsafe.Offsetof(s1.E) != 32: + panic("unsafe.Offsetof(s1.E) != 32") + case unsafe.Offsetof(s1.F) != 40: + panic("unsafe.Offsetof(s1.F) != 40") + case unsafe.Offsetof(s1.G) != 48: + panic("unsafe.Offsetof(s1.G) != 48") + case unsafe.Offsetof(s1.H) != 56: + panic("unsafe.Offsetof(s1.H) != 56") + case unsafe.Offsetof(s1.S1) != 64: + panic("unsafe.Offsetof(s1.S1) != 64") + case unsafe.Offsetof(s1.S1.S2.S3.S4.S5.S6.S7.S8.S1.S2) != 8: + panic("unsafe.Offsetof(s1.S1.S2.S3.S4.S5.S6.S7.S8.S1.S2) != 8") } } diff --git a/test/slice3.go b/test/slice3.go new file mode 100644 index 000000000..3cf34b57e --- /dev/null +++ b/test/slice3.go @@ -0,0 +1,156 @@ +// runoutput + +// Copyright 2013 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. + +// Test run-time behavior of 3-index slice expressions. + +package main + +import ( + "bufio" + "fmt" + "os" + "strconv" +) + +var bout *bufio.Writer + +func main() { + bout = bufio.NewWriter(os.Stdout) + + fmt.Fprintf(bout, "%s", programTop) + fmt.Fprintf(bout, "func main() {\n") + + index := []string{ + "0", + "1", + "2", + "3", + "10", + "20", + "vminus1", + "v0", + "v1", + "v2", + "v3", + "v10", + "v20", + } + + parse := func(s string) (n int, isconst bool) { + if s == "vminus1" { + return -1, false + } + isconst = true + if s[0] == 'v' { + isconst = false + s = s[1:] + } + n, _ = strconv.Atoi(s) + return n, isconst + } + + const Cap = 10 // cap of slice, array + + for _, base := range []string{"array", "slice"} { + for _, i := range index { + iv, iconst := parse(i) + for _, j := range index { + jv, jconst := parse(j) + for _, k := range index { + kv, kconst := parse(k) + // Avoid errors that would make the program not compile. + // Those are tested by slice3err.go. + switch { + case iconst && jconst && iv > jv, + jconst && kconst && jv > kv, + iconst && kconst && iv > kv, + iconst && base == "array" && iv > Cap, + jconst && base == "array" && jv > Cap, + kconst && base == "array" && kv > Cap: + continue + } + + expr := base + "[" + i + ":" + j + ":" + k + "]" + var xbase, xlen, xcap int + if iv > jv || jv > kv || kv > Cap || iv < 0 || jv < 0 || kv < 0 { + xbase, xlen, xcap = -1, -1, -1 + } else { + xbase = iv + xlen = jv - iv + xcap = kv - iv + } + fmt.Fprintf(bout, "\tcheckSlice(%q, func() []byte { return %s }, %d, %d, %d)\n", expr, expr, xbase, xlen, xcap) + } + } + } + } + + fmt.Fprintf(bout, "\tif !ok { os.Exit(1) }\n") + fmt.Fprintf(bout, "}\n") + bout.Flush() +} + +var programTop = ` +package main + +import ( + "fmt" + "os" + "unsafe" +) + +var ok = true + +var ( + array = new([10]byte) + slice = array[:] + + vminus1 = -1 + v0 = 0 + v1 = 1 + v2 = 2 + v3 = 3 + v4 = 4 + v5 = 5 + v10 = 10 + v20 = 20 +) + +func notOK() { + if ok { + println("BUG:") + ok = false + } +} + +func checkSlice(desc string, f func() []byte, xbase, xlen, xcap int) { + defer func() { + if err := recover(); err != nil { + if xbase >= 0 { + notOK() + println(desc, " unexpected panic: ", fmt.Sprint(err)) + } + } + // "no panic" is checked below + }() + + x := f() + + arrayBase := uintptr(unsafe.Pointer(array)) + raw := *(*[3]uintptr)(unsafe.Pointer(&x)) + base, len, cap := raw[0] - arrayBase, raw[1], raw[2] + if xbase < 0 { + notOK() + println(desc, "=", base, len, cap, "want panic") + return + } + if base != uintptr(xbase) || len != uintptr(xlen) || cap != uintptr(xcap) { + notOK() + println(desc, "=", base, len, cap, "want", xbase, xlen, xcap) + } +} + +` diff --git a/test/slice3err.go b/test/slice3err.go new file mode 100644 index 000000000..906b00703 --- /dev/null +++ b/test/slice3err.go @@ -0,0 +1,121 @@ +// errorcheck + +// Copyright 2013 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 p + +var array *[10]int +var slice []int +var str string +var i, j, k int + +func f() { + // check what missing arguments are allowed + _ = array[:] + _ = array[i:] + _ = array[:j] + _ = array[i:j] + _ = array[::] // ERROR "middle index required in 3-index slice" "final index required in 3-index slice" + _ = array[i::] // ERROR "middle index required in 3-index slice" "final index required in 3-index slice" + _ = array[:j:] // ERROR "final index required in 3-index slice" + _ = array[i:j:] // ERROR "final index required in 3-index slice" + _ = array[::k] // ERROR "middle index required in 3-index slice" + _ = array[i::k] // ERROR "middle index required in 3-index slice" + _ = array[:j:k] + _ = array[i:j:k] + + _ = slice[:] + _ = slice[i:] + _ = slice[:j] + _ = slice[i:j] + _ = slice[::] // ERROR "middle index required in 3-index slice" "final index required in 3-index slice" + _ = slice[i::] // ERROR "middle index required in 3-index slice" "final index required in 3-index slice" + _ = slice[:j:] // ERROR "final index required in 3-index slice" + _ = slice[i:j:] // ERROR "final index required in 3-index slice" + _ = slice[::k] // ERROR "middle index required in 3-index slice" + _ = slice[i::k] // ERROR "middle index required in 3-index slice" + _ = slice[:j:k] + _ = slice[i:j:k] + + _ = str[:] + _ = str[i:] + _ = str[:j] + _ = str[i:j] + _ = str[::] // ERROR "3-index slice of string" "middle index required in 3-index slice" "final index required in 3-index slice" + _ = str[i::] // ERROR "3-index slice of string" "middle index required in 3-index slice" "final index required in 3-index slice" + _ = str[:j:] // ERROR "3-index slice of string" "final index required in 3-index slice" + _ = str[i:j:] // ERROR "3-index slice of string" "final index required in 3-index slice" + _ = str[::k] // ERROR "3-index slice of string" "middle index required in 3-index slice" + _ = str[i::k] // ERROR "3-index slice of string" "middle index required in 3-index slice" + _ = str[:j:k] // ERROR "3-index slice of string" + _ = str[i:j:k] // ERROR "3-index slice of string" + + // check invalid indices + _ = array[1:2] + _ = array[2:1] // ERROR "invalid slice index" + _ = array[2:2] + _ = array[i:1] + _ = array[1:j] + _ = array[1:2:3] + _ = array[1:3:2] // ERROR "invalid slice index" + _ = array[2:1:3] // ERROR "invalid slice index" + _ = array[2:3:1] // ERROR "invalid slice index" + _ = array[3:1:2] // ERROR "invalid slice index" + _ = array[3:2:1] // ERROR "invalid slice index" + _ = array[i:1:2] + _ = array[i:2:1] // ERROR "invalid slice index" + _ = array[1:j:2] + _ = array[2:j:1] // ERROR "invalid slice index" + _ = array[1:2:k] + _ = array[2:1:k] // ERROR "invalid slice index" + + _ = slice[1:2] + _ = slice[2:1] // ERROR "invalid slice index" + _ = slice[2:2] + _ = slice[i:1] + _ = slice[1:j] + _ = slice[1:2:3] + _ = slice[1:3:2] // ERROR "invalid slice index" + _ = slice[2:1:3] // ERROR "invalid slice index" + _ = slice[2:3:1] // ERROR "invalid slice index" + _ = slice[3:1:2] // ERROR "invalid slice index" + _ = slice[3:2:1] // ERROR "invalid slice index" + _ = slice[i:1:2] + _ = slice[i:2:1] // ERROR "invalid slice index" + _ = slice[1:j:2] + _ = slice[2:j:1] // ERROR "invalid slice index" + _ = slice[1:2:k] + _ = slice[2:1:k] // ERROR "invalid slice index" + + _ = str[1:2] + _ = str[2:1] // ERROR "invalid slice index" + _ = str[2:2] + _ = str[i:1] + _ = str[1:j] + + // check out of bounds indices on array + _ = array[11:11] // ERROR "out of bounds for 10-element array" + _ = array[11:12] // ERROR "out of bounds for 10-element array" + _ = array[11:] // ERROR "out of bounds for 10-element array" + _ = array[:11] // ERROR "out of bounds for 10-element array" + _ = array[1:11] // ERROR "out of bounds for 10-element array" + _ = array[1:11:12] // ERROR "out of bounds for 10-element array" + _ = array[1:2:11] // ERROR "out of bounds for 10-element array" + _ = array[1:11:3] // ERROR "out of bounds for 10-element array" + _ = array[11:2:3] // ERROR "out of bounds for 10-element array" + _ = array[11:12:13] // ERROR "out of bounds for 10-element array" + + // slice bounds not checked + _ = slice[11:11] + _ = slice[11:12] + _ = slice[11:] + _ = slice[:11] + _ = slice[1:11] + _ = slice[1:11:12] + _ = slice[1:2:11] + _ = slice[1:11:3] // ERROR "invalid slice index" + _ = slice[11:2:3] // ERROR "invalid slice index" + _ = slice[11:12:13] +} diff --git a/test/stress/runstress.go b/test/stress/runstress.go index b5adf6a4a..76ab2a8b4 100644 --- a/test/stress/runstress.go +++ b/test/stress/runstress.go @@ -114,11 +114,16 @@ func stressExec() { } } -func ringf(in <-chan int, out chan<- int, donec chan<- bool) { +func ringf(in <-chan int, out chan<- int, donec chan bool) { for { - n := <-in + var n int + select { + case <-donec: + return + case n = <-in: + } if n == 0 { - donec <- true + close(donec) return } out <- n - 1 diff --git a/test/syntax/chan1.go b/test/syntax/chan1.go index 868a1226d..4860422ad 100644 --- a/test/syntax/chan1.go +++ b/test/syntax/chan1.go @@ -10,8 +10,8 @@ var c chan int var v int func main() { - if c <- v { // ERROR "send statement.*value.*select" + if c <- v { // ERROR "used as value" } } -var _ = c <- v // ERROR "send statement.*value.*select" +var _ = c <- v // ERROR "used as value" diff --git a/test/syntax/semi1.go b/test/syntax/semi1.go index 8fbfb206a..cc30f2654 100644 --- a/test/syntax/semi1.go +++ b/test/syntax/semi1.go @@ -7,7 +7,7 @@ package main func main() { - if x; y // ERROR "unexpected semicolon or newline before .?{.?|undefined" + if x; y // ERROR "missing { after if clause|undefined" { z // GCCGO_ERROR "undefined" diff --git a/test/syntax/semi2.go b/test/syntax/semi2.go index cfb0ed17b..61b8bf6d4 100644 --- a/test/syntax/semi2.go +++ b/test/syntax/semi2.go @@ -7,7 +7,7 @@ package main func main() { - switch x; y // ERROR "unexpected semicolon or newline before .?{.?|undefined" + switch x; y // ERROR "missing { after switch clause|undefined" { z diff --git a/test/syntax/semi3.go b/test/syntax/semi3.go index 645af7354..bb87520c5 100644 --- a/test/syntax/semi3.go +++ b/test/syntax/semi3.go @@ -7,7 +7,7 @@ package main func main() { - for x; y; z // ERROR "unexpected semicolon or newline before .?{.?|undefined" + for x; y; z // ERROR "missing { after for clause|undefined" { z // GCCGO_ERROR "undefined" diff --git a/test/syntax/semi4.go b/test/syntax/semi4.go index e192348aa..00fa3f575 100644 --- a/test/syntax/semi4.go +++ b/test/syntax/semi4.go @@ -8,7 +8,7 @@ package main func main() { for x // GCCGO_ERROR "undefined" - { // ERROR "unexpected semicolon or newline before .?{.?" + { // ERROR "missing { after for clause" z // GCCGO_ERROR "undefined" diff --git a/test/testlib b/test/testlib index de138b1d1..4a17f4feb 100644 --- a/test/testlib +++ b/test/testlib @@ -16,29 +16,50 @@ pkgs() { done | sort } +_match() { + case $1 in + *,*) + #echo >&2 "match comma separated $1" + first=$(echo $1 | sed 's/,.*//') + rest=$(echo $1 | sed 's/[^,]*,//') + if _match $first && _match $rest; then + return 0 + fi + return 1 + ;; + '!'*) + #echo >&2 "match negation $1" + neg=$(echo $1 | sed 's/^!//') + if _match $neg; then + return 1 + fi + return 0 + ;; + $GOARCH|$GOOS) + #echo >&2 "match GOARCH or GOOS $1" + return 0 + ;; + esac + return 1 +} + # +build aborts execution if the supplied tags don't match, # i.e. none of the tags (x or !x) matches GOARCH or GOOS. +build() { if (( $# == 0 )); then return fi + m=0 for tag; do - case $tag in - $GOARCH|$GOOS) - #echo >&2 "match $tag in $1" - return # don't exclude. - ;; - '!'$GOARCH|'!'$GOOS) - ;; - '!'*) - # not x where x is neither GOOS nor GOARCH. - #echo >&2 "match $tag in $1" - return # don't exclude - ;; - esac + if _match $tag; then + m=1 + fi done - # no match. - exit 0 + if [ $m = 0 ]; then + #echo >&2 no match + exit 0 + fi + unset m } compile() { |