Tokenizer: Throw unknownMacro in non-executable scope
This commit is contained in:
parent
bdf715b3e5
commit
6f6f9dd5bc
|
@ -4302,6 +4302,8 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
|
|||
|
||||
createLinks();
|
||||
|
||||
reportUnknownMacrosInNonExecutableScopes();
|
||||
|
||||
simplifyHeaders();
|
||||
|
||||
// Remove __asm..
|
||||
|
@ -9283,6 +9285,29 @@ static bool isCPPAttribute(const Token * tok)
|
|||
return Token::simpleMatch(tok, "[ [") && tok->link() && tok->link()->previous() == tok->linkAt(1);
|
||||
}
|
||||
|
||||
void Tokenizer::reportUnknownMacrosInNonExecutableScopes()
|
||||
{
|
||||
for (const Token *tok = tokens(); tok; tok = tok->next()) {
|
||||
// Skip executable scopes..
|
||||
if (tok->str() == "{") {
|
||||
const Token *prev = tok->previous();
|
||||
while (prev && prev->isName())
|
||||
prev = prev->previous();
|
||||
if (prev && prev->str() == ")")
|
||||
tok = tok->link();
|
||||
}
|
||||
|
||||
if (Token::Match(tok, "%name% (") && tok->isUpperCaseName() && Token::simpleMatch(tok->linkAt(1), ") (") && Token::simpleMatch(tok->linkAt(1)->linkAt(1), ") {")) {
|
||||
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()) {
|
||||
if (Token::Match(tok2, "if|switch|for|while|return"))
|
||||
unknownMacroError(tok);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Tokenizer::findGarbageCode() const
|
||||
{
|
||||
const bool isCPP11 = isCPP() && mSettings->standards.cpp >= Standards::CPP11;
|
||||
|
|
|
@ -634,6 +634,9 @@ private:
|
|||
*/
|
||||
void validate() const;
|
||||
|
||||
/** Detect unknown macros and throw unknownMacro */
|
||||
void reportUnknownMacrosInNonExecutableScopes();
|
||||
|
||||
/** Detect garbage code and call syntaxError() if found. */
|
||||
void findGarbageCode() const;
|
||||
|
||||
|
|
|
@ -2537,10 +2537,9 @@ private:
|
|||
|
||||
void symboldatabase5() {
|
||||
// ticket #2178 - segmentation fault
|
||||
check("int CL_INLINE_DECL(integer_decode_float) (int x) {\n"
|
||||
ASSERT_THROW(check("int CL_INLINE_DECL(integer_decode_float) (int x) {\n"
|
||||
" return (sign ? cl_I() : 0);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
"}"), InternalError);
|
||||
}
|
||||
|
||||
void symboldatabase6() {
|
||||
|
|
|
@ -466,6 +466,8 @@ private:
|
|||
|
||||
TEST_CASE(sizeofAddParentheses);
|
||||
|
||||
TEST_CASE(reportUnknownMacrosInNonExecutableScopes);
|
||||
|
||||
// Make sure the Tokenizer::findGarbageCode() does not have false positives
|
||||
// The TestGarbage ensures that there are true positives
|
||||
TEST_CASE(findGarbageCode);
|
||||
|
@ -7959,6 +7961,12 @@ 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 findGarbageCode() { // Test Tokenizer::findGarbageCode()
|
||||
// before if|for|while|switch
|
||||
ASSERT_NO_THROW(tokenizeAndStringify("void f() { do switch (a) {} while (1); }"))
|
||||
|
|
Loading…
Reference in New Issue