[checklocks] Support iterators
- Dominant language
- Go
- Stars
- 19.3k
- Forks
- 2k
- Avg merge
- 3d 5h
- Merged PRs (30d)
- 264
Description
### Description
Currently locked access to struct members inside a loop over an [iterator](https://pkg.go.dev/iter) is not detected correctly.
Example:
```golang
package main
import (
"strings"
"sync"
)
type Entries struct {
mu sync.Mutex
// +checklocks:mu
entries []string
}
func (e *Entries) Add(s string) {
e.mu.Lock()
defer e.mu.Unlock()
for item := range strings.SplitSeq(s, " ") {
e.entries = append(e.entries, item)
}
}
```
Error:
```
go vet -vettool=$HOME/go/bin/checklocks iter_seq_checklocks.go
# command-line-arguments
./iter_seq_checklocks.go:19:24: invalid field access, mu (&({freevar:e}.mu)) must be locked when accessing entries (locks: no locks held)
./iter_seq_checklocks.go:19:5: invalid field access, mu (&({freevar:e}.mu)) must be locked when accessing entries (locks: no locks held)
```
This works if the lock is acquired inside the loop.
```golang
func (e *Entries) Add(s string) {
for item := range strings.SplitSeq(s, " ") {
e.mu.Lock()
e.entries = append(e.entries, item)
e.mu.Unlock()
}
}
```
### Is this feature related to a specific bug?
_No response_
### Do you have a specific solution in mind?
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.