Suppressions: Validate inline suppressions
This commit is contained in:
parent
3fc53eb122
commit
a0c9de0048
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue