diff --git a/src/cmd/compile/internal/types/size.go b/src/cmd/compile/internal/types/size.go index 7122b2720f..a5a5c0b5b1 100644 --- a/src/cmd/compile/internal/types/size.go +++ b/src/cmd/compile/internal/types/size.go @@ -169,7 +169,7 @@ func calcStructOffset(errtype *Type, t *Type, o int64, flag int) int64 { } // Special case: sync/atomic.align64 is an empty struct we recognize // as a signal that the struct it contains must be 64-bit-aligned. - if isStruct && t.NumFields() == 0 && t.Sym() != nil && t.Sym().Name == "align64" && isSyncAtomic(t.Sym().Pkg) { + if isStruct && t.NumFields() == 0 && t.Sym() != nil && t.Sym().Name == "align64" && isAtomicStdPkg(t.Sym().Pkg) { maxalign = 8 } lastzero := int64(0) @@ -231,8 +231,9 @@ func calcStructOffset(errtype *Type, t *Type, o int64, flag int) int64 { return o } -func isSyncAtomic(p *Pkg) bool { - return p.Prefix == "sync/atomic" || p.Prefix == `""` && base.Ctxt.Pkgpath == "sync/atomic" +func isAtomicStdPkg(p *Pkg) bool { + return (p.Prefix == "sync/atomic" || p.Prefix == `""` && base.Ctxt.Pkgpath == "sync/atomic") || + (p.Prefix == "runtime/internal/atomic" || p.Prefix == `""` && base.Ctxt.Pkgpath == "runtime/internal/atomic") } // CalcSize calculates and stores the size and alignment for t. diff --git a/src/runtime/internal/atomic/types.go b/src/runtime/internal/atomic/types.go index d9cffbf88f..d346a76b67 100644 --- a/src/runtime/internal/atomic/types.go +++ b/src/runtime/internal/atomic/types.go @@ -49,9 +49,12 @@ func (i *Int32) Add(delta int32) int32 { // Int64 is an atomically accessed int64 value. // +// 8-byte aligned on all platforms, unlike a regular int64. +// // An Int64 must not be copied. type Int64 struct { noCopy noCopy + _ align64 value int64 } @@ -242,9 +245,12 @@ func (u *Uint32) Add(delta int32) uint32 { // Uint64 is an atomically accessed uint64 value. // +// 8-byte aligned on all platforms, unlike a regular uint64. +// // A Uint64 must not be copied. type Uint64 struct { noCopy noCopy + _ align64 value uint64 } @@ -346,9 +352,11 @@ func (u *Uintptr) Add(delta uintptr) uintptr { // Float64 is an atomically accessed float64 value. // +// 8-byte aligned on all platforms, unlike a regular float64. +// // A Float64 must not be copied. type Float64 struct { - // Inherits noCopy from Uint64. + // Inherits noCopy and align64 from Uint64. u Uint64 } @@ -416,3 +424,8 @@ type noCopy struct{} // Lock is a no-op used by -copylocks checker from `go vet`. func (*noCopy) Lock() {} func (*noCopy) Unlock() {} + +// align64 may be added to structs that must be 64-bit aligned. +// This struct is recognized by a special case in the compiler +// and will not work if copied to any other package. +type align64 struct{}