runtime: synchronize empty struct field handling

In GCCGO and gollvm, the logic for allocating one byte for the last field is:
1. the last field has zero size
2. the struct itself does not have zero size
3. the last field is not blank
this commit adds the last two conditions to runtime.structToFFI.

For golang/go#55146

Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/431735
This commit is contained in:
melonedo
2022-09-19 16:01:04 +08:00
committed by Ian Lance Taylor
parent 0b2706ac0e
commit f38162977e
2 changed files with 11 additions and 5 deletions

View File

@@ -1,4 +1,4 @@
42efec8c126cf3787bc7c89d9c7f224eff7c5a21
0140cca9bc0fad1108c7ed369376ac71cc4bfecf
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.

View File

@@ -4,6 +4,7 @@
// Only build this file if libffi is supported.
//go:build libffi
// +build libffi
package runtime
@@ -221,9 +222,6 @@ func stringToFFI() *__ffi_type {
// structToFFI returns an ffi_type for a Go struct type.
func structToFFI(typ *structtype) *__ffi_type {
c := len(typ.fields)
if c == 0 {
return emptyStructToFFI()
}
if typ.typ.kind&kindDirectIface != 0 {
return ffi_type_pointer()
}
@@ -231,6 +229,7 @@ func structToFFI(typ *structtype) *__ffi_type {
fields := make([]*__ffi_type, 0, c+1)
checkPad := false
lastzero := false
sawnonzero := false
for i, v := range typ.fields {
// Skip zero-sized fields; they confuse libffi,
// and there is no value to pass in any case.
@@ -239,10 +238,13 @@ func structToFFI(typ *structtype) *__ffi_type {
// next field.
if v.typ.size == 0 {
checkPad = true
lastzero = true
if v.name == nil || *v.name != "_" {
lastzero = true
}
continue
}
lastzero = false
sawnonzero = true
if checkPad {
off := uintptr(0)
@@ -263,6 +265,10 @@ func structToFFI(typ *structtype) *__ffi_type {
fields = append(fields, typeToFFI(v.typ))
}
if !sawnonzero {
return emptyStructToFFI()
}
if lastzero {
// The compiler adds one byte padding to non-empty struct ending
// with a zero-sized field (types.cc:get_backend_struct_fields).