https://github.com/ericsssan/zbc
A deep static analyzer for Zig.
https://github.com/ericsssan/zbc
lifetimes linter memory-safety ownership static-analysis zig
Last synced: 9 days ago
JSON representation
A deep static analyzer for Zig.
- Host: GitHub
- URL: https://github.com/ericsssan/zbc
- Owner: ericsssan
- License: mit
- Created: 2026-05-20T17:12:44.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-06-11T15:28:34.000Z (about 1 month ago)
- Last Synced: 2026-07-16T02:33:59.136Z (9 days ago)
- Topics: lifetimes, linter, memory-safety, ownership, static-analysis, zig
- Language: Zig
- Size: 2.2 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# zbc
Infers Zig lifetime, ownership, and cleanup bugs from your code — no
annotations, no runtime instrumentation.
## Example
```zig
const Owner = struct {
data: []u8,
pub fn deinit(self: *Owner, gpa: Allocator) void { gpa.free(self.data); }
};
var owner = Owner{ .data = try gpa.alloc(u8, 16) };
const x = owner.data;
owner.deinit(gpa); // frees self.data — zbc reads the body to know this
_ = x; // → heap-use-after-free
```
## Build integration
```sh
zig fetch --save https://github.com/ericsssan/zbc/archive/refs/tags/v0.1.0.tar.gz
```
```zig
// build.zig
const zbc_dep = b.dependency("zbc", .{
.target = target,
.optimize = .ReleaseFast,
});
const zbc_run = b.addRunArtifact(zbc_dep.artifact("zbc"));
zbc_run.addArg("src/");
b.default_step.dependOn(&zbc_run.step);
```
## CLI
For standalone use:
```sh
zig build -Doptimize=ReleaseFast
zbc src/
zbc --format=compact src/ # grep-friendly
zbc --list-rules
zbc --explain
```
Exit 0 if clean, 1 if problems found.
## Rules
45 rules in two families:
**Flow analysis** — must-not-escape / must-not-free-twice guarantees via
per-fn CFG and abstract interpretation:
`heap-use-after-free`, `heap-double-free`, `arena-use-after-kill`,
`arena-escape`, `stack-escape`, `use-undefined`, `allocator-mismatch`,
`interior-pointer-destroy`
**Pattern detectors** — catches recurring bug shapes from real Zig PRs:
- Heap leak / aliasing: `heap-leak`, `partial-union-write`,
`aliased-heap-dupe`, `clobbered-by-struct-reset`, `realloc-byte-count`,
`asymmetric-field-free`, `free-without-null-then-check`,
`overwrite-without-deinit`
- Error-path cleanup: `missing-errdefer-between-tries`,
`free-then-try-realloc`, `destroy-after-deinit-in-loop`,
`dead-errdefer-in-result-fn`, `duplicate-errdefer`,
`missing-errdefer-on-out-param`, `unreleased-refs-on-error`,
`unreleased-factory-handle`
- Pointer / slice stability: `hashmap-getptr-rehash`,
`arraylist-items-slice`, `fd-write-after-close`,
`stack-fallback-escape`, `slice-of-arena-into-heap`,
`borrowed-slice-into-out-param`,
`borrowed-slice-into-stack-buffer-returned`,
`memset-undef-after-len-truncation`,
`sentinel-strip-free-size-mismatch`
- Tagged-union semantics: `tagged-union-retag-with-old-payload-read`,
`union-deinit-without-inert-reset`, `self-undefined-after-destroy`,
`return-borrowed-payload`
- Lifecycle / sibling consistency: `reset-skips-pooled-resource-release`,
`missing-deinit-on-composed-owner`, `owned-field-no-outer-cleanup`,
`deinit-order-violates-construction-dep`,
`defer-and-errdefer-free-overlap`, `move-out-without-restore`
- Concurrency / hardening: `publish-then-touch-self`,
`assert-on-untrusted-input`
`zbc --explain ` prints the rationale, canonical bug, and fix.
## False positives and missed bugs
If zbc fires on correct code (false positive) or misses a real bug (false
negative), please [open an issue](https://github.com/ericsssan/zbc/issues)
with a minimal reproducer. Both matter — FP reports drive suppression
improvements, FN reports drive new rules and deeper inference.
## Suppressions
Silence a false positive with a source comment:
```zig
buf[idx - 1] // zbc-disable-line: index-minus-one-without-zero-guard
// zbc-disable-next-line: heap-use-after-free
_ = ptr;
_ = val; // zbc-disable-line: * (all rules on this line)
```
## Sponsor
If zbc saves you debugging time, consider [sponsoring development](https://github.com/sponsors/ericsssan).
## Acknowledgements
- [ZLS](https://github.com/zigtools/zls) — type-resolution internals
(`DocumentStore`, `InternPool`, `Analyser`) extracted and adapted into
`src/type_engine/` as zbc's embedded type engine. Not imported as a
package; vendored and modified in-tree.