Tokenizer: Add --check-config warning for macro with semicolon in argument
This commit is contained in:
parent
c16d82d729
commit
8ffed6862d
|
@ -3336,6 +3336,8 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
|
|||
if (const Token *garbage = findGarbageCode())
|
||||
syntaxError(garbage);
|
||||
|
||||
checkConfiguration();
|
||||
|
||||
// if (x) MACRO() ..
|
||||
for (const Token *tok = list.front(); tok; tok = tok->next()) {
|
||||
if (Token::simpleMatch(tok, "if (")) {
|
||||
|
@ -7638,6 +7640,14 @@ void Tokenizer::unhandled_macro_class_x_y(const Token *tok) const
|
|||
tok->strAt(3) + "' is not handled. You can use -I or --include to add handling of this code.");
|
||||
}
|
||||
|
||||
void Tokenizer::macroWithSemicolonError(const Token *tok, const std::string ¯oName) const
|
||||
{
|
||||
reportError(tok,
|
||||
Severity::information,
|
||||
"macroWithSemicolon",
|
||||
"Ensure that '" + macroName + "' is defined either using -I, --include or -D.");
|
||||
}
|
||||
|
||||
void Tokenizer::cppcheckError(const Token *tok) const
|
||||
{
|
||||
printDebugOutput(0);
|
||||
|
@ -8004,6 +8014,25 @@ void Tokenizer::simplifyComma()
|
|||
}
|
||||
}
|
||||
|
||||
void Tokenizer::checkConfiguration() const
|
||||
{
|
||||
if (!_settings->checkConfiguration)
|
||||
return;
|
||||
for (const Token *tok = tokens(); tok; tok = tok->next()) {
|
||||
if (!Token::Match(tok, "%name% ("))
|
||||
continue;
|
||||
if (Token::Match(tok, "if|for|while|switch"))
|
||||
continue;
|
||||
for (const Token *tok2 = tok->tokAt(2); tok2 && tok2->str() != ")"; tok2 = tok2->next()) {
|
||||
if (tok2->str() == ";") {
|
||||
macroWithSemicolonError(tok, tok->str());
|
||||
break;
|
||||
}
|
||||
if (Token::Match(tok2, "(|{"))
|
||||
tok2 = tok2->link();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Tokenizer::validateC() const
|
||||
{
|
||||
|
|
|
@ -576,6 +576,10 @@ private:
|
|||
/** Report that there is an unhandled "class x y {" code */
|
||||
void unhandled_macro_class_x_y(const Token *tok) const;
|
||||
|
||||
/** Check configuration (unknown macros etc) */
|
||||
void checkConfiguration() const;
|
||||
void macroWithSemicolonError(const Token *tok, const std::string ¯oName) const;
|
||||
|
||||
/**
|
||||
* Is there C++ code in C file?
|
||||
*/
|
||||
|
|
|
@ -457,6 +457,9 @@ private:
|
|||
// Make sure the Tokenizer::findGarbageCode() does not have false positives
|
||||
// The TestGarbage ensures that there are true positives
|
||||
TEST_CASE(findGarbageCode);
|
||||
|
||||
// --check-config
|
||||
TEST_CASE(checkConfiguration);
|
||||
}
|
||||
|
||||
std::string tokenizeAndStringify(const char code[], bool simplify = false, bool expand = true, Settings::PlatformType platform = Settings::Native, const char* filename = "test.cpp", bool cpp11 = true) {
|
||||
|
@ -8250,6 +8253,24 @@ private:
|
|||
// after (expr)
|
||||
ASSERT_NO_THROW(tokenizeAndStringify("void f() { switch (a) int b; }"));
|
||||
}
|
||||
|
||||
|
||||
void checkConfig(const char code[]) {
|
||||
errout.str("");
|
||||
|
||||
Settings s;
|
||||
s.checkConfiguration = true;
|
||||
|
||||
// tokenize..
|
||||
Tokenizer tokenizer(&s, this);
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
}
|
||||
|
||||
void checkConfiguration() {
|
||||
checkConfig("void f() { DEBUG(x();y()); }");
|
||||
ASSERT_EQUALS("[test.cpp:1]: (information) Ensure that 'DEBUG' is defined either using -I, --include or -D.\n", errout.str());
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestTokenizer)
|
||||
|
|
Loading…
Reference in New Issue