1
0
mirror of https://github.com/golang/go synced 2024-11-18 16:54:43 -07:00

go.tools/go/ssa/interp: some fixes to tests

- Break out parts of coverage.go into more specific files.
- Re-enable test of nil interface-to-interface conversion.
- Update initorder test to reflect spec ambiguity and gc vs go/types variance.
- Re-enable test dependent on now-fixed bug 8189 ("value,ok" yields an untyped bool)

LGTM=gri
R=gri
CC=golang-codereviews
https://golang.org/cl/119530043
This commit is contained in:
Alan Donovan 2014-08-07 10:57:00 -04:00
parent 11569f39ea
commit d3f2df4854
7 changed files with 293 additions and 269 deletions

View File

@ -135,14 +135,18 @@ var gorootTestTests = []string{
// These are files in go.tools/go/ssa/interp/testdata/.
var testdataTests = []string{
"boundmeth.go",
"complit.go",
"coverage.go",
"defer.go",
"fieldprom.go",
"ifaceconv.go",
"ifaceprom.go",
"initorder.go",
"methprom.go",
"mrvchain.go",
"range.go",
"recover.go",
"static.go",
"callstack.go",
}

84
go/ssa/interp/testdata/complit.go vendored Normal file
View File

@ -0,0 +1,84 @@
package main
// Tests of composite literals.
import "fmt"
// Map literals.
func init() {
type M map[int]int
m1 := []*M{{1: 1}, &M{2: 2}}
want := "map[1:1] map[2:2]"
if got := fmt.Sprint(*m1[0], *m1[1]); got != want {
panic(got)
}
m2 := []M{{1: 1}, M{2: 2}}
if got := fmt.Sprint(m2[0], m2[1]); got != want {
panic(got)
}
}
// Nonliteral keys in composite literal.
func init() {
const zero int = 1
var v = []int{1 + zero: 42}
if x := fmt.Sprint(v); x != "[0 0 42]" {
panic(x)
}
}
// Test for in-place initialization.
func init() {
// struct
type S struct {
a, b int
}
s := S{1, 2}
s = S{b: 3}
if s.a != 0 {
panic("s.a != 0")
}
if s.b != 3 {
panic("s.b != 3")
}
s = S{}
if s.a != 0 {
panic("s.a != 0")
}
if s.b != 0 {
panic("s.b != 0")
}
// array
type A [4]int
a := A{2, 4, 6, 8}
a = A{1: 6, 2: 4}
if a[0] != 0 {
panic("a[0] != 0")
}
if a[1] != 6 {
panic("a[1] != 6")
}
if a[2] != 4 {
panic("a[2] != 4")
}
if a[3] != 0 {
panic("a[3] != 0")
}
a = A{}
if a[0] != 0 {
panic("a[0] != 0")
}
if a[1] != 0 {
panic("a[1] != 0")
}
if a[2] != 0 {
panic("a[2] != 0")
}
if a[3] != 0 {
panic("a[3] != 0")
}
}
func main() {
}

View File

@ -1,11 +1,8 @@
// This interpreter test is designed to run very quickly yet provide
// some coverage of a broad selection of constructs.
// TODO(adonovan): more.
//
// Validate this file with 'go run' after editing.
// TODO(adonovan): break this into small files organized by theme.
// TODO(adonovan): move static tests (sanity checks) of ssa
// construction into ssa/testdata.
package main
@ -14,17 +11,6 @@ import (
"reflect"
)
const zero int = 1
var v = []int{1 + zero: 42}
// Nonliteral keys in composite literal.
func init() {
if x := fmt.Sprint(v); x != "[0 0 42]" {
panic(x)
}
}
func init() {
// Call of variadic function with (implicit) empty slice.
if x := fmt.Sprint(); x != "" {
@ -126,40 +112,6 @@ func init() {
}
}
// Range over string.
func init() {
if x := len("Hello, 世界"); x != 13 { // bytes
panic(x)
}
var indices []int
var runes []rune
for i, r := range "Hello, 世界" {
runes = append(runes, r)
indices = append(indices, i)
}
if x := fmt.Sprint(runes); x != "[72 101 108 108 111 44 32 19990 30028]" {
panic(x)
}
if x := fmt.Sprint(indices); x != "[0 1 2 3 4 5 6 7 10]" {
panic(x)
}
s := ""
for _, r := range runes {
s = fmt.Sprintf("%s%c", s, r)
}
if s != "Hello, 世界" {
panic(s)
}
var x int
for range "Hello, 世界" {
x++
}
if x != len(indices) {
panic(x)
}
}
func main() {
print() // legal
@ -289,25 +241,6 @@ func main() {
_ = map[int]*struct{}{0: {}}
}
// A blocking select (sans "default:") cannot fall through.
// Regression test for issue 7022.
func bug7022() int {
var c1, c2 chan int
select {
case <-c1:
return 123
case <-c2:
return 456
}
}
// Parens should not prevent intrinsic treatment of built-ins.
// (Regression test for a crash.)
func init() {
_ = (new)(int)
_ = (make)([]int, 0)
}
type mybool bool
func (mybool) f() {}
@ -350,26 +283,6 @@ func init() {
}
}
var order []int
func create(x int) int {
order = append(order, x)
return x
}
var c = create(b + 1)
var a, b = create(1), create(2)
// Initialization order of package-level value specs.
func init() {
if x := fmt.Sprint(order); x != "[1 2 3]" {
panic(x)
}
if c != 3 {
panic(c)
}
}
// Shifts.
func init() {
var i int64 = 1
@ -408,15 +321,16 @@ func init() {
// An I->I type-assert fails iff the value is nil.
func init() {
// TODO(adonovan): temporarily disabled; see comment at bottom of file.
// defer func() {
// r := fmt.Sprint(recover())
// if r != "interface conversion: interface is nil, not main.I" {
// panic("I->I type assertion succeeded for nil value")
// }
// }()
// var x I
// _ = x.(I)
defer func() {
r := fmt.Sprint(recover())
// Exact error varies by toolchain.
if r != "runtime error: interface conversion: interface is nil, not main.I" &&
r != "interface conversion: interface is nil, not main.I" {
panic("I->I type assertion succeeded for nil value")
}
}()
var x I
_ = x.(I)
}
//////////////////////////////////////////////////////////////////////
@ -488,54 +402,6 @@ func init() {
multipleLabels()
}
////////////////////////////////////////////////////////////////////////
// Defer
func deferMutatesResults(noArgReturn bool) (a, b int) {
defer func() {
if a != 1 || b != 2 {
panic(fmt.Sprint(a, b))
}
a, b = 3, 4
}()
if noArgReturn {
a, b = 1, 2
return
}
return 1, 2
}
func init() {
a, b := deferMutatesResults(true)
if a != 3 || b != 4 {
panic(fmt.Sprint(a, b))
}
a, b = deferMutatesResults(false)
if a != 3 || b != 4 {
panic(fmt.Sprint(a, b))
}
}
// We concatenate init blocks to make a single function, but we must
// run defers at the end of each block, not the combined function.
var deferCount = 0
func init() {
deferCount = 1
defer func() {
deferCount++
}()
// defer runs HERE
}
func init() {
// Strictly speaking the spec says deferCount may be 0 or 2
// since the relative order of init blocks is unspecified.
if deferCount != 2 {
panic(deferCount) // defer call has not run!
}
}
func init() {
// Struct equivalence ignores blank fields.
type s struct{ x, _, z int }
@ -566,21 +432,6 @@ func init() {
_ = i == j // interface comparison recurses on types
}
// Composite literals
func init() {
type M map[int]int
m1 := []*M{{1: 1}, &M{2: 2}}
want := "map[1:1] map[2:2]"
if got := fmt.Sprint(*m1[0], *m1[1]); got != want {
panic(got)
}
m2 := []M{{1: 1}, M{2: 2}}
if got := fmt.Sprint(m2[0], m2[1]); got != want {
panic(got)
}
}
func init() {
// Regression test for SSA renaming bug.
var ints []int
@ -594,42 +445,6 @@ func init() {
}
}
func init() {
// Regression test for issue 6806.
ch := make(chan int)
select {
case n, _ := <-ch:
_ = n
default:
// The default case disables the simplification of
// select to a simple receive statement.
}
// TODO(adonovan, gri) enable again once we accept issue 8189.
// value,ok-form receive where TypeOf(ok) is a named boolean.
// type mybool bool
// var x int
// var y mybool
// select {
// case x, y = <-ch:
// default:
// // The default case disables the simplification of
// // select to a simple receive statement.
// }
// TODO(adonovan, gri) remove once we accept issue 8189.
var x int
var y bool
select {
case x, y = <-ch:
default:
// The default case disables the simplification of
// select to a simple receive statement.
}
_ = x
_ = y
}
// Regression test for issue 6949:
// []byte("foo") is not a constant since it allocates memory.
func init() {
@ -655,33 +470,14 @@ func init() {
panic(got)
}
max := 3
if v[2] == 42 {
max = 2
if "a"[0] == 'a' {
max = 2 // max is non-constant, even in SSA form
}
if got := lenCapLoHi(s[1:2:max]); got != [4]int{1, 1, 1, 1} {
panic(got)
}
}
// Regression test for issue 7840 (covered by SSA sanity checker).
func bug7840() bool {
// This creates a single-predecessor block with a φ-node.
return false && a == 0 && a == 0
}
// Regression test for range of pointer to named array type.
func init() {
type intarr [3]int
ia := intarr{1, 2, 3}
var count int
for _, x := range &ia {
count += x
}
if count != 6 {
panic(count)
}
}
// Test that a nice error is issue by indirection wrappers.
func init() {
var ptr *T
@ -698,56 +494,3 @@ func init() {
i.f()
panic("unreachable")
}
// Test for in-place initialization.
func init() {
// struct
type S struct {
a, b int
}
s := S{1, 2}
s = S{b: 3}
if s.a != 0 {
panic("s.a != 0")
}
if s.b != 3 {
panic("s.b != 3")
}
s = S{}
if s.a != 0 {
panic("s.a != 0")
}
if s.b != 0 {
panic("s.b != 0")
}
// array
type A [4]int
a := A{2, 4, 6, 8}
a = A{1: 6, 2: 4}
if a[0] != 0 {
panic("a[0] != 0")
}
if a[1] != 6 {
panic("a[1] != 6")
}
if a[2] != 4 {
panic("a[2] != 4")
}
if a[3] != 0 {
panic("a[3] != 0")
}
a = A{}
if a[0] != 0 {
panic("a[0] != 0")
}
if a[1] != 0 {
panic("a[1] != 0")
}
if a[2] != 0 {
panic("a[2] != 0")
}
if a[3] != 0 {
panic("a[3] != 0")
}
}

53
go/ssa/interp/testdata/defer.go vendored Normal file
View File

@ -0,0 +1,53 @@
package main
// Tests of defer. (Deferred recover() belongs is recover.go.)
import "fmt"
func deferMutatesResults(noArgReturn bool) (a, b int) {
defer func() {
if a != 1 || b != 2 {
panic(fmt.Sprint(a, b))
}
a, b = 3, 4
}()
if noArgReturn {
a, b = 1, 2
return
}
return 1, 2
}
func init() {
a, b := deferMutatesResults(true)
if a != 3 || b != 4 {
panic(fmt.Sprint(a, b))
}
a, b = deferMutatesResults(false)
if a != 3 || b != 4 {
panic(fmt.Sprint(a, b))
}
}
// We concatenate init blocks to make a single function, but we must
// run defers at the end of each block, not the combined function.
var deferCount = 0
func init() {
deferCount = 1
defer func() {
deferCount++
}()
// defer runs HERE
}
func init() {
// Strictly speaking the spec says deferCount may be 0 or 2
// since the relative order of init blocks is unspecified.
if deferCount != 2 {
panic(deferCount) // defer call has not run!
}
}
func main() {
}

View File

@ -1,5 +1,7 @@
package main
import "fmt"
// Test of initialization order of package-level vars.
var counter int
@ -38,3 +40,28 @@ var order = makeOrder()
var a, b = next(), next()
var c, d = next2()
var e, f = next(), next()
// ------------------------------------------------------------------------
var order2 []string
func create(x int, name string) int {
order2 = append(order2, name)
return x
}
var C = create(B+1, "C")
var A, B = create(1, "A"), create(2, "B")
// Initialization order of package-level value specs.
func init() {
x := fmt.Sprint(order2)
// Result varies by toolchain. This is a spec bug.
if x != "[B C A]" && // gc
x != "[A B C]" { // go/types
panic(x)
}
if C != 3 {
panic(c)
}
}

55
go/ssa/interp/testdata/range.go vendored Normal file
View File

@ -0,0 +1,55 @@
package main
// Tests of range loops.
import "fmt"
// Range over string.
func init() {
if x := len("Hello, 世界"); x != 13 { // bytes
panic(x)
}
var indices []int
var runes []rune
for i, r := range "Hello, 世界" {
runes = append(runes, r)
indices = append(indices, i)
}
if x := fmt.Sprint(runes); x != "[72 101 108 108 111 44 32 19990 30028]" {
panic(x)
}
if x := fmt.Sprint(indices); x != "[0 1 2 3 4 5 6 7 10]" {
panic(x)
}
s := ""
for _, r := range runes {
s = fmt.Sprintf("%s%c", s, r)
}
if s != "Hello, 世界" {
panic(s)
}
var x int
for range "Hello, 世界" {
x++
}
if x != len(indices) {
panic(x)
}
}
// Regression test for range of pointer to named array type.
func init() {
type intarr [3]int
ia := intarr{1, 2, 3}
var count int
for _, x := range &ia {
count += x
}
if count != 6 {
panic(count)
}
}
func main() {
}

58
go/ssa/interp/testdata/static.go vendored Normal file
View File

@ -0,0 +1,58 @@
package main
// Static tests of SSA builder (via the sanity checker).
// Dynamic semantics are not exercised.
func init() {
// Regression test for issue 6806.
ch := make(chan int)
select {
case n, _ := <-ch:
_ = n
default:
// The default case disables the simplification of
// select to a simple receive statement.
}
// value,ok-form receive where TypeOf(ok) is a named boolean.
type mybool bool
var x int
var y mybool
select {
case x, y = <-ch:
default:
// The default case disables the simplification of
// select to a simple receive statement.
}
_ = x
_ = y
}
var a int
// Regression test for issue 7840 (covered by SSA sanity checker).
func bug7840() bool {
// This creates a single-predecessor block with a φ-node.
return false && a == 0 && a == 0
}
// A blocking select (sans "default:") cannot fall through.
// Regression test for issue 7022.
func bug7022() int {
var c1, c2 chan int
select {
case <-c1:
return 123
case <-c2:
return 456
}
}
// Parens should not prevent intrinsic treatment of built-ins.
// (Regression test for a crash.)
func init() {
_ = (new)(int)
_ = (make)([]int, 0)
}
func main() {}