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:
xgopilot
2025-10-23 10:30:00 +00:00
parent d2a22252c2
commit dba9bcc4e4

View File

@@ -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)
} }
} }