pkg/proc: fix can not call method of an embedded filed directly (#1691)

`func (v *Variable) findMethod` should support for searching methods of an
embedded filed.

Fixes #1688
This commit is contained in:
chainhelen
2019-09-26 09:37:23 -05:00
committed by Derek Parker
parent 4905cff3c8
commit a82e6d6987
3 changed files with 45 additions and 1 deletions

View File

@ -121,6 +121,19 @@ func noreturncall(n int) {
return
}
type Base struct{
y int
}
type Derived struct {
x int
Base
}
func (b *Base) Method() int {
return b.y
}
func main() {
one, two := 1, 2
intslice := []int{1, 2, 3}
@ -142,9 +155,13 @@ func main() {
fn2ptrmeth := pa.PRcvr
var fn2nil func()
d := &Derived{3, Base{4}}
runtime.Breakpoint()
call1(one, two)
fn2clos(2)
strings.LastIndexByte(stringslice[1], 'w')
fmt.Println(one, two, zero, callpanic, callstacktrace, stringsJoin, intslice, stringslice, comma, a.VRcvr, a.PRcvr, pa, vable_a, vable_pa, pable_pa, fn2clos, fn2glob, fn2valmeth, fn2ptrmeth, fn2nil, ga, escapeArg, a2, square, intcallpanic, onetwothree, curriedAdd, getAStruct, getAStructPtr, getVRcvrableFromAStruct, getPRcvrableFromAStructPtr, getVRcvrableFromAStructPtr, pa2, noreturncall, str)
d.Method()
d.Base.Method()
fmt.Println(one, two, zero, callpanic, callstacktrace, stringsJoin, intslice, stringslice, comma, a.VRcvr, a.PRcvr, pa, vable_a, vable_pa, pable_pa, fn2clos, fn2glob, fn2valmeth, fn2ptrmeth, fn2nil, ga, escapeArg, a2, square, intcallpanic, onetwothree, curriedAdd, getAStruct, getAStructPtr, getVRcvrableFromAStruct, getPRcvrableFromAStructPtr, getVRcvrableFromAStructPtr, pa2, noreturncall, str, d)
}

View File

@ -1847,7 +1847,32 @@ func (v *Variable) findMethod(mname string) (*Variable, error) {
}
return r, nil
}
return v.tryFindMethodInEmbeddedFields(mname)
}
func (v *Variable) tryFindMethodInEmbeddedFields(mname string) (*Variable, error) {
structVar := v.maybeDereference()
structVar.Name = v.Name
if structVar.Unreadable != nil {
return structVar, nil
}
switch t := structVar.RealType.(type) {
case *godwarf.StructType:
for _, field := range t.Field {
if field.Embedded {
// Recursively check for promoted fields on the embedded field
embeddedVar, err := structVar.toField(field)
if err != nil {
return nil, err
}
if embeddedMethod, err := embeddedVar.findMethod(mname); err != nil {
return nil, err
} else if embeddedMethod != nil {
return embeddedMethod, nil
}
}
}
}
return nil, nil
}

View File

@ -1181,6 +1181,8 @@ func TestCallFunction(t *testing.T) {
{`strings.Join(stringslice, ",")`, []string{`:string:"one,two,three"`}, nil},
{`strings.LastIndexByte(stringslice[1], 'w')`, []string{":int:1"}, nil},
{`strings.LastIndexByte(stringslice[1], 'o')`, []string{":int:2"}, nil},
{`d.Base.Method()`, []string{ `:int:4` }, nil },
{`d.Method()`, []string{ `:int:4` }, nil },
}
var testcases113 = []testCaseCallFunction{