Tokenizer::findGarbageCode: detect wrong struct declaration

This commit is contained in:
Daniel Marjamäki 2021-05-08 15:28:21 +02:00
parent a197e94573
commit 895a96f9dd
3 changed files with 23 additions and 1 deletions

View File

@ -10224,6 +10224,22 @@ void Tokenizer::findGarbageCode() const
}
}
// invalid struct declaration
for (const Token *tok = tokens(); tok; tok = tok->next()) {
if (Token::Match(tok, "struct|class|enum %name%| {") && (!tok->previous() || Token::Match(tok->previous(), "[;{}]"))) {
const Token *tok2 = tok->linkAt(tok->next()->isName() ? 2 : 1);
if (Token::Match(tok2, "} %op%")) {
tok2 = tok2->next();
if (!Token::Match(tok2, "*|&|&&"))
syntaxError(tok2, "Unexpected token '" + tok2->str() + "'");
while (Token::Match(tok2, "*|&|&&"))
tok2 = tok2->next();
if (!Token::Match(tok2, "%name%"))
syntaxError(tok2, "Unexpected token '" + tok2->str() + "'");
}
}
}
// Keywords in global scope
static const std::unordered_set<std::string> nonGlobalKeywords{"break",
"continue",

View File

@ -47,6 +47,7 @@ private:
TEST_CASE(wrong_syntax4); // #3618
TEST_CASE(wrong_syntax_if_macro); // #2518 - if MACRO()
TEST_CASE(wrong_syntax_class_x_y); // #3585 - class x y { };
TEST_CASE(wrong_syntax_anonymous_struct);
TEST_CASE(syntax_case_default);
TEST_CASE(garbageCode1);
TEST_CASE(garbageCode2); // #4300
@ -403,6 +404,11 @@ private:
}
}
void wrong_syntax_anonymous_struct() {
ASSERT_THROW(checkCode("struct { int x; } = {0};"), InternalError);
ASSERT_THROW(checkCode("struct { int x; } * = {0};"), InternalError);
}
void syntax_case_default() {
ASSERT_THROW(checkCode("void f() {switch (n) { case: z(); break;}}"), InternalError);

View File

@ -2173,7 +2173,7 @@ private:
" return ret;\n"
"}");
ASSERT_EQUALS("", errout.str());
check("char *x() {\n"
" return strcpy(malloc(10), \"abc\");\n"
"}");