Suppressions: Validate inline suppressions

This commit is contained in:
Daniel Marjamäki 2018-04-11 08:18:00 +02:00
parent 3fc53eb122
commit a0c9de0048
4 changed files with 77 additions and 19 deletions

View File

@ -67,30 +67,27 @@ Preprocessor::~Preprocessor()
delete it->second;
}
namespace {
struct BadInlineSuppression {
BadInlineSuppression(const simplecpp::Location &l, const std::string &msg) : location(l), errmsg(msg) {}
simplecpp::Location location;
std::string errmsg;
};
}
static void inlineSuppressions(const simplecpp::TokenList &tokens, Settings &_settings)
static void inlineSuppressions(const simplecpp::TokenList &tokens, Settings &_settings, std::list<BadInlineSuppression> *bad)
{
std::list<Suppressions::Suppression> inlineSuppressions;
for (const simplecpp::Token *tok = tokens.cfront(); tok; tok = tok->next) {
if (tok->comment) {
std::istringstream iss(tok->str.substr(2));
std::string word;
iss >> word;
if (word != "cppcheck-suppress")
continue;
Suppressions::Suppression s;
iss >> s.errorId;
if (!iss)
std::string errmsg;
if (!s.parseComment(tok->str, &errmsg))
continue;
while (iss) {
iss >> word;
if (!iss)
break;
if (word.compare(0,11,"symbolName=")==0)
s.symbolName = word.substr(11);
}
inlineSuppressions.push_back(s);
if (!errmsg.empty())
bad->push_back(BadInlineSuppression(tok->location, errmsg));
if (!s.errorId.empty())
inlineSuppressions.push_back(s);
continue;
}
@ -123,10 +120,14 @@ void Preprocessor::inlineSuppressions(const simplecpp::TokenList &tokens)
{
if (!_settings.inlineSuppressions)
return;
::inlineSuppressions(tokens, _settings);
std::list<BadInlineSuppression> err;
::inlineSuppressions(tokens, _settings, &err);
for (std::map<std::string,simplecpp::TokenList*>::const_iterator it = tokenlists.begin(); it != tokenlists.end(); ++it) {
if (it->second)
::inlineSuppressions(*it->second, _settings);
::inlineSuppressions(*it->second, _settings, &err);
}
for (const BadInlineSuppression &bad : err) {
error(bad.location.file(), bad.location.line, bad.errmsg);
}
}

View File

@ -176,6 +176,40 @@ void Suppressions::ErrorMessage::setFileName(const std::string &s)
_fileName = Path::simplifyPath(s);
}
bool Suppressions::Suppression::parseComment(std::string comment, std::string *errorMessage)
{
if (comment.size() < 2)
return false;
if (comment.find(";") != std::string::npos)
comment.erase(comment.find(";"));
if (comment.find("//", 2) != std::string::npos)
comment.erase(comment.find("//",2));
if (comment.compare(comment.size() - 2, 2, "*/") == 0)
comment.erase(comment.size() - 2, 2);
std::istringstream iss(comment.substr(2));
std::string word;
iss >> word;
if (word != "cppcheck-suppress")
return false;
iss >> errorId;
if (!iss)
return false;
while (iss) {
iss >> word;
if (!iss)
break;
if (word.compare(0,11,"symbolName=")==0)
symbolName = word.substr(11);
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";
}
return true;
}
bool Suppressions::Suppression::isSuppressed(const Suppressions::ErrorMessage &errmsg) const
{
if (!errorId.empty() && !matchglob(errorId, errmsg.errorId))

View File

@ -74,6 +74,14 @@ public:
return symbolName < other.symbolName;
};
/**
* Parse inline suppression in comment
* @param comment the full comment text
* @param errorMessage output parameter for error message (wrong suppression attribute)
* @return true if it is a inline comment.
*/
bool parseComment(std::string comment, std::string *errorMessage);
bool isSuppressed(const ErrorMessage &errmsg) const;
bool isMatch(const ErrorMessage &errmsg);

View File

@ -47,6 +47,7 @@ private:
TEST_CASE(suppressionsMultiFile);
TEST_CASE(suppressionsPathSeparator);
TEST_CASE(inlinesuppress);
TEST_CASE(inlinesuppress_symbolname);
TEST_CASE(inlinesuppress_unusedFunction); // #4210 - unusedFunction
@ -397,6 +398,20 @@ private:
ASSERT_EQUALS(true, s2.isSuppressed(errorMessage("abc", "include/1.h", 142)));
}
void inlinesuppress() {
Suppressions::Suppression s;
std::string errmsg;
ASSERT_EQUALS(false, s.parseComment("/* some text */", &errmsg));
ASSERT_EQUALS(false, s.parseComment("/* cppcheck-suppress */", &errmsg));
errmsg.clear();
ASSERT_EQUALS(true, s.parseComment("/* cppcheck-suppress id */", &errmsg));
ASSERT_EQUALS("", errmsg);
ASSERT_EQUALS(true, s.parseComment("/* cppcheck-suppress id some text */", &errmsg));
ASSERT_EQUALS("Bad suppression attribute 'some'. You can write comments in the comment after a ; or //. Valid suppression attributes; symbolName=sym", errmsg);
}
void inlinesuppress_symbolname() {
Suppressions suppressions;