diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 1b7a587ef1ca..9e330d763842 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -602,6 +602,10 @@ unsigned int CppCheck::check(const FileSettings &fs) const unsigned int returnValue = temp.checkFile(Path::simplifyPath(fs.filename), fs.cfg); for (const auto& suppr : temp.mSettings.supprs.nomsg.getSuppressions()) { + // skip inline suppressions - are handled in checkFile() + if (suppr.isInline) + continue; + const bool res = mSettings.supprs.nomsg.updateSuppressionState(suppr); if (!res) throw InternalError(nullptr, "could not update suppression '" + suppr.errorId + "'"); // TODO: remove @@ -947,8 +951,10 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string fdump << "" << std::endl; } - // Need to call this even if the hash will skip this configuration - mSettings.supprs.nomsg.markUnmatchedInlineSuppressionsAsChecked(tokenizer); + if (mSettings.inlineSuppressions) { + // Need to call this even if the hash will skip this configuration + mSettings.supprs.nomsg.markUnmatchedInlineSuppressionsAsChecked(tokenizer); + } // Skip if we already met the same simplified token list if (mSettings.force || mSettings.maxConfigs > 1) { @@ -1038,10 +1044,16 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string mAnalyzerInformation.close(); } - // In jointSuppressionReport mode, unmatched suppressions are - // collected after all files are processed - if (!mSettings.useSingleJob() && (mSettings.severity.isEnabled(Severity::information) || mSettings.checkConfiguration)) { - SuppressionList::reportUnmatchedSuppressions(mSettings.supprs.nomsg.getUnmatchedLocalSuppressions(filename, (bool)mUnusedFunctionsCheck), *this); + if (mSettings.severity.isEnabled(Severity::information) || mSettings.checkConfiguration) { + // TODO: check result? + SuppressionList::reportUnmatchedSuppressions(mSettings.supprs.nomsg.getUnmatchedInlineSuppressions(false), *this); + + // In jointSuppressionReport mode, unmatched suppressions are + // collected after all files are processed + if (!mSettings.useSingleJob()) { + // TODO: check result? + SuppressionList::reportUnmatchedSuppressions(mSettings.supprs.nomsg.getUnmatchedLocalSuppressions(filename, (bool)mUnusedFunctionsCheck)), *this); + } } mErrorList.clear(); diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 0cd272ae49b1..dbf75bd7d069 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -229,6 +229,7 @@ static void addInlineSuppressions(const simplecpp::TokenList &tokens, const Sett // Add the suppressions. for (SuppressionList::Suppression &suppr : inlineSuppressions) { suppr.fileName = relativeFilename; + suppr.isInline = true; // TODO: set earlier if (SuppressionList::Type::blockBegin == suppr.type) { diff --git a/lib/suppressions.cpp b/lib/suppressions.cpp index ea1ef10083cf..551a59318798 100644 --- a/lib/suppressions.cpp +++ b/lib/suppressions.cpp @@ -492,6 +492,8 @@ std::list SuppressionList::getUnmatchedLocalSuppre std::string tmpFile = Path::simplifyPath(file); std::list result; for (const Suppression &s : mSuppressions) { + if (s.isInline) + continue; if (s.matched || ((s.lineNumber != Suppression::NO_LINE) && !s.checked)) continue; if (s.type == SuppressionList::Type::macro) @@ -513,6 +515,8 @@ std::list SuppressionList::getUnmatchedGlobalSuppr { std::list result; for (const Suppression &s : mSuppressions) { + if (s.isInline) + continue; if (s.matched || ((s.lineNumber != Suppression::NO_LINE) && !s.checked)) continue; if (s.hash > 0) @@ -528,6 +532,25 @@ std::list SuppressionList::getUnmatchedGlobalSuppr return result; } +std::list SuppressionList::getUnmatchedInlineSuppressions(const bool unusedFunctionChecking) const +{ + std::list result; + for (const SuppressionList::Suppression &s : SuppressionList::mSuppressions) { + if (!s.isInline) + continue; + if (!s.checked) + continue; + if (s.matched) + continue; + if (s.hash > 0) + continue; + if (!unusedFunctionChecking && s.errorId == ID_UNUSEDFUNCTION) + continue; + result.push_back(s); + } + return result; +} + const std::list &SuppressionList::getSuppressions() const { return mSuppressions; diff --git a/lib/suppressions.h b/lib/suppressions.h index 4e6bddf8962f..0e227e6002a5 100644 --- a/lib/suppressions.h +++ b/lib/suppressions.h @@ -148,6 +148,7 @@ class CPPCHECKLIB SuppressionList { bool thisAndNextLine{}; // Special case for backwards compatibility: { // cppcheck-suppress something bool matched{}; bool checked{}; // for inline suppressions, checked or not + bool isInline{}; enum { NO_LINE = -1 }; }; @@ -244,6 +245,12 @@ class CPPCHECKLIB SuppressionList { */ std::list getUnmatchedGlobalSuppressions(const bool unusedFunctionChecking) const; + /** + * @brief Returns list of unmatched inline suppressions. + * @return list of unmatched suppressions + */ + std::list getUnmatchedInlineSuppressions(const bool unusedFunctionChecking) const; + /** * @brief Returns list of all suppressions. * @return list of suppressions diff --git a/test/testsuppressions.cpp b/test/testsuppressions.cpp index 1e877c49e7d4..0ef1f57b465f 100644 --- a/test/testsuppressions.cpp +++ b/test/testsuppressions.cpp @@ -880,7 +880,7 @@ class TestSuppressions : public TestFixture { "#define DIV(A,B) A/B\n" "a = DIV(10,1);\n", ""); - ASSERT_EQUALS("", errout_str()); // <- no unmatched suppression reported for macro suppression + ASSERT_EQUALS("[test.cpp:2]: (information) Unmatched suppression: abc\n", errout_str()); } void suppressionsSettingsFiles() {