aboutsummaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
authormelonedo <funanzeng@gmail.com>2022-09-19 16:01:04 +0800
committerIan Lance Taylor <iant@golang.org>2022-09-27 09:28:39 -0700
commitf38162977e2b7efaa75233a0cba2a30a2b7f5132 (patch)
treefe1805c24a4ce17d6d50af1ed31d23cb29ae935e /libgo
parent0b2706ac0e6d6b990d789325f9e081dfe4501f4f (diff)
downloadgcc-f38162977e2b7efaa75233a0cba2a30a2b7f5132.zip
gcc-f38162977e2b7efaa75233a0cba2a30a2b7f5132.tar.gz
gcc-f38162977e2b7efaa75233a0cba2a30a2b7f5132.tar.bz2
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
Diffstat (limited to 'libgo')
-rw-r--r--libgo/go/runtime/ffi.go14
1 files changed, 10 insertions, 4 deletions
diff --git a/libgo/go/runtime/ffi.go b/libgo/go/runtime/ffi.go
index cd8479e..86ce5b8 100644
--- a/libgo/go/runtime/ffi.go
+++ b/libgo/go/runtime/ffi.go
@@ -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).