aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2024-01-10 18:24:56 +0100
committerRon Evans <[email protected]>2024-01-12 14:54:42 +0100
commitd0445d6f839f4cb3139c1f2ad82c1b82b87ce7b6 (patch)
tree98df8e0cd915489099edc544d83aa626f8448855
parenta40b11f5356090b4cefde1625b29eb07e04344a2 (diff)
downloadtinygo-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.go6
-rw-r--r--testdata/cgo/main.go9
-rw-r--r--testdata/cgo/out.txt1
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