CheckInternal: Improved checking of multiCompare patterns
This commit is contained in:
parent
0877adb542
commit
62c608141d
|
@ -22,6 +22,7 @@
|
|||
#include "symboldatabase.h"
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <cstring>
|
||||
|
||||
// Register this check class (by creating a static instance of it).
|
||||
// Disabled in release builds
|
||||
|
@ -48,6 +49,32 @@ void CheckInternal::checkTokenMatchPatterns()
|
|||
continue;
|
||||
}
|
||||
|
||||
const char *p = pattern.c_str();
|
||||
while (*p) {
|
||||
while (*p && std::isspace(*p))
|
||||
p++;
|
||||
const char *start = p;
|
||||
while (*p && !std::isspace(*p))
|
||||
p++;
|
||||
const char *end = p - 1;
|
||||
if (start < end && !(*start == '[' && *end == ']')) {
|
||||
// check multicompare pattern..
|
||||
for (const char *s = start; s != end; s++) {
|
||||
if (*s == '|') {
|
||||
if (*(s+1) == '%' &&
|
||||
std::isalpha(*(s+2)) &&
|
||||
std::strncmp(s+1,"%op%",4)!=0 &&
|
||||
std::strncmp(s+1,"%or%",4)!=0 &&
|
||||
std::strncmp(s+1,"%cop%",5)!=0 &&
|
||||
std::strncmp(s+1,"%var%",5)!=0 &&
|
||||
std::strncmp(s+1,"%oror%",6)!=0) {
|
||||
multiComparePatternError(tok, pattern, funcname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for signs of complex patterns
|
||||
if (pattern.find_first_of("[|%") != std::string::npos)
|
||||
continue;
|
||||
|
@ -245,6 +272,13 @@ void CheckInternal::checkRedundantNextPrevious()
|
|||
}
|
||||
}
|
||||
|
||||
void CheckInternal::multiComparePatternError(const Token* tok, const std::string& pattern, const std::string &funcname)
|
||||
{
|
||||
reportError(tok, Severity::error, "multiComparePatternError",
|
||||
"Bad multicompare pattern (a %cmd% must be first unless it is %or%,%op%,%cop%,%var%,%oror%) inside Token::" + funcname + "() call: \"" + pattern + "\""
|
||||
);
|
||||
}
|
||||
|
||||
void CheckInternal::simplePatternError(const Token* tok, const std::string& pattern, const std::string &funcname)
|
||||
{
|
||||
reportError(tok, Severity::warning, "simplePatternError",
|
||||
|
|
|
@ -73,6 +73,7 @@ public:
|
|||
void checkRedundantNextPrevious();
|
||||
|
||||
private:
|
||||
void multiComparePatternError(const Token *tok, const std::string &pattern, const std::string &funcname);
|
||||
void simplePatternError(const Token *tok, const std::string &pattern, const std::string &funcname);
|
||||
void complexPatternError(const Token *tok, const std::string &pattern, const std::string &funcname);
|
||||
void missingPercentCharacterError(const Token *tok, const std::string &pattern, const std::string &funcname);
|
||||
|
@ -81,6 +82,7 @@ private:
|
|||
|
||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {
|
||||
CheckInternal c(0, settings, errorLogger);
|
||||
c.multiComparePatternError(0, ";|%type%", "Match");
|
||||
c.simplePatternError(0, "class {", "Match");
|
||||
c.complexPatternError(0, "%type% ( )", "Match");
|
||||
c.missingPercentCharacterError(0, "%num", "Match");
|
||||
|
|
|
@ -40,6 +40,7 @@ private:
|
|||
TEST_CASE(unknownPattern)
|
||||
TEST_CASE(redundantNextPrevious)
|
||||
TEST_CASE(internalError)
|
||||
TEST_CASE(invalidMultiCompare);
|
||||
}
|
||||
|
||||
void check(const char code[]) {
|
||||
|
@ -222,7 +223,9 @@ private:
|
|||
" const Token *tok;\n"
|
||||
" Token::Match(tok, \"foo|%type|bar\");\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Missing percent end character in Token::Match() pattern: \"foo|%type|bar\"\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Bad multicompare pattern (a %cmd% must be first unless it is %or%,%op%,%cop%,%var%,%oror%) inside Token::Match() call: \"foo|%type|bar\"\n"
|
||||
"[test.cpp:3]: (error) Missing percent end character in Token::Match() pattern: \"foo|%type|bar\"\n"
|
||||
, errout.str());
|
||||
|
||||
// Make sure we don't take %or% for a broken %oror%
|
||||
check("void f() {\n"
|
||||
|
@ -312,6 +315,21 @@ private:
|
|||
"};");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void invalidMultiCompare() {
|
||||
// #5310
|
||||
check("void f() {\n"
|
||||
" const Token *tok;\n"
|
||||
" Token::Match(tok, \";|%type%\");\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Bad multicompare pattern (a %cmd% must be first unless it is %or%,%op%,%cop%,%var%,%oror%) inside Token::Match() call: \";|%type%\"\n", errout.str());
|
||||
|
||||
check("void f() {\n"
|
||||
" const Token *tok;\n"
|
||||
" Token::Match(tok, \";|%oror%\");\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestInternal)
|
||||
|
|
Loading…
Reference in New Issue