Inline suppression for block of code or whole file (#5402)
Added new suppress comments: - `cppcheck-suppress-begin` and `cppcheck-suppress-end` to remove blocks of suppression - `cppcheck-suppress-file` to remove suppression at file level The suppressions do not interfere with each others. For example, all the suppressions are matched in the following code: ```c // cppcheck-suppress-file uninitvar void f() { int a; // cppcheck-suppress-begin uninitvar // cppcheck-suppress uninitvar a++; // cppcheck-suppress-end uninitvar } ``` Tickets: https://trac.cppcheck.net/ticket/11902 https://trac.cppcheck.net/ticket/8528
This commit is contained in:
parent
8ef4da475a
commit
44ab976451
|
@ -76,8 +76,9 @@ Preprocessor::~Preprocessor()
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct BadInlineSuppression {
|
struct BadInlineSuppression {
|
||||||
BadInlineSuppression(const simplecpp::Location &l, std::string msg) : location(l), errmsg(std::move(msg)) {}
|
BadInlineSuppression(std::string file, const int line, std::string msg) : file(std::move(file)), line(line), errmsg(std::move(msg)) {}
|
||||||
simplecpp::Location location;
|
std::string file;
|
||||||
|
int line;
|
||||||
std::string errmsg;
|
std::string errmsg;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -97,18 +98,50 @@ static bool parseInlineSuppressionCommentToken(const simplecpp::Token *tok, std:
|
||||||
if (comment.substr(pos1, cppchecksuppress.size()) != cppchecksuppress)
|
if (comment.substr(pos1, cppchecksuppress.size()) != cppchecksuppress)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// skip spaces after "cppcheck-suppress"
|
// check if it has a prefix
|
||||||
const std::string::size_type pos2 = comment.find_first_not_of(' ', pos1+cppchecksuppress.size());
|
const std::string::size_type posEndComment = comment.find_first_of(" [", pos1+cppchecksuppress.size());
|
||||||
|
|
||||||
|
// skip spaces after "cppcheck-suppress" and its possible prefix
|
||||||
|
const std::string::size_type pos2 = comment.find_first_not_of(' ', posEndComment);
|
||||||
if (pos2 == std::string::npos)
|
if (pos2 == std::string::npos)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
Suppressions::Type errorType = Suppressions::Type::unique;
|
||||||
|
|
||||||
|
// determine prefix if specified
|
||||||
|
if (posEndComment >= (pos1 + cppchecksuppress.size() + 1)) {
|
||||||
|
if (comment.at(pos1 + cppchecksuppress.size()) != '-')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const unsigned int argumentLength =
|
||||||
|
posEndComment - (pos1 + cppchecksuppress.size() + 1);
|
||||||
|
|
||||||
|
const std::string suppressTypeString =
|
||||||
|
comment.substr(pos1 + cppchecksuppress.size() + 1, argumentLength);
|
||||||
|
|
||||||
|
if ("file" == suppressTypeString) {
|
||||||
|
errorType = Suppressions::Type::file;
|
||||||
|
} else if ("begin" == suppressTypeString) {
|
||||||
|
errorType = Suppressions::Type::blockBegin;
|
||||||
|
} else if ("end" == suppressTypeString) {
|
||||||
|
errorType = Suppressions::Type::blockEnd;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (comment[pos2] == '[') {
|
if (comment[pos2] == '[') {
|
||||||
// multi suppress format
|
// multi suppress format
|
||||||
std::string errmsg;
|
std::string errmsg;
|
||||||
std::vector<Suppressions::Suppression> suppressions = Suppressions::parseMultiSuppressComment(comment, &errmsg);
|
std::vector<Suppressions::Suppression> suppressions = Suppressions::parseMultiSuppressComment(comment, &errmsg);
|
||||||
|
|
||||||
|
for (Suppressions::Suppression &s : suppressions) {
|
||||||
|
s.type = errorType;
|
||||||
|
s.lineNumber = tok->location.line;
|
||||||
|
}
|
||||||
|
|
||||||
if (!errmsg.empty())
|
if (!errmsg.empty())
|
||||||
bad.emplace_back(tok->location, std::move(errmsg));
|
bad.emplace_back(tok->location.file(), tok->location.line, std::move(errmsg));
|
||||||
|
|
||||||
std::copy_if(suppressions.cbegin(), suppressions.cend(), std::back_inserter(inlineSuppressions), [](const Suppressions::Suppression& s) {
|
std::copy_if(suppressions.cbegin(), suppressions.cend(), std::back_inserter(inlineSuppressions), [](const Suppressions::Suppression& s) {
|
||||||
return !s.errorId.empty();
|
return !s.errorId.empty();
|
||||||
|
@ -120,21 +153,30 @@ static bool parseInlineSuppressionCommentToken(const simplecpp::Token *tok, std:
|
||||||
if (!s.parseComment(comment, &errmsg))
|
if (!s.parseComment(comment, &errmsg))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
s.type = errorType;
|
||||||
|
s.lineNumber = tok->location.line;
|
||||||
|
|
||||||
if (!s.errorId.empty())
|
if (!s.errorId.empty())
|
||||||
inlineSuppressions.push_back(std::move(s));
|
inlineSuppressions.push_back(std::move(s));
|
||||||
|
|
||||||
if (!errmsg.empty())
|
if (!errmsg.empty())
|
||||||
bad.emplace_back(tok->location, std::move(errmsg));
|
bad.emplace_back(tok->location.file(), tok->location.line, std::move(errmsg));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addinlineSuppressions(const simplecpp::TokenList &tokens, const Settings &settings, Suppressions &suppressions, std::list<BadInlineSuppression> &bad)
|
static void addInlineSuppressions(const simplecpp::TokenList &tokens, const Settings &settings, Suppressions &suppressions, std::list<BadInlineSuppression> &bad)
|
||||||
{
|
{
|
||||||
|
std::list<Suppressions::Suppression> inlineSuppressionsBlockBegin;
|
||||||
|
|
||||||
|
bool onlyComments = true;
|
||||||
|
|
||||||
for (const simplecpp::Token *tok = tokens.cfront(); tok; tok = tok->next) {
|
for (const simplecpp::Token *tok = tokens.cfront(); tok; tok = tok->next) {
|
||||||
if (!tok->comment)
|
if (!tok->comment) {
|
||||||
|
onlyComments = false;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
std::list<Suppressions::Suppression> inlineSuppressions;
|
std::list<Suppressions::Suppression> inlineSuppressions;
|
||||||
if (!parseInlineSuppressionCommentToken(tok, inlineSuppressions, bad))
|
if (!parseInlineSuppressionCommentToken(tok, inlineSuppressions, bad))
|
||||||
|
@ -142,18 +184,27 @@ static void addinlineSuppressions(const simplecpp::TokenList &tokens, const Sett
|
||||||
|
|
||||||
if (!sameline(tok->previous, tok)) {
|
if (!sameline(tok->previous, tok)) {
|
||||||
// find code after comment..
|
// find code after comment..
|
||||||
tok = tok->next;
|
if (tok->next) {
|
||||||
while (tok && tok->comment) {
|
|
||||||
parseInlineSuppressionCommentToken(tok, inlineSuppressions, bad);
|
|
||||||
tok = tok->next;
|
tok = tok->next;
|
||||||
|
|
||||||
|
while (tok->comment) {
|
||||||
|
parseInlineSuppressionCommentToken(tok, inlineSuppressions, bad);
|
||||||
|
if (tok->next) {
|
||||||
|
tok = tok->next;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!tok)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inlineSuppressions.empty())
|
if (inlineSuppressions.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// It should never happen
|
||||||
|
if (!tok)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Relative filename
|
// Relative filename
|
||||||
std::string relativeFilename(tok->location.file());
|
std::string relativeFilename(tok->location.file());
|
||||||
if (settings.relativePaths) {
|
if (settings.relativePaths) {
|
||||||
|
@ -166,23 +217,66 @@ static void addinlineSuppressions(const simplecpp::TokenList &tokens, const Sett
|
||||||
}
|
}
|
||||||
relativeFilename = Path::simplifyPath(relativeFilename);
|
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.
|
// Add the suppressions.
|
||||||
for (Suppressions::Suppression &suppr : inlineSuppressions) {
|
for (Suppressions::Suppression &suppr : inlineSuppressions) {
|
||||||
suppr.fileName = relativeFilename;
|
suppr.fileName = relativeFilename;
|
||||||
suppr.lineNumber = tok->location.line;
|
|
||||||
suppr.thisAndNextLine = thisAndNextLine;
|
if (Suppressions::Type::blockBegin == suppr.type)
|
||||||
suppressions.addSuppression(std::move(suppr));
|
{
|
||||||
|
inlineSuppressionsBlockBegin.push_back(std::move(suppr));
|
||||||
|
} else if (Suppressions::Type::blockEnd == suppr.type) {
|
||||||
|
bool throwError = true;
|
||||||
|
|
||||||
|
if (!inlineSuppressionsBlockBegin.empty()) {
|
||||||
|
const Suppressions::Suppression lastBeginSuppression = inlineSuppressionsBlockBegin.back();
|
||||||
|
|
||||||
|
for (const Suppressions::Suppression &supprBegin : inlineSuppressionsBlockBegin)
|
||||||
|
{
|
||||||
|
if (lastBeginSuppression.lineNumber != supprBegin.lineNumber)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (suppr.symbolName == supprBegin.symbolName && suppr.lineNumber > supprBegin.lineNumber) {
|
||||||
|
suppr.lineBegin = supprBegin.lineNumber;
|
||||||
|
suppr.lineEnd = suppr.lineNumber;
|
||||||
|
suppr.lineNumber = supprBegin.lineNumber;
|
||||||
|
suppr.type = Suppressions::Type::block;
|
||||||
|
inlineSuppressionsBlockBegin.remove(supprBegin);
|
||||||
|
suppressions.addSuppression(std::move(suppr));
|
||||||
|
throwError = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (throwError) {
|
||||||
|
// NOLINTNEXTLINE(bugprone-use-after-move) - moved only when thrownError is false
|
||||||
|
bad.emplace_back(suppr.fileName, suppr.lineNumber, "Suppress End: No matching begin");
|
||||||
|
}
|
||||||
|
} else if (Suppressions::Type::unique == suppr.type) {
|
||||||
|
// 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() == "{";
|
||||||
|
|
||||||
|
suppr.thisAndNextLine = thisAndNextLine;
|
||||||
|
suppr.lineNumber = tok->location.line;
|
||||||
|
suppressions.addSuppression(std::move(suppr));
|
||||||
|
} else if (Suppressions::Type::file == suppr.type) {
|
||||||
|
if (onlyComments)
|
||||||
|
suppressions.addSuppression(std::move(suppr));
|
||||||
|
else
|
||||||
|
bad.emplace_back(suppr.fileName, suppr.lineNumber, "File suppression should be at the top of the file");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::for_each(inlineSuppressionsBlockBegin.begin(), inlineSuppressionsBlockBegin.end(), [&](const Suppressions::Suppression & suppr) {
|
||||||
|
bad.emplace_back(suppr.fileName, suppr.lineNumber, "Suppress Begin: No matching end");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Preprocessor::inlineSuppressions(const simplecpp::TokenList &tokens, Suppressions &suppressions)
|
void Preprocessor::inlineSuppressions(const simplecpp::TokenList &tokens, Suppressions &suppressions)
|
||||||
|
@ -190,13 +284,13 @@ void Preprocessor::inlineSuppressions(const simplecpp::TokenList &tokens, Suppre
|
||||||
if (!mSettings.inlineSuppressions)
|
if (!mSettings.inlineSuppressions)
|
||||||
return;
|
return;
|
||||||
std::list<BadInlineSuppression> err;
|
std::list<BadInlineSuppression> err;
|
||||||
::addinlineSuppressions(tokens, mSettings, suppressions, err);
|
::addInlineSuppressions(tokens, mSettings, suppressions, err);
|
||||||
for (std::map<std::string,simplecpp::TokenList*>::const_iterator it = mTokenLists.cbegin(); it != mTokenLists.cend(); ++it) {
|
for (std::map<std::string,simplecpp::TokenList*>::const_iterator it = mTokenLists.cbegin(); it != mTokenLists.cend(); ++it) {
|
||||||
if (it->second)
|
if (it->second)
|
||||||
::addinlineSuppressions(*it->second, mSettings, suppressions, err);
|
::addInlineSuppressions(*it->second, mSettings, suppressions, err);
|
||||||
}
|
}
|
||||||
for (const BadInlineSuppression &bad : err) {
|
for (const BadInlineSuppression &bad : err) {
|
||||||
error(bad.location.file(), bad.location.line, bad.errmsg);
|
error(bad.file, bad.line, bad.errmsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,6 +165,8 @@ std::vector<Suppressions::Suppression> Suppressions::parseMultiSuppressComment(c
|
||||||
return suppressions;
|
return suppressions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string SymbolNameString = "symbolName=";
|
||||||
|
|
||||||
while (iss) {
|
while (iss) {
|
||||||
std::string word;
|
std::string word;
|
||||||
iss >> word;
|
iss >> word;
|
||||||
|
@ -172,8 +174,8 @@ std::vector<Suppressions::Suppression> Suppressions::parseMultiSuppressComment(c
|
||||||
break;
|
break;
|
||||||
if (word.find_first_not_of("+-*/%#;") == std::string::npos)
|
if (word.find_first_not_of("+-*/%#;") == std::string::npos)
|
||||||
break;
|
break;
|
||||||
if (startsWith(word, "symbolName=")) {
|
if (startsWith(word, SymbolNameString)) {
|
||||||
s.symbolName = word.substr(11);
|
s.symbolName = word.substr(SymbolNameString.size());
|
||||||
} else {
|
} else {
|
||||||
if (errorMessage && errorMessage->empty())
|
if (errorMessage && errorMessage->empty())
|
||||||
*errorMessage = "Bad multi suppression '" + comment + "'. legal format is cppcheck-suppress[errorId, errorId symbolName=arr, ...]";
|
*errorMessage = "Bad multi suppression '" + comment + "'. legal format is cppcheck-suppress[errorId, errorId symbolName=arr, ...]";
|
||||||
|
@ -302,22 +304,28 @@ bool Suppressions::Suppression::parseComment(std::string comment, std::string *e
|
||||||
if (comment.compare(comment.size() - 2, 2, "*/") == 0)
|
if (comment.compare(comment.size() - 2, 2, "*/") == 0)
|
||||||
comment.erase(comment.size() - 2, 2);
|
comment.erase(comment.size() - 2, 2);
|
||||||
|
|
||||||
|
const std::string cppchecksuppress = "cppcheck-suppress";
|
||||||
|
|
||||||
std::istringstream iss(comment.substr(2));
|
std::istringstream iss(comment.substr(2));
|
||||||
std::string word;
|
std::string word;
|
||||||
iss >> word;
|
iss >> word;
|
||||||
if (word != "cppcheck-suppress")
|
if (word.substr(0, cppchecksuppress.size()) != cppchecksuppress)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
iss >> errorId;
|
iss >> errorId;
|
||||||
if (!iss)
|
if (!iss)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
const std::string SymbolNameString = "symbolName=";
|
||||||
|
|
||||||
while (iss) {
|
while (iss) {
|
||||||
iss >> word;
|
iss >> word;
|
||||||
if (!iss)
|
if (!iss)
|
||||||
break;
|
break;
|
||||||
if (word.find_first_not_of("+-*/%#;") == std::string::npos)
|
if (word.find_first_not_of("+-*/%#;") == std::string::npos)
|
||||||
break;
|
break;
|
||||||
if (startsWith(word,"symbolName="))
|
if (startsWith(word, SymbolNameString))
|
||||||
symbolName = word.substr(11);
|
symbolName = word.substr(SymbolNameString.size());
|
||||||
else if (errorMessage && errorMessage->empty())
|
else if (errorMessage && errorMessage->empty())
|
||||||
*errorMessage = "Bad suppression attribute '" + word + "'. You can write comments in the comment after a ; or //. Valid suppression attributes; symbolName=sym";
|
*errorMessage = "Bad suppression attribute '" + word + "'. You can write comments in the comment after a ; or //. Valid suppression attributes; symbolName=sym";
|
||||||
}
|
}
|
||||||
|
@ -332,10 +340,12 @@ bool Suppressions::Suppression::isSuppressed(const Suppressions::ErrorMessage &e
|
||||||
return false;
|
return false;
|
||||||
if (!fileName.empty() && !matchglob(fileName, errmsg.getFileName()))
|
if (!fileName.empty() && !matchglob(fileName, errmsg.getFileName()))
|
||||||
return false;
|
return false;
|
||||||
if (lineNumber != NO_LINE && lineNumber != errmsg.lineNumber) {
|
if ((Suppressions::Type::unique == type) && (lineNumber != NO_LINE) && (lineNumber != errmsg.lineNumber)) {
|
||||||
if (!thisAndNextLine || lineNumber + 1 != errmsg.lineNumber)
|
if (!thisAndNextLine || lineNumber + 1 != errmsg.lineNumber)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if ((Suppressions::Type::block == type) && ((errmsg.lineNumber < lineBegin) || (errmsg.lineNumber > lineEnd)))
|
||||||
|
return false;
|
||||||
if (!symbolName.empty()) {
|
if (!symbolName.empty()) {
|
||||||
for (std::string::size_type pos = 0; pos < errmsg.symbolNames.size();) {
|
for (std::string::size_type pos = 0; pos < errmsg.symbolNames.size();) {
|
||||||
const std::string::size_type pos2 = errmsg.symbolNames.find('\n',pos);
|
const std::string::size_type pos2 = errmsg.symbolNames.find('\n',pos);
|
||||||
|
@ -385,15 +395,16 @@ std::string Suppressions::Suppression::getText() const
|
||||||
bool Suppressions::isSuppressed(const Suppressions::ErrorMessage &errmsg, bool global)
|
bool Suppressions::isSuppressed(const Suppressions::ErrorMessage &errmsg, bool global)
|
||||||
{
|
{
|
||||||
const bool unmatchedSuppression(errmsg.errorId == "unmatchedSuppression");
|
const bool unmatchedSuppression(errmsg.errorId == "unmatchedSuppression");
|
||||||
|
bool return_value = false;
|
||||||
for (Suppression &s : mSuppressions) {
|
for (Suppression &s : mSuppressions) {
|
||||||
if (!global && !s.isLocal())
|
if (!global && !s.isLocal())
|
||||||
continue;
|
continue;
|
||||||
if (unmatchedSuppression && s.errorId != errmsg.errorId)
|
if (unmatchedSuppression && s.errorId != errmsg.errorId)
|
||||||
continue;
|
continue;
|
||||||
if (s.isMatch(errmsg))
|
if (s.isMatch(errmsg))
|
||||||
return true;
|
return_value = true;
|
||||||
}
|
}
|
||||||
return false;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Suppressions::isSuppressed(const ::ErrorMessage &errmsg)
|
bool Suppressions::isSuppressed(const ::ErrorMessage &errmsg)
|
||||||
|
@ -470,7 +481,15 @@ void Suppressions::markUnmatchedInlineSuppressionsAsChecked(const Tokenizer &tok
|
||||||
currLineNr = tok->linenr();
|
currLineNr = tok->linenr();
|
||||||
currFileIdx = tok->fileIndex();
|
currFileIdx = tok->fileIndex();
|
||||||
for (auto &suppression : mSuppressions) {
|
for (auto &suppression : mSuppressions) {
|
||||||
if (!suppression.checked && (suppression.lineNumber == currLineNr) && (suppression.fileName == tokenizer.list.file(tok))) {
|
if (suppression.type == Suppressions::Type::unique) {
|
||||||
|
if (!suppression.checked && (suppression.lineNumber == currLineNr) && (suppression.fileName == tokenizer.list.file(tok))) {
|
||||||
|
suppression.checked = true;
|
||||||
|
}
|
||||||
|
} else if (suppression.type == Suppressions::Type::block) {
|
||||||
|
if ((!suppression.checked && (suppression.lineBegin <= currLineNr) && (suppression.lineEnd >= currLineNr) && (suppression.fileName == tokenizer.list.file(tok)))) {
|
||||||
|
suppression.checked = true;
|
||||||
|
}
|
||||||
|
} else if (!suppression.checked && suppression.fileName == tokenizer.list.file(tok)) {
|
||||||
suppression.checked = true;
|
suppression.checked = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,10 @@ enum class Certainty;
|
||||||
class CPPCHECKLIB Suppressions {
|
class CPPCHECKLIB Suppressions {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum class Type {
|
||||||
|
unique, file, block, blockBegin, blockEnd
|
||||||
|
};
|
||||||
|
|
||||||
struct CPPCHECKLIB ErrorMessage {
|
struct CPPCHECKLIB ErrorMessage {
|
||||||
std::size_t hash;
|
std::size_t hash;
|
||||||
std::string errorId;
|
std::string errorId;
|
||||||
|
@ -77,6 +81,26 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator==(const Suppression &other) const {
|
||||||
|
if (errorId != other.errorId)
|
||||||
|
return false;
|
||||||
|
if (lineNumber < other.lineNumber)
|
||||||
|
return false;
|
||||||
|
if (fileName != other.fileName)
|
||||||
|
return false;
|
||||||
|
if (symbolName != other.symbolName)
|
||||||
|
return false;
|
||||||
|
if (hash != other.hash)
|
||||||
|
return false;
|
||||||
|
if (type != other.type)
|
||||||
|
return false;
|
||||||
|
if (lineBegin != other.lineBegin)
|
||||||
|
return false;
|
||||||
|
if (lineEnd != other.lineEnd)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse inline suppression in comment
|
* Parse inline suppression in comment
|
||||||
* @param comment the full comment text
|
* @param comment the full comment text
|
||||||
|
@ -107,6 +131,9 @@ public:
|
||||||
std::string errorId;
|
std::string errorId;
|
||||||
std::string fileName;
|
std::string fileName;
|
||||||
int lineNumber = NO_LINE;
|
int lineNumber = NO_LINE;
|
||||||
|
int lineBegin = NO_LINE;
|
||||||
|
int lineEnd = NO_LINE;
|
||||||
|
Type type = Type::unique;
|
||||||
std::string symbolName;
|
std::string symbolName;
|
||||||
std::size_t hash{};
|
std::size_t hash{};
|
||||||
bool thisAndNextLine{}; // Special case for backwards compatibility: { // cppcheck-suppress something
|
bool thisAndNextLine{}; // Special case for backwards compatibility: { // cppcheck-suppress something
|
||||||
|
|
|
@ -91,6 +91,11 @@ bool startsWith(const std::string& str, const char (&start)[N])
|
||||||
return startsWith(str, start, N - 1);
|
return startsWith(str, start, N - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool startsWith(const std::string& str, const std::string& start)
|
||||||
|
{
|
||||||
|
return startsWith(str, start.c_str(), start.length());
|
||||||
|
}
|
||||||
|
|
||||||
inline bool endsWith(const std::string &str, char c)
|
inline bool endsWith(const std::string &str, char c)
|
||||||
{
|
{
|
||||||
return !str.empty() && str.back() == c;
|
return !str.empty() && str.back() == c;
|
||||||
|
|
|
@ -531,6 +531,26 @@ Suppressing multiple ids in one comment by using []:
|
||||||
|
|
||||||
// cppcheck-suppress [aaaa, bbbb]
|
// cppcheck-suppress [aaaa, bbbb]
|
||||||
|
|
||||||
|
Suppressing warnings `aaaa` on a block of code:
|
||||||
|
|
||||||
|
// cppcheck-suppress-begin aaaa
|
||||||
|
...
|
||||||
|
// cppcheck-suppress-end aaaa
|
||||||
|
|
||||||
|
Suppressing multiple ids on a block of code:
|
||||||
|
|
||||||
|
// cppcheck-suppress-begin [aaaa, bbbb]
|
||||||
|
...
|
||||||
|
// cppcheck-suppress-end [aaaa, bbbb]
|
||||||
|
|
||||||
|
Suppressing warnings `aaaa` for a whole file:
|
||||||
|
|
||||||
|
// cppcheck-suppress-file aaaa
|
||||||
|
|
||||||
|
Suppressing multiple ids for a whole file:
|
||||||
|
|
||||||
|
// cppcheck-suppress-file [aaaa, bbbb]
|
||||||
|
|
||||||
### Comment before code or on same line
|
### Comment before code or on same line
|
||||||
|
|
||||||
The comment can be put before the code or at the same line as the code.
|
The comment can be put before the code or at the same line as the code.
|
||||||
|
|
|
@ -277,7 +277,7 @@ private:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void runChecks(unsigned int (TestSuppressions::*check)(const char[], const std::string &)) {
|
void runChecks(unsigned int (TestSuppressions::*check)(const char[], const std::string &)) {
|
||||||
// check to make sure the appropriate error is present
|
// check to make sure the appropriate errors are present
|
||||||
ASSERT_EQUALS(1, (this->*check)("void f() {\n"
|
ASSERT_EQUALS(1, (this->*check)("void f() {\n"
|
||||||
" int a;\n"
|
" int a;\n"
|
||||||
" a++;\n"
|
" a++;\n"
|
||||||
|
@ -285,6 +285,16 @@ private:
|
||||||
""));
|
""));
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
|
||||||
|
|
||||||
|
ASSERT_EQUALS(1, (this->*check)("void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" a++;\n"
|
||||||
|
" int b;\n"
|
||||||
|
" b++;\n"
|
||||||
|
"}\n",
|
||||||
|
""));
|
||||||
|
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n"
|
||||||
|
"[test.cpp:5]: (error) Uninitialized variable: b\n", errout.str());
|
||||||
|
|
||||||
// suppress uninitvar globally
|
// suppress uninitvar globally
|
||||||
ASSERT_EQUALS(0, (this->*check)("void f() {\n"
|
ASSERT_EQUALS(0, (this->*check)("void f() {\n"
|
||||||
" int a;\n"
|
" int a;\n"
|
||||||
|
@ -293,6 +303,59 @@ private:
|
||||||
"uninitvar"));
|
"uninitvar"));
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
(this->*check)("void f() {\n"
|
||||||
|
" // cppcheck-suppress-file uninitvar\n"
|
||||||
|
" int a;\n"
|
||||||
|
" a++;\n"
|
||||||
|
"}\n",
|
||||||
|
"");
|
||||||
|
ASSERT_EQUALS("[test.cpp:2]: (error) File suppression should be at the top of the file\n"
|
||||||
|
"[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
|
||||||
|
|
||||||
|
(this->*check)("void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" a++;\n"
|
||||||
|
"}\n"
|
||||||
|
"// cppcheck-suppress-file uninitvar\n",
|
||||||
|
"");
|
||||||
|
ASSERT_EQUALS("[test.cpp:5]: (error) File suppression should be at the top of the file\n"
|
||||||
|
"[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
|
||||||
|
|
||||||
|
ASSERT_EQUALS(0, (this->*check)("// cppcheck-suppress-file uninitvar\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" a++;\n"
|
||||||
|
" int b;\n"
|
||||||
|
" b++;\n"
|
||||||
|
"}\n",
|
||||||
|
""));
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
ASSERT_EQUALS(0, (this->*check)("/* Fake file description\n"
|
||||||
|
" * End\n"
|
||||||
|
" */\n"
|
||||||
|
"\n"
|
||||||
|
"// cppcheck-suppress-file uninitvar\n"
|
||||||
|
"\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" a++;\n"
|
||||||
|
" int b;\n"
|
||||||
|
" b++;\n"
|
||||||
|
"}\n",
|
||||||
|
""));
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
(this->*check)("// cppcheck-suppress-file uninitvar\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" a++;\n"
|
||||||
|
" int b;\n"
|
||||||
|
" b++;\n"
|
||||||
|
"}\n",
|
||||||
|
"");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
// suppress uninitvar globally, without error present
|
// suppress uninitvar globally, without error present
|
||||||
ASSERT_EQUALS(0, (this->*check)("void f() {\n"
|
ASSERT_EQUALS(0, (this->*check)("void f() {\n"
|
||||||
" int a;\n"
|
" int a;\n"
|
||||||
|
@ -301,6 +364,14 @@ private:
|
||||||
"uninitvar"));
|
"uninitvar"));
|
||||||
ASSERT_EQUALS("(information) Unmatched suppression: uninitvar\n", errout.str());
|
ASSERT_EQUALS("(information) Unmatched suppression: uninitvar\n", errout.str());
|
||||||
|
|
||||||
|
(this->*check)("// cppcheck-suppress-file uninitvar\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" b++;\n"
|
||||||
|
"}\n",
|
||||||
|
"");
|
||||||
|
ASSERT_EQUALS("[test.cpp:1]: (information) Unmatched suppression: uninitvar\n", errout.str());
|
||||||
|
|
||||||
// suppress uninitvar for this file only
|
// suppress uninitvar for this file only
|
||||||
ASSERT_EQUALS(0, (this->*check)("void f() {\n"
|
ASSERT_EQUALS(0, (this->*check)("void f() {\n"
|
||||||
" int a;\n"
|
" int a;\n"
|
||||||
|
@ -479,6 +550,222 @@ private:
|
||||||
"");
|
"");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (information) Unmatched suppression: uninitvar\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (information) Unmatched suppression: uninitvar\n", errout.str());
|
||||||
|
|
||||||
|
// suppress block inline checks
|
||||||
|
ASSERT_EQUALS(0, (this->*check)("void f() {\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" int a;\n"
|
||||||
|
" a++;\n"
|
||||||
|
" int b;\n"
|
||||||
|
" b++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
"}\n",
|
||||||
|
""));
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
ASSERT_EQUALS(1, (this->*check)("void f() {\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" int a;\n"
|
||||||
|
" a++;\n"
|
||||||
|
" int b;\n"
|
||||||
|
" b++;\n"
|
||||||
|
"}\n",
|
||||||
|
""));
|
||||||
|
ASSERT_EQUALS("[test.cpp:2]: (error) Suppress Begin: No matching end\n"
|
||||||
|
"[test.cpp:4]: (error) Uninitialized variable: a\n"
|
||||||
|
"[test.cpp:6]: (error) Uninitialized variable: b\n", errout.str());
|
||||||
|
|
||||||
|
ASSERT_EQUALS(1, (this->*check)("void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" a++;\n"
|
||||||
|
" int b;\n"
|
||||||
|
" b++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
"}\n",
|
||||||
|
""));
|
||||||
|
ASSERT_EQUALS("[test.cpp:6]: (error) Suppress End: No matching begin\n"
|
||||||
|
"[test.cpp:3]: (error) Uninitialized variable: a\n"
|
||||||
|
"[test.cpp:5]: (error) Uninitialized variable: b\n", errout.str());
|
||||||
|
|
||||||
|
ASSERT_EQUALS(1, (this->*check)("void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" a++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
" int b;\n"
|
||||||
|
" b++;\n"
|
||||||
|
"}\n",
|
||||||
|
""));
|
||||||
|
ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: b\n", errout.str());
|
||||||
|
|
||||||
|
ASSERT_EQUALS(1, (this->*check)("void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" a++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
" int b;\n"
|
||||||
|
" b++;\n"
|
||||||
|
"}\n",
|
||||||
|
""));
|
||||||
|
ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: b\n", errout.str());
|
||||||
|
|
||||||
|
ASSERT_EQUALS(1, (this->*check)("void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" // cppcheck-suppress-begin[uninitvar]\n"
|
||||||
|
" a++;\n"
|
||||||
|
" // cppcheck-suppress-end[uninitvar]\n"
|
||||||
|
" int b;\n"
|
||||||
|
" b++;\n"
|
||||||
|
"}\n",
|
||||||
|
""));
|
||||||
|
ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: b\n", errout.str());
|
||||||
|
|
||||||
|
ASSERT_EQUALS(1, (this->*check)("void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" // cppcheck-suppress-begin [uninitvar]\n"
|
||||||
|
" a++;\n"
|
||||||
|
" // cppcheck-suppress-end [uninitvar]\n"
|
||||||
|
" int b;\n"
|
||||||
|
" b++;\n"
|
||||||
|
"}\n",
|
||||||
|
""));
|
||||||
|
ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: b\n", errout.str());
|
||||||
|
|
||||||
|
(this->*check)("void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" a++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
" int b;\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" b++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
"}\n",
|
||||||
|
"");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
(this->*check)("void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" a++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" int b;\n"
|
||||||
|
" b++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
"}\n",
|
||||||
|
"");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
(this->*check)("void f() {\n"
|
||||||
|
" // cppcheck-suppress-begin [uninitvar]\n"
|
||||||
|
" int a;\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" a++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
" int b;\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" b++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
" // cppcheck-suppress-end [uninitvar]\n"
|
||||||
|
"}\n",
|
||||||
|
"");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
(this->*check)("void f() {\n"
|
||||||
|
" // cppcheck-suppress-begin [uninitvar, syntaxError]\n"
|
||||||
|
" int a;\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" a++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
" int b;\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" b++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
" // cppcheck-suppress-end [uninitvar, syntaxError]\n"
|
||||||
|
"}\n",
|
||||||
|
"");
|
||||||
|
ASSERT_EQUALS("[test.cpp:2]: (information) Unmatched suppression: syntaxError\n", errout.str());
|
||||||
|
|
||||||
|
(this->*check)("// cppcheck-suppress-begin [uninitvar, syntaxError]\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" a++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
" int b;\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" b++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
"}\n"
|
||||||
|
"// cppcheck-suppress-end [uninitvar, syntaxError]\n",
|
||||||
|
"");
|
||||||
|
ASSERT_EQUALS("[test.cpp:1]: (information) Unmatched suppression: syntaxError\n", errout.str());
|
||||||
|
|
||||||
|
(this->*check)("// cppcheck-suppress-begin [uninitvar, syntaxError]\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" a++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
" int b;\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" b++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
"}\n"
|
||||||
|
"// cppcheck-suppress-end [uninitvar, syntaxError]",
|
||||||
|
"");
|
||||||
|
ASSERT_EQUALS("[test.cpp:1]: (information) Unmatched suppression: syntaxError\n", errout.str());
|
||||||
|
|
||||||
|
// test of multiple suppression types
|
||||||
|
(this->*check)("// cppcheck-suppress-file uninitvar\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" // cppcheck-suppress uninitvar\n"
|
||||||
|
" a++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
"}\n",
|
||||||
|
"");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
(this->*check)("void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" // cppcheck-suppress uninitvar\n"
|
||||||
|
" a++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
"}\n",
|
||||||
|
"");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
(this->*check)("// cppcheck-suppress-file uninitvar\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" // cppcheck-suppress uninitvar\n"
|
||||||
|
" a++;\n"
|
||||||
|
"}\n",
|
||||||
|
"");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
(this->*check)("// cppcheck-suppress-file uninitvar\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" // cppcheck-suppress-begin uninitvar\n"
|
||||||
|
" a++;\n"
|
||||||
|
" // cppcheck-suppress-end uninitvar\n"
|
||||||
|
"}\n",
|
||||||
|
"");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
(this->*check)("// cppcheck-suppress-file uninitvar\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" // cppcheck-suppress uninitvar\n"
|
||||||
|
" int a;\n"
|
||||||
|
" a++;\n"
|
||||||
|
"}\n",
|
||||||
|
"");
|
||||||
|
ASSERT_EQUALS("[test.cpp:4]: (information) Unmatched suppression: uninitvar\n", errout.str());
|
||||||
|
|
||||||
// #5746 - exitcode
|
// #5746 - exitcode
|
||||||
ASSERT_EQUALS(1U,
|
ASSERT_EQUALS(1U,
|
||||||
(this->*check)("int f() {\n"
|
(this->*check)("int f() {\n"
|
||||||
|
@ -571,15 +858,42 @@ private:
|
||||||
void inlinesuppress() const {
|
void inlinesuppress() const {
|
||||||
Suppressions::Suppression s;
|
Suppressions::Suppression s;
|
||||||
std::string msg;
|
std::string msg;
|
||||||
|
|
||||||
|
// Suppress without attribute
|
||||||
ASSERT_EQUALS(false, s.parseComment("/* some text */", &msg));
|
ASSERT_EQUALS(false, s.parseComment("/* some text */", &msg));
|
||||||
ASSERT_EQUALS(false, s.parseComment("/* cppcheck-suppress */", &msg));
|
ASSERT_EQUALS(false, s.parseComment("/* cppcheck-suppress */", &msg));
|
||||||
|
ASSERT_EQUALS(false, s.parseComment("/* cppcheck-suppress-file */", &msg));
|
||||||
|
ASSERT_EQUALS(false, s.parseComment("/* cppcheck-suppress-begin */", &msg));
|
||||||
|
ASSERT_EQUALS(false, s.parseComment("/* cppcheck-suppress-end */", &msg));
|
||||||
|
|
||||||
|
// Correct suppress
|
||||||
msg.clear();
|
msg.clear();
|
||||||
ASSERT_EQUALS(true, s.parseComment("/* cppcheck-suppress id */", &msg));
|
ASSERT_EQUALS(true, s.parseComment("/* cppcheck-suppress id */", &msg));
|
||||||
ASSERT_EQUALS("", msg);
|
ASSERT_EQUALS("", msg);
|
||||||
|
|
||||||
|
msg.clear();
|
||||||
|
ASSERT_EQUALS(true, s.parseComment("/* cppcheck-suppress-file id */", &msg));
|
||||||
|
ASSERT_EQUALS("", msg);
|
||||||
|
|
||||||
|
msg.clear();
|
||||||
|
ASSERT_EQUALS(true, s.parseComment("/* cppcheck-suppress-begin id */", &msg));
|
||||||
|
ASSERT_EQUALS("", msg);
|
||||||
|
|
||||||
|
msg.clear();
|
||||||
|
ASSERT_EQUALS(true, s.parseComment("/* cppcheck-suppress-end id */", &msg));
|
||||||
|
ASSERT_EQUALS("", msg);
|
||||||
|
|
||||||
|
// Bad attribute construction
|
||||||
|
const std::string badSuppressionAttribute = "Bad suppression attribute 'some'. You can write comments in the comment after a ; or //. Valid suppression attributes; symbolName=sym";
|
||||||
|
|
||||||
ASSERT_EQUALS(true, s.parseComment("/* cppcheck-suppress id some text */", &msg));
|
ASSERT_EQUALS(true, s.parseComment("/* cppcheck-suppress id some text */", &msg));
|
||||||
ASSERT_EQUALS("Bad suppression attribute 'some'. You can write comments in the comment after a ; or //. Valid suppression attributes; symbolName=sym", msg);
|
ASSERT_EQUALS(badSuppressionAttribute, msg);
|
||||||
|
ASSERT_EQUALS(true, s.parseComment("/* cppcheck-suppress-file id some text */", &msg));
|
||||||
|
ASSERT_EQUALS(badSuppressionAttribute, msg);
|
||||||
|
ASSERT_EQUALS(true, s.parseComment("/* cppcheck-suppress-begin id some text */", &msg));
|
||||||
|
ASSERT_EQUALS(badSuppressionAttribute, msg);
|
||||||
|
ASSERT_EQUALS(true, s.parseComment("/* cppcheck-suppress-end id some text */", &msg));
|
||||||
|
ASSERT_EQUALS(badSuppressionAttribute, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void inlinesuppress_symbolname() {
|
void inlinesuppress_symbolname() {
|
||||||
|
@ -622,6 +936,48 @@ private:
|
||||||
ASSERT_EQUALS("", suppressions[0].symbolName);
|
ASSERT_EQUALS("", suppressions[0].symbolName);
|
||||||
ASSERT_EQUALS("", errMsg);
|
ASSERT_EQUALS("", errMsg);
|
||||||
|
|
||||||
|
errMsg = "";
|
||||||
|
suppressions=Suppressions::parseMultiSuppressComment("// cppcheck-suppress-begin[errorId]", &errMsg);
|
||||||
|
ASSERT_EQUALS(1, suppressions.size());
|
||||||
|
ASSERT_EQUALS("errorId", suppressions[0].errorId);
|
||||||
|
ASSERT_EQUALS("", suppressions[0].symbolName);
|
||||||
|
ASSERT_EQUALS("", errMsg);
|
||||||
|
|
||||||
|
errMsg = "";
|
||||||
|
suppressions=Suppressions::parseMultiSuppressComment("// cppcheck-suppress-begin [errorId]", &errMsg);
|
||||||
|
ASSERT_EQUALS(1, suppressions.size());
|
||||||
|
ASSERT_EQUALS("errorId", suppressions[0].errorId);
|
||||||
|
ASSERT_EQUALS("", suppressions[0].symbolName);
|
||||||
|
ASSERT_EQUALS("", errMsg);
|
||||||
|
|
||||||
|
errMsg = "";
|
||||||
|
suppressions=Suppressions::parseMultiSuppressComment("// cppcheck-suppress-end[errorId]", &errMsg);
|
||||||
|
ASSERT_EQUALS(1, suppressions.size());
|
||||||
|
ASSERT_EQUALS("errorId", suppressions[0].errorId);
|
||||||
|
ASSERT_EQUALS("", suppressions[0].symbolName);
|
||||||
|
ASSERT_EQUALS("", errMsg);
|
||||||
|
|
||||||
|
errMsg = "";
|
||||||
|
suppressions=Suppressions::parseMultiSuppressComment("// cppcheck-suppress-end [errorId]", &errMsg);
|
||||||
|
ASSERT_EQUALS(1, suppressions.size());
|
||||||
|
ASSERT_EQUALS("errorId", suppressions[0].errorId);
|
||||||
|
ASSERT_EQUALS("", suppressions[0].symbolName);
|
||||||
|
ASSERT_EQUALS("", errMsg);
|
||||||
|
|
||||||
|
errMsg = "";
|
||||||
|
suppressions=Suppressions::parseMultiSuppressComment("// cppcheck-suppress-file[errorId]", &errMsg);
|
||||||
|
ASSERT_EQUALS(1, suppressions.size());
|
||||||
|
ASSERT_EQUALS("errorId", suppressions[0].errorId);
|
||||||
|
ASSERT_EQUALS("", suppressions[0].symbolName);
|
||||||
|
ASSERT_EQUALS("", errMsg);
|
||||||
|
|
||||||
|
errMsg = "";
|
||||||
|
suppressions=Suppressions::parseMultiSuppressComment("// cppcheck-suppress-file [errorId]", &errMsg);
|
||||||
|
ASSERT_EQUALS(1, suppressions.size());
|
||||||
|
ASSERT_EQUALS("errorId", suppressions[0].errorId);
|
||||||
|
ASSERT_EQUALS("", suppressions[0].symbolName);
|
||||||
|
ASSERT_EQUALS("", errMsg);
|
||||||
|
|
||||||
errMsg = "";
|
errMsg = "";
|
||||||
suppressions=Suppressions::parseMultiSuppressComment("// cppcheck-suppress[errorId symbolName=arr]", &errMsg);
|
suppressions=Suppressions::parseMultiSuppressComment("// cppcheck-suppress[errorId symbolName=arr]", &errMsg);
|
||||||
ASSERT_EQUALS(1, suppressions.size());
|
ASSERT_EQUALS(1, suppressions.size());
|
||||||
|
|
Loading…
Reference in New Issue