Report unknown macros for pattern '%name% %num%'
This commit is contained in:
parent
a62ddc6edd
commit
f07a71e3e1
|
@ -4302,7 +4302,7 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
|
|||
|
||||
createLinks();
|
||||
|
||||
reportUnknownMacrosInNonExecutableScopes();
|
||||
reportUnknownMacros();
|
||||
|
||||
simplifyHeaders();
|
||||
|
||||
|
@ -9285,8 +9285,21 @@ static bool isCPPAttribute(const Token * tok)
|
|||
return Token::simpleMatch(tok, "[ [") && tok->link() && tok->link()->previous() == tok->linkAt(1);
|
||||
}
|
||||
|
||||
void Tokenizer::reportUnknownMacrosInNonExecutableScopes()
|
||||
void Tokenizer::reportUnknownMacros()
|
||||
{
|
||||
// Report unknown macros used in expressions "%name% %num%"
|
||||
for (const Token *tok = tokens(); tok; tok = tok->next()) {
|
||||
if (Token::Match(tok, "%name% %num%")) {
|
||||
// A keyword is not an unknown macro
|
||||
if (list.isKeyword(tok->str()))
|
||||
continue;
|
||||
|
||||
if (Token::Match(tok->previous(), "%op%|("))
|
||||
unknownMacroError(tok);
|
||||
}
|
||||
}
|
||||
|
||||
// Report unknown macros in non-executable scopes..
|
||||
for (const Token *tok = tokens(); tok; tok = tok->next()) {
|
||||
// Skip executable scopes..
|
||||
if (tok->str() == "{") {
|
||||
|
@ -9298,6 +9311,10 @@ void Tokenizer::reportUnknownMacrosInNonExecutableScopes()
|
|||
}
|
||||
|
||||
if (Token::Match(tok, "%name% (") && tok->isUpperCaseName() && Token::simpleMatch(tok->linkAt(1), ") (") && Token::simpleMatch(tok->linkAt(1)->linkAt(1), ") {")) {
|
||||
// A keyword is not an unknown macro
|
||||
if (list.isKeyword(tok->str()))
|
||||
continue;
|
||||
|
||||
const Token *bodyStart = tok->linkAt(1)->linkAt(1)->tokAt(2);
|
||||
const Token *bodyEnd = tok->link();
|
||||
for (const Token *tok2 = bodyStart; tok2 && tok2 != bodyEnd; tok2 = tok2->next()) {
|
||||
|
|
|
@ -635,7 +635,7 @@ private:
|
|||
void validate() const;
|
||||
|
||||
/** Detect unknown macros and throw unknownMacro */
|
||||
void reportUnknownMacrosInNonExecutableScopes();
|
||||
void reportUnknownMacros();
|
||||
|
||||
/** Detect garbage code and call syntaxError() if found. */
|
||||
void findGarbageCode() const;
|
||||
|
|
|
@ -43,6 +43,40 @@ TokenList::TokenList(const Settings* settings) :
|
|||
mIsC(false),
|
||||
mIsCpp(false)
|
||||
{
|
||||
mKeywords.insert("auto");
|
||||
mKeywords.insert("break");
|
||||
mKeywords.insert("case");
|
||||
mKeywords.insert("char");
|
||||
mKeywords.insert("const");
|
||||
mKeywords.insert("continue");
|
||||
mKeywords.insert("default");
|
||||
mKeywords.insert("do");
|
||||
mKeywords.insert("double");
|
||||
mKeywords.insert("else");
|
||||
mKeywords.insert("enum");
|
||||
mKeywords.insert("extern");
|
||||
mKeywords.insert("float");
|
||||
mKeywords.insert("for");
|
||||
mKeywords.insert("goto");
|
||||
mKeywords.insert("if");
|
||||
mKeywords.insert("inline");
|
||||
mKeywords.insert("int");
|
||||
mKeywords.insert("long");
|
||||
mKeywords.insert("register");
|
||||
mKeywords.insert("restrict");
|
||||
mKeywords.insert("return");
|
||||
mKeywords.insert("short");
|
||||
mKeywords.insert("signed");
|
||||
mKeywords.insert("sizeof");
|
||||
mKeywords.insert("static");
|
||||
mKeywords.insert("struct");
|
||||
mKeywords.insert("switch");
|
||||
mKeywords.insert("typedef");
|
||||
mKeywords.insert("union");
|
||||
mKeywords.insert("unsigned");
|
||||
mKeywords.insert("void");
|
||||
mKeywords.insert("volatile");
|
||||
mKeywords.insert("while");
|
||||
}
|
||||
|
||||
TokenList::~TokenList()
|
||||
|
@ -90,6 +124,38 @@ int TokenList::appendFileIfNew(const std::string &fileName)
|
|||
mIsC = mSettings->enforcedLang == Settings::C || (mSettings->enforcedLang == Settings::None && Path::isC(getSourceFilePath()));
|
||||
mIsCpp = mSettings->enforcedLang == Settings::CPP || (mSettings->enforcedLang == Settings::None && Path::isCPP(getSourceFilePath()));
|
||||
}
|
||||
|
||||
if (mIsCpp) {
|
||||
mKeywords.insert("catch");
|
||||
mKeywords.insert("delete");
|
||||
mKeywords.insert("class");
|
||||
mKeywords.insert("const_cast");
|
||||
mKeywords.insert("delete");
|
||||
mKeywords.insert("dynamic_cast");
|
||||
mKeywords.insert("explicit");
|
||||
mKeywords.insert("export");
|
||||
mKeywords.insert("false");
|
||||
mKeywords.insert("friend");
|
||||
mKeywords.insert("mutable");
|
||||
mKeywords.insert("namespace");
|
||||
mKeywords.insert("new");
|
||||
mKeywords.insert("operator");
|
||||
mKeywords.insert("private");
|
||||
mKeywords.insert("protected");
|
||||
mKeywords.insert("public");
|
||||
mKeywords.insert("reinterpret_cast");
|
||||
mKeywords.insert("static_cast");
|
||||
mKeywords.insert("template");
|
||||
mKeywords.insert("this");
|
||||
mKeywords.insert("throw");
|
||||
mKeywords.insert("true");
|
||||
mKeywords.insert("try");
|
||||
mKeywords.insert("typeid");
|
||||
mKeywords.insert("typename");
|
||||
mKeywords.insert("using");
|
||||
mKeywords.insert("virtual");
|
||||
mKeywords.insert("wchar_t");
|
||||
}
|
||||
}
|
||||
return mFiles.size() - 1;
|
||||
}
|
||||
|
@ -140,7 +206,7 @@ void TokenList::addtoken(std::string str, const nonneg int lineno, const nonneg
|
|||
mTokensFrontBack.back->str(str);
|
||||
}
|
||||
|
||||
if (isCPP() && str == "delete")
|
||||
if (isKeyword(str))
|
||||
mTokensFrontBack.back->isKeyword(true);
|
||||
mTokensFrontBack.back->linenr(lineno);
|
||||
mTokensFrontBack.back->fileIndex(fileno);
|
||||
|
@ -1690,3 +1756,7 @@ void TokenList::simplifyStdType()
|
|||
}
|
||||
}
|
||||
|
||||
bool TokenList::isKeyword(const std::string &str) const
|
||||
{
|
||||
return mKeywords.find(str) != mKeywords.end();
|
||||
}
|
||||
|
|
|
@ -188,6 +188,8 @@ public:
|
|||
|
||||
void clangSetOrigFiles();
|
||||
|
||||
bool isKeyword(const std::string &str) const;
|
||||
|
||||
private:
|
||||
|
||||
/** Disable copy constructor, no implementation */
|
||||
|
@ -208,8 +210,11 @@ private:
|
|||
/** settings */
|
||||
const Settings* mSettings;
|
||||
|
||||
std::set<std::string> mKeywords;
|
||||
|
||||
/** File is known to be C/C++ code */
|
||||
bool mIsC, mIsCpp;
|
||||
bool mIsC;
|
||||
bool mIsCpp;
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
|
|
@ -467,7 +467,7 @@ private:
|
|||
|
||||
TEST_CASE(sizeofAddParentheses);
|
||||
|
||||
TEST_CASE(reportUnknownMacrosInNonExecutableScopes);
|
||||
TEST_CASE(reportUnknownMacros);
|
||||
|
||||
// Make sure the Tokenizer::findGarbageCode() does not have false positives
|
||||
// The TestGarbage ensures that there are true positives
|
||||
|
@ -7972,10 +7972,13 @@ private:
|
|||
ASSERT_EQUALS("sizeof ( a ) > sizeof ( & main ) ;", tokenizeAndStringify("sizeof a > sizeof &main;"));
|
||||
}
|
||||
|
||||
void reportUnknownMacrosInNonExecutableScopes() {
|
||||
const char code[] = "MY_UNKNOWN_IMP1(IInStream)\n"
|
||||
"STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) { if (ptr); }";
|
||||
ASSERT_THROW(tokenizeAndStringify(code), InternalError);
|
||||
void reportUnknownMacros() {
|
||||
const char code1[] = "MY_UNKNOWN_IMP1(IInStream)\n"
|
||||
"STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) { if (ptr); }";
|
||||
ASSERT_THROW(tokenizeAndStringify(code1), InternalError);
|
||||
|
||||
const char code2[] = "void foo() { dostuff(x 0); }";
|
||||
ASSERT_THROW(tokenizeAndStringify(code2), InternalError);
|
||||
}
|
||||
|
||||
void findGarbageCode() { // Test Tokenizer::findGarbageCode()
|
||||
|
|
Loading…
Reference in New Issue