Skip to content

Commit 00bee6d

Browse files
cuonglmgopherbot
authored andcommitted
cmd/compile/internal/typebits: relax alignment check
Now we have 8-byte alignment types on 32-bit system, so in some rare case, e.g, generated wrapper for embedded interface, the function argument may need more than 4 byte alignment. We could pad somehow, but this is a rare case which makes it hard to ensure that we've got it right. So relaxing the check for argument and return value region of the stack. Fixes #54991 Change-Id: I34986e17a920254392a39439ad3dcb323da2ea8d Reviewed-on: https://go-review.googlesource.com/c/go/+/431098 Reviewed-by: Keith Randall <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Cherry Mui <[email protected]> Run-TryBot: Cuong Manh Le <[email protected]> Auto-Submit: Keith Randall <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent 638c9aa commit 00bee6d

File tree

3 files changed

+44
-6
lines changed

3 files changed

+44
-6
lines changed

src/cmd/compile/internal/liveness/plive.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ func (lv *liveness) pointerMap(liveout bitvec.BitVec, vars []*ir.Name, args, loc
425425
if node.FrameOffset() < 0 {
426426
lv.f.Fatalf("Node %v has frameoffset %d\n", node.Sym().Name, node.FrameOffset())
427427
}
428-
typebits.Set(node.Type(), node.FrameOffset(), args)
428+
typebits.SetNoCheck(node.Type(), node.FrameOffset(), args)
429429
break
430430
}
431431
fallthrough // PPARAMOUT in registers acts memory-allocates like an AUTO
@@ -1498,7 +1498,7 @@ func WriteFuncMap(fn *ir.Func, abiInfo *abi.ABIParamResultInfo) {
14981498
bv := bitvec.New(int32(nptr) * 2)
14991499

15001500
for _, p := range abiInfo.InParams() {
1501-
typebits.Set(p.Type, p.FrameOffset(abiInfo), bv)
1501+
typebits.SetNoCheck(p.Type, p.FrameOffset(abiInfo), bv)
15021502
}
15031503

15041504
nbitmap := 1
@@ -1513,7 +1513,7 @@ func WriteFuncMap(fn *ir.Func, abiInfo *abi.ABIParamResultInfo) {
15131513
if fn.Type().NumResults() > 0 {
15141514
for _, p := range abiInfo.OutParams() {
15151515
if len(p.Registers) == 0 {
1516-
typebits.Set(p.Type, p.FrameOffset(abiInfo), bv)
1516+
typebits.SetNoCheck(p.Type, p.FrameOffset(abiInfo), bv)
15171517
}
15181518
}
15191519
off = objw.BitVec(lsym, off, bv)

src/cmd/compile/internal/typebits/typebits.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,16 @@ import (
1414
// the first run and then simply copied into bv at the correct offset
1515
// on future calls with the same type t.
1616
func Set(t *types.Type, off int64, bv bitvec.BitVec) {
17-
if uint8(t.Alignment()) > 0 && off&int64(uint8(t.Alignment())-1) != 0 {
17+
set(t, off, bv, false)
18+
}
19+
20+
// SetNoCheck is like Set, but do not check for alignment.
21+
func SetNoCheck(t *types.Type, off int64, bv bitvec.BitVec) {
22+
set(t, off, bv, true)
23+
}
24+
25+
func set(t *types.Type, off int64, bv bitvec.BitVec, skip bool) {
26+
if !skip && uint8(t.Alignment()) > 0 && off&int64(uint8(t.Alignment())-1) != 0 {
1827
base.Fatalf("typebits.Set: invalid initial alignment: type %v has alignment %d, but offset is %v", t, uint8(t.Alignment()), off)
1928
}
2029
if !t.HasPointers() {
@@ -72,13 +81,13 @@ func Set(t *types.Type, off int64, bv bitvec.BitVec) {
7281
break
7382
}
7483
for i := int64(0); i < t.NumElem(); i++ {
75-
Set(elt, off, bv)
84+
set(elt, off, bv, skip)
7685
off += elt.Size()
7786
}
7887

7988
case types.TSTRUCT:
8089
for _, f := range t.Fields().Slice() {
81-
Set(f.Type, off+f.Offset, bv)
90+
set(f.Type, off+f.Offset, bv, skip)
8291
}
8392

8493
default:

test/fixedbugs/issue54991.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// compile
2+
3+
// Copyright 2022 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package p
8+
9+
import (
10+
"sync/atomic"
11+
)
12+
13+
type I interface {
14+
M()
15+
}
16+
17+
type S struct{}
18+
19+
func (*S) M() {}
20+
21+
type T struct {
22+
I
23+
x atomic.Int64
24+
}
25+
26+
func F() {
27+
t := &T{I: &S{}}
28+
t.M()
29+
}

0 commit comments

Comments
 (0)