summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/bench/shootout/timing.log91
-rw-r--r--test/blank.go14
-rw-r--r--test/blank1.go9
-rw-r--r--test/chan/doubleselect.go2
-rw-r--r--test/chan/select2.go3
-rw-r--r--test/cmp.go6
-rw-r--r--test/cmp6.go2
-rw-r--r--test/const6.go12
-rw-r--r--test/deferfin.go59
-rw-r--r--test/divmod.go460
-rwxr-xr-xtest/errchk2
-rw-r--r--test/escape2.go32
-rw-r--r--test/escape5.go7
-rw-r--r--test/fixedbugs/bug086.go4
-rw-r--r--test/fixedbugs/bug205.go6
-rw-r--r--test/fixedbugs/bug295.go4
-rw-r--r--test/fixedbugs/bug385_64.go217
-rw-r--r--test/fixedbugs/bug435.go2
-rw-r--r--test/fixedbugs/bug459.go2
-rw-r--r--test/fixedbugs/bug460.dir/a.go4
-rw-r--r--test/fixedbugs/bug460.dir/b.go7
-rw-r--r--test/fixedbugs/bug475.go22
-rw-r--r--test/fixedbugs/bug476.go23
-rw-r--r--test/fixedbugs/bug477.go34
-rw-r--r--test/fixedbugs/bug478.dir/a.go9
-rw-r--r--test/fixedbugs/bug478.dir/b.go13
-rw-r--r--test/fixedbugs/bug478.go10
-rw-r--r--test/fixedbugs/bug479.dir/a.go15
-rw-r--r--test/fixedbugs/bug479.dir/b.go16
-rw-r--r--test/fixedbugs/bug479.go10
-rw-r--r--test/fixedbugs/issue3783.go2
-rw-r--r--test/fixedbugs/issue3925.go4
-rw-r--r--test/fixedbugs/issue4085a.go10
-rw-r--r--test/fixedbugs/issue4097.go2
-rw-r--r--test/fixedbugs/issue4232.go28
-rw-r--r--test/fixedbugs/issue4251.go6
-rw-r--r--test/fixedbugs/issue4452.go2
-rw-r--r--test/fixedbugs/issue4458.go2
-rw-r--r--test/fixedbugs/issue4463.go44
-rw-r--r--test/fixedbugs/issue4517d.go9
-rw-r--r--test/fixedbugs/issue4545.go4
-rw-r--r--test/fixedbugs/issue4776.go10
-rw-r--r--test/fixedbugs/issue4813.go12
-rw-r--r--test/fixedbugs/issue4847.go24
-rw-r--r--test/fixedbugs/issue5172.go19
-rw-r--r--test/fixedbugs/issue5358.go17
-rw-r--r--test/fixedbugs/issue5493.go2
-rw-r--r--test/fixedbugs/issue5581.go34
-rw-r--r--test/fixedbugs/issue5609.go13
-rw-r--r--test/fixedbugs/issue5698.go18
-rw-r--r--test/fixedbugs/issue5704.go46
-rw-r--r--test/fixedbugs/issue5856.go38
-rw-r--r--test/fixedbugs/issue5910.dir/a.go22
-rw-r--r--test/fixedbugs/issue5910.dir/main.go12
-rw-r--r--test/fixedbugs/issue5910.go10
-rw-r--r--test/fixedbugs/issue5957.dir/a.go3
-rw-r--r--test/fixedbugs/issue5957.dir/b.go2
-rw-r--r--test/fixedbugs/issue5957.dir/c.go12
-rw-r--r--test/fixedbugs/issue5957.go7
-rw-r--r--test/fixedbugs/issue5963.go50
-rw-r--r--test/fixedbugs/issue6004.go15
-rw-r--r--test/fixedbugs/issue6036.go44
-rw-r--r--test/fixedbugs/issue6055.go35
-rw-r--r--test/fixedbugs/issue6131.go20
-rw-r--r--test/fixedbugs/issue6140.go31
-rw-r--r--test/fixedbugs/issue6247.go17
-rw-r--r--test/fixedbugs/issue6269.go39
-rw-r--r--test/fixedbugs/issue6298.go15
-rw-r--r--test/fixedbugs/issue6399.go27
-rw-r--r--test/fixedbugs/issue6513.dir/a.go7
-rw-r--r--test/fixedbugs/issue6513.dir/b.go9
-rw-r--r--test/fixedbugs/issue6513.dir/main.go16
-rw-r--r--test/fixedbugs/issue6513.go10
-rw-r--r--test/import1.go3
-rw-r--r--test/index.go2
-rw-r--r--test/interface/explicit.go19
-rw-r--r--test/interface/fail.go19
-rw-r--r--test/mapnan.go12
-rw-r--r--test/method2.go5
-rw-r--r--test/nilcheck.go184
-rw-r--r--test/nilptr.go28
-rw-r--r--test/nilptr2.go128
-rw-r--r--test/nilptr3.go191
-rw-r--r--test/recover.go240
-rw-r--r--test/recover3.go3
-rw-r--r--test/return.go108
-rw-r--r--test/run.go89
-rw-r--r--test/shift1.go185
-rw-r--r--test/shift2.go1
-rw-r--r--test/sizeof.go54
-rw-r--r--test/slice3.go156
-rw-r--r--test/slice3err.go121
-rw-r--r--test/stress/runstress.go11
-rw-r--r--test/syntax/chan1.go4
-rw-r--r--test/syntax/semi1.go2
-rw-r--r--test/syntax/semi2.go2
-rw-r--r--test/syntax/semi3.go2
-rw-r--r--test/syntax/semi4.go2
-rw-r--r--test/testlib51
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() {