fix(ssa): fix incorrectly generated ABI for uninstantiated generic methods

This commit is contained in:
Li Jie
2025-01-17 18:14:28 +08:00
parent e016e92c41
commit 918b36e28f
3 changed files with 29 additions and 3 deletions

View File

@@ -260,6 +260,8 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Fun
fn.Inline(llssa.NoInline) fn.Inline(llssa.NoInline)
} }
} }
// set compiled to check generic function global instantiation
pkg.Prog.SetFuncCompiled(name)
isCgo := isCgoExternSymbol(f) isCgo := isCgoExternSymbol(f)
if nblk := len(f.Blocks); nblk > 0 { if nblk := len(f.Blocks); nblk > 0 {
p.cgoCalled = false p.cgoCalled = false

View File

@@ -155,6 +155,11 @@ func (b Builder) abiMethodOf(mPkg *types.Package, mName string, mSig *types.Sign
func (b Builder) abiMthd(mPkg *types.Package, mName string, mSig *types.Signature, name, abiTyp, ifn llvm.Value) (ret Expr, tfn llvm.Value) { func (b Builder) abiMthd(mPkg *types.Package, mName string, mSig *types.Signature, name, abiTyp, ifn llvm.Value) (ret Expr, tfn llvm.Value) {
fullName := FuncName(mPkg, mName, mSig.Recv(), false) fullName := FuncName(mPkg, mName, mSig.Recv(), false)
if mSig.TypeParams().Len() > 0 || mSig.RecvTypeParams().Len() > 0 {
if !b.Pkg.Prog.FuncCompiled(fullName) {
return
}
}
if b.Pkg.fnlink != nil { if b.Pkg.fnlink != nil {
fullName = b.Pkg.fnlink(fullName) fullName = b.Pkg.fnlink(fullName)
} }
@@ -286,14 +291,20 @@ func (b Builder) abiInitNamed(ret Expr, t *types.Named) func() Expr {
if !mthd.IsNil() { if !mthd.IsNil() {
mthds = append(mthds, mthd) mthds = append(mthds, mthd)
} }
ptrMthds = append(ptrMthds, ptrMthd) if !ptrMthd.IsNil() {
ptrMthds = append(ptrMthds, ptrMthd)
}
} }
if len(mthds) > 0 { if len(mthds) > 0 {
methods = b.SliceLit(tSlice, mthds...) methods = b.SliceLit(tSlice, mthds...)
} else { } else {
methods = prog.Zero(tSlice) methods = prog.Zero(tSlice)
} }
ptrMethods = b.SliceLit(tSlice, ptrMthds...) if len(ptrMthds) > 0 {
ptrMethods = b.SliceLit(tSlice, ptrMthds...)
} else {
ptrMethods = prog.Zero(tSlice)
}
} }
return b.Call(initNamed, ret, under, methods, ptrMethods) return b.Call(initNamed, ret, under, methods, ptrMethods)
} }

View File

@@ -109,6 +109,8 @@ type aProgram struct {
patchType func(types.Type) types.Type patchType func(types.Type) types.Type
fnsCompiled map[string]bool
rt *types.Package rt *types.Package
rtget func() *types.Package rtget func() *types.Package
@@ -218,6 +220,7 @@ func NewProgram(target *Target) Program {
} }
ctx := llvm.NewContext() ctx := llvm.NewContext()
td := target.targetData() // TODO(xsw): target config td := target.targetData() // TODO(xsw): target config
fnsCompiled := make(map[string]bool)
/* /*
arch := target.GOARCH arch := target.GOARCH
if arch == "" { if arch == "" {
@@ -230,7 +233,7 @@ func NewProgram(target *Target) Program {
*/ */
is32Bits := (td.PointerSize() == 4 || target.GOARCH == "x86") // TODO(xsw): remove temp code is32Bits := (td.PointerSize() == 4 || target.GOARCH == "x86") // TODO(xsw): remove temp code
return &aProgram{ return &aProgram{
ctx: ctx, gocvt: newGoTypes(), ctx: ctx, gocvt: newGoTypes(), fnsCompiled: fnsCompiled,
target: target, td: td, is32Bits: is32Bits, target: target, td: td, is32Bits: is32Bits,
ptrSize: td.PointerSize(), named: make(map[string]llvm.Type), fnnamed: make(map[string]int), ptrSize: td.PointerSize(), named: make(map[string]llvm.Type), fnnamed: make(map[string]int),
linkname: make(map[string]string), linkname: make(map[string]string),
@@ -280,6 +283,16 @@ func (p Program) runtime() *types.Package {
return p.rt return p.rt
} }
// check generic function instantiation
func (p Program) FuncCompiled(name string) bool {
_, ok := p.fnsCompiled[name]
return ok
}
func (p Program) SetFuncCompiled(name string) {
p.fnsCompiled[name] = true
}
func (p Program) rtNamed(name string) *types.Named { func (p Program) rtNamed(name string) *types.Named {
if rt := p.runtime(); rt != nil { if rt := p.runtime(); rt != nil {
if rtScope := rt.Scope(); rtScope != nil { if rtScope := rt.Scope(); rtScope != nil {