diff options
Diffstat (limited to 'src/runtime/panic.go')
| -rw-r--r-- | src/runtime/panic.go | 26 |
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 |
