diff options
Diffstat (limited to 'go/ssa/interp/testdata/fixedbugs')
-rw-r--r-- | go/ssa/interp/testdata/fixedbugs/issue52342.go | 17 | ||||
-rw-r--r-- | go/ssa/interp/testdata/fixedbugs/issue52835.go | 27 | ||||
-rw-r--r-- | go/ssa/interp/testdata/fixedbugs/issue55086.go | 132 |
3 files changed, 176 insertions, 0 deletions
diff --git a/go/ssa/interp/testdata/fixedbugs/issue52342.go b/go/ssa/interp/testdata/fixedbugs/issue52342.go new file mode 100644 index 000000000..2e1cc63cf --- /dev/null +++ b/go/ssa/interp/testdata/fixedbugs/issue52342.go @@ -0,0 +1,17 @@ +package main + +func main() { + var d byte + + d = 1 + d <<= 256 + if d != 0 { + panic(d) + } + + d = 1 + d >>= 256 + if d != 0 { + panic(d) + } +} diff --git a/go/ssa/interp/testdata/fixedbugs/issue52835.go b/go/ssa/interp/testdata/fixedbugs/issue52835.go new file mode 100644 index 000000000..f1d99abb7 --- /dev/null +++ b/go/ssa/interp/testdata/fixedbugs/issue52835.go @@ -0,0 +1,27 @@ +package main + +var called bool + +type I interface { + Foo() +} + +type A struct{} + +func (a A) Foo() { + called = true +} + +func lambda[X I]() func() func() { + return func() func() { + var x X + return x.Foo + } +} + +func main() { + lambda[A]()()() + if !called { + panic(called) + } +} diff --git a/go/ssa/interp/testdata/fixedbugs/issue55086.go b/go/ssa/interp/testdata/fixedbugs/issue55086.go new file mode 100644 index 000000000..84c81e91a --- /dev/null +++ b/go/ssa/interp/testdata/fixedbugs/issue55086.go @@ -0,0 +1,132 @@ +// Copyright 2022 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 a() (r string) { + s := "initial" + var p *struct{ i int } + defer func() { + recover() + r = s + }() + + s, p.i = "set", 2 // s must be set before p.i panics + return "unreachable" +} + +func b() (r string) { + s := "initial" + fn := func() []int { panic("") } + defer func() { + recover() + r = s + }() + + s, fn()[0] = "set", 2 // fn() panics before any assignment occurs + return "unreachable" +} + +func c() (r string) { + s := "initial" + var p map[int]int + defer func() { + recover() + r = s + }() + + s, p[0] = "set", 2 //s must be set before p[0] index panics" + return "unreachable" +} + +func d() (r string) { + s := "initial" + var p map[int]int + defer func() { + recover() + r = s + }() + fn := func() int { panic("") } + + s, p[0] = "set", fn() // fn() panics before s is set + return "unreachable" +} + +func e() (r string) { + s := "initial" + p := map[int]int{} + defer func() { + recover() + r = s + }() + fn := func() int { panic("") } + + s, p[fn()] = "set", 0 // fn() panics before any assignment occurs + return "unreachable" +} + +func f() (r string) { + s := "initial" + p := []int{} + defer func() { + recover() + r = s + }() + + s, p[1] = "set", 0 // p[1] panics after s is set + return "unreachable" +} + +func g() (r string) { + s := "initial" + p := map[any]any{} + defer func() { + recover() + r = s + }() + var i any = func() {} + s, p[i] = "set", 0 // p[i] panics after s is set + return "unreachable" +} + +func h() (r string) { + fail := false + defer func() { + recover() + if fail { + r = "fail" + } else { + r = "success" + } + }() + + type T struct{ f int } + var p *struct{ *T } + + // The implicit "p.T" operand should be evaluated in phase 1 (and panic), + // before the "fail = true" assignment in phase 2. + fail, p.f = true, 0 + return "unreachable" +} + +func main() { + for _, test := range []struct { + fn func() string + want string + desc string + }{ + {a, "set", "s must be set before p.i panics"}, + {b, "initial", "p() panics before s is set"}, + {c, "set", "s must be set before p[0] index panics"}, + {d, "initial", "fn() panics before s is set"}, + {e, "initial", "fn() panics before s is set"}, + {f, "set", "p[1] panics after s is set"}, + {g, "set", "p[i] panics after s is set"}, + {h, "success", "p.T panics before fail is set"}, + } { + if test.fn() != test.want { + panic(test.desc) + } + } +} |