Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/cmd/cgo/gcc.go
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,9 @@ func (p *Package) hasPointer(f *File, t ast.Expr, top bool) bool {
if t.Name == "error" {
return true
}
if t.Name == "any" {
return true
}
if goTypes[t.Name] != nil {
return false
}
Expand Down
1 change: 1 addition & 0 deletions src/cmd/cgo/internal/test/cgo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ func TestSetEnv(t *testing.T) { testSetEnv(t) }
func TestThreadLock(t *testing.T) { testThreadLockFunc(t) }
func TestUnsignedInt(t *testing.T) { testUnsignedInt(t) }
func TestZeroArgCallback(t *testing.T) { testZeroArgCallback(t) }
func TestAny(t *testing.T) { testAny(t) }

func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
func BenchmarkGoString(b *testing.B) { benchGoString(b) }
Expand Down
30 changes: 30 additions & 0 deletions src/cmd/cgo/internal/test/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,18 @@ typedef struct {
} issue69086struct;
static int issue690861(issue69086struct* p) { p->b = 1234; return p->c; }
static int issue690862(unsigned long ul1, unsigned long ul2, unsigned int u, issue69086struct s) { return (int)(s.b); }

typedef struct { void *t; void *v; } GoInterface;
extern int exportAnyParam(GoInterface);
extern GoInterface exportAnyReturn(int);

int testAnyFromC(GoInterface obj) {
return exportAnyParam(obj);
}

GoInterface testAnyReturnFromC(int val) {
return exportAnyReturn(val);
}
*/
import "C"

Expand Down Expand Up @@ -2396,3 +2408,21 @@ func test69086(t *testing.T) {
t.Errorf("call: got %d, want 1234", got)
}
}

func testAny(t *testing.T) {
var emptyInterface C.GoInterface
r1 := C.testAnyFromC(emptyInterface)
if r1 != 0 {
t.Errorf("testAnyFromC with nil interface: got %d, want 0", r1)
}

r2 := C.testAnyReturnFromC(42)
if r2.t == nil && r2.v == nil {
t.Error("testAnyReturnFromC(42) returned nil interface")
}

r3 := C.testAnyReturnFromC(0)
if r3.t != nil || r3.v != nil {
t.Errorf("testAnyReturnFromC(0) returned non-nil interface: got %v, want nil", r3)
}
}
18 changes: 18 additions & 0 deletions src/cmd/cgo/internal/test/testx.go
Original file line number Diff line number Diff line change
Expand Up @@ -595,3 +595,21 @@ func test49633(t *testing.T) {
t.Errorf("msg = %q, want 'hello'", v.msg)
}
}

//export exportAnyParam
func exportAnyParam(obj any) C.int {
if obj == nil {
return 0
}

return 1
}

//export exportAnyReturn
func exportAnyReturn(val C.int) any {
if val == 0 {
return nil
}

return int(val)
}
3 changes: 3 additions & 0 deletions src/cmd/cgo/out.go
Original file line number Diff line number Diff line change
Expand Up @@ -1528,6 +1528,9 @@ func (p *Package) doCgoType(e ast.Expr, m map[ast.Expr]bool) *Type {
if t.Name == "error" {
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 {
return goTypesFixup(r)
}
Expand Down
3 changes: 3 additions & 0 deletions src/runtime/cgocall.go
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,9 @@ func cgoCheckResult(val any) {

ep := efaceOf(&val)
t := ep._type
if t == nil {
return
}
cgoCheckArg(t, ep.data, !t.IsDirectIface(), false, cgoResultFail)
}

Expand Down