diff options
author | Ayke van Laethem <[email protected]> | 2024-01-10 18:24:56 +0100 |
---|---|---|
committer | Ron Evans <[email protected]> | 2024-01-12 14:54:42 +0100 |
commit | d0445d6f839f4cb3139c1f2ad82c1b82b87ce7b6 (patch) | |
tree | 98df8e0cd915489099edc544d83aa626f8448855 | |
parent | a40b11f5356090b4cefde1625b29eb07e04344a2 (diff) | |
download | tinygo-d0445d6f839f4cb3139c1f2ad82c1b82b87ce7b6.tar.gz tinygo-d0445d6f839f4cb3139c1f2ad82c1b82b87ce7b6.zip |
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.
-rw-r--r-- | compiler/compiler.go | 6 | ||||
-rw-r--r-- | testdata/cgo/main.go | 9 | ||||
-rw-r--r-- | testdata/cgo/out.txt | 1 |
3 files changed, 15 insertions, 1 deletions
diff --git a/compiler/compiler.go b/compiler/compiler.go index 7a1c1e440..432412461 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 1b810a565..aac5221f4 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 d5f3b1379..781187b50 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 |