From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2116) id BE27D3858C50; Tue, 27 Sep 2022 16:28:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BE27D3858C50 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1664296136; bh=ArxzXqZt3+j7wlc3VFJflkbkj9abZgmsNFSSpqyz5So=; h=From:To:Subject:Date:From; b=Q82aIDjzTVVlgEHQWxCZI/EPYK+7fRFfTfrGfFBWXixi/+LZeCbq3HNgURRbzPZA9 vC+Jd0Qdp2ZrHOt7OsSen5bGSoaDbaxyfeTjQyq/Pd/BHh2Rl9p1EKFxCDCrCo4yeR t4BamtjNE5jksQoHV4uZ9rHcWovAcXwX2lMgyzJ8= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Ian Lance Taylor To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-2902] runtime: synchronize empty struct field handling X-Act-Checkin: gcc X-Git-Author: melonedo X-Git-Refname: refs/heads/master X-Git-Oldrev: 0b2706ac0e6d6b990d789325f9e081dfe4501f4f X-Git-Newrev: f38162977e2b7efaa75233a0cba2a30a2b7f5132 Message-Id: <20220927162856.BE27D3858C50@sourceware.org> Date: Tue, 27 Sep 2022 16:28:56 +0000 (GMT) List-Id: https://gcc.gnu.org/g:f38162977e2b7efaa75233a0cba2a30a2b7f5132 commit r13-2902-gf38162977e2b7efaa75233a0cba2a30a2b7f5132 Author: melonedo Date: Mon Sep 19 16:01:04 2022 +0800 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 Diff: --- gcc/go/gofrontend/MERGE | 2 +- libgo/go/runtime/ffi.go | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index f7a7985287d..73aa712dbdf 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -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. diff --git a/libgo/go/runtime/ffi.go b/libgo/go/runtime/ffi.go index cd8479ef551..86ce5b85d04 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).