From 162b88265ed41e61d6af20f7ad2039ddcdf51a2c Mon Sep 17 00:00:00 2001 From: Michael Anthony Knyszek Date: Fri, 3 Jun 2022 19:15:24 +0000 Subject: [PATCH] cmd/compile/internal/escape: escape values with >PtrSize alignment After CL 381317 there exist values that may have an alignment greater than the pointer size for that platform. Specifically, atomic.{Ui|I}nt64 may be aligned to 8 bytes on a 32-bit platform. If such a value, or a container for the value, gets stack-allocated, it's possible that it won't be aligned correctly, because the maximum alignment we enforce on stacks is governed by the pointer size. Changing that would be a significant undertaking, so just escape these values to the heap instead, where we're sure they'll actually be aligned correctly. Change is by rsc@, I'm just shepherding it through code review. For #50860. Change-Id: I51669561c0a13ecb84f821020e144c58cb528418 Reviewed-on: https://go-review.googlesource.com/c/go/+/410131 Run-TryBot: Michael Knyszek TryBot-Result: Gopher Robot Reviewed-by: Matthew Dempsky --- src/cmd/compile/internal/escape/utils.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/cmd/compile/internal/escape/utils.go b/src/cmd/compile/internal/escape/utils.go index 2c6e9bcbeb..b481d8e4b6 100644 --- a/src/cmd/compile/internal/escape/utils.go +++ b/src/cmd/compile/internal/escape/utils.go @@ -7,6 +7,7 @@ package escape import ( "cmd/compile/internal/ir" "cmd/compile/internal/typecheck" + "cmd/compile/internal/types" ) func isSliceSelfAssign(dst, src ir.Node) bool { @@ -185,10 +186,16 @@ func HeapAllocReason(n ir.Node) string { if n.Type().Size() > ir.MaxStackVarSize { return "too large for stack" } + if n.Type().Alignment() > int64(types.PtrSize) { + return "too aligned for stack" + } if (n.Op() == ir.ONEW || n.Op() == ir.OPTRLIT) && n.Type().Elem().Size() > ir.MaxImplicitStackVarSize { return "too large for stack" } + if (n.Op() == ir.ONEW || n.Op() == ir.OPTRLIT) && n.Type().Elem().Alignment() > int64(types.PtrSize) { + return "too aligned for stack" + } if n.Op() == ir.OCLOSURE && typecheck.ClosureType(n.(*ir.ClosureExpr)).Size() > ir.MaxImplicitStackVarSize { return "too large for stack"