aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/panic.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/panic.go')
-rw-r--r--src/runtime/panic.go26
1 files changed, 23 insertions, 3 deletions
diff --git a/src/runtime/panic.go b/src/runtime/panic.go
index 58d13b6adb..8bbb769df7 100644
--- a/src/runtime/panic.go
+++ b/src/runtime/panic.go
@@ -297,11 +297,31 @@ func deferproc(fn func()) {
// been set and must not be clobbered.
}
-var rangeExitError = error(errorString("range function continued iteration after exit"))
+var rangeDoneError = error(errorString("range function continued iteration after loop body exit"))
+var rangePanicError = error(errorString("range function continued iteration after loop body panic"))
+var rangeExhaustedError = error(errorString("range function continued iteration after whole loop exit"))
+var rangeMissingPanicError = error(errorString("range function recovered a loop body panic and did not resume panicking"))
//go:noinline
-func panicrangeexit() {
- panic(rangeExitError)
+func panicrangestate(state int) {
+ const (
+ // These duplicate magic numbers in cmd/compile/internal/rangefunc
+ DONE = 0 // body of loop has exited in a non-panic way
+ PANIC = 2 // body of loop is either currently running, or has panicked
+ EXHAUSTED = 3 // iterator function return, i.e., sequence is "exhausted"
+ MISSING_PANIC = 4 // body of loop panicked but iterator function defer-recovered it away
+ )
+ switch state {
+ case DONE:
+ panic(rangeDoneError)
+ case PANIC:
+ panic(rangePanicError)
+ case EXHAUSTED:
+ panic(rangeExhaustedError)
+ case MISSING_PANIC:
+ panic(rangeMissingPanicError)
+ }
+ throw("unexpected state passed to panicrangestate")
}
// deferrangefunc is called by functions that are about to