fold/docs/internal/code-quality-detector-opportunities.md
trvon 27bb4d807f
docs: code quality detector opportunities — API misuse, exception safety, concurrency, deprecated APIs
- 12 detector ideas across 4 categories
- Phase 1 (S effort): deprecated APIs, throwing dtors, missing noexcept
- Phase 2 (M-L): use-after-move, iterator invalidation, lock inversion
- All phase 1 detectors are syntactic (RecursiveASTVisitor, no Z3 needed)
2026-05-29 10:03:25 -04:00

94 lines
2.6 KiB
Markdown

# Code Quality Detector Opportunities for fold
> Generated 2026-05-29. Research on non-memory-safety detectors fold could add.
## API Misuse Detectors
### 1. Missing std::move on return (Z3)
```cpp
// BAD: copies unnecessarily
std::string foo() {
std::string s = build();
return s; // copy — should be std::move(s) or RVO
}
```
Z3 query: prove that a local variable is returned without move and without RVO eligibility.
### 2. Use-after-move (Z3)
```cpp
// BAD: reading moved-from value
auto x = std::move(y);
y.size(); // UB: y was moved
```
Z3 query: prove that a moved-from object is accessed on some path.
### 3. Missing std::forward (Syntactic)
```cpp
// BAD: forwarding reference not forwarded
template<typename T> void wrap(T&& x) {
foo(x); // should be foo(std::forward<T>(x))
}
```
### 4. Iterator invalidation (Z3)
```cpp
// BAD: iterator used after container mutation
auto it = v.begin();
v.push_back(42); // may invalidate it
*it = 7; // UB
```
## Exception Safety Detectors
### 5. Throwing destructor (Syntactic)
```cpp
// BAD: destructor may throw
~File() { close(); } // if close() throws, std::terminate
```
### 6. Missing noexcept on move (Syntactic)
```cpp
// BAD: move not noexcept may prevent vector growth optimization
MyType(MyType&& other) : data(other.data) {} // missing noexcept
```
## Concurrency Detectors
### 7. Data race on non-atomic (Z3)
```cpp
// BAD: unguarded shared state
int shared = 0;
// Thread A: shared++; // UB: data race
```
### 8. Lock inversion (Z3)
```cpp
// BAD: inconsistent lock ordering
std::lock(mu1, mu2); // first path
std::lock(mu2, mu1); // second path — deadlock potential
```
## Deprecated API Detection (Syntactic)
| API | Replacement | Severity |
|-----|-------------|----------|
| `std::auto_ptr` | `std::unique_ptr` | High |
| `rand()` | `<random>` | Medium |
| `gets()` | `fgets()` | Critical |
| `sprintf()` | `snprintf()` | High |
| `strcpy()` | `strncpy()` / `std::string` | High |
| `::bind()` (old API) | `::bind()` (new) | Low |
## Implementation Priority
| Priority | Detector | Effort | Expected False Positives |
|----------|----------|--------|--------------------------|
| 1 | Deprecated API (syntactic) | S | Very low |
| 2 | Throwing destructor | S | Very low |
| 3 | Missing noexcept on move | S | Low |
| 4 | Missing std::move on return | M | Medium |
| 5 | Use-after-move | L | Medium |
| 6 | Iterator invalidation | L | High |
| 7 | Lock inversion | L | High |
Phase 1-2 detectors (4 items, ~200 lines total) could be added as RecursiveASTVisitor-based syntactic detectors — no Z3 needed. This follows the same pattern as the existing `deprecated_api.cpp` detector.