Fix 10721: Crash in Tokenizer::simplifyTokenList1 (#3712)

This commit is contained in:
Paul Fultz II 2022-01-16 05:46:20 -06:00 committed by GitHub
parent abb0563cef
commit 7406dd8c94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 0 deletions

View File

@ -1057,6 +1057,7 @@ void Tokenizer::simplifyTypedef()
int memberScope = 0;
bool globalScope = false;
int classLevel = spaceInfo.size();
bool inTypeDef = false;
std::string removed;
std::string classPath;
for (size_t i = 1; i < spaceInfo.size(); ++i) {
@ -1071,6 +1072,36 @@ void Tokenizer::simplifyTypedef()
removed.clear();
if (Token::simpleMatch(tok2, "typedef"))
inTypeDef = true;
if (inTypeDef && Token::simpleMatch(tok2, ";"))
inTypeDef = false;
// Check for variable declared with the same name
if (!inTypeDef && spaceInfo.size() == 1 && Token::Match(tok2->previous(), "%name%") &&
!tok2->previous()->isKeyword()) {
Token* varDecl = tok2;
while (Token::Match(varDecl, "*|&|&&|const"))
varDecl = varDecl->next();
if (Token::Match(varDecl, "%name% ;|,|)|=") && varDecl->str() == typeName->str()) {
// Skip to the next closing brace
if (Token::Match(varDecl, "%name% ) {")) { // is argument variable
tok2 = varDecl->linkAt(2)->next();
} else {
tok2 = varDecl;
while (tok2 && !Token::simpleMatch(tok2, "}")) {
if (Token::Match(tok2, "(|{|["))
tok2 = tok2->link();
tok2 = tok2->next();
}
}
if (!tok2)
break;
continue;
}
}
if (tok2->link()) { // Pre-check for performance
// check for end of scope
if (tok2->str() == "}") {

View File

@ -179,6 +179,7 @@ private:
TEST_CASE(simplifyTypedef136);
TEST_CASE(simplifyTypedef137);
TEST_CASE(simplifyTypedef138);
TEST_CASE(simplifyTypedef139);
TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@ -3006,6 +3007,20 @@ private:
ASSERT_EQUALS("namespace foo { class Bar ; } class Baz ; namespace bar { class C : Baz { } ; }", tok(code));
}
void simplifyTypedef139()
{
const char code[] = "typedef struct c a;\n"
"struct {\n"
" a *b;\n"
"} * d;\n"
"void e(a *a) {\n"
" if (a < d[0].b) {}\n"
"}\n";
ASSERT_EQUALS(
"struct Anonymous0 { struct c * b ; } ; struct Anonymous0 * d ; void e ( struct c * a ) { if ( a < d [ 0 ] . b ) { } }",
tok(code));
}
void simplifyTypedefFunction1() {
{
const char code[] = "typedef void (*my_func)();\n"