Warn when there is a unknown macro

This commit is contained in:
Daniel Marjamäki 2018-11-13 16:49:02 +01:00
parent 69e7392ce2
commit e6a5e0f752
4 changed files with 27 additions and 15 deletions

View File

@ -4198,12 +4198,15 @@ void Tokenizer::removeMacrosInGlobalScope()
tok->deleteNext(); tok->deleteNext();
} }
if ((!tok->previous() || Token::Match(tok->previous(), "[;{}]")) && if (Token::Match(tok, "%type%") && tok->isUpperCaseName() &&
Token::Match(tok, "%type%") && tok->isUpperCaseName()) { (!tok->previous() || Token::Match(tok->previous(), "[;{}]") || (tok->previous()->isName() && endsWith(tok->previous()->str(), ':')))) {
const Token *tok2 = tok->next(); const Token *tok2 = tok->next();
if (tok2 && tok2->str() == "(") if (tok2 && tok2->str() == "(")
tok2 = tok2->link()->next(); tok2 = tok2->link()->next();
if (Token::Match(tok, "%type% (") && Token::Match(tok2, "%type% (") && isFunctionHead(tok2->next(), "{"))
unknownMacroError(tok);
// remove unknown macros before namespace|class|struct|union // remove unknown macros before namespace|class|struct|union
if (Token::Match(tok2, "namespace|class|struct|union")) { if (Token::Match(tok2, "namespace|class|struct|union")) {
// is there a "{" for? // is there a "{" for?
@ -4218,14 +4221,15 @@ void Tokenizer::removeMacrosInGlobalScope()
} }
// replace unknown macros before foo( // replace unknown macros before foo(
if (Token::Match(tok2, "%type% (") && isFunctionHead(tok2->next(), "{")) { /*
std::string typeName; if (Token::Match(tok2, "%type% (") && isFunctionHead(tok2->next(), "{")) {
for (const Token* tok3 = tok; tok3 != tok2; tok3 = tok3->next()) std::string typeName;
typeName += tok3->str(); for (const Token* tok3 = tok; tok3 != tok2; tok3 = tok3->next())
Token::eraseTokens(tok, tok2); typeName += tok3->str();
tok->str(typeName); Token::eraseTokens(tok, tok2);
} tok->str(typeName);
}
*/
// remove unknown macros before foo::foo( // remove unknown macros before foo::foo(
if (Token::Match(tok2, "%type% :: %type%")) { if (Token::Match(tok2, "%type% :: %type%")) {
const Token *tok3 = tok2; const Token *tok3 = tok2;
@ -7916,6 +7920,12 @@ void Tokenizer::syntaxErrorC(const Token *tok, const std::string &what) const
throw InternalError(tok, "Code '"+what+"' is invalid C code. Use --std or --language to configure the language.", InternalError::SYNTAX); throw InternalError(tok, "Code '"+what+"' is invalid C code. Use --std or --language to configure the language.", InternalError::SYNTAX);
} }
void Tokenizer::unknownMacroError(const Token *tok1) const
{
printDebugOutput(0);
throw InternalError(tok1, "There is an unknown macro here somewhere. Configuration is required. If " + tok1->str() + " is a macro then please configure it.", InternalError::SYNTAX);
}
void Tokenizer::unhandled_macro_class_x_y(const Token *tok) const void Tokenizer::unhandled_macro_class_x_y(const Token *tok) const
{ {
reportError(tok, reportError(tok,

View File

@ -598,6 +598,9 @@ public:
/** Syntax error. C++ code in C file. */ /** Syntax error. C++ code in C file. */
void syntaxErrorC(const Token *tok, const std::string &what) const; void syntaxErrorC(const Token *tok, const std::string &what) const;
/** Warn about unknown macro(s), configuration is recommended */
void unknownMacroError(const Token *tok1) const;
private: private:
/** Report that there is an unhandled "class x y {" code */ /** Report that there is an unhandled "class x y {" code */

View File

@ -1448,9 +1448,8 @@ private:
const char code[] = "typedef char (* type1)[10];\n" const char code[] = "typedef char (* type1)[10];\n"
"LOCAL(type1) foo() { }"; "LOCAL(type1) foo() { }";
// this is invalid C so just make sure it doesn't generate an internal error // this is invalid C, assert that an "unknown macro" warning is written
checkSimplifyTypedef(code); ASSERT_THROW(checkSimplifyTypedef(code), InternalError);
ASSERT_EQUALS("", errout.str());
} }
} }

View File

@ -6155,8 +6155,8 @@ private:
ASSERT_EQUALS("; foo :: foo ( ) { }", ASSERT_EQUALS("; foo :: foo ( ) { }",
tokenizeAndStringify("; AB(foo*) foo::foo() { }")); tokenizeAndStringify("; AB(foo*) foo::foo() { }"));
// #4834 // #4834 - syntax error
ASSERT_EQUALS("A(B) foo ( ) { }", tokenizeAndStringify("A(B) foo() {}")); ASSERT_THROW(tokenizeAndStringify("A(B) foo() {}"), InternalError);
// #3855 // #3855
ASSERT_EQUALS("; class foo { }", ASSERT_EQUALS("; class foo { }",