diff --git a/go/analysis/passes/atomicalign/atomicalign.go b/go/analysis/passes/atomicalign/atomicalign.go index d3fc3e2d..0326bf53 100644 --- a/go/analysis/passes/atomicalign/atomicalign.go +++ b/go/analysis/passes/atomicalign/atomicalign.go @@ -21,7 +21,7 @@ import ( var Analyzer = &analysis.Analyzer{ Name: "atomicalign", - Doc: "check for non-64-bits-aligned arguments to sync/atomic functions", + Doc: "check for non-64-bit-aligned arguments to sync/atomic functions", Requires: []*analysis.Analyzer{inspect.Analyzer}, Run: run, } @@ -70,7 +70,7 @@ func run(pass *analysis.Pass) (interface{}, error) { } func check64BitAlignment(pass *analysis.Pass, funcName string, arg ast.Expr) { - // Checks the argument is made of the address operator (&) applied to + // Checks the argument is made of the address operator (&) applied // to a struct field (as opposed to a variable as the first word of // uint64 and int64 variables can be relied upon to be 64-bit aligned. unary, ok := arg.(*ast.UnaryExpr) @@ -80,16 +80,18 @@ func check64BitAlignment(pass *analysis.Pass, funcName string, arg ast.Expr) { // Retrieve the types.Struct in order to get the offset of the // atomically accessed field. - sel, ok := unary.X.(*ast.SelectorExpr) + selector, ok := unary.X.(*ast.SelectorExpr) if !ok { return } - tvar, ok := pass.TypesInfo.Selections[sel].Obj().(*types.Var) + + sel := pass.TypesInfo.Selections[selector] + tvar, ok := sel.Obj().(*types.Var) if !ok || !tvar.IsField() { return } - stype, ok := pass.TypesInfo.Types[sel.X].Type.Underlying().(*types.Struct) + stype, ok := sel.Recv().Underlying().(*types.Struct) if !ok { return } diff --git a/go/analysis/passes/atomicalign/testdata/src/a/a.go b/go/analysis/passes/atomicalign/testdata/src/a/a.go index 45dd73d3..7aa7278e 100644 --- a/go/analysis/passes/atomicalign/testdata/src/a/a.go +++ b/go/analysis/passes/atomicalign/testdata/src/a/a.go @@ -228,3 +228,22 @@ func embeddedStructFields() { atomic.AddUint64(&s1.b, 9) // want "address of non 64-bit aligned field .b passed to atomic.AddUint64" atomic.AddInt64(&s1.c, 9) } + +type t struct { + _ int32 + a int64 + _ int16 + _ int16 + b uint64 +} + +func (t *t) structPointerReceiver() { + atomic.LoadInt64(&t.a) // want "address of non 64-bit aligned field .a passed to atomic.LoadInt64" + atomic.LoadUint64(&t.b) +} + +func structPointer() { + t := &t{} + atomic.StoreInt64(&t.a, -1) // want "address of non 64-bit aligned field .a passed to atomic.StoreInt64" + atomic.StoreUint64(&t.b, 1) +}