-
Notifications
You must be signed in to change notification settings - Fork 0
Add resetgen-analyzer static analysis tool #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds resetgen-analyzer, a static analysis tool that detects missing Reset() calls before sync.Pool.Put() operations. The analyzer complements the existing resetgen code generator by providing runtime validation of proper pool usage patterns.
Key Changes:
- Adds static analyzer CLI and core detection logic for sync.Pool misuse patterns
- Implements variable tracking to match Reset() calls with Pool.Put() operations
- Includes comprehensive test suite with testdata covering various pool usage scenarios
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
go.mod |
Adds golang.org/x/tools dependency for analysis framework |
go.sum |
Dependency checksums for new analyzer dependencies |
cmd/resetgen-analyzer/main.go |
CLI entry point using singlechecker for standalone/go vet integration |
cmd/resetgen-analyzer/analyzer/analyzer.go |
Core analysis logic tracking Reset() calls and sync.Pool.Put() operations |
cmd/resetgen-analyzer/analyzer/analyzer_test.go |
Test harness using analysistest framework |
cmd/resetgen-analyzer/analyzer/testdata/src/a/a.go |
Comprehensive test cases covering good/bad pool usage patterns |
README.md |
Documentation for both tools with installation, usage, and examples |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| bufferPool.Put(w.buf) // want "sync.Pool.Put\\(\\) called without Reset\\(\\) on w" | ||
| } | ||
|
|
||
| // Generic pool wrapper that handles Reset internally - should NOT trigger |
Copilot
AI
Dec 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment "should NOT trigger" is misleading. The analyzer currently doesn't analyze the body of genericPool.Put() to see if it calls Reset() internally. The line at 112 doesn't trigger an error only because genericPool is not a sync.Pool type - it's a custom Pool[T] type. The analyzer only checks for direct sync.Pool.Put() calls. This should be clarified in the comment to avoid confusion about what the analyzer actually does versus what it's supposed to do.
| // Generic pool wrapper that handles Reset internally - should NOT trigger | |
| // Generic pool wrapper that handles Reset internally. | |
| // NOTE: The analyzer does NOT analyze the body of genericPool.Put() to see if it calls Reset(). | |
| // The line below does NOT trigger an error only because genericPool is not a sync.Pool type. | |
| // The analyzer only checks for direct sync.Pool.Put() calls. |
|
|
||
| buf.data = encodeJSON(buf.data, v) | ||
| _, err := dst.Write(buf.data) | ||
|
|
Copilot
AI
Dec 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This example has a bug: the buffer is returned to the pool at line 175 without calling buf.Reset() first. This violates the pattern that the resetgen-analyzer is designed to detect. The code should be:
buf.Reset()
bufPool.Put(buf)
Or alternatively, since this uses the generic Pool wrapper that calls Reset() internally (line 152), the comment should clarify that Reset() is handled by the wrapper's Put method.
| buf.Reset() |
| | Global pool | `bufferPool.Put(buf)` without `buf.Reset()` | | ||
| | Struct field pool | `s.pool.Put(buf)` without `buf.Reset()` | | ||
| | Wrapped variable | `pool.Put(w.buf)` without `w.buf.Reset()` | | ||
| | Pool wrapper | `p.p.Put(v)` without `v.Reset()` inside wrapper method | |
Copilot
AI
Dec 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "Pool wrapper" pattern description is misleading. The current analyzer implementation doesn't actually analyze what happens inside wrapper methods. It only detects direct sync.Pool.Put() calls. So p.p.Put(v) is detected because p.p is a sync.Pool, not because it's inside a wrapper method. The analyzer would flag this even if Reset() was called elsewhere in the same method. Consider clarifying this documentation to accurately reflect what the analyzer does versus what it's intended to catch.
| | Pool wrapper | `p.p.Put(v)` without `v.Reset()` inside wrapper method | | |
| | Pool wrapper | `p.p.Put(v)` without `v.Reset()` (analyzer does not check if inside wrapper method or if Reset is called elsewhere) | |
Summary
Adds
resetgen-analyzer- a static analyzer that detects missingReset()calls beforesync.Pool.Put().Features
sync.Pool.Put(x)without precedingx.Reset()p.p.Put(v)withoutv.Reset())go vet -vettoolInstallation
go install github.com/flaticols/resetgen/cmd/resetgen-analyzer@latest # or go get -tool github.com/flaticols/resetgen/cmd/resetgen-analyzerUsage
Files
cmd/resetgen-analyzer/main.go- CLI entry pointcmd/resetgen-analyzer/analyzer/- Core analysis logic with tests