go.lang.correctness.looppointer.exported_loop_pointer

Author
161
Download Count*
License
$VALUE
is a loop pointer that may be exported from the loop. This pointer is shared between loop iterations, so the exported reference will always point to the last loop value, which is likely unintentional. To fix, copy the pointer to a new pointer within the loop.
Run Locally
Run in CI
Defintion
rules:
- id: exported_loop_pointer
message: "`$VALUE` is a loop pointer that may be exported from the loop. This
pointer is shared between loop iterations, so the exported reference will
always point to the last loop value, which is likely unintentional. To
fix, copy the pointer to a new pointer within the loop."
metadata:
references:
- https://github.com/kyoh86/looppointer
category: correctness
technology:
- go
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
severity: WARNING
languages:
- go
pattern-either:
- pattern: |
for _, $VALUE := range $SOURCE {
<... &($VALUE) ...>
}
- pattern: |
for _, $VALUE := range $SOURCE {
<... func() { <... &$VALUE ...> } ...>
}
- pattern: |
for _, $VALUE := range $SOURCE {
<... $ANYTHING(..., <... $VALUE ...>, ...) ...>
}
Examples
looppointer.go
func() {
values := []string{"a", "b", "c"}
var funcs []func()
// ruleid:exported_loop_pointer
for _, val := range values {
funcs = append(funcs, func() {
fmt.Println(&val)
})
}
}
func() {
// ruleid:exported_loop_pointer
for _, val := range values {
print_pointer(val)
}
}
func() {
values := []string{"a", "b", "c"}
var funcs []func()
// ok:exported_loop_pointer
for _, val := range values {
val := val // pin!
funcs = append(funcs, func() {
fmt.Println(&val)
})
}
}
Short Link: https://sg.run/709G