Suppressions: Validate inline suppressions
This commit is contained in:
parent
3fc53eb122
commit
a0c9de0048
|
@ -67,30 +67,27 @@ Preprocessor::~Preprocessor()
|
||||||
delete it->second;
|
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;
|
std::list<Suppressions::Suppression> inlineSuppressions;
|
||||||
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) {
|
||||||
std::istringstream iss(tok->str.substr(2));
|
|
||||||
std::string word;
|
|
||||||
iss >> word;
|
|
||||||
if (word != "cppcheck-suppress")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Suppressions::Suppression s;
|
Suppressions::Suppression s;
|
||||||
iss >> s.errorId;
|
std::string errmsg;
|
||||||
if (!iss)
|
if (!s.parseComment(tok->str, &errmsg))
|
||||||
continue;
|
continue;
|
||||||
while (iss) {
|
if (!errmsg.empty())
|
||||||
iss >> word;
|
bad->push_back(BadInlineSuppression(tok->location, errmsg));
|
||||||
if (!iss)
|
if (!s.errorId.empty())
|
||||||
break;
|
inlineSuppressions.push_back(s);
|
||||||
if (word.compare(0,11,"symbolName=")==0)
|
|
||||||
s.symbolName = word.substr(11);
|
|
||||||
}
|
|
||||||
inlineSuppressions.push_back(s);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,10 +120,14 @@ void Preprocessor::inlineSuppressions(const simplecpp::TokenList &tokens)
|
||||||
{
|
{
|
||||||
if (!_settings.inlineSuppressions)
|
if (!_settings.inlineSuppressions)
|
||||||
return;
|
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) {
|
for (std::map<std::string,simplecpp::TokenList*>::const_iterator it = tokenlists.begin(); it != tokenlists.end(); ++it) {
|
||||||
if (it->second)
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -176,6 +176,40 @@ void Suppressions::ErrorMessage::setFileName(const std::string &s)
|
||||||
_fileName = Path::simplifyPath(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
|
bool Suppressions::Suppression::isSuppressed(const Suppressions::ErrorMessage &errmsg) const
|
||||||
{
|
{
|
||||||
if (!errorId.empty() && !matchglob(errorId, errmsg.errorId))
|
if (!errorId.empty() && !matchglob(errorId, errmsg.errorId))
|
||||||
|
|
|
@ -74,6 +74,14 @@ public:
|
||||||
return symbolName < other.symbolName;
|
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 isSuppressed(const ErrorMessage &errmsg) const;
|
||||||
|
|
||||||
bool isMatch(const ErrorMessage &errmsg);
|
bool isMatch(const ErrorMessage &errmsg);
|
||||||
|
|
|
@ -47,6 +47,7 @@ private:
|
||||||
TEST_CASE(suppressionsMultiFile);
|
TEST_CASE(suppressionsMultiFile);
|
||||||
TEST_CASE(suppressionsPathSeparator);
|
TEST_CASE(suppressionsPathSeparator);
|
||||||
|
|
||||||
|
TEST_CASE(inlinesuppress);
|
||||||
TEST_CASE(inlinesuppress_symbolname);
|
TEST_CASE(inlinesuppress_symbolname);
|
||||||
|
|
||||||
TEST_CASE(inlinesuppress_unusedFunction); // #4210 - unusedFunction
|
TEST_CASE(inlinesuppress_unusedFunction); // #4210 - unusedFunction
|
||||||
|
@ -397,6 +398,20 @@ private:
|
||||||
ASSERT_EQUALS(true, s2.isSuppressed(errorMessage("abc", "include/1.h", 142)));
|
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() {
|
void inlinesuppress_symbolname() {
|
||||||
Suppressions suppressions;
|
Suppressions suppressions;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue