func (s *ssafn) AllocFrame(f *ssa.Func) {
s.stksize = 0
s.stkptrsize = 0
+ s.stkalign = int64(types.RegSize)
fn := s.curfn
// Mark the PAUTO's unused.
}
s.stksize += w
s.stksize = types.RoundUp(s.stksize, n.Type().Alignment())
+ if n.Type().Alignment() > int64(types.RegSize) {
+ s.stkalign = n.Type().Alignment()
+ }
if n.Type().HasPointers() {
s.stkptrsize = s.stksize
lastHasPtr = true
n.SetFrameOffset(-s.stksize)
}
- s.stksize = types.RoundUp(s.stksize, int64(types.RegSize))
- s.stkptrsize = types.RoundUp(s.stkptrsize, int64(types.RegSize))
+ s.stksize = types.RoundUp(s.stksize, s.stkalign)
+ s.stkptrsize = types.RoundUp(s.stkptrsize, s.stkalign)
}
const maxStackSize = 1 << 30
func defframe(s *State, e *ssafn, f *ssa.Func) {
pp := s.pp
- frame := types.RoundUp(s.maxarg+e.stksize, int64(types.RegSize))
+ s.maxarg = types.RoundUp(s.maxarg, e.stkalign)
+ frame := s.maxarg + e.stksize
if Arch.PadFrame != nil {
frame = Arch.PadFrame(frame)
}
strings map[string]*obj.LSym // map from constant string to data symbols
stksize int64 // stack size for current frame
stkptrsize int64 // prefix of stack containing pointers
- log bool // print ssa debug to the stdout
+
+ // alignment for current frame.
+ // NOTE: when stkalign > PtrSize, currently this only ensures the offsets of
+ // objects in the stack frame are aligned. The stack pointer is still aligned
+ // only PtrSize.
+ stkalign int64
+
+ log bool // print ssa debug to the stdout
}
// StringData returns a symbol which
--- /dev/null
+// compile
+
+// Copyright 2022 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.
+
+// Issue 54638: composite literal assignment with
+// alignment > PtrSize causes ICE.
+
+package p
+
+import "sync/atomic"
+
+type S struct{ l any }
+
+type T struct {
+ H any
+ a [14]int64
+ f func()
+ x atomic.Int64
+}
+
+//go:noinline
+func (T) M(any) {}
+
+type W [2]int64
+
+//go:noinline
+func (W) Done() {}
+
+func F(l any) [3]*int {
+ var w W
+ var x [3]*int // use some stack
+ t := T{H: S{l: l}}
+ go func() {
+ t.M(l)
+ w.Done()
+ }()
+ return x
+}