Browse Source

cgo: fix calling CGo callback inside generic function

The package of the generic function might not be set, so we have to call
Origin() for it.

Found while porting mcufont to TinyGo.
build-llvm-image
Ayke van Laethem 10 months ago
committed by Ron Evans
parent
commit
d0445d6f83
  1. 6
      compiler/compiler.go
  2. 9
      testdata/cgo/main.go
  3. 1
      testdata/cgo/out.txt

6
compiler/compiler.go

@ -3261,7 +3261,11 @@ func (b *builder) createUnOp(unop *ssa.UnOp) (llvm.Value, error) {
// Instead of a load from the global, create a bitcast of the
// function pointer itself.
name := strings.TrimSuffix(unop.X.(*ssa.Global).Name(), "$funcaddr")
_, fn := b.getFunction(b.fn.Pkg.Members[name].(*ssa.Function))
pkg := b.fn.Pkg
if pkg == nil {
pkg = b.fn.Origin().Pkg
}
_, fn := b.getFunction(pkg.Members[name].(*ssa.Function))
if fn.IsNil() {
return llvm.Value{}, b.makeError(unop.Pos(), "cgo function not found: "+name)
}

9
testdata/cgo/main.go

@ -43,6 +43,7 @@ func main() {
println("callback 1:", C.doCallback(20, 30, cb))
cb = C.binop_t(C.mul)
println("callback 2:", C.doCallback(20, 30, cb))
genericCallbackCall[int]()
// variadic functions
println("variadic0:", C.variadic0())
@ -197,3 +198,11 @@ func printBitfield(bitfield *C.bitfield_t) {
println("bitfield d:", bitfield.d)
println("bitfield e:", bitfield.e)
}
type Int interface {
int | uint
}
func genericCallbackCall[T Int]() {
println("callback inside generic function:", C.doCallback(20, 30, C.binop_t(C.add)))
}

1
testdata/cgo/out.txt

@ -13,6 +13,7 @@ defined expr: 9
25: 25
callback 1: 50
callback 2: 600
callback inside generic function: 50
variadic0: 1
variadic2: 15
headerfunc: 6

Loading…
Cancel
Save