summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorTianon Gravi <admwiggin@gmail.com>2015-01-15 11:54:00 -0700
committerTianon Gravi <admwiggin@gmail.com>2015-01-15 11:54:00 -0700
commitf154da9e12608589e8d5f0508f908a0c3e88a1bb (patch)
treef8255d51e10c6f1e0ed69702200b966c9556a431 /test
parent8d8329ed5dfb9622c82a9fbec6fd99a580f9c9f6 (diff)
downloadgolang-f154da9e12608589e8d5f0508f908a0c3e88a1bb.tar.gz
Imported Upstream version 1.4upstream/1.4
Diffstat (limited to 'test')
-rw-r--r--test/assign.go12
-rw-r--r--test/bench/garbage/parser.go2
-rw-r--r--test/bench/shootout/chameneosredux.go2
-rw-r--r--test/chan/perm.go3
-rw-r--r--test/chan/select5.go6
-rw-r--r--test/escape2.go2
-rw-r--r--test/escape2n.go1494
-rw-r--r--test/fixedbugs/bug173.go2
-rw-r--r--test/fixedbugs/bug255.go19
-rw-r--r--test/fixedbugs/bug299.go10
-rw-r--r--test/fixedbugs/bug371.go6
-rw-r--r--test/fixedbugs/bug406.go2
-rw-r--r--test/fixedbugs/bug486.go14
-rw-r--r--test/fixedbugs/bug487.go24
-rw-r--r--test/fixedbugs/bug488.dir/a.go7
-rw-r--r--test/fixedbugs/bug488.dir/b.go9
-rw-r--r--test/fixedbugs/bug488.go12
-rw-r--r--test/fixedbugs/bug489.go22
-rw-r--r--test/fixedbugs/bug490.go16
-rw-r--r--test/fixedbugs/bug491.go110
-rw-r--r--test/fixedbugs/issue4232.go29
-rw-r--r--test/fixedbugs/issue4388.go6
-rw-r--r--test/fixedbugs/issue5856.go2
-rw-r--r--test/fixedbugs/issue6703a.go16
-rw-r--r--test/fixedbugs/issue6703b.go16
-rw-r--r--test/fixedbugs/issue6703c.go18
-rw-r--r--test/fixedbugs/issue6703d.go18
-rw-r--r--test/fixedbugs/issue6703e.go18
-rw-r--r--test/fixedbugs/issue6703f.go18
-rw-r--r--test/fixedbugs/issue6703g.go20
-rw-r--r--test/fixedbugs/issue6703h.go20
-rw-r--r--test/fixedbugs/issue6703i.go20
-rw-r--r--test/fixedbugs/issue6703j.go20
-rw-r--r--test/fixedbugs/issue6703k.go21
-rw-r--r--test/fixedbugs/issue6703l.go21
-rw-r--r--test/fixedbugs/issue6703m.go25
-rw-r--r--test/fixedbugs/issue6703n.go25
-rw-r--r--test/fixedbugs/issue6703o.go23
-rw-r--r--test/fixedbugs/issue6703p.go23
-rw-r--r--test/fixedbugs/issue6703q.go28
-rw-r--r--test/fixedbugs/issue6703r.go28
-rw-r--r--test/fixedbugs/issue6703s.go18
-rw-r--r--test/fixedbugs/issue6703t.go18
-rw-r--r--test/fixedbugs/issue6703u.go18
-rw-r--r--test/fixedbugs/issue6703v.go18
-rw-r--r--test/fixedbugs/issue6703w.go21
-rw-r--r--test/fixedbugs/issue6703x.go21
-rw-r--r--test/fixedbugs/issue6703y.go23
-rw-r--r--test/fixedbugs/issue6703z.go23
-rw-r--r--test/fixedbugs/issue7690.go49
-rw-r--r--test/fixedbugs/issue7760.go25
-rw-r--r--test/fixedbugs/issue8017.go26
-rw-r--r--test/fixedbugs/issue8060.dir/a.go7
-rw-r--r--test/fixedbugs/issue8060.dir/b.go13
-rw-r--r--test/fixedbugs/issue8060.go9
-rw-r--r--test/fixedbugs/issue8074.go16
-rw-r--r--test/fixedbugs/issue8079.go11
-rw-r--r--test/fixedbugs/issue8280.dir/a.go3
-rw-r--r--test/fixedbugs/issue8280.dir/b.go5
-rw-r--r--test/fixedbugs/issue8280.go9
-rw-r--r--test/fixedbugs/issue8311.go16
-rw-r--r--test/fixedbugs/issue8336.go29
-rw-r--r--test/fixedbugs/issue8347.go27
-rw-r--r--test/fixedbugs/issue8475.go25
-rw-r--r--test/fixedbugs/issue8507.go16
-rw-r--r--test/fixedbugs/issue8612.go34
-rw-r--r--test/fixedbugs/issue8761.go26
-rw-r--r--test/fixedbugs/issue8947.go53
-rw-r--r--test/fixedbugs/issue8961.go20
-rw-r--r--test/fixedbugs/issue9006.go37
-rw-r--r--test/fixedbugs/issue9110.go90
-rw-r--r--test/interface/explicit.go4
-rw-r--r--test/interface/fail.go14
-rw-r--r--test/linkx.go12
-rw-r--r--test/linkx_run.go33
-rw-r--r--test/live.go77
-rw-r--r--test/live2.go12
-rw-r--r--test/map.go2
-rw-r--r--test/maplinear.go172
-rw-r--r--test/mapnan.go56
-rw-r--r--test/named1.go8
-rw-r--r--test/nosplit.go23
-rw-r--r--test/print.go42
-rw-r--r--test/print.out24
-rw-r--r--test/range.go92
-rw-r--r--test/recover.go92
-rw-r--r--test/run.go49
-rw-r--r--test/shift1.go2
-rw-r--r--test/sinit.go77
-rw-r--r--test/sinit_run.go40
-rw-r--r--test/slice3.go18
-rw-r--r--test/slicecap.go90
-rw-r--r--test/stress/maps.go2
-rw-r--r--test/stress/parsego.go2
-rw-r--r--test/torture.go7
95 files changed, 3625 insertions, 220 deletions
diff --git a/test/assign.go b/test/assign.go
index da0192f83..6611f8ce3 100644
--- a/test/assign.go
+++ b/test/assign.go
@@ -53,4 +53,16 @@ func main() {
_ = x
_ = y
}
+ {
+ var x = 1
+ {
+ x, x := 2, 3 // ERROR "x repeated on left side of :="
+ _ = x
+ }
+ _ = x
+ }
+ {
+ a, a := 1, 2 // ERROR "a repeated on left side of :="
+ _ = a
+ }
}
diff --git a/test/bench/garbage/parser.go b/test/bench/garbage/parser.go
index d85110b63..a685507c5 100644
--- a/test/bench/garbage/parser.go
+++ b/test/bench/garbage/parser.go
@@ -85,7 +85,7 @@ func main() {
var t0 time.Time
var numGC uint32
var pauseTotalNs uint64
- pkgroot := runtime.GOROOT() + "/src/pkg/"
+ pkgroot := runtime.GOROOT() + "/src/"
for pass := 0; pass < 2; pass++ {
// Once the heap is grown to full size, reset counters.
// This hides the start-up pauses, which are much smaller
diff --git a/test/bench/shootout/chameneosredux.go b/test/bench/shootout/chameneosredux.go
index 339579862..72ce7dd13 100644
--- a/test/bench/shootout/chameneosredux.go
+++ b/test/bench/shootout/chameneosredux.go
@@ -123,7 +123,7 @@ func pallmall(cols []int) {
fmt.Println(msg)
tot := 0
// wait for all results
- for _ = range cols {
+ for range cols {
result := <-ended
tot += result.met
fmt.Printf("%v%v\n", result.met, spell(result.same, true))
diff --git a/test/chan/perm.go b/test/chan/perm.go
index 7e152c5eb..919fa30fb 100644
--- a/test/chan/perm.go
+++ b/test/chan/perm.go
@@ -56,6 +56,9 @@ func main() {
for _ = range cs {// ERROR "receive"
}
+ for range cs {// ERROR "receive"
+ }
+
close(c)
close(cs)
close(cr) // ERROR "receive"
diff --git a/test/chan/select5.go b/test/chan/select5.go
index f72cfe4b4..1081cb296 100644
--- a/test/chan/select5.go
+++ b/test/chan/select5.go
@@ -27,16 +27,16 @@ func main() {
fmt.Fprintln(out, header)
a := new(arg)
- // Generate each kind of test as a separate function to avoid
+ // Generate each test as a separate function to avoid
// hitting the 6g optimizer with one enormous function.
// If we name all the functions init we don't have to
// maintain a list of which ones to run.
do := func(t *template.Template) {
- fmt.Fprintln(out, `func init() {`)
for ; next(); a.reset() {
+ fmt.Fprintln(out, `func init() {`)
run(t, a, out)
+ fmt.Fprintln(out, `}`)
}
- fmt.Fprintln(out, `}`)
}
do(recv)
diff --git a/test/escape2.go b/test/escape2.go
index 28251aa98..6a46ce86a 100644
--- a/test/escape2.go
+++ b/test/escape2.go
@@ -7,6 +7,8 @@
// Test, using compiler diagnostic flags, that the escape analysis is working.
// Compiles but does not run. Inlining is disabled.
+// escape2n.go contains all the same tests but compiles with -N.
+
package foo
import (
diff --git a/test/escape2n.go b/test/escape2n.go
new file mode 100644
index 000000000..002a78ea5
--- /dev/null
+++ b/test/escape2n.go
@@ -0,0 +1,1494 @@
+// errorcheck -0 -N -m -l
+
+// Copyright 2010 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, using compiler diagnostic flags, that the escape analysis is working.
+// Compiles but does not run. Inlining is disabled.
+// Registerization is disabled too (-N), which should
+// have no effect on escape analysis.
+
+package foo
+
+import (
+ "fmt"
+ "unsafe"
+)
+
+var gxx *int
+
+func foo1(x int) { // ERROR "moved to heap: x"
+ gxx = &x // ERROR "&x escapes to heap"
+}
+
+func foo2(yy *int) { // ERROR "leaking param: yy"
+ gxx = yy
+}
+
+func foo3(x int) *int { // ERROR "moved to heap: x"
+ return &x // ERROR "&x escapes to heap"
+}
+
+type T *T
+
+func foo3b(t T) { // ERROR "leaking param: t"
+ *t = t
+}
+
+// xx isn't going anywhere, so use of yy is ok
+func foo4(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape"
+ xx = yy
+}
+
+// xx isn't going anywhere, so taking address of yy is ok
+func foo5(xx **int, yy *int) { // ERROR "xx does not escape" "yy does not escape"
+ xx = &yy // ERROR "&yy does not escape"
+}
+
+func foo6(xx **int, yy *int) { // ERROR "xx does not escape" "leaking param: yy"
+ *xx = yy
+}
+
+func foo7(xx **int, yy *int) { // ERROR "xx does not escape" "yy does not escape"
+ **xx = *yy
+}
+
+func foo8(xx, yy *int) int { // ERROR "xx does not escape" "yy does not escape"
+ xx = yy
+ return *xx
+}
+
+func foo9(xx, yy *int) *int { // ERROR "leaking param: xx" "leaking param: yy"
+ xx = yy
+ return xx
+}
+
+func foo10(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape"
+ *xx = *yy
+}
+
+func foo11() int {
+ x, y := 0, 42
+ xx := &x // ERROR "&x does not escape"
+ yy := &y // ERROR "&y does not escape"
+ *xx = *yy
+ return x
+}
+
+var xxx **int
+
+func foo12(yyy **int) { // ERROR "leaking param: yyy"
+ xxx = yyy
+}
+
+// Must treat yyy as leaking because *yyy leaks, and the escape analysis
+// summaries in exported metadata do not distinguish these two cases.
+func foo13(yyy **int) { // ERROR "leaking param: yyy"
+ *xxx = *yyy
+}
+
+func foo14(yyy **int) { // ERROR "yyy does not escape"
+ **xxx = **yyy
+}
+
+func foo15(yy *int) { // ERROR "moved to heap: yy"
+ xxx = &yy // ERROR "&yy escapes to heap"
+}
+
+func foo16(yy *int) { // ERROR "leaking param: yy"
+ *xxx = yy
+}
+
+func foo17(yy *int) { // ERROR "yy does not escape"
+ **xxx = *yy
+}
+
+func foo18(y int) { // ERROR "moved to heap: "y"
+ *xxx = &y // ERROR "&y escapes to heap"
+}
+
+func foo19(y int) {
+ **xxx = y
+}
+
+type Bar struct {
+ i int
+ ii *int
+}
+
+func NewBar() *Bar {
+ return &Bar{42, nil} // ERROR "&Bar literal escapes to heap"
+}
+
+func NewBarp(x *int) *Bar { // ERROR "leaking param: x"
+ return &Bar{42, x} // ERROR "&Bar literal escapes to heap"
+}
+
+func NewBarp2(x *int) *Bar { // ERROR "x does not escape"
+ return &Bar{*x, nil} // ERROR "&Bar literal escapes to heap"
+}
+
+func (b *Bar) NoLeak() int { // ERROR "b does not escape"
+ return *(b.ii)
+}
+
+func (b *Bar) Leak() *int { // ERROR "leaking param: b"
+ return &b.i // ERROR "&b.i escapes to heap"
+}
+
+func (b *Bar) AlsoNoLeak() *int { // ERROR "leaking param b content to result ~r0"
+ return b.ii
+}
+
+func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b"
+ return b.ii
+}
+
+func (b Bar) LeaksToo() *int { // ERROR "leaking param: b"
+ v := 0 // ERROR "moved to heap: v"
+ b.ii = &v // ERROR "&v escapes"
+ return b.ii
+}
+
+func (b *Bar) LeaksABit() *int { // ERROR "leaking param b content to result ~r0"
+ v := 0 // ERROR "moved to heap: v"
+ b.ii = &v // ERROR "&v escapes"
+ return b.ii
+}
+
+func (b Bar) StillNoLeak() int { // ERROR "b does not escape"
+ v := 0
+ b.ii = &v // ERROR "&v does not escape"
+ return b.i
+}
+
+func goLeak(b *Bar) { // ERROR "leaking param: b"
+ go b.NoLeak()
+}
+
+type Bar2 struct {
+ i [12]int
+ ii []int
+}
+
+func NewBar2() *Bar2 {
+ return &Bar2{[12]int{42}, nil} // ERROR "&Bar2 literal escapes to heap"
+}
+
+func (b *Bar2) NoLeak() int { // ERROR "b does not escape"
+ return b.i[0]
+}
+
+func (b *Bar2) Leak() []int { // ERROR "leaking param: b"
+ return b.i[:] // ERROR "b.i escapes to heap"
+}
+
+func (b *Bar2) AlsoNoLeak() []int { // ERROR "leaking param b content to result ~r0"
+ return b.ii[0:1]
+}
+
+func (b Bar2) AgainNoLeak() [12]int { // ERROR "b does not escape"
+ return b.i
+}
+
+func (b *Bar2) LeakSelf() { // ERROR "leaking param: b"
+ b.ii = b.i[0:4] // ERROR "b.i escapes to heap"
+}
+
+func (b *Bar2) LeakSelf2() { // ERROR "leaking param: b"
+ var buf []int
+ buf = b.i[0:] // ERROR "b.i escapes to heap"
+ b.ii = buf
+}
+
+func foo21() func() int {
+ x := 42 // ERROR "moved to heap: x"
+ return func() int { // ERROR "func literal escapes to heap"
+ return x // ERROR "&x escapes to heap"
+ }
+}
+
+func foo22() int {
+ x := 42
+ return func() int { // ERROR "func literal does not escape"
+ return x
+ }()
+}
+
+func foo23(x int) func() int { // ERROR "moved to heap: x"
+ return func() int { // ERROR "func literal escapes to heap"
+ return x // ERROR "&x escapes to heap"
+ }
+}
+
+func foo23a(x int) func() int { // ERROR "moved to heap: x"
+ f := func() int { // ERROR "func literal escapes to heap"
+ return x // ERROR "&x escapes to heap"
+ }
+ return f
+}
+
+func foo23b(x int) *(func() int) { // ERROR "moved to heap: x"
+ f := func() int { return x } // ERROR "moved to heap: f" "func literal escapes to heap" "&x escapes to heap"
+ return &f // ERROR "&f escapes to heap"
+}
+
+func foo24(x int) int {
+ return func() int { // ERROR "func literal does not escape"
+ return x
+ }()
+}
+
+var x *int
+
+func fooleak(xx *int) int { // ERROR "leaking param: xx"
+ x = xx
+ return *x
+}
+
+func foonoleak(xx *int) int { // ERROR "xx does not escape"
+ return *x + *xx
+}
+
+func foo31(x int) int { // ERROR "moved to heap: x"
+ return fooleak(&x) // ERROR "&x escapes to heap"
+}
+
+func foo32(x int) int {
+ return foonoleak(&x) // ERROR "&x does not escape"
+}
+
+type Foo struct {
+ xx *int
+ x int
+}
+
+var F Foo
+var pf *Foo
+
+func (f *Foo) fooleak() { // ERROR "leaking param: f"
+ pf = f
+}
+
+func (f *Foo) foonoleak() { // ERROR "f does not escape"
+ F.x = f.x
+}
+
+func (f *Foo) Leak() { // ERROR "leaking param: f"
+ f.fooleak()
+}
+
+func (f *Foo) NoLeak() { // ERROR "f does not escape"
+ f.foonoleak()
+}
+
+func foo41(x int) { // ERROR "moved to heap: x"
+ F.xx = &x // ERROR "&x escapes to heap"
+}
+
+func (f *Foo) foo42(x int) { // ERROR "f does not escape" "moved to heap: x"
+ f.xx = &x // ERROR "&x escapes to heap"
+}
+
+func foo43(f *Foo, x int) { // ERROR "f does not escape" "moved to heap: x"
+ f.xx = &x // ERROR "&x escapes to heap"
+}
+
+func foo44(yy *int) { // ERROR "leaking param: yy"
+ F.xx = yy
+}
+
+func (f *Foo) foo45() { // ERROR "f does not escape"
+ F.x = f.x
+}
+
+// See foo13 above for explanation of why f leaks.
+func (f *Foo) foo46() { // ERROR "leaking param: f"
+ F.xx = f.xx
+}
+
+func (f *Foo) foo47() { // ERROR "leaking param: f"
+ f.xx = &f.x // ERROR "&f.x escapes to heap"
+}
+
+var ptrSlice []*int
+
+func foo50(i *int) { // ERROR "leaking param: i"
+ ptrSlice[0] = i
+}
+
+var ptrMap map[*int]*int
+
+func foo51(i *int) { // ERROR "leaking param: i"
+ ptrMap[i] = i
+}
+
+func indaddr1(x int) *int { // ERROR "moved to heap: x"
+ return &x // ERROR "&x escapes to heap"
+}
+
+func indaddr2(x *int) *int { // ERROR "leaking param: x"
+ return *&x // ERROR "&x does not escape"
+}
+
+func indaddr3(x *int32) *int { // ERROR "leaking param: x"
+ return *(**int)(unsafe.Pointer(&x)) // ERROR "&x does not escape"
+}
+
+// From package math:
+
+func Float32bits(f float32) uint32 {
+ return *(*uint32)(unsafe.Pointer(&f)) // ERROR "&f does not escape"
+}
+
+func Float32frombits(b uint32) float32 {
+ return *(*float32)(unsafe.Pointer(&b)) // ERROR "&b does not escape"
+}
+
+func Float64bits(f float64) uint64 {
+ return *(*uint64)(unsafe.Pointer(&f)) // ERROR "&f does not escape"
+}
+
+func Float64frombits(b uint64) float64 {
+ return *(*float64)(unsafe.Pointer(&b)) // ERROR "&b does not escape"
+}
+
+// contrast with
+func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: f"
+ return (*uint64)(unsafe.Pointer(&f)) // ERROR "&f escapes to heap"
+}
+
+func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f"
+ return (*uint64)(unsafe.Pointer(f))
+}
+
+func typesw(i interface{}) *int { // ERROR "leaking param: i"
+ switch val := i.(type) {
+ case *int:
+ return val
+ case *int8:
+ v := int(*val) // ERROR "moved to heap: v"
+ return &v // ERROR "&v escapes to heap"
+ }
+ return nil
+}
+
+func exprsw(i *int) *int { // ERROR "leaking param: i"
+ switch j := i; *j + 110 {
+ case 12:
+ return j
+ case 42:
+ return nil
+ }
+ return nil
+
+}
+
+// assigning to an array element is like assigning to the array
+func foo60(i *int) *int { // ERROR "leaking param: i"
+ var a [12]*int
+ a[0] = i
+ return a[1]
+}
+
+func foo60a(i *int) *int { // ERROR "i does not escape"
+ var a [12]*int
+ a[0] = i
+ return nil
+}
+
+// assigning to a struct field is like assigning to the struct
+func foo61(i *int) *int { // ERROR "leaking param: i"
+ type S struct {
+ a, b *int
+ }
+ var s S
+ s.a = i
+ return s.b
+}
+
+func foo61a(i *int) *int { // ERROR "i does not escape"
+ type S struct {
+ a, b *int
+ }
+ var s S
+ s.a = i
+ return nil
+}
+
+// assigning to a struct field is like assigning to the struct but
+// here this subtlety is lost, since s.a counts as an assignment to a
+// track-losing dereference.
+func foo62(i *int) *int { // ERROR "leaking param: i"
+ type S struct {
+ a, b *int
+ }
+ s := new(S) // ERROR "new[(]S[)] does not escape"
+ s.a = i
+ return nil // s.b
+}
+
+type M interface {
+ M()
+}
+
+func foo63(m M) { // ERROR "m does not escape"
+}
+
+func foo64(m M) { // ERROR "leaking param: m"
+ m.M()
+}
+
+func foo64b(m M) { // ERROR "leaking param: m"
+ defer m.M()
+}
+
+type MV int
+
+func (MV) M() {}
+
+func foo65() {
+ var mv MV
+ foo63(&mv) // ERROR "&mv does not escape"
+}
+
+func foo66() {
+ var mv MV // ERROR "moved to heap: mv"
+ foo64(&mv) // ERROR "&mv escapes to heap"
+}
+
+func foo67() {
+ var mv MV
+ foo63(mv)
+}
+
+func foo68() {
+ var mv MV
+ foo64(mv) // escapes but it's an int so irrelevant
+}
+
+func foo69(m M) { // ERROR "leaking param: m"
+ foo64(m)
+}
+
+func foo70(mv1 *MV, m M) { // ERROR "leaking param: mv1" "leaking param: m"
+ m = mv1
+ foo64(m)
+}
+
+func foo71(x *int) []*int { // ERROR "leaking param: x"
+ var y []*int
+ y = append(y, x)
+ return y
+}
+
+func foo71a(x int) []*int { // ERROR "moved to heap: x"
+ var y []*int
+ y = append(y, &x) // ERROR "&x escapes to heap"
+ return y
+}
+
+func foo72() {
+ var x int
+ var y [1]*int
+ y[0] = &x // ERROR "&x does not escape"
+}
+
+func foo72aa() [10]*int {
+ var x int // ERROR "moved to heap: x"
+ var y [10]*int
+ y[0] = &x // ERROR "&x escapes to heap"
+ return y
+}
+
+func foo72a() {
+ var y [10]*int
+ for i := 0; i < 10; i++ {
+ // escapes its scope
+ x := i // ERROR "moved to heap: x"
+ y[i] = &x // ERROR "&x escapes to heap"
+ }
+ return
+}
+
+func foo72b() [10]*int {
+ var y [10]*int
+ for i := 0; i < 10; i++ {
+ x := i // ERROR "moved to heap: x"
+ y[i] = &x // ERROR "&x escapes to heap"
+ }
+ return y
+}
+
+// issue 2145
+func foo73() {
+ s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
+ for _, v := range s {
+ vv := v // ERROR "moved to heap: vv"
+ // actually just escapes its scope
+ defer func() { // ERROR "func literal escapes to heap"
+ println(vv) // ERROR "&vv escapes to heap"
+ }()
+ }
+}
+
+func foo74() {
+ s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
+ for _, v := range s {
+ vv := v // ERROR "moved to heap: vv"
+ // actually just escapes its scope
+ fn := func() { // ERROR "func literal escapes to heap"
+ println(vv) // ERROR "&vv escapes to heap"
+ }
+ defer fn()
+ }
+}
+
+// issue 3975
+func foo74b() {
+ var array [3]func()
+ s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
+ for i, v := range s {
+ vv := v // ERROR "moved to heap: vv"
+ // actually just escapes its scope
+ array[i] = func() { // ERROR "func literal escapes to heap"
+ println(vv) // ERROR "&vv escapes to heap"
+ }
+ }
+}
+
+func myprint(y *int, x ...interface{}) *int { // ERROR "x does not escape" "leaking param: y"
+ return y
+}
+
+func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "y does not escape" "leaking param: x"
+ return &x[0] // ERROR "&x.0. escapes to heap"
+}
+
+func foo75(z *int) { // ERROR "z does not escape"
+ myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+}
+
+func foo75a(z *int) { // ERROR "z does not escape"
+ myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+}
+
+func foo75esc(z *int) { // ERROR "leaking param: z"
+ gxx = myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+}
+
+func foo75aesc(z *int) { // ERROR "z does not escape"
+ var ppi **interface{} // assignments to pointer dereferences lose track
+ *ppi = myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
+}
+
+func foo76(z *int) { // ERROR "leaking param: z"
+ myprint(nil, z) // ERROR "[.][.][.] argument does not escape"
+}
+
+func foo76a(z *int) { // ERROR "leaking param: z"
+ myprint1(nil, z) // ERROR "[.][.][.] argument does not escape"
+}
+
+func foo76b() {
+ myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+}
+
+func foo76c() {
+ myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+}
+
+func foo76d() {
+ defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+}
+
+func foo76e() {
+ defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+}
+
+func foo76f() {
+ for {
+ // TODO: This one really only escapes its scope, but we don't distinguish yet.
+ defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
+ }
+}
+
+func foo76g() {
+ for {
+ defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
+ }
+}
+
+func foo77(z []interface{}) { // ERROR "z does not escape"
+ myprint(nil, z...) // z does not escape
+}
+
+func foo77a(z []interface{}) { // ERROR "z does not escape"
+ myprint1(nil, z...)
+}
+
+func foo77b(z []interface{}) { // ERROR "leaking param: z"
+ var ppi **interface{}
+ *ppi = myprint1(nil, z...)
+}
+
+func foo78(z int) *int { // ERROR "moved to heap: z"
+ return &z // ERROR "&z escapes to heap"
+}
+
+func foo78a(z int) *int { // ERROR "moved to heap: z"
+ y := &z // ERROR "&z escapes to heap"
+ x := &y // ERROR "&y does not escape"
+ return *x // really return y
+}
+
+func foo79() *int {
+ return new(int) // ERROR "new[(]int[)] escapes to heap"
+}
+
+func foo80() *int {
+ var z *int
+ for {
+ // Really just escapes its scope but we don't distinguish
+ z = new(int) // ERROR "new[(]int[)] escapes to heap"
+ }
+ _ = z
+ return nil
+}
+
+func foo81() *int {
+ for {
+ z := new(int) // ERROR "new[(]int[)] does not escape"
+ _ = z
+ }
+ return nil
+}
+
+func tee(p *int) (x, y *int) { return p, p } // ERROR "leaking param"
+
+func noop(x, y *int) {} // ERROR "does not escape"
+
+func foo82() {
+ var x, y, z int // ERROR "moved to heap"
+ go noop(tee(&z)) // ERROR "&z escapes to heap"
+ go noop(&x, &y) // ERROR "escapes to heap"
+ for {
+ var u, v, w int // ERROR "moved to heap"
+ defer noop(tee(&u)) // ERROR "&u escapes to heap"
+ defer noop(&v, &w) // ERROR "escapes to heap"
+ }
+}
+
+type Fooer interface {
+ Foo()
+}
+
+type LimitedFooer struct {
+ Fooer
+ N int64
+}
+
+func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r"
+ return &LimitedFooer{r, n} // ERROR "&LimitedFooer literal escapes to heap"
+}
+
+func foo90(x *int) map[*int]*int { // ERROR "leaking param: x"
+ return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap"
+}
+
+func foo91(x *int) map[*int]*int { // ERROR "leaking param: x"
+ return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap"
+}
+
+func foo92(x *int) [2]*int { // ERROR "leaking param: x"
+ return [2]*int{x, nil}
+}
+
+// does not leak c
+func foo93(c chan *int) *int { // ERROR "c does not escape"
+ for v := range c {
+ return v
+ }
+ return nil
+}
+
+// does not leak m
+func foo94(m map[*int]*int, b bool) *int { // ERROR "m does not escape"
+ for k, v := range m {
+ if b {
+ return k
+ }
+ return v
+ }
+ return nil
+}
+
+// does leak x
+func foo95(m map[*int]*int, x *int) { // ERROR "m does not escape" "leaking param: x"
+ m[x] = x
+}
+
+// does not leak m
+func foo96(m []*int) *int { // ERROR "m does not escape"
+ return m[0]
+}
+
+// does leak m
+func foo97(m [1]*int) *int { // ERROR "leaking param: m"
+ return m[0]
+}
+
+// does not leak m
+func foo98(m map[int]*int) *int { // ERROR "m does not escape"
+ return m[0]
+}
+
+// does leak m
+func foo99(m *[1]*int) []*int { // ERROR "leaking param: m"
+ return m[:]
+}
+
+// does not leak m
+func foo100(m []*int) *int { // ERROR "m does not escape"
+ for _, v := range m {
+ return v
+ }
+ return nil
+}
+
+// does leak m
+func foo101(m [1]*int) *int { // ERROR "leaking param: m"
+ for _, v := range m {
+ return v
+ }
+ return nil
+}
+
+// does not leak m
+func foo101a(m [1]*int) *int { // ERROR "m does not escape"
+ for i := range m { // ERROR "moved to heap: i"
+ return &i // ERROR "&i escapes to heap"
+ }
+ return nil
+}
+
+// does leak x
+func foo102(m []*int, x *int) { // ERROR "m does not escape" "leaking param: x"
+ m[0] = x
+}
+
+// does not leak x
+func foo103(m [1]*int, x *int) { // ERROR "m does not escape" "x does not escape"
+ m[0] = x
+}
+
+var y []*int
+
+// does not leak x
+func foo104(x []*int) { // ERROR "x does not escape"
+ copy(y, x)
+}
+
+// does not leak x
+func foo105(x []*int) { // ERROR "x does not escape"
+ _ = append(y, x...)
+}
+
+// does leak x
+func foo106(x *int) { // ERROR "leaking param: x"
+ _ = append(y, x)
+}
+
+func foo107(x *int) map[*int]*int { // ERROR "leaking param: x"
+ return map[*int]*int{x: nil} // ERROR "map.* literal escapes to heap"
+}
+
+func foo108(x *int) map[*int]*int { // ERROR "leaking param: x"
+ return map[*int]*int{nil: x} // ERROR "map.* literal escapes to heap"
+}
+
+func foo109(x *int) *int { // ERROR "leaking param: x"
+ m := map[*int]*int{x: nil} // ERROR "map.* literal does not escape"
+ for k, _ := range m {
+ return k
+ }
+ return nil
+}
+
+func foo110(x *int) *int { // ERROR "leaking param: x"
+ m := map[*int]*int{nil: x} // ERROR "map.* literal does not escape"
+ return m[nil]
+}
+
+func foo111(x *int) *int { // ERROR "leaking param: x"
+ m := []*int{x} // ERROR "\[\]\*int literal does not escape"
+ return m[0]
+}
+
+func foo112(x *int) *int { // ERROR "leaking param: x"
+ m := [1]*int{x}
+ return m[0]
+}
+
+func foo113(x *int) *int { // ERROR "leaking param: x"
+ m := Bar{ii: x}
+ return m.ii
+}
+
+func foo114(x *int) *int { // ERROR "leaking param: x"
+ m := &Bar{ii: x} // ERROR "&Bar literal does not escape"
+ return m.ii
+}
+
+func foo115(x *int) *int { // ERROR "leaking param: x"
+ return (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(x)) + 1))
+}
+
+func foo116(b bool) *int {
+ if b {
+ x := 1 // ERROR "moved to heap: x"
+ return &x // ERROR "&x escapes to heap"
+ } else {
+ y := 1 // ERROR "moved to heap: y"
+ return &y // ERROR "&y escapes to heap"
+ }
+ return nil
+}
+
+func foo117(unknown func(interface{})) { // ERROR "unknown does not escape"
+ x := 1 // ERROR "moved to heap: x"
+ unknown(&x) // ERROR "&x escapes to heap"
+}
+
+func foo118(unknown func(*int)) { // ERROR "unknown does not escape"
+ x := 1 // ERROR "moved to heap: x"
+ unknown(&x) // ERROR "&x escapes to heap"
+}
+
+func external(*int)
+
+func foo119(x *int) { // ERROR "leaking param: x"
+ external(x)
+}
+
+func foo120() {
+ // formerly exponential time analysis
+L1:
+L2:
+L3:
+L4:
+L5:
+L6:
+L7:
+L8:
+L9:
+L10:
+L11:
+L12:
+L13:
+L14:
+L15:
+L16:
+L17:
+L18:
+L19:
+L20:
+L21:
+L22:
+L23:
+L24:
+L25:
+L26:
+L27:
+L28:
+L29:
+L30:
+L31:
+L32:
+L33:
+L34:
+L35:
+L36:
+L37:
+L38:
+L39:
+L40:
+L41:
+L42:
+L43:
+L44:
+L45:
+L46:
+L47:
+L48:
+L49:
+L50:
+L51:
+L52:
+L53:
+L54:
+L55:
+L56:
+L57:
+L58:
+L59:
+L60:
+L61:
+L62:
+L63:
+L64:
+L65:
+L66:
+L67:
+L68:
+L69:
+L70:
+L71:
+L72:
+L73:
+L74:
+L75:
+L76:
+L77:
+L78:
+L79:
+L80:
+L81:
+L82:
+L83:
+L84:
+L85:
+L86:
+L87:
+L88:
+L89:
+L90:
+L91:
+L92:
+L93:
+L94:
+L95:
+L96:
+L97:
+L98:
+L99:
+L100:
+ // use the labels to silence compiler errors
+ goto L1
+ goto L2
+ goto L3
+ goto L4
+ goto L5
+ goto L6
+ goto L7
+ goto L8
+ goto L9
+ goto L10
+ goto L11
+ goto L12
+ goto L13
+ goto L14
+ goto L15
+ goto L16
+ goto L17
+ goto L18
+ goto L19
+ goto L20
+ goto L21
+ goto L22
+ goto L23
+ goto L24
+ goto L25
+ goto L26
+ goto L27
+ goto L28
+ goto L29
+ goto L30
+ goto L31
+ goto L32
+ goto L33
+ goto L34
+ goto L35
+ goto L36
+ goto L37
+ goto L38
+ goto L39
+ goto L40
+ goto L41
+ goto L42
+ goto L43
+ goto L44
+ goto L45
+ goto L46
+ goto L47
+ goto L48
+ goto L49
+ goto L50
+ goto L51
+ goto L52
+ goto L53
+ goto L54
+ goto L55
+ goto L56
+ goto L57
+ goto L58
+ goto L59
+ goto L60
+ goto L61
+ goto L62
+ goto L63
+ goto L64
+ goto L65
+ goto L66
+ goto L67
+ goto L68
+ goto L69
+ goto L70
+ goto L71
+ goto L72
+ goto L73
+ goto L74
+ goto L75
+ goto L76
+ goto L77
+ goto L78
+ goto L79
+ goto L80
+ goto L81
+ goto L82
+ goto L83
+ goto L84
+ goto L85
+ goto L86
+ goto L87
+ goto L88
+ goto L89
+ goto L90
+ goto L91
+ goto L92
+ goto L93
+ goto L94
+ goto L95
+ goto L96
+ goto L97
+ goto L98
+ goto L99
+ goto L100
+}
+
+func foo121() {
+ for i := 0; i < 10; i++ {
+ defer myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap"
+ go myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap"
+ }
+}
+
+// same as foo121 but check across import
+func foo121b() {
+ for i := 0; i < 10; i++ {
+ defer fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap"
+ go fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap"
+ }
+}
+
+// a harmless forward jump
+func foo122() {
+ var i *int
+
+ goto L1
+L1:
+ i = new(int) // ERROR "new.int. does not escape"
+ _ = i
+}
+
+// a backward jump, increases loopdepth
+func foo123() {
+ var i *int
+
+L1:
+ i = new(int) // ERROR "new.int. escapes to heap"
+
+ goto L1
+ _ = i
+}
+
+func foo124(x **int) { // ERROR "x does not escape"
+ var i int // ERROR "moved to heap: i"
+ p := &i // ERROR "&i escapes"
+ func() { // ERROR "func literal does not escape"
+ *x = p // ERROR "leaking closure reference p"
+ }()
+}
+
+func foo125(ch chan *int) { // ERROR "does not escape"
+ var i int // ERROR "moved to heap"
+ p := &i // ERROR "&i escapes to heap"
+ func() { // ERROR "func literal does not escape"
+ ch <- p // ERROR "leaking closure reference p"
+ }()
+}
+
+func foo126() {
+ var px *int // loopdepth 0
+ for {
+ // loopdepth 1
+ var i int // ERROR "moved to heap"
+ func() { // ERROR "func literal does not escape"
+ px = &i // ERROR "&i escapes"
+ }()
+ }
+ _ = px
+}
+
+var px *int
+
+func foo127() {
+ var i int // ERROR "moved to heap: i"
+ p := &i // ERROR "&i escapes to heap"
+ q := p
+ px = q
+}
+
+func foo128() {
+ var i int
+ p := &i // ERROR "&i does not escape"
+ q := p
+ _ = q
+}
+
+func foo129() {
+ var i int // ERROR "moved to heap: i"
+ p := &i // ERROR "&i escapes to heap"
+ func() { // ERROR "func literal does not escape"
+ q := p // ERROR "leaking closure reference p"
+ func() { // ERROR "func literal does not escape"
+ r := q // ERROR "leaking closure reference q"
+ px = r
+ }()
+ }()
+}
+
+func foo130() {
+ for {
+ var i int // ERROR "moved to heap"
+ func() { // ERROR "func literal does not escape"
+ px = &i // ERROR "&i escapes" "leaking closure reference i"
+ }()
+ }
+}
+
+func foo131() {
+ var i int // ERROR "moved to heap"
+ func() { // ERROR "func literal does not escape"
+ px = &i // ERROR "&i escapes" "leaking closure reference i"
+ }()
+}
+
+func foo132() {
+ var i int // ERROR "moved to heap"
+ go func() { // ERROR "func literal escapes to heap"
+ px = &i // ERROR "&i escapes" "leaking closure reference i"
+ }()
+}
+
+func foo133() {
+ var i int // ERROR "moved to heap"
+ defer func() { // ERROR "func literal does not escape"
+ px = &i // ERROR "&i escapes" "leaking closure reference i"
+ }()
+}
+
+func foo134() {
+ var i int
+ p := &i // ERROR "&i does not escape"
+ func() { // ERROR "func literal does not escape"
+ q := p
+ func() { // ERROR "func literal does not escape"
+ r := q
+ _ = r
+ }()
+ }()
+}
+
+func foo135() {
+ var i int // ERROR "moved to heap: i"
+ p := &i // ERROR "&i escapes to heap" "moved to heap: p"
+ go func() { // ERROR "func literal escapes to heap"
+ q := p // ERROR "&p escapes to heap"
+ func() { // ERROR "func literal does not escape"
+ r := q
+ _ = r
+ }()
+ }()
+}
+
+func foo136() {
+ var i int // ERROR "moved to heap: i"
+ p := &i // ERROR "&i escapes to heap" "moved to heap: p"
+ go func() { // ERROR "func literal escapes to heap"
+ q := p // ERROR "&p escapes to heap" "leaking closure reference p"
+ func() { // ERROR "func literal does not escape"
+ r := q // ERROR "leaking closure reference q"
+ px = r
+ }()
+ }()
+}
+
+func foo137() {
+ var i int // ERROR "moved to heap: i"
+ p := &i // ERROR "&i escapes to heap"
+ func() { // ERROR "func literal does not escape"
+ q := p // ERROR "leaking closure reference p" "moved to heap: q"
+ go func() { // ERROR "func literal escapes to heap"
+ r := q // ERROR "&q escapes to heap"
+ _ = r
+ }()
+ }()
+}
+
+func foo138() *byte {
+ type T struct {
+ x [1]byte
+ }
+ t := new(T) // ERROR "new.T. escapes to heap"
+ return &t.x[0] // ERROR "&t.x.0. escapes to heap"
+}
+
+func foo139() *byte {
+ type T struct {
+ x struct {
+ y byte
+ }
+ }
+ t := new(T) // ERROR "new.T. escapes to heap"
+ return &t.x.y // ERROR "&t.x.y escapes to heap"
+}
+
+// issue 4751
+func foo140() interface{} {
+ type T struct {
+ X string
+ }
+ type U struct {
+ X string
+ T *T
+ }
+ t := &T{} // ERROR "&T literal escapes to heap"
+ return U{
+ X: t.X,
+ T: t,
+ }
+}
+
+//go:noescape
+
+func F1([]byte)
+
+func F2([]byte)
+
+//go:noescape
+
+func F3(x []byte) // ERROR "F3 x does not escape"
+
+func F4(x []byte)
+
+func G() {
+ var buf1 [10]byte
+ F1(buf1[:]) // ERROR "buf1 does not escape"
+
+ var buf2 [10]byte // ERROR "moved to heap: buf2"
+ F2(buf2[:]) // ERROR "buf2 escapes to heap"
+
+ var buf3 [10]byte
+ F3(buf3[:]) // ERROR "buf3 does not escape"
+
+ var buf4 [10]byte // ERROR "moved to heap: buf4"
+ F4(buf4[:]) // ERROR "buf4 escapes to heap"
+}
+
+type Tm struct {
+ x int
+}
+
+func (t *Tm) M() { // ERROR "t does not escape"
+}
+
+func foo141() {
+ var f func()
+
+ t := new(Tm) // ERROR "escapes to heap"
+ f = t.M // ERROR "t.M does not escape"
+ _ = f
+}
+
+var gf func()
+
+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)
+
+// issue 7313: for loop init should not be treated as "in loop"
+
+type List struct {
+ Next *List
+}
+
+func foo145(l List) { // ERROR "l does not escape"
+ var p *List
+ for p = &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
+ }
+}
+
+func foo146(l List) { // ERROR "l does not escape"
+ var p *List
+ p = &l // ERROR "&l does not escape"
+ for ; p.Next != nil; p = p.Next {
+ }
+}
+
+func foo147(l List) { // ERROR "l does not escape"
+ var p *List
+ p = &l // ERROR "&l does not escape"
+ for p.Next != nil {
+ p = p.Next
+ }
+}
+
+func foo148(l List) { // ERROR " l does not escape"
+ for p := &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
+ }
+}
+
+// related: address of variable should have depth of variable, not of loop
+
+func foo149(l List) { // ERROR " l does not escape"
+ var p *List
+ for {
+ for p = &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
+ }
+ }
+}
+
+// issue 7934: missed ... if element type had no pointers
+
+var save150 []byte
+
+func foo150(x ...byte) { // ERROR "leaking param: x"
+ save150 = x
+}
+
+func bar150() {
+ foo150(1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
+}
+
+// issue 7931: bad handling of slice of array
+
+var save151 *int
+
+func foo151(x *int) { // ERROR "leaking param: x"
+ save151 = x
+}
+
+func bar151() {
+ var a [64]int // ERROR "moved to heap: a"
+ a[4] = 101
+ foo151(&(&a)[4:8][0]) // ERROR "&\(&a\)\[4:8\]\[0\] escapes to heap" "&a escapes to heap"
+}
+
+func bar151b() {
+ var a [10]int // ERROR "moved to heap: a"
+ b := a[:] // ERROR "a escapes to heap"
+ foo151(&b[4:8][0]) // ERROR "&b\[4:8\]\[0\] escapes to heap"
+}
+
+func bar151c() {
+ var a [64]int // ERROR "moved to heap: a"
+ a[4] = 101
+ foo151(&(&a)[4:8:8][0]) // ERROR "&\(&a\)\[4:8:8\]\[0\] escapes to heap" "&a escapes to heap"
+}
+
+func bar151d() {
+ var a [10]int // ERROR "moved to heap: a"
+ b := a[:] // ERROR "a escapes to heap"
+ foo151(&b[4:8:8][0]) // ERROR "&b\[4:8:8\]\[0\] escapes to heap"
+}
+
+// issue 8120
+
+type U struct {
+ s *string
+}
+
+func (u *U) String() *string { // ERROR "leaking param u content to result ~r0"
+ return u.s
+}
+
+type V struct {
+ s *string
+}
+
+func NewV(u U) *V { // ERROR "leaking param: u"
+ return &V{u.String()} // ERROR "&V literal escapes to heap" "u does not escape"
+}
+
+func foo152() {
+ a := "a" // ERROR "moved to heap: a"
+ u := U{&a} // ERROR "&a escapes to heap"
+ v := NewV(u)
+ println(v)
+}
+
+// issue 8176 - &x in type switch body not marked as escaping
+
+func foo153(v interface{}) *int { // ERROR "leaking param: v"
+ switch x := v.(type) {
+ case int: // ERROR "moved to heap: x"
+ return &x // ERROR "&x escapes to heap"
+ }
+ panic(0)
+}
+
+// issue 8185 - &result escaping into result
+
+func f() (x int, y *int) { // ERROR "moved to heap: x"
+ y = &x // ERROR "&x escapes to heap"
+ return
+}
+
+func g() (x interface{}) { // ERROR "moved to heap: x"
+ x = &x // ERROR "&x escapes to heap"
+ return
+}
diff --git a/test/fixedbugs/bug173.go b/test/fixedbugs/bug173.go
index 6479bb253..3515c649b 100644
--- a/test/fixedbugs/bug173.go
+++ b/test/fixedbugs/bug173.go
@@ -18,4 +18,6 @@ func main() {
}
for _ = range t {
}
+ for range t {
+ }
}
diff --git a/test/fixedbugs/bug255.go b/test/fixedbugs/bug255.go
index acf4f2391..65ed1b8f6 100644
--- a/test/fixedbugs/bug255.go
+++ b/test/fixedbugs/bug255.go
@@ -6,10 +6,15 @@
package main
-var a [10]int // ok
-var b [1e1]int // ok
-var c [1.5]int // ERROR "truncated"
-var d ["abc"]int // ERROR "invalid array bound|not numeric"
-var e [nil]int // ERROR "invalid array bound|not numeric"
-var f [e]int // ERROR "invalid array bound|not constant"
-var g [1<<65]int // ERROR "array bound is too large|overflows"
+var a [10]int // ok
+var b [1e1]int // ok
+var c [1.5]int // ERROR "truncated"
+var d ["abc"]int // ERROR "invalid array bound|not numeric"
+var e [nil]int // ERROR "invalid array bound|not numeric"
+var f [e]int // ERROR "invalid array bound|not constant"
+var g [1 << 65]int // ERROR "array bound is too large|overflows"
+var h [len(a)]int // ok
+
+func ff() string
+
+var i [len([1]string{ff()})]int // ERROR "non-constant array bound|not constant"
diff --git a/test/fixedbugs/bug299.go b/test/fixedbugs/bug299.go
index 9646723bf..1067fd147 100644
--- a/test/fixedbugs/bug299.go
+++ b/test/fixedbugs/bug299.go
@@ -21,7 +21,9 @@ type T struct {
// legal according to spec
func (p T) m() {}
-// not legal according to spec
-func (p (T)) f() {} // ERROR "parenthesize|expected"
-func (p *(T)) g() {} // ERROR "parenthesize|expected"
-func (p (*T)) h() {} // ERROR "parenthesize|expected"
+// now legal according to spec
+func (p (T)) f() {}
+func (p *(T)) g() {}
+func (p (*T)) h() {}
+func (p (*(T))) i() {}
+func ((T),) j() {}
diff --git a/test/fixedbugs/bug371.go b/test/fixedbugs/bug371.go
index 6329e9635..86c73bf4a 100644
--- a/test/fixedbugs/bug371.go
+++ b/test/fixedbugs/bug371.go
@@ -8,10 +8,10 @@
package main
-type T struct {}
+type T struct{}
func (t *T) pm() {}
-func (t T) m() {}
+func (t T) m() {}
func main() {
p := &T{}
@@ -20,5 +20,5 @@ func main() {
q := &p
q.m() // ERROR "requires explicit dereference"
- q.pm()
+ q.pm() // ERROR "requires explicit dereference"
}
diff --git a/test/fixedbugs/bug406.go b/test/fixedbugs/bug406.go
index c6f8534c9..6df3c5cae 100644
--- a/test/fixedbugs/bug406.go
+++ b/test/fixedbugs/bug406.go
@@ -14,6 +14,8 @@ type matrix struct {
func (a matrix) equal() bool {
for _ = range a.e {
}
+ for range a.e {
+ }
return true
}
diff --git a/test/fixedbugs/bug486.go b/test/fixedbugs/bug486.go
new file mode 100644
index 000000000..c1a4723f9
--- /dev/null
+++ b/test/fixedbugs/bug486.go
@@ -0,0 +1,14 @@
+// compile
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The gccgo lexer had a bug handling nested comments.
+// http://gcc.gnu.org/PR61746
+// http://code.google.com/p/gofrontend/issues/detail?id=35
+
+package main
+
+/*// comment
+*/
diff --git a/test/fixedbugs/bug487.go b/test/fixedbugs/bug487.go
new file mode 100644
index 000000000..eb1ad5e57
--- /dev/null
+++ b/test/fixedbugs/bug487.go
@@ -0,0 +1,24 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The gccgo compiler did not reliably report mismatches between the
+// number of function results and the number of expected results.
+
+package p
+
+func G() (int, int, int) {
+ return 0, 0, 0
+}
+
+func F() {
+ a, b := G() // ERROR "mismatch"
+ a, b = G() // ERROR "mismatch"
+ _, _ = a, b
+}
+
+func H() (int, int) {
+ return G() // ERROR "too many|mismatch"
+}
diff --git a/test/fixedbugs/bug488.dir/a.go b/test/fixedbugs/bug488.dir/a.go
new file mode 100644
index 000000000..94eaf7f1e
--- /dev/null
+++ b/test/fixedbugs/bug488.dir/a.go
@@ -0,0 +1,7 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+var p2 = Printf // ERROR "undefined"
diff --git a/test/fixedbugs/bug488.dir/b.go b/test/fixedbugs/bug488.dir/b.go
new file mode 100644
index 000000000..21b4c5b54
--- /dev/null
+++ b/test/fixedbugs/bug488.dir/b.go
@@ -0,0 +1,9 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+import . "fmt"
+
+var p1 = Print
diff --git a/test/fixedbugs/bug488.go b/test/fixedbugs/bug488.go
new file mode 100644
index 000000000..63a601ed9
--- /dev/null
+++ b/test/fixedbugs/bug488.go
@@ -0,0 +1,12 @@
+// errorcheckdir
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The gccgo compiler had a bug: if one file in a package did a dot
+// import, then an earlier file in the package would incorrectly
+// resolve to the imported names rather than reporting undefined
+// errors.
+
+package ignored
diff --git a/test/fixedbugs/bug489.go b/test/fixedbugs/bug489.go
new file mode 100644
index 000000000..4cf19e059
--- /dev/null
+++ b/test/fixedbugs/bug489.go
@@ -0,0 +1,22 @@
+// compile
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The gccgo compiler had a bug: mentioning a function type in an
+// expression in a function literal messed up the list of variables
+// referenced in enclosing functions.
+
+package main
+
+func main() {
+ v1, v2 := 0, 0
+ f := func() {
+ a := v1
+ g := (func())(nil)
+ b := v2
+ _, _, _ = a, g, b
+ }
+ _, _, _ = v1, v2, f
+}
diff --git a/test/fixedbugs/bug490.go b/test/fixedbugs/bug490.go
new file mode 100644
index 000000000..7d05f3945
--- /dev/null
+++ b/test/fixedbugs/bug490.go
@@ -0,0 +1,16 @@
+// compile
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The gccgo compiler used to crash building a comparison between an
+// interface and an empty struct literal.
+
+package p
+
+type S struct{}
+
+func F(v interface{}) bool {
+ return v == S{}
+}
diff --git a/test/fixedbugs/bug491.go b/test/fixedbugs/bug491.go
new file mode 100644
index 000000000..f4b58af1e
--- /dev/null
+++ b/test/fixedbugs/bug491.go
@@ -0,0 +1,110 @@
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test order of calls to builtin functions.
+// Discovered during CL 144530045 review.
+
+package main
+
+func main() {
+ // append
+ {
+ x := make([]int, 0)
+ f := func() int { x = make([]int, 2); return 2 }
+ a, b, c := append(x, 1), f(), append(x, 1)
+ if len(a) != 1 || len(c) != 3 {
+ bug()
+ println("append call not ordered:", len(a), b, len(c))
+ }
+ }
+
+ // cap
+ {
+ x := make([]int, 1)
+ f := func() int { x = make([]int, 3); return 2 }
+ a, b, c := cap(x), f(), cap(x)
+ if a != 1 || c != 3 {
+ bug()
+ println("cap call not ordered:", a, b, c)
+ }
+ }
+
+ // complex
+ {
+ x := 1.0
+ f := func() int { x = 3; return 2 }
+ a, b, c := complex(x, 0), f(), complex(x, 0)
+ if real(a) != 1 || real(c) != 3 {
+ bug()
+ println("complex call not ordered:", a, b, c)
+ }
+ }
+
+ // copy
+ {
+ tmp := make([]int, 100)
+ x := make([]int, 1)
+ f := func() int { x = make([]int, 3); return 2 }
+ a, b, c := copy(tmp, x), f(), copy(tmp, x)
+ if a != 1 || c != 3 {
+ bug()
+ println("copy call not ordered:", a, b, c)
+ }
+ }
+
+ // imag
+ {
+ x := 1i
+ f := func() int { x = 3i; return 2 }
+ a, b, c := imag(x), f(), imag(x)
+ if a != 1 || c != 3 {
+ bug()
+ println("imag call not ordered:", a, b, c)
+ }
+ }
+
+ // len
+ {
+ x := make([]int, 1)
+ f := func() int { x = make([]int, 3); return 2 }
+ a, b, c := len(x), f(), len(x)
+ if a != 1 || c != 3 {
+ bug()
+ println("len call not ordered:", a, b, c)
+ }
+ }
+
+ // make
+ {
+ x := 1
+ f := func() int { x = 3; return 2 }
+ a, b, c := make([]int, x), f(), make([]int, x)
+ if len(a) != 1 || len(c) != 3 {
+ bug()
+ println("make call not ordered:", len(a), b, len(c))
+ }
+ }
+
+ // real
+ {
+ x := 1 + 0i
+ f := func() int { x = 3; return 2 }
+ a, b, c := real(x), f(), real(x)
+ if a != 1 || c != 3 {
+ bug()
+ println("real call not ordered:", a, b, c)
+ }
+ }
+}
+
+var bugged = false
+
+func bug() {
+ if !bugged {
+ println("BUG")
+ bugged = true
+ }
+} \ No newline at end of file
diff --git a/test/fixedbugs/issue4232.go b/test/fixedbugs/issue4232.go
index e5daa6562..755b1b1de 100644
--- a/test/fixedbugs/issue4232.go
+++ b/test/fixedbugs/issue4232.go
@@ -4,6 +4,9 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+// issue 4232
+// issue 7200
+
package p
func f() {
@@ -12,22 +15,42 @@ func f() {
_ = 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"
+ _ = a[9:10]
+ _ = a[10:10]
+ _ = a[9:12] // ERROR "invalid slice index 12|index out of bounds"
+ _ = a[11:12] // ERROR "invalid slice index 11|index out of bounds"
+ _ = a[1<<100 : 1<<110] // ERROR "overflows int" "invalid slice index 1 << 100|index out of bounds"
var s []int
_ = 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]
+ _ = s[9:10]
+ _ = s[10:10]
+ _ = s[9:12]
+ _ = s[11:12]
+ _ = s[1<<100 : 1<<110] // ERROR "overflows int" "invalid slice index 1 << 100|index out of bounds"
- const c = "foo"
+ const c = "foofoofoof"
_ = 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"
+ _ = c[10] // ERROR "invalid string index 10|index out of bounds"
+ _ = c[9:10]
+ _ = c[10:10]
+ _ = c[9:12] // ERROR "invalid slice index 12|index out of bounds"
+ _ = c[11:12] // ERROR "invalid slice index 11|index out of bounds"
+ _ = c[1<<100 : 1<<110] // ERROR "overflows int" "invalid slice index 1 << 100|index out of bounds"
var t string
_ = 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]
+ _ = t[10]
+ _ = t[9:10]
+ _ = t[10:10]
+ _ = t[9:12]
+ _ = t[11:12]
+ _ = t[1<<100 : 1<<110] // ERROR "overflows int" "invalid slice index 1 << 100|index out of bounds"
}
diff --git a/test/fixedbugs/issue4388.go b/test/fixedbugs/issue4388.go
index 2e052e138..b18c98bac 100644
--- a/test/fixedbugs/issue4388.go
+++ b/test/fixedbugs/issue4388.go
@@ -17,18 +17,18 @@ type T struct {
}
func f1() {
- // The 4 here and below depends on the number of internal runtime frames
+ // The 5 here and below depends on the number of internal runtime frames
// that sit between a deferred function called during panic and
// the original frame. If that changes, this test will start failing and
// the number here will need to be updated.
- defer checkLine(4)
+ defer checkLine(5)
var t *T
var c io.Closer = t
c.Close()
}
func f2() {
- defer checkLine(4)
+ defer checkLine(5)
var t T
var c io.Closer = t
c.Close()
diff --git a/test/fixedbugs/issue5856.go b/test/fixedbugs/issue5856.go
index 35cadf8c9..78ca3b9f6 100644
--- a/test/fixedbugs/issue5856.go
+++ b/test/fixedbugs/issue5856.go
@@ -29,7 +29,7 @@ func f() {
}
func g() {
- _, file, line, _ := runtime.Caller(2)
+ _, file, line, _ := runtime.Caller(3)
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)
diff --git a/test/fixedbugs/issue6703a.go b/test/fixedbugs/issue6703a.go
new file mode 100644
index 000000000..d4c008f83
--- /dev/null
+++ b/test/fixedbugs/issue6703a.go
@@ -0,0 +1,16 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in a function value.
+
+package funcvalue
+
+func fx() int {
+ _ = x
+ return 0
+}
+
+var x = fx // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703b.go b/test/fixedbugs/issue6703b.go
new file mode 100644
index 000000000..326b5839a
--- /dev/null
+++ b/test/fixedbugs/issue6703b.go
@@ -0,0 +1,16 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in a function call.
+
+package funccall
+
+func fx() int {
+ _ = x
+ return 0
+}
+
+var x = fx() // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703c.go b/test/fixedbugs/issue6703c.go
new file mode 100644
index 000000000..473576475
--- /dev/null
+++ b/test/fixedbugs/issue6703c.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in a method expression.
+
+package methexpr
+
+type T int
+
+func (T) m() int {
+ _ = x
+ return 0
+}
+
+var x = T.m // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703d.go b/test/fixedbugs/issue6703d.go
new file mode 100644
index 000000000..0a1952f78
--- /dev/null
+++ b/test/fixedbugs/issue6703d.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in a method expression call.
+
+package methexprcall
+
+type T int
+
+func (T) m() int {
+ _ = x
+ return 0
+}
+
+var x = T.m(0) // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703e.go b/test/fixedbugs/issue6703e.go
new file mode 100644
index 000000000..416066e85
--- /dev/null
+++ b/test/fixedbugs/issue6703e.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in the method value of a value literal.
+
+package litmethvalue
+
+type T int
+
+func (T) m() int {
+ _ = x
+ return 0
+}
+
+var x = T(0).m // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703f.go b/test/fixedbugs/issue6703f.go
new file mode 100644
index 000000000..30238297b
--- /dev/null
+++ b/test/fixedbugs/issue6703f.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in the method call of a value literal.
+
+package litmethcall
+
+type T int
+
+func (T) m() int {
+ _ = x
+ return 0
+}
+
+var x = T(0).m() // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703g.go b/test/fixedbugs/issue6703g.go
new file mode 100644
index 000000000..002b5a636
--- /dev/null
+++ b/test/fixedbugs/issue6703g.go
@@ -0,0 +1,20 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in an embedded method expression.
+
+package embedmethexpr
+
+type T int
+
+func (T) m() int {
+ _ = x
+ return 0
+}
+
+type E struct{ T }
+
+var x = E.m // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703h.go b/test/fixedbugs/issue6703h.go
new file mode 100644
index 000000000..234ccb365
--- /dev/null
+++ b/test/fixedbugs/issue6703h.go
@@ -0,0 +1,20 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles when calling an embedded method expression.
+
+package embedmethexprcall
+
+type T int
+
+func (T) m() int {
+ _ = x
+ return 0
+}
+
+type E struct{ T }
+
+var x = E.m(E{0}) // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703i.go b/test/fixedbugs/issue6703i.go
new file mode 100644
index 000000000..78b4d4980
--- /dev/null
+++ b/test/fixedbugs/issue6703i.go
@@ -0,0 +1,20 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in an embedded struct literal's method value.
+
+package embedlitmethvalue
+
+type T int
+
+func (T) m() int {
+ _ = x
+ return 0
+}
+
+type E struct{ T }
+
+var x = E{}.m // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703j.go b/test/fixedbugs/issue6703j.go
new file mode 100644
index 000000000..a7f63f748
--- /dev/null
+++ b/test/fixedbugs/issue6703j.go
@@ -0,0 +1,20 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in an embedded struct literal's method call.
+
+package embedlitmethcall
+
+type T int
+
+func (T) m() int {
+ _ = x
+ return 0
+}
+
+type E struct{ T }
+
+var x = E{}.m() // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703k.go b/test/fixedbugs/issue6703k.go
new file mode 100644
index 000000000..19c61078c
--- /dev/null
+++ b/test/fixedbugs/issue6703k.go
@@ -0,0 +1,21 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in a method value.
+
+package methvalue
+
+type T int
+
+func (T) m() int {
+ _ = x
+ return 0
+}
+
+var (
+ t T
+ x = t.m // ERROR "initialization loop|depends upon itself"
+)
diff --git a/test/fixedbugs/issue6703l.go b/test/fixedbugs/issue6703l.go
new file mode 100644
index 000000000..3f4ca3147
--- /dev/null
+++ b/test/fixedbugs/issue6703l.go
@@ -0,0 +1,21 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in a method call.
+
+package methcall
+
+type T int
+
+func (T) m() int {
+ _ = x
+ return 0
+}
+
+var (
+ t T
+ x = t.m() // ERROR "initialization loop|depends upon itself"
+)
diff --git a/test/fixedbugs/issue6703m.go b/test/fixedbugs/issue6703m.go
new file mode 100644
index 000000000..d80959cdc
--- /dev/null
+++ b/test/fixedbugs/issue6703m.go
@@ -0,0 +1,25 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in the method value of a value returned from a function call.
+
+package funcmethvalue
+
+type T int
+
+func (T) m() int {
+ _ = x
+ return 0
+}
+
+func f() T {
+ return T(0)
+}
+
+var (
+ t T
+ x = f().m // ERROR "initialization loop|depends upon itself"
+)
diff --git a/test/fixedbugs/issue6703n.go b/test/fixedbugs/issue6703n.go
new file mode 100644
index 000000000..2c623f219
--- /dev/null
+++ b/test/fixedbugs/issue6703n.go
@@ -0,0 +1,25 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in the method call of a value returned from a function call.
+
+package funcmethcall
+
+type T int
+
+func (T) m() int {
+ _ = x
+ return 0
+}
+
+func f() T {
+ return T(0)
+}
+
+var (
+ t T
+ x = f().m() // ERROR "initialization loop|depends upon itself"
+)
diff --git a/test/fixedbugs/issue6703o.go b/test/fixedbugs/issue6703o.go
new file mode 100644
index 000000000..efc894737
--- /dev/null
+++ b/test/fixedbugs/issue6703o.go
@@ -0,0 +1,23 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in an embedded struct's method value.
+
+package embedmethvalue
+
+type T int
+
+func (T) m() int {
+ _ = x
+ return 0
+}
+
+type E struct{ T }
+
+var (
+ e E
+ x = e.m // ERROR "initialization loop|depends upon itself"
+)
diff --git a/test/fixedbugs/issue6703p.go b/test/fixedbugs/issue6703p.go
new file mode 100644
index 000000000..dad88f634
--- /dev/null
+++ b/test/fixedbugs/issue6703p.go
@@ -0,0 +1,23 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in an embedded struct's method call.
+
+package embedmethcall
+
+type T int
+
+func (T) m() int {
+ _ = x
+ return 0
+}
+
+type E struct{ T }
+
+var (
+ e E
+ x = e.m() // ERROR "initialization loop|depends upon itself"
+)
diff --git a/test/fixedbugs/issue6703q.go b/test/fixedbugs/issue6703q.go
new file mode 100644
index 000000000..7bd748aaa
--- /dev/null
+++ b/test/fixedbugs/issue6703q.go
@@ -0,0 +1,28 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in the method value of an embedded struct returned
+// from a function call.
+
+package funcembedmethvalue
+
+type T int
+
+func (T) m() int {
+ _ = x
+ return 0
+}
+
+func g() E {
+ return E{0}
+}
+
+type E struct{ T }
+
+var (
+ e E
+ x = g().m // ERROR "initialization loop|depends upon itself"
+)
diff --git a/test/fixedbugs/issue6703r.go b/test/fixedbugs/issue6703r.go
new file mode 100644
index 000000000..669846241
--- /dev/null
+++ b/test/fixedbugs/issue6703r.go
@@ -0,0 +1,28 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in the method call of an embedded struct returned
+// from a function call.
+
+package funcembedmethcall
+
+type T int
+
+func (T) m() int {
+ _ = x
+ return 0
+}
+
+func g() E {
+ return E{0}
+}
+
+type E struct{ T }
+
+var (
+ e E
+ x = g().m() // ERROR "initialization loop|depends upon itself"
+)
diff --git a/test/fixedbugs/issue6703s.go b/test/fixedbugs/issue6703s.go
new file mode 100644
index 000000000..6aa28483a
--- /dev/null
+++ b/test/fixedbugs/issue6703s.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in a pointer method expression.
+
+package ptrmethexpr
+
+type T int
+
+func (*T) pm() int {
+ _ = x
+ return 0
+}
+
+var x = (*T).pm // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703t.go b/test/fixedbugs/issue6703t.go
new file mode 100644
index 000000000..bad65ad16
--- /dev/null
+++ b/test/fixedbugs/issue6703t.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in the call of a pointer method expression.
+
+package ptrmethexprcall
+
+type T int
+
+func (*T) pm() int {
+ _ = x
+ return 0
+}
+
+var x = (*T).pm(nil) // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703u.go b/test/fixedbugs/issue6703u.go
new file mode 100644
index 000000000..b6813b771
--- /dev/null
+++ b/test/fixedbugs/issue6703u.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in a pointer literal's method value.
+
+package ptrlitmethvalue
+
+type T int
+
+func (*T) pm() int {
+ _ = x
+ return 0
+}
+
+var x = (*T)(nil).pm // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703v.go b/test/fixedbugs/issue6703v.go
new file mode 100644
index 000000000..a1b3711bb
--- /dev/null
+++ b/test/fixedbugs/issue6703v.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in a pointer literal's method call.
+
+package ptrlitmethcall
+
+type T int
+
+func (*T) pm() int {
+ _ = x
+ return 0
+}
+
+var x = (*T)(nil).pm() // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703w.go b/test/fixedbugs/issue6703w.go
new file mode 100644
index 000000000..d4733deba
--- /dev/null
+++ b/test/fixedbugs/issue6703w.go
@@ -0,0 +1,21 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in a pointer value's method value.
+
+package ptrmethvalue
+
+type T int
+
+func (*T) pm() int {
+ _ = x
+ return 0
+}
+
+var (
+ p *T
+ x = p.pm // ERROR "initialization loop|depends upon itself"
+)
diff --git a/test/fixedbugs/issue6703x.go b/test/fixedbugs/issue6703x.go
new file mode 100644
index 000000000..8008b8c37
--- /dev/null
+++ b/test/fixedbugs/issue6703x.go
@@ -0,0 +1,21 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in a pointer value's method call.
+
+package ptrmethcall
+
+type T int
+
+func (*T) pm() int {
+ _ = x
+ return 0
+}
+
+var (
+ p *T
+ x = p.pm() // ERROR "initialization loop|depends upon itself"
+)
diff --git a/test/fixedbugs/issue6703y.go b/test/fixedbugs/issue6703y.go
new file mode 100644
index 000000000..ac4526dda
--- /dev/null
+++ b/test/fixedbugs/issue6703y.go
@@ -0,0 +1,23 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in the method value of a pointer value returned
+// from a function call.
+
+package funcptrmethvalue
+
+type T int
+
+func (*T) pm() int {
+ _ = x
+ return 0
+}
+
+func pf() *T {
+ return nil
+}
+
+var x = pf().pm // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703z.go b/test/fixedbugs/issue6703z.go
new file mode 100644
index 000000000..d4c17e13a
--- /dev/null
+++ b/test/fixedbugs/issue6703z.go
@@ -0,0 +1,23 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check for cycles in the method call of a pointer value returned
+// from a function call.
+
+package funcptrmethcall
+
+type T int
+
+func (*T) pm() int {
+ _ = x
+ return 0
+}
+
+func pf() *T {
+ return nil
+}
+
+var x = pf().pm() // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue7690.go b/test/fixedbugs/issue7690.go
new file mode 100644
index 000000000..4ad9e8622
--- /dev/null
+++ b/test/fixedbugs/issue7690.go
@@ -0,0 +1,49 @@
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// issue 7690 - Stack and other routines did not back up initial PC
+// into CALL instruction, instead reporting line number of next instruction,
+// which might be on a different line.
+
+package main
+
+import (
+ "bytes"
+ "regexp"
+ "runtime"
+ "strconv"
+)
+
+func main() {
+ buf1 := make([]byte, 1000)
+ buf2 := make([]byte, 1000)
+
+ runtime.Stack(buf1, false) // CALL is last instruction on this line
+ n := runtime.Stack(buf2, false) // CALL is followed by load of result from stack
+
+ buf1 = buf1[:bytes.IndexByte(buf1, 0)]
+ buf2 = buf2[:n]
+
+ re := regexp.MustCompile(`(?m)^main\.main\(\)\n.*/issue7690.go:([0-9]+)`)
+ m1 := re.FindStringSubmatch(string(buf1))
+ if m1 == nil {
+ println("BUG: cannot find main.main in first trace")
+ return
+ }
+ m2 := re.FindStringSubmatch(string(buf2))
+ if m2 == nil {
+ println("BUG: cannot find main.main in second trace")
+ return
+ }
+
+ n1, _ := strconv.Atoi(m1[1])
+ n2, _ := strconv.Atoi(m2[1])
+ if n1+1 != n2 {
+ println("BUG: expect runtime.Stack on back to back lines, have", n1, n2)
+ println(string(buf1))
+ println(string(buf2))
+ }
+}
diff --git a/test/fixedbugs/issue7760.go b/test/fixedbugs/issue7760.go
new file mode 100644
index 000000000..cccae4891
--- /dev/null
+++ b/test/fixedbugs/issue7760.go
@@ -0,0 +1,25 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Verify that pointers can't be used as constants.
+
+package main
+
+import "unsafe"
+
+type myPointer unsafe.Pointer
+
+const _ = unsafe.Pointer(uintptr(1)) // ERROR "is not (a )?constant"
+const _ = myPointer(uintptr(1)) // ERROR "is not (a )?constant"
+
+const _ = (*int)(unsafe.Pointer(uintptr(1))) // ERROR "is not (a )?constant"
+const _ = (*int)(myPointer(uintptr(1))) // ERROR "is not (a )?constant"
+
+const _ = uintptr(unsafe.Pointer(uintptr(1))) // ERROR "is not (a )?constant"
+const _ = uintptr(myPointer(uintptr(1))) // ERROR "is not (a )?constant"
+
+const _ = []byte("") // ERROR "is not (a )?constant"
+const _ = []rune("") // ERROR "is not (a )?constant"
diff --git a/test/fixedbugs/issue8017.go b/test/fixedbugs/issue8017.go
new file mode 100644
index 000000000..22056e08c
--- /dev/null
+++ b/test/fixedbugs/issue8017.go
@@ -0,0 +1,26 @@
+// compile
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issues 8017 and 8058: walk modifies nodes generated
+// by slicelit and causes an internal error afterwards
+// when gen_as_init parses it back.
+
+package main
+
+func F() {
+ var ch chan int
+ select {
+ case <-ch:
+ case <-make(chan int, len([2][]int{([][]int{})[len(ch)], []int{}})):
+ }
+}
+
+func G() {
+ select {
+ case <-([1][]chan int{[]chan int{}})[0][0]:
+ default:
+ }
+}
diff --git a/test/fixedbugs/issue8060.dir/a.go b/test/fixedbugs/issue8060.dir/a.go
new file mode 100644
index 000000000..22ba69ee1
--- /dev/null
+++ b/test/fixedbugs/issue8060.dir/a.go
@@ -0,0 +1,7 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+var A = []*[2][1]float64{}
diff --git a/test/fixedbugs/issue8060.dir/b.go b/test/fixedbugs/issue8060.dir/b.go
new file mode 100644
index 000000000..85fb6ec7d
--- /dev/null
+++ b/test/fixedbugs/issue8060.dir/b.go
@@ -0,0 +1,13 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package b
+
+import "a"
+
+var X = a.A
+
+func b() {
+ _ = [3][1]float64{}
+}
diff --git a/test/fixedbugs/issue8060.go b/test/fixedbugs/issue8060.go
new file mode 100644
index 000000000..ec52659e6
--- /dev/null
+++ b/test/fixedbugs/issue8060.go
@@ -0,0 +1,9 @@
+// compiledir
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 8060: internal compiler error.
+
+package ignored
diff --git a/test/fixedbugs/issue8074.go b/test/fixedbugs/issue8074.go
new file mode 100644
index 000000000..aedab240e
--- /dev/null
+++ b/test/fixedbugs/issue8074.go
@@ -0,0 +1,16 @@
+// compile
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// issue 8074.
+// was "cannot take the address of 1"
+
+package main
+
+func main() {
+ a := make([]byte, 10)
+ m := make(map[float64][]byte)
+ go copy(a, m[1.0])
+}
diff --git a/test/fixedbugs/issue8079.go b/test/fixedbugs/issue8079.go
new file mode 100644
index 000000000..994999bf6
--- /dev/null
+++ b/test/fixedbugs/issue8079.go
@@ -0,0 +1,11 @@
+// compile
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 8079: gccgo crashes when compiling interface with blank type name.
+
+package p
+
+type _ interface{}
diff --git a/test/fixedbugs/issue8280.dir/a.go b/test/fixedbugs/issue8280.dir/a.go
new file mode 100644
index 000000000..588536e79
--- /dev/null
+++ b/test/fixedbugs/issue8280.dir/a.go
@@ -0,0 +1,3 @@
+package a
+
+var Bar = func() (_ int) { return 0 }
diff --git a/test/fixedbugs/issue8280.dir/b.go b/test/fixedbugs/issue8280.dir/b.go
new file mode 100644
index 000000000..c46c55458
--- /dev/null
+++ b/test/fixedbugs/issue8280.dir/b.go
@@ -0,0 +1,5 @@
+package b
+
+import "./a"
+
+var foo = a.Bar
diff --git a/test/fixedbugs/issue8280.go b/test/fixedbugs/issue8280.go
new file mode 100644
index 000000000..91256c852
--- /dev/null
+++ b/test/fixedbugs/issue8280.go
@@ -0,0 +1,9 @@
+// compiledir
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 8280: cannot import package exporting a func var returning a result named _
+
+package ignored
diff --git a/test/fixedbugs/issue8311.go b/test/fixedbugs/issue8311.go
new file mode 100644
index 000000000..dd928566d
--- /dev/null
+++ b/test/fixedbugs/issue8311.go
@@ -0,0 +1,16 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// issue 8311.
+// error for x++ should say x++ not x += 1
+
+package p
+
+func f() {
+ var x []byte
+ x++ // ERROR "invalid operation: x[+][+]"
+
+}
diff --git a/test/fixedbugs/issue8336.go b/test/fixedbugs/issue8336.go
new file mode 100644
index 000000000..26bdeabb2
--- /dev/null
+++ b/test/fixedbugs/issue8336.go
@@ -0,0 +1,29 @@
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 8336. Order of evaluation of receive channels in select.
+
+package main
+
+type X struct {
+ c chan int
+}
+
+func main() {
+ defer func() {
+ recover()
+ }()
+ var x *X
+ select {
+ case <-x.c: // should fault and panic before foo is called
+ case <-foo():
+ }
+}
+
+func foo() chan int {
+ println("BUG: foo must not be called")
+ return make(chan int)
+}
diff --git a/test/fixedbugs/issue8347.go b/test/fixedbugs/issue8347.go
new file mode 100644
index 000000000..0828ccf06
--- /dev/null
+++ b/test/fixedbugs/issue8347.go
@@ -0,0 +1,27 @@
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func main() {
+ c := make(chan bool, 1)
+ ok := true
+ for i := 0; i < 12; i++ {
+ select {
+ case _, ok = <-c:
+ if i < 10 && !ok {
+ panic("BUG")
+ }
+ default:
+ }
+ if i < 10 && !ok {
+ panic("BUG")
+ }
+ if i >= 10 && ok {
+ close(c)
+ }
+ }
+}
diff --git a/test/fixedbugs/issue8475.go b/test/fixedbugs/issue8475.go
new file mode 100644
index 000000000..e69794534
--- /dev/null
+++ b/test/fixedbugs/issue8475.go
@@ -0,0 +1,25 @@
+// build
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 8745: comma-ok assignments should produce untyped bool as 2nd result.
+
+package main
+
+type mybool bool
+
+func main() {
+ var ok mybool
+ _ = ok
+
+ var i interface{}
+ _, ok = i.(int)
+
+ var m map[int]int
+ _, ok = m[0]
+
+ var c chan int
+ _, ok = <-c
+}
diff --git a/test/fixedbugs/issue8507.go b/test/fixedbugs/issue8507.go
new file mode 100644
index 000000000..00a14aa88
--- /dev/null
+++ b/test/fixedbugs/issue8507.go
@@ -0,0 +1,16 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// issue 8507
+// used to call algtype on invalid recursive type and get into infinite recursion
+
+package p
+
+type T struct{ T } // ERROR "invalid recursive type T"
+
+func f() {
+ println(T{} == T{})
+}
diff --git a/test/fixedbugs/issue8612.go b/test/fixedbugs/issue8612.go
new file mode 100644
index 000000000..93370cf66
--- /dev/null
+++ b/test/fixedbugs/issue8612.go
@@ -0,0 +1,34 @@
+//compile
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Gccgo had a bug comparing a struct or array value with an interface
+// values, when the struct or array was not addressable.
+
+package p
+
+type A [10]int
+
+type S struct {
+ i int
+}
+
+func F1() S {
+ return S{0}
+}
+
+func F2() A {
+ return A{}
+}
+
+func Cmp(v interface{}) bool {
+ if F1() == v {
+ return true
+ }
+ if F2() == v {
+ return true
+ }
+ return false
+}
diff --git a/test/fixedbugs/issue8761.go b/test/fixedbugs/issue8761.go
new file mode 100644
index 000000000..badf639fc
--- /dev/null
+++ b/test/fixedbugs/issue8761.go
@@ -0,0 +1,26 @@
+// compile
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// issue 8761
+// used to confuse code generator into using temporary before initialization.
+// caused 'variable live at entry' error in liveness analysis.
+
+package p
+
+func _() {
+ type C chan int
+ _ = [1][]C{[]C{make(chan int)}}
+}
+
+func _() {
+ type C interface{}
+ _ = [1][]C{[]C{recover()}}
+}
+
+func _() {
+ type C *int
+ _ = [1][]C{[]C{new(int)}}
+}
diff --git a/test/fixedbugs/issue8947.go b/test/fixedbugs/issue8947.go
new file mode 100644
index 000000000..f40c02e99
--- /dev/null
+++ b/test/fixedbugs/issue8947.go
@@ -0,0 +1,53 @@
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Some uses of zeroed constants in non-assignment
+// expressions broke with our more aggressive zeroing
+// of assignments (internal compiler errors).
+
+package main
+
+func f1() {
+ type T [2]int
+ p := T{0, 1}
+ switch p {
+ case T{0, 0}:
+ panic("wrong1")
+ case T{0, 1}:
+ // ok
+ default:
+ panic("wrong2")
+ }
+
+ if p == (T{0, 0}) {
+ panic("wrong3")
+ } else if p == (T{0, 1}) {
+ // ok
+ } else {
+ panic("wrong4")
+ }
+}
+
+type T struct {
+ V int
+}
+
+var X = T{}.V
+
+func f2() {
+ var x = T{}.V
+ if x != 0 {
+ panic("wrongx")
+ }
+ if X != 0 {
+ panic("wrongX")
+ }
+}
+
+func main() {
+ f1()
+ f2()
+}
diff --git a/test/fixedbugs/issue8961.go b/test/fixedbugs/issue8961.go
new file mode 100644
index 000000000..fbfb7e67f
--- /dev/null
+++ b/test/fixedbugs/issue8961.go
@@ -0,0 +1,20 @@
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 8961. Empty composite literals to small globals were not filled in
+package main
+
+type small struct { a int }
+var foo small
+
+func main() {
+ foo.a = 1
+ foo = small{}
+ if foo.a != 0 {
+ println("expected foo.a to be 0, was", foo.a)
+ panic("composite literal not filled in")
+ }
+}
diff --git a/test/fixedbugs/issue9006.go b/test/fixedbugs/issue9006.go
new file mode 100644
index 000000000..c559f58f1
--- /dev/null
+++ b/test/fixedbugs/issue9006.go
@@ -0,0 +1,37 @@
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+type T1 struct {
+ X int
+}
+
+func NewT1(x int) T1 { return T1{x} }
+
+type T2 int
+
+func NewT2(x int) T2 { return T2(x) }
+
+func main() {
+ switch (T1{}) {
+ case NewT1(1):
+ panic("bad1")
+ case NewT1(0):
+ // ok
+ default:
+ panic("bad2")
+ }
+
+ switch T2(0) {
+ case NewT2(2):
+ panic("bad3")
+ case NewT2(0):
+ // ok
+ default:
+ panic("bad4")
+ }
+}
diff --git a/test/fixedbugs/issue9110.go b/test/fixedbugs/issue9110.go
new file mode 100644
index 000000000..729463305
--- /dev/null
+++ b/test/fixedbugs/issue9110.go
@@ -0,0 +1,90 @@
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Scenario that used to leak arbitrarily many SudoG structs.
+// See golang.org/issue/9110.
+
+package main
+
+import (
+ "runtime"
+ "runtime/debug"
+ "sync"
+ "time"
+)
+
+func main() {
+ debug.SetGCPercent(1000000) // only GC when we ask for GC
+
+ var stats, stats1, stats2 runtime.MemStats
+
+ release := func() {}
+ for i := 0; i < 20; i++ {
+ if i == 10 {
+ // Should be warmed up by now.
+ runtime.ReadMemStats(&stats1)
+ }
+
+ c := make(chan int)
+ for i := 0; i < 10; i++ {
+ go func() {
+ select {
+ case <-c:
+ case <-c:
+ case <-c:
+ }
+ }()
+ }
+ time.Sleep(1 * time.Millisecond)
+ release()
+
+ close(c) // let select put its sudog's into the cache
+ time.Sleep(1 * time.Millisecond)
+
+ // pick up top sudog
+ var cond1 sync.Cond
+ var mu1 sync.Mutex
+ cond1.L = &mu1
+ go func() {
+ mu1.Lock()
+ cond1.Wait()
+ mu1.Unlock()
+ }()
+ time.Sleep(1 * time.Millisecond)
+
+ // pick up next sudog
+ var cond2 sync.Cond
+ var mu2 sync.Mutex
+ cond2.L = &mu2
+ go func() {
+ mu2.Lock()
+ cond2.Wait()
+ mu2.Unlock()
+ }()
+ time.Sleep(1 * time.Millisecond)
+
+ // put top sudog back
+ cond1.Broadcast()
+ time.Sleep(1 * time.Millisecond)
+
+ // drop cache on floor
+ runtime.GC()
+
+ // release cond2 after select has gotten to run
+ release = func() {
+ cond2.Broadcast()
+ time.Sleep(1 * time.Millisecond)
+ }
+ }
+
+ runtime.GC()
+
+ runtime.ReadMemStats(&stats2)
+
+ if int(stats2.HeapObjects)-int(stats1.HeapObjects) > 20 { // normally at most 1 or 2; was 300 with leak
+ print("BUG: object leak: ", stats.HeapObjects, " -> ", stats1.HeapObjects, " -> ", stats2.HeapObjects, "\n")
+ }
+}
diff --git a/test/interface/explicit.go b/test/interface/explicit.go
index 36fa1a422..b10d02f24 100644
--- a/test/interface/explicit.go
+++ b/test/interface/explicit.go
@@ -83,12 +83,12 @@ var m4 = M(jj) // ERROR "invalid|wrong type for M method"
type B1 interface {
- _()
+ _() // ERROR "methods must have a unique non-blank name"
}
type B2 interface {
M()
- _()
+ _() // ERROR "methods must have a unique non-blank name"
}
type T2 struct{}
diff --git a/test/interface/fail.go b/test/interface/fail.go
index 81eb6cb3c..d40a15138 100644
--- a/test/interface/fail.go
+++ b/test/interface/fail.go
@@ -14,7 +14,6 @@ type I interface {
func main() {
shouldPanic(p1)
- shouldPanic(p2)
}
func p1() {
@@ -30,19 +29,6 @@ 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()) {
defer func() {
if recover() == nil {
diff --git a/test/linkx.go b/test/linkx.go
index 12d446ffc..151b6db1e 100644
--- a/test/linkx.go
+++ b/test/linkx.go
@@ -1,20 +1,18 @@
-// $G $D/$F.go && $L -X main.tbd hello $F.$A && ./$A.out
-
-// NOTE: This test is not run by 'run.go' and so not run by all.bash.
-// To run this test you must use the ./run shell script.
+// skip
// 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.
// Test the -X facility of the gc linker (6l etc.).
+// This test is run by linkx_run.go.
package main
var tbd string
+var overwrite string = "dibs"
func main() {
- if tbd != "hello" {
- println("BUG: test/linkx", len(tbd), tbd)
- }
+ println(tbd)
+ println(overwrite)
}
diff --git a/test/linkx_run.go b/test/linkx_run.go
new file mode 100644
index 000000000..5b67ce7d3
--- /dev/null
+++ b/test/linkx_run.go
@@ -0,0 +1,33 @@
+// +build !nacl
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Run the linkx test.
+
+package main
+
+import (
+ "fmt"
+ "os"
+ "os/exec"
+)
+
+func main() {
+ cmd := exec.Command("go", "run", "-ldflags=-X main.tbd hello -X main.overwrite trumped", "linkx.go")
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ fmt.Println(string(out))
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ want := "hello\ntrumped\n"
+ got := string(out)
+ if got != want {
+ fmt.Printf("got %q want %q\n", got, want)
+ os.Exit(1)
+ }
+}
diff --git a/test/live.go b/test/live.go
index b4cced47e..f15bb74ba 100644
--- a/test/live.go
+++ b/test/live.go
@@ -1,4 +1,4 @@
-// errorcheck -0 -l -live
+// errorcheck -0 -l -live -wb=0
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
@@ -118,7 +118,10 @@ var i9 interface{}
func f9() bool {
g8()
x := i9
- return x != 99
+ // using complex number in comparison so that
+ // there is always a convT2E, no matter what the
+ // interface rules are.
+ return x != 99.0i // ERROR "live at call to convT2E: x"
}
// liveness formerly confused by UNDEF followed by RET,
@@ -138,7 +141,7 @@ var b bool
// this used to have a spurious "live at entry to f11a: ~r0"
func f11a() *int {
- select { // ERROR "live at call to selectgo: autotmp"
+ select { // ERROR "live at call to newselect: autotmp" "live at call to selectgo: autotmp"
case <-c: // ERROR "live at call to selectrecv: autotmp"
return nil
case <-c: // ERROR "live at call to selectrecv: autotmp"
@@ -153,7 +156,7 @@ func f11b() *int {
// get to the bottom of the function.
// This used to have a spurious "live at call to printint: p".
print(1) // nothing live here!
- select { // ERROR "live at call to selectgo: autotmp"
+ select { // ERROR "live at call to newselect: autotmp" "live at call to selectgo: autotmp"
case <-c: // ERROR "live at call to selectrecv: autotmp"
return nil
case <-c: // ERROR "live at call to selectrecv: autotmp"
@@ -170,7 +173,7 @@ func f11c() *int {
// Unlike previous, the cases in this select fall through,
// so we can get to the println, so p is not dead.
print(1) // ERROR "live at call to printint: p"
- select { // ERROR "live at call to newselect: p" "live at call to selectgo: autotmp.* p"
+ select { // ERROR "live at call to newselect: autotmp.* p" "live at call to selectgo: autotmp.* p"
case <-c: // ERROR "live at call to selectrecv: autotmp.* p"
case <-c: // ERROR "live at call to selectrecv: autotmp.* p"
}
@@ -184,7 +187,7 @@ func f11c() *int {
func f12() *int {
if b {
- select{}
+ select {}
} else {
return nil
}
@@ -215,7 +218,7 @@ func f15() {
var x string
_ = &x
x = g15() // ERROR "live at call to g15: x"
- print(x) // ERROR "live at call to printstring: x"
+ print(x) // ERROR "live at call to printstring: x"
}
func g15() string
@@ -287,7 +290,7 @@ var ch chan *byte
func f19() {
// dest temporary for channel receive.
var z *byte
-
+
if b {
z = <-ch // ERROR "live at call to chanrecv1: autotmp_[0-9]+$"
}
@@ -348,21 +351,21 @@ func f25(b bool) {
var x string
_ = &x
x = g15() // ERROR "live at call to g15: x"
- print(x) // ERROR "live at call to printstring: x"
+ print(x) // ERROR "live at call to printstring: x"
} // ERROR "live at call to deferreturn: x"
func g25()
-
+
// non-escaping ... slices passed to function call should die on return,
// so that the temporaries do not stack and do not cause ambiguously
// live variables.
func f26(b bool) {
if b {
- print26(1,2,3) // ERROR "live at call to print26: autotmp_[0-9]+$"
+ print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "live at call to print26: autotmp_[0-9]+$"
}
- print26(4,5,6) // ERROR "live at call to print26: autotmp_[0-9]+$"
- print26(7,8,9) // ERROR "live at call to print26: autotmp_[0-9]+$"
+ print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "live at call to print26: autotmp_[0-9]+$"
+ print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "live at call to print26: autotmp_[0-9]+$"
println()
}
@@ -374,10 +377,10 @@ func print26(...interface{})
func f27(b bool) {
x := 0
if b {
- call27(func() {x++}) // ERROR "live at call to call27: autotmp_[0-9]+$"
+ call27(func() { x++ }) // ERROR "live at call to call27: autotmp_[0-9]+$"
}
- call27(func() {x++}) // ERROR "live at call to call27: autotmp_[0-9]+$"
- call27(func() {x++}) // ERROR "live at call to call27: autotmp_[0-9]+$"
+ call27(func() { x++ }) // ERROR "live at call to call27: autotmp_[0-9]+$"
+ call27(func() { x++ }) // ERROR "live at call to call27: autotmp_[0-9]+$"
println()
}
@@ -386,10 +389,10 @@ func f27(b bool) {
func f27defer(b bool) {
x := 0
if b {
- defer call27(func() {x++}) // ERROR "live at call to deferproc: autotmp_[0-9]+$" "live at call to deferreturn: autotmp_[0-9]+$"
+ defer call27(func() { x++ }) // ERROR "live at call to deferproc: autotmp_[0-9]+$" "live at call to deferreturn: autotmp_[0-9]+$"
}
- defer call27(func() {x++}) // ERROR "live at call to deferproc: autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to deferreturn: autotmp_[0-9]+ autotmp_[0-9]+$" "ambiguously live"
- println() // ERROR "live at call to printnl: autotmp_[0-9]+ autotmp_[0-9]+$"
+ defer call27(func() { x++ }) // ERROR "live at call to deferproc: autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to deferreturn: autotmp_[0-9]+ autotmp_[0-9]+$" "ambiguously live"
+ println() // ERROR "live at call to printnl: autotmp_[0-9]+ autotmp_[0-9]+$"
} // ERROR "live at call to deferreturn: autotmp_[0-9]+ autotmp_[0-9]+$"
// and newproc (go) escapes to the heap
@@ -397,9 +400,9 @@ func f27defer(b bool) {
func f27go(b bool) {
x := 0
if b {
- go call27(func() {x++}) // ERROR "live at call to new: &x" "live at call to newproc: &x$"
+ go call27(func() { x++ }) // ERROR "live at call to newobject: &x" "live at call to newproc: &x$"
}
- go call27(func() {x++}) // ERROR "live at call to new: &x"
+ go call27(func() { x++ }) // ERROR "live at call to newobject: &x"
println()
}
@@ -412,11 +415,11 @@ var s1, s2, s3, s4, s5, s6, s7, s8, s9, s10 string
func f28(b bool) {
if b {
- print(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10) // ERROR "live at call to concatstrings: autotmp_[0-9]+$" "live at call to printstring: autotmp_[0-9]+$"
+ print(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10) // ERROR "live at call to concatstrings: autotmp_[0-9]+$" "live at call to printstring: autotmp_[0-9]+$"
}
- print(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10) // ERROR "live at call to concatstrings: autotmp_[0-9]+$" "live at call to printstring: autotmp_[0-9]+$"
- print(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10) // ERROR "live at call to concatstrings: autotmp_[0-9]+$" "live at call to printstring: autotmp_[0-9]+$"
-}
+ print(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10) // ERROR "live at call to concatstrings: autotmp_[0-9]+$" "live at call to printstring: autotmp_[0-9]+$"
+ print(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10) // ERROR "live at call to concatstrings: autotmp_[0-9]+$" "live at call to printstring: autotmp_[0-9]+$"
+}
// map iterator should die on end of range loop
@@ -461,10 +464,10 @@ func f31(b1, b2, b3 bool) {
g31("a") // ERROR "live at call to convT2E: autotmp_[0-9]+$" "live at call to g31: autotmp_[0-9]+$"
}
if b2 {
- h31("b") // ERROR "live at call to new: autotmp_[0-9]+$" "live at call to convT2E: autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to h31: autotmp_[0-9]+$"
+ h31("b") // ERROR "live at call to newobject: autotmp_[0-9]+$" "live at call to convT2E: autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to h31: autotmp_[0-9]+$"
}
if b3 {
- panic("asdf") // ERROR "live at call to convT2E: autotmp_[0-9]+$" "live at call to panic: autotmp_[0-9]+$"
+ panic("asdf") // ERROR "live at call to convT2E: autotmp_[0-9]+$" "live at call to gopanic: autotmp_[0-9]+$"
}
print(b3)
}
@@ -583,14 +586,16 @@ func f39a() (x []int) {
}
func f39b() (x [10]*int) {
- x = [10]*int{new(int)} // ERROR "live at call to new: x"
- println() // ERROR "live at call to printnl: x"
+ x = [10]*int{}
+ x[0] = new(int) // ERROR "live at call to newobject: x"
+ println() // ERROR "live at call to printnl: x"
return x
}
func f39c() (x [10]*int) {
- x = [10]*int{new(int)} // ERROR "live at call to new: x"
- println() // ERROR "live at call to printnl: x"
+ x = [10]*int{}
+ x[0] = new(int) // ERROR "live at call to newobject: x"
+ println() // ERROR "live at call to printnl: x"
return
}
@@ -602,9 +607,8 @@ type T40 struct {
}
func newT40() *T40 {
- ret := T40{ // ERROR "live at call to makemap: &ret"
- make(map[int]int),
- }
+ ret := T40{}
+ ret.m = make(map[int]int) // ERROR "live at call to makemap: &ret"
return &ret
}
@@ -615,9 +619,8 @@ func bad40() {
}
func good40() {
- ret := T40{ // ERROR "live at call to makemap: ret"
- make(map[int]int),
- }
+ ret := T40{}
+ ret.m = make(map[int]int) // ERROR "live at call to makemap: ret"
t := &ret
println() // ERROR "live at call to printnl: ret"
_ = t
diff --git a/test/live2.go b/test/live2.go
index 1e3279402..ef6ad994c 100644
--- a/test/live2.go
+++ b/test/live2.go
@@ -1,4 +1,4 @@
-// errorcheck -0 -live
+// errorcheck -0 -live -wb=0
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
@@ -17,9 +17,8 @@ type T40 struct {
}
func newT40() *T40 {
- ret := T40{ // ERROR "live at call to makemap: &ret"
- make(map[int]int),
- }
+ ret := T40{}
+ ret.m = make(map[int]int) // ERROR "live at call to makemap: &ret"
return &ret
}
@@ -30,9 +29,8 @@ func bad40() {
}
func good40() {
- ret := T40{ // ERROR "live at call to makemap: ret"
- make(map[int]int),
- }
+ ret := T40{}
+ ret.m = make(map[int]int) // ERROR "live at call to makemap: ret"
t := &ret
println() // ERROR "live at call to printnl: ret"
_ = t
diff --git a/test/map.go b/test/map.go
index 485e743fe..2c1cf8a14 100644
--- a/test/map.go
+++ b/test/map.go
@@ -5,7 +5,7 @@
// license that can be found in the LICENSE file.
// Test maps, almost exhaustively.
-// NaN complexity test is in mapnan.go.
+// Complexity (linearity) test is in maplinear.go.
package main
diff --git a/test/maplinear.go b/test/maplinear.go
new file mode 100644
index 000000000..34d091491
--- /dev/null
+++ b/test/maplinear.go
@@ -0,0 +1,172 @@
+// +build darwin linux
+// 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 maps don't go quadratic for NaNs and other values.
+
+package main
+
+import (
+ "fmt"
+ "math"
+ "time"
+)
+
+// checkLinear asserts that the running time of f(n) is in O(n).
+// tries is the initial number of iterations.
+func checkLinear(typ string, tries int, f func(n int)) {
+ // Depending on the machine and OS, this test might be too fast
+ // to measure with accurate enough granularity. On failure,
+ // make it run longer, hoping that the timing granularity
+ // is eventually sufficient.
+
+ timeF := func(n int) time.Duration {
+ t1 := time.Now()
+ f(n)
+ return time.Since(t1)
+ }
+
+ t0 := time.Now()
+
+ n := tries
+ fails := 0
+ for {
+ t1 := timeF(n)
+ t2 := timeF(2 * n)
+
+ // should be 2x (linear); allow up to 3x
+ if t2 < 3*t1 {
+ if false {
+ fmt.Println(typ, "\t", time.Since(t0))
+ }
+ return
+ }
+ // If n ops run in under a second and the ratio
+ // doesn't work out, make n bigger, trying to reduce
+ // the effect that a constant amount of overhead has
+ // on the computed ratio.
+ if t1 < 1*time.Second {
+ n *= 2
+ continue
+ }
+ // Once the test runs long enough for n ops,
+ // try to get the right ratio at least once.
+ // If five in a row all fail, give up.
+ if fails++; fails >= 5 {
+ panic(fmt.Sprintf("%s: too slow: %d inserts: %v; %d inserts: %v\n",
+ typ, n, t1, 2*n, t2))
+ }
+ }
+}
+
+type I interface {
+ f()
+}
+
+type C int
+
+func (C) f() {}
+
+func main() {
+ // NaNs. ~31ms on a 1.6GHz Zeon.
+ checkLinear("NaN", 30000, func(n int) {
+ m := map[float64]int{}
+ nan := math.NaN()
+ for i := 0; i < n; i++ {
+ m[nan] = 1
+ }
+ if len(m) != n {
+ panic("wrong size map after nan insertion")
+ }
+ })
+
+ // ~6ms on a 1.6GHz Zeon.
+ checkLinear("eface", 10000, func(n int) {
+ m := map[interface{}]int{}
+ for i := 0; i < n; i++ {
+ m[i] = 1
+ }
+ })
+
+ // ~7ms on a 1.6GHz Zeon.
+ // Regression test for CL 119360043.
+ checkLinear("iface", 10000, func(n int) {
+ m := map[I]int{}
+ for i := 0; i < n; i++ {
+ m[C(i)] = 1
+ }
+ })
+
+ // ~6ms on a 1.6GHz Zeon.
+ checkLinear("int", 10000, func(n int) {
+ m := map[int]int{}
+ for i := 0; i < n; i++ {
+ m[i] = 1
+ }
+ })
+
+ // ~18ms on a 1.6GHz Zeon.
+ checkLinear("string", 10000, func(n int) {
+ m := map[string]int{}
+ for i := 0; i < n; i++ {
+ m[fmt.Sprint(i)] = 1
+ }
+ })
+
+ // ~6ms on a 1.6GHz Zeon.
+ checkLinear("float32", 10000, func(n int) {
+ m := map[float32]int{}
+ for i := 0; i < n; i++ {
+ m[float32(i)] = 1
+ }
+ })
+
+ // ~6ms on a 1.6GHz Zeon.
+ checkLinear("float64", 10000, func(n int) {
+ m := map[float64]int{}
+ for i := 0; i < n; i++ {
+ m[float64(i)] = 1
+ }
+ })
+
+ // ~22ms on a 1.6GHz Zeon.
+ checkLinear("complex64", 10000, func(n int) {
+ m := map[complex64]int{}
+ for i := 0; i < n; i++ {
+ m[complex(float32(i), float32(i))] = 1
+ }
+ })
+
+ // ~32ms on a 1.6GHz Zeon.
+ checkLinear("complex128", 10000, func(n int) {
+ m := map[complex128]int{}
+ for i := 0; i < n; i++ {
+ m[complex(float64(i), float64(i))] = 1
+ }
+ })
+
+ // ~70ms on a 1.6GHz Zeon.
+ // The iterate/delete idiom currently takes expected
+ // O(n lg n) time. Fortunately, the checkLinear test
+ // leaves enough wiggle room to include n lg n time
+ // (it actually tests for O(n^log_2(3)).
+ // To prevent false positives, average away variation
+ // by doing multiple rounds within a single run.
+ checkLinear("iterdelete", 2500, func(n int) {
+ for round := 0; round < 4; round++ {
+ m := map[int]int{}
+ for i := 0; i < n; i++ {
+ m[i] = i
+ }
+ for i := 0; i < n; i++ {
+ for k := range m {
+ delete(m, k)
+ break
+ }
+ }
+ }
+ })
+}
diff --git a/test/mapnan.go b/test/mapnan.go
deleted file mode 100644
index f081cab01..000000000
--- a/test/mapnan.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// +build darwin linux
-// 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 NaNs in maps don't go quadratic.
-
-package main
-
-import (
- "fmt"
- "math"
- "time"
-)
-
-func main() {
-
- // Test that NaNs in maps don't go quadratic.
- t := func(n int) time.Duration {
- t1 := time.Now()
- m := map[float64]int{}
- nan := math.NaN()
- for i := 0; i < n; i++ {
- m[nan] = 1
- }
- if len(m) != n {
- panic("wrong size map after nan insertion")
- }
- return time.Since(t1)
- }
-
- // Depending on the machine and OS, this test might be too fast
- // to measure with accurate enough granularity. On failure,
- // make it run longer, hoping that the timing granularity
- // is eventually sufficient.
-
- n := 30000 // ~8ms user time on a Mid 2011 MacBook Air (1.8 GHz Core i7)
- fails := 0
- for {
- t1 := t(n)
- t2 := t(2 * n)
- // should be 2x (linear); allow up to 3x
- if t2 < 3*t1 {
- return
- }
- fails++
- if fails == 6 {
- panic(fmt.Sprintf("too slow: %d inserts: %v; %d inserts: %v\n", n, t1, 2*n, t2))
- }
- if fails < 4 {
- n *= 2
- }
- }
-}
diff --git a/test/named1.go b/test/named1.go
index 62b874c5c..febad64ec 100644
--- a/test/named1.go
+++ b/test/named1.go
@@ -41,21 +41,21 @@ func main() {
asBool(1 != 2) // ok now
asBool(i < j) // ok now
- _, b = m[2] // ERROR "cannot .* bool.*type Bool"
+ _, b = m[2] // ok now
var inter interface{}
- _, b = inter.(Map) // ERROR "cannot .* bool.*type Bool"
+ _, b = inter.(Map) // ok now
_ = b
var minter interface {
M()
}
- _, b = minter.(Map) // ERROR "cannot .* bool.*type Bool"
+ _, b = minter.(Map) // ok now
_ = b
_, bb := <-c
asBool(bb) // ERROR "cannot use.*type bool.*as type Bool"
- _, b = <-c // ERROR "cannot .* bool.*type Bool"
+ _, b = <-c // ok now
_ = b
asString(String(slice)) // ok
diff --git a/test/nosplit.go b/test/nosplit.go
index 35aa51017..953a5bf0a 100644
--- a/test/nosplit.go
+++ b/test/nosplit.go
@@ -12,6 +12,7 @@ import (
"bytes"
"fmt"
"io/ioutil"
+ "log"
"os"
"os/exec"
"path/filepath"
@@ -190,7 +191,6 @@ func main() {
return
}
defer os.RemoveAll(dir)
- ioutil.WriteFile(filepath.Join(dir, "main.go"), []byte("package main\nfunc main()\n"), 0666)
tests = strings.Replace(tests, "\t", " ", -1)
tests = commentRE.ReplaceAllString(tests, "")
@@ -230,6 +230,9 @@ TestCases:
continue
}
+ var gobuf bytes.Buffer
+ fmt.Fprintf(&gobuf, "package main\n")
+
var buf bytes.Buffer
if goarch == "arm" {
fmt.Fprintf(&buf, "#define CALL BL\n#define REGISTER (R0)\n")
@@ -242,7 +245,7 @@ TestCases:
if line == "" {
continue
}
- for _, subline := range strings.Split(line, ";") {
+ for i, subline := range strings.Split(line, ";") {
subline = strings.TrimSpace(subline)
if subline == "" {
continue
@@ -255,6 +258,14 @@ TestCases:
}
name := m[1]
size, _ := strconv.Atoi(m[2])
+
+ // The limit was originally 128 but is now 384.
+ // Instead of rewriting the test cases above, adjust
+ // the first stack frame to use up the extra 32 bytes.
+ if i == 0 {
+ size += 384 - 128
+ }
+
if goarch == "amd64" && size%8 == 4 {
continue TestCases
}
@@ -269,11 +280,17 @@ TestCases:
body = callRE.ReplaceAllString(body, "CALL ·$1(SB);")
body = callindRE.ReplaceAllString(body, "CALL REGISTER;")
+ fmt.Fprintf(&gobuf, "func %s()\n", name)
fmt.Fprintf(&buf, "TEXT ·%s(SB)%s,$%d-0\n\t%s\n\tRET\n\n", name, nosplit, size, body)
}
}
- ioutil.WriteFile(filepath.Join(dir, "asm.s"), buf.Bytes(), 0666)
+ if err := ioutil.WriteFile(filepath.Join(dir, "asm.s"), buf.Bytes(), 0666); err != nil {
+ log.Fatal(err)
+ }
+ if err := ioutil.WriteFile(filepath.Join(dir, "main.go"), gobuf.Bytes(), 0666); err != nil {
+ log.Fatal(err)
+ }
cmd := exec.Command("go", "build")
cmd.Dir = dir
diff --git a/test/print.go b/test/print.go
new file mode 100644
index 000000000..466e19f1b
--- /dev/null
+++ b/test/print.go
@@ -0,0 +1,42 @@
+// cmpout
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test internal print routines that are generated
+// by the print builtin. This test is not exhaustive,
+// we're just checking that the formatting is correct.
+
+package main
+
+func main() {
+ println((interface{})(nil)) // printeface
+ println((interface { // printiface
+ f()
+ })(nil))
+ println((map[int]int)(nil)) // printpointer
+ println(([]int)(nil)) // printslice
+ println(int64(-7)) // printint
+ println(uint64(7)) // printuint
+ println(8.0) // printfloat
+ println(complex(9.0, 10.0)) // printcomplex
+ println(true) // printbool
+ println(false) // printbool
+ println("hello") // printstring
+ println("one", "two") // printsp
+
+ // test goprintf
+ defer println((interface{})(nil))
+ defer println((interface{f()})(nil))
+ defer println((map[int]int)(nil))
+ defer println(([]int)(nil))
+ defer println(int64(-11))
+ defer println(uint64(12))
+ defer println(13.0)
+ defer println(complex(14.0, 15.0))
+ defer println(true)
+ defer println(false)
+ defer println("hello")
+ defer println("one", "two")
+}
diff --git a/test/print.out b/test/print.out
new file mode 100644
index 000000000..266fe5d6b
--- /dev/null
+++ b/test/print.out
@@ -0,0 +1,24 @@
+(0x0,0x0)
+(0x0,0x0)
+0x0
+[0/0]0x0
+-7
+7
++8.000000e+000
+(+9.000000e+000+1.000000e+001i)
+true
+false
+hello
+one two
+one two
+hello
+false
+true
+(+1.400000e+001+1.500000e+001i)
++1.300000e+001
+12
+-11
+[0/0]0x0
+0x0
+(0x0,0x0)
+(0x0,0x0)
diff --git a/test/range.go b/test/range.go
index 8effbe9c5..af89edac5 100644
--- a/test/range.go
+++ b/test/range.go
@@ -32,6 +32,13 @@ func testchan() {
println("Wanted lowercase alphabet; got", s)
panic("fail")
}
+ n := 0
+ for range seq('a', 'z') {
+ n++
+ }
+ if n != 26 {
+ println("testchan wrong count", n, "want 26")
+ }
}
// test that range over slice only evaluates
@@ -87,6 +94,22 @@ func testslice1() {
}
}
+func testslice2() {
+ n := 0
+ nmake = 0
+ for range makeslice() {
+ n++
+ }
+ if nmake != 1 {
+ println("range called makeslice", nmake, "times")
+ panic("fail")
+ }
+ if n != 5 {
+ println("wrong count ranging over makeslice", n)
+ panic("fail")
+ }
+}
+
// test that range over array only evaluates
// the expression after "range" once.
@@ -127,6 +150,22 @@ func testarray1() {
}
}
+func testarray2() {
+ n := 0
+ nmake = 0
+ for range makearray() {
+ n++
+ }
+ if nmake != 1 {
+ println("range called makearray", nmake, "times")
+ panic("fail")
+ }
+ if n != 5 {
+ println("wrong count ranging over makearray", n)
+ panic("fail")
+ }
+}
+
func makearrayptr() *[5]int {
nmake++
return &[5]int{1, 2, 3, 4, 5}
@@ -176,6 +215,22 @@ func testarrayptr1() {
}
}
+func testarrayptr2() {
+ n := 0
+ nmake = 0
+ for range makearrayptr() {
+ n++
+ }
+ if nmake != 1 {
+ println("range called makearrayptr", nmake, "times")
+ panic("fail")
+ }
+ if n != 5 {
+ println("wrong count ranging over makearrayptr", n)
+ panic("fail")
+ }
+}
+
// test that range over string only evaluates
// the expression after "range" once.
@@ -216,6 +271,22 @@ func teststring1() {
}
}
+func teststring2() {
+ n := 0
+ nmake = 0
+ for range makestring() {
+ n++
+ }
+ if nmake != 1 {
+ println("range called makestring", nmake, "times")
+ panic("fail")
+ }
+ if n != 5 {
+ println("wrong count ranging over makestring", n)
+ panic("fail")
+ }
+}
+
// test that range over map only evaluates
// the expression after "range" once.
@@ -256,6 +327,22 @@ func testmap1() {
}
}
+func testmap2() {
+ n := 0
+ nmake = 0
+ for range makemap() {
+ n++
+ }
+ if nmake != 1 {
+ println("range called makemap", nmake, "times")
+ panic("fail")
+ }
+ if n != 5 {
+ println("wrong count ranging over makemap", n)
+ panic("fail")
+ }
+}
+
// test that range evaluates the index and value expressions
// exactly once per iteration.
@@ -298,13 +385,18 @@ func main() {
testchan()
testarray()
testarray1()
+ testarray2()
testarrayptr()
testarrayptr1()
+ testarrayptr2()
testslice()
testslice1()
+ testslice2()
teststring()
teststring1()
+ teststring2()
testmap()
testmap1()
+ testmap2()
testcalls()
}
diff --git a/test/recover.go b/test/recover.go
index 071be6667..f92c15c1d 100644
--- a/test/recover.go
+++ b/test/recover.go
@@ -47,6 +47,7 @@ func main() {
test11reflect1()
test11reflect2()
}
+ test111()
test12()
if !interp {
test12reflect1()
@@ -62,6 +63,7 @@ func main() {
test14reflect1()
test14reflect2()
test15()
+ test16()
}
}
@@ -77,7 +79,7 @@ func mustRecoverBody(v1, v2, v3, x interface{}) {
}
v = v2
if v == nil {
- println("missing recover")
+ println("missing recover", x.(int))
die() // panic is useless here
}
if v != x {
@@ -113,10 +115,23 @@ func withoutRecover() {
mustNotRecover() // because it's a sub-call
}
+func withoutRecoverRecursive(n int) {
+ if n == 0 {
+ withoutRecoverRecursive(1)
+ } else {
+ v := recover()
+ if v != nil {
+ println("spurious recover (recursive)", v)
+ die()
+ }
+ }
+}
+
func test1() {
- defer mustNotRecover() // because mustRecover will squelch it
- defer mustRecover(1) // because of panic below
- defer withoutRecover() // should be no-op, leaving for mustRecover to find
+ defer mustNotRecover() // because mustRecover will squelch it
+ defer mustRecover(1) // because of panic below
+ defer withoutRecover() // should be no-op, leaving for mustRecover to find
+ defer withoutRecoverRecursive(0) // ditto
panic(1)
}
@@ -137,7 +152,7 @@ func test1WithClosures() {
mustNotRecover()
v := recover()
if v == nil {
- println("missing recover")
+ println("missing recover", x.(int))
die()
}
if v != x {
@@ -406,6 +421,49 @@ func test11reflect2() {
panic(11)
}
+// tiny receiver, so basic wrapper in i.M()
+type T3deeper struct{}
+
+func (T3deeper) M() {
+ badstate() // difference from T3
+ mustRecoverBody(doubleRecover(), recover(), recover(), 111)
+}
+
+func test111() {
+ var i I = T3deeper{}
+ defer i.M()
+ panic(111)
+}
+
+type Tiny struct{}
+
+func (Tiny) M() {
+ panic(112)
+}
+
+// i.M is a wrapper, and i.M panics.
+//
+// This is a torture test for an old implementation of recover that
+// tried to deal with wrapper functions by doing some argument
+// positioning math on both entry and exit. Doing anything on exit
+// is a problem because sometimes functions exit via panic instead
+// of an ordinary return, so panic would have to know to do the
+// same math when unwinding the stack. It gets complicated fast.
+// This particular test never worked with the old scheme, because
+// panic never did the right unwinding math.
+//
+// The new scheme adjusts Panic.argp on entry to a wrapper.
+// It has no exit work, so if a wrapper is interrupted by a panic,
+// there's no cleanup that panic itself must do.
+// This test just works now.
+func badstate() {
+ defer func() {
+ recover()
+ }()
+ var i I = Tiny{}
+ i.M()
+}
+
// large receiver, so basic wrapper in i.M()
type T4 [2]string
@@ -503,3 +561,27 @@ func test15() {
defer f()
panic(15)
}
+
+func reflectFunc2(args []reflect.Value) (results []reflect.Value) {
+ // This will call reflectFunc3
+ args[0].Interface().(func())()
+ return nil
+}
+
+func reflectFunc3(args []reflect.Value) (results []reflect.Value) {
+ if v := recover(); v != nil {
+ println("spurious recover", v)
+ die()
+ }
+ return nil
+}
+
+func test16() {
+ defer mustRecover(16)
+
+ f2 := reflect.MakeFunc(reflect.TypeOf((func(func()))(nil)), reflectFunc2).Interface().(func(func()))
+ f3 := reflect.MakeFunc(reflect.TypeOf((func())(nil)), reflectFunc3).Interface().(func())
+ defer f2(f3)
+
+ panic(16)
+}
diff --git a/test/run.go b/test/run.go
index a8d4baa3a..e8ec2df9c 100644
--- a/test/run.go
+++ b/test/run.go
@@ -45,7 +45,7 @@ var (
// letter is the build.ArchChar
letter string
-
+
goos, goarch string
// dirs are the directories to look for *.go files in.
@@ -71,8 +71,9 @@ const maxTests = 5000
func main() {
flag.Parse()
- goos = os.Getenv("GOOS")
- goarch = os.Getenv("GOARCH")
+ goos = getenv("GOOS", runtime.GOOS)
+ goarch = getenv("GOARCH", runtime.GOARCH)
+
findExecCmd()
// Disable parallelism if printing or if using a simulator.
@@ -121,7 +122,7 @@ func main() {
failed := false
resCount := map[string]int{}
for _, test := range tests {
- <-test.donec
+ <-test.donec
status := "ok "
errStr := ""
if _, isSkip := test.err.(skipError); isSkip {
@@ -225,8 +226,8 @@ func check(err error) {
type test struct {
dir, gofile string
donec chan bool // closed when done
- dt time.Duration
-
+ dt time.Duration
+
src string
action string // "compile", "build", etc.
@@ -625,6 +626,7 @@ func (t *test) run() {
out, err := runcmd(append([]string{"go", "run", t.goFileName()}, args...)...)
if err != nil {
t.err = err
+ return
}
if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
t.err = fmt.Errorf("incorrect output\n%s", out)
@@ -639,6 +641,7 @@ func (t *test) run() {
out, err := runcmd(append([]string{"go", "run", t.goFileName()}, args...)...)
if err != nil {
t.err = err
+ return
}
tfile := filepath.Join(t.tempDir, "tmp__.go")
if err := ioutil.WriteFile(tfile, out, 0666); err != nil {
@@ -648,6 +651,7 @@ func (t *test) run() {
out, err = runcmd("go", "run", tfile)
if err != nil {
t.err = err
+ return
}
if string(out) != t.expectedOutput() {
t.err = fmt.Errorf("incorrect output\n%s", out)
@@ -658,6 +662,7 @@ func (t *test) run() {
out, err := runcmd(append([]string{"go", "run", t.goFileName()}, args...)...)
if err != nil {
t.err = err
+ return
}
tfile := filepath.Join(t.tempDir, "tmp__.go")
err = ioutil.WriteFile(tfile, out, 0666)
@@ -700,7 +705,7 @@ func findExecCmd() []string {
execCmd = []string{path}
}
return execCmd
-}
+}
func (t *test) String() string {
return filepath.Join(t.dir, t.gofile)
@@ -834,11 +839,11 @@ func partitionStrings(prefix string, strs []string) (matched, unmatched []string
}
type wantedError struct {
- reStr string
- re *regexp.Regexp
- lineNum int
- file string
- prefix string
+ reStr string
+ re *regexp.Regexp
+ lineNum int
+ file string
+ prefix string
}
var (
@@ -889,11 +894,11 @@ func (t *test) wantedErrors(file, short string) (errs []wantedError) {
}
prefix := fmt.Sprintf("%s:%d", short, lineNum)
errs = append(errs, wantedError{
- reStr: rx,
- re: re,
- prefix: prefix,
- lineNum: lineNum,
- file: short,
+ reStr: rx,
+ re: re,
+ prefix: prefix,
+ lineNum: lineNum,
+ file: short,
})
}
}
@@ -902,8 +907,6 @@ func (t *test) wantedErrors(file, short string) (errs []wantedError) {
}
var skipOkay = map[string]bool{
- "linkx.go": true, // like "run" but wants linker flags
- "sinit.go": true,
"fixedbugs/bug248.go": true, // combines errorcheckdir and rundir in the same dir.
"fixedbugs/bug302.go": true, // tests both .$O and .a imports.
"fixedbugs/bug345.go": true, // needs the appropriate flags in gc invocation.
@@ -972,3 +975,11 @@ func envForDir(dir string) []string {
env = append(env, "PWD="+dir)
return env
}
+
+func getenv(key, def string) string {
+ value := os.Getenv(key)
+ if value != "" {
+ return value
+ }
+ return def
+}
diff --git a/test/shift1.go b/test/shift1.go
index 44a3792c4..04f5321b7 100644
--- a/test/shift1.go
+++ b/test/shift1.go
@@ -238,4 +238,6 @@ func _() {
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"
+
+ _, _, _ = x, y, z
}
diff --git a/test/sinit.go b/test/sinit.go
index 5e50e1100..df1a4cc93 100644
--- a/test/sinit.go
+++ b/test/sinit.go
@@ -1,7 +1,4 @@
-// $G -S $D/$F.go | egrep initdone >/dev/null && echo BUG sinit || true
-
-// NOTE: This test is not run by 'run.go' and so not run by all.bash.
-// To run this test you must use the ./run shell script.
+// skip
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
@@ -9,6 +6,7 @@
// Test that many initializations can be done at link time and
// generate no executable init functions.
+// This test is run by sinit_run.go.
package p
@@ -106,20 +104,27 @@ var answers = [...]int{
}
var (
- copy_zero = zero
- copy_one = one
- copy_pi = pi
- copy_slice = slice
+ copy_zero = zero
+ copy_one = one
+ copy_pi = pi
+ copy_slice = slice
copy_sliceInt = sliceInt
- copy_hello = hello
- copy_bytes = bytes
+ copy_hello = hello
+
+ // Could be handled without an initialization function, but
+ // requires special handling for "a = []byte("..."); b = a"
+ // which is not a likely case.
+ // copy_bytes = bytes
+ // https://codereview.appspot.com/171840043 is one approach to
+ // make this special case work.
+
copy_four, copy_five = four, five
- copy_x, copy_y = x, y
- copy_nilslice = nilslice
- copy_nilmap = nilmap
- copy_nilfunc = nilfunc
- copy_nilchan = nilchan
- copy_nilptr = nilptr
+ copy_x, copy_y = x, y
+ copy_nilslice = nilslice
+ copy_nilmap = nilmap
+ copy_nilfunc = nilfunc
+ copy_nilchan = nilchan
+ copy_nilptr = nilptr
)
var copy_a = a
@@ -172,7 +177,7 @@ var sx []int
var s0 = []int{0, 0, 0}
var s1 = []int{1, 2, 3}
-func fi() int
+func fi() int { return 1 }
var ax [10]int
var a0 = [10]int{0, 0, 0}
@@ -202,58 +207,66 @@ var pt0b = &T{X: 0}
var pt1 = &T{X: 1, Y: 2}
var pt1a = &T{3, 4}
-var copy_bx = bx
+// The checks similar to
+// var copy_bx = bx
+// are commented out. The compiler no longer statically initializes them.
+// See issue 7665 and https://codereview.appspot.com/93200044.
+// If https://codereview.appspot.com/169040043 is submitted, and this
+// test is changed to pass -complete to the compiler, then we can
+// uncomment the copy lines again.
+
+// var copy_bx = bx
var copy_b0 = b0
var copy_b1 = b1
-var copy_fx = fx
+// var copy_fx = fx
var copy_f0 = f0
var copy_f1 = f1
-var copy_gx = gx
+// var copy_gx = gx
var copy_g0 = g0
var copy_g1 = g1
-var copy_ix = ix
+// var copy_ix = ix
var copy_i0 = i0
var copy_i1 = i1
-var copy_jx = jx
+// var copy_jx = jx
var copy_j0 = j0
var copy_j1 = j1
-var copy_cx = cx
+// var copy_cx = cx
var copy_c0 = c0
var copy_c1 = c1
-var copy_dx = dx
+// var copy_dx = dx
var copy_d0 = d0
var copy_d1 = d1
-var copy_sx = sx
+// var copy_sx = sx
var copy_s0 = s0
var copy_s1 = s1
-var copy_ax = ax
+// var copy_ax = ax
var copy_a0 = a0
var copy_a1 = a1
-var copy_tx = tx
+// var copy_tx = tx
var copy_t0 = t0
var copy_t0a = t0a
var copy_t0b = t0b
var copy_t1 = t1
var copy_t1a = t1a
-var copy_psx = psx
+// var copy_psx = psx
var copy_ps0 = ps0
var copy_ps1 = ps1
-var copy_pax = pax
+// var copy_pax = pax
var copy_pa0 = pa0
var copy_pa1 = pa1
-var copy_ptx = ptx
+// var copy_ptx = ptx
var copy_pt0 = pt0
var copy_pt0a = pt0a
var copy_pt0b = pt0b
@@ -266,6 +279,8 @@ type T1 int
func (t *T1) M() {}
-type Mer interface { M() }
+type Mer interface {
+ M()
+}
var _ Mer = (*T1)(nil)
diff --git a/test/sinit_run.go b/test/sinit_run.go
new file mode 100644
index 000000000..b0a91ce5b
--- /dev/null
+++ b/test/sinit_run.go
@@ -0,0 +1,40 @@
+// +build !nacl
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Run the sinit test.
+
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "go/build"
+ "os"
+ "os/exec"
+)
+
+func main() {
+ letter, err := build.ArchChar(build.Default.GOARCH)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ cmd := exec.Command("go", "tool", letter+"g", "-S", "sinit.go")
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ fmt.Println(string(out))
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ os.Remove("sinit." + letter)
+
+ if bytes.Contains(out, []byte("initdone")) {
+ fmt.Println("sinit generated an init function")
+ os.Exit(1)
+ }
+}
diff --git a/test/slice3.go b/test/slice3.go
index 3cf34b57e..857eaf3a0 100644
--- a/test/slice3.go
+++ b/test/slice3.go
@@ -19,10 +19,10 @@ 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",
@@ -38,7 +38,7 @@ func main() {
"v10",
"v20",
}
-
+
parse := func(s string) (n int, isconst bool) {
if s == "vminus1" {
return -1, false
@@ -69,7 +69,7 @@ func main() {
iconst && kconst && iv > kv,
iconst && base == "array" && iv > Cap,
jconst && base == "array" && jv > Cap,
- kconst && base == "array" && kv > Cap:
+ kconst && base == "array" && kv > Cap:
continue
}
@@ -82,7 +82,7 @@ func main() {
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, "\tcheckSlice(%q, func() []byte { return %s }, %d, %d, %d)\n", expr, expr, xbase, xlen, xcap)
}
}
}
@@ -147,9 +147,13 @@ func checkSlice(desc string, f func() []byte, xbase, xlen, xcap int) {
println(desc, "=", base, len, cap, "want panic")
return
}
- if base != uintptr(xbase) || len != uintptr(xlen) || cap != uintptr(xcap) {
+ if cap != 0 && base != uintptr(xbase) || base >= 10 || len != uintptr(xlen) || cap != uintptr(xcap) {
notOK()
- println(desc, "=", base, len, cap, "want", xbase, xlen, xcap)
+ if cap == 0 {
+ println(desc, "=", base, len, cap, "want", "0-9", xlen, xcap)
+ } else {
+ println(desc, "=", base, len, cap, "want", xbase, xlen, xcap)
+ }
}
}
diff --git a/test/slicecap.go b/test/slicecap.go
new file mode 100644
index 000000000..dceb7e2cc
--- /dev/null
+++ b/test/slicecap.go
@@ -0,0 +1,90 @@
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "unsafe"
+
+var (
+ hello = "hello"
+ bytes = []byte{1, 2, 3, 4, 5}
+ ints = []int32{1, 2, 3, 4, 5}
+
+ five = 5
+
+ ok = true
+)
+
+func notOK() {
+ if ok {
+ println("BUG:")
+ ok = false
+ }
+}
+
+func checkString(desc, s string) {
+ p1 := *(*uintptr)(unsafe.Pointer(&s))
+ p2 := *(*uintptr)(unsafe.Pointer(&hello))
+ if p1-p2 >= 5 {
+ notOK()
+ println("string", desc, "has invalid base")
+ }
+}
+
+func checkBytes(desc string, s []byte) {
+ p1 := *(*uintptr)(unsafe.Pointer(&s))
+ p2 := *(*uintptr)(unsafe.Pointer(&bytes))
+ if p1-p2 >= 5 {
+ println("byte slice", desc, "has invalid base")
+ }
+}
+
+func checkInts(desc string, s []int32) {
+ p1 := *(*uintptr)(unsafe.Pointer(&s))
+ p2 := *(*uintptr)(unsafe.Pointer(&ints))
+ if p1-p2 >= 5*4 {
+ println("int slice", desc, "has invalid base")
+ }
+}
+
+func main() {
+ {
+ x := hello
+ checkString("x", x)
+ checkString("x[5:]", x[5:])
+ checkString("x[five:]", x[five:])
+ checkString("x[5:five]", x[5:five])
+ checkString("x[five:5]", x[five:5])
+ checkString("x[five:five]", x[five:five])
+ checkString("x[1:][2:][2:]", x[1:][2:][2:])
+ y := x[4:]
+ checkString("y[1:]", y[1:])
+ }
+ {
+ x := bytes
+ checkBytes("x", x)
+ checkBytes("x[5:]", x[5:])
+ checkBytes("x[five:]", x[five:])
+ checkBytes("x[5:five]", x[5:five])
+ checkBytes("x[five:5]", x[five:5])
+ checkBytes("x[five:five]", x[five:five])
+ checkBytes("x[1:][2:][2:]", x[1:][2:][2:])
+ y := x[4:]
+ checkBytes("y[1:]", y[1:])
+ }
+ {
+ x := ints
+ checkInts("x", x)
+ checkInts("x[5:]", x[5:])
+ checkInts("x[five:]", x[five:])
+ checkInts("x[5:five]", x[5:five])
+ checkInts("x[five:5]", x[five:5])
+ checkInts("x[five:five]", x[five:five])
+ checkInts("x[1:][2:][2:]", x[1:][2:][2:])
+ y := x[4:]
+ checkInts("y[1:]", y[1:])
+ }
+}
diff --git a/test/stress/maps.go b/test/stress/maps.go
index d022e19ad..fc5ab05a2 100644
--- a/test/stress/maps.go
+++ b/test/stress/maps.go
@@ -97,6 +97,8 @@ func (m intMap) Len() int { return len(m) }
func (m intMap) RangeAll() {
for _ = range m {
}
+ for range m {
+ }
}
func stressMaps() {
diff --git a/test/stress/parsego.go b/test/stress/parsego.go
index a781f1993..a5856dd80 100644
--- a/test/stress/parsego.go
+++ b/test/stress/parsego.go
@@ -64,7 +64,7 @@ func parseDir(dirpath string) map[string]*ast.Package {
}
func stressParseGo() {
- pkgroot := runtime.GOROOT() + "/src/pkg/"
+ pkgroot := runtime.GOROOT() + "/src/"
for {
m := make(map[string]map[string]*ast.Package)
for _, pkg := range packages {
diff --git a/test/torture.go b/test/torture.go
index bbf6d347d..197b481e6 100644
--- a/test/torture.go
+++ b/test/torture.go
@@ -337,3 +337,10 @@ func ChainDivConst(a int) int {
func ChainMulBytes(a, b, c byte) byte {
return a*(a*(a*(a*(a*(a*(a*(a*(a*b+c)+c)+c)+c)+c)+c)+c)+c) + c
}
+
+func ChainCap() {
+ select {
+ case <-make(chan int, cap(make(chan int, cap(make(chan int, cap(make(chan int, cap(make(chan int))))))))):
+ default:
+ }
+}