Skip to content

Commit a106e63

Browse files
authored
fix(rule/modifies-value-receiver): miss modification by ++/-- (#1175)
1 parent 3e1dbc0 commit a106e63

File tree

2 files changed

+50
-25
lines changed

2 files changed

+50
-25
lines changed

rule/modifies_value_receiver.go

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func (r *ModifiesValRecRule) Apply(file *lint.File, _ lint.Arguments) []lint.Fai
2929
}
3030

3131
receiverName := receiver.Names[0].Name
32-
assignmentsToReceiver := r.getAssignmentsToReceiver(receiverName, funcDecl.Body)
32+
assignmentsToReceiver := r.getReceiverModifications(receiverName, funcDecl.Body)
3333
if len(assignmentsToReceiver) == 0 {
3434
continue // receiver is not modified
3535
}
@@ -140,38 +140,44 @@ func (r *ModifiesValRecRule) mustSkip(receiver *ast.Field, pkg *lint.Package) bo
140140
return false
141141
}
142142

143-
func (r *ModifiesValRecRule) getAssignmentsToReceiver(receiverName string, funcBody *ast.BlockStmt) []ast.Node {
144-
receiverAssignmentFinder := func(n ast.Node) bool {
145-
// look for assignments with the receiver in the right hand
146-
assignment, ok := n.(*ast.AssignStmt)
147-
if !ok {
148-
return false
149-
}
143+
func (r *ModifiesValRecRule) getReceiverModifications(receiverName string, funcBody *ast.BlockStmt) []ast.Node {
144+
receiverModificationFinder := func(n ast.Node) bool {
145+
switch node := n.(type) {
146+
case *ast.IncDecStmt:
147+
se, ok := node.X.(*ast.SelectorExpr)
148+
if !ok {
149+
return false
150+
}
150151

151-
for _, exp := range assignment.Lhs {
152-
switch e := exp.(type) {
153-
case *ast.IndexExpr: // receiver...[] = ...
154-
continue
155-
case *ast.StarExpr: // *receiver = ...
156-
continue
157-
case *ast.SelectorExpr: // receiver.field = ...
158-
name := r.getNameFromExpr(e.X)
159-
if name == "" || name != receiverName {
152+
name := r.getNameFromExpr(se.X)
153+
return name == receiverName
154+
case *ast.AssignStmt:
155+
// look for assignments with the receiver in the right hand
156+
for _, exp := range node.Lhs {
157+
switch e := exp.(type) {
158+
case *ast.IndexExpr: // receiver...[] = ...
160159
continue
161-
}
162-
case *ast.Ident: // receiver := ...
163-
if e.Name != receiverName {
160+
case *ast.StarExpr: // *receiver = ...
161+
continue
162+
case *ast.SelectorExpr: // receiver.field = ...
163+
name := r.getNameFromExpr(e.X)
164+
if name == "" || name != receiverName {
165+
continue
166+
}
167+
case *ast.Ident: // receiver := ...
168+
if e.Name != receiverName {
169+
continue
170+
}
171+
default:
164172
continue
165173
}
166-
default:
167-
continue
168-
}
169174

170-
return true
175+
return true
176+
}
171177
}
172178

173179
return false
174180
}
175181

176-
return pick(funcBody, receiverAssignmentFinder)
182+
return pick(funcBody, receiverModificationFinder)
177183
}

testdata/modifies_value_receiver.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,22 @@ func (b JailerCommandBuilder) WithBin(bin string) JailerCommandBuilder {
2828
b.bin = bin
2929
return b
3030
}
31+
32+
func (this data) incrementDecrement() {
33+
this.num++ // MATCH /suspicious assignment to a by-value method receiver/
34+
this.num-- // MATCH /suspicious assignment to a by-value method receiver/
35+
other++
36+
}
37+
38+
func (this data) assignmentOperators() {
39+
this.num += 1 // MATCH /suspicious assignment to a by-value method receiver/
40+
this.num -= 1 // MATCH /suspicious assignment to a by-value method receiver/
41+
this.num *= 1 // MATCH /suspicious assignment to a by-value method receiver/
42+
this.num /= 1 // MATCH /suspicious assignment to a by-value method receiver/
43+
this.num %= 1 // MATCH /suspicious assignment to a by-value method receiver/
44+
this.num &= 1 // MATCH /suspicious assignment to a by-value method receiver/
45+
this.num ^= 1 // MATCH /suspicious assignment to a by-value method receiver/
46+
this.num |= 1 // MATCH /suspicious assignment to a by-value method receiver/
47+
this.num >>= 1 // MATCH /suspicious assignment to a by-value method receiver/
48+
this.num <<= 1 // MATCH /suspicious assignment to a by-value method receiver/
49+
}

0 commit comments

Comments
 (0)