Skip to content

Add clang-tidy static analysis#15

Merged
NiceAndPeter merged 2 commits into
mainfrom
clang-tidy
Jun 25, 2026
Merged

Add clang-tidy static analysis#15
NiceAndPeter merged 2 commits into
mainfrom
clang-tidy

Conversation

@NiceAndPeter

Copy link
Copy Markdown
Owner

Adds clang-tidy as a static-analysis CI gate — the layer above the sanitizers /
coverage / perf gates from the previous pass. It catches at parse/AST time what
runtime checks can't (bugprone integer/sign patterns, accidental copies, missing
moves, portability traps).

What's in it

.clang-tidy — a curated, correctness-only config. This is a bug-finding
gate, not a restyle. A broad set produced ~355 findings on a single TU, almost
all style or by-design (const-correctness, literal-suffix casing, public members
for NTTP/memcpy, intentional numeric narrowing). The config keeps
bugprone-* / performance-* / portability-* and disables only the specific
checks that are false positives or fight bound's deliberate design — each with a
one-line rationale in the file:

Disabled check Why
misc-redundant-expression fires on <L> op <R> template pairs it can't distinguish pre-instantiation (and fold-expr identity seeds) — net FP
bugprone-narrowing-conversions intentional, guarded numeric narrowing (MSVC C4244/C4305)
bugprone-signed-char-misuse i8 is a numeric raw-storage type; sign-extension is intended
bugprone-exception-escape noexcept helpers route errors through the replaceable raise() handler (traps under -fno-exceptions) by design
bugprone-branch-clone / performance-enum-size / bugprone-easily-swappable-parameters template FP / deliberate int enums / pervasive numeric pairs

The only two genuine, intentional sites left are // NOLINT'd in test code
only
(a macro-expansion inc-dec FP in test_compound_assign, deliberate
catch-alls in the fuzz harness) — no suppressions in library headers.

CI job (linux clang-tidy): configures with clang-18 + compile_commands and
runs run-clang-tidy over tests + examples, header-scoped to include/bound/.
WarningsAsErrors: '*' fails the run on any finding.

Verification

  • Full local run over tests/*.cpp + examples/*.cpp: 0 findings.
  • Gate has teeth: a planted issue (performance-for-range-copy) makes it fail.
  • No library headers changed (config + two test files only), so the single-header
    amalgamation is unaffected.

Follow-up

After this is green and merged, I'll add linux clang-tidy to the required
status checks on main (currently 18 → 19).

🤖 Generated with Claude Code

Peter Neiss and others added 2 commits June 25, 2026 11:05
A bug-finding gate, not a restyle. A broad check set produced ~355 findings on a
single TU, almost all style or by-design (const-correctness, literal-suffix
casing, public members for NTTP, intentional numeric narrowing). The curated set
keeps bugprone-*/performance-*/portability-* and disables only the specific
checks that are false positives or fight bound's deliberate design, each with a
documented rationale in the config:
  - misc-redundant-expression: fires on `<L> op <R>` template pairs it can't tell
    apart pre-instantiation (and fold-expression identity seeds) — net FP
  - bugprone-narrowing-conversions: intentional, guarded (MSVC C4244/C4305)
  - bugprone-signed-char-misuse: i8 is a numeric raw-storage type
  - bugprone-exception-escape: noexcept helpers route through the replaceable
    raise() handler (traps under -fno-exceptions) by design
  - branch-clone / enum-size / easily-swappable-parameters: FP / deliberate

The two genuine, intentional sites left are NOLINT'd in test code only (a
macro-expansion inc-dec FP in test_compound_assign, deliberate catch-alls in the
fuzz harness) — no suppressions in library headers. Full run over tests + examples
is clean (0 findings); confirmed the gate still fires on planted issues.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Dedicated job (clang-18) that configures with compile_commands and runs
run-clang-tidy over the test + example TUs, scoping header diagnostics to
include/bound/. WarningsAsErrors in .clang-tidy makes any finding fail the run;
no build step needed since clang-tidy parses from the compile database.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@NiceAndPeter
NiceAndPeter merged commit 6ee4f75 into main Jun 25, 2026
21 checks passed
@NiceAndPeter
NiceAndPeter deleted the clang-tidy branch June 25, 2026 09:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant