diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index 06910450ff..8ad7f6ace8 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -3658,7 +3658,8 @@ func usemethod(n *Node) { // Note: Don't rely on res0.Type.String() since its formatting depends on multiple factors // (including global variables such as numImports - was issue #19028). - if s := res0.Type.Sym; s != nil && s.Name == "Method" && s.Pkg != nil && s.Pkg.Path == "reflect" { + // Also need to check for reflect package itself (see Issue #38515). + if s := res0.Type.Sym; s != nil && s.Name == "Method" && s.Pkg != nil && (s.Pkg.Path == "reflect" || s.Pkg == localpkg && myimportpath == "reflect") { Curfn.Func.SetReflectMethod(true) } } diff --git a/test/reflectmethod5.go b/test/reflectmethod5.go new file mode 100644 index 0000000000..a3fdaa2dcd --- /dev/null +++ b/test/reflectmethod5.go @@ -0,0 +1,30 @@ +// run + +// Copyright 2020 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. + +// Issue 38515: failed to mark the method wrapper +// reflect.Type.Method itself as REFLECTMETHOD. + +package main + +import "reflect" + +var called bool + +type foo struct{} + +func (foo) X() { called = true } + +var h = reflect.Type.Method + +func main() { + v := reflect.ValueOf(foo{}) + m := h(v.Type(), 0) + f := m.Func.Interface().(func(foo)) + f(foo{}) + if !called { + panic("FAIL") + } +} diff --git a/test/reflectmethod6.go b/test/reflectmethod6.go new file mode 100644 index 0000000000..004ea303e6 --- /dev/null +++ b/test/reflectmethod6.go @@ -0,0 +1,32 @@ +// run + +// Copyright 2020 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. + +// Similar to reflectmethod5.go, but for reflect.Type.MethodByName. + +package main + +import "reflect" + +var called bool + +type foo struct{} + +func (foo) X() { called = true } + +var h = reflect.Type.MethodByName + +func main() { + v := reflect.ValueOf(foo{}) + m, ok := h(v.Type(), "X") + if !ok { + panic("FAIL") + } + f := m.Func.Interface().(func(foo)) + f(foo{}) + if !called { + panic("FAIL") + } +}