From 9d04637009df7d984a0daa642963343bc966576f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Sat, 11 Mar 2023 00:28:03 +0000 Subject: [PATCH] ensure the alignment of sync/atomic types works Added in Go 1.19, types like sync/atomic.Uint64 are handy, because they ensure proper alignment even on 32-bit GOOSes. However, this was done via a magic `type align64 struct{}`, which the compiler spotted by name. To keep that magic working, do not obfuscate the name. Neither package path was being obfuscated, as both packages contain compiler intrinsics already. Fixes #686. --- main.go | 4 +++ testdata/script/atomic.txtar | 51 ++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 testdata/script/atomic.txtar diff --git a/main.go b/main.go index b482c90..95bce4a 100644 --- a/main.go +++ b/main.go @@ -1907,6 +1907,10 @@ func (tf *transformer) transformGoFile(file *ast.File) *ast.File { // match any field or method named FS. path := pkg.Path() switch path { + case "sync/atomic", "runtime/internal/atomic": + if name == "align64" { + return true + } case "embed": // FS is detected by the compiler for //go:embed. // TODO: We probably want a conditional, otherwise we're not diff --git a/testdata/script/atomic.txtar b/testdata/script/atomic.txtar new file mode 100644 index 0000000..ba81ede --- /dev/null +++ b/testdata/script/atomic.txtar @@ -0,0 +1,51 @@ +# amd64 can typically run 386 programs, +# which is handy to actually make this test useful. +# We assume that the same applies to arm64. +# Note that darwin is an exception compared to linux and windows, +# as darwin/386 and darwin/arm are not supported. +[amd64] [!darwin] env GOARCH=386 +[arm64] [!darwin] env GOARCH=arm + +garble build +exec ./main +cmp stderr main.stderr + +[short] stop # no need to verify this with -short + +go build +exec ./main +cmp stderr main.stderr +-- go.mod -- +module test/main + +go 1.20 +-- main.go -- +package main + +import ( + "sync" + "sync/atomic" +) + +var unalignedUint64 struct { + // If sync/atomic's support in the compiler is broken, + // then u64 is not aligned to 64 bits on 32-bit platforms, + // and that may cause a panic. + _ bool + u64 atomic.Uint64 +} + +func main() { + var wg sync.WaitGroup + for i := 0; i < 10; i++ { + wg.Add(1) + go func() { + unalignedUint64.u64.Add(2) + wg.Done() + }() + } + wg.Wait() + println(unalignedUint64.u64.Load()) +} +-- main.stderr -- +20