]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix register/offset calculation for trailing empty field case.
authorDavid Chase <drchase@google.com>
Thu, 1 Apr 2021 02:51:44 +0000 (22:51 -0400)
committerDavid Chase <drchase@google.com>
Thu, 1 Apr 2021 15:50:43 +0000 (15:50 +0000)
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 <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/compile/internal/abi/abiutils.go
test/abi/fuzz_trailing_zero_field.go [new file with mode: 0644]

index 56e008830fe3f8524ce3ae43a7c3591c140445fd..50a818c025cc63bfb3b9acfb7924856322e75e53 100644 (file)
@@ -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 (file)
index 0000000..ae7ad32
--- /dev/null
@@ -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)
+}