Skip to content

Commit f335f97

Browse files
range-val-address: improve detection (#647)
1 parent 577441d commit f335f97

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

rule/range-val-address.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,16 +95,34 @@ func (bw rangeBodyVisitor) Visit(node ast.Node) ast.Visitor {
9595
case *ast.CallExpr:
9696
if fun, ok := e.Fun.(*ast.Ident); ok && fun.Name == "append" { // e.g. ...append(arr, &value)
9797
for _, v := range e.Args {
98-
if bw.isAccessingRangeValueAddress(v) {
99-
bw.onFailure(bw.newFailure(e))
98+
if lit, ok := v.(*ast.CompositeLit); ok { // e.g. ...append(arr, v{id:&value})
99+
bw.checkCompositeLit(lit)
100+
continue
101+
}
102+
if bw.isAccessingRangeValueAddress(v) { // e.g. ...append(arr, &value)
103+
bw.onFailure(bw.newFailure(v))
100104
}
101105
}
102106
}
107+
case *ast.CompositeLit: // e.g. ...v{id:&value}
108+
bw.checkCompositeLit(e)
103109
}
104110
}
105111
return bw
106112
}
107113

114+
func (bw rangeBodyVisitor) checkCompositeLit(comp *ast.CompositeLit) {
115+
for _, exp := range comp.Elts {
116+
e, ok := exp.(*ast.KeyValueExpr)
117+
if !ok {
118+
continue
119+
}
120+
if bw.isAccessingRangeValueAddress(e.Value) {
121+
bw.onFailure(bw.newFailure(e.Value))
122+
}
123+
}
124+
}
125+
108126
func (bw rangeBodyVisitor) isAccessingRangeValueAddress(exp ast.Expr) bool {
109127
u, ok := exp.(*ast.UnaryExpr)
110128
if !ok {

testdata/range-val-address.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,26 @@ func rangeValAddress13() {
138138
m = append(m, &value.id)
139139
}
140140
}
141+
142+
func rangeValAddress14() {
143+
type v struct {
144+
id *string
145+
}
146+
147+
m := []v{}
148+
for _, value := range []string{"A", "B", "C"} {
149+
a := v{id: &value} // MATCH /suspicious assignment of 'value'. range-loop variables always have the same address/
150+
m = append(m, a)
151+
}
152+
}
153+
154+
func rangeValAddress15() {
155+
type v struct {
156+
id *string
157+
}
158+
159+
m := []v{}
160+
for _, value := range []string{"A", "B", "C"} {
161+
m = append(m, v{id: &value}) // MATCH /suspicious assignment of 'value'. range-loop variables always have the same address/
162+
}
163+
}

0 commit comments

Comments
 (0)