}
// 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)
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.
// 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
}
// 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
}
// 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
}
// 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{}