From a9f48d0dab851b9a7805153adb6b4bb8464fd84c Mon Sep 17 00:00:00 2001 From: firewave Date: Fri, 31 Oct 2025 13:02:31 +0100 Subject: [PATCH 1/8] ignore all other suppressions when `UNUSEDFUNCTION_ONLY` hack is active / selfcheck.yml: enabled `information` messages --- .github/workflows/selfcheck.yml | 19 ++++++------------- cli/cppcheckexecutor.cpp | 22 +++++++++++++++++----- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/.github/workflows/selfcheck.yml b/.github/workflows/selfcheck.yml index f667dc78451..190ca4f31ab 100644 --- a/.github/workflows/selfcheck.yml +++ b/.github/workflows/selfcheck.yml @@ -16,7 +16,6 @@ permissions: contents: read jobs: - # TODO: enable information build: runs-on: ubuntu-22.04 @@ -77,11 +76,10 @@ jobs: # make sure the auto-generated GUI dependencies exist make -C cmake.output gui-build-deps - # TODO: find a way to report unmatched suppressions without need to add information checks - name: Self check (unusedFunction) if: false # TODO: fails with preprocessorErrorDirective - see #10667 run: | - ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction --exception-handling -rp=. --project=cmake.output/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr + ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr env: DISABLE_VALUEFLOW: 1 UNUSEDFUNCTION_ONLY: 1 @@ -103,10 +101,9 @@ jobs: # make sure the auto-generated GUI dependencies exist make -C cmake.output.notest gui-build-deps - # TODO: find a way to report unmatched suppressions without need to add information checks - name: Self check (unusedFunction / no test) run: | - ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.notest/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr + ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.notest/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr env: DISABLE_VALUEFLOW: 1 UNUSEDFUNCTION_ONLY: 1 @@ -122,10 +119,9 @@ jobs: # make sure the precompiled headers exist make -C cmake.output.notest_nogui lib/CMakeFiles/cppcheck-core.dir/cmake_pch.hxx.cxx - # TODO: find a way to report unmatched suppressions without need to add information checks - name: Self check (unusedFunction / no test / no gui) run: | - ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib -D__CPPCHECK__ -D__GNUC__ --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.notest_nogui/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr + ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib -D__CPPCHECK__ -D__GNUC__ --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.notest_nogui/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr env: DISABLE_VALUEFLOW: 1 UNUSEDFUNCTION_ONLY: 1 @@ -145,11 +141,10 @@ jobs: # make sure the auto-generated GUI dependencies exist make -C cmake.output.notest_nocli gui-build-deps - # TODO: find a way to report unmatched suppressions without need to add information checks - name: Self check (unusedFunction / no test / no cli) if: false # TODO: the findings are currently too intrusive run: | - ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.notest_nocli/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr + ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.notest_nocli/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr env: DISABLE_VALUEFLOW: 1 UNUSEDFUNCTION_ONLY: 1 @@ -165,11 +160,10 @@ jobs: # make sure the precompiled headers exist make -C cmake.output.notest_nocli_nogui lib/CMakeFiles/cppcheck-core.dir/cmake_pch.hxx.cxx - # TODO: find a way to report unmatched suppressions without need to add information checks - name: Self check (unusedFunction / no test / no cli / no gui) if: false # TODO: the findings are currently too intrusive run: | - ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.notest_nocli_nogui/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr + ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.notest_nocli_nogui/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr env: DISABLE_VALUEFLOW: 1 UNUSEDFUNCTION_ONLY: 1 @@ -193,11 +187,10 @@ jobs: # make sure the auto-generated GUI dependencies exist make -C cmake.output.corpus gui-build-deps - # TODO: find a way to report unmatched suppressions without need to add information checks - name: Self check (unusedFunction / corpus / no test / callgrind) run: | # TODO: fix -rp so the suppressions actually work - valgrind --tool=callgrind ./cppcheck --template=selfcheck --error-exitcode=0 --library=cppcheck-lib --library=qt -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.corpus/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr 2>callgrind.log || (cat callgrind.log && false) + valgrind --tool=callgrind ./cppcheck --template=selfcheck --error-exitcode=0 --library=cppcheck-lib --library=qt -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.corpus/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr 2>callgrind.log || (cat callgrind.log && false) cat callgrind.log callgrind_annotate --auto=no > callgrind.annotated.log head -50 callgrind.annotated.log diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 54d83ee4789..8baab2ed78e 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -339,27 +339,39 @@ bool CppCheckExecutor::reportUnmatchedSuppressions(const Settings &settings, con assert(!(!files.empty() && !fileSettings.empty())); // bail out if there is a suppression of unmatchedSuppression which matches any file - const auto suppr = suppressions.getSuppressions(); + auto suppr = suppressions.getSuppressions(); if (std::any_of(suppr.cbegin(), suppr.cend(), [](const SuppressionList::Suppression& s) { return s.errorId == "unmatchedSuppression" && (s.fileName.empty() || s.fileName == "*") && s.lineNumber == SuppressionList::Suppression::NO_LINE; })) return false; + SuppressionList supprlist; + + const char* unusedFunctionOnly = std::getenv("UNUSEDFUNCTION_ONLY"); + const bool doUnusedFunctionOnly = unusedFunctionOnly && (std::strcmp(unusedFunctionOnly, "1") == 0); + // ignore all other suppressions if we use the unusedFunction hack + for (auto&& s : suppr) + { + if (doUnusedFunctionOnly && s.errorId != "unusedFunction") + continue; + supprlist.addSuppression(std::move(s)); + } + bool err = false; for (auto i = files.cbegin(); i != files.cend(); ++i) { - err |= ::reportUnmatchedSuppressions(suppressions.getUnmatchedLocalSuppressions(*i), errorLogger, settings.unmatchedSuppressionFilters); + err |= ::reportUnmatchedSuppressions(supprlist.getUnmatchedLocalSuppressions(*i), errorLogger, settings.unmatchedSuppressionFilters); } for (auto i = fileSettings.cbegin(); i != fileSettings.cend(); ++i) { - err |= ::reportUnmatchedSuppressions(suppressions.getUnmatchedLocalSuppressions(i->file), errorLogger, settings.unmatchedSuppressionFilters); + err |= ::reportUnmatchedSuppressions(supprlist.getUnmatchedLocalSuppressions(i->file), errorLogger, settings.unmatchedSuppressionFilters); } if (settings.inlineSuppressions) { - err |= ::reportUnmatchedSuppressions(suppressions.getUnmatchedInlineSuppressions(), errorLogger, settings.unmatchedSuppressionFilters); + err |= ::reportUnmatchedSuppressions(supprlist.getUnmatchedInlineSuppressions(), errorLogger, settings.unmatchedSuppressionFilters); } - err |= ::reportUnmatchedSuppressions(suppressions.getUnmatchedGlobalSuppressions(), errorLogger, settings.unmatchedSuppressionFilters); + err |= ::reportUnmatchedSuppressions(supprlist.getUnmatchedGlobalSuppressions(), errorLogger, settings.unmatchedSuppressionFilters); return err; } From 55860e433394c997dcddf5f6b0b1fbb8b37550cd Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 1 Nov 2025 11:46:49 +0100 Subject: [PATCH 2/8] mitigated `unmatchedSuppressions` selfcheck warnings --- gui/checkthread.cpp | 1 - lib/errorlogger.h | 1 - lib/importproject.cpp | 2 -- lib/keywords.cpp | 3 --- lib/mathlib.cpp | 1 - lib/programmemory.cpp | 1 - lib/suppressions.cpp | 2 -- lib/token.cpp | 1 - lib/utils.h | 1 - 9 files changed, 13 deletions(-) diff --git a/gui/checkthread.cpp b/gui/checkthread.cpp index 440bfa11624..090b698a6e7 100644 --- a/gui/checkthread.cpp +++ b/gui/checkthread.cpp @@ -124,7 +124,6 @@ void CheckThread::analyseWholeProgram(const std::list &files, c start(); } -// cppcheck-suppress unusedFunction - TODO: false positive void CheckThread::run() { mState = Running; diff --git a/lib/errorlogger.h b/lib/errorlogger.h index 8c88cfbbc9e..8cb7cbb8c42 100644 --- a/lib/errorlogger.h +++ b/lib/errorlogger.h @@ -190,7 +190,6 @@ class CPPCHECKLIB ErrorMessage { } /** Verbose message (may be the same as the short message) */ - // cppcheck-suppress unusedFunction - used by GUI only const std::string &verboseMessage() const { return mVerboseMessage; } diff --git a/lib/importproject.cpp b/lib/importproject.cpp index d484a326660..32c8a14d222 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -1505,7 +1505,6 @@ void ImportProject::selectOneVsConfig(Platform::Type platform) } } -// cppcheck-suppress unusedFunction - used by GUI only void ImportProject::selectVsConfigurations(Platform::Type platform, const std::vector &configurations) { for (auto it = fileSettings.cbegin(); it != fileSettings.cend();) { @@ -1530,7 +1529,6 @@ void ImportProject::selectVsConfigurations(Platform::Type platform, const std::v } } -// cppcheck-suppress unusedFunction - used by GUI only std::list ImportProject::getVSConfigs() { return std::list(mAllVSConfigs.cbegin(), mAllVSConfigs.cend()); diff --git a/lib/keywords.cpp b/lib/keywords.cpp index 91bad4e9338..51fb67237c9 100644 --- a/lib/keywords.cpp +++ b/lib/keywords.cpp @@ -173,7 +173,6 @@ static const std::unordered_set cpp26_keywords_all = { CPP03_KEYWORDS, CPP11_KEYWORDS, CPP20_KEYWORDS }; -// cppcheck-suppress unusedFunction const std::unordered_set& Keywords::getAll(Standards::cstd_t cStd) { switch (cStd) { @@ -193,7 +192,6 @@ const std::unordered_set& Keywords::getAll(Standards::cstd_t cStd) cppcheck::unreachable(); } -// cppcheck-suppress unusedFunction const std::unordered_set& Keywords::getAll(Standards::cppstd_t cppStd) { switch (cppStd) { case Standards::cppstd_t::CPP03: @@ -234,7 +232,6 @@ const std::unordered_set& Keywords::getOnly(Standards::cstd_t cStd) cppcheck::unreachable(); } -// cppcheck-suppress unusedFunction const std::unordered_set& Keywords::getOnly(Standards::cppstd_t cppStd) { switch (cppStd) { diff --git a/lib/mathlib.cpp b/lib/mathlib.cpp index 54240fa4f2f..68a3cae82f6 100644 --- a/lib/mathlib.cpp +++ b/lib/mathlib.cpp @@ -789,7 +789,6 @@ static bool isValidIntegerSuffixIt(std::string::const_iterator it, std::string:: (state == Status::SUFFIX_LITERAL)); } -// cppcheck-suppress unusedFunction bool MathLib::isValidIntegerSuffix(const std::string& str, bool supportMicrosoftExtensions) { return isValidIntegerSuffixIt(str.cbegin(), str.cend(), supportMicrosoftExtensions); diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 55419879055..750fd6653e0 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -96,7 +96,6 @@ const ValueFlow::Value* ProgramMemory::getValue(nonneg int exprid, bool impossib return nullptr; } -// cppcheck-suppress unusedFunction bool ProgramMemory::getIntValue(nonneg int exprid, MathLib::bigint& result) const { const ValueFlow::Value* value = getValue(exprid); diff --git a/lib/suppressions.cpp b/lib/suppressions.cpp index 7724082480d..13149876811 100644 --- a/lib/suppressions.cpp +++ b/lib/suppressions.cpp @@ -302,7 +302,6 @@ std::string SuppressionList::addSuppressions(std::list suppressions return ""; } -// cppcheck-suppress unusedFunction bool SuppressionList::updateSuppressionState(const SuppressionList::Suppression& suppression) { std::lock_guard lg(mSuppressionsSync); @@ -446,7 +445,6 @@ bool SuppressionList::Suppression::isMatch(const SuppressionList::ErrorMessage & cppcheck::unreachable(); } -// cppcheck-suppress unusedFunction - used by GUI only std::string SuppressionList::Suppression::getText() const { std::string ret; diff --git a/lib/token.cpp b/lib/token.cpp index e5a7fe4480e..575b1966aee 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -2630,7 +2630,6 @@ const ValueFlow::Value* Token::getMovedValue() const return it == mImpl->mValues->end() ? nullptr : &*it; } -// cppcheck-suppress unusedFunction const ValueFlow::Value* Token::getContainerSizeValue(const MathLib::bigint val) const { if (!mImpl->mValues) diff --git a/lib/utils.h b/lib/utils.h index 07350660281..c59e4d3a32c 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -291,7 +291,6 @@ T strToInt(const std::string& str) * \return size of array * */ template -// cppcheck-suppress unusedFunction - only used in conditional code std::size_t getArrayLength(const T (& /*unused*/)[size]) { return size; From f95416e826fdcf683bee285bde09bf7578bbf281 Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 1 Nov 2025 11:48:50 +0100 Subject: [PATCH 3/8] suppress `checkersReport` in `unusedFunction` selfchecks / add special handling in `UNUSEDFUNCTION_ONLY` hack --- .selfcheck_unused_suppressions | 3 +++ cli/cppcheckexecutor.cpp | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.selfcheck_unused_suppressions b/.selfcheck_unused_suppressions index ce685d8ab10..03e4b6c3f6c 100644 --- a/.selfcheck_unused_suppressions +++ b/.selfcheck_unused_suppressions @@ -1,3 +1,6 @@ +# should not be reported - see #13387 +checkersReport + # we are not using all methods of their interfaces unusedFunction:externals/*/* diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 8baab2ed78e..43ab69b5d49 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -352,7 +352,8 @@ bool CppCheckExecutor::reportUnmatchedSuppressions(const Settings &settings, con // ignore all other suppressions if we use the unusedFunction hack for (auto&& s : suppr) { - if (doUnusedFunctionOnly && s.errorId != "unusedFunction") + // TODO: checkersReport should not be reported - see #13387 + if (doUnusedFunctionOnly && s.errorId != "unusedFunction" && s.errorId != "checkersReport") continue; supprlist.addSuppression(std::move(s)); } From 01a37806d75f467024f48c2b4bbbad3846cf3990 Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 1 Nov 2025 12:03:26 +0100 Subject: [PATCH 4/8] moved `SuppressionList::Suppression::getText()` to `gui/projectfiledialog.cpp` --- gui/projectfiledialog.cpp | 22 ++++++++++++++++++++-- lib/suppressions.cpp | 18 ------------------ lib/suppressions.h | 2 -- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/gui/projectfiledialog.cpp b/gui/projectfiledialog.cpp index e8330cff2cd..9a85124e4dc 100644 --- a/gui/projectfiledialog.cpp +++ b/gui/projectfiledialog.cpp @@ -90,6 +90,24 @@ static const std::array builtinPlatforms = { Platform::Type::Unix64 }; +static std::string suppressionAsText(const SuppressionList::Suppression& s) +{ + std::string ret; + if (!s.errorId.empty()) + ret = s.errorId; + if (!s.fileName.empty()) + ret += " fileName=" + s.fileName; + if (s.lineNumber != SuppressionList::Suppression::NO_LINE) + ret += " lineNumber=" + std::to_string(s.lineNumber); + if (!s.symbolName.empty()) + ret += " symbolName=" + s.symbolName; + if (s.hash > 0) + ret += " hash=" + std::to_string(s.hash); + if (startsWith(ret," ")) + return ret.substr(1); + return ret; +} + QStringList ProjectFileDialog::getProjectConfigs(const QString &fileName) { if (!fileName.endsWith(".sln") && !fileName.endsWith(".vcxproj")) @@ -808,7 +826,7 @@ void ProjectFileDialog::setLibraries(const QStringList &libraries) void ProjectFileDialog::addSingleSuppression(const SuppressionList::Suppression &suppression) { mSuppressions += suppression; - mUI->mListSuppressions->addItem(QString::fromStdString(suppression.getText())); + mUI->mListSuppressions->addItem(QString::fromStdString(suppressionAsText(suppression))); } void ProjectFileDialog::setSuppressions(const QList &suppressions) @@ -949,7 +967,7 @@ int ProjectFileDialog::getSuppressionIndex(const QString &shortText) const { const std::string s = shortText.toStdString(); auto it = std::find_if(mSuppressions.cbegin(), mSuppressions.cend(), [&](const SuppressionList::Suppression& sup) { - return sup.getText() == s; + return suppressionAsText(sup) == s; }); return it == mSuppressions.cend() ? -1 : static_cast(std::distance(mSuppressions.cbegin(), it)); } diff --git a/lib/suppressions.cpp b/lib/suppressions.cpp index 13149876811..65595673ca8 100644 --- a/lib/suppressions.cpp +++ b/lib/suppressions.cpp @@ -445,24 +445,6 @@ bool SuppressionList::Suppression::isMatch(const SuppressionList::ErrorMessage & cppcheck::unreachable(); } -std::string SuppressionList::Suppression::getText() const -{ - std::string ret; - if (!errorId.empty()) - ret = errorId; - if (!fileName.empty()) - ret += " fileName=" + fileName; - if (lineNumber != NO_LINE) - ret += " lineNumber=" + std::to_string(lineNumber); - if (!symbolName.empty()) - ret += " symbolName=" + symbolName; - if (hash > 0) - ret += " hash=" + std::to_string(hash); - if (startsWith(ret," ")) - return ret.substr(1); - return ret; -} - bool SuppressionList::isSuppressed(const SuppressionList::ErrorMessage &errmsg, bool global) { std::lock_guard lg(mSuppressionsSync); diff --git a/lib/suppressions.h b/lib/suppressions.h index 8b6776560b4..0ff4dbaa36f 100644 --- a/lib/suppressions.h +++ b/lib/suppressions.h @@ -127,8 +127,6 @@ class CPPCHECKLIB SuppressionList { bool isMatch(const ErrorMessage &errmsg); - std::string getText() const; - bool isWildcard() const { return fileName.find_first_of("?*") != std::string::npos; } From 28db4b1624b38ee97af1f2a5eec74733a4211c81 Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 1 Nov 2025 12:18:32 +0100 Subject: [PATCH 5/8] selfcheck.yml: added suppressions for conditionally unused code --- .github/workflows/selfcheck.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/selfcheck.yml b/.github/workflows/selfcheck.yml index 190ca4f31ab..13e70b56668 100644 --- a/.github/workflows/selfcheck.yml +++ b/.github/workflows/selfcheck.yml @@ -121,7 +121,8 @@ jobs: - name: Self check (unusedFunction / no test / no gui) run: | - ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib -D__CPPCHECK__ -D__GNUC__ --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.notest_nogui/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr + supprs="--suppress=unusedFunction:lib/errorlogger.h:193 --suppress=unusedFunction:lib/importproject.cpp:1508 --suppress=unusedFunction:lib/importproject.cpp:1532" + ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib -D__CPPCHECK__ -D__GNUC__ --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.notest_nogui/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr $supprs env: DISABLE_VALUEFLOW: 1 UNUSEDFUNCTION_ONLY: 1 From 1efeeebf4d52ebc52f981c570b4347bffcca1e74 Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 1 Nov 2025 12:18:55 +0100 Subject: [PATCH 6/8] use inline suppression for `symboldatabase.cpp` --- .selfcheck_unused_suppressions | 3 --- lib/symboldatabase.cpp | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.selfcheck_unused_suppressions b/.selfcheck_unused_suppressions index 03e4b6c3f6c..5da7c225dfa 100644 --- a/.selfcheck_unused_suppressions +++ b/.selfcheck_unused_suppressions @@ -4,8 +4,5 @@ checkersReport # we are not using all methods of their interfaces unusedFunction:externals/*/* -# usage is disabled -unusedFunction:lib/symboldatabase.cpp - # Q_OBJECT functions which are not called in our code unusedFunction:cmake.output.notest/gui/cppcheck-gui_autogen/*/moc_aboutdialog.cpp diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index c976d887e87..156d38b7a30 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -6404,6 +6404,7 @@ const Function* SymbolDatabase::findFunction(const Token* const tok) const //--------------------------------------------------------------------------- +// cppcheck-suppress unusedFunction const Scope *SymbolDatabase::findScopeByName(const std::string& name) const { auto it = std::find_if(scopeList.cbegin(), scopeList.cend(), [&](const Scope& s) { From 58005c9c4680a3ae3d25f2aa5d051bc5b930e168 Mon Sep 17 00:00:00 2001 From: firewave Date: Mon, 3 Nov 2025 17:40:47 +0100 Subject: [PATCH 7/8] moved reading of `UNUSEDFUNCTION_ONLY` into a single place --- cli/cppcheckexecutor.cpp | 3 +-- lib/cppcheck.cpp | 3 +-- lib/settings.cpp | 6 ++++++ lib/settings.h | 3 ++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 43ab69b5d49..a2c8697f70e 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -347,8 +347,7 @@ bool CppCheckExecutor::reportUnmatchedSuppressions(const Settings &settings, con SuppressionList supprlist; - const char* unusedFunctionOnly = std::getenv("UNUSEDFUNCTION_ONLY"); - const bool doUnusedFunctionOnly = unusedFunctionOnly && (std::strcmp(unusedFunctionOnly, "1") == 0); + const bool doUnusedFunctionOnly = Settings::unusedFunctionOnly(); // ignore all other suppressions if we use the unusedFunction hack for (auto&& s : suppr) { diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 887a4b0c04e..eab0575eb10 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1340,8 +1340,7 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer, AnalyzerInformation // TODO: this should actually be the behavior if only "--enable=unusedFunction" is specified - see #10648 // TODO: log message when this is active? - const char* unusedFunctionOnly = std::getenv("UNUSEDFUNCTION_ONLY"); - const bool doUnusedFunctionOnly = unusedFunctionOnly && (std::strcmp(unusedFunctionOnly, "1") == 0); + const bool doUnusedFunctionOnly = Settings::unusedFunctionOnly(); if (!doUnusedFunctionOnly) { const std::time_t maxTime = mSettings.checksMaxTime > 0 ? std::time(nullptr) + mSettings.checksMaxTime : 0; diff --git a/lib/settings.cpp b/lib/settings.cpp index 7be37686e0b..bae5c6c1671 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -715,3 +715,9 @@ Settings::ExecutorType Settings::defaultExecutor() #endif return defaultExecutor; } + +bool Settings::unusedFunctionOnly() +{ + const char* unusedFunctionOnly = std::getenv("UNUSEDFUNCTION_ONLY"); + return unusedFunctionOnly && (std::strcmp(unusedFunctionOnly, "1") == 0); +} diff --git a/lib/settings.h b/lib/settings.h index 615c2acdf96..ea2951bbf64 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -554,9 +554,10 @@ class CPPCHECKLIB WARN_UNUSED Settings { void setCheckLevel(CheckLevel level); - static ExecutorType defaultExecutor(); + static bool unusedFunctionOnly(); + private: static std::string parseEnabled(const std::string &str, std::tuple, SimpleEnableGroup> &groups); std::string applyEnabled(const std::string &str, bool enable); From 9f0b7c03cb1d3473ec25e0fc290d17fd43a030a5 Mon Sep 17 00:00:00 2001 From: firewave Date: Mon, 3 Nov 2025 17:47:13 +0100 Subject: [PATCH 8/8] cleaned up includes based on `include-what-you-use` --- cli/cppcheckexecutor.cpp | 2 -- lib/settings.cpp | 2 ++ lib/suppressions.cpp | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index a2c8697f70e..fd36252f7e3 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -32,7 +32,6 @@ #include "errorlogger.h" #include "errortypes.h" #include "filesettings.h" -#include "json.h" #include "path.h" #include "sarifreport.h" #include "settings.h" @@ -49,7 +48,6 @@ #include #include -#include #include #include // EXIT_SUCCESS and EXIT_FAILURE #include diff --git a/lib/settings.cpp b/lib/settings.cpp index bae5c6c1671..35cdae7308b 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -25,6 +25,8 @@ #include "vfvalue.h" #include +#include +#include #include #include #include diff --git a/lib/suppressions.cpp b/lib/suppressions.cpp index 65595673ca8..b91db635478 100644 --- a/lib/suppressions.cpp +++ b/lib/suppressions.cpp @@ -19,7 +19,6 @@ #include "suppressions.h" #include "errorlogger.h" -#include "errortypes.h" #include "filesettings.h" #include "path.h" #include "pathmatch.h"