XPerf
LanguagesC

cperf-lint

Heuristic checker for C/C++ sources, implemented in C11 (no libclang). Expect false positives.

Build

cd packages/cperf/cperf-lint
make          # → ./cperf-lint
# or: ./build.sh

Rules (v0)

IDapp/engineallSummaryFP / suppress notes
cp-alloc-hoterrorerrormalloc/calloc/realloc inside a for/while/do bodyEvidence ../evidence/cp-alloc-hot.*; thin return wrappers skipped; same-line *2/<<1 realloc skipped
cp-realloc-grow-oneerrorerrorrealloc(p, … + 1) / old+1 style growthEvidence ../evidence/cp-realloc-grow-one.*; best-effort scan of 2nd arg
cp-printf-hotofferrorprintf / fprintf / puts in a loop body windowG3 demote (OK-idiom on corpora); dump/debug/#if 0 suppressions; --severity cp-printf-hot=hint
cp-strlen-in-condhinterrorstrlen( in for/while conditionHoist length; corpus TPs on quickjs intl + gcc attribs
cp-strcat-hotofferrorstrcat/strncat in loop bodyG3 demote (CLI/path OK-idiom); --severity cp-strcat-hot=hint; macro \ skipped
cp-sprintf-hothinterrorformatted buffer write in a loop bodyJSONL present; stays hint; not corpus-triaged
cp-fopen-hothinterrorfile open in a loop bodyJSONL present; stays hint; not corpus-triaged
cp-gettime-hothinterrorclock sample in a loop bodybare time is not matched; JSONL present; stays hint; not corpus-triaged
cp-wide-bool-flagshinterrorfour or more full-width boolean flags in one structno bit-field in that struct; JSONL present; stays hint; not corpus-triaged
cp-regex-hothinterrorregcomp in a loop bodyregexec is not matched; JSONL about 9.7×; stay hint; not corpus-triaged

Usage

./cperf-lint PATH... [--format text|json] [--preset app|engine|all]
./cperf-lint PATH... --severity cp-printf-hot=off --severity cp-alloc-hot=hint
./cperf-lint PATH... --strict-hints    # hints also fail exit code
./cperf-lint PATH... --no-fail
./cperf-lint --version

Default --preset app (=engine): cp-alloc-hot/cp-realloc-grow-one error (evidence-gated); cp-strlen-in-cond, cp-sprintf-hot, cp-fopen-hot, cp-gettime-hot, cp-wide-bool-flags, and cp-regex-hot hint; cp-printf-hot/cp-strcat-hot off. Unknown slugs stay hint. See ../docs/evidence-policy.md. --severity applies after the preset.

Text lines look like path:line: error cp-alloc-hot: … or … hint cp-printf-hot: …. JSON includes a "severity" field. off rules are omitted.

Exit 0 if clean, or only hints (unless --strict-hints). Exit 1 on any error-severity finding. Exit 2 on usage/IO errors. --no-fail forces 0 for findings.

Self-lint (mandatory dogfood)

make self-lint   # runs ./cperf-lint on src/ + include/; expects 0 findings
make test        # smoke fixtures + preset checks + self-lint

Fixtures

fixtures/good should be silent; fixtures/bad should emit the matching rule ids. Under default app, the bad tree exits 1 because cp-alloc-hot/cp-realloc-grow-one are error; cp-strlen-in-cond, the 2026-10-23 hints, and cp-regex-hot are hint (exit 0 unless --strict-hints or --severity RULE=error); cp-printf-hot/cp-strcat-hot need --preset all or --severity.

Dogfood corpora: ../docs/corpus.md.

Evidence

Measured gates: ../evidence/cp-alloc-hot.md, cp-realloc-grow-one.md, cp-printf-hot.md. Policy: ../docs/evidence-policy.md.