diff --git a/tools/checklocks/analysis.go b/tools/checklocks/analysis.go index 62a32d099..16c54884d 100644 --- a/tools/checklocks/analysis.go +++ b/tools/checklocks/analysis.go @@ -140,6 +140,10 @@ func (pc *passContext) checkAtomicCall(inst ssa.Instruction, obj types.Object, a } return } + if fn.Signature.Recv() != nil { + // always allow calls to methods of atomic wrappers such as atomic.Int32 introduced in Go 1.19 + return + } if ar == nonAtomic { // We are *not* expecting an atomic dispatch. if _, ok := pc.forced[pc.positionKey(inst.Pos())]; !ok { diff --git a/tools/checklocks/test/atomics.go b/tools/checklocks/test/atomics.go index 8e060d8a2..851d6772f 100644 --- a/tools/checklocks/test/atomics.go +++ b/tools/checklocks/test/atomics.go @@ -27,6 +27,8 @@ type atomicStruct struct { // +checklocksignore ignored int32 + + wrapper atomic.Int32 // safe without any annotations } func testNormalAccess(tc *atomicStruct, v chan int32, p chan *int32) { @@ -89,3 +91,9 @@ func testAtomicMixedInvalidAtomicWrite(tc *atomicMixedStruct, v chan int32, p ch func testAtomicMixedInvalidWrite(tc *atomicMixedStruct, v chan int32, p chan *int32) { tc.accessedMixed = 1 // +checklocksfail:2 } + +func testAtomicWrapper(tc *atomicStruct, v chan int32) { + v <- tc.wrapper.Load() + v <- tc.wrapper.Add(33) + tc.wrapper.Store(44) +}