From d0445d6f839f4cb3139c1f2ad82c1b82b87ce7b6 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Wed, 10 Jan 2024 18:24:56 +0100 Subject: [PATCH] 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. --- compiler/compiler.go | 6 +++++- testdata/cgo/main.go | 9 +++++++++ testdata/cgo/out.txt | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/compiler/compiler.go b/compiler/compiler.go index 7a1c1e44..43241246 100644 --- a/compiler/compiler.go +++ b/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) } diff --git a/testdata/cgo/main.go b/testdata/cgo/main.go index 1b810a56..aac5221f 100644 --- a/testdata/cgo/main.go +++ b/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))) +} diff --git a/testdata/cgo/out.txt b/testdata/cgo/out.txt index d5f3b137..781187b5 100644 --- a/testdata/cgo/out.txt +++ b/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