On Fri, Jan 11, 2019 at 3:16 PM Ian Lance Taylor <i...@golang.org> wrote:
>
> This patch by Cherry Zhang changes the Go frontend to pad structs
> ending with a zero-sized field.  For a struct with zero-sized last
> field, the address of the field falls out of the object boundary,
> which confuses the garbage collector.  Pad an extra byte in this case.
> Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
> to mainline.

This follow-up patch by Cherry Zhang adds the padding to the FFI type
when using using libffi.  This fixes reflect.Call with structs that
end in a zero-sized field.  This fixes test/fixedbugs/issue26335.go in
the main repo.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian
Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE     (revision 267950)
+++ gcc/go/gofrontend/MERGE     (working copy)
@@ -1,4 +1,4 @@
-87005025fcd0d7e7908b3aae7062b52cb80eb0f3
+9a79c333e896ea49f6a708d459148074d29a2af6
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: libgo/go/runtime/ffi.go
===================================================================
--- libgo/go/runtime/ffi.go     (revision 267941)
+++ libgo/go/runtime/ffi.go     (working copy)
@@ -227,6 +227,7 @@ func structToFFI(typ *structtype) *__ffi
 
        fields := make([]*__ffi_type, 0, c+1)
        checkPad := false
+       lastzero := false
        for i, v := range typ.fields {
                // Skip zero-sized fields; they confuse libffi,
                // and there is no value to pass in any case.
@@ -235,8 +236,10 @@ func structToFFI(typ *structtype) *__ffi
                // next field.
                if v.typ.size == 0 {
                        checkPad = true
+                       lastzero = true
                        continue
                }
+               lastzero = false
 
                if checkPad {
                        off := uintptr(0)
@@ -257,6 +260,13 @@ func structToFFI(typ *structtype) *__ffi
                fields = append(fields, typeToFFI(v.typ))
        }
 
+       if lastzero {
+               // The compiler adds one byte padding to non-empty struct ending
+               // with a zero-sized field (types.cc:get_backend_struct_fields).
+               // Add this padding to the FFI type.
+               fields = append(fields, ffi_type_uint8())
+       }
+
        fields = append(fields, nil)
 
        return &__ffi_type{

Reply via email to