]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.19] cmd/compile: correct alignment of atomic.Int64
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Wed, 3 Aug 2022 08:14:25 +0000 (15:14 +0700)
committerHeschi Kreinick <heschi@google.com>
Mon, 29 Aug 2022 19:08:15 +0000 (19:08 +0000)
Same as CL 417555, but for cmd/compile.

Fixes #54235

Change-Id: I4cc6deaf0a87c952f636888b4ab73f81a44bfebd
Reviewed-on: https://go-review.googlesource.com/c/go/+/420975
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/422034
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/compile/internal/noder/sizes.go
src/cmd/compile/internal/types2/sizes.go
test/fixedbugs/issue54220.go [new file with mode: 0644]

index 9ba0e509d79cc429c6a091e8fe8af4e6e8a33799..7820746db1342eebe8916f2de59e7268c31ac076 100644 (file)
@@ -25,6 +25,17 @@ func (s *gcSizes) Alignof(T types2.Type) int64 {
                // is the same as unsafe.Alignof(x[0]), but at least 1."
                return s.Alignof(t.Elem())
        case *types2.Struct:
+               if t.NumFields() == 0 && types2.IsSyncAtomicAlign64(T) {
+                       // Special case: sync/atomic.align64 is an
+                       // empty struct we recognize as a signal that
+                       // the struct it contains must be
+                       // 64-bit-aligned.
+                       //
+                       // This logic is equivalent to the logic in
+                       // cmd/compile/internal/types/size.go:calcStructOffset
+                       return 8
+               }
+
                // spec: "For a variable x of struct type: unsafe.Alignof(x)
                // is the largest of the values unsafe.Alignof(x.f) for each
                // field f of x, but at least 1."
index 4da309461f3974f3e97708896d875e35c3688350..c99a12b2e9205705d8134fbf38a085fcc1155fc5 100644 (file)
@@ -53,7 +53,7 @@ func (s *StdSizes) Alignof(T Type) int64 {
                // is the same as unsafe.Alignof(x[0]), but at least 1."
                return s.Alignof(t.elem)
        case *Struct:
-               if len(t.fields) == 0 && isSyncAtomicAlign64(T) {
+               if len(t.fields) == 0 && IsSyncAtomicAlign64(T) {
                        // Special case: sync/atomic.align64 is an
                        // empty struct we recognize as a signal that
                        // the struct it contains must be
@@ -104,7 +104,7 @@ func (s *StdSizes) Alignof(T Type) int64 {
        return a
 }
 
-func isSyncAtomicAlign64(T Type) bool {
+func IsSyncAtomicAlign64(T Type) bool {
        named, ok := T.(*Named)
        if !ok {
                return false
diff --git a/test/fixedbugs/issue54220.go b/test/fixedbugs/issue54220.go
new file mode 100644 (file)
index 0000000..105f6e9
--- /dev/null
@@ -0,0 +1,26 @@
+// run
+
+// 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.
+
+package main
+
+import (
+       "strconv"
+       "sync/atomic"
+       "unsafe"
+)
+
+type t struct {
+       i1 atomic.Int32
+       i2 atomic.Int64
+}
+
+var v t
+
+func main() {
+       if o := unsafe.Offsetof(v.i2); o != 8 {
+               panic("unexpected offset, want: 8, got: " + strconv.Itoa(int(o)))
+       }
+}