Skip to content

Commit 7dfbccf

Browse files
runtime/cgo: add support for any param and return type
When using `any` as param or return type of an exported function, we currently have the error `unrecognized Go type any`. `any` is an alias of `interface{}` which is already supported. This would avoid such change: php/frankenphp#1976 Fixes #76340
1 parent feae743 commit 7dfbccf

File tree

6 files changed

+59
-0
lines changed

6 files changed

+59
-0
lines changed

src/cmd/cgo/gcc.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,9 @@ func (p *Package) hasPointer(f *File, t ast.Expr, top bool) bool {
11211121
if t.Name == "error" {
11221122
return true
11231123
}
1124+
if t.Name == "any" {
1125+
return true
1126+
}
11241127
if goTypes[t.Name] != nil {
11251128
return false
11261129
}

src/cmd/cgo/internal/test/cgo_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ func TestSetEnv(t *testing.T) { testSetEnv(t) }
106106
func TestThreadLock(t *testing.T) { testThreadLockFunc(t) }
107107
func TestUnsignedInt(t *testing.T) { testUnsignedInt(t) }
108108
func TestZeroArgCallback(t *testing.T) { testZeroArgCallback(t) }
109+
func Test76340(t *testing.T) { test76340(t) }
109110

110111
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
111112
func BenchmarkGoString(b *testing.B) { benchGoString(b) }

src/cmd/cgo/internal/test/test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,18 @@ char * const issue75751p = &issue75751v;
959959
#define issue75751m issue75751p
960960
char * const volatile issue75751p2 = &issue75751v;
961961
#define issue75751m2 issue75751p2
962+
963+
typedef struct { void *t; void *v; } GoInterface;
964+
extern int exportAny76340Param(GoInterface);
965+
extern GoInterface exportAny76340Return(int);
966+
967+
int issue76340testFromC(GoInterface obj) {
968+
return exportAny76340Param(obj);
969+
}
970+
971+
GoInterface issue76340returnFromC(int val) {
972+
return exportAny76340Return(val);
973+
}
962974
*/
963975
import "C"
964976

@@ -2407,3 +2419,22 @@ func test69086(t *testing.T) {
24072419
func test75751() int {
24082420
return int(*C.issue75751m) + int(*C.issue75751m2)
24092421
}
2422+
2423+
// Issue 76340.
2424+
func test76340(t *testing.T) {
2425+
var emptyInterface C.GoInterface
2426+
r1 := C.issue76340testFromC(emptyInterface)
2427+
if r1 != 0 {
2428+
t.Errorf("issue76340testFromC with nil interface: got %d, want 0", r1)
2429+
}
2430+
2431+
r2 := C.issue76340returnFromC(42)
2432+
if r2.t == nil && r2.v == nil {
2433+
t.Error("issue76340returnFromC(42) returned nil interface")
2434+
}
2435+
2436+
r3 := C.issue76340returnFromC(0)
2437+
if r3.t != nil || r3.v != nil {
2438+
t.Errorf("issue76340returnFromC(0) returned non-nil interface: got %v, want nil", r3)
2439+
}
2440+
}

src/cmd/cgo/internal/test/testx.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,3 +595,21 @@ func test49633(t *testing.T) {
595595
t.Errorf("msg = %q, want 'hello'", v.msg)
596596
}
597597
}
598+
599+
//export exportAny76340Param
600+
func exportAny76340Param(obj any) C.int {
601+
if obj == nil {
602+
return 0
603+
}
604+
605+
return 1
606+
}
607+
608+
//export exportAny76340Return
609+
func exportAny76340Return(val C.int) any {
610+
if val == 0 {
611+
return nil
612+
}
613+
614+
return int(val)
615+
}

src/cmd/cgo/out.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,6 +1558,9 @@ func (p *Package) doCgoType(e ast.Expr, m map[ast.Expr]bool) *Type {
15581558
if t.Name == "error" {
15591559
return &Type{Size: 2 * p.PtrSize, Align: p.PtrSize, C: c("GoInterface")}
15601560
}
1561+
if t.Name == "any" {
1562+
return &Type{Size: 2 * p.PtrSize, Align: p.PtrSize, C: c("GoInterface")}
1563+
}
15611564
if r, ok := goTypes[t.Name]; ok {
15621565
return goTypesFixup(r)
15631566
}

src/runtime/cgocall.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,9 @@ func cgoCheckResult(val any) {
796796

797797
ep := efaceOf(&val)
798798
t := ep._type
799+
if t == nil {
800+
return
801+
}
799802
cgoCheckArg(t, ep.data, !t.IsDirectIface(), false, cgoResultFail)
800803
}
801804

0 commit comments

Comments
 (0)