Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,15 @@ jobs:
# check sets currently surface only false positives (GNU computed-goto
# label addresses, caller-guaranteed non-null params, defensive
# redundant-null-check heuristics), so this reports without gating.
# cppcheck runs whole-tree here (fast); the heavier clang-tidy pass
# cppcheck runs whole-tree here over one pinned configuration (see
# CPPCHECK_DEFS in the Makefile); the heavier clang-tidy pass
# (`make tidy`) runs locally and in the nightly workflow. Flip to a
# blocking gate once the baseline is annotated clean.
# blocking gate once the baseline is annotated clean. The timeout keeps a
# regression in analysis time from holding a runner for hours.
static-analysis:
runs-on: ubuntu-latest
continue-on-error: true
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- name: Install cppcheck
Expand Down
12 changes: 11 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -420,14 +420,24 @@ tidy:
clang-tidy --quiet $(FILES) -- $(TIDY_FLAGS)

# cppcheck is a second-opinion linter — advisory only, never a gate.
#
# CPPCHECK_DEFS pins ONE preprocessor configuration: the gcc / x86-64 / Linux
# debug build CI compiles. Given no -D, cppcheck enumerates the #ifdef
# combinations it finds (platform, DEBUG, endianness, fuzzing) and analyses
# each file up to 12 times — most files hit that cap, which is what made
# the whole-tree pass take ~50 minutes. Undefined macros stay undefined, so
# the Windows/macOS/WASM branches are not analysed here; every Linux file is.
CPPCHECK_DEFS = -D__linux__ -D__GNUC__ -D__x86_64__ -D__SIZEOF_INT128__=16 \
-D__ORDER_LITTLE_ENDIAN__=1234 -D__BYTE_ORDER__=1234 -D__GLIBC__ -DDEBUG

cppcheck:
@command -v cppcheck >/dev/null || { echo "cppcheck: not found"; exit 1; }
cppcheck --enable=warning,portability --inline-suppr --error-exitcode=1 \
-j $(shell nproc 2>/dev/null || echo 4) \
--suppress=missingIncludeSystem \
--suppress=assignBoolToPointer \
--suppress=nullPointerRedundantCheck \
--std=c17 -q $(INCLUDES) src/
--std=c17 -q $(CPPCHECK_DEFS) $(INCLUDES) src/
# assignBoolToPointer: cppcheck misparses the GNU computed-goto label
# address `&&label` (a void*) as a logical-AND yielding a bool.
# nullPointerRedundantCheck: a heuristic that fires on the codebase's
Expand Down
Loading