diff --git a/rule/range-val-address.go b/rule/range-val-address.go index 18554825a..ece01ddf6 100644 --- a/rule/range-val-address.go +++ b/rule/range-val-address.go @@ -77,7 +77,7 @@ func (bw rangeBodyVisitor) Visit(node ast.Node) ast.Visitor { for _, exp := range asgmt.Rhs { switch e := exp.(type) { - case *ast.UnaryExpr: // e.g. ...&value + case *ast.UnaryExpr: // e.g. ...&value, ...&value.id if bw.isAccessingRangeValueAddress(e) { bw.onFailure(bw.newFailure(e)) } @@ -100,8 +100,21 @@ func (bw rangeBodyVisitor) isAccessingRangeValueAddress(exp ast.Expr) bool { return false } + if u.Op != token.AND { + return false + } + v, ok := u.X.(*ast.Ident) - return ok && u.Op == token.AND && v.Obj == bw.valueID + if !ok { + var s *ast.SelectorExpr + s, ok = u.X.(*ast.SelectorExpr) + if !ok { + return false + } + v, ok = s.X.(*ast.Ident) + } + + return ok && v.Obj == bw.valueID } func (bw rangeBodyVisitor) newFailure(node ast.Node) lint.Failure { diff --git a/rule/string-format.go b/rule/string-format.go index a862c9a34..6017c4180 100644 --- a/rule/string-format.go +++ b/rule/string-format.go @@ -30,11 +30,12 @@ func (r *StringFormatRule) Apply(file *lint.File, arguments lint.Arguments) []li return failures } +// Name returns the rule name. func (r *StringFormatRule) Name() string { return "string-format" } -// Public wrapper around w.parseArguments used for testing, returns the error message provided to panic, or nil if no error was encountered +// ParseArgumentsTest is a public wrapper around w.parseArguments used for testing. Returns the error message provided to panic, or nil if no error was encountered func (r *StringFormatRule) ParseArgumentsTest(arguments lint.Arguments) *string { w := lintStringFormatRule{} c := make(chan interface{}) diff --git a/testdata/range-val-address.go b/testdata/range-val-address.go index 3c24ef06f..dc9f11bff 100644 --- a/testdata/range-val-address.go +++ b/testdata/range-val-address.go @@ -45,3 +45,15 @@ func rangeValAddress5() { m[&value] = value // MATCH /suspicious assignment of 'value'. range-loop variables always have the same address/ } } + +func rangeValAddress6() { + type v struct { + id string + } + m := []*string{} + + mySlice := []v{{id: "A"}, {id: "B"}, {id: "C"}} + for _, value := range mySlice { + m = append(m, &value.id) // MATCH /suspicious assignment of 'value'. range-loop variables always have the same address/ + } +}