diff --git a/src/cmd/compile/internal/ssagen/abi.go b/src/cmd/compile/internal/ssagen/abi.go index ecd6a32eb3..9229d0212c 100644 --- a/src/cmd/compile/internal/ssagen/abi.go +++ b/src/cmd/compile/internal/ssagen/abi.go @@ -393,10 +393,20 @@ func setupTextLSym(f *ir.Func, flag int) { } // Clumsy but important. + // For functions that could be on the path of invoking a deferred + // function that can recover (runtime.reflectcall, reflect.callReflect, + // and reflect.callMethod), we want the panic+recover special handling. // See test/recover.go for test cases and src/reflect/value.go // for the actual functions being considered. - if base.Ctxt.Pkgpath == "reflect" { - switch f.Sym().Name { + // + // runtime.reflectcall is an assembly function which tailcalls + // WRAPPER functions (runtime.callNN). Its ABI wrapper needs WRAPPER + // flag as well. + fnname := f.Sym().Name + if base.Ctxt.Pkgpath == "runtime" && fnname == "reflectcall" { + flag |= obj.WRAPPER + } else if base.Ctxt.Pkgpath == "reflect" { + switch fnname { case "callReflect", "callMethod": flag |= obj.WRAPPER }