diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 617e52e96..e2257db4b 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -166,10 +166,20 @@ static void inlineSuppressions(const simplecpp::TokenList &tokens, Settings &mSe } relativeFilename = Path::simplifyPath(relativeFilename); + // special handling when suppressing { warnings for backwards compatibility + const bool thisAndNextLine = tok->previous && + tok->previous->previous && + tok->next && + !sameline(tok->previous->previous, tok->previous) && + tok->location.line + 1 == tok->next->location.line && + tok->location.fileIndex == tok->next->location.fileIndex && + tok->previous->str() == "{"; + // Add the suppressions. for (Suppressions::Suppression &suppr : inlineSuppressions) { suppr.fileName = relativeFilename; suppr.lineNumber = tok->location.line; + suppr.thisAndNextLine = thisAndNextLine; mSettings.nomsg.addSuppression(suppr); } } diff --git a/lib/suppressions.cpp b/lib/suppressions.cpp index 1d94155b6..947bebe93 100644 --- a/lib/suppressions.cpp +++ b/lib/suppressions.cpp @@ -291,8 +291,10 @@ bool Suppressions::Suppression::isSuppressed(const Suppressions::ErrorMessage &e return false; if (!fileName.empty() && !matchglob(fileName, errmsg.getFileName())) return false; - if (lineNumber != NO_LINE && lineNumber != errmsg.lineNumber) - return false; + if (lineNumber != NO_LINE && lineNumber != errmsg.lineNumber) { + if (!thisAndNextLine || lineNumber + 1 != errmsg.lineNumber) + return false; + } if (!symbolName.empty()) { for (std::string::size_type pos = 0; pos < errmsg.symbolNames.size();) { const std::string::size_type pos2 = errmsg.symbolNames.find('\n',pos); diff --git a/lib/suppressions.h b/lib/suppressions.h index a34207106..21a401f22 100644 --- a/lib/suppressions.h +++ b/lib/suppressions.h @@ -53,7 +53,7 @@ public: Suppression(const Suppression &other) { *this = other; } - Suppression(const std::string &id, const std::string &file, int line=NO_LINE) : errorId(id), fileName(file), lineNumber(line), hash(0), matched(false) {} + Suppression(const std::string &id, const std::string &file, int line=NO_LINE) : errorId(id), fileName(file), lineNumber(line), hash(0), thisAndNextLine(false), matched(false) {} Suppression & operator=(const Suppression &other) { errorId = other.errorId; @@ -61,6 +61,7 @@ public: lineNumber = other.lineNumber; symbolName = other.symbolName; hash = other.hash; + thisAndNextLine = other.thisAndNextLine; matched = other.matched; return *this; } @@ -76,6 +77,8 @@ public: return symbolName < other.symbolName; if (hash != other.hash) return hash < other.hash; + if (thisAndNextLine != other.thisAndNextLine) + return thisAndNextLine; return false; } @@ -101,6 +104,7 @@ public: int lineNumber; std::string symbolName; std::size_t hash; + bool thisAndNextLine; // Special case for backwards compatibility: { // cppcheck-suppress something bool matched; enum { NO_LINE = -1 }; diff --git a/test/cli/test-inline-suppress.py b/test/cli/test-inline-suppress.py index 9b4102d2e..3cc7ba8e2 100644 --- a/test/cli/test-inline-suppress.py +++ b/test/cli/test-inline-suppress.py @@ -24,3 +24,11 @@ def test_unmatched_suppression_path_with_extra_stuf(): ret, stdout, stderr = cppcheck(['--inline-suppr', '--enable=information', '--error-exitcode=1', './proj-inline-suppress/2.c']) assert ret == 1 assert 'Unmatched suppression: some_warning_id' in stderr + +def test_backwards_compatibility(): + ret, stdout, stderr = cppcheck(['--enable=unusedFunction', 'proj-inline-suppress/3.cpp']) + assert len(stderr) > 0 + + ret, stdout, stderr = cppcheck(['--inline-suppr', '--enable=unusedFunction', 'proj-inline-suppress/3.cpp']) + assert ret == 0 + assert stderr == ''