fix(scripts): make lint-cppcheck-dash actually report warnings - #7535
Merged
PastaPastaPasta merged 17 commits intoAug 8, 2026
Merged
Conversation
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue being fixed or feature implemented
test/lint/lint-cppcheck-dash.pyhas been effectively vacuous — it ran cppcheck, silently analyzed almost nothing, and always passed. Two failure modes:-Dlist,__GNUC__is not defined, sosrc/attributes.hhits#error No known always_inline attribute(preprocessorErrorDirective), aborting cppcheck's analysis of nearly every translation unit. The error lines were then dropped by the output filter, which only keeps lines pointing at files fromtest/util/data/non-backported.txt.--check-level=exhaustivecrashes with an assertion inTokenList::setLang(child dies with signal 6) — and that crash message was explicitly listed inSUPPRESSED_WARNINGS.Net effect: an injected canary warning in a non-backported file was not flagged, locally or in CI.
What was done?
Linter (
test/lint/lint-cppcheck-dash.py):__GNUC__so preprocessing succeeds.FATAL_ERRORSlist (preprocessorErrorDirective,syntaxError, internal errors/crashes) that fails the lint regardless of which file the line points at, so analysis failures can never again be silently filtered away. MakingsyntaxErrorfatal immediately surfaced real cases:QT_VERSION_CHECKandQT_CONFIGare function-like macros cppcheck cannot evaluate on its own, which aborted analysis of Qt translation units (especially in working trees withuic-generated headers likeui_masternodelist.h) — they are now defined on the cppcheck command line (-DQT_VERSION_CHECK=...,-DQT_CONFIG(x)=0).--error-exitcode, diagnostics never make cppcheck return nonzero, so a nonzero status always means the analysis itself failed (bad arguments, unloadable config, OOM kill, crash) and cannot be allowed to pass.note:/source-context lines: they don't carry the check id that suppressions match on, so orphaned notes of suppressed warnings leaked through the filter.knownConditionTrueFalse(always-falsestate.Invalid(...)/state.Error(...)returns),shadowFunction(the_translation function), anduninitMemberVarNoCtor(ActiveDKG/UtilParametersmembers) — so new violations of these checks elsewhere in the tree are still reported.duplInheritedMemberanduseStlAlgorithmare suppressed wholesale by check id: the former as a plain burn-down entry, the latter deliberately — earlier revisions of this branch rewrote the flagged raw loops intostd::rangesalgorithms, but lambda-based algorithms lose Clang thread-safety-analysis lock context (cs_wallet,cs_coinjoin,cs_store) and obscure otherwise-clear control flow, so the loops stay and the check is disabled instead. Messages matchingALWAYS_ENABLED_WARNINGSstill override these suppressions.Container (
contrib/containers/ci/ci-slim.Dockerfile): bump cppcheck 2.17.1 → 2.21.0, which no longer crashes under--check-level=exhaustive.Code fixes for the ~11 warnings that
ALWAYS_ENABLED_WARNINGSpatterns force-report (these cannot be suppressed by check id): removed dead locals (src/active/dkgsession.cpp,src/rpc/evo.cpp), made single-argument constructorsexplicit(chainlock::Chainlocks,CDSTXManager; no implicit-conversion call sites exist), inline-suppressedCBLSIdImplicit's intentionally implicit constructor, narrowed three static benchmark counters to their usage scope insrc/evo/specialtxman.cpp(static storage duration unchanged), passedCSigBaseby const reference inInitSession(callers already sliced identically by value; accessors are non-virtual), movedBlsCheck's by-value constructor parameters into members, and bound the temporaryRPCResultreturned byGetVotesJsonHelpto a local variable insrc/rpc/governance.cpp(avoiding a C++20 dangling reference).How Has This Been Tested?
With cppcheck 2.21.0 locally (matching the bumped container version):
unreadVariable) intosrc/spork.cpp: the linter reports exactly that warning and exits 1.-D__GNUC__to simulate failure mode 1: theattributes.h#errorline surfaces viaFATAL_ERRORSand the linter exits 1.clang -fsyntax-onlywith the project's compile flags;test/lint/lint-python.pypasses.Note: the previously-suppressed
count_if/find_ifuseStlAlgorithmvariants are now covered by the wholesale id suppression along with the rest of the burn-down list.Breaking Changes
None. CI lint may take somewhat longer since cppcheck now actually analyzes all 273 non-backported files with
--check-level=exhaustive.Checklist: