]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
runtime: synchronize empty struct field handling
authormelonedo <funanzeng@gmail.com>
Mon, 19 Sep 2022 08:01:04 +0000 (16:01 +0800)
committerIan Lance Taylor <iant@golang.org>
Tue, 27 Sep 2022 16:28:39 +0000 (09:28 -0700)
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

gcc/go/gofrontend/MERGE
libgo/go/runtime/ffi.go

index f7a7985287da779f04a9204862d6ea802021790b..73aa712dbdf8434fc9d481287d32156406e5ecda 100644 (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.
index cd8479ef55145bee54e718483fa437a08af58507..86ce5b85d046aee89c9de2c4f72fa3309f82252b 100644 (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).