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{