Open
Description
Go version
tip, and Go 1.18 - 1.24
Output of go env
in your module/workspace:
darwin/arm64 (or any)
What did you do?
Run https://go.dev/play/p/z4BHWcNalVg
package main
func callRecover() {
if recover() != nil {
println("recovered")
}
}
type T int
func (*T) M() { callRecover() }
type S struct{ *T } // has a wrapper S.M wrapping (*T.M)
var p = S{new(T)}
var fn = S.M // using a function pointer to force using the wrapper
func main() {
defer fn(p)
panic("XXX")
}
What did you see happen?
The panic is recovered. The program prints "recovered" and exits normally.
What did you expect to see?
Similar to #73916, it is expected to not recover.
Also similarly, it panics as expected if inlining is disabled.
$ go run -gcflags=-l x.go
panic: XXX
goroutine 1 [running]:
main.main()
/tmp/x.go:21 +0x68
exit status 2
Go 1.17 got it right. Go 1.18 and later fail. Bisection points to CL https://go.dev/cl/327871 . Also similarly, it is a phase ordering change. Before that CL, the wrapper S.M
is generated late and cannot inline the wrapped function (*T).M
. After the CL, it does, while keeping the WRAPPER attribute. The rest of the reasoning is the same as #73916.
Found while investigating #73747.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Todo