Skip to content

Commit

Permalink
range-val-address: improve detection (#647)
Browse files Browse the repository at this point in the history
  • Loading branch information
bernhardreisenberger committed Mar 12, 2022
1 parent 577441d commit f335f97
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 2 deletions.
22 changes: 20 additions & 2 deletions rule/range-val-address.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,34 @@ func (bw rangeBodyVisitor) Visit(node ast.Node) ast.Visitor {
case *ast.CallExpr:
if fun, ok := e.Fun.(*ast.Ident); ok && fun.Name == "append" { // e.g. ...append(arr, &value)
for _, v := range e.Args {
if bw.isAccessingRangeValueAddress(v) {
bw.onFailure(bw.newFailure(e))
if lit, ok := v.(*ast.CompositeLit); ok { // e.g. ...append(arr, v{id:&value})
bw.checkCompositeLit(lit)
continue
}
if bw.isAccessingRangeValueAddress(v) { // e.g. ...append(arr, &value)
bw.onFailure(bw.newFailure(v))
}
}
}
case *ast.CompositeLit: // e.g. ...v{id:&value}
bw.checkCompositeLit(e)
}
}
return bw
}

func (bw rangeBodyVisitor) checkCompositeLit(comp *ast.CompositeLit) {
for _, exp := range comp.Elts {
e, ok := exp.(*ast.KeyValueExpr)
if !ok {
continue
}
if bw.isAccessingRangeValueAddress(e.Value) {
bw.onFailure(bw.newFailure(e.Value))
}
}
}

func (bw rangeBodyVisitor) isAccessingRangeValueAddress(exp ast.Expr) bool {
u, ok := exp.(*ast.UnaryExpr)
if !ok {
Expand Down
23 changes: 23 additions & 0 deletions testdata/range-val-address.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,26 @@ func rangeValAddress13() {
m = append(m, &value.id)
}
}

func rangeValAddress14() {
type v struct {
id *string
}

m := []v{}
for _, value := range []string{"A", "B", "C"} {
a := v{id: &value} // MATCH /suspicious assignment of 'value'. range-loop variables always have the same address/
m = append(m, a)
}
}

func rangeValAddress15() {
type v struct {
id *string
}

m := []v{}
for _, value := range []string{"A", "B", "C"} {
m = append(m, v{id: &value}) // MATCH /suspicious assignment of 'value'. range-loop variables always have the same address/
}
}

0 comments on commit f335f97

Please sign in to comment.