fix(ssa): use correct package path for interface metadata in abiInterfaceOf
When converting concrete type pointers to interfaces with private methods across packages, the interface metadata's PkgPath was incorrectly set to the current compilation package instead of the interface definition package. This caused the runtime to only fill exported methods in the itab, leaving private method slots as NULL (0x0), which led to segmentation faults when calling these private methods. The fix extracts the package path from the interface's private methods (if any) instead of using the current package path. This ensures the runtime receives the correct package path for the visibility check. Fixes #1370 Generated with [codeagent](https://github.com/qbox/codeagent) Co-authored-by: luoliwoshang <luoliwoshang@users.noreply.github.com>
This commit is contained in:
@@ -187,19 +187,28 @@ func (b Builder) abiInterfaceOf(t *types.Interface) func() Expr {
|
|||||||
return func() Expr {
|
return func() Expr {
|
||||||
prog := b.Prog
|
prog := b.Prog
|
||||||
methods := make([]Expr, n)
|
methods := make([]Expr, n)
|
||||||
|
pkgPath := ""
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
m := t.Method(i)
|
m := t.Method(i)
|
||||||
mName := m.Name()
|
mName := m.Name()
|
||||||
if !token.IsExported(mName) {
|
if !token.IsExported(mName) {
|
||||||
|
if pkgPath == "" {
|
||||||
|
if mPkg := m.Pkg(); mPkg != nil {
|
||||||
|
pkgPath = mPkg.Path()
|
||||||
|
}
|
||||||
|
}
|
||||||
mName = abi.FullName(m.Pkg(), mName)
|
mName = abi.FullName(m.Pkg(), mName)
|
||||||
}
|
}
|
||||||
methods[i] = b.abiImethodOf(mName, typs[i])
|
methods[i] = b.abiImethodOf(mName, typs[i])
|
||||||
}
|
}
|
||||||
pkg := b.Pkg
|
pkg := b.Pkg
|
||||||
|
if pkgPath == "" {
|
||||||
|
pkgPath = pkg.Path()
|
||||||
|
}
|
||||||
fn := pkg.rtFunc("Interface")
|
fn := pkg.rtFunc("Interface")
|
||||||
tSlice := lastParamType(prog, fn)
|
tSlice := lastParamType(prog, fn)
|
||||||
methodSlice := b.SliceLit(tSlice, methods...)
|
methodSlice := b.SliceLit(tSlice, methods...)
|
||||||
return b.Call(fn, b.Str(pkg.Path()), methodSlice)
|
return b.Call(fn, b.Str(pkgPath), methodSlice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user