Skip to content
← Prism
Prism
Overview
Features
defer orelse zeroinit raw bounds-check auto-unreachable auto-static check
C in practice
goto skips init tag namespace struct padding strict aliasing char signedness signed overflow VLAs
Spec Draft Releases Blog
GitHub ↗

checkrun cppcheck or clang-tidy on Prism sources

Prepend prism check to the analyzer command you already run. Source arguments are swapped for transpiled standard-C artifacts, everything else passes through verbatim, and findings cite your original source lines.

added in: v1.1.5

#Overview

A C static analyzer cannot read Prism source. Point CppCheck at a file containing orelse and it stops at the first keyword with an unknownMacro configuration error, because orelse is not C.

prism check wraps the analyzer the same way CC=prism wraps your compiler. It transpiles the .c and .i arguments to standard C, runs the tool against those artifacts, and preserves the tool's exit code so it still works as a build gate. The emitted #line directives do the rest: every finding maps back to the line you wrote.

prism check cppcheck --enable=all src.c
# src.c:12:4: error: Array 'arr[8]' accessed at index 8, out of bounds

The finding cites src.c line 12, not a line in the generated artifact.

#Usage

Anything after the tool name is passed through untouched, including the analyzer's own -- separator:

prism check cppcheck --enable=all src.c
prism check clang-tidy src.c -- -I include

Prism's own flags go before check, and still apply to the transpile:

prism -fno-zeroinit check cppcheck src.c

#How the artifact is shaped

Two of Prism's defaults would blind an analyzer, so check turns them off for the analysis artifact only:

This affects the analysis artifact and nothing else. Your shipping build keeps both features on.

#Bugs only the expansion shows

Analyzing the transpiled output is stronger than analyzing the source, because the expansion contains the real control flow. Cleanup that defer schedules becomes ordinary C statements on every exit path, and the analyzer can finally reason about it.

Consider a manual close alongside a deferred one:

FILE *f = fopen(path, "r") orelse return -1;
defer fclose(f);

if (bad) {
    fclose(f);   // and then the defer runs too
    return -1;
}

CppCheck reports it:

src.c:14:9: error: doubleFree: Resource handle 'f' freed twice

No source-level C analyzer finds this on its own, because none of them parse defer. The bug is only visible once the cleanup is lowered to the exit paths it actually runs on.

#Doing it by hand

If you want the artifact itself, check is equivalent to transpiling with the two flags above and running the tool yourself:

prism transpile -fno-flatten-headers -fno-bounds-check src.c > build/src.c
cppcheck --enable=all build/src.c

#Caveats

#Spec Reference

CLI modes: Prism Spec §8