diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go index 5a5c91b751..962c326c03 100644 --- a/src/reflect/all_test.go +++ b/src/reflect/all_test.go @@ -5521,6 +5521,25 @@ func TestKeepFuncLive(t *testing.T) { MakeFunc(typ, f).Call([]Value{ValueOf(10)}) } +type UnExportedFirst int + +func (i UnExportedFirst) ΦExported() {} +func (i UnExportedFirst) unexported() {} + +// Issue 21177 +func TestMethodByNameUnExportedFirst(t *testing.T) { + defer func() { + if recover() != nil { + t.Errorf("should not panic") + } + }() + typ := TypeOf(UnExportedFirst(0)) + m, _ := typ.MethodByName("ΦExported") + if m.Name != "ΦExported" { + t.Errorf("got %s, expected ΦExported", m.Name) + } +} + // Issue 18635 (method version). type KeepMethodLive struct{} diff --git a/src/reflect/type.go b/src/reflect/type.go index dbb65f14bf..9f02219c8e 100644 --- a/src/reflect/type.go +++ b/src/reflect/type.go @@ -871,11 +871,15 @@ func (t *rtype) MethodByName(name string) (m Method, ok bool) { return Method{}, false } utmethods := ut.methods() + var eidx int for i := 0; i < int(ut.mcount); i++ { p := utmethods[i] pname := t.nameOff(p.name) - if pname.isExported() && pname.name() == name { - return t.Method(i), true + if pname.isExported() { + if pname.name() == name { + return t.Method(eidx), true + } + eidx++ } } return Method{}, false