From 45ca9ef5c1235a80ceffca459cbf1bd47032b35f Mon Sep 17 00:00:00 2001 From: David Chase Date: Wed, 31 Mar 2021 22:51:44 -0400 Subject: [PATCH] cmd/compile: fix register/offset calculation for trailing empty field case. Includes test. Long term, need to make the offending code be more in terms of official types package offsets, instead of duplicating that logic. For #40724. Change-Id: Id33a153f10aed3289cc48d1f99a8e0f6ece9474d Reviewed-on: https://go-review.googlesource.com/c/go/+/306469 Trust: David Chase Run-TryBot: David Chase TryBot-Result: Go Bot Reviewed-by: Than McIntosh Reviewed-by: Cherry Zhang --- src/cmd/compile/internal/abi/abiutils.go | 5 ++- test/abi/fuzz_trailing_zero_field.go | 39 ++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 test/abi/fuzz_trailing_zero_field.go diff --git a/src/cmd/compile/internal/abi/abiutils.go b/src/cmd/compile/internal/abi/abiutils.go index 56e008830fe..50a818c025c 100644 --- a/src/cmd/compile/internal/abi/abiutils.go +++ b/src/cmd/compile/internal/abi/abiutils.go @@ -211,8 +211,11 @@ func appendParamOffsets(offsets []int64, at int64, t *types.Type) ([]int64, int6 offsets, at = appendParamOffsets(offsets, at, t.Elem()) } case types.TSTRUCT: - for _, f := range t.FieldSlice() { + for i, f := range t.FieldSlice() { offsets, at = appendParamOffsets(offsets, at, f.Type) + if f.Type.Width == 0 && i == t.NumFields()-1 { + at++ // last field has zero width + } } at = align(at, t) // type size is rounded up to its alignment case types.TSLICE: diff --git a/test/abi/fuzz_trailing_zero_field.go b/test/abi/fuzz_trailing_zero_field.go new file mode 100644 index 00000000000..ae7ad32aa22 --- /dev/null +++ b/test/abi/fuzz_trailing_zero_field.go @@ -0,0 +1,39 @@ +// run + +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +var p0exp = S1{ + F1: complex(float64(2.3640607624715027), float64(-0.2717825524109192)), + F2: S2{F1: 9}, + F3: 103050709, +} + +type S1 struct { + F1 complex128 + F2 S2 + F3 uint64 +} + +type S2 struct { + F1 uint64 + F2 empty +} + +type empty struct { +} + +//go:noinline +//go:registerparams +func callee(p0 S1) { + if p0 != p0exp { + panic("bad p0") + } +} + +func main() { + callee(p0exp) +}