]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: align stack-allocated backing stores higher than required
authorKeith Randall <khr@golang.org>
Thu, 17 Apr 2025 05:48:06 +0000 (22:48 -0700)
committerGopher Robot <gobot@golang.org>
Tue, 20 May 2025 01:12:50 +0000 (18:12 -0700)
Because that's what mallocgc did and some user code came to rely on it.

Fixes #73199

Change-Id: I45ca00d2ea448e6729ef9ac4cec3c1eb0ceccc89
Reviewed-on: https://go-review.googlesource.com/c/go/+/666116
Reviewed-by: t hepudds <thepudds1460@gmail.com>
Reviewed-by: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/cmd/compile/internal/walk/builtin.go

index 99cf2d784d8cdd5186a7b208a332c2edc73af610..84e7436103ecb9054e4c6a99e49820ac3a9d470f 100644 (file)
@@ -600,11 +600,23 @@ func walkMakeSlice(n *ir.MakeExpr, init *ir.Nodes) ir.Node {
                        lenCap.Body.Append(mkcall("panicmakeslicecap", nil, &lenCap.Body))
                        nif.Body.Append(lenCap)
 
-                       t := types.NewArray(t.Elem(), K)                              // [K]E
-                       arr := typecheck.TempAt(base.Pos, ir.CurFunc, t)              // var arr [K]E
-                       nif.Body.Append(ir.NewAssignStmt(base.Pos, arr, nil))         // arr = {} (zero it)
-                       s := ir.NewSliceExpr(base.Pos, ir.OSLICE, arr, nil, len, cap) // arr[:len:cap]
-                       nif.Body.Append(ir.NewAssignStmt(base.Pos, slice, s))         // slice = arr[:len:cap]
+                       t := types.NewArray(t.Elem(), K) // [K]E
+                       // Wrap in a struct containing a [0]uintptr field to force
+                       // pointer alignment. Some user code expects higher alignment
+                       // than what is guaranteed by the element type, because that's
+                       // the behavior they observed of mallocgc, and then relied upon.
+                       // See issue 73199.
+                       field := typecheck.Lookup("arr")
+                       t = types.NewStruct([]*types.Field{
+                               {Sym: types.BlankSym, Type: types.NewArray(types.Types[types.TUINTPTR], 0)},
+                               {Sym: field, Type: t},
+                       })
+                       t.SetNoalg(true)
+                       store := typecheck.TempAt(base.Pos, ir.CurFunc, t)            // var store struct{_ uintptr[0]; arr [K]E}
+                       nif.Body.Append(ir.NewAssignStmt(base.Pos, store, nil))       // store = {} (zero it)
+                       arr := ir.NewSelectorExpr(base.Pos, ir.ODOT, store, field)    // arr = store.arr
+                       s := ir.NewSliceExpr(base.Pos, ir.OSLICE, arr, nil, len, cap) // store.arr[:len:cap]
+                       nif.Body.Append(ir.NewAssignStmt(base.Pos, slice, s))         // slice = store.arr[:len:cap]
 
                        appendWalkStmt(init, typecheck.Stmt(nif))