mirror of
https://github.com/golang/go
synced 2024-11-18 18:44:42 -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:
parent
11569f39ea
commit
d3f2df4854
@ -135,14 +135,18 @@ var gorootTestTests = []string{
|
|||||||
// These are files in go.tools/go/ssa/interp/testdata/.
|
// These are files in go.tools/go/ssa/interp/testdata/.
|
||||||
var testdataTests = []string{
|
var testdataTests = []string{
|
||||||
"boundmeth.go",
|
"boundmeth.go",
|
||||||
|
"complit.go",
|
||||||
"coverage.go",
|
"coverage.go",
|
||||||
|
"defer.go",
|
||||||
"fieldprom.go",
|
"fieldprom.go",
|
||||||
"ifaceconv.go",
|
"ifaceconv.go",
|
||||||
"ifaceprom.go",
|
"ifaceprom.go",
|
||||||
"initorder.go",
|
"initorder.go",
|
||||||
"methprom.go",
|
"methprom.go",
|
||||||
"mrvchain.go",
|
"mrvchain.go",
|
||||||
|
"range.go",
|
||||||
"recover.go",
|
"recover.go",
|
||||||
|
"static.go",
|
||||||
"callstack.go",
|
"callstack.go",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
84
go/ssa/interp/testdata/complit.go
vendored
Normal file
84
go/ssa/interp/testdata/complit.go
vendored
Normal 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() {
|
||||||
|
}
|
281
go/ssa/interp/testdata/coverage.go
vendored
281
go/ssa/interp/testdata/coverage.go
vendored
@ -1,11 +1,8 @@
|
|||||||
// This interpreter test is designed to run very quickly yet provide
|
// This interpreter test is designed to run very quickly yet provide
|
||||||
// some coverage of a broad selection of constructs.
|
// some coverage of a broad selection of constructs.
|
||||||
// TODO(adonovan): more.
|
|
||||||
//
|
//
|
||||||
// Validate this file with 'go run' after editing.
|
// Validate this file with 'go run' after editing.
|
||||||
// TODO(adonovan): break this into small files organized by theme.
|
// 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
|
package main
|
||||||
|
|
||||||
@ -14,17 +11,6 @@ import (
|
|||||||
"reflect"
|
"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() {
|
func init() {
|
||||||
// Call of variadic function with (implicit) empty slice.
|
// Call of variadic function with (implicit) empty slice.
|
||||||
if x := fmt.Sprint(); x != "" {
|
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() {
|
func main() {
|
||||||
print() // legal
|
print() // legal
|
||||||
|
|
||||||
@ -289,25 +241,6 @@ func main() {
|
|||||||
_ = map[int]*struct{}{0: {}}
|
_ = 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
|
type mybool bool
|
||||||
|
|
||||||
func (mybool) f() {}
|
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.
|
// Shifts.
|
||||||
func init() {
|
func init() {
|
||||||
var i int64 = 1
|
var i int64 = 1
|
||||||
@ -408,15 +321,16 @@ func init() {
|
|||||||
|
|
||||||
// An I->I type-assert fails iff the value is nil.
|
// An I->I type-assert fails iff the value is nil.
|
||||||
func init() {
|
func init() {
|
||||||
// TODO(adonovan): temporarily disabled; see comment at bottom of file.
|
defer func() {
|
||||||
// defer func() {
|
r := fmt.Sprint(recover())
|
||||||
// r := fmt.Sprint(recover())
|
// Exact error varies by toolchain.
|
||||||
// if r != "interface conversion: interface is nil, not main.I" {
|
if r != "runtime error: interface conversion: interface is nil, not main.I" &&
|
||||||
// panic("I->I type assertion succeeded for nil value")
|
r != "interface conversion: interface is nil, not main.I" {
|
||||||
// }
|
panic("I->I type assertion succeeded for nil value")
|
||||||
// }()
|
}
|
||||||
// var x I
|
}()
|
||||||
// _ = x.(I)
|
var x I
|
||||||
|
_ = x.(I)
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -488,54 +402,6 @@ func init() {
|
|||||||
multipleLabels()
|
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() {
|
func init() {
|
||||||
// Struct equivalence ignores blank fields.
|
// Struct equivalence ignores blank fields.
|
||||||
type s struct{ x, _, z int }
|
type s struct{ x, _, z int }
|
||||||
@ -566,21 +432,6 @@ func init() {
|
|||||||
_ = i == j // interface comparison recurses on types
|
_ = 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() {
|
func init() {
|
||||||
// Regression test for SSA renaming bug.
|
// Regression test for SSA renaming bug.
|
||||||
var ints []int
|
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:
|
// Regression test for issue 6949:
|
||||||
// []byte("foo") is not a constant since it allocates memory.
|
// []byte("foo") is not a constant since it allocates memory.
|
||||||
func init() {
|
func init() {
|
||||||
@ -655,33 +470,14 @@ func init() {
|
|||||||
panic(got)
|
panic(got)
|
||||||
}
|
}
|
||||||
max := 3
|
max := 3
|
||||||
if v[2] == 42 {
|
if "a"[0] == 'a' {
|
||||||
max = 2
|
max = 2 // max is non-constant, even in SSA form
|
||||||
}
|
}
|
||||||
if got := lenCapLoHi(s[1:2:max]); got != [4]int{1, 1, 1, 1} {
|
if got := lenCapLoHi(s[1:2:max]); got != [4]int{1, 1, 1, 1} {
|
||||||
panic(got)
|
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.
|
// Test that a nice error is issue by indirection wrappers.
|
||||||
func init() {
|
func init() {
|
||||||
var ptr *T
|
var ptr *T
|
||||||
@ -698,56 +494,3 @@ func init() {
|
|||||||
i.f()
|
i.f()
|
||||||
panic("unreachable")
|
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
53
go/ssa/interp/testdata/defer.go
vendored
Normal 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() {
|
||||||
|
}
|
27
go/ssa/interp/testdata/initorder.go
vendored
27
go/ssa/interp/testdata/initorder.go
vendored
@ -1,5 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
// Test of initialization order of package-level vars.
|
// Test of initialization order of package-level vars.
|
||||||
|
|
||||||
var counter int
|
var counter int
|
||||||
@ -38,3 +40,28 @@ var order = makeOrder()
|
|||||||
var a, b = next(), next()
|
var a, b = next(), next()
|
||||||
var c, d = next2()
|
var c, d = next2()
|
||||||
var e, f = next(), next()
|
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
55
go/ssa/interp/testdata/range.go
vendored
Normal 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
58
go/ssa/interp/testdata/static.go
vendored
Normal 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() {}
|
Loading…
Reference in New Issue
Block a user