| // run | |
| // Copyright 2025 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 | |
| //go:noinline | |
| func i() { | |
| for range yieldInts { | |
| defer func() { | |
| println("I") | |
| recover() | |
| }() | |
| } | |
| // This panic causes dead code elimination of the return block. | |
| // The compiler should nonetheless emit a deferreturn. | |
| panic("i panic") | |
| } | |
| //go:noinline | |
| func h() { | |
| defer func() { | |
| println("H first") | |
| }() | |
| for range yieldInts { | |
| defer func() { | |
| println("H second") | |
| }() | |
| } | |
| defer func() { | |
| println("H third") | |
| }() | |
| for range yieldIntsPanic { | |
| defer func() { | |
| println("h recover:called") | |
| recover() | |
| }() | |
| } | |
| } | |
| //go:noinline | |
| func yieldInts(yield func(int) bool) { | |
| if !yield(0) { | |
| return | |
| } | |
| } | |
| //go:noinline | |
| func g() { | |
| defer func() { | |
| println("G first") | |
| }() | |
| for range yieldIntsPanic { | |
| defer func() { | |
| println("g recover:called") | |
| recover() | |
| }() | |
| } | |
| } | |
| //go:noinline | |
| func yieldIntsPanic(yield func(int) bool) { | |
| if !yield(0) { | |
| return | |
| } | |
| panic("yield stop") | |
| } | |
| //go:noinline | |
| func next(i int) int { | |
| if i == 0 { | |
| panic("next stop") | |
| } | |
| return i + 1 | |
| } | |
| //go:noinline | |
| func f() { | |
| defer func() { | |
| println("F first") | |
| }() | |
| for i := 0; i < 1; i = next(i) { | |
| defer func() { | |
| println("f recover:called") | |
| recover() | |
| }() | |
| } | |
| } | |
| func main() { | |
| f() | |
| println("f returned") | |
| g() | |
| println("g returned") | |
| h() | |
| println("h returned") | |
| i() | |
| println("i returned") | |
| } |