diff --git a/src/cmd/compile/internal/abi/abiutils.go b/src/cmd/compile/internal/abi/abiutils.go index 56e008830f..50a818c025 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 0000000000..ae7ad32aa2 --- /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) +}