aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/rangefunc/rangefunc_test.go
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2024-11-04 16:40:09 -0500
committerDavid Chase <drchase@google.com>2024-11-13 18:30:21 +0000
commitd311cc95dcc58becdeb0f66a5b828477ee0d83bd (patch)
tree0bd411c91aa03697e8d8e806c191d64908a9beb5 /src/cmd/compile/internal/rangefunc/rangefunc_test.go
parent7c405444417f4f5412f96f0406cabd081e95b603 (diff)
downloadgo-d311cc95dcc58becdeb0f66a5b828477ee0d83bd.tar.xz
cmd/compile: change status of "bad iterator" panic
Execution of the loop body previously either terminated the iteration (returned false because of a break, goto, or return) or actually panicked. The check against abi.RF_READY ensures that the body can no longer run and also panics. This CL in addition transitions the loop state to abi.RF_PANIC so that if this already badly-behaved iterator defer-recovers this panic, then the exit check at the loop context will catch the problem and panic there. Previously, panics triggered by attempted execution of a no-longer active loop would not trigger a panic at the loop context if they were defer-recovered. Change-Id: Ieeed2fafd0d65edb66098dc27dc9ae8c1e6bcc8c Reviewed-on: https://go-review.googlesource.com/c/go/+/625455 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Tim King <taking@google.com>
Diffstat (limited to 'src/cmd/compile/internal/rangefunc/rangefunc_test.go')
-rw-r--r--src/cmd/compile/internal/rangefunc/rangefunc_test.go153
1 files changed, 107 insertions, 46 deletions
diff --git a/src/cmd/compile/internal/rangefunc/rangefunc_test.go b/src/cmd/compile/internal/rangefunc/rangefunc_test.go
index acf0ef6e09..4b4974b9dd 100644
--- a/src/cmd/compile/internal/rangefunc/rangefunc_test.go
+++ b/src/cmd/compile/internal/rangefunc/rangefunc_test.go
@@ -185,10 +185,11 @@ func Check2[U, V any](forall Seq2[U, V]) Seq2[U, V] {
return func(body func(U, V) bool) {
state := READY
forall(func(u U, v V) bool {
- if state != READY {
- panic(fail[state])
- }
+ tmp := state
state = PANIC
+ if tmp != READY {
+ panic(fail[tmp])
+ }
ret := body(u, v)
if ret {
state = READY
@@ -208,10 +209,11 @@ func Check[U any](forall Seq[U]) Seq[U] {
return func(body func(U) bool) {
state := READY
forall(func(u U) bool {
- if state != READY {
- panic(fail[state])
- }
+ tmp := state
state = PANIC
+ if tmp != READY {
+ panic(fail[tmp])
+ }
ret := body(u)
if ret {
state = READY
@@ -1122,12 +1124,12 @@ func TestPanickyIterator1(t *testing.T) {
} else {
t.Errorf("Saw wrong panic '%v'", r)
}
+ if !slices.Equal(expect, result) {
+ t.Errorf("Expected %v, got %v", expect, result)
+ }
} else {
t.Errorf("Wanted to see a failure, result was %v", result)
}
- if !slices.Equal(expect, result) {
- t.Errorf("Expected %v, got %v", expect, result)
- }
}()
for _, z := range PanickyOfSliceIndex([]int{1, 2, 3, 4}) {
result = append(result, z)
@@ -1172,12 +1174,12 @@ func TestPanickyIterator2(t *testing.T) {
} else {
t.Errorf("Saw wrong panic '%v'", r)
}
+ if !slices.Equal(expect, result) {
+ t.Errorf("Expected %v, got %v", expect, result)
+ }
} else {
t.Errorf("Wanted to see a failure, result was %v", result)
}
- if !slices.Equal(expect, result) {
- t.Errorf("Expected %v, got %v", expect, result)
- }
}()
for _, x := range OfSliceIndex([]int{100, 200}) {
result = append(result, x)
@@ -1207,11 +1209,11 @@ func TestPanickyIterator2Check(t *testing.T) {
} else {
t.Errorf("Saw wrong panic '%v'", r)
}
+ if !slices.Equal(expect, result) {
+ t.Errorf("Expected %v, got %v", expect, result)
+ }
} else {
- t.Errorf("Wanted to see a failure, result was %v", result)
- }
- if !slices.Equal(expect, result) {
- t.Errorf("Expected %v, got %v", expect, result)
+ t.Errorf("Wanted to see a panic, result was %v", result)
}
}()
for _, x := range Check2(OfSliceIndex([]int{100, 200})) {
@@ -1234,13 +1236,19 @@ func TestPanickyIterator2Check(t *testing.T) {
func TestPanickyIterator3(t *testing.T) {
var result []int
- var expect = []int{100, 10, 1, 2, 200, 10, 1, 2}
+ var expect = []int{100, 10, 1, 2}
defer func() {
if r := recover(); r != nil {
- t.Errorf("Unexpected panic '%v'", r)
- }
- if !slices.Equal(expect, result) {
- t.Errorf("Expected %v, got %v", expect, result)
+ if matchError(r, RERR_MISSING) {
+ t.Logf("Saw expected panic '%v'", r)
+ } else {
+ t.Errorf("Saw wrong panic '%v'", r)
+ }
+ if !slices.Equal(expect, result) {
+ t.Errorf("Expected %v, got %v", expect, result)
+ }
+ } else {
+ t.Errorf("Wanted to see a panic, result was %v", result)
}
}()
for _, x := range OfSliceIndex([]int{100, 200}) {
@@ -1262,13 +1270,19 @@ func TestPanickyIterator3(t *testing.T) {
}
func TestPanickyIterator3Check(t *testing.T) {
var result []int
- var expect = []int{100, 10, 1, 2, 200, 10, 1, 2}
+ var expect = []int{100, 10, 1, 2}
defer func() {
if r := recover(); r != nil {
- t.Errorf("Unexpected panic '%v'", r)
- }
- if !slices.Equal(expect, result) {
- t.Errorf("Expected %v, got %v", expect, result)
+ if matchError(r, CERR_MISSING) {
+ t.Logf("Saw expected panic '%v'", r)
+ } else {
+ t.Errorf("Saw wrong panic '%v'", r)
+ }
+ if !slices.Equal(expect, result) {
+ t.Errorf("Expected %v, got %v", expect, result)
+ }
+ } else {
+ t.Errorf("Wanted to see a panic, result was %v", result)
}
}()
for _, x := range Check2(OfSliceIndex([]int{100, 200})) {
@@ -1298,9 +1312,11 @@ func TestPanickyIterator4(t *testing.T) {
} else {
t.Errorf("Saw wrong panic '%v'", r)
}
- }
- if !slices.Equal(expect, result) {
- t.Errorf("Expected %v, got %v", expect, result)
+ if !slices.Equal(expect, result) {
+ t.Errorf("Expected %v, got %v", expect, result)
+ }
+ } else {
+ t.Errorf("Wanted to see a panic, result was %v", result)
}
}()
for _, x := range SwallowPanicOfSliceIndex([]int{1, 2, 3, 4}) {
@@ -1321,9 +1337,11 @@ func TestPanickyIterator4Check(t *testing.T) {
} else {
t.Errorf("Saw wrong panic '%v'", r)
}
- }
- if !slices.Equal(expect, result) {
- t.Errorf("Expected %v, got %v", expect, result)
+ if !slices.Equal(expect, result) {
+ t.Errorf("Expected %v, got %v", expect, result)
+ }
+ } else {
+ t.Errorf("Wanted to see a panic, result was %v", result)
}
}()
for _, x := range Check2(SwallowPanicOfSliceIndex([]int{1, 2, 3, 4})) {
@@ -1409,33 +1427,76 @@ X:
// TestVeryBad1 checks the behavior of an extremely poorly behaved iterator.
func TestVeryBad1(t *testing.T) {
- result := veryBad([]int{10, 20, 30, 40, 50}) // odd length
- expect := []int{1, 10}
+ expect := []int{} // assignment does not happen
+ var result []int
- if !slices.Equal(expect, result) {
- t.Errorf("Expected %v, got %v", expect, result)
+ defer func() {
+ if r := recover(); r != nil {
+ expectPanic(t, r, RERR_MISSING)
+ if !slices.Equal(expect, result) {
+ t.Errorf("(Inner) Expected %v, got %v", expect, result)
+ }
+ } else {
+ t.Error("Wanted to see a failure")
+ }
+ }()
+
+ result = veryBad([]int{10, 20, 30, 40, 50}) // odd length
+
+}
+
+func expectPanic(t *testing.T, r any, s string) {
+ if matchError(r, s) {
+ t.Logf("Saw expected panic '%v'", r)
+ } else {
+ t.Errorf("Saw wrong panic '%v'", r)
+ }
+}
+
+func expectError(t *testing.T, err any, s string) {
+ if matchError(err, s) {
+ t.Logf("Saw expected error '%v'", err)
+ } else {
+ t.Errorf("Saw wrong error '%v'", err)
}
}
// TestVeryBad2 checks the behavior of an extremely poorly behaved iterator.
func TestVeryBad2(t *testing.T) {
- result := veryBad([]int{10, 20, 30, 40}) // even length
- expect := []int{1, 10}
+ result := []int{}
+ expect := []int{}
+
+ defer func() {
+ if r := recover(); r != nil {
+ expectPanic(t, r, RERR_MISSING)
+ if !slices.Equal(expect, result) {
+ t.Errorf("(Inner) Expected %v, got %v", expect, result)
+ }
+ } else {
+ t.Error("Wanted to see a failure")
+ }
+ }()
+
+ result = veryBad([]int{10, 20, 30, 40}) // even length
- if !slices.Equal(expect, result) {
- t.Errorf("Expected %v, got %v", expect, result)
- }
}
// TestVeryBadCheck checks the behavior of an extremely poorly behaved iterator,
// which also suppresses the exceptions from "Check"
func TestVeryBadCheck(t *testing.T) {
- result := veryBadCheck([]int{10, 20, 30, 40}) // even length
- expect := []int{1, 10}
+ expect := []int{}
+ var result []int
+ defer func() {
+ if r := recover(); r != nil {
+ expectPanic(t, r, CERR_MISSING)
+ }
+ if !slices.Equal(expect, result) {
+ t.Errorf("Expected %v, got %v", expect, result)
+ }
+ }()
+
+ result = veryBadCheck([]int{10, 20, 30, 40}) // even length
- if !slices.Equal(expect, result) {
- t.Errorf("Expected %v, got %v", expect, result)
- }
}
// TestOk is the nice version of the very bad iterator.