Skip to content

Commit

Permalink
Fix #12026 (simplifyTypedef: not handled properly when typedef and en…
Browse files Browse the repository at this point in the history
…um constant has same name) (#5500)
  • Loading branch information
danmar committed Oct 1, 2023
1 parent 6773cdb commit 6a8f787
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 8 deletions.
34 changes: 27 additions & 7 deletions lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -921,20 +921,27 @@ namespace {
}
}

bool canReplace(const Token* tok) {
if (mNameToken == tok)
return false;
if (!Token::Match(tok->previous(), "%name%|;|{|}|(|,|<") && !Token::Match(tok->previous(), "!!. %name% ("))
return false;
static int canReplaceStatic(const Token* tok) {
if (!Token::Match(tok, "%name% %name%|*|&|&&|;|(|)|,|::")) {
if (Token::Match(tok->previous(), "( %name% =") && Token::Match(tok->linkAt(-1), ") %name%|{") && !tok->tokAt(-2)->isKeyword())
return true;
if (Token::Match(tok->previous(), ", %name% ="))
return true;
if (Token::Match(tok->previous(), "new %name% ["))
return true;
if (Token::Match(tok->previous(), "< %name% >"))
if (Token::Match(tok->previous(), "< %name%") && tok->previous()->findClosingBracket())
return true;
if (Token::Match(tok->previous(), ", %name% >|>>")) {
for (const Token* prev = tok->previous(); prev; prev = prev->previous()) {
if (Token::Match(prev, "[;{}(]"))
break;
if (prev->str() == "<" && prev->findClosingBracket() == tok->next())
return true;
if (prev->str() == ")")
prev = prev->link();
}
return true;
}
if (Token::Match(tok->previous(), "public|protected|private"))
return true;
if (Token::Match(tok->previous(), ", %name% :")) {
Expand All @@ -951,6 +958,19 @@ namespace {
}
return false;
}
return -1;
}

bool canReplace(const Token* tok) {
if (mNameToken == tok)
return false;
if (!Token::Match(tok->previous(), "%name%|;|{|}|(|,|<") && !Token::Match(tok->previous(), "!!. %name% ("))
return false;
{
const int res = canReplaceStatic(tok);
if (res == 0 || res == 1)
return res != 0;
}
if (Token::Match(tok->previous(), "%name%") && !tok->previous()->isKeyword())
return false;
if (Token::simpleMatch(tok->next(), "(") && Token::Match(tok->linkAt(1), ") %name%|{"))
Expand Down Expand Up @@ -1843,7 +1863,7 @@ void Tokenizer::simplifyTypedefCpp()
} else if (Token::Match(tok2->tokAt(-2), "%type% *|&")) {
// Ticket #5868: Don't substitute variable names
} else if (tok2->previous()->str() != ".") {
simplifyType = true;
simplifyType = (TypedefSimplifier::canReplaceStatic(tok2) != 0);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/testgarbage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,7 @@ class TestGarbage : public TestFixture {
}

void garbageCode85() { // #6784
ASSERT_THROW(checkCode("{ } { } typedef void ( *VoidFunc() ) ( ) ; VoidFunc"), InternalError); // do not crash
checkCode("{ } { } typedef void ( *VoidFunc() ) ( ) ; VoidFunc"); // do not crash
}

void garbageCode86() { // #6785
Expand Down
9 changes: 9 additions & 0 deletions test/testsimplifytypedef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class TestSimplifyTypedef : public TestFixture {
TEST_CASE(canreplace1);
TEST_CASE(canreplace2);
TEST_CASE(canreplace3);
TEST_CASE(canreplace4);
TEST_CASE(cconst);
TEST_CASE(cstruct1);
TEST_CASE(cstruct2);
Expand Down Expand Up @@ -353,6 +354,14 @@ class TestSimplifyTypedef : public TestFixture {
ASSERT_EQUALS("struct S { const char * g ( ) const { return s . c_str ( ) ; } std :: string s ; } ;", simplifyTypedefC(code1));
}

void canreplace4() {
const char code1[] = "typedef std::vector<int> X;\n" // #12026
"struct S {\n"
" enum E { X };\n"
"};\n";
ASSERT_EQUALS("struct S { enum E { X } ; } ;", simplifyTypedef(code1));
}

void cconst() {
const char code1[] = "typedef void* HWND;\n"
"const HWND x;";
Expand Down

0 comments on commit 6a8f787

Please sign in to comment.