Browse Source

compiler,reflect: NumMethods reports exported methods only

Fixes #3796
pull/3817/head
Damian Gryski 1 year ago
committed by Ron Evans
parent
commit
acba0748f1
  1. 25
      compiler/interface.go
  2. 10
      src/reflect/value_test.go

25
compiler/interface.go

@ -128,6 +128,15 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
hasMethodSet = false
}
var numMethods int
if hasMethodSet {
for i := 0; i < ms.Len(); i++ {
if ms.At(i).Obj().Exported() {
numMethods++
}
}
}
// Short-circuit all the global pointer logic here for pointers to pointers.
if typ, ok := typ.(*types.Pointer); ok {
if _, ok := typ.Elem().(*types.Pointer); ok {
@ -277,11 +286,11 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
}
pkgPathPtr := c.pkgPathPtr(pkgpath)
typeFields = []llvm.Value{
llvm.ConstInt(c.ctx.Int16Type(), uint64(ms.Len()), false), // numMethods
c.getTypeCode(types.NewPointer(typ)), // ptrTo
c.getTypeCode(typ.Underlying()), // underlying
pkgPathPtr, // pkgpath pointer
c.ctx.ConstString(pkgname+"."+name+"\x00", false), // name
llvm.ConstInt(c.ctx.Int16Type(), uint64(numMethods), false), // numMethods
c.getTypeCode(types.NewPointer(typ)), // ptrTo
c.getTypeCode(typ.Underlying()), // underlying
pkgPathPtr, // pkgpath pointer
c.ctx.ConstString(pkgname+"."+name+"\x00", false), // name
}
metabyte |= 1 << 5 // "named" flag
case *types.Chan:
@ -308,7 +317,7 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
}
case *types.Pointer:
typeFields = []llvm.Value{
llvm.ConstInt(c.ctx.Int16Type(), uint64(ms.Len()), false), // numMethods
llvm.ConstInt(c.ctx.Int16Type(), uint64(numMethods), false), // numMethods
c.getTypeCode(typ.Elem()),
}
case *types.Array:
@ -337,8 +346,8 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
llvmStructType := c.getLLVMType(typ)
size := c.targetData.TypeStoreSize(llvmStructType)
typeFields = []llvm.Value{
llvm.ConstInt(c.ctx.Int16Type(), uint64(ms.Len()), false), // numMethods
c.getTypeCode(types.NewPointer(typ)), // ptrTo
llvm.ConstInt(c.ctx.Int16Type(), uint64(numMethods), false), // numMethods
c.getTypeCode(types.NewPointer(typ)), // ptrTo
pkgPathPtr,
llvm.ConstInt(c.ctx.Int32Type(), uint64(size), false), // size
llvm.ConstInt(c.ctx.Int16Type(), uint64(typ.NumFields()), false), // numFields

10
src/reflect/value_test.go

@ -560,7 +560,7 @@ type methodStruct struct {
i int
}
func (m methodStruct) valueMethod1() int {
func (m methodStruct) ValueMethod1() int {
return m.i
}
@ -568,11 +568,11 @@ func (m methodStruct) valueMethod2() int {
return m.i
}
func (m *methodStruct) pointerMethod1() int {
func (m *methodStruct) PointerMethod1() int {
return m.i
}
func (m *methodStruct) pointerMethod2() int {
func (m *methodStruct) PointerMethod2() int {
return m.i
}
@ -582,12 +582,12 @@ func (m *methodStruct) pointerMethod3() int {
func TestTinyNumMethods(t *testing.T) {
refptrt := TypeOf(&methodStruct{})
if got, want := refptrt.NumMethod(), 2+3; got != want {
if got, want := refptrt.NumMethod(), 1+2; got != want {
t.Errorf("Pointer Methods=%v, want %v", got, want)
}
reft := refptrt.Elem()
if got, want := reft.NumMethod(), 2; got != want {
if got, want := reft.NumMethod(), 1; got != want {
t.Errorf("Value Methods=%v, want %v", got, want)
}
}

Loading…
Cancel
Save