Skip to content

Commit

Permalink
ensure the alignment of sync/atomic types works
Browse files Browse the repository at this point in the history
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 burrowers#686.
  • Loading branch information
mvdan committed Mar 11, 2023
1 parent b87830e commit e7fa568
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
4 changes: 4 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
49 changes: 49 additions & 0 deletions testdata/script/atomic.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# amd64 can typically run 386 programs,
# which is handy to actually make this test useful.
# We assume that the same applies to arm64.
[amd64] env GOARCH=386
[arm64] 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

0 comments on commit e7fa568

Please sign in to comment.