1
# DP: Backport fix for calling a function or method that
2
# DP: takes or returns an empty struct via reflection.
4
--- a/src/libgo/go/reflect/all_test.go
5
+++ b/src/libgo/go/reflect/all_test.go
6
@@ -1430,6 +1430,46 @@ func TestFunc(t *testing.T) {
10
+type emptyStruct struct{}
12
+type nonEmptyStruct struct {
16
+func returnEmpty() emptyStruct {
17
+ return emptyStruct{}
20
+func takesEmpty(e emptyStruct) {
23
+func returnNonEmpty(i int) nonEmptyStruct {
24
+ return nonEmptyStruct{member: i}
27
+func takesNonEmpty(n nonEmptyStruct) int {
31
+func TestCallWithStruct(t *testing.T) {
32
+ r := ValueOf(returnEmpty).Call([]Value{})
33
+ if len(r) != 1 || r[0].Type() != TypeOf(emptyStruct{}) {
34
+ t.Errorf("returning empty struct returned %s instead", r)
36
+ r = ValueOf(takesEmpty).Call([]Value{ValueOf(emptyStruct{})})
38
+ t.Errorf("takesEmpty returned values: %s", r)
40
+ r = ValueOf(returnNonEmpty).Call([]Value{ValueOf(42)})
41
+ if len(r) != 1 || r[0].Type() != TypeOf(nonEmptyStruct{}) || r[0].Field(0).Int() != 42 {
42
+ t.Errorf("returnNonEmpty returned %s", r)
44
+ r = ValueOf(takesNonEmpty).Call([]Value{ValueOf(nonEmptyStruct{member: 42})})
45
+ if len(r) != 1 || r[0].Type() != TypeOf(1) || r[0].Int() != 42 {
46
+ t.Errorf("takesNonEmpty returned %s", r)
50
func TestMakeFunc(t *testing.T) {
51
switch runtime.GOARCH {
53
--- a/src/libgo/runtime/go-reflect-call.c
54
+++ b/src/libgo/runtime/go-reflect-call.c
55
@@ -98,9 +98,12 @@ go_struct_to_ffi (const struct __go_struct_type *descriptor)
56
const struct __go_struct_field *fields;
59
+ field_count = descriptor->__fields.__count;
60
+ if (field_count == 0) {
61
+ return &ffi_type_void;
63
ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
64
ret->type = FFI_TYPE_STRUCT;
65
- field_count = descriptor->__fields.__count;
66
fields = (const struct __go_struct_field *) descriptor->__fields.__values;
67
ret->elements = (ffi_type **) __go_alloc ((field_count + 1)
68
* sizeof (ffi_type *));