Penguin - 2026-10-01

Hello,

I found a preprocessing cache issue and have prepared a fix and regression test locally. Could a team member please create a Trac ticket so I can reference it in a pull request?

Issue

With --cppcheck-build-dir, unchanged input can be analyzed again on the immediate second run because the preprocessing hash depends on header load order.

I reproduced this on commit fa6c1f1327057cb8ad4764df236daf6d3c70e359, using Windows x64 and an MSVC 2022 Debug build.

Minimal reproduction

Create these three files, each ending with a newline:

z.h:

#define VALUE 1

a.h:

#undef VALUE
#define VALUE 0

test.c:

#include "z.h"
#include "a.h"
int f(void) { return 1 / VALUE; }

Create an empty directory named cache, then run the following command twice from the directory containing these files:

cppcheck -j1 -q --debug-analyzerinfo --template=simple --cppcheck-build-dir=cache test.c

Expected: The second run reuses the cached result.

Actual: The first run reports no cached result, and the second reports hash mismatch, even though the input and arguments have not changed. Both runs report the same division-by-zero diagnostic.

Cause and proposed fix

Preprocessor::calculateHash processes cached headers in load order. However, saved include information is restored in filename order. In this example, the initial order is z.h, then a.h, while the restored order is reversed.

The proposed fix sorts a temporary, non-owning pointer list by filename for hash calculation only. It does not change actual header loading, token order within files, or the persistent cache format. Existing caches may miss once and then regenerate.

Validation

The new CLI regression fails before the fix and passes afterward. It also checks source/header invalidation, subsequent cache hits, and diagnostic/exit-code equality with uncached analysis. The existing test_analyzerinfo test passes, and TestPreprocessor completes with 182 tests, zero failures, and five existing TODOs.

The full test suite has not been run. This fix does not address cache misses after removing an include.

Thank you for helping create the ticket.