mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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: https://github.com/php/frankenphp/pull/1976
Fixes #76340
Change-Id: I301838ff72e99ae78b035a8eff2405f6a145ed1a
GitHub-Last-Rev: 7dfbccfa58
GitHub-Pull-Request: golang/go#76325
Reviewed-on: https://go-review.googlesource.com/c/go/+/720960
Reviewed-by: Mark Freeman <markfreeman@google.com>
Auto-Submit: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
89552911b3
commit
a593ca9d65
6 changed files with 59 additions and 0 deletions
|
|
@ -1121,6 +1121,9 @@ func (p *Package) hasPointer(f *File, t ast.Expr, top bool) bool {
|
||||||
if t.Name == "error" {
|
if t.Name == "error" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
if t.Name == "any" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
if goTypes[t.Name] != nil {
|
if goTypes[t.Name] != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,7 @@ func TestSetEnv(t *testing.T) { testSetEnv(t) }
|
||||||
func TestThreadLock(t *testing.T) { testThreadLockFunc(t) }
|
func TestThreadLock(t *testing.T) { testThreadLockFunc(t) }
|
||||||
func TestUnsignedInt(t *testing.T) { testUnsignedInt(t) }
|
func TestUnsignedInt(t *testing.T) { testUnsignedInt(t) }
|
||||||
func TestZeroArgCallback(t *testing.T) { testZeroArgCallback(t) }
|
func TestZeroArgCallback(t *testing.T) { testZeroArgCallback(t) }
|
||||||
|
func Test76340(t *testing.T) { test76340(t) }
|
||||||
|
|
||||||
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
|
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
|
||||||
func BenchmarkGoString(b *testing.B) { benchGoString(b) }
|
func BenchmarkGoString(b *testing.B) { benchGoString(b) }
|
||||||
|
|
|
||||||
|
|
@ -959,6 +959,18 @@ char * const issue75751p = &issue75751v;
|
||||||
#define issue75751m issue75751p
|
#define issue75751m issue75751p
|
||||||
char * const volatile issue75751p2 = &issue75751v;
|
char * const volatile issue75751p2 = &issue75751v;
|
||||||
#define issue75751m2 issue75751p2
|
#define issue75751m2 issue75751p2
|
||||||
|
|
||||||
|
typedef struct { void *t; void *v; } GoInterface;
|
||||||
|
extern int exportAny76340Param(GoInterface);
|
||||||
|
extern GoInterface exportAny76340Return(int);
|
||||||
|
|
||||||
|
int issue76340testFromC(GoInterface obj) {
|
||||||
|
return exportAny76340Param(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
GoInterface issue76340returnFromC(int val) {
|
||||||
|
return exportAny76340Return(val);
|
||||||
|
}
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
|
|
@ -2407,3 +2419,22 @@ func test69086(t *testing.T) {
|
||||||
func test75751() int {
|
func test75751() int {
|
||||||
return int(*C.issue75751m) + int(*C.issue75751m2)
|
return int(*C.issue75751m) + int(*C.issue75751m2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue 76340.
|
||||||
|
func test76340(t *testing.T) {
|
||||||
|
var emptyInterface C.GoInterface
|
||||||
|
r1 := C.issue76340testFromC(emptyInterface)
|
||||||
|
if r1 != 0 {
|
||||||
|
t.Errorf("issue76340testFromC with nil interface: got %d, want 0", r1)
|
||||||
|
}
|
||||||
|
|
||||||
|
r2 := C.issue76340returnFromC(42)
|
||||||
|
if r2.t == nil && r2.v == nil {
|
||||||
|
t.Error("issue76340returnFromC(42) returned nil interface")
|
||||||
|
}
|
||||||
|
|
||||||
|
r3 := C.issue76340returnFromC(0)
|
||||||
|
if r3.t != nil || r3.v != nil {
|
||||||
|
t.Errorf("issue76340returnFromC(0) returned non-nil interface: got %v, want nil", r3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -595,3 +595,21 @@ func test49633(t *testing.T) {
|
||||||
t.Errorf("msg = %q, want 'hello'", v.msg)
|
t.Errorf("msg = %q, want 'hello'", v.msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//export exportAny76340Param
|
||||||
|
func exportAny76340Param(obj any) C.int {
|
||||||
|
if obj == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
//export exportAny76340Return
|
||||||
|
func exportAny76340Return(val C.int) any {
|
||||||
|
if val == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return int(val)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1558,6 +1558,9 @@ func (p *Package) doCgoType(e ast.Expr, m map[ast.Expr]bool) *Type {
|
||||||
if t.Name == "error" {
|
if t.Name == "error" {
|
||||||
return &Type{Size: 2 * p.PtrSize, Align: p.PtrSize, C: c("GoInterface")}
|
return &Type{Size: 2 * p.PtrSize, Align: p.PtrSize, C: c("GoInterface")}
|
||||||
}
|
}
|
||||||
|
if t.Name == "any" {
|
||||||
|
return &Type{Size: 2 * p.PtrSize, Align: p.PtrSize, C: c("GoInterface")}
|
||||||
|
}
|
||||||
if r, ok := goTypes[t.Name]; ok {
|
if r, ok := goTypes[t.Name]; ok {
|
||||||
return goTypesFixup(r)
|
return goTypesFixup(r)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -796,6 +796,9 @@ func cgoCheckResult(val any) {
|
||||||
|
|
||||||
ep := efaceOf(&val)
|
ep := efaceOf(&val)
|
||||||
t := ep._type
|
t := ep._type
|
||||||
|
if t == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
cgoCheckArg(t, ep.data, !t.IsDirectIface(), false, cgoResultFail)
|
cgoCheckArg(t, ep.data, !t.IsDirectIface(), false, cgoResultFail)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue